Salome HOME
Copyrights update 2015.
[modules/med.git] / src / MEDCoupling / MEDCouplingMemArray.cxx
1 // Copyright (C) 2007-2015  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 "MEDCouplingAutoRefCountObjectPtr.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 ParaMEDMEM;
39
40 template<int SPACEDIM>
41 void DataArrayDouble::findCommonTuplesAlg(const double *bbox, int nbNodes, int limitNodeId, double prec, DataArrayInt *c, DataArrayInt *cI) const
42 {
43   const double *coordsPtr=getConstPointer();
44   BBTreePts<SPACEDIM,int> myTree(bbox,0,0,nbNodes,prec);
45   std::vector<bool> isDone(nbNodes);
46   for(int i=0;i<nbNodes;i++)
47     {
48       if(!isDone[i])
49         {
50           std::vector<int> intersectingElems;
51           myTree.getElementsAroundPoint(coordsPtr+i*SPACEDIM,intersectingElems);
52           if(intersectingElems.size()>1)
53             {
54               std::vector<int> commonNodes;
55               for(std::vector<int>::const_iterator it=intersectingElems.begin();it!=intersectingElems.end();it++)
56                 if(*it!=i)
57                   if(*it>=limitNodeId)
58                     {
59                       commonNodes.push_back(*it);
60                       isDone[*it]=true;
61                     }
62               if(!commonNodes.empty())
63                 {
64                   cI->pushBackSilent(cI->back()+(int)commonNodes.size()+1);
65                   c->pushBackSilent(i);
66                   c->insertAtTheEnd(commonNodes.begin(),commonNodes.end());
67                 }
68             }
69         }
70     }
71 }
72
73 template<int SPACEDIM>
74 void DataArrayDouble::FindTupleIdsNearTuplesAlg(const BBTreePts<SPACEDIM,int>& myTree, const double *pos, int nbOfTuples, double eps,
75                                                 DataArrayInt *c, DataArrayInt *cI)
76 {
77   for(int i=0;i<nbOfTuples;i++)
78     {
79       std::vector<int> intersectingElems;
80       myTree.getElementsAroundPoint(pos+i*SPACEDIM,intersectingElems);
81       std::vector<int> commonNodes;
82       for(std::vector<int>::const_iterator it=intersectingElems.begin();it!=intersectingElems.end();it++)
83         commonNodes.push_back(*it);
84       cI->pushBackSilent(cI->back()+(int)commonNodes.size());
85       c->insertAtTheEnd(commonNodes.begin(),commonNodes.end());
86     }
87 }
88
89 template<int SPACEDIM>
90 void DataArrayDouble::FindClosestTupleIdAlg(const BBTreePts<SPACEDIM,int>& myTree, double dist, const double *pos, int nbOfTuples, const double *thisPt, int thisNbOfTuples, int *res)
91 {
92   double distOpt(dist);
93   const double *p(pos);
94   int *r(res);
95   for(int i=0;i<nbOfTuples;i++,p+=SPACEDIM,r++)
96     {
97       while(true)
98         {
99           int elem=-1;
100           double ret=myTree.getElementsAroundPoint2(p,distOpt,elem);
101           if(ret!=std::numeric_limits<double>::max())
102             {
103               distOpt=std::max(ret,1e-4);
104               *r=elem;
105               break;
106             }
107           else
108             { distOpt=2*distOpt; continue; }
109         }
110     }
111 }
112
113 std::size_t DataArray::getHeapMemorySizeWithoutChildren() const
114 {
115   std::size_t sz1=_name.capacity();
116   std::size_t sz2=_info_on_compo.capacity();
117   std::size_t sz3=0;
118   for(std::vector<std::string>::const_iterator it=_info_on_compo.begin();it!=_info_on_compo.end();it++)
119     sz3+=(*it).capacity();
120   return sz1+sz2+sz3;
121 }
122
123 std::vector<const BigMemoryObject *> DataArray::getDirectChildrenWithNull() const
124 {
125   return std::vector<const BigMemoryObject *>();
126 }
127
128 /*!
129  * Sets the attribute \a _name of \a this array.
130  * See \ref MEDCouplingArrayBasicsName "DataArrays infos" for more information.
131  *  \param [in] name - new array name
132  */
133 void DataArray::setName(const std::string& name)
134 {
135   _name=name;
136 }
137
138 /*!
139  * Copies textual data from an \a other DataArray. The copied data are
140  * - the name attribute,
141  * - the information of components.
142  *
143  * For more information on these data see \ref MEDCouplingArrayBasicsName "DataArrays infos".
144  *
145  *  \param [in] other - another instance of DataArray to copy the textual data from.
146  *  \throw If number of components of \a this array differs from that of the \a other.
147  */
148 void DataArray::copyStringInfoFrom(const DataArray& other)
149 {
150   if(_info_on_compo.size()!=other._info_on_compo.size())
151     throw INTERP_KERNEL::Exception("Size of arrays mismatches on copyStringInfoFrom !");
152   _name=other._name;
153   _info_on_compo=other._info_on_compo;
154 }
155
156 void DataArray::copyPartOfStringInfoFrom(const DataArray& other, const std::vector<int>& compoIds)
157 {
158   int nbOfCompoOth=other.getNumberOfComponents();
159   std::size_t newNbOfCompo=compoIds.size();
160   for(std::size_t i=0;i<newNbOfCompo;i++)
161     if(compoIds[i]>=nbOfCompoOth || compoIds[i]<0)
162       {
163         std::ostringstream oss; oss << "Specified component id is out of range (" << compoIds[i] << ") compared with nb of actual components (" << nbOfCompoOth << ")";
164         throw INTERP_KERNEL::Exception(oss.str().c_str());
165       }
166   for(std::size_t i=0;i<newNbOfCompo;i++)
167     setInfoOnComponent((int)i,other.getInfoOnComponent(compoIds[i]));
168 }
169
170 void DataArray::copyPartOfStringInfoFrom2(const std::vector<int>& compoIds, const DataArray& other)
171 {
172   int nbOfCompo=getNumberOfComponents();
173   std::size_t partOfCompoToSet=compoIds.size();
174   if((int)partOfCompoToSet!=other.getNumberOfComponents())
175     throw INTERP_KERNEL::Exception("Given compoIds has not the same size as number of components of given array !");
176   for(std::size_t i=0;i<partOfCompoToSet;i++)
177     if(compoIds[i]>=nbOfCompo || compoIds[i]<0)
178       {
179         std::ostringstream oss; oss << "Specified component id is out of range (" << compoIds[i] << ") compared with nb of actual components (" << nbOfCompo << ")";
180         throw INTERP_KERNEL::Exception(oss.str().c_str());
181       }
182   for(std::size_t i=0;i<partOfCompoToSet;i++)
183     setInfoOnComponent(compoIds[i],other.getInfoOnComponent((int)i));
184 }
185
186 bool DataArray::areInfoEqualsIfNotWhy(const DataArray& other, std::string& reason) const
187 {
188   std::ostringstream oss;
189   if(_name!=other._name)
190     {
191       oss << "Names DataArray mismatch : this name=\"" << _name << " other name=\"" << other._name << "\" !";
192       reason=oss.str();
193       return false;
194     }
195   if(_info_on_compo!=other._info_on_compo)
196     {
197       oss << "Components DataArray mismatch : \nThis components=";
198       for(std::vector<std::string>::const_iterator it=_info_on_compo.begin();it!=_info_on_compo.end();it++)
199         oss << "\"" << *it << "\",";
200       oss << "\nOther components=";
201       for(std::vector<std::string>::const_iterator it=other._info_on_compo.begin();it!=other._info_on_compo.end();it++)
202         oss << "\"" << *it << "\",";
203       reason=oss.str();
204       return false;
205     }
206   return true;
207 }
208
209 /*!
210  * Compares textual information of \a this DataArray with that of an \a other one.
211  * The compared data are
212  * - the name attribute,
213  * - the information of components.
214  *
215  * For more information on these data see \ref MEDCouplingArrayBasicsName "DataArrays infos".
216  *  \param [in] other - another instance of DataArray to compare the textual data of.
217  *  \return bool - \a true if the textual information is same, \a false else.
218  */
219 bool DataArray::areInfoEquals(const DataArray& other) const
220 {
221   std::string tmp;
222   return areInfoEqualsIfNotWhy(other,tmp);
223 }
224
225 void DataArray::reprWithoutNameStream(std::ostream& stream) const
226 {
227   stream << "Number of components : "<< getNumberOfComponents() << "\n";
228   stream << "Info of these components : ";
229   for(std::vector<std::string>::const_iterator iter=_info_on_compo.begin();iter!=_info_on_compo.end();iter++)
230     stream << "\"" << *iter << "\"   ";
231   stream << "\n";
232 }
233
234 std::string DataArray::cppRepr(const std::string& varName) const
235 {
236   std::ostringstream ret;
237   reprCppStream(varName,ret);
238   return ret.str();
239 }
240
241 /*!
242  * Sets information on all components. To know more on format of this information
243  * see \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
244  *  \param [in] info - a vector of strings.
245  *  \throw If size of \a info differs from the number of components of \a this.
246  */
247 void DataArray::setInfoOnComponents(const std::vector<std::string>& info)
248 {
249   if(getNumberOfComponents()!=(int)info.size())
250     {
251       std::ostringstream oss; oss << "DataArray::setInfoOnComponents : input is of size " << info.size() << " whereas number of components is equal to " << getNumberOfComponents() << " !";
252       throw INTERP_KERNEL::Exception(oss.str().c_str());
253     }
254   _info_on_compo=info;
255 }
256
257 /*!
258  * This method is only a dispatcher towards DataArrayDouble::setPartOfValues3, DataArrayInt::setPartOfValues3, DataArrayChar::setPartOfValues3 depending on the true
259  * type of \a this and \a aBase.
260  *
261  * \throw If \a aBase and \a this do not have the same type.
262  *
263  * \sa DataArrayDouble::setPartOfValues3, DataArrayInt::setPartOfValues3, DataArrayChar::setPartOfValues3.
264  */
265 void DataArray::setPartOfValuesBase3(const DataArray *aBase, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare)
266 {
267   if(!aBase)
268     throw INTERP_KERNEL::Exception("DataArray::setPartOfValuesBase3 : input aBase object is NULL !");
269   DataArrayDouble *this1(dynamic_cast<DataArrayDouble *>(this));
270   DataArrayInt *this2(dynamic_cast<DataArrayInt *>(this));
271   DataArrayChar *this3(dynamic_cast<DataArrayChar *>(this));
272   const DataArrayDouble *a1(dynamic_cast<const DataArrayDouble *>(aBase));
273   const DataArrayInt *a2(dynamic_cast<const DataArrayInt *>(aBase));
274   const DataArrayChar *a3(dynamic_cast<const DataArrayChar *>(aBase));
275   if(this1 && a1)
276     {
277       this1->setPartOfValues3(a1,bgTuples,endTuples,bgComp,endComp,stepComp,strictCompoCompare);
278       return ;
279     }
280   if(this2 && a2)
281     {
282       this2->setPartOfValues3(a2,bgTuples,endTuples,bgComp,endComp,stepComp,strictCompoCompare);
283       return ;
284     }
285   if(this3 && a3)
286     {
287       this3->setPartOfValues3(a3,bgTuples,endTuples,bgComp,endComp,stepComp,strictCompoCompare);
288       return ;
289     }
290   throw INTERP_KERNEL::Exception("DataArray::setPartOfValuesBase3 : input aBase object and this do not have the same type !");
291 }
292
293 std::vector<std::string> DataArray::getVarsOnComponent() const
294 {
295   int nbOfCompo=(int)_info_on_compo.size();
296   std::vector<std::string> ret(nbOfCompo);
297   for(int i=0;i<nbOfCompo;i++)
298     ret[i]=getVarOnComponent(i);
299   return ret;
300 }
301
302 std::vector<std::string> DataArray::getUnitsOnComponent() const
303 {
304   int nbOfCompo=(int)_info_on_compo.size();
305   std::vector<std::string> ret(nbOfCompo);
306   for(int i=0;i<nbOfCompo;i++)
307     ret[i]=getUnitOnComponent(i);
308   return ret;
309 }
310
311 /*!
312  * Returns information on a component specified by an index.
313  * To know more on format of this information
314  * see \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
315  *  \param [in] i - the index (zero based) of the component of interest.
316  *  \return std::string - a string containing the information on \a i-th component.
317  *  \throw If \a i is not a valid component index.
318  */
319 std::string DataArray::getInfoOnComponent(int i) const
320 {
321   if(i<(int)_info_on_compo.size() && i>=0)
322     return _info_on_compo[i];
323   else
324     {
325       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();
326       throw INTERP_KERNEL::Exception(oss.str().c_str());
327     }
328 }
329
330 /*!
331  * Returns the var part of the full information of the \a i-th component.
332  * For example, if \c getInfoOnComponent(0) returns "SIGXY [N/m^2]", then
333  * \c getVarOnComponent(0) returns "SIGXY".
334  * If a unit part of information is not detected by presence of
335  * two square brackets, then the full information is returned.
336  * To read more about the component information format, see
337  * \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
338  *  \param [in] i - the index (zero based) of the component of interest.
339  *  \return std::string - a string containing the var information, or the full info.
340  *  \throw If \a i is not a valid component index.
341  */
342 std::string DataArray::getVarOnComponent(int i) const
343 {
344   if(i<(int)_info_on_compo.size() && i>=0)
345     {
346       return GetVarNameFromInfo(_info_on_compo[i]);
347     }
348   else
349     {
350       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();
351       throw INTERP_KERNEL::Exception(oss.str().c_str());
352     }
353 }
354
355 /*!
356  * Returns the unit part of the full information of the \a i-th component.
357  * For example, if \c getInfoOnComponent(0) returns "SIGXY [ N/m^2]", then
358  * \c getUnitOnComponent(0) returns " N/m^2".
359  * If a unit part of information is not detected by presence of
360  * two square brackets, then an empty string is returned.
361  * To read more about the component information format, see
362  * \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
363  *  \param [in] i - the index (zero based) of the component of interest.
364  *  \return std::string - a string containing the unit information, if any, or "".
365  *  \throw If \a i is not a valid component index.
366  */
367 std::string DataArray::getUnitOnComponent(int i) const
368 {
369   if(i<(int)_info_on_compo.size() && i>=0)
370     {
371       return GetUnitFromInfo(_info_on_compo[i]);
372     }
373   else
374     {
375       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();
376       throw INTERP_KERNEL::Exception(oss.str().c_str());
377     }
378 }
379
380 /*!
381  * Returns the var part of the full component information.
382  * For example, if \a info == "SIGXY [N/m^2]", then this method returns "SIGXY".
383  * If a unit part of information is not detected by presence of
384  * two square brackets, then the whole \a info is returned.
385  * To read more about the component information format, see
386  * \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
387  *  \param [in] info - the full component information.
388  *  \return std::string - a string containing only var information, or the \a info.
389  */
390 std::string DataArray::GetVarNameFromInfo(const std::string& info)
391 {
392   std::size_t p1=info.find_last_of('[');
393   std::size_t p2=info.find_last_of(']');
394   if(p1==std::string::npos || p2==std::string::npos)
395     return info;
396   if(p1>p2)
397     return info;
398   if(p1==0)
399     return std::string();
400   std::size_t p3=info.find_last_not_of(' ',p1-1);
401   return info.substr(0,p3+1);
402 }
403
404 /*!
405  * Returns the unit part of the full component information.
406  * For example, if \a info == "SIGXY [ N/m^2]", then this method returns " N/m^2".
407  * If a unit part of information is not detected by presence of
408  * two square brackets, then an empty string is returned.
409  * To read more about the component information format, see
410  * \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
411  *  \param [in] info - the full component information.
412  *  \return std::string - a string containing only unit information, if any, or "".
413  */
414 std::string DataArray::GetUnitFromInfo(const std::string& info)
415 {
416   std::size_t p1=info.find_last_of('[');
417   std::size_t p2=info.find_last_of(']');
418   if(p1==std::string::npos || p2==std::string::npos)
419     return std::string();
420   if(p1>p2)
421     return std::string();
422   return info.substr(p1+1,p2-p1-1);
423 }
424
425 /*!
426  * This method put in info format the result of the merge of \a var and \a unit.
427  * The standard format for that is "var [unit]".
428  * Inversely you can retrieve the var part or the unit part of info string using resp. GetVarNameFromInfo and GetUnitFromInfo.
429  */
430 std::string DataArray::BuildInfoFromVarAndUnit(const std::string& var, const std::string& unit)
431 {
432   std::ostringstream oss;
433   oss << var << " [" << unit << "]";
434   return oss.str();
435 }
436
437 /*!
438  * Returns a new DataArray by concatenating all given arrays, so that (1) the number
439  * of tuples in the result array is a sum of the number of tuples of given arrays and (2)
440  * the number of component in the result array is same as that of each of given arrays.
441  * Info on components is copied from the first of the given arrays. Number of components
442  * in the given arrays must be  the same.
443  *  \param [in] arrs - a sequence of arrays to include in the result array. All arrays must have the same type.
444  *  \return DataArray * - the new instance of DataArray (that can be either DataArrayInt, DataArrayDouble, DataArrayChar).
445  *          The caller is to delete this result array using decrRef() as it is no more
446  *          needed.
447  *  \throw If all arrays within \a arrs are NULL.
448  *  \throw If all not null arrays in \a arrs have not the same type.
449  *  \throw If getNumberOfComponents() of arrays within \a arrs.
450  */
451 DataArray *DataArray::Aggregate(const std::vector<const DataArray *>& arrs)
452 {
453   std::vector<const DataArray *> arr2;
454   for(std::vector<const DataArray *>::const_iterator it=arrs.begin();it!=arrs.end();it++)
455     if(*it)
456       arr2.push_back(*it);
457   if(arr2.empty())
458     throw INTERP_KERNEL::Exception("DataArray::Aggregate : only null instance in input vector !");
459   std::vector<const DataArrayDouble *> arrd;
460   std::vector<const DataArrayInt *> arri;
461   std::vector<const DataArrayChar *> arrc;
462   for(std::vector<const DataArray *>::const_iterator it=arr2.begin();it!=arr2.end();it++)
463     {
464       const DataArrayDouble *a=dynamic_cast<const DataArrayDouble *>(*it);
465       if(a)
466         { arrd.push_back(a); continue; }
467       const DataArrayInt *b=dynamic_cast<const DataArrayInt *>(*it);
468       if(b)
469         { arri.push_back(b); continue; }
470       const DataArrayChar *c=dynamic_cast<const DataArrayChar *>(*it);
471       if(c)
472         { arrc.push_back(c); continue; }
473       throw INTERP_KERNEL::Exception("DataArray::Aggregate : presence of not null instance in inuput that is not in [DataArrayDouble, DataArrayInt, DataArrayChar] !");
474     }
475   if(arr2.size()==arrd.size())
476     return DataArrayDouble::Aggregate(arrd);
477   if(arr2.size()==arri.size())
478     return DataArrayInt::Aggregate(arri);
479   if(arr2.size()==arrc.size())
480     return DataArrayChar::Aggregate(arrc);
481   throw INTERP_KERNEL::Exception("DataArray::Aggregate : all input arrays must have the same type !");
482 }
483
484 /*!
485  * Sets information on a component specified by an index.
486  * To know more on format of this information
487  * see \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
488  *  \warning Don't pass NULL as \a info!
489  *  \param [in] i - the index (zero based) of the component of interest.
490  *  \param [in] info - the string containing the information.
491  *  \throw If \a i is not a valid component index.
492  */
493 void DataArray::setInfoOnComponent(int i, const std::string& info)
494 {
495   if(i<(int)_info_on_compo.size() && i>=0)
496     _info_on_compo[i]=info;
497   else
498     {
499       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();
500       throw INTERP_KERNEL::Exception(oss.str().c_str());
501     }
502 }
503
504 /*!
505  * Sets information on all components. This method can change number of components
506  * at certain conditions; if the conditions are not respected, an exception is thrown.
507  * The number of components can be changed in \a this only if \a this is not allocated.
508  * The condition of number of components must not be changed.
509  *
510  * To know more on format of the component information see
511  * \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
512  *  \param [in] info - a vector of component infos.
513  *  \throw If \a this->getNumberOfComponents() != \a info.size() && \a this->isAllocated()
514  */
515 void DataArray::setInfoAndChangeNbOfCompo(const std::vector<std::string>& info)
516 {
517   if(getNumberOfComponents()!=(int)info.size())
518     {
519       if(!isAllocated())
520         _info_on_compo=info;
521       else
522         {
523           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 !";
524           throw INTERP_KERNEL::Exception(oss.str().c_str());
525         }
526     }
527   else
528     _info_on_compo=info;
529 }
530
531 void DataArray::checkNbOfTuples(int nbOfTuples, const std::string& msg) const
532 {
533   if(getNumberOfTuples()!=nbOfTuples)
534     {
535       std::ostringstream oss; oss << msg << " : mismatch number of tuples : expected " <<  nbOfTuples << " having " << getNumberOfTuples() << " !";
536       throw INTERP_KERNEL::Exception(oss.str().c_str());
537     }
538 }
539
540 void DataArray::checkNbOfComps(int nbOfCompo, const std::string& msg) const
541 {
542   if(getNumberOfComponents()!=nbOfCompo)
543     {
544       std::ostringstream oss; oss << msg << " : mismatch number of components : expected " << nbOfCompo << " having " << getNumberOfComponents() << " !";
545       throw INTERP_KERNEL::Exception(oss.str().c_str());
546     }
547 }
548
549 void DataArray::checkNbOfElems(std::size_t nbOfElems, const std::string& msg) const
550 {
551   if(getNbOfElems()!=nbOfElems)
552     {
553       std::ostringstream oss; oss << msg << " : mismatch number of elems : Expected " << nbOfElems << " having " << getNbOfElems() << " !";
554       throw INTERP_KERNEL::Exception(oss.str().c_str());
555     }
556 }
557
558 void DataArray::checkNbOfTuplesAndComp(const DataArray& other, const std::string& msg) const
559 {
560   if(getNumberOfTuples()!=other.getNumberOfTuples())
561     {
562       std::ostringstream oss; oss << msg << " : mismatch number of tuples : expected " <<  other.getNumberOfTuples() << " having " << getNumberOfTuples() << " !";
563       throw INTERP_KERNEL::Exception(oss.str().c_str());
564     }
565   if(getNumberOfComponents()!=other.getNumberOfComponents())
566     {
567       std::ostringstream oss; oss << msg << " : mismatch number of components : expected " << other.getNumberOfComponents() << " having " << getNumberOfComponents() << " !";
568       throw INTERP_KERNEL::Exception(oss.str().c_str());
569     }
570 }
571
572 void DataArray::checkNbOfTuplesAndComp(int nbOfTuples, int nbOfCompo, const std::string& msg) const
573 {
574   checkNbOfTuples(nbOfTuples,msg);
575   checkNbOfComps(nbOfCompo,msg);
576 }
577
578 /*!
579  * Simply this method checks that \b value is in [0,\b ref).
580  */
581 void DataArray::CheckValueInRange(int ref, int value, const std::string& msg)
582 {
583   if(value<0 || value>=ref)
584     {
585       std::ostringstream oss; oss << "DataArray::CheckValueInRange : " << msg  << " ! Expected in range [0," << ref << "[ having " << value << " !";
586       throw INTERP_KERNEL::Exception(oss.str().c_str());
587     }
588 }
589
590 /*!
591  * This method checks that [\b start, \b end) is compliant with ref length \b value.
592  * typicaly start in [0,\b value) and end in [0,\b value). If value==start and start==end, it is supported.
593  */
594 void DataArray::CheckValueInRangeEx(int value, int start, int end, const std::string& msg)
595 {
596   if(start<0 || start>=value)
597     {
598       if(value!=start || end!=start)
599         {
600           std::ostringstream oss; oss << "DataArray::CheckValueInRangeEx : " << msg  << " ! Expected start " << start << " of input range, in [0," << value << "[ !";
601           throw INTERP_KERNEL::Exception(oss.str().c_str());
602         }
603     }
604   if(end<0 || end>value)
605     {
606       std::ostringstream oss; oss << "DataArray::CheckValueInRangeEx : " << msg  << " ! Expected end " << end << " of input range, in [0," << value << "] !";
607       throw INTERP_KERNEL::Exception(oss.str().c_str());
608     }
609 }
610
611 void DataArray::CheckClosingParInRange(int ref, int value, const std::string& msg)
612 {
613   if(value<0 || value>ref)
614     {
615       std::ostringstream oss; oss << "DataArray::CheckClosingParInRange : " << msg  << " ! Expected input range in [0," << ref << "] having closing open parenthesis " << value << " !";
616       throw INTERP_KERNEL::Exception(oss.str().c_str());
617     }
618 }
619
620 /*!
621  * 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, 
622  * typically it is a whole slice of tuples of DataArray or cells, nodes of a mesh...
623  *
624  * The input \a sliceId should be an id in [0, \a nbOfSlices) that specifies the slice of work.
625  *
626  * \param [in] start - the start of the input slice of the whole work to perform splitted into slices.
627  * \param [in] stop - the stop of the input slice of the whole work to perform splitted into slices.
628  * \param [in] step - the step (that can be <0) of the input slice of the whole work to perform splitted into slices.
629  * \param [in] sliceId - the slice id considered
630  * \param [in] nbOfSlices - the number of slices (typically the number of cores on which the work is expected to be sliced)
631  * \param [out] startSlice - the start of the slice considered
632  * \param [out] stopSlice - the stop of the slice consided
633  * 
634  * \throw If \a step == 0
635  * \throw If \a nbOfSlices not > 0
636  * \throw If \a sliceId not in [0,nbOfSlices)
637  */
638 void DataArray::GetSlice(int start, int stop, int step, int sliceId, int nbOfSlices, int& startSlice, int& stopSlice)
639 {
640   if(nbOfSlices<=0)
641     {
642       std::ostringstream oss; oss << "DataArray::GetSlice : nbOfSlices (" << nbOfSlices << ") must be > 0 !";
643       throw INTERP_KERNEL::Exception(oss.str().c_str());
644     }
645   if(sliceId<0 || sliceId>=nbOfSlices)
646     {
647       std::ostringstream oss; oss << "DataArray::GetSlice : sliceId (" << nbOfSlices << ") must be in [0 , nbOfSlices (" << nbOfSlices << ") ) !";
648       throw INTERP_KERNEL::Exception(oss.str().c_str());
649     }
650   int nbElems=GetNumberOfItemGivenBESRelative(start,stop,step,"DataArray::GetSlice");
651   int minNbOfElemsPerSlice=nbElems/nbOfSlices;
652   startSlice=start+minNbOfElemsPerSlice*step*sliceId;
653   if(sliceId<nbOfSlices-1)
654     stopSlice=start+minNbOfElemsPerSlice*step*(sliceId+1);
655   else
656     stopSlice=stop;
657 }
658
659 int DataArray::GetNumberOfItemGivenBES(int begin, int end, int step, const std::string& msg)
660 {
661   if(end<begin)
662     {
663       std::ostringstream oss; oss << msg << " : end before begin !";
664       throw INTERP_KERNEL::Exception(oss.str().c_str());
665     }
666   if(end==begin)
667     return 0;
668   if(step<=0)
669     {
670       std::ostringstream oss; oss << msg << " : invalid step should be > 0 !";
671       throw INTERP_KERNEL::Exception(oss.str().c_str());
672     }
673   return (end-1-begin)/step+1;
674 }
675
676 int DataArray::GetNumberOfItemGivenBESRelative(int begin, int end, int step, const std::string& msg)
677 {
678   if(step==0)
679     throw INTERP_KERNEL::Exception("DataArray::GetNumberOfItemGivenBES : step=0 is not allowed !");
680   if(end<begin && step>0)
681     {
682       std::ostringstream oss; oss << msg << " : end before begin whereas step is positive !";
683       throw INTERP_KERNEL::Exception(oss.str().c_str());
684     }
685   if(begin<end && step<0)
686     {
687       std::ostringstream oss; oss << msg << " : invalid step should be > 0 !";
688       throw INTERP_KERNEL::Exception(oss.str().c_str());
689     }
690   if(begin!=end)
691     return (std::max(begin,end)-1-std::min(begin,end))/std::abs(step)+1;
692   else
693     return 0;
694 }
695
696 int DataArray::GetPosOfItemGivenBESRelativeNoThrow(int value, int begin, int end, int step)
697 {
698   if(step!=0)
699     {
700       if(step>0)
701         {
702           if(begin<=value && value<end)
703             {
704               if((value-begin)%step==0)
705                 return (value-begin)/step;
706               else
707                 return -1;
708             }
709           else
710             return -1;
711         }
712       else
713         {
714           if(begin>=value && value>end)
715             {
716               if((begin-value)%(-step)==0)
717                 return (begin-value)/(-step);
718               else
719                 return -1;
720             }
721           else
722             return -1;
723         }
724     }
725   else
726     return -1;
727 }
728
729 /*!
730  * Returns a new instance of DataArrayDouble. The caller is to delete this array
731  * using decrRef() as it is no more needed. 
732  */
733 DataArrayDouble *DataArrayDouble::New()
734 {
735   return new DataArrayDouble;
736 }
737
738 /*!
739  * Checks if raw data is allocated. Read more on the raw data
740  * in \ref MEDCouplingArrayBasicsTuplesAndCompo "DataArrays infos" for more information.
741  *  \return bool - \a true if the raw data is allocated, \a false else.
742  */
743 bool DataArrayDouble::isAllocated() const
744 {
745   return getConstPointer()!=0;
746 }
747
748 /*!
749  * Checks if raw data is allocated and throws an exception if it is not the case.
750  *  \throw If the raw data is not allocated.
751  */
752 void DataArrayDouble::checkAllocated() const
753 {
754   if(!isAllocated())
755     throw INTERP_KERNEL::Exception("DataArrayDouble::checkAllocated : Array is defined but not allocated ! Call alloc or setValues method first !");
756 }
757
758 /*!
759  * This method desallocated \a this without modification of informations relative to the components.
760  * After call of this method, DataArrayDouble::isAllocated will return false.
761  * If \a this is already not allocated, \a this is let unchanged.
762  */
763 void DataArrayDouble::desallocate()
764 {
765   _mem.destroy();
766 }
767
768 std::size_t DataArrayDouble::getHeapMemorySizeWithoutChildren() const
769 {
770   std::size_t sz(_mem.getNbOfElemAllocated());
771   sz*=sizeof(double);
772   return DataArray::getHeapMemorySizeWithoutChildren()+sz;
773 }
774
775 /*!
776  * Returns the only one value in \a this, if and only if number of elements
777  * (nb of tuples * nb of components) is equal to 1, and that \a this is allocated.
778  *  \return double - the sole value stored in \a this array.
779  *  \throw If at least one of conditions stated above is not fulfilled.
780  */
781 double DataArrayDouble::doubleValue() const
782 {
783   if(isAllocated())
784     {
785       if(getNbOfElems()==1)
786         {
787           return *getConstPointer();
788         }
789       else
790         throw INTERP_KERNEL::Exception("DataArrayDouble::doubleValue : DataArrayDouble instance is allocated but number of elements is not equal to 1 !");
791     }
792   else
793     throw INTERP_KERNEL::Exception("DataArrayDouble::doubleValue : DataArrayDouble instance is not allocated !");
794 }
795
796 /*!
797  * Checks the number of tuples.
798  *  \return bool - \a true if getNumberOfTuples() == 0, \a false else.
799  *  \throw If \a this is not allocated.
800  */
801 bool DataArrayDouble::empty() const
802 {
803   checkAllocated();
804   return getNumberOfTuples()==0;
805 }
806
807 /*!
808  * Returns a full copy of \a this. For more info on copying data arrays see
809  * \ref MEDCouplingArrayBasicsCopyDeep.
810  *  \return DataArrayDouble * - a new instance of DataArrayDouble. The caller is to
811  *          delete this array using decrRef() as it is no more needed. 
812  */
813 DataArrayDouble *DataArrayDouble::deepCpy() const
814 {
815   return new DataArrayDouble(*this);
816 }
817
818 /*!
819  * Returns either a \a deep or \a shallow copy of this array. For more info see
820  * \ref MEDCouplingArrayBasicsCopyDeep and \ref MEDCouplingArrayBasicsCopyShallow.
821  *  \param [in] dCpy - if \a true, a deep copy is returned, else, a shallow one.
822  *  \return DataArrayDouble * - either a new instance of DataArrayDouble (if \a dCpy
823  *          == \a true) or \a this instance (if \a dCpy == \a false).
824  */
825 DataArrayDouble *DataArrayDouble::performCpy(bool dCpy) const
826 {
827   if(dCpy)
828     return deepCpy();
829   else
830     {
831       incrRef();
832       return const_cast<DataArrayDouble *>(this);
833     }
834 }
835
836 /*!
837  * Copies all the data from another DataArrayDouble. For more info see
838  * \ref MEDCouplingArrayBasicsCopyDeepAssign.
839  *  \param [in] other - another instance of DataArrayDouble to copy data from.
840  *  \throw If the \a other is not allocated.
841  */
842 void DataArrayDouble::cpyFrom(const DataArrayDouble& other)
843 {
844   other.checkAllocated();
845   int nbOfTuples=other.getNumberOfTuples();
846   int nbOfComp=other.getNumberOfComponents();
847   allocIfNecessary(nbOfTuples,nbOfComp);
848   std::size_t nbOfElems=(std::size_t)nbOfTuples*nbOfComp;
849   double *pt=getPointer();
850   const double *ptI=other.getConstPointer();
851   for(std::size_t i=0;i<nbOfElems;i++)
852     pt[i]=ptI[i];
853   copyStringInfoFrom(other);
854 }
855
856 /*!
857  * This method reserve nbOfElems elements in memory ( nbOfElems*8 bytes ) \b without impacting the number of tuples in \a this.
858  * If \a this has already been allocated, this method checks that \a this has only one component. If not an INTERP_KERNEL::Exception will be thrown.
859  * If \a this has not already been allocated, number of components is set to one.
860  * This method allows to reduce number of reallocations on invokation of DataArrayDouble::pushBackSilent and DataArrayDouble::pushBackValsSilent on \a this.
861  * 
862  * \sa DataArrayDouble::pack, DataArrayDouble::pushBackSilent, DataArrayDouble::pushBackValsSilent
863  */
864 void DataArrayDouble::reserve(std::size_t nbOfElems)
865 {
866   int nbCompo=getNumberOfComponents();
867   if(nbCompo==1)
868     {
869       _mem.reserve(nbOfElems);
870     }
871   else if(nbCompo==0)
872     {
873       _mem.reserve(nbOfElems);
874       _info_on_compo.resize(1);
875     }
876   else
877     throw INTERP_KERNEL::Exception("DataArrayDouble::reserve : not available for DataArrayDouble with number of components different than 1 !");
878 }
879
880 /*!
881  * This method adds at the end of \a this the single value \a val. This method do \b not update its time label to avoid useless incrementation
882  * of counter. So the caller is expected to call TimeLabel::declareAsNew on \a this at the end of the push session.
883  *
884  * \param [in] val the value to be added in \a this
885  * \throw If \a this has already been allocated with number of components different from one.
886  * \sa DataArrayDouble::pushBackValsSilent
887  */
888 void DataArrayDouble::pushBackSilent(double val)
889 {
890   int nbCompo=getNumberOfComponents();
891   if(nbCompo==1)
892     _mem.pushBack(val);
893   else if(nbCompo==0)
894     {
895       _info_on_compo.resize(1);
896       _mem.pushBack(val);
897     }
898   else
899     throw INTERP_KERNEL::Exception("DataArrayDouble::pushBackSilent : not available for DataArrayDouble with number of components different than 1 !");
900 }
901
902 /*!
903  * This method adds at the end of \a this a serie of values [\c valsBg,\c valsEnd). This method do \b not update its time label to avoid useless incrementation
904  * of counter. So the caller is expected to call TimeLabel::declareAsNew on \a this at the end of the push session.
905  *
906  *  \param [in] valsBg - an array of values to push at the end of \this.
907  *  \param [in] valsEnd - specifies the end of the array \a valsBg, so that
908  *              the last value of \a valsBg is \a valsEnd[ -1 ].
909  * \throw If \a this has already been allocated with number of components different from one.
910  * \sa DataArrayDouble::pushBackSilent
911  */
912 void DataArrayDouble::pushBackValsSilent(const double *valsBg, const double *valsEnd)
913 {
914   int nbCompo=getNumberOfComponents();
915   if(nbCompo==1)
916     _mem.insertAtTheEnd(valsBg,valsEnd);
917   else if(nbCompo==0)
918     {
919       _info_on_compo.resize(1);
920       _mem.insertAtTheEnd(valsBg,valsEnd);
921     }
922   else
923     throw INTERP_KERNEL::Exception("DataArrayDouble::pushBackValsSilent : not available for DataArrayDouble with number of components different than 1 !");
924 }
925
926 /*!
927  * This method returns silently ( without updating time label in \a this ) the last value, if any and suppress it.
928  * \throw If \a this is already empty.
929  * \throw If \a this has number of components different from one.
930  */
931 double DataArrayDouble::popBackSilent()
932 {
933   if(getNumberOfComponents()==1)
934     return _mem.popBack();
935   else
936     throw INTERP_KERNEL::Exception("DataArrayDouble::popBackSilent : not available for DataArrayDouble with number of components different than 1 !");
937 }
938
939 /*!
940  * This method \b do \b not modify content of \a this. It only modify its memory footprint if the allocated memory is to high regarding real data to store.
941  *
942  * \sa DataArrayDouble::getHeapMemorySizeWithoutChildren, DataArrayDouble::reserve
943  */
944 void DataArrayDouble::pack() const
945 {
946   _mem.pack();
947 }
948
949 /*!
950  * Allocates the raw data in memory. If exactly same memory as needed already
951  * allocated, it is not re-allocated.
952  *  \param [in] nbOfTuple - number of tuples of data to allocate.
953  *  \param [in] nbOfCompo - number of components of data to allocate.
954  *  \throw If \a nbOfTuple < 0 or \a nbOfCompo < 0.
955  */
956 void DataArrayDouble::allocIfNecessary(int nbOfTuple, int nbOfCompo)
957 {
958   if(isAllocated())
959     {
960       if(nbOfTuple!=getNumberOfTuples() || nbOfCompo!=getNumberOfComponents())
961         alloc(nbOfTuple,nbOfCompo);
962     }
963   else
964     alloc(nbOfTuple,nbOfCompo);
965 }
966
967 /*!
968  * Allocates the raw data in memory. If the memory was already allocated, then it is
969  * freed and re-allocated. See an example of this method use
970  * \ref MEDCouplingArraySteps1WC "here".
971  *  \param [in] nbOfTuple - number of tuples of data to allocate.
972  *  \param [in] nbOfCompo - number of components of data to allocate.
973  *  \throw If \a nbOfTuple < 0 or \a nbOfCompo < 0.
974  */
975 void DataArrayDouble::alloc(int nbOfTuple, int nbOfCompo)
976 {
977   if(nbOfTuple<0 || nbOfCompo<0)
978     throw INTERP_KERNEL::Exception("DataArrayDouble::alloc : request for negative length of data !");
979   _info_on_compo.resize(nbOfCompo);
980   _mem.alloc(nbOfCompo*(std::size_t)nbOfTuple);
981   declareAsNew();
982 }
983
984 /*!
985  * Assign zero to all values in \a this array. To know more on filling arrays see
986  * \ref MEDCouplingArrayFill.
987  * \throw If \a this is not allocated.
988  */
989 void DataArrayDouble::fillWithZero()
990 {
991   checkAllocated();
992   _mem.fillWithValue(0.);
993   declareAsNew();
994 }
995
996 /*!
997  * Assign \a val to all values in \a this array. To know more on filling arrays see
998  * \ref MEDCouplingArrayFill.
999  *  \param [in] val - the value to fill with.
1000  *  \throw If \a this is not allocated.
1001  */
1002 void DataArrayDouble::fillWithValue(double val)
1003 {
1004   checkAllocated();
1005   _mem.fillWithValue(val);
1006   declareAsNew();
1007 }
1008
1009 /*!
1010  * Set all values in \a this array so that the i-th element equals to \a init + i
1011  * (i starts from zero). To know more on filling arrays see \ref MEDCouplingArrayFill.
1012  *  \param [in] init - value to assign to the first element of array.
1013  *  \throw If \a this->getNumberOfComponents() != 1
1014  *  \throw If \a this is not allocated.
1015  */
1016 void DataArrayDouble::iota(double init)
1017 {
1018   checkAllocated();
1019   if(getNumberOfComponents()!=1)
1020     throw INTERP_KERNEL::Exception("DataArrayDouble::iota : works only for arrays with only one component, you can call 'rearrange' method before !");
1021   double *ptr=getPointer();
1022   int ntuples=getNumberOfTuples();
1023   for(int i=0;i<ntuples;i++)
1024     ptr[i]=init+double(i);
1025   declareAsNew();
1026 }
1027
1028 /*!
1029  * Checks if all values in \a this array are equal to \a val at precision \a eps.
1030  *  \param [in] val - value to check equality of array values to.
1031  *  \param [in] eps - precision to check the equality.
1032  *  \return bool - \a true if all values are in range (_val_ - _eps_; _val_ + _eps_),
1033  *                 \a false else.
1034  *  \throw If \a this->getNumberOfComponents() != 1
1035  *  \throw If \a this is not allocated.
1036  */
1037 bool DataArrayDouble::isUniform(double val, double eps) const
1038 {
1039   checkAllocated();
1040   if(getNumberOfComponents()!=1)
1041     throw INTERP_KERNEL::Exception("DataArrayDouble::isUniform : must be applied on DataArrayDouble with only one component, you can call 'rearrange' method before !");
1042   int nbOfTuples=getNumberOfTuples();
1043   const double *w=getConstPointer();
1044   const double *end2=w+nbOfTuples;
1045   const double vmin=val-eps;
1046   const double vmax=val+eps;
1047   for(;w!=end2;w++)
1048     if(*w<vmin || *w>vmax)
1049       return false;
1050   return true;
1051 }
1052
1053 /*!
1054  * Sorts values of the array.
1055  *  \param [in] asc - \a true means ascending order, \a false, descending.
1056  *  \throw If \a this is not allocated.
1057  *  \throw If \a this->getNumberOfComponents() != 1.
1058  */
1059 void DataArrayDouble::sort(bool asc)
1060 {
1061   checkAllocated();
1062   if(getNumberOfComponents()!=1)
1063     throw INTERP_KERNEL::Exception("DataArrayDouble::sort : only supported with 'this' array with ONE component !");
1064   _mem.sort(asc);
1065   declareAsNew();
1066 }
1067
1068 /*!
1069  * Reverse the array values.
1070  *  \throw If \a this->getNumberOfComponents() < 1.
1071  *  \throw If \a this is not allocated.
1072  */
1073 void DataArrayDouble::reverse()
1074 {
1075   checkAllocated();
1076   _mem.reverse(getNumberOfComponents());
1077   declareAsNew();
1078 }
1079
1080 /*!
1081  * Checks that \a this array is consistently **increasing** or **decreasing** in value,
1082  * with at least absolute difference value of |\a eps| at each step.
1083  * If not an exception is thrown.
1084  *  \param [in] increasing - if \a true, the array values should be increasing.
1085  *  \param [in] eps - minimal absolute difference between the neighbor values at which 
1086  *                    the values are considered different.
1087  *  \throw If sequence of values is not strictly monotonic in agreement with \a
1088  *         increasing arg.
1089  *  \throw If \a this->getNumberOfComponents() != 1.
1090  *  \throw If \a this is not allocated.
1091  */
1092 void DataArrayDouble::checkMonotonic(bool increasing, double eps) const
1093 {
1094   if(!isMonotonic(increasing,eps))
1095     {
1096       if (increasing)
1097         throw INTERP_KERNEL::Exception("DataArrayDouble::checkMonotonic : 'this' is not INCREASING monotonic !");
1098       else
1099         throw INTERP_KERNEL::Exception("DataArrayDouble::checkMonotonic : 'this' is not DECREASING monotonic !");
1100     }
1101 }
1102
1103 /*!
1104  * Checks that \a this array is consistently **increasing** or **decreasing** in value,
1105  * with at least absolute difference value of |\a eps| at each step.
1106  *  \param [in] increasing - if \a true, array values should be increasing.
1107  *  \param [in] eps - minimal absolute difference between the neighbor values at which 
1108  *                    the values are considered different.
1109  *  \return bool - \a true if values change in accordance with \a increasing arg.
1110  *  \throw If \a this->getNumberOfComponents() != 1.
1111  *  \throw If \a this is not allocated.
1112  */
1113 bool DataArrayDouble::isMonotonic(bool increasing, double eps) const
1114 {
1115   checkAllocated();
1116   if(getNumberOfComponents()!=1)
1117     throw INTERP_KERNEL::Exception("DataArrayDouble::isMonotonic : only supported with 'this' array with ONE component !");
1118   int nbOfElements=getNumberOfTuples();
1119   const double *ptr=getConstPointer();
1120   if(nbOfElements==0)
1121     return true;
1122   double ref=ptr[0];
1123   double absEps=fabs(eps);
1124   if(increasing)
1125     {
1126       for(int i=1;i<nbOfElements;i++)
1127         {
1128           if(ptr[i]<(ref+absEps))
1129             return false;
1130           ref=ptr[i];
1131         }
1132       return true;
1133     }
1134   else
1135     {
1136       for(int i=1;i<nbOfElements;i++)
1137         {
1138           if(ptr[i]>(ref-absEps))
1139             return false;
1140           ref=ptr[i];
1141         }
1142       return true;
1143     }
1144 }
1145
1146 /*!
1147  * Returns a textual and human readable representation of \a this instance of
1148  * DataArrayDouble. This text is shown when a DataArrayDouble is printed in Python.
1149  *  \return std::string - text describing \a this DataArrayDouble.
1150  */
1151 std::string DataArrayDouble::repr() const
1152 {
1153   std::ostringstream ret;
1154   reprStream(ret);
1155   return ret.str();
1156 }
1157
1158 std::string DataArrayDouble::reprZip() const
1159 {
1160   std::ostringstream ret;
1161   reprZipStream(ret);
1162   return ret.str();
1163 }
1164
1165 void DataArrayDouble::writeVTK(std::ostream& ofs, int indent, const std::string& nameInFile, DataArrayByte *byteArr) const
1166 {
1167   static const char SPACE[4]={' ',' ',' ',' '};
1168   checkAllocated();
1169   std::string idt(indent,' ');
1170   ofs.precision(17);
1171   ofs << idt << "<DataArray type=\"Float32\" Name=\"" << nameInFile << "\" NumberOfComponents=\"" << getNumberOfComponents() << "\"";
1172   //
1173   bool areAllEmpty(true);
1174   for(std::vector<std::string>::const_iterator it=_info_on_compo.begin();it!=_info_on_compo.end();it++)
1175     if(!(*it).empty())
1176       areAllEmpty=false;
1177   if(!areAllEmpty)
1178     for(std::size_t i=0;i<_info_on_compo.size();i++)
1179       ofs << " ComponentName" << i << "=\"" << _info_on_compo[i] << "\"";
1180   //
1181   if(byteArr)
1182     {
1183       ofs << " format=\"appended\" offset=\"" << byteArr->getNumberOfTuples() << "\">";
1184       INTERP_KERNEL::AutoPtr<float> tmp(new float[getNbOfElems()]);
1185       float *pt(tmp);
1186       // to make Visual C++ happy : instead of std::copy(begin(),end(),(float *)tmp);
1187       for(const double *src=begin();src!=end();src++,pt++)
1188         *pt=float(*src);
1189       const char *data(reinterpret_cast<const char *>((float *)tmp));
1190       std::size_t sz(getNbOfElems()*sizeof(float));
1191       byteArr->insertAtTheEnd(data,data+sz);
1192       byteArr->insertAtTheEnd(SPACE,SPACE+4);
1193     }
1194   else
1195     {
1196       ofs << " RangeMin=\"" << getMinValueInArray() << "\" RangeMax=\"" << getMaxValueInArray() << "\" format=\"ascii\">\n" << idt;
1197       std::copy(begin(),end(),std::ostream_iterator<double>(ofs," "));
1198     }
1199   ofs << std::endl << idt << "</DataArray>\n";
1200 }
1201
1202 void DataArrayDouble::reprStream(std::ostream& stream) const
1203 {
1204   stream << "Name of double array : \"" << _name << "\"\n";
1205   reprWithoutNameStream(stream);
1206 }
1207
1208 void DataArrayDouble::reprZipStream(std::ostream& stream) const
1209 {
1210   stream << "Name of double array : \"" << _name << "\"\n";
1211   reprZipWithoutNameStream(stream);
1212 }
1213
1214 void DataArrayDouble::reprWithoutNameStream(std::ostream& stream) const
1215 {
1216   DataArray::reprWithoutNameStream(stream);
1217   stream.precision(17);
1218   _mem.repr(getNumberOfComponents(),stream);
1219 }
1220
1221 void DataArrayDouble::reprZipWithoutNameStream(std::ostream& stream) const
1222 {
1223   DataArray::reprWithoutNameStream(stream);
1224   stream.precision(17);
1225   _mem.reprZip(getNumberOfComponents(),stream);
1226 }
1227
1228 void DataArrayDouble::reprCppStream(const std::string& varName, std::ostream& stream) const
1229 {
1230   int nbTuples=getNumberOfTuples(),nbComp=getNumberOfComponents();
1231   const double *data=getConstPointer();
1232   stream.precision(17);
1233   stream << "DataArrayDouble *" << varName << "=DataArrayDouble::New();" << std::endl;
1234   if(nbTuples*nbComp>=1)
1235     {
1236       stream << "const double " << varName << "Data[" << nbTuples*nbComp << "]={";
1237       std::copy(data,data+nbTuples*nbComp-1,std::ostream_iterator<double>(stream,","));
1238       stream << data[nbTuples*nbComp-1] << "};" << std::endl;
1239       stream << varName << "->useArray(" << varName << "Data,false,CPP_DEALLOC," << nbTuples << "," << nbComp << ");" << std::endl;
1240     }
1241   else
1242     stream << varName << "->alloc(" << nbTuples << "," << nbComp << ");" << std::endl;
1243   stream << varName << "->setName(\"" << getName() << "\");" << std::endl;
1244 }
1245
1246 /*!
1247  * Method that gives a quick overvien of \a this for python.
1248  */
1249 void DataArrayDouble::reprQuickOverview(std::ostream& stream) const
1250 {
1251   static const std::size_t MAX_NB_OF_BYTE_IN_REPR=300;
1252   stream << "DataArrayDouble C++ instance at " << this << ". ";
1253   if(isAllocated())
1254     {
1255       int nbOfCompo=(int)_info_on_compo.size();
1256       if(nbOfCompo>=1)
1257         {
1258           int nbOfTuples=getNumberOfTuples();
1259           stream << "Number of tuples : " << nbOfTuples << ". Number of components : " << nbOfCompo << "." << std::endl;
1260           reprQuickOverviewData(stream,MAX_NB_OF_BYTE_IN_REPR);
1261         }
1262       else
1263         stream << "Number of components : 0.";
1264     }
1265   else
1266     stream << "*** No data allocated ****";
1267 }
1268
1269 void DataArrayDouble::reprQuickOverviewData(std::ostream& stream, std::size_t maxNbOfByteInRepr) const
1270 {
1271   const double *data=begin();
1272   int nbOfTuples=getNumberOfTuples();
1273   int nbOfCompo=(int)_info_on_compo.size();
1274   std::ostringstream oss2; oss2 << "[";
1275   oss2.precision(17);
1276   std::string oss2Str(oss2.str());
1277   bool isFinished=true;
1278   for(int i=0;i<nbOfTuples && isFinished;i++)
1279     {
1280       if(nbOfCompo>1)
1281         {
1282           oss2 << "(";
1283           for(int j=0;j<nbOfCompo;j++,data++)
1284             {
1285               oss2 << *data;
1286               if(j!=nbOfCompo-1) oss2 << ", ";
1287             }
1288           oss2 << ")";
1289         }
1290       else
1291         oss2 << *data++;
1292       if(i!=nbOfTuples-1) oss2 << ", ";
1293       std::string oss3Str(oss2.str());
1294       if(oss3Str.length()<maxNbOfByteInRepr)
1295         oss2Str=oss3Str;
1296       else
1297         isFinished=false;
1298     }
1299   stream << oss2Str;
1300   if(!isFinished)
1301     stream << "... ";
1302   stream << "]";
1303 }
1304
1305 /*!
1306  * Equivalent to DataArrayDouble::isEqual except that if false the reason of
1307  * mismatch is given.
1308  * 
1309  * \param [in] other the instance to be compared with \a this
1310  * \param [in] prec the precision to compare numeric data of the arrays.
1311  * \param [out] reason In case of inequality returns the reason.
1312  * \sa DataArrayDouble::isEqual
1313  */
1314 bool DataArrayDouble::isEqualIfNotWhy(const DataArrayDouble& other, double prec, std::string& reason) const
1315 {
1316   if(!areInfoEqualsIfNotWhy(other,reason))
1317     return false;
1318   return _mem.isEqual(other._mem,prec,reason);
1319 }
1320
1321 /*!
1322  * Checks if \a this and another DataArrayDouble are fully equal. For more info see
1323  * \ref MEDCouplingArrayBasicsCompare.
1324  *  \param [in] other - an instance of DataArrayDouble to compare with \a this one.
1325  *  \param [in] prec - precision value to compare numeric data of the arrays.
1326  *  \return bool - \a true if the two arrays are equal, \a false else.
1327  */
1328 bool DataArrayDouble::isEqual(const DataArrayDouble& other, double prec) const
1329 {
1330   std::string tmp;
1331   return isEqualIfNotWhy(other,prec,tmp);
1332 }
1333
1334 /*!
1335  * Checks if values of \a this and another DataArrayDouble are equal. For more info see
1336  * \ref MEDCouplingArrayBasicsCompare.
1337  *  \param [in] other - an instance of DataArrayDouble to compare with \a this one.
1338  *  \param [in] prec - precision value to compare numeric data of the arrays.
1339  *  \return bool - \a true if the values of two arrays are equal, \a false else.
1340  */
1341 bool DataArrayDouble::isEqualWithoutConsideringStr(const DataArrayDouble& other, double prec) const
1342 {
1343   std::string tmp;
1344   return _mem.isEqual(other._mem,prec,tmp);
1345 }
1346
1347 /*!
1348  * Changes number of tuples in the array. If the new number of tuples is smaller
1349  * than the current number the array is truncated, otherwise the array is extended.
1350  *  \param [in] nbOfTuples - new number of tuples. 
1351  *  \throw If \a this is not allocated.
1352  *  \throw If \a nbOfTuples is negative.
1353  */
1354 void DataArrayDouble::reAlloc(int nbOfTuples)
1355 {
1356   if(nbOfTuples<0)
1357     throw INTERP_KERNEL::Exception("DataArrayDouble::reAlloc : input new number of tuples should be >=0 !");
1358   checkAllocated();
1359   _mem.reAlloc(getNumberOfComponents()*(std::size_t)nbOfTuples);
1360   declareAsNew();
1361 }
1362
1363 /*!
1364  * Creates a new DataArrayInt and assigns all (textual and numerical) data of \a this
1365  * array to the new one.
1366  *  \return DataArrayInt * - the new instance of DataArrayInt.
1367  */
1368 DataArrayInt *DataArrayDouble::convertToIntArr() const
1369 {
1370   DataArrayInt *ret=DataArrayInt::New();
1371   ret->alloc(getNumberOfTuples(),getNumberOfComponents());
1372   int *dest=ret->getPointer();
1373   // to make Visual C++ happy : instead of std::size_t nbOfVals=getNbOfElems(); std::copy(src,src+nbOfVals,dest);
1374   for(const double *src=begin();src!=end();src++,dest++)
1375     *dest=(int)*src;
1376   ret->copyStringInfoFrom(*this);
1377   return ret;
1378 }
1379
1380 /*!
1381  * Returns a new DataArrayDouble holding the same values as \a this array but differently
1382  * arranged in memory. If \a this array holds 2 components of 3 values:
1383  * \f$ x_0,x_1,x_2,y_0,y_1,y_2 \f$, then the result array holds these values arranged
1384  * as follows: \f$ x_0,y_0,x_1,y_1,x_2,y_2 \f$.
1385  *  \warning Do not confuse this method with transpose()!
1386  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1387  *          is to delete using decrRef() as it is no more needed.
1388  *  \throw If \a this is not allocated.
1389  */
1390 DataArrayDouble *DataArrayDouble::fromNoInterlace() const
1391 {
1392   if(_mem.isNull())
1393     throw INTERP_KERNEL::Exception("DataArrayDouble::fromNoInterlace : Not defined array !");
1394   double *tab=_mem.fromNoInterlace(getNumberOfComponents());
1395   DataArrayDouble *ret=DataArrayDouble::New();
1396   ret->useArray(tab,true,C_DEALLOC,getNumberOfTuples(),getNumberOfComponents());
1397   return ret;
1398 }
1399
1400 /*!
1401  * Returns a new DataArrayDouble holding the same values as \a this array but differently
1402  * arranged in memory. If \a this array holds 2 components of 3 values:
1403  * \f$ x_0,y_0,x_1,y_1,x_2,y_2 \f$, then the result array holds these values arranged
1404  * as follows: \f$ x_0,x_1,x_2,y_0,y_1,y_2 \f$.
1405  *  \warning Do not confuse this method with transpose()!
1406  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1407  *          is to delete using decrRef() as it is no more needed.
1408  *  \throw If \a this is not allocated.
1409  */
1410 DataArrayDouble *DataArrayDouble::toNoInterlace() const
1411 {
1412   if(_mem.isNull())
1413     throw INTERP_KERNEL::Exception("DataArrayDouble::toNoInterlace : Not defined array !");
1414   double *tab=_mem.toNoInterlace(getNumberOfComponents());
1415   DataArrayDouble *ret=DataArrayDouble::New();
1416   ret->useArray(tab,true,C_DEALLOC,getNumberOfTuples(),getNumberOfComponents());
1417   return ret;
1418 }
1419
1420 /*!
1421  * Permutes values of \a this array as required by \a old2New array. The values are
1422  * permuted so that \c new[ \a old2New[ i ]] = \c old[ i ]. Number of tuples remains
1423  * the same as in \this one.
1424  * If a permutation reduction is needed, substr() or selectByTupleId() should be used.
1425  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
1426  *  \param [in] old2New - C array of length equal to \a this->getNumberOfTuples()
1427  *     giving a new position for i-th old value.
1428  */
1429 void DataArrayDouble::renumberInPlace(const int *old2New)
1430 {
1431   checkAllocated();
1432   int nbTuples=getNumberOfTuples();
1433   int nbOfCompo=getNumberOfComponents();
1434   double *tmp=new double[nbTuples*nbOfCompo];
1435   const double *iptr=getConstPointer();
1436   for(int i=0;i<nbTuples;i++)
1437     {
1438       int v=old2New[i];
1439       if(v>=0 && v<nbTuples)
1440         std::copy(iptr+nbOfCompo*i,iptr+nbOfCompo*(i+1),tmp+nbOfCompo*v);
1441       else
1442         {
1443           std::ostringstream oss; oss << "DataArrayDouble::renumberInPlace : At place #" << i << " value is " << v << " ! Should be in [0," << nbTuples << ") !";
1444           throw INTERP_KERNEL::Exception(oss.str().c_str());
1445         }
1446     }
1447   std::copy(tmp,tmp+nbTuples*nbOfCompo,getPointer());
1448   delete [] tmp;
1449   declareAsNew();
1450 }
1451
1452 /*!
1453  * Permutes values of \a this array as required by \a new2Old array. The values are
1454  * permuted so that \c new[ i ] = \c old[ \a new2Old[ i ]]. Number of tuples remains
1455  * the same as in \this one.
1456  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
1457  *  \param [in] new2Old - C array of length equal to \a this->getNumberOfTuples()
1458  *     giving a previous position of i-th new value.
1459  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1460  *          is to delete using decrRef() as it is no more needed.
1461  */
1462 void DataArrayDouble::renumberInPlaceR(const int *new2Old)
1463 {
1464   checkAllocated();
1465   int nbTuples=getNumberOfTuples();
1466   int nbOfCompo=getNumberOfComponents();
1467   double *tmp=new double[nbTuples*nbOfCompo];
1468   const double *iptr=getConstPointer();
1469   for(int i=0;i<nbTuples;i++)
1470     {
1471       int v=new2Old[i];
1472       if(v>=0 && v<nbTuples)
1473         std::copy(iptr+nbOfCompo*v,iptr+nbOfCompo*(v+1),tmp+nbOfCompo*i);
1474       else
1475         {
1476           std::ostringstream oss; oss << "DataArrayDouble::renumberInPlaceR : At place #" << i << " value is " << v << " ! Should be in [0," << nbTuples << ") !";
1477           throw INTERP_KERNEL::Exception(oss.str().c_str());
1478         }
1479     }
1480   std::copy(tmp,tmp+nbTuples*nbOfCompo,getPointer());
1481   delete [] tmp;
1482   declareAsNew();
1483 }
1484
1485 /*!
1486  * Returns a copy of \a this array with values permuted as required by \a old2New array.
1487  * The values are permuted so that  \c new[ \a old2New[ i ]] = \c old[ i ].
1488  * Number of tuples in the result array remains the same as in \this one.
1489  * If a permutation reduction is needed, renumberAndReduce() should be used.
1490  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
1491  *  \param [in] old2New - C array of length equal to \a this->getNumberOfTuples()
1492  *          giving a new position for i-th old value.
1493  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1494  *          is to delete using decrRef() as it is no more needed.
1495  *  \throw If \a this is not allocated.
1496  */
1497 DataArrayDouble *DataArrayDouble::renumber(const int *old2New) const
1498 {
1499   checkAllocated();
1500   int nbTuples=getNumberOfTuples();
1501   int nbOfCompo=getNumberOfComponents();
1502   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
1503   ret->alloc(nbTuples,nbOfCompo);
1504   ret->copyStringInfoFrom(*this);
1505   const double *iptr=getConstPointer();
1506   double *optr=ret->getPointer();
1507   for(int i=0;i<nbTuples;i++)
1508     std::copy(iptr+nbOfCompo*i,iptr+nbOfCompo*(i+1),optr+nbOfCompo*old2New[i]);
1509   ret->copyStringInfoFrom(*this);
1510   return ret.retn();
1511 }
1512
1513 /*!
1514  * Returns a copy of \a this array with values permuted as required by \a new2Old array.
1515  * The values are permuted so that  \c new[ i ] = \c old[ \a new2Old[ i ]]. Number of
1516  * tuples in the result array remains the same as in \this one.
1517  * If a permutation reduction is needed, substr() or selectByTupleId() should be used.
1518  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
1519  *  \param [in] new2Old - C array of length equal to \a this->getNumberOfTuples()
1520  *     giving a previous position of i-th new value.
1521  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1522  *          is to delete using decrRef() as it is no more needed.
1523  */
1524 DataArrayDouble *DataArrayDouble::renumberR(const int *new2Old) const
1525 {
1526   checkAllocated();
1527   int nbTuples=getNumberOfTuples();
1528   int nbOfCompo=getNumberOfComponents();
1529   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
1530   ret->alloc(nbTuples,nbOfCompo);
1531   ret->copyStringInfoFrom(*this);
1532   const double *iptr=getConstPointer();
1533   double *optr=ret->getPointer();
1534   for(int i=0;i<nbTuples;i++)
1535     std::copy(iptr+nbOfCompo*new2Old[i],iptr+nbOfCompo*(new2Old[i]+1),optr+i*nbOfCompo);
1536   ret->copyStringInfoFrom(*this);
1537   return ret.retn();
1538 }
1539
1540 /*!
1541  * Returns a shorten and permuted copy of \a this array. The new DataArrayDouble is
1542  * of size \a newNbOfTuple and it's values are permuted as required by \a old2New array.
1543  * The values are permuted so that  \c new[ \a old2New[ i ]] = \c old[ i ] for all
1544  * \a old2New[ i ] >= 0. In other words every i-th tuple in \a this array, for which 
1545  * \a old2New[ i ] is negative, is missing from the result array.
1546  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
1547  *  \param [in] old2New - C array of length equal to \a this->getNumberOfTuples()
1548  *     giving a new position for i-th old tuple and giving negative position for
1549  *     for i-th old tuple that should be omitted.
1550  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1551  *          is to delete using decrRef() as it is no more needed.
1552  */
1553 DataArrayDouble *DataArrayDouble::renumberAndReduce(const int *old2New, int newNbOfTuple) const
1554 {
1555   checkAllocated();
1556   int nbTuples=getNumberOfTuples();
1557   int nbOfCompo=getNumberOfComponents();
1558   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
1559   ret->alloc(newNbOfTuple,nbOfCompo);
1560   const double *iptr=getConstPointer();
1561   double *optr=ret->getPointer();
1562   for(int i=0;i<nbTuples;i++)
1563     {
1564       int w=old2New[i];
1565       if(w>=0)
1566         std::copy(iptr+i*nbOfCompo,iptr+(i+1)*nbOfCompo,optr+w*nbOfCompo);
1567     }
1568   ret->copyStringInfoFrom(*this);
1569   return ret.retn();
1570 }
1571
1572 /*!
1573  * Returns a shorten and permuted copy of \a this array. The new DataArrayDouble is
1574  * of size \a new2OldEnd - \a new2OldBg and it's values are permuted as required by
1575  * \a new2OldBg array.
1576  * The values are permuted so that  \c new[ i ] = \c old[ \a new2OldBg[ i ]].
1577  * This method is equivalent to renumberAndReduce() except that convention in input is
1578  * \c new2old and \b not \c old2new.
1579  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
1580  *  \param [in] new2OldBg - pointer to the beginning of a permutation array that gives a
1581  *              tuple index in \a this array to fill the i-th tuple in the new array.
1582  *  \param [in] new2OldEnd - specifies the end of the permutation array that starts at
1583  *              \a new2OldBg, so that pointer to a tuple index (\a pi) varies as this:
1584  *              \a new2OldBg <= \a pi < \a new2OldEnd.
1585  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1586  *          is to delete using decrRef() as it is no more needed.
1587  */
1588 DataArrayDouble *DataArrayDouble::selectByTupleId(const int *new2OldBg, const int *new2OldEnd) const
1589 {
1590   checkAllocated();
1591   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
1592   int nbComp=getNumberOfComponents();
1593   ret->alloc((int)std::distance(new2OldBg,new2OldEnd),nbComp);
1594   ret->copyStringInfoFrom(*this);
1595   double *pt=ret->getPointer();
1596   const double *srcPt=getConstPointer();
1597   int i=0;
1598   for(const int *w=new2OldBg;w!=new2OldEnd;w++,i++)
1599     std::copy(srcPt+(*w)*nbComp,srcPt+((*w)+1)*nbComp,pt+i*nbComp);
1600   ret->copyStringInfoFrom(*this);
1601   return ret.retn();
1602 }
1603
1604 /*!
1605  * Returns a shorten and permuted copy of \a this array. The new DataArrayDouble is
1606  * of size \a new2OldEnd - \a new2OldBg and it's values are permuted as required by
1607  * \a new2OldBg array.
1608  * The values are permuted so that  \c new[ i ] = \c old[ \a new2OldBg[ i ]].
1609  * This method is equivalent to renumberAndReduce() except that convention in input is
1610  * \c new2old and \b not \c old2new.
1611  * This method is equivalent to selectByTupleId() except that it prevents coping data
1612  * from behind the end of \a this array.
1613  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
1614  *  \param [in] new2OldBg - pointer to the beginning of a permutation array that gives a
1615  *              tuple index in \a this array to fill the i-th tuple in the new array.
1616  *  \param [in] new2OldEnd - specifies the end of the permutation array that starts at
1617  *              \a new2OldBg, so that pointer to a tuple index (\a pi) varies as this:
1618  *              \a new2OldBg <= \a pi < \a new2OldEnd.
1619  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1620  *          is to delete using decrRef() as it is no more needed.
1621  *  \throw If \a new2OldEnd - \a new2OldBg > \a this->getNumberOfTuples().
1622  */
1623 DataArrayDouble *DataArrayDouble::selectByTupleIdSafe(const int *new2OldBg, const int *new2OldEnd) const
1624 {
1625   checkAllocated();
1626   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
1627   int nbComp=getNumberOfComponents();
1628   int oldNbOfTuples=getNumberOfTuples();
1629   ret->alloc((int)std::distance(new2OldBg,new2OldEnd),nbComp);
1630   ret->copyStringInfoFrom(*this);
1631   double *pt=ret->getPointer();
1632   const double *srcPt=getConstPointer();
1633   int i=0;
1634   for(const int *w=new2OldBg;w!=new2OldEnd;w++,i++)
1635     if(*w>=0 && *w<oldNbOfTuples)
1636       std::copy(srcPt+(*w)*nbComp,srcPt+((*w)+1)*nbComp,pt+i*nbComp);
1637     else
1638       throw INTERP_KERNEL::Exception("DataArrayDouble::selectByTupleIdSafe : some ids has been detected to be out of [0,this->getNumberOfTuples) !");
1639   ret->copyStringInfoFrom(*this);
1640   return ret.retn();
1641 }
1642
1643 /*!
1644  * Returns a shorten copy of \a this array. The new DataArrayDouble contains every
1645  * (\a bg + \c i * \a step)-th tuple of \a this array located before the \a end2-th
1646  * tuple. Indices of the selected tuples are the same as ones returned by the Python
1647  * command \c range( \a bg, \a end2, \a step ).
1648  * This method is equivalent to selectByTupleIdSafe() except that the input array is
1649  * not constructed explicitly.
1650  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
1651  *  \param [in] bg - index of the first tuple to copy from \a this array.
1652  *  \param [in] end2 - index of the tuple before which the tuples to copy are located.
1653  *  \param [in] step - index increment to get index of the next tuple to copy.
1654  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1655  *          is to delete using decrRef() as it is no more needed.
1656  *  \sa DataArrayDouble::substr.
1657  */
1658 DataArrayDouble *DataArrayDouble::selectByTupleId2(int bg, int end2, int step) const
1659 {
1660   checkAllocated();
1661   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
1662   int nbComp=getNumberOfComponents();
1663   int newNbOfTuples=GetNumberOfItemGivenBESRelative(bg,end2,step,"DataArrayDouble::selectByTupleId2 : ");
1664   ret->alloc(newNbOfTuples,nbComp);
1665   double *pt=ret->getPointer();
1666   const double *srcPt=getConstPointer()+bg*nbComp;
1667   for(int i=0;i<newNbOfTuples;i++,srcPt+=step*nbComp)
1668     std::copy(srcPt,srcPt+nbComp,pt+i*nbComp);
1669   ret->copyStringInfoFrom(*this);
1670   return ret.retn();
1671 }
1672
1673 /*!
1674  * Returns a shorten copy of \a this array. The new DataArrayDouble contains ranges
1675  * of tuples specified by \a ranges parameter.
1676  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
1677  *  \param [in] ranges - std::vector of std::pair's each of which defines a range
1678  *              of tuples in [\c begin,\c end) format.
1679  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1680  *          is to delete using decrRef() as it is no more needed.
1681  *  \throw If \a end < \a begin.
1682  *  \throw If \a end > \a this->getNumberOfTuples().
1683  *  \throw If \a this is not allocated.
1684  */
1685 DataArray *DataArrayDouble::selectByTupleRanges(const std::vector<std::pair<int,int> >& ranges) const
1686 {
1687   checkAllocated();
1688   int nbOfComp=getNumberOfComponents();
1689   int nbOfTuplesThis=getNumberOfTuples();
1690   if(ranges.empty())
1691     {
1692       DataArrayDouble *ret=DataArrayDouble::New();
1693       ret->alloc(0,nbOfComp);
1694       ret->copyStringInfoFrom(*this);
1695       return ret;
1696     }
1697   int ref=ranges.front().first;
1698   int nbOfTuples=0;
1699   bool isIncreasing=true;
1700   for(std::vector<std::pair<int,int> >::const_iterator it=ranges.begin();it!=ranges.end();it++)
1701     {
1702       if((*it).first<=(*it).second)
1703         {
1704           if((*it).first>=0 && (*it).second<=nbOfTuplesThis)
1705             {
1706               nbOfTuples+=(*it).second-(*it).first;
1707               if(isIncreasing)
1708                 isIncreasing=ref<=(*it).first;
1709               ref=(*it).second;
1710             }
1711           else
1712             {
1713               std::ostringstream oss; oss << "DataArrayDouble::selectByTupleRanges : on range #" << std::distance(ranges.begin(),it);
1714               oss << " (" << (*it).first << "," << (*it).second << ") is greater than number of tuples of this :" << nbOfTuples << " !";
1715               throw INTERP_KERNEL::Exception(oss.str().c_str());
1716             }
1717         }
1718       else
1719         {
1720           std::ostringstream oss; oss << "DataArrayDouble::selectByTupleRanges : on range #" << std::distance(ranges.begin(),it);
1721           oss << " (" << (*it).first << "," << (*it).second << ") end is before begin !";
1722           throw INTERP_KERNEL::Exception(oss.str().c_str());
1723         }
1724     }
1725   if(isIncreasing && nbOfTuplesThis==nbOfTuples)
1726     return deepCpy();
1727   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
1728   ret->alloc(nbOfTuples,nbOfComp);
1729   ret->copyStringInfoFrom(*this);
1730   const double *src=getConstPointer();
1731   double *work=ret->getPointer();
1732   for(std::vector<std::pair<int,int> >::const_iterator it=ranges.begin();it!=ranges.end();it++)
1733     work=std::copy(src+(*it).first*nbOfComp,src+(*it).second*nbOfComp,work);
1734   return ret.retn();
1735 }
1736
1737 /*!
1738  * Returns a shorten copy of \a this array. The new DataArrayDouble contains all
1739  * tuples starting from the \a tupleIdBg-th tuple and including all tuples located before
1740  * the \a tupleIdEnd-th one. This methods has a similar behavior as std::string::substr().
1741  * This method is a specialization of selectByTupleId2().
1742  *  \param [in] tupleIdBg - index of the first tuple to copy from \a this array.
1743  *  \param [in] tupleIdEnd - index of the tuple before which the tuples to copy are located.
1744  *          If \a tupleIdEnd == -1, all the tuples till the end of \a this array are copied.
1745  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1746  *          is to delete using decrRef() as it is no more needed.
1747  *  \throw If \a tupleIdBg < 0.
1748  *  \throw If \a tupleIdBg > \a this->getNumberOfTuples().
1749     \throw If \a tupleIdEnd != -1 && \a tupleIdEnd < \a this->getNumberOfTuples().
1750  *  \sa DataArrayDouble::selectByTupleId2
1751  */
1752 DataArrayDouble *DataArrayDouble::substr(int tupleIdBg, int tupleIdEnd) const
1753 {
1754   checkAllocated();
1755   int nbt=getNumberOfTuples();
1756   if(tupleIdBg<0)
1757     throw INTERP_KERNEL::Exception("DataArrayDouble::substr : The tupleIdBg parameter must be greater than 0 !");
1758   if(tupleIdBg>nbt)
1759     throw INTERP_KERNEL::Exception("DataArrayDouble::substr : The tupleIdBg parameter is greater than number of tuples !");
1760   int trueEnd=tupleIdEnd;
1761   if(tupleIdEnd!=-1)
1762     {
1763       if(tupleIdEnd>nbt)
1764         throw INTERP_KERNEL::Exception("DataArrayDouble::substr : The tupleIdBg parameter is greater or equal than number of tuples !");
1765     }
1766   else
1767     trueEnd=nbt;
1768   int nbComp=getNumberOfComponents();
1769   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
1770   ret->alloc(trueEnd-tupleIdBg,nbComp);
1771   ret->copyStringInfoFrom(*this);
1772   std::copy(getConstPointer()+tupleIdBg*nbComp,getConstPointer()+trueEnd*nbComp,ret->getPointer());
1773   return ret.retn();
1774 }
1775
1776 /*!
1777  * Returns a shorten or extended copy of \a this array. If \a newNbOfComp is less
1778  * than \a this->getNumberOfComponents() then the result array is shorten as each tuple
1779  * is truncated to have \a newNbOfComp components, keeping first components. If \a
1780  * newNbOfComp is more than \a this->getNumberOfComponents() then the result array is
1781  * expanded as each tuple is populated with \a dftValue to have \a newNbOfComp
1782  * components.  
1783  *  \param [in] newNbOfComp - number of components for the new array to have.
1784  *  \param [in] dftValue - value assigned to new values added to the new array.
1785  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1786  *          is to delete using decrRef() as it is no more needed.
1787  *  \throw If \a this is not allocated.
1788  */
1789 DataArrayDouble *DataArrayDouble::changeNbOfComponents(int newNbOfComp, double dftValue) const
1790 {
1791   checkAllocated();
1792   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
1793   ret->alloc(getNumberOfTuples(),newNbOfComp);
1794   const double *oldc=getConstPointer();
1795   double *nc=ret->getPointer();
1796   int nbOfTuples=getNumberOfTuples();
1797   int oldNbOfComp=getNumberOfComponents();
1798   int dim=std::min(oldNbOfComp,newNbOfComp);
1799   for(int i=0;i<nbOfTuples;i++)
1800     {
1801       int j=0;
1802       for(;j<dim;j++)
1803         nc[newNbOfComp*i+j]=oldc[i*oldNbOfComp+j];
1804       for(;j<newNbOfComp;j++)
1805         nc[newNbOfComp*i+j]=dftValue;
1806     }
1807   ret->setName(getName());
1808   for(int i=0;i<dim;i++)
1809     ret->setInfoOnComponent(i,getInfoOnComponent(i));
1810   ret->setName(getName());
1811   return ret.retn();
1812 }
1813
1814 /*!
1815  * Changes the number of components within \a this array so that its raw data **does
1816  * not** change, instead splitting this data into tuples changes.
1817  *  \warning This method erases all (name and unit) component info set before!
1818  *  \param [in] newNbOfComp - number of components for \a this array to have.
1819  *  \throw If \a this is not allocated
1820  *  \throw If getNbOfElems() % \a newNbOfCompo != 0.
1821  *  \throw If \a newNbOfCompo is lower than 1.
1822  *  \throw If the rearrange method would lead to a number of tuples higher than 2147483647 (maximal capacity of int32 !).
1823  *  \warning This method erases all (name and unit) component info set before!
1824  */
1825 void DataArrayDouble::rearrange(int newNbOfCompo)
1826 {
1827   checkAllocated();
1828   if(newNbOfCompo<1)
1829     throw INTERP_KERNEL::Exception("DataArrayDouble::rearrange : input newNbOfCompo must be > 0 !");
1830   std::size_t nbOfElems=getNbOfElems();
1831   if(nbOfElems%newNbOfCompo!=0)
1832     throw INTERP_KERNEL::Exception("DataArrayDouble::rearrange : nbOfElems%newNbOfCompo!=0 !");
1833   if(nbOfElems/newNbOfCompo>(std::size_t)std::numeric_limits<int>::max())
1834     throw INTERP_KERNEL::Exception("DataArrayDouble::rearrange : the rearrangement leads to too high number of tuples (> 2147483647) !");
1835   _info_on_compo.clear();
1836   _info_on_compo.resize(newNbOfCompo);
1837   declareAsNew();
1838 }
1839
1840 /*!
1841  * Changes the number of components within \a this array to be equal to its number
1842  * of tuples, and inversely its number of tuples to become equal to its number of 
1843  * components. So that its raw data **does not** change, instead splitting this
1844  * data into tuples changes.
1845  *  \warning This method erases all (name and unit) component info set before!
1846  *  \warning Do not confuse this method with fromNoInterlace() and toNoInterlace()!
1847  *  \throw If \a this is not allocated.
1848  *  \sa rearrange()
1849  */
1850 void DataArrayDouble::transpose()
1851 {
1852   checkAllocated();
1853   int nbOfTuples=getNumberOfTuples();
1854   rearrange(nbOfTuples);
1855 }
1856
1857 /*!
1858  * Returns a copy of \a this array composed of selected components.
1859  * The new DataArrayDouble has the same number of tuples but includes components
1860  * specified by \a compoIds parameter. So that getNbOfElems() of the result array
1861  * can be either less, same or more than \a this->getNbOfElems().
1862  *  \param [in] compoIds - sequence of zero based indices of components to include
1863  *              into the new array.
1864  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1865  *          is to delete using decrRef() as it is no more needed.
1866  *  \throw If \a this is not allocated.
1867  *  \throw If a component index (\a i) is not valid: 
1868  *         \a i < 0 || \a i >= \a this->getNumberOfComponents().
1869  *
1870  *  \if ENABLE_EXAMPLES
1871  *  \ref py_mcdataarraydouble_KeepSelectedComponents "Here is a Python example".
1872  *  \endif
1873  */
1874 DataArrayDouble *DataArrayDouble::keepSelectedComponents(const std::vector<int>& compoIds) const
1875 {
1876   checkAllocated();
1877   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret(DataArrayDouble::New());
1878   std::size_t newNbOfCompo=compoIds.size();
1879   int oldNbOfCompo=getNumberOfComponents();
1880   for(std::vector<int>::const_iterator it=compoIds.begin();it!=compoIds.end();it++)
1881     if((*it)<0 || (*it)>=oldNbOfCompo)
1882       {
1883         std::ostringstream oss; oss << "DataArrayDouble::keepSelectedComponents : invalid requested component : " << *it << " whereas it should be in [0," << oldNbOfCompo << ") !";
1884         throw INTERP_KERNEL::Exception(oss.str().c_str());
1885       }
1886   int nbOfTuples=getNumberOfTuples();
1887   ret->alloc(nbOfTuples,(int)newNbOfCompo);
1888   ret->copyPartOfStringInfoFrom(*this,compoIds);
1889   const double *oldc=getConstPointer();
1890   double *nc=ret->getPointer();
1891   for(int i=0;i<nbOfTuples;i++)
1892     for(std::size_t j=0;j<newNbOfCompo;j++,nc++)
1893       *nc=oldc[i*oldNbOfCompo+compoIds[j]];
1894   return ret.retn();
1895 }
1896
1897 /*!
1898  * Appends components of another array to components of \a this one, tuple by tuple.
1899  * So that the number of tuples of \a this array remains the same and the number of 
1900  * components increases.
1901  *  \param [in] other - the DataArrayDouble to append to \a this one.
1902  *  \throw If \a this is not allocated.
1903  *  \throw If \a this and \a other arrays have different number of tuples.
1904  *
1905  *  \if ENABLE_EXAMPLES
1906  *  \ref cpp_mcdataarraydouble_meldwith "Here is a C++ example".
1907  *
1908  *  \ref py_mcdataarraydouble_meldwith "Here is a Python example".
1909  *  \endif
1910  */
1911 void DataArrayDouble::meldWith(const DataArrayDouble *other)
1912 {
1913   checkAllocated();
1914   other->checkAllocated();
1915   int nbOfTuples=getNumberOfTuples();
1916   if(nbOfTuples!=other->getNumberOfTuples())
1917     throw INTERP_KERNEL::Exception("DataArrayDouble::meldWith : mismatch of number of tuples !");
1918   int nbOfComp1=getNumberOfComponents();
1919   int nbOfComp2=other->getNumberOfComponents();
1920   double *newArr=(double *)malloc((nbOfTuples*(nbOfComp1+nbOfComp2))*sizeof(double));
1921   double *w=newArr;
1922   const double *inp1=getConstPointer();
1923   const double *inp2=other->getConstPointer();
1924   for(int i=0;i<nbOfTuples;i++,inp1+=nbOfComp1,inp2+=nbOfComp2)
1925     {
1926       w=std::copy(inp1,inp1+nbOfComp1,w);
1927       w=std::copy(inp2,inp2+nbOfComp2,w);
1928     }
1929   useArray(newArr,true,C_DEALLOC,nbOfTuples,nbOfComp1+nbOfComp2);
1930   std::vector<int> compIds(nbOfComp2);
1931   for(int i=0;i<nbOfComp2;i++)
1932     compIds[i]=nbOfComp1+i;
1933   copyPartOfStringInfoFrom2(compIds,*other);
1934 }
1935
1936 /*!
1937  * This method checks that all tuples in \a other are in \a this.
1938  * If true, the output param \a tupleIds contains the tuples ids of \a this that correspond to tupes in \a this.
1939  * 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.
1940  *
1941  * \param [in] other - the array having the same number of components than \a this.
1942  * \param [out] tupleIds - the tuple ids containing the same number of tuples than \a other has.
1943  * \sa DataArrayDouble::findCommonTuples
1944  */
1945 bool DataArrayDouble::areIncludedInMe(const DataArrayDouble *other, double prec, DataArrayInt *&tupleIds) const
1946 {
1947   if(!other)
1948     throw INTERP_KERNEL::Exception("DataArrayDouble::areIncludedInMe : input array is NULL !");
1949   checkAllocated(); other->checkAllocated();
1950   if(getNumberOfComponents()!=other->getNumberOfComponents())
1951     throw INTERP_KERNEL::Exception("DataArrayDouble::areIncludedInMe : the number of components does not match !");
1952   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> a=DataArrayDouble::Aggregate(this,other);
1953   DataArrayInt *c=0,*ci=0;
1954   a->findCommonTuples(prec,getNumberOfTuples(),c,ci);
1955   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cSafe(c),ciSafe(ci);
1956   int newNbOfTuples=-1;
1957   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ids=DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2(a->getNumberOfTuples(),c->begin(),ci->begin(),ci->end(),newNbOfTuples);
1958   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret1=ids->selectByTupleId2(getNumberOfTuples(),a->getNumberOfTuples(),1);
1959   tupleIds=ret1.retn();
1960   return newNbOfTuples==getNumberOfTuples();
1961 }
1962
1963 /*!
1964  * Searches for tuples coincident within \a prec tolerance. Each tuple is considered
1965  * as coordinates of a point in getNumberOfComponents()-dimensional space. The
1966  * distance separating two points is computed with the infinite norm.
1967  *
1968  * Indices of coincident tuples are stored in output arrays.
1969  * A pair of arrays (\a comm, \a commIndex) is called "Surjective Format 2".
1970  *
1971  * This method is typically used by MEDCouplingPointSet::findCommonNodes() and
1972  * MEDCouplingUMesh::mergeNodes().
1973  *  \param [in] prec - minimal absolute distance between two tuples (infinite norm) at which they are
1974  *              considered not coincident.
1975  *  \param [in] limitTupleId - limit tuple id. If all tuples within a group of coincident
1976  *              tuples have id strictly lower than \a limitTupleId then they are not returned.
1977  *  \param [out] comm - the array holding ids (== indices) of coincident tuples. 
1978  *               \a comm->getNumberOfComponents() == 1. 
1979  *               \a comm->getNumberOfTuples() == \a commIndex->back().
1980  *  \param [out] commIndex - the array dividing all indices stored in \a comm into
1981  *               groups of (indices of) coincident tuples. Its every value is a tuple
1982  *               index where a next group of tuples begins. For example the second
1983  *               group of tuples in \a comm is described by following range of indices:
1984  *               [ \a commIndex[1], \a commIndex[2] ). \a commIndex->getNumberOfTuples()-1
1985  *               gives the number of groups of coincident tuples.
1986  *  \throw If \a this is not allocated.
1987  *  \throw If the number of components is not in [1,2,3,4].
1988  *
1989  *  \if ENABLE_EXAMPLES
1990  *  \ref cpp_mcdataarraydouble_findcommontuples "Here is a C++ example".
1991  *
1992  *  \ref py_mcdataarraydouble_findcommontuples  "Here is a Python example".
1993  *  \endif
1994  *  \sa DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2(), DataArrayDouble::areIncludedInMe
1995  */
1996 void DataArrayDouble::findCommonTuples(double prec, int limitTupleId, DataArrayInt *&comm, DataArrayInt *&commIndex) const
1997 {
1998   checkAllocated();
1999   int nbOfCompo=getNumberOfComponents();
2000   if ((nbOfCompo<1) || (nbOfCompo>4)) //test before work
2001     throw INTERP_KERNEL::Exception("DataArrayDouble::findCommonTuples : Unexpected spacedim of coords. Must be 1, 2, 3 or 4.");
2002
2003   int nbOfTuples=getNumberOfTuples();
2004   //
2005   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> c(DataArrayInt::New()),cI(DataArrayInt::New()); c->alloc(0,1); cI->pushBackSilent(0);
2006   switch(nbOfCompo)
2007   {
2008     case 4:
2009       findCommonTuplesAlg<4>(begin(),nbOfTuples,limitTupleId,prec,c,cI);
2010       break;
2011     case 3:
2012       findCommonTuplesAlg<3>(begin(),nbOfTuples,limitTupleId,prec,c,cI);
2013       break;
2014     case 2:
2015       findCommonTuplesAlg<2>(begin(),nbOfTuples,limitTupleId,prec,c,cI);
2016       break;
2017     case 1:
2018       findCommonTuplesAlg<1>(begin(),nbOfTuples,limitTupleId,prec,c,cI);
2019       break;
2020     default:
2021       throw INTERP_KERNEL::Exception("DataArrayDouble::findCommonTuples : nb of components managed are 1,2,3 and 4 ! not implemented for other number of components !");
2022   }
2023   comm=c.retn();
2024   commIndex=cI.retn();
2025 }
2026
2027 /*!
2028  * 
2029  * \param [in] nbTimes specifies the nb of times each tuples in \a this will be duplicated contiguouly in returned DataArrayDouble instance.
2030  *             \a nbTimes  should be at least equal to 1.
2031  * \return a newly allocated DataArrayDouble having one component and number of tuples equal to \a nbTimes * \c this->getNumberOfTuples.
2032  * \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.
2033  */
2034 DataArrayDouble *DataArrayDouble::duplicateEachTupleNTimes(int nbTimes) const
2035 {
2036   checkAllocated();
2037   if(getNumberOfComponents()!=1)
2038     throw INTERP_KERNEL::Exception("DataArrayDouble::duplicateEachTupleNTimes : this should have only one component !");
2039   if(nbTimes<1)
2040     throw INTERP_KERNEL::Exception("DataArrayDouble::duplicateEachTupleNTimes : nb times should be >= 1 !");
2041   int nbTuples=getNumberOfTuples();
2042   const double *inPtr=getConstPointer();
2043   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New(); ret->alloc(nbTimes*nbTuples,1);
2044   double *retPtr=ret->getPointer();
2045   for(int i=0;i<nbTuples;i++,inPtr++)
2046     {
2047       double val=*inPtr;
2048       for(int j=0;j<nbTimes;j++,retPtr++)
2049         *retPtr=val;
2050     }
2051   ret->copyStringInfoFrom(*this);
2052   return ret.retn();
2053 }
2054
2055 /*!
2056  * This methods returns the minimal distance between the two set of points \a this and \a other.
2057  * So \a this and \a other have to have the same number of components. If not an INTERP_KERNEL::Exception will be thrown.
2058  * This method works only if number of components of \a this (equal to those of \a other) is in 1, 2 or 3.
2059  *
2060  * \param [out] thisTupleId the tuple id in \a this corresponding to the returned minimal distance
2061  * \param [out] otherTupleId the tuple id in \a other corresponding to the returned minimal distance
2062  * \return the minimal distance between the two set of points \a this and \a other.
2063  * \sa DataArrayDouble::findClosestTupleId
2064  */
2065 double DataArrayDouble::minimalDistanceTo(const DataArrayDouble *other, int& thisTupleId, int& otherTupleId) const
2066 {
2067   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> part1=findClosestTupleId(other);
2068   int nbOfCompo(getNumberOfComponents());
2069   int otherNbTuples(other->getNumberOfTuples());
2070   const double *thisPt(begin()),*otherPt(other->begin());
2071   const int *part1Pt(part1->begin());
2072   double ret=std::numeric_limits<double>::max();
2073   for(int i=0;i<otherNbTuples;i++,part1Pt++,otherPt+=nbOfCompo)
2074     {
2075       double tmp(0.);
2076       for(int j=0;j<nbOfCompo;j++)
2077         tmp+=(otherPt[j]-thisPt[nbOfCompo*(*part1Pt)+j])*(otherPt[j]-thisPt[nbOfCompo*(*part1Pt)+j]);
2078       if(tmp<ret)
2079         { ret=tmp; thisTupleId=*part1Pt; otherTupleId=i; }
2080     }
2081   return sqrt(ret);
2082 }
2083
2084 /*!
2085  * This methods returns for each tuple in \a other which tuple in \a this is the closest.
2086  * So \a this and \a other have to have the same number of components. If not an INTERP_KERNEL::Exception will be thrown.
2087  * This method works only if number of components of \a this (equal to those of \a other) is in 1, 2 or 3.
2088  *
2089  * \return a newly allocated (new object to be dealt by the caller) DataArrayInt having \c other->getNumberOfTuples() tuples and one components.
2090  * \sa DataArrayDouble::minimalDistanceTo
2091  */
2092 DataArrayInt *DataArrayDouble::findClosestTupleId(const DataArrayDouble *other) const
2093 {
2094   if(!other)
2095     throw INTERP_KERNEL::Exception("DataArrayDouble::findClosestTupleId : other instance is NULL !");
2096   checkAllocated(); other->checkAllocated();
2097   int nbOfCompo=getNumberOfComponents();
2098   if(nbOfCompo!=other->getNumberOfComponents())
2099     {
2100       std::ostringstream oss; oss << "DataArrayDouble::findClosestTupleId : number of components in this is " << nbOfCompo;
2101       oss << ", whereas number of components in other is " << other->getNumberOfComponents() << "! Should be equal !";
2102       throw INTERP_KERNEL::Exception(oss.str().c_str());
2103     }
2104   int nbOfTuples=other->getNumberOfTuples();
2105   int thisNbOfTuples=getNumberOfTuples();
2106   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbOfTuples,1);
2107   double bounds[6];
2108   getMinMaxPerComponent(bounds);
2109   switch(nbOfCompo)
2110   {
2111     case 3:
2112       {
2113         double xDelta(fabs(bounds[1]-bounds[0])),yDelta(fabs(bounds[3]-bounds[2])),zDelta(fabs(bounds[5]-bounds[4]));
2114         double delta=std::max(xDelta,yDelta); delta=std::max(delta,zDelta);
2115         double characSize=pow((delta*delta*delta)/((double)thisNbOfTuples),1./3.);
2116         BBTreePts<3,int> myTree(begin(),0,0,getNumberOfTuples(),characSize*1e-12);
2117         FindClosestTupleIdAlg<3>(myTree,3.*characSize*characSize,other->begin(),nbOfTuples,begin(),thisNbOfTuples,ret->getPointer());
2118         break;
2119       }
2120     case 2:
2121       {
2122         double xDelta(fabs(bounds[1]-bounds[0])),yDelta(fabs(bounds[3]-bounds[2]));
2123         double delta=std::max(xDelta,yDelta);
2124         double characSize=sqrt(delta/(double)thisNbOfTuples);
2125         BBTreePts<2,int> myTree(begin(),0,0,getNumberOfTuples(),characSize*1e-12);
2126         FindClosestTupleIdAlg<2>(myTree,2.*characSize*characSize,other->begin(),nbOfTuples,begin(),thisNbOfTuples,ret->getPointer());
2127         break;
2128       }
2129     case 1:
2130       {
2131         double characSize=fabs(bounds[1]-bounds[0])/thisNbOfTuples;
2132         BBTreePts<1,int> myTree(begin(),0,0,getNumberOfTuples(),characSize*1e-12);
2133         FindClosestTupleIdAlg<1>(myTree,1.*characSize*characSize,other->begin(),nbOfTuples,begin(),thisNbOfTuples,ret->getPointer());
2134         break;
2135       }
2136     default:
2137       throw INTERP_KERNEL::Exception("Unexpected spacedim of coords for findClosestTupleId. Must be 1, 2 or 3.");
2138   }
2139   return ret.retn();
2140 }
2141
2142 /*!
2143  * This method expects that \a this and \a otherBBoxFrmt arrays are bounding box arrays ( as the output of MEDCouplingPointSet::getBoundingBoxForBBTree method ).
2144  * 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
2145  * how many bounding boxes in \a otherBBoxFrmt.
2146  * So, this method expects that \a this and \a otherBBoxFrmt have the same number of components.
2147  *
2148  * \param [in] otherBBoxFrmt - It is an array .
2149  * \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.
2150  * \sa MEDCouplingPointSet::getBoundingBoxForBBTree
2151  * \throw If \a this and \a otherBBoxFrmt have not the same number of components.
2152  * \throw If \a this and \a otherBBoxFrmt number of components is not even (BBox format).
2153  */
2154 DataArrayInt *DataArrayDouble::computeNbOfInteractionsWith(const DataArrayDouble *otherBBoxFrmt, double eps) const
2155 {
2156   if(!otherBBoxFrmt)
2157     throw INTERP_KERNEL::Exception("DataArrayDouble::computeNbOfInteractionsWith : input array is NULL !");
2158   if(!isAllocated() || !otherBBoxFrmt->isAllocated())
2159     throw INTERP_KERNEL::Exception("DataArrayDouble::computeNbOfInteractionsWith : this and input array must be allocated !");
2160   int nbOfComp(getNumberOfComponents()),nbOfTuples(getNumberOfTuples());
2161   if(nbOfComp!=otherBBoxFrmt->getNumberOfComponents())
2162     {
2163       std::ostringstream oss; oss << "DataArrayDouble::computeNbOfInteractionsWith : this number of components (" << nbOfComp << ") must be equal to the number of components of input array (" << otherBBoxFrmt->getNumberOfComponents() << ") !";
2164       throw INTERP_KERNEL::Exception(oss.str().c_str());
2165     }
2166   if(nbOfComp%2!=0)
2167     {
2168       std::ostringstream oss; oss << "DataArrayDouble::computeNbOfInteractionsWith : Number of components (" << nbOfComp << ") is not even ! It should be to be compatible with bbox format !";
2169       throw INTERP_KERNEL::Exception(oss.str().c_str());
2170     }
2171   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(nbOfTuples,1);
2172   const double *thisBBPtr(begin());
2173   int *retPtr(ret->getPointer());
2174   switch(nbOfComp/2)
2175   {
2176     case 3:
2177       {
2178         BBTree<3,int> bbt(otherBBoxFrmt->begin(),0,0,otherBBoxFrmt->getNumberOfTuples(),eps);
2179         for(int i=0;i<nbOfTuples;i++,retPtr++,thisBBPtr+=nbOfComp)
2180           *retPtr=bbt.getNbOfIntersectingElems(thisBBPtr);
2181         break;
2182       }
2183     case 2:
2184       {
2185         BBTree<2,int> bbt(otherBBoxFrmt->begin(),0,0,otherBBoxFrmt->getNumberOfTuples(),eps);
2186         for(int i=0;i<nbOfTuples;i++,retPtr++,thisBBPtr+=nbOfComp)
2187           *retPtr=bbt.getNbOfIntersectingElems(thisBBPtr);
2188         break;
2189       }
2190     case 1:
2191       {
2192         BBTree<1,int> bbt(otherBBoxFrmt->begin(),0,0,otherBBoxFrmt->getNumberOfTuples(),eps);
2193         for(int i=0;i<nbOfTuples;i++,retPtr++,thisBBPtr+=nbOfComp)
2194           *retPtr=bbt.getNbOfIntersectingElems(thisBBPtr);
2195         break;
2196       }
2197     default:
2198       throw INTERP_KERNEL::Exception("DataArrayDouble::computeNbOfInteractionsWith : space dimension supported are [1,2,3] !");
2199   }
2200
2201   return ret.retn();
2202 }
2203
2204 /*!
2205  * Returns a copy of \a this array by excluding coincident tuples. Each tuple is
2206  * considered as coordinates of a point in getNumberOfComponents()-dimensional
2207  * space. The distance between tuples is computed using norm2. If several tuples are
2208  * not far each from other than \a prec, only one of them remains in the result
2209  * array. The order of tuples in the result array is same as in \a this one except
2210  * that coincident tuples are excluded.
2211  *  \param [in] prec - minimal absolute distance between two tuples at which they are
2212  *              considered not coincident.
2213  *  \param [in] limitTupleId - limit tuple id. If all tuples within a group of coincident
2214  *              tuples have id strictly lower than \a limitTupleId then they are not excluded.
2215  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
2216  *          is to delete using decrRef() as it is no more needed.
2217  *  \throw If \a this is not allocated.
2218  *  \throw If the number of components is not in [1,2,3,4].
2219  *
2220  *  \if ENABLE_EXAMPLES
2221  *  \ref py_mcdataarraydouble_getdifferentvalues "Here is a Python example".
2222  *  \endif
2223  */
2224 DataArrayDouble *DataArrayDouble::getDifferentValues(double prec, int limitTupleId) const
2225 {
2226   checkAllocated();
2227   DataArrayInt *c0=0,*cI0=0;
2228   findCommonTuples(prec,limitTupleId,c0,cI0);
2229   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> c(c0),cI(cI0);
2230   int newNbOfTuples=-1;
2231   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> o2n=DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2(getNumberOfTuples(),c0->begin(),cI0->begin(),cI0->end(),newNbOfTuples);
2232   return renumberAndReduce(o2n->getConstPointer(),newNbOfTuples);
2233 }
2234
2235 /*!
2236  * Copy all components in a specified order from another DataArrayDouble.
2237  * Both numerical and textual data is copied. The number of tuples in \a this and
2238  * the other array can be different.
2239  *  \param [in] a - the array to copy data from.
2240  *  \param [in] compoIds - sequence of zero based indices of components, data of which is
2241  *              to be copied.
2242  *  \throw If \a a is NULL.
2243  *  \throw If \a compoIds.size() != \a a->getNumberOfComponents().
2244  *  \throw If \a compoIds[i] < 0 or \a compoIds[i] > \a this->getNumberOfComponents().
2245  *
2246  *  \if ENABLE_EXAMPLES
2247  *  \ref py_mcdataarraydouble_setselectedcomponents "Here is a Python example".
2248  *  \endif
2249  */
2250 void DataArrayDouble::setSelectedComponents(const DataArrayDouble *a, const std::vector<int>& compoIds)
2251 {
2252   if(!a)
2253     throw INTERP_KERNEL::Exception("DataArrayDouble::setSelectedComponents : input DataArrayDouble is NULL !");
2254   checkAllocated();
2255   copyPartOfStringInfoFrom2(compoIds,*a);
2256   std::size_t partOfCompoSz=compoIds.size();
2257   int nbOfCompo=getNumberOfComponents();
2258   int nbOfTuples=std::min(getNumberOfTuples(),a->getNumberOfTuples());
2259   const double *ac=a->getConstPointer();
2260   double *nc=getPointer();
2261   for(int i=0;i<nbOfTuples;i++)
2262     for(std::size_t j=0;j<partOfCompoSz;j++,ac++)
2263       nc[nbOfCompo*i+compoIds[j]]=*ac;
2264 }
2265
2266 /*!
2267  * Copy all values from another DataArrayDouble into specified tuples and components
2268  * of \a this array. Textual data is not copied.
2269  * The tree parameters defining set of indices of tuples and components are similar to
2270  * the tree parameters of the Python function \c range(\c start,\c stop,\c step).
2271  *  \param [in] a - the array to copy values from.
2272  *  \param [in] bgTuples - index of the first tuple of \a this array to assign values to.
2273  *  \param [in] endTuples - index of the tuple before which the tuples to assign to
2274  *              are located.
2275  *  \param [in] stepTuples - index increment to get index of the next tuple to assign to.
2276  *  \param [in] bgComp - index of the first component of \a this array to assign values to.
2277  *  \param [in] endComp - index of the component before which the components to assign
2278  *              to are located.
2279  *  \param [in] stepComp - index increment to get index of the next component to assign to.
2280  *  \param [in] strictCompoCompare - if \a true (by default), then \a a->getNumberOfComponents() 
2281  *              must be equal to the number of columns to assign to, else an
2282  *              exception is thrown; if \a false, then it is only required that \a
2283  *              a->getNbOfElems() equals to number of values to assign to (this condition
2284  *              must be respected even if \a strictCompoCompare is \a true). The number of 
2285  *              values to assign to is given by following Python expression:
2286  *              \a nbTargetValues = 
2287  *              \c len(\c range(\a bgTuples,\a endTuples,\a stepTuples)) *
2288  *              \c len(\c range(\a bgComp,\a endComp,\a stepComp)).
2289  *  \throw If \a a is NULL.
2290  *  \throw If \a a is not allocated.
2291  *  \throw If \a this is not allocated.
2292  *  \throw If parameters specifying tuples and components to assign to do not give a
2293  *            non-empty range of increasing indices.
2294  *  \throw If \a a->getNbOfElems() != \a nbTargetValues.
2295  *  \throw If \a strictCompoCompare == \a true && \a a->getNumberOfComponents() !=
2296  *            \c len(\c range(\a bgComp,\a endComp,\a stepComp)).
2297  *
2298  *  \if ENABLE_EXAMPLES
2299  *  \ref py_mcdataarraydouble_setpartofvalues1 "Here is a Python example".
2300  *  \endif
2301  */
2302 void DataArrayDouble::setPartOfValues1(const DataArrayDouble *a, int bgTuples, int endTuples, int stepTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare)
2303 {
2304   if(!a)
2305     throw INTERP_KERNEL::Exception("DataArrayDouble::setPartOfValues1 : input DataArrayDouble is NULL !");
2306   const char msg[]="DataArrayDouble::setPartOfValues1";
2307   checkAllocated();
2308   a->checkAllocated();
2309   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
2310   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
2311   int nbComp=getNumberOfComponents();
2312   int nbOfTuples=getNumberOfTuples();
2313   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
2314   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
2315   bool assignTech=true;
2316   if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
2317     {
2318       if(strictCompoCompare)
2319         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
2320     }
2321   else
2322     {
2323       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
2324       assignTech=false;
2325     }
2326   const double *srcPt=a->getConstPointer();
2327   double *pt=getPointer()+bgTuples*nbComp+bgComp;
2328   if(assignTech)
2329     {
2330       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
2331         for(int j=0;j<newNbOfComp;j++,srcPt++)
2332           pt[j*stepComp]=*srcPt;
2333     }
2334   else
2335     {
2336       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
2337         {
2338           const double *srcPt2=srcPt;
2339           for(int j=0;j<newNbOfComp;j++,srcPt2++)
2340             pt[j*stepComp]=*srcPt2;
2341         }
2342     }
2343 }
2344
2345 /*!
2346  * Assign a given value to values at specified tuples and components of \a this array.
2347  * The tree parameters defining set of indices of tuples and components are similar to
2348  * the tree parameters of the Python function \c range(\c start,\c stop,\c step)..
2349  *  \param [in] a - the value to assign.
2350  *  \param [in] bgTuples - index of the first tuple of \a this array to assign to.
2351  *  \param [in] endTuples - index of the tuple before which the tuples to assign to
2352  *              are located.
2353  *  \param [in] stepTuples - index increment to get index of the next tuple to assign to.
2354  *  \param [in] bgComp - index of the first component of \a this array to assign to.
2355  *  \param [in] endComp - index of the component before which the components to assign
2356  *              to are located.
2357  *  \param [in] stepComp - index increment to get index of the next component to assign to.
2358  *  \throw If \a this is not allocated.
2359  *  \throw If parameters specifying tuples and components to assign to, do not give a
2360  *            non-empty range of increasing indices or indices are out of a valid range
2361  *            for \this array.
2362  *
2363  *  \if ENABLE_EXAMPLES
2364  *  \ref py_mcdataarraydouble_setpartofvaluessimple1 "Here is a Python example".
2365  *  \endif
2366  */
2367 void DataArrayDouble::setPartOfValuesSimple1(double a, int bgTuples, int endTuples, int stepTuples, int bgComp, int endComp, int stepComp)
2368 {
2369   const char msg[]="DataArrayDouble::setPartOfValuesSimple1";
2370   checkAllocated();
2371   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
2372   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
2373   int nbComp=getNumberOfComponents();
2374   int nbOfTuples=getNumberOfTuples();
2375   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
2376   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
2377   double *pt=getPointer()+bgTuples*nbComp+bgComp;
2378   for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
2379     for(int j=0;j<newNbOfComp;j++)
2380       pt[j*stepComp]=a;
2381 }
2382
2383 /*!
2384  * Copy all values from another DataArrayDouble (\a a) into specified tuples and 
2385  * components of \a this array. Textual data is not copied.
2386  * The tuples and components to assign to are defined by C arrays of indices.
2387  * There are two *modes of usage*:
2388  * - If \a a->getNbOfElems() equals to number of values to assign to, then every value
2389  *   of \a a is assigned to its own location within \a this array. 
2390  * - If \a a includes one tuple, then all values of \a a are assigned to the specified
2391  *   components of every specified tuple of \a this array. In this mode it is required
2392  *   that \a a->getNumberOfComponents() equals to the number of specified components.
2393  *
2394  *  \param [in] a - the array to copy values from.
2395  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
2396  *              assign values of \a a to.
2397  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
2398  *              pointer to a tuple index <em>(pi)</em> varies as this: 
2399  *              \a bgTuples <= \a pi < \a endTuples.
2400  *  \param [in] bgComp - pointer to an array of component indices of \a this array to
2401  *              assign values of \a a to.
2402  *  \param [in] endComp - specifies the end of the array \a bgTuples, so that
2403  *              pointer to a component index <em>(pi)</em> varies as this: 
2404  *              \a bgComp <= \a pi < \a endComp.
2405  *  \param [in] strictCompoCompare - this parameter is checked only if the
2406  *               *mode of usage* is the first; if it is \a true (default), 
2407  *               then \a a->getNumberOfComponents() must be equal 
2408  *               to the number of specified columns, else this is not required.
2409  *  \throw If \a a is NULL.
2410  *  \throw If \a a is not allocated.
2411  *  \throw If \a this is not allocated.
2412  *  \throw If any index of tuple/component given by <em>bgTuples / bgComp</em> is
2413  *         out of a valid range for \a this array.
2414  *  \throw In the first *mode of usage*, if <em>strictCompoCompare == true </em> and
2415  *         if <em> a->getNumberOfComponents() != (endComp - bgComp) </em>.
2416  *  \throw In the second *mode of usage*, if \a a->getNumberOfTuples() != 1 or
2417  *         <em> a->getNumberOfComponents() != (endComp - bgComp)</em>.
2418  *
2419  *  \if ENABLE_EXAMPLES
2420  *  \ref py_mcdataarraydouble_setpartofvalues2 "Here is a Python example".
2421  *  \endif
2422  */
2423 void DataArrayDouble::setPartOfValues2(const DataArrayDouble *a, const int *bgTuples, const int *endTuples, const int *bgComp, const int *endComp, bool strictCompoCompare)
2424 {
2425   if(!a)
2426     throw INTERP_KERNEL::Exception("DataArrayDouble::setPartOfValues2 : input DataArrayDouble is NULL !");
2427   const char msg[]="DataArrayDouble::setPartOfValues2";
2428   checkAllocated();
2429   a->checkAllocated();
2430   int nbComp=getNumberOfComponents();
2431   int nbOfTuples=getNumberOfTuples();
2432   for(const int *z=bgComp;z!=endComp;z++)
2433     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
2434   int newNbOfTuples=(int)std::distance(bgTuples,endTuples);
2435   int newNbOfComp=(int)std::distance(bgComp,endComp);
2436   bool assignTech=true;
2437   if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
2438     {
2439       if(strictCompoCompare)
2440         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
2441     }
2442   else
2443     {
2444       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
2445       assignTech=false;
2446     }
2447   double *pt=getPointer();
2448   const double *srcPt=a->getConstPointer();
2449   if(assignTech)
2450     {    
2451       for(const int *w=bgTuples;w!=endTuples;w++)
2452         {
2453           DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
2454           for(const int *z=bgComp;z!=endComp;z++,srcPt++)
2455             {    
2456               pt[(std::size_t)(*w)*nbComp+(*z)]=*srcPt;
2457             }
2458         }
2459     }
2460   else
2461     {
2462       for(const int *w=bgTuples;w!=endTuples;w++)
2463         {
2464           const double *srcPt2=srcPt;
2465           DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
2466           for(const int *z=bgComp;z!=endComp;z++,srcPt2++)
2467             {    
2468               pt[(std::size_t)(*w)*nbComp+(*z)]=*srcPt2;
2469             }
2470         }
2471     }
2472 }
2473
2474 /*!
2475  * Assign a given value to values at specified tuples and components of \a this array.
2476  * The tuples and components to assign to are defined by C arrays of indices.
2477  *  \param [in] a - the value to assign.
2478  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
2479  *              assign \a a to.
2480  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
2481  *              pointer to a tuple index (\a pi) varies as this: 
2482  *              \a bgTuples <= \a pi < \a endTuples.
2483  *  \param [in] bgComp - pointer to an array of component indices of \a this array to
2484  *              assign \a a to.
2485  *  \param [in] endComp - specifies the end of the array \a bgTuples, so that
2486  *              pointer to a component index (\a pi) varies as this: 
2487  *              \a bgComp <= \a pi < \a endComp.
2488  *  \throw If \a this is not allocated.
2489  *  \throw If any index of tuple/component given by <em>bgTuples / bgComp</em> is
2490  *         out of a valid range for \a this array.
2491  *
2492  *  \if ENABLE_EXAMPLES
2493  *  \ref py_mcdataarraydouble_setpartofvaluessimple2 "Here is a Python example".
2494  *  \endif
2495  */
2496 void DataArrayDouble::setPartOfValuesSimple2(double a, const int *bgTuples, const int *endTuples, const int *bgComp, const int *endComp)
2497 {
2498   checkAllocated();
2499   int nbComp=getNumberOfComponents();
2500   int nbOfTuples=getNumberOfTuples();
2501   for(const int *z=bgComp;z!=endComp;z++)
2502     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
2503   double *pt=getPointer();
2504   for(const int *w=bgTuples;w!=endTuples;w++)
2505     for(const int *z=bgComp;z!=endComp;z++)
2506       {
2507         DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
2508         pt[(std::size_t)(*w)*nbComp+(*z)]=a;
2509       }
2510 }
2511
2512 /*!
2513  * Copy all values from another DataArrayDouble (\a a) into specified tuples and 
2514  * components of \a this array. Textual data is not copied.
2515  * The tuples to assign to are defined by a C array of indices.
2516  * The components to assign to are defined by three values similar to parameters of
2517  * the Python function \c range(\c start,\c stop,\c step).
2518  * There are two *modes of usage*:
2519  * - If \a a->getNbOfElems() equals to number of values to assign to, then every value
2520  *   of \a a is assigned to its own location within \a this array. 
2521  * - If \a a includes one tuple, then all values of \a a are assigned to the specified
2522  *   components of every specified tuple of \a this array. In this mode it is required
2523  *   that \a a->getNumberOfComponents() equals to the number of specified components.
2524  *
2525  *  \param [in] a - the array to copy values from.
2526  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
2527  *              assign values of \a a to.
2528  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
2529  *              pointer to a tuple index <em>(pi)</em> varies as this: 
2530  *              \a bgTuples <= \a pi < \a endTuples.
2531  *  \param [in] bgComp - index of the first component of \a this array to assign to.
2532  *  \param [in] endComp - index of the component before which the components to assign
2533  *              to are located.
2534  *  \param [in] stepComp - index increment to get index of the next component to assign to.
2535  *  \param [in] strictCompoCompare - this parameter is checked only in the first
2536  *               *mode of usage*; if \a strictCompoCompare is \a true (default), 
2537  *               then \a a->getNumberOfComponents() must be equal 
2538  *               to the number of specified columns, else this is not required.
2539  *  \throw If \a a is NULL.
2540  *  \throw If \a a is not allocated.
2541  *  \throw If \a this is not allocated.
2542  *  \throw If any index of tuple given by \a bgTuples is out of a valid range for 
2543  *         \a this array.
2544  *  \throw In the first *mode of usage*, if <em>strictCompoCompare == true </em> and
2545  *         if <em> a->getNumberOfComponents()</em> is unequal to the number of components
2546  *         defined by <em>(bgComp,endComp,stepComp)</em>.
2547  *  \throw In the second *mode of usage*, if \a a->getNumberOfTuples() != 1 or
2548  *         <em> a->getNumberOfComponents()</em> is unequal to the number of components
2549  *         defined by <em>(bgComp,endComp,stepComp)</em>.
2550  *  \throw If parameters specifying components to assign to, do not give a
2551  *            non-empty range of increasing indices or indices are out of a valid range
2552  *            for \this array.
2553  *
2554  *  \if ENABLE_EXAMPLES
2555  *  \ref py_mcdataarraydouble_setpartofvalues3 "Here is a Python example".
2556  *  \endif
2557  */
2558 void DataArrayDouble::setPartOfValues3(const DataArrayDouble *a, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare)
2559 {
2560   if(!a)
2561     throw INTERP_KERNEL::Exception("DataArrayDouble::setPartOfValues3 : input DataArrayDouble is NULL !");
2562   const char msg[]="DataArrayDouble::setPartOfValues3";
2563   checkAllocated();
2564   a->checkAllocated();
2565   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
2566   int nbComp=getNumberOfComponents();
2567   int nbOfTuples=getNumberOfTuples();
2568   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
2569   int newNbOfTuples=(int)std::distance(bgTuples,endTuples);
2570   bool assignTech=true;
2571   if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
2572     {
2573       if(strictCompoCompare)
2574         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
2575     }
2576   else
2577     {
2578       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
2579       assignTech=false;
2580     }
2581   double *pt=getPointer()+bgComp;
2582   const double *srcPt=a->getConstPointer();
2583   if(assignTech)
2584     {
2585       for(const int *w=bgTuples;w!=endTuples;w++)
2586         for(int j=0;j<newNbOfComp;j++,srcPt++)
2587           {
2588             DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
2589             pt[(std::size_t)(*w)*nbComp+j*stepComp]=*srcPt;
2590           }
2591     }
2592   else
2593     {
2594       for(const int *w=bgTuples;w!=endTuples;w++)
2595         {
2596           const double *srcPt2=srcPt;
2597           for(int j=0;j<newNbOfComp;j++,srcPt2++)
2598             {
2599               DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
2600               pt[(std::size_t)(*w)*nbComp+j*stepComp]=*srcPt2;
2601             }
2602         }
2603     }
2604 }
2605
2606 /*!
2607  * Assign a given value to values at specified tuples and components of \a this array.
2608  * The tuples to assign to are defined by a C array of indices.
2609  * The components to assign to are defined by three values similar to parameters of
2610  * the Python function \c range(\c start,\c stop,\c step).
2611  *  \param [in] a - the value to assign.
2612  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
2613  *              assign \a a to.
2614  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
2615  *              pointer to a tuple index <em>(pi)</em> varies as this: 
2616  *              \a bgTuples <= \a pi < \a endTuples.
2617  *  \param [in] bgComp - index of the first component of \a this array to assign to.
2618  *  \param [in] endComp - index of the component before which the components to assign
2619  *              to are located.
2620  *  \param [in] stepComp - index increment to get index of the next component to assign to.
2621  *  \throw If \a this is not allocated.
2622  *  \throw If any index of tuple given by \a bgTuples is out of a valid range for 
2623  *         \a this array.
2624  *  \throw If parameters specifying components to assign to, do not give a
2625  *            non-empty range of increasing indices or indices are out of a valid range
2626  *            for \this array.
2627  *
2628  *  \if ENABLE_EXAMPLES
2629  *  \ref py_mcdataarraydouble_setpartofvaluessimple3 "Here is a Python example".
2630  *  \endif
2631  */
2632 void DataArrayDouble::setPartOfValuesSimple3(double a, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp)
2633 {
2634   const char msg[]="DataArrayDouble::setPartOfValuesSimple3";
2635   checkAllocated();
2636   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
2637   int nbComp=getNumberOfComponents();
2638   int nbOfTuples=getNumberOfTuples();
2639   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
2640   double *pt=getPointer()+bgComp;
2641   for(const int *w=bgTuples;w!=endTuples;w++)
2642     for(int j=0;j<newNbOfComp;j++)
2643       {
2644         DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
2645         pt[(std::size_t)(*w)*nbComp+j*stepComp]=a;
2646       }
2647 }
2648
2649 /*!
2650  * Copy all values from another DataArrayDouble into specified tuples and components
2651  * of \a this array. Textual data is not copied.
2652  * The tree parameters defining set of indices of tuples and components are similar to
2653  * the tree parameters of the Python function \c range(\c start,\c stop,\c step).
2654  *  \param [in] a - the array to copy values from.
2655  *  \param [in] bgTuples - index of the first tuple of \a this array to assign values to.
2656  *  \param [in] endTuples - index of the tuple before which the tuples to assign to
2657  *              are located.
2658  *  \param [in] stepTuples - index increment to get index of the next tuple to assign to.
2659  *  \param [in] bgComp - pointer to an array of component indices of \a this array to
2660  *              assign \a a to.
2661  *  \param [in] endComp - specifies the end of the array \a bgTuples, so that
2662  *              pointer to a component index (\a pi) varies as this: 
2663  *              \a bgComp <= \a pi < \a endComp.
2664  *  \param [in] strictCompoCompare - if \a true (by default), then \a a->getNumberOfComponents() 
2665  *              must be equal to the number of columns to assign to, else an
2666  *              exception is thrown; if \a false, then it is only required that \a
2667  *              a->getNbOfElems() equals to number of values to assign to (this condition
2668  *              must be respected even if \a strictCompoCompare is \a true). The number of 
2669  *              values to assign to is given by following Python expression:
2670  *              \a nbTargetValues = 
2671  *              \c len(\c range(\a bgTuples,\a endTuples,\a stepTuples)) *
2672  *              \c len(\c range(\a bgComp,\a endComp,\a stepComp)).
2673  *  \throw If \a a is NULL.
2674  *  \throw If \a a is not allocated.
2675  *  \throw If \a this is not allocated.
2676  *  \throw If parameters specifying tuples and components to assign to do not give a
2677  *            non-empty range of increasing indices.
2678  *  \throw If \a a->getNbOfElems() != \a nbTargetValues.
2679  *  \throw If \a strictCompoCompare == \a true && \a a->getNumberOfComponents() !=
2680  *            \c len(\c range(\a bgComp,\a endComp,\a stepComp)).
2681  *
2682  */
2683 void DataArrayDouble::setPartOfValues4(const DataArrayDouble *a, int bgTuples, int endTuples, int stepTuples, const int *bgComp, const int *endComp, bool strictCompoCompare)
2684 {
2685   if(!a)
2686     throw INTERP_KERNEL::Exception("DataArrayDouble::setPartOfValues4 : input DataArrayDouble is NULL !");
2687   const char msg[]="DataArrayDouble::setPartOfValues4";
2688   checkAllocated();
2689   a->checkAllocated();
2690   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
2691   int newNbOfComp=(int)std::distance(bgComp,endComp);
2692   int nbComp=getNumberOfComponents();
2693   for(const int *z=bgComp;z!=endComp;z++)
2694     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
2695   int nbOfTuples=getNumberOfTuples();
2696   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
2697   bool assignTech=true;
2698   if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
2699     {
2700       if(strictCompoCompare)
2701         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
2702     }
2703   else
2704     {
2705       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
2706       assignTech=false;
2707     }
2708   const double *srcPt=a->getConstPointer();
2709   double *pt=getPointer()+bgTuples*nbComp;
2710   if(assignTech)
2711     {
2712       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
2713         for(const int *z=bgComp;z!=endComp;z++,srcPt++)
2714           pt[*z]=*srcPt;
2715     }
2716   else
2717     {
2718       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
2719         {
2720           const double *srcPt2=srcPt;
2721           for(const int *z=bgComp;z!=endComp;z++,srcPt2++)
2722             pt[*z]=*srcPt2;
2723         }
2724     }
2725 }
2726
2727 void DataArrayDouble::setPartOfValuesSimple4(double a, int bgTuples, int endTuples, int stepTuples, const int *bgComp, const int *endComp)
2728 {
2729   const char msg[]="DataArrayDouble::setPartOfValuesSimple4";
2730   checkAllocated();
2731   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
2732   int nbComp=getNumberOfComponents();
2733   for(const int *z=bgComp;z!=endComp;z++)
2734     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
2735   int nbOfTuples=getNumberOfTuples();
2736   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
2737   double *pt=getPointer()+bgTuples*nbComp;
2738   for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
2739     for(const int *z=bgComp;z!=endComp;z++)
2740       pt[*z]=a;
2741 }
2742
2743 /*!
2744  * Copy some tuples from another DataArrayDouble into specified tuples
2745  * of \a this array. Textual data is not copied. Both arrays must have equal number of
2746  * components.
2747  * Both the tuples to assign and the tuples to assign to are defined by a DataArrayInt.
2748  * All components of selected tuples are copied.
2749  *  \param [in] a - the array to copy values from.
2750  *  \param [in] tuplesSelec - the array specifying both source tuples of \a a and
2751  *              target tuples of \a this. \a tuplesSelec has two components, and the
2752  *              first component specifies index of the source tuple and the second
2753  *              one specifies index of the target tuple.
2754  *  \throw If \a this is not allocated.
2755  *  \throw If \a a is NULL.
2756  *  \throw If \a a is not allocated.
2757  *  \throw If \a tuplesSelec is NULL.
2758  *  \throw If \a tuplesSelec is not allocated.
2759  *  \throw If <em>this->getNumberOfComponents() != a->getNumberOfComponents()</em>.
2760  *  \throw If \a tuplesSelec->getNumberOfComponents() != 2.
2761  *  \throw If any tuple index given by \a tuplesSelec is out of a valid range for 
2762  *         the corresponding (\a this or \a a) array.
2763  */
2764 void DataArrayDouble::setPartOfValuesAdv(const DataArrayDouble *a, const DataArrayInt *tuplesSelec)
2765 {
2766   if(!a || !tuplesSelec)
2767     throw INTERP_KERNEL::Exception("DataArrayDouble::setPartOfValuesAdv : input DataArrayDouble is NULL !");
2768   checkAllocated();
2769   a->checkAllocated();
2770   tuplesSelec->checkAllocated();
2771   int nbOfComp=getNumberOfComponents();
2772   if(nbOfComp!=a->getNumberOfComponents())
2773     throw INTERP_KERNEL::Exception("DataArrayDouble::setPartOfValuesAdv : This and a do not have the same number of components !");
2774   if(tuplesSelec->getNumberOfComponents()!=2)
2775     throw INTERP_KERNEL::Exception("DataArrayDouble::setPartOfValuesAdv : Expecting to have a tuple selector DataArrayInt instance with exactly 2 components !");
2776   int thisNt=getNumberOfTuples();
2777   int aNt=a->getNumberOfTuples();
2778   double *valsToSet=getPointer();
2779   const double *valsSrc=a->getConstPointer();
2780   for(const int *tuple=tuplesSelec->begin();tuple!=tuplesSelec->end();tuple+=2)
2781     {
2782       if(tuple[1]>=0 && tuple[1]<aNt)
2783         {
2784           if(tuple[0]>=0 && tuple[0]<thisNt)
2785             std::copy(valsSrc+nbOfComp*tuple[1],valsSrc+nbOfComp*(tuple[1]+1),valsToSet+nbOfComp*tuple[0]);
2786           else
2787             {
2788               std::ostringstream oss; oss << "DataArrayDouble::setPartOfValuesAdv : Tuple #" << std::distance(tuplesSelec->begin(),tuple)/2;
2789               oss << " of 'tuplesSelec' request of tuple id #" << tuple[0] << " in 'this' ! It should be in [0," << thisNt << ") !";
2790               throw INTERP_KERNEL::Exception(oss.str().c_str());
2791             }
2792         }
2793       else
2794         {
2795           std::ostringstream oss; oss << "DataArrayDouble::setPartOfValuesAdv : Tuple #" << std::distance(tuplesSelec->begin(),tuple)/2;
2796           oss << " of 'tuplesSelec' request of tuple id #" << tuple[1] << " in 'a' ! It should be in [0," << aNt << ") !";
2797           throw INTERP_KERNEL::Exception(oss.str().c_str());
2798         }
2799     }
2800 }
2801
2802 /*!
2803  * Copy some tuples from another DataArrayDouble (\a aBase) into contiguous tuples
2804  * of \a this array. Textual data is not copied. Both arrays must have equal number of
2805  * components.
2806  * The tuples to assign to are defined by index of the first tuple, and
2807  * their number is defined by \a tuplesSelec->getNumberOfTuples().
2808  * The tuples to copy are defined by values of a DataArrayInt.
2809  * All components of selected tuples are copied.
2810  *  \param [in] tupleIdStart - index of the first tuple of \a this array to assign
2811  *              values to.
2812  *  \param [in] aBase - the array to copy values from.
2813  *  \param [in] tuplesSelec - the array specifying tuples of \a a to copy.
2814  *  \throw If \a this is not allocated.
2815  *  \throw If \a aBase is NULL.
2816  *  \throw If \a aBase is not allocated.
2817  *  \throw If \a tuplesSelec is NULL.
2818  *  \throw If \a tuplesSelec is not allocated.
2819  *  \throw If <em>this->getNumberOfComponents() != aBase->getNumberOfComponents()</em>.
2820  *  \throw If \a tuplesSelec->getNumberOfComponents() != 1.
2821  *  \throw If <em>tupleIdStart + tuplesSelec->getNumberOfTuples() > this->getNumberOfTuples().</em>
2822  *  \throw If any tuple index given by \a tuplesSelec is out of a valid range for 
2823  *         \a aBase array.
2824  */
2825 void DataArrayDouble::setContigPartOfSelectedValues(int tupleIdStart, const DataArray *aBase, const DataArrayInt *tuplesSelec)
2826 {
2827   if(!aBase || !tuplesSelec)
2828     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues : input DataArray is NULL !");
2829   const DataArrayDouble *a=dynamic_cast<const DataArrayDouble *>(aBase);
2830   if(!a)
2831     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues : input DataArray aBase is not a DataArrayDouble !");
2832   checkAllocated();
2833   a->checkAllocated();
2834   tuplesSelec->checkAllocated();
2835   int nbOfComp=getNumberOfComponents();
2836   if(nbOfComp!=a->getNumberOfComponents())
2837     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues : This and a do not have the same number of components !");
2838   if(tuplesSelec->getNumberOfComponents()!=1)
2839     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues : Expecting to have a tuple selector DataArrayInt instance with exactly 1 component !");
2840   int thisNt=getNumberOfTuples();
2841   int aNt=a->getNumberOfTuples();
2842   int nbOfTupleToWrite=tuplesSelec->getNumberOfTuples();
2843   double *valsToSet=getPointer()+tupleIdStart*nbOfComp;
2844   if(tupleIdStart+nbOfTupleToWrite>thisNt)
2845     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues : invalid number range of values to write !");
2846   const double *valsSrc=a->getConstPointer();
2847   for(const int *tuple=tuplesSelec->begin();tuple!=tuplesSelec->end();tuple++,valsToSet+=nbOfComp)
2848     {
2849       if(*tuple>=0 && *tuple<aNt)
2850         {
2851           std::copy(valsSrc+nbOfComp*(*tuple),valsSrc+nbOfComp*(*tuple+1),valsToSet);
2852         }
2853       else
2854         {
2855           std::ostringstream oss; oss << "DataArrayDouble::setContigPartOfSelectedValues : Tuple #" << std::distance(tuplesSelec->begin(),tuple);
2856           oss << " of 'tuplesSelec' request of tuple id #" << *tuple << " in 'a' ! It should be in [0," << aNt << ") !";
2857           throw INTERP_KERNEL::Exception(oss.str().c_str());
2858         }
2859     }
2860 }
2861
2862 /*!
2863  * Copy some tuples from another DataArrayDouble (\a aBase) into contiguous tuples
2864  * of \a this array. Textual data is not copied. Both arrays must have equal number of
2865  * components.
2866  * The tuples to copy are defined by three values similar to parameters of
2867  * the Python function \c range(\c start,\c stop,\c step).
2868  * The tuples to assign to are defined by index of the first tuple, and
2869  * their number is defined by number of tuples to copy.
2870  * All components of selected tuples are copied.
2871  *  \param [in] tupleIdStart - index of the first tuple of \a this array to assign
2872  *              values to.
2873  *  \param [in] aBase - the array to copy values from.
2874  *  \param [in] bg - index of the first tuple to copy of the array \a aBase.
2875  *  \param [in] end2 - index of the tuple of \a aBase before which the tuples to copy
2876  *              are located.
2877  *  \param [in] step - index increment to get index of the next tuple to copy.
2878  *  \throw If \a this is not allocated.
2879  *  \throw If \a aBase is NULL.
2880  *  \throw If \a aBase is not allocated.
2881  *  \throw If <em>this->getNumberOfComponents() != aBase->getNumberOfComponents()</em>.
2882  *  \throw If <em>tupleIdStart + len(range(bg,end2,step)) > this->getNumberOfTuples().</em>
2883  *  \throw If parameters specifying tuples to copy, do not give a
2884  *            non-empty range of increasing indices or indices are out of a valid range
2885  *            for the array \a aBase.
2886  */
2887 void DataArrayDouble::setContigPartOfSelectedValues2(int tupleIdStart, const DataArray *aBase, int bg, int end2, int step)
2888 {
2889   if(!aBase)
2890     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues2 : input DataArray is NULL !");
2891   const DataArrayDouble *a=dynamic_cast<const DataArrayDouble *>(aBase);
2892   if(!a)
2893     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues2 : input DataArray aBase is not a DataArrayDouble !");
2894   checkAllocated();
2895   a->checkAllocated();
2896   int nbOfComp=getNumberOfComponents();
2897   const char msg[]="DataArrayDouble::setContigPartOfSelectedValues2";
2898   int nbOfTupleToWrite=DataArray::GetNumberOfItemGivenBES(bg,end2,step,msg);
2899   if(nbOfComp!=a->getNumberOfComponents())
2900     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues2 : This and a do not have the same number of components !");
2901   int thisNt=getNumberOfTuples();
2902   int aNt=a->getNumberOfTuples();
2903   double *valsToSet=getPointer()+tupleIdStart*nbOfComp;
2904   if(tupleIdStart+nbOfTupleToWrite>thisNt)
2905     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues2 : invalid number range of values to write !");
2906   if(end2>aNt)
2907     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues2 : invalid range of values to read !");
2908   const double *valsSrc=a->getConstPointer()+bg*nbOfComp;
2909   for(int i=0;i<nbOfTupleToWrite;i++,valsToSet+=nbOfComp,valsSrc+=step*nbOfComp)
2910     {
2911       std::copy(valsSrc,valsSrc+nbOfComp,valsToSet);
2912     }
2913 }
2914
2915 /*!
2916  * Returns a value located at specified tuple and component.
2917  * This method is equivalent to DataArrayDouble::getIJ() except that validity of
2918  * parameters is checked. So this method is safe but expensive if used to go through
2919  * all values of \a this.
2920  *  \param [in] tupleId - index of tuple of interest.
2921  *  \param [in] compoId - index of component of interest.
2922  *  \return double - value located by \a tupleId and \a compoId.
2923  *  \throw If \a this is not allocated.
2924  *  \throw If condition <em>( 0 <= tupleId < this->getNumberOfTuples() )</em> is violated.
2925  *  \throw If condition <em>( 0 <= compoId < this->getNumberOfComponents() )</em> is violated.
2926  */
2927 double DataArrayDouble::getIJSafe(int tupleId, int compoId) const
2928 {
2929   checkAllocated();
2930   if(tupleId<0 || tupleId>=getNumberOfTuples())
2931     {
2932       std::ostringstream oss; oss << "DataArrayDouble::getIJSafe : request for tupleId " << tupleId << " should be in [0," << getNumberOfTuples() << ") !";
2933       throw INTERP_KERNEL::Exception(oss.str().c_str());
2934     }
2935   if(compoId<0 || compoId>=getNumberOfComponents())
2936     {
2937       std::ostringstream oss; oss << "DataArrayDouble::getIJSafe : request for compoId " << compoId << " should be in [0," << getNumberOfComponents() << ") !";
2938       throw INTERP_KERNEL::Exception(oss.str().c_str());
2939     }
2940   return _mem[tupleId*_info_on_compo.size()+compoId];
2941 }
2942
2943 /*!
2944  * Returns the first value of \a this. 
2945  *  \return double - the last value of \a this array.
2946  *  \throw If \a this is not allocated.
2947  *  \throw If \a this->getNumberOfComponents() != 1.
2948  *  \throw If \a this->getNumberOfTuples() < 1.
2949  */
2950 double DataArrayDouble::front() const
2951 {
2952   checkAllocated();
2953   if(getNumberOfComponents()!=1)
2954     throw INTERP_KERNEL::Exception("DataArrayDouble::front : number of components not equal to one !");
2955   int nbOfTuples=getNumberOfTuples();
2956   if(nbOfTuples<1)
2957     throw INTERP_KERNEL::Exception("DataArrayDouble::front : number of tuples must be >= 1 !");
2958   return *(getConstPointer());
2959 }
2960
2961 /*!
2962  * Returns the last value of \a this. 
2963  *  \return double - the last value of \a this array.
2964  *  \throw If \a this is not allocated.
2965  *  \throw If \a this->getNumberOfComponents() != 1.
2966  *  \throw If \a this->getNumberOfTuples() < 1.
2967  */
2968 double DataArrayDouble::back() const
2969 {
2970   checkAllocated();
2971   if(getNumberOfComponents()!=1)
2972     throw INTERP_KERNEL::Exception("DataArrayDouble::back : number of components not equal to one !");
2973   int nbOfTuples=getNumberOfTuples();
2974   if(nbOfTuples<1)
2975     throw INTERP_KERNEL::Exception("DataArrayDouble::back : number of tuples must be >= 1 !");
2976   return *(getConstPointer()+nbOfTuples-1);
2977 }
2978
2979 void DataArrayDouble::SetArrayIn(DataArrayDouble *newArray, DataArrayDouble* &arrayToSet)
2980 {
2981   if(newArray!=arrayToSet)
2982     {
2983       if(arrayToSet)
2984         arrayToSet->decrRef();
2985       arrayToSet=newArray;
2986       if(arrayToSet)
2987         arrayToSet->incrRef();
2988     }
2989 }
2990
2991 /*!
2992  * Sets a C array to be used as raw data of \a this. The previously set info
2993  *  of components is retained and re-sized. 
2994  * For more info see \ref MEDCouplingArraySteps1.
2995  *  \param [in] array - the C array to be used as raw data of \a this.
2996  *  \param [in] ownership - if \a true, \a array will be deallocated at destruction of \a this.
2997  *  \param [in] type - specifies how to deallocate \a array. If \a type == ParaMEDMEM::CPP_DEALLOC,
2998  *                     \c delete [] \c array; will be called. If \a type == ParaMEDMEM::C_DEALLOC,
2999  *                     \c free(\c array ) will be called.
3000  *  \param [in] nbOfTuple - new number of tuples in \a this.
3001  *  \param [in] nbOfCompo - new number of components in \a this.
3002  */
3003 void DataArrayDouble::useArray(const double *array, bool ownership, DeallocType type, int nbOfTuple, int nbOfCompo)
3004 {
3005   _info_on_compo.resize(nbOfCompo);
3006   _mem.useArray(array,ownership,type,(std::size_t)nbOfTuple*nbOfCompo);
3007   declareAsNew();
3008 }
3009
3010 void DataArrayDouble::useExternalArrayWithRWAccess(const double *array, int nbOfTuple, int nbOfCompo)
3011 {
3012   _info_on_compo.resize(nbOfCompo);
3013   _mem.useExternalArrayWithRWAccess(array,(std::size_t)nbOfTuple*nbOfCompo);
3014   declareAsNew();
3015 }
3016
3017 /*!
3018  * Checks if 0.0 value is present in \a this array. If it is the case, an exception
3019  * is thrown.
3020  * \throw If zero is found in \a this array.
3021  */
3022 void DataArrayDouble::checkNoNullValues() const
3023 {
3024   const double *tmp=getConstPointer();
3025   std::size_t nbOfElems=getNbOfElems();
3026   const double *where=std::find(tmp,tmp+nbOfElems,0.);
3027   if(where!=tmp+nbOfElems)
3028     throw INTERP_KERNEL::Exception("A value 0.0 have been detected !");
3029 }
3030
3031 /*!
3032  * Computes minimal and maximal value in each component. An output array is filled
3033  * with \c 2 * \a this->getNumberOfComponents() values, so the caller is to allocate
3034  * enough memory before calling this method.
3035  *  \param [out] bounds - array of size at least 2 *\a this->getNumberOfComponents().
3036  *               It is filled as follows:<br>
3037  *               \a bounds[0] = \c min_of_component_0 <br>
3038  *               \a bounds[1] = \c max_of_component_0 <br>
3039  *               \a bounds[2] = \c min_of_component_1 <br>
3040  *               \a bounds[3] = \c max_of_component_1 <br>
3041  *               ...
3042  */
3043 void DataArrayDouble::getMinMaxPerComponent(double *bounds) const
3044 {
3045   checkAllocated();
3046   int dim=getNumberOfComponents();
3047   for (int idim=0; idim<dim; idim++)
3048     {
3049       bounds[idim*2]=std::numeric_limits<double>::max();
3050       bounds[idim*2+1]=-std::numeric_limits<double>::max();
3051     } 
3052   const double *ptr=getConstPointer();
3053   int nbOfTuples=getNumberOfTuples();
3054   for(int i=0;i<nbOfTuples;i++)
3055     {
3056       for(int idim=0;idim<dim;idim++)
3057         {
3058           if(bounds[idim*2]>ptr[i*dim+idim])
3059             {
3060               bounds[idim*2]=ptr[i*dim+idim];
3061             }
3062           if(bounds[idim*2+1]<ptr[i*dim+idim])
3063             {
3064               bounds[idim*2+1]=ptr[i*dim+idim];
3065             }
3066         }
3067     }
3068 }
3069
3070 /*!
3071  * This method retrieves a newly allocated DataArrayDouble instance having same number of tuples than \a this and twice number of components than \a this
3072  * to store both the min and max per component of each tuples. 
3073  * \param [in] epsilon the width of the bbox (identical in each direction) - 0.0 by default
3074  *
3075  * \return a newly created DataArrayDouble instance having \c this->getNumberOfTuples() tuples and 2 * \c this->getNumberOfComponent() components
3076  *
3077  * \throw If \a this is not allocated yet.
3078  */
3079 DataArrayDouble *DataArrayDouble::computeBBoxPerTuple(double epsilon) const
3080 {
3081   checkAllocated();
3082   const double *dataPtr=getConstPointer();
3083   int nbOfCompo=getNumberOfComponents();
3084   int nbTuples=getNumberOfTuples();
3085   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> bbox=DataArrayDouble::New();
3086   bbox->alloc(nbTuples,2*nbOfCompo);
3087   double *bboxPtr=bbox->getPointer();
3088   for(int i=0;i<nbTuples;i++)
3089     {
3090       for(int j=0;j<nbOfCompo;j++)
3091         {
3092           bboxPtr[2*nbOfCompo*i+2*j]=dataPtr[nbOfCompo*i+j]-epsilon;
3093           bboxPtr[2*nbOfCompo*i+2*j+1]=dataPtr[nbOfCompo*i+j]+epsilon;
3094         }
3095     }
3096   return bbox.retn();
3097 }
3098
3099 /*!
3100  * For each tuples **t** in \a other, this method retrieves tuples in \a this that are equal to **t**.
3101  * Two tuples are considered equal if the euclidian distance between the two tuples is lower than \a eps.
3102  * 
3103  * \param [in] other a DataArrayDouble having same number of components than \a this.
3104  * \param [in] eps absolute precision representing distance (using infinite norm) between 2 tuples behind which 2 tuples are considered equal.
3105  * \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.
3106  *             \a cI allows to extract information in \a c.
3107  * \param [out] cI is an indirection array that allows to extract the data contained in \a c.
3108  *
3109  * \throw In case of:
3110  *  - \a this is not allocated
3111  *  - \a other is not allocated or null
3112  *  - \a this and \a other do not have the same number of components
3113  *  - if number of components of \a this is not in [1,2,3]
3114  *
3115  * \sa MEDCouplingPointSet::getNodeIdsNearPoints, DataArrayDouble::getDifferentValues
3116  */
3117 void DataArrayDouble::computeTupleIdsNearTuples(const DataArrayDouble *other, double eps, DataArrayInt *& c, DataArrayInt *& cI) const
3118 {
3119   if(!other)
3120     throw INTERP_KERNEL::Exception("DataArrayDouble::computeTupleIdsNearTuples : input pointer other is null !");
3121   checkAllocated();
3122   other->checkAllocated();
3123   int nbOfCompo=getNumberOfComponents();
3124   int otherNbOfCompo=other->getNumberOfComponents();
3125   if(nbOfCompo!=otherNbOfCompo)
3126     throw INTERP_KERNEL::Exception("DataArrayDouble::computeTupleIdsNearTuples : number of components should be equal between this and other !");
3127   int nbOfTuplesOther=other->getNumberOfTuples();
3128   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cArr(DataArrayInt::New()),cIArr(DataArrayInt::New()); cArr->alloc(0,1); cIArr->pushBackSilent(0);
3129   switch(nbOfCompo)
3130   {
3131     case 3:
3132       {
3133         BBTreePts<3,int> myTree(begin(),0,0,getNumberOfTuples(),eps);
3134         FindTupleIdsNearTuplesAlg<3>(myTree,other->getConstPointer(),nbOfTuplesOther,eps,cArr,cIArr);
3135         break;
3136       }
3137     case 2:
3138       {
3139         BBTreePts<2,int> myTree(begin(),0,0,getNumberOfTuples(),eps);
3140         FindTupleIdsNearTuplesAlg<2>(myTree,other->getConstPointer(),nbOfTuplesOther,eps,cArr,cIArr);
3141         break;
3142       }
3143     case 1:
3144       {
3145         BBTreePts<1,int> myTree(begin(),0,0,getNumberOfTuples(),eps);
3146         FindTupleIdsNearTuplesAlg<1>(myTree,other->getConstPointer(),nbOfTuplesOther,eps,cArr,cIArr);
3147         break;
3148       }
3149     default:
3150       throw INTERP_KERNEL::Exception("Unexpected spacedim of coords for computeTupleIdsNearTuples. Must be 1, 2 or 3.");
3151   }
3152   c=cArr.retn(); cI=cIArr.retn();
3153 }
3154
3155 /*!
3156  * 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
3157  * around origin of 'radius' 1.
3158  * 
3159  * \param [in] eps absolute epsilon. under that value of delta between max and min no scale is performed.
3160  */
3161 void DataArrayDouble::recenterForMaxPrecision(double eps)
3162 {
3163   checkAllocated();
3164   int dim=getNumberOfComponents();
3165   std::vector<double> bounds(2*dim);
3166   getMinMaxPerComponent(&bounds[0]);
3167   for(int i=0;i<dim;i++)
3168     {
3169       double delta=bounds[2*i+1]-bounds[2*i];
3170       double offset=(bounds[2*i]+bounds[2*i+1])/2.;
3171       if(delta>eps)
3172         applyLin(1./delta,-offset/delta,i);
3173       else
3174         applyLin(1.,-offset,i);
3175     }
3176 }
3177
3178 /*!
3179  * Returns the maximal value and its location within \a this one-dimensional array.
3180  *  \param [out] tupleId - index of the tuple holding the maximal value.
3181  *  \return double - the maximal value among all values of \a this array.
3182  *  \throw If \a this->getNumberOfComponents() != 1
3183  *  \throw If \a this->getNumberOfTuples() < 1
3184  */
3185 double DataArrayDouble::getMaxValue(int& tupleId) const
3186 {
3187   checkAllocated();
3188   if(getNumberOfComponents()!=1)
3189     throw INTERP_KERNEL::Exception("DataArrayDouble::getMaxValue : must be applied on DataArrayDouble with only one component, you can call 'rearrange' method before or call 'getMaxValueInArray' method !");
3190   int nbOfTuples=getNumberOfTuples();
3191   if(nbOfTuples<=0)
3192     throw INTERP_KERNEL::Exception("DataArrayDouble::getMaxValue : array exists but number of tuples must be > 0 !");
3193   const double *vals=getConstPointer();
3194   const double *loc=std::max_element(vals,vals+nbOfTuples);
3195   tupleId=(int)std::distance(vals,loc);
3196   return *loc;
3197 }
3198
3199 /*!
3200  * Returns the maximal value within \a this array that is allowed to have more than
3201  *  one component.
3202  *  \return double - the maximal value among all values of \a this array.
3203  *  \throw If \a this is not allocated.
3204  */
3205 double DataArrayDouble::getMaxValueInArray() const
3206 {
3207   checkAllocated();
3208   const double *loc=std::max_element(begin(),end());
3209   return *loc;
3210 }
3211
3212 /*!
3213  * Returns the maximal value and all its locations within \a this one-dimensional array.
3214  *  \param [out] tupleIds - a new instance of DataArrayInt containg indices of
3215  *               tuples holding the maximal value. The caller is to delete it using
3216  *               decrRef() as it is no more needed.
3217  *  \return double - the maximal value among all values of \a this array.
3218  *  \throw If \a this->getNumberOfComponents() != 1
3219  *  \throw If \a this->getNumberOfTuples() < 1
3220  */
3221 double DataArrayDouble::getMaxValue2(DataArrayInt*& tupleIds) const
3222 {
3223   int tmp;
3224   tupleIds=0;
3225   double ret=getMaxValue(tmp);
3226   tupleIds=getIdsInRange(ret,ret);
3227   return ret;
3228 }
3229
3230 /*!
3231  * Returns the minimal value and its location within \a this one-dimensional array.
3232  *  \param [out] tupleId - index of the tuple holding the minimal value.
3233  *  \return double - the minimal value among all values of \a this array.
3234  *  \throw If \a this->getNumberOfComponents() != 1
3235  *  \throw If \a this->getNumberOfTuples() < 1
3236  */
3237 double DataArrayDouble::getMinValue(int& tupleId) const
3238 {
3239   checkAllocated();
3240   if(getNumberOfComponents()!=1)
3241     throw INTERP_KERNEL::Exception("DataArrayDouble::getMinValue : must be applied on DataArrayDouble with only one component, you can call 'rearrange' method before call 'getMinValueInArray' method !");
3242   int nbOfTuples=getNumberOfTuples();
3243   if(nbOfTuples<=0)
3244     throw INTERP_KERNEL::Exception("DataArrayDouble::getMinValue : array exists but number of tuples must be > 0 !");
3245   const double *vals=getConstPointer();
3246   const double *loc=std::min_element(vals,vals+nbOfTuples);
3247   tupleId=(int)std::distance(vals,loc);
3248   return *loc;
3249 }
3250
3251 /*!
3252  * Returns the minimal value within \a this array that is allowed to have more than
3253  *  one component.
3254  *  \return double - the minimal value among all values of \a this array.
3255  *  \throw If \a this is not allocated.
3256  */
3257 double DataArrayDouble::getMinValueInArray() const
3258 {
3259   checkAllocated();
3260   const double *loc=std::min_element(begin(),end());
3261   return *loc;
3262 }
3263
3264 /*!
3265  * Returns the minimal value and all its locations within \a this one-dimensional array.
3266  *  \param [out] tupleIds - a new instance of DataArrayInt containg indices of
3267  *               tuples holding the minimal value. The caller is to delete it using
3268  *               decrRef() as it is no more needed.
3269  *  \return double - the minimal value among all values of \a this array.
3270  *  \throw If \a this->getNumberOfComponents() != 1
3271  *  \throw If \a this->getNumberOfTuples() < 1
3272  */
3273 double DataArrayDouble::getMinValue2(DataArrayInt*& tupleIds) const
3274 {
3275   int tmp;
3276   tupleIds=0;
3277   double ret=getMinValue(tmp);
3278   tupleIds=getIdsInRange(ret,ret);
3279   return ret;
3280 }
3281
3282 /*!
3283  * 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.
3284  * This method only works for single component array.
3285  *
3286  * \return a value in [ 0, \c this->getNumberOfTuples() )
3287  *
3288  * \throw If \a this is not allocated
3289  *
3290  */
3291 int DataArrayDouble::count(double value, double eps) const
3292 {
3293   int ret=0;
3294   checkAllocated();
3295   if(getNumberOfComponents()!=1)
3296     throw INTERP_KERNEL::Exception("DataArrayDouble::count : must be applied on DataArrayDouble with only one component, you can call 'rearrange' method before !");
3297   const double *vals=begin();
3298   int nbOfTuples=getNumberOfTuples();
3299   for(int i=0;i<nbOfTuples;i++,vals++)
3300     if(fabs(*vals-value)<=eps)
3301       ret++;
3302   return ret;
3303 }
3304
3305 /*!
3306  * Returns the average value of \a this one-dimensional array.
3307  *  \return double - the average value over all values of \a this array.
3308  *  \throw If \a this->getNumberOfComponents() != 1
3309  *  \throw If \a this->getNumberOfTuples() < 1
3310  */
3311 double DataArrayDouble::getAverageValue() const
3312 {
3313   if(getNumberOfComponents()!=1)
3314     throw INTERP_KERNEL::Exception("DataArrayDouble::getAverageValue : must be applied on DataArrayDouble with only one component, you can call 'rearrange' method before !");
3315   int nbOfTuples=getNumberOfTuples();
3316   if(nbOfTuples<=0)
3317     throw INTERP_KERNEL::Exception("DataArrayDouble::getAverageValue : array exists but number of tuples must be > 0 !");
3318   const double *vals=getConstPointer();
3319   double ret=std::accumulate(vals,vals+nbOfTuples,0.);
3320   return ret/nbOfTuples;
3321 }
3322
3323 /*!
3324  * Returns the Euclidean norm of the vector defined by \a this array.
3325  *  \return double - the value of the Euclidean norm, i.e.
3326  *          the square root of the inner product of vector.
3327  *  \throw If \a this is not allocated.
3328  */
3329 double DataArrayDouble::norm2() const
3330 {
3331   checkAllocated();
3332   double ret=0.;
3333   std::size_t nbOfElems=getNbOfElems();
3334   const double *pt=getConstPointer();
3335   for(std::size_t i=0;i<nbOfElems;i++,pt++)
3336     ret+=(*pt)*(*pt);
3337   return sqrt(ret);
3338 }
3339
3340 /*!
3341  * Returns the maximum norm of the vector defined by \a this array.
3342  * This method works even if the number of components is diferent from one.
3343  * If the number of elements in \a this is 0, -1. is returned.
3344  *  \return double - the value of the maximum norm, i.e.
3345  *          the maximal absolute value among values of \a this array (whatever its number of components).
3346  *  \throw If \a this is not allocated.
3347  */
3348 double DataArrayDouble::normMax() const
3349 {
3350   checkAllocated();
3351   double ret(-1.);
3352   std::size_t nbOfElems(getNbOfElems());
3353   const double *pt(getConstPointer());
3354   for(std::size_t i=0;i<nbOfElems;i++,pt++)
3355     {
3356       double val(std::abs(*pt));
3357       if(val>ret)
3358         ret=val;
3359     }
3360   return ret;
3361 }
3362
3363 /*!
3364  * Returns the minimum norm (absolute value) of the vector defined by \a this array.
3365  * This method works even if the number of components is diferent from one.
3366  * If the number of elements in \a this is 0, std::numeric_limits<double>::max() is returned.
3367  *  \return double - the value of the minimum norm, i.e.
3368  *          the minimal absolute value among values of \a this array (whatever its number of components).
3369  *  \throw If \a this is not allocated.
3370  */
3371 double DataArrayDouble::normMin() const
3372 {
3373   checkAllocated();
3374   double ret(std::numeric_limits<double>::max());
3375   std::size_t nbOfElems(getNbOfElems());
3376   const double *pt(getConstPointer());
3377   for(std::size_t i=0;i<nbOfElems;i++,pt++)
3378     {
3379       double val(std::abs(*pt));
3380       if(val<ret)
3381         ret=val;
3382     }
3383   return ret;
3384 }
3385
3386 /*!
3387  * Accumulates values of each component of \a this array.
3388  *  \param [out] res - an array of length \a this->getNumberOfComponents(), allocated 
3389  *         by the caller, that is filled by this method with sum value for each
3390  *         component.
3391  *  \throw If \a this is not allocated.
3392  */
3393 void DataArrayDouble::accumulate(double *res) const
3394 {
3395   checkAllocated();
3396   const double *ptr=getConstPointer();
3397   int nbTuple=getNumberOfTuples();
3398   int nbComps=getNumberOfComponents();
3399   std::fill(res,res+nbComps,0.);
3400   for(int i=0;i<nbTuple;i++)
3401     std::transform(ptr+i*nbComps,ptr+(i+1)*nbComps,res,res,std::plus<double>());
3402 }
3403
3404 /*!
3405  * This method returns the min distance from an external tuple defined by [ \a tupleBg , \a tupleEnd ) to \a this and
3406  * the first tuple in \a this that matches the returned distance. If there is no tuples in \a this an exception will be thrown.
3407  *
3408  *
3409  * \a this is expected to be allocated and expected to have a number of components equal to the distance from \a tupleBg to
3410  * \a tupleEnd. If not an exception will be thrown.
3411  *
3412  * \param [in] tupleBg start pointer (included) of input external tuple
3413  * \param [in] tupleEnd end pointer (not included) of input external tuple
3414  * \param [out] tupleId the tuple id in \a this that matches the min of distance between \a this and input external tuple
3415  * \return the min distance.
3416  * \sa MEDCouplingUMesh::distanceToPoint
3417  */
3418 double DataArrayDouble::distanceToTuple(const double *tupleBg, const double *tupleEnd, int& tupleId) const
3419 {
3420   checkAllocated();
3421   int nbTuple=getNumberOfTuples();
3422   int nbComps=getNumberOfComponents();
3423   if(nbComps!=(int)std::distance(tupleBg,tupleEnd))
3424     { 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()); }
3425   if(nbTuple==0)
3426     throw INTERP_KERNEL::Exception("DataArrayDouble::distanceToTuple : no tuple in this ! No distance to compute !");
3427   double ret0=std::numeric_limits<double>::max();
3428   tupleId=-1;
3429   const double *work=getConstPointer();
3430   for(int i=0;i<nbTuple;i++)
3431     {
3432       double val=0.;
3433       for(int j=0;j<nbComps;j++,work++) 
3434         val+=(*work-tupleBg[j])*((*work-tupleBg[j]));
3435       if(val>=ret0)
3436         continue;
3437       else
3438         { ret0=val; tupleId=i; }
3439     }
3440   return sqrt(ret0);
3441 }
3442
3443 /*!
3444  * Accumulate values of the given component of \a this array.
3445  *  \param [in] compId - the index of the component of interest.
3446  *  \return double - a sum value of \a compId-th component.
3447  *  \throw If \a this is not allocated.
3448  *  \throw If \a the condition ( 0 <= \a compId < \a this->getNumberOfComponents() ) is
3449  *         not respected.
3450  */
3451 double DataArrayDouble::accumulate(int compId) const
3452 {
3453   checkAllocated();
3454   const double *ptr=getConstPointer();
3455   int nbTuple=getNumberOfTuples();
3456   int nbComps=getNumberOfComponents();
3457   if(compId<0 || compId>=nbComps)
3458     throw INTERP_KERNEL::Exception("DataArrayDouble::accumulate : Invalid compId specified : No such nb of components !");
3459   double ret=0.;
3460   for(int i=0;i<nbTuple;i++)
3461     ret+=ptr[i*nbComps+compId];
3462   return ret;
3463 }
3464
3465 /*!
3466  * This method accumulate using addition tuples in \a this using input index array [ \a bgOfIndex, \a endOfIndex ).
3467  * The returned array will have same number of components than \a this and number of tuples equal to
3468  * \c std::distance(bgOfIndex,endOfIndex) \b minus \b one.
3469  *
3470  * The input index array is expected to be ascendingly sorted in which the all referenced ids should be in [0, \c this->getNumberOfTuples).
3471  * 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.
3472  *
3473  * \param [in] bgOfIndex - begin (included) of the input index array.
3474  * \param [in] endOfIndex - end (excluded) of the input index array.
3475  * \return DataArrayDouble * - the new instance having the same number of components than \a this.
3476  * 
3477  * \throw If bgOfIndex or end is NULL.
3478  * \throw If input index array is not ascendingly sorted.
3479  * \throw If there is an id in [ \a bgOfIndex, \a endOfIndex ) not in [0, \c this->getNumberOfTuples).
3480  * \throw If std::distance(bgOfIndex,endOfIndex)==0.
3481  */
3482 DataArrayDouble *DataArrayDouble::accumulatePerChunck(const int *bgOfIndex, const int *endOfIndex) const
3483 {
3484   if(!bgOfIndex || !endOfIndex)
3485     throw INTERP_KERNEL::Exception("DataArrayDouble::accumulatePerChunck : input pointer NULL !");
3486   checkAllocated();
3487   int nbCompo=getNumberOfComponents();
3488   int nbOfTuples=getNumberOfTuples();
3489   int sz=(int)std::distance(bgOfIndex,endOfIndex);
3490   if(sz<1)
3491     throw INTERP_KERNEL::Exception("DataArrayDouble::accumulatePerChunck : invalid size of input index array !");
3492   sz--;
3493   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New(); ret->alloc(sz,nbCompo);
3494   const int *w=bgOfIndex;
3495   if(*w<0 || *w>=nbOfTuples)
3496     throw INTERP_KERNEL::Exception("DataArrayDouble::accumulatePerChunck : The first element of the input index not in [0,nbOfTuples) !");
3497   const double *srcPt=begin()+(*w)*nbCompo;
3498   double *tmp=ret->getPointer();
3499   for(int i=0;i<sz;i++,tmp+=nbCompo,w++)
3500     {
3501       std::fill(tmp,tmp+nbCompo,0.);
3502       if(w[1]>=w[0])
3503         {
3504           for(int j=w[0];j<w[1];j++,srcPt+=nbCompo)
3505             {
3506               if(j>=0 && j<nbOfTuples)
3507                 std::transform(srcPt,srcPt+nbCompo,tmp,tmp,std::plus<double>());
3508               else
3509                 {
3510                   std::ostringstream oss; oss << "DataArrayDouble::accumulatePerChunck : At rank #" << i << " the input index array points to id " << j << " should be in [0," << nbOfTuples << ") !";
3511                   throw INTERP_KERNEL::Exception(oss.str().c_str());
3512                 }
3513             }
3514         }
3515       else
3516         {
3517           std::ostringstream oss; oss << "DataArrayDouble::accumulatePerChunck : At rank #" << i << " the input index array is not in ascendingly sorted.";
3518           throw INTERP_KERNEL::Exception(oss.str().c_str());
3519         }
3520     }
3521   ret->copyStringInfoFrom(*this);
3522   return ret.retn();
3523 }
3524
3525 /*!
3526  * Converts each 2D point defined by the tuple of \a this array from the Polar to the
3527  * Cartesian coordinate system. The two components of the tuple of \a this array are 
3528  * considered to contain (1) radius and (2) angle of the point in the Polar CS.
3529  *  \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
3530  *          contains X and Y coordinates of the point in the Cartesian CS. The caller
3531  *          is to delete this array using decrRef() as it is no more needed. The array
3532  *          does not contain any textual info on components.
3533  *  \throw If \a this->getNumberOfComponents() != 2.
3534  */
3535 DataArrayDouble *DataArrayDouble::fromPolarToCart() const
3536 {
3537   checkAllocated();
3538   int nbOfComp=getNumberOfComponents();
3539   if(nbOfComp!=2)
3540     throw INTERP_KERNEL::Exception("DataArrayDouble::fromPolarToCart : must be an array with exactly 2 components !");
3541   int nbOfTuple=getNumberOfTuples();
3542   DataArrayDouble *ret=DataArrayDouble::New();
3543   ret->alloc(nbOfTuple,2);
3544   double *w=ret->getPointer();
3545   const double *wIn=getConstPointer();
3546   for(int i=0;i<nbOfTuple;i++,w+=2,wIn+=2)
3547     {
3548       w[0]=wIn[0]*cos(wIn[1]);
3549       w[1]=wIn[0]*sin(wIn[1]);
3550     }
3551   return ret;
3552 }
3553
3554 /*!
3555  * Converts each 3D point defined by the tuple of \a this array from the Cylindrical to
3556  * the Cartesian coordinate system. The three components of the tuple of \a this array 
3557  * are considered to contain (1) radius, (2) azimuth and (3) altitude of the point in
3558  * the Cylindrical CS.
3559  *  \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
3560  *          contains X, Y and Z coordinates of the point in the Cartesian CS. The info
3561  *          on the third component is copied from \a this array. The caller
3562  *          is to delete this array using decrRef() as it is no more needed. 
3563  *  \throw If \a this->getNumberOfComponents() != 3.
3564  */
3565 DataArrayDouble *DataArrayDouble::fromCylToCart() const
3566 {
3567   checkAllocated();
3568   int nbOfComp=getNumberOfComponents();
3569   if(nbOfComp!=3)
3570     throw INTERP_KERNEL::Exception("DataArrayDouble::fromCylToCart : must be an array with exactly 3 components !");
3571   int nbOfTuple=getNumberOfTuples();
3572   DataArrayDouble *ret=DataArrayDouble::New();
3573   ret->alloc(getNumberOfTuples(),3);
3574   double *w=ret->getPointer();
3575   const double *wIn=getConstPointer();
3576   for(int i=0;i<nbOfTuple;i++,w+=3,wIn+=3)
3577     {
3578       w[0]=wIn[0]*cos(wIn[1]);
3579       w[1]=wIn[0]*sin(wIn[1]);
3580       w[2]=wIn[2];
3581     }
3582   ret->setInfoOnComponent(2,getInfoOnComponent(2));
3583   return ret;
3584 }
3585
3586 /*!
3587  * Converts each 3D point defined by the tuple of \a this array from the Spherical to
3588  * the Cartesian coordinate system. The three components of the tuple of \a this array 
3589  * are considered to contain (1) radius, (2) polar angle and (3) azimuthal angle of the
3590  * point in the Cylindrical CS.
3591  *  \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
3592  *          contains X, Y and Z coordinates of the point in the Cartesian CS. The info
3593  *          on the third component is copied from \a this array. The caller
3594  *          is to delete this array using decrRef() as it is no more needed.
3595  *  \throw If \a this->getNumberOfComponents() != 3.
3596  */
3597 DataArrayDouble *DataArrayDouble::fromSpherToCart() const
3598 {
3599   checkAllocated();
3600   int nbOfComp=getNumberOfComponents();
3601   if(nbOfComp!=3)
3602     throw INTERP_KERNEL::Exception("DataArrayDouble::fromSpherToCart : must be an array with exactly 3 components !");
3603   int nbOfTuple=getNumberOfTuples();
3604   DataArrayDouble *ret=DataArrayDouble::New();
3605   ret->alloc(getNumberOfTuples(),3);
3606   double *w=ret->getPointer();
3607   const double *wIn=getConstPointer();
3608   for(int i=0;i<nbOfTuple;i++,w+=3,wIn+=3)
3609     {
3610       w[0]=wIn[0]*cos(wIn[2])*sin(wIn[1]);
3611       w[1]=wIn[0]*sin(wIn[2])*sin(wIn[1]);
3612       w[2]=wIn[0]*cos(wIn[1]);
3613     }
3614   return ret;
3615 }
3616
3617 /*!
3618  * Computes the doubly contracted product of every tensor defined by the tuple of \a this
3619  * array contating 6 components.
3620  *  \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
3621  *          is calculated from the tuple <em>(t)</em> of \a this array as follows:
3622  *          \f$ t[0]^2+t[1]^2+t[2]^2+2*t[3]^2+2*t[4]^2+2*t[5]^2\f$.
3623  *         The caller is to delete this result array using decrRef() as it is no more needed. 
3624  *  \throw If \a this->getNumberOfComponents() != 6.
3625  */
3626 DataArrayDouble *DataArrayDouble::doublyContractedProduct() const
3627 {
3628   checkAllocated();
3629   int nbOfComp=getNumberOfComponents();
3630   if(nbOfComp!=6)
3631     throw INTERP_KERNEL::Exception("DataArrayDouble::doublyContractedProduct : must be an array with exactly 6 components !");
3632   DataArrayDouble *ret=DataArrayDouble::New();
3633   int nbOfTuple=getNumberOfTuples();
3634   ret->alloc(nbOfTuple,1);
3635   const double *src=getConstPointer();
3636   double *dest=ret->getPointer();
3637   for(int i=0;i<nbOfTuple;i++,dest++,src+=6)
3638     *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];
3639   return ret;
3640 }
3641
3642 /*!
3643  * Computes the determinant of every square matrix defined by the tuple of \a this
3644  * array, which contains either 4, 6 or 9 components. The case of 6 components
3645  * corresponds to that of the upper triangular matrix.
3646  *  \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
3647  *          is the determinant of matrix of the corresponding tuple of \a this array.
3648  *          The caller is to delete this result array using decrRef() as it is no more
3649  *          needed. 
3650  *  \throw If \a this->getNumberOfComponents() is not in [4,6,9].
3651  */
3652 DataArrayDouble *DataArrayDouble::determinant() const
3653 {
3654   checkAllocated();
3655   DataArrayDouble *ret=DataArrayDouble::New();
3656   int nbOfTuple=getNumberOfTuples();
3657   ret->alloc(nbOfTuple,1);
3658   const double *src=getConstPointer();
3659   double *dest=ret->getPointer();
3660   switch(getNumberOfComponents())
3661   {
3662     case 6:
3663       for(int i=0;i<nbOfTuple;i++,dest++,src+=6)
3664         *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];
3665       return ret;
3666     case 4:
3667       for(int i=0;i<nbOfTuple;i++,dest++,src+=4)
3668         *dest=src[0]*src[3]-src[1]*src[2];
3669       return ret;
3670     case 9:
3671       for(int i=0;i<nbOfTuple;i++,dest++,src+=9)
3672         *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];
3673       return ret;
3674     default:
3675       ret->decrRef();
3676       throw INTERP_KERNEL::Exception("DataArrayDouble::determinant : Invalid number of components ! must be in 4,6,9 !");
3677   }
3678 }
3679
3680 /*!
3681  * Computes 3 eigenvalues of every upper triangular matrix defined by the tuple of
3682  * \a this array, which contains 6 components.
3683  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing 3
3684  *          components, whose each tuple contains the eigenvalues of the matrix of
3685  *          corresponding tuple of \a this array. 
3686  *          The caller is to delete this result array using decrRef() as it is no more
3687  *          needed. 
3688  *  \throw If \a this->getNumberOfComponents() != 6.
3689  */
3690 DataArrayDouble *DataArrayDouble::eigenValues() const
3691 {
3692   checkAllocated();
3693   int nbOfComp=getNumberOfComponents();
3694   if(nbOfComp!=6)
3695     throw INTERP_KERNEL::Exception("DataArrayDouble::eigenValues : must be an array with exactly 6 components !");
3696   DataArrayDouble *ret=DataArrayDouble::New();
3697   int nbOfTuple=getNumberOfTuples();
3698   ret->alloc(nbOfTuple,3);
3699   const double *src=getConstPointer();
3700   double *dest=ret->getPointer();
3701   for(int i=0;i<nbOfTuple;i++,dest+=3,src+=6)
3702     INTERP_KERNEL::computeEigenValues6(src,dest);
3703   return ret;
3704 }
3705
3706 /*!
3707  * Computes 3 eigenvectors of every upper triangular matrix defined by the tuple of
3708  * \a this array, which contains 6 components.
3709  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing 9
3710  *          components, whose each tuple contains 3 eigenvectors of the matrix of
3711  *          corresponding tuple of \a this array.
3712  *          The caller is to delete this result array using decrRef() as it is no more
3713  *          needed.
3714  *  \throw If \a this->getNumberOfComponents() != 6.
3715  */
3716 DataArrayDouble *DataArrayDouble::eigenVectors() const
3717 {
3718   checkAllocated();
3719   int nbOfComp=getNumberOfComponents();
3720   if(nbOfComp!=6)
3721     throw INTERP_KERNEL::Exception("DataArrayDouble::eigenVectors : must be an array with exactly 6 components !");
3722   DataArrayDouble *ret=DataArrayDouble::New();
3723   int nbOfTuple=getNumberOfTuples();
3724   ret->alloc(nbOfTuple,9);
3725   const double *src=getConstPointer();
3726   double *dest=ret->getPointer();
3727   for(int i=0;i<nbOfTuple;i++,src+=6)
3728     {
3729       double tmp[3];
3730       INTERP_KERNEL::computeEigenValues6(src,tmp);
3731       for(int j=0;j<3;j++,dest+=3)
3732         INTERP_KERNEL::computeEigenVectorForEigenValue6(src,tmp[j],1e-12,dest);
3733     }
3734   return ret;
3735 }
3736
3737 /*!
3738  * Computes the inverse matrix of every matrix defined by the tuple of \a this
3739  * array, which contains either 4, 6 or 9 components. The case of 6 components
3740  * corresponds to that of the upper triangular matrix.
3741  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
3742  *          same number of components as \a this one, whose each tuple is the inverse
3743  *          matrix of the matrix of corresponding tuple of \a this array. 
3744  *          The caller is to delete this result array using decrRef() as it is no more
3745  *          needed. 
3746  *  \throw If \a this->getNumberOfComponents() is not in [4,6,9].
3747  */
3748 DataArrayDouble *DataArrayDouble::inverse() const
3749 {
3750   checkAllocated();
3751   int nbOfComp=getNumberOfComponents();
3752   if(nbOfComp!=6 && nbOfComp!=9 && nbOfComp!=4)
3753     throw INTERP_KERNEL::Exception("DataArrayDouble::inversion : must be an array with 4,6 or 9 components !");
3754   DataArrayDouble *ret=DataArrayDouble::New();
3755   int nbOfTuple=getNumberOfTuples();
3756   ret->alloc(nbOfTuple,nbOfComp);
3757   const double *src=getConstPointer();
3758   double *dest=ret->getPointer();
3759   if(nbOfComp==6)
3760     for(int i=0;i<nbOfTuple;i++,dest+=6,src+=6)
3761       {
3762         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];
3763         dest[0]=(src[1]*src[2]-src[4]*src[4])/det;
3764         dest[1]=(src[0]*src[2]-src[5]*src[5])/det;
3765         dest[2]=(src[0]*src[1]-src[3]*src[3])/det;
3766         dest[3]=(src[5]*src[4]-src[3]*src[2])/det;
3767         dest[4]=(src[5]*src[3]-src[0]*src[4])/det;
3768         dest[5]=(src[3]*src[4]-src[1]*src[5])/det;
3769       }
3770   else if(nbOfComp==4)
3771     for(int i=0;i<nbOfTuple;i++,dest+=4,src+=4)
3772       {
3773         double det=src[0]*src[3]-src[1]*src[2];
3774         dest[0]=src[3]/det;
3775         dest[1]=-src[1]/det;
3776         dest[2]=-src[2]/det;
3777         dest[3]=src[0]/det;
3778       }
3779   else
3780     for(int i=0;i<nbOfTuple;i++,dest+=9,src+=9)
3781       {
3782         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];
3783         dest[0]=(src[4]*src[8]-src[7]*src[5])/det;
3784         dest[1]=(src[7]*src[2]-src[1]*src[8])/det;
3785         dest[2]=(src[1]*src[5]-src[4]*src[2])/det;
3786         dest[3]=(src[6]*src[5]-src[3]*src[8])/det;
3787         dest[4]=(src[0]*src[8]-src[6]*src[2])/det;
3788         dest[5]=(src[2]*src[3]-src[0]*src[5])/det;
3789         dest[6]=(src[3]*src[7]-src[6]*src[4])/det;
3790         dest[7]=(src[6]*src[1]-src[0]*src[7])/det;
3791         dest[8]=(src[0]*src[4]-src[1]*src[3])/det;
3792       }
3793   return ret;
3794 }
3795
3796 /*!
3797  * Computes the trace of every matrix defined by the tuple of \a this
3798  * array, which contains either 4, 6 or 9 components. The case of 6 components
3799  * corresponds to that of the upper triangular matrix.
3800  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing 
3801  *          1 component, whose each tuple is the trace of
3802  *          the matrix of corresponding tuple of \a this array. 
3803  *          The caller is to delete this result array using decrRef() as it is no more
3804  *          needed. 
3805  *  \throw If \a this->getNumberOfComponents() is not in [4,6,9].
3806  */
3807 DataArrayDouble *DataArrayDouble::trace() const
3808 {
3809   checkAllocated();
3810   int nbOfComp=getNumberOfComponents();
3811   if(nbOfComp!=6 && nbOfComp!=9 && nbOfComp!=4)
3812     throw INTERP_KERNEL::Exception("DataArrayDouble::trace : must be an array with 4,6 or 9 components !");
3813   DataArrayDouble *ret=DataArrayDouble::New();
3814   int nbOfTuple=getNumberOfTuples();
3815   ret->alloc(nbOfTuple,1);
3816   const double *src=getConstPointer();
3817   double *dest=ret->getPointer();
3818   if(nbOfComp==6)
3819     for(int i=0;i<nbOfTuple;i++,dest++,src+=6)
3820       *dest=src[0]+src[1]+src[2];
3821   else if(nbOfComp==4)
3822     for(int i=0;i<nbOfTuple;i++,dest++,src+=4)
3823       *dest=src[0]+src[3];
3824   else
3825     for(int i=0;i<nbOfTuple;i++,dest++,src+=9)
3826       *dest=src[0]+src[4]+src[8];
3827   return ret;
3828 }
3829
3830 /*!
3831  * Computes the stress deviator tensor of every stress tensor defined by the tuple of
3832  * \a this array, which contains 6 components.
3833  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
3834  *          same number of components and tuples as \a this array.
3835  *          The caller is to delete this result array using decrRef() as it is no more
3836  *          needed.
3837  *  \throw If \a this->getNumberOfComponents() != 6.
3838  */
3839 DataArrayDouble *DataArrayDouble::deviator() const
3840 {
3841   checkAllocated();
3842   int nbOfComp=getNumberOfComponents();
3843   if(nbOfComp!=6)
3844     throw INTERP_KERNEL::Exception("DataArrayDouble::deviator : must be an array with exactly 6 components !");
3845   DataArrayDouble *ret=DataArrayDouble::New();
3846   int nbOfTuple=getNumberOfTuples();
3847   ret->alloc(nbOfTuple,6);
3848   const double *src=getConstPointer();
3849   double *dest=ret->getPointer();
3850   for(int i=0;i<nbOfTuple;i++,dest+=6,src+=6)
3851     {
3852       double tr=(src[0]+src[1]+src[2])/3.;
3853       dest[0]=src[0]-tr;
3854       dest[1]=src[1]-tr;
3855       dest[2]=src[2]-tr;
3856       dest[3]=src[3];
3857       dest[4]=src[4];
3858       dest[5]=src[5];
3859     }
3860   return ret;
3861 }
3862
3863 /*!
3864  * Computes the magnitude of every vector defined by the tuple of
3865  * \a this array.
3866  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
3867  *          same number of tuples as \a this array and one component.
3868  *          The caller is to delete this result array using decrRef() as it is no more
3869  *          needed.
3870  *  \throw If \a this is not allocated.
3871  */
3872 DataArrayDouble *DataArrayDouble::magnitude() const
3873 {
3874   checkAllocated();
3875   int nbOfComp=getNumberOfComponents();
3876   DataArrayDouble *ret=DataArrayDouble::New();
3877   int nbOfTuple=getNumberOfTuples();
3878   ret->alloc(nbOfTuple,1);
3879   const double *src=getConstPointer();
3880   double *dest=ret->getPointer();
3881   for(int i=0;i<nbOfTuple;i++,dest++)
3882     {
3883       double sum=0.;
3884       for(int j=0;j<nbOfComp;j++,src++)
3885         sum+=(*src)*(*src);
3886       *dest=sqrt(sum);
3887     }
3888   return ret;
3889 }
3890
3891 /*!
3892  * Computes for each tuple the sum of number of components values in the tuple and return it.
3893  * 
3894  * \return DataArrayDouble * - the new instance of DataArrayDouble containing the
3895  *          same number of tuples as \a this array and one component.
3896  *          The caller is to delete this result array using decrRef() as it is no more
3897  *          needed.
3898  *  \throw If \a this is not allocated.
3899  */
3900 DataArrayDouble *DataArrayDouble::sumPerTuple() const
3901 {
3902   checkAllocated();
3903   int nbOfComp(getNumberOfComponents()),nbOfTuple(getNumberOfTuples());
3904   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret(DataArrayDouble::New());
3905   ret->alloc(nbOfTuple,1);
3906   const double *src(getConstPointer());
3907   double *dest(ret->getPointer());
3908   for(int i=0;i<nbOfTuple;i++,dest++,src+=nbOfComp)
3909     *dest=std::accumulate(src,src+nbOfComp,0.);
3910   return ret.retn();
3911 }
3912
3913 /*!
3914  * Computes the maximal value within every tuple of \a this array.
3915  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
3916  *          same number of tuples as \a this array and one component.
3917  *          The caller is to delete this result array using decrRef() as it is no more
3918  *          needed.
3919  *  \throw If \a this is not allocated.
3920  *  \sa DataArrayDouble::maxPerTupleWithCompoId
3921  */
3922 DataArrayDouble *DataArrayDouble::maxPerTuple() const
3923 {
3924   checkAllocated();
3925   int nbOfComp=getNumberOfComponents();
3926   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
3927   int nbOfTuple=getNumberOfTuples();
3928   ret->alloc(nbOfTuple,1);
3929   const double *src=getConstPointer();
3930   double *dest=ret->getPointer();
3931   for(int i=0;i<nbOfTuple;i++,dest++,src+=nbOfComp)
3932     *dest=*std::max_element(src,src+nbOfComp);
3933   return ret.retn();
3934 }
3935
3936 /*!
3937  * Computes the maximal value within every tuple of \a this array and it returns the first component
3938  * id for each tuple that corresponds to the maximal value within the tuple.
3939  * 
3940  *  \param [out] compoIdOfMaxPerTuple - the new new instance of DataArrayInt containing the
3941  *          same number of tuples and only one component.
3942  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
3943  *          same number of tuples as \a this array and one component.
3944  *          The caller is to delete this result array using decrRef() as it is no more
3945  *          needed.
3946  *  \throw If \a this is not allocated.
3947  *  \sa DataArrayDouble::maxPerTuple
3948  */
3949 DataArrayDouble *DataArrayDouble::maxPerTupleWithCompoId(DataArrayInt* &compoIdOfMaxPerTuple) const
3950 {
3951   checkAllocated();
3952   int nbOfComp=getNumberOfComponents();
3953   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret0=DataArrayDouble::New();
3954   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret1=DataArrayInt::New();
3955   int nbOfTuple=getNumberOfTuples();
3956   ret0->alloc(nbOfTuple,1); ret1->alloc(nbOfTuple,1);
3957   const double *src=getConstPointer();
3958   double *dest=ret0->getPointer(); int *dest1=ret1->getPointer();
3959   for(int i=0;i<nbOfTuple;i++,dest++,dest1++,src+=nbOfComp)
3960     {
3961       const double *loc=std::max_element(src,src+nbOfComp);
3962       *dest=*loc;
3963       *dest1=(int)std::distance(src,loc);
3964     }
3965   compoIdOfMaxPerTuple=ret1.retn();
3966   return ret0.retn();
3967 }
3968
3969 /*!
3970  * This method returns a newly allocated DataArrayDouble instance having one component and \c this->getNumberOfTuples() * \c this->getNumberOfTuples() tuples.
3971  * \n This returned array contains the euclidian distance for each tuple in \a this. 
3972  * \n So the returned array can be seen as a dense symmetrical matrix whose diagonal elements are equal to 0.
3973  * \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)
3974  *
3975  * \warning use this method with care because it can leads to big amount of consumed memory !
3976  * 
3977  * \return A newly allocated (huge) ParaMEDMEM::DataArrayDouble instance that the caller should deal with.
3978  *
3979  * \throw If \a this is not allocated.
3980  *
3981  * \sa DataArrayDouble::buildEuclidianDistanceDenseMatrixWith
3982  */
3983 DataArrayDouble *DataArrayDouble::buildEuclidianDistanceDenseMatrix() const
3984 {
3985   checkAllocated();
3986   int nbOfComp=getNumberOfComponents();
3987   int nbOfTuples=getNumberOfTuples();
3988   const double *inData=getConstPointer();
3989   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
3990   ret->alloc(nbOfTuples*nbOfTuples,1);
3991   double *outData=ret->getPointer();
3992   for(int i=0;i<nbOfTuples;i++)
3993     {
3994       outData[i*nbOfTuples+i]=0.;
3995       for(int j=i+1;j<nbOfTuples;j++)
3996         {
3997           double dist=0.;
3998           for(int k=0;k<nbOfComp;k++)
3999             { double delta=inData[i*nbOfComp+k]-inData[j*nbOfComp+k]; dist+=delta*delta; }
4000           dist=sqrt(dist);
4001           outData[i*nbOfTuples+j]=dist;
4002           outData[j*nbOfTuples+i]=dist;
4003         }
4004     }
4005   return ret.retn();
4006 }
4007
4008 /*!
4009  * This method returns a newly allocated DataArrayDouble instance having one component and \c this->getNumberOfTuples() * \c other->getNumberOfTuples() tuples.
4010  * \n This returned array contains the euclidian distance for each tuple in \a other with each tuple in \a this. 
4011  * \n So the returned array can be seen as a dense rectangular matrix with \c other->getNumberOfTuples() rows and \c this->getNumberOfTuples() columns.
4012  * \n Output rectangular matrix is sorted along rows.
4013  * \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)
4014  *
4015  * \warning use this method with care because it can leads to big amount of consumed memory !
4016  * 
4017  * \param [in] other DataArrayDouble instance having same number of components than \a this.
4018  * \return A newly allocated (huge) ParaMEDMEM::DataArrayDouble instance that the caller should deal with.
4019  *
4020  * \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.
4021  *
4022  * \sa DataArrayDouble::buildEuclidianDistanceDenseMatrix
4023  */
4024 DataArrayDouble *DataArrayDouble::buildEuclidianDistanceDenseMatrixWith(const DataArrayDouble *other) const
4025 {
4026   if(!other)
4027     throw INTERP_KERNEL::Exception("DataArrayDouble::buildEuclidianDistanceDenseMatrixWith : input parameter is null !");
4028   checkAllocated();
4029   other->checkAllocated();
4030   int nbOfComp=getNumberOfComponents();
4031   int otherNbOfComp=other->getNumberOfComponents();
4032   if(nbOfComp!=otherNbOfComp)
4033     {
4034       std::ostringstream oss; oss << "DataArrayDouble::buildEuclidianDistanceDenseMatrixWith : this nb of compo=" << nbOfComp << " and other nb of compo=" << otherNbOfComp << ". It should match !";
4035       throw INTERP_KERNEL::Exception(oss.str().c_str());
4036     }
4037   int nbOfTuples=getNumberOfTuples();
4038   int otherNbOfTuples=other->getNumberOfTuples();
4039   const double *inData=getConstPointer();
4040   const double *inDataOther=other->getConstPointer();
4041   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
4042   ret->alloc(otherNbOfTuples*nbOfTuples,1);
4043   double *outData=ret->getPointer();
4044   for(int i=0;i<otherNbOfTuples;i++,inDataOther+=nbOfComp)
4045     {
4046       for(int j=0;j<nbOfTuples;j++)
4047         {
4048           double dist=0.;
4049           for(int k=0;k<nbOfComp;k++)
4050             { double delta=inDataOther[k]-inData[j*nbOfComp+k]; dist+=delta*delta; }
4051           dist=sqrt(dist);
4052           outData[i*nbOfTuples+j]=dist;
4053         }
4054     }
4055   return ret.retn();
4056 }
4057
4058 /*!
4059  * Sorts value within every tuple of \a this array.
4060  *  \param [in] asc - if \a true, the values are sorted in ascending order, else,
4061  *              in descending order.
4062  *  \throw If \a this is not allocated.
4063  */
4064 void DataArrayDouble::sortPerTuple(bool asc)
4065 {
4066   checkAllocated();
4067   double *pt=getPointer();
4068   int nbOfTuple=getNumberOfTuples();
4069   int nbOfComp=getNumberOfComponents();
4070   if(asc)
4071     for(int i=0;i<nbOfTuple;i++,pt+=nbOfComp)
4072       std::sort(pt,pt+nbOfComp);
4073   else
4074     for(int i=0;i<nbOfTuple;i++,pt+=nbOfComp)
4075       std::sort(pt,pt+nbOfComp,std::greater<double>());
4076   declareAsNew();
4077 }
4078
4079 /*!
4080  * Converts every value of \a this array to its absolute value.
4081  * \b WARNING this method is non const. If a new DataArrayDouble instance should be built containing the result of abs DataArrayDouble::computeAbs
4082  * should be called instead.
4083  *
4084  * \throw If \a this is not allocated.
4085  * \sa DataArrayDouble::computeAbs
4086  */
4087 void DataArrayDouble::abs()
4088 {
4089   checkAllocated();
4090   double *ptr(getPointer());
4091   std::size_t nbOfElems(getNbOfElems());
4092   std::transform(ptr,ptr+nbOfElems,ptr,std::ptr_fun<double,double>(fabs));
4093   declareAsNew();
4094 }
4095
4096 /*!
4097  * This method builds a new instance of \a this object containing the result of std::abs applied of all elements in \a this.
4098  * This method is a const method (that do not change any values in \a this) contrary to  DataArrayDouble::abs method.
4099  *
4100  * \return DataArrayDouble * - the new instance of DataArrayDouble containing the
4101  *         same number of tuples and component as \a this array.
4102  *         The caller is to delete this result array using decrRef() as it is no more
4103  *         needed.
4104  * \throw If \a this is not allocated.
4105  * \sa DataArrayDouble::abs
4106  */
4107 DataArrayDouble *DataArrayDouble::computeAbs() const
4108 {
4109   checkAllocated();
4110   DataArrayDouble *newArr(DataArrayDouble::New());
4111   int nbOfTuples(getNumberOfTuples());
4112   int nbOfComp(getNumberOfComponents());
4113   newArr->alloc(nbOfTuples,nbOfComp);
4114   std::transform(begin(),end(),newArr->getPointer(),std::ptr_fun<double,double>(fabs));
4115   newArr->copyStringInfoFrom(*this);
4116   return newArr;
4117 }
4118
4119 /*!
4120  * Apply a linear function to a given component of \a this array, so that
4121  * an array element <em>(x)</em> becomes \f$ a * x + b \f$.
4122  *  \param [in] a - the first coefficient of the function.
4123  *  \param [in] b - the second coefficient of the function.
4124  *  \param [in] compoId - the index of component to modify.
4125  *  \throw If \a this is not allocated, or \a compoId is not in [0,\c this->getNumberOfComponents() ).
4126  */
4127 void DataArrayDouble::applyLin(double a, double b, int compoId)
4128 {
4129   checkAllocated();
4130   double *ptr(getPointer()+compoId);
4131   int nbOfComp(getNumberOfComponents()),nbOfTuple(getNumberOfTuples());
4132   if(compoId<0 || compoId>=nbOfComp)
4133     {
4134       std::ostringstream oss; oss << "DataArrayDouble::applyLin : The compoId requested (" << compoId << ") is not valid ! Must be in [0," << nbOfComp << ") !";
4135       throw INTERP_KERNEL::Exception(oss.str().c_str());
4136     }
4137   for(int i=0;i<nbOfTuple;i++,ptr+=nbOfComp)
4138     *ptr=a*(*ptr)+b;
4139   declareAsNew();
4140 }
4141
4142 /*!
4143  * Apply a linear function to all elements of \a this array, so that
4144  * an element _x_ becomes \f$ a * x + b \f$.
4145  *  \param [in] a - the first coefficient of the function.
4146  *  \param [in] b - the second coefficient of the function.
4147  *  \throw If \a this is not allocated.
4148  */
4149 void DataArrayDouble::applyLin(double a, double b)
4150 {
4151   checkAllocated();
4152   double *ptr=getPointer();
4153   std::size_t nbOfElems=getNbOfElems();
4154   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
4155     *ptr=a*(*ptr)+b;
4156   declareAsNew();
4157 }
4158
4159 /*!
4160  * Modify all elements of \a this array, so that
4161  * an element _x_ becomes \f$ numerator / x \f$.
4162  *  \warning If an exception is thrown because of presence of 0.0 element in \a this 
4163  *           array, all elements processed before detection of the zero element remain
4164  *           modified.
4165  *  \param [in] numerator - the numerator used to modify array elements.
4166  *  \throw If \a this is not allocated.
4167  *  \throw If there is an element equal to 0.0 in \a this array.
4168  */
4169 void DataArrayDouble::applyInv(double numerator)
4170 {
4171   checkAllocated();
4172   double *ptr=getPointer();
4173   std::size_t nbOfElems=getNbOfElems();
4174   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
4175     {
4176       if(std::abs(*ptr)>std::numeric_limits<double>::min())
4177         {
4178           *ptr=numerator/(*ptr);
4179         }
4180       else
4181         {
4182           std::ostringstream oss; oss << "DataArrayDouble::applyInv : presence of null value in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
4183           oss << " !";
4184           throw INTERP_KERNEL::Exception(oss.str().c_str());
4185         }
4186     }
4187   declareAsNew();
4188 }
4189
4190 /*!
4191  * Returns a full copy of \a this array except that sign of all elements is reversed.
4192  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
4193  *          same number of tuples and component as \a this array.
4194  *          The caller is to delete this result array using decrRef() as it is no more
4195  *          needed.
4196  *  \throw If \a this is not allocated.
4197  */
4198 DataArrayDouble *DataArrayDouble::negate() const
4199 {
4200   checkAllocated();
4201   DataArrayDouble *newArr=DataArrayDouble::New();
4202   int nbOfTuples=getNumberOfTuples();
4203   int nbOfComp=getNumberOfComponents();
4204   newArr->alloc(nbOfTuples,nbOfComp);
4205   const double *cptr=getConstPointer();
4206   std::transform(cptr,cptr+nbOfTuples*nbOfComp,newArr->getPointer(),std::negate<double>());
4207   newArr->copyStringInfoFrom(*this);
4208   return newArr;
4209 }
4210
4211 /*!
4212  * Modify all elements of \a this array, so that
4213  * an element _x_ becomes <em> val ^ x </em>. Contrary to DataArrayInt::applyPow
4214  * all values in \a this have to be >= 0 if val is \b not integer.
4215  *  \param [in] val - the value used to apply pow on all array elements.
4216  *  \throw If \a this is not allocated.
4217  *  \warning If an exception is thrown because of presence of 0 element in \a this 
4218  *           array and \a val is \b not integer, all elements processed before detection of the zero element remain
4219  *           modified.
4220  */
4221 void DataArrayDouble::applyPow(double val)
4222 {
4223   checkAllocated();
4224   double *ptr=getPointer();
4225   std::size_t nbOfElems=getNbOfElems();
4226   int val2=(int)val;
4227   bool isInt=((double)val2)==val;
4228   if(!isInt)
4229     {
4230       for(std::size_t i=0;i<nbOfElems;i++,ptr++)
4231         {
4232           if(*ptr>=0)
4233             *ptr=pow(*ptr,val);
4234           else
4235             {
4236               std::ostringstream oss; oss << "DataArrayDouble::applyPow (double) : At elem # " << i << " value is " << *ptr << " ! must be >=0. !";
4237               throw INTERP_KERNEL::Exception(oss.str().c_str());
4238             }
4239         }
4240     }
4241   else
4242     {
4243       for(std::size_t i=0;i<nbOfElems;i++,ptr++)
4244         *ptr=pow(*ptr,val2);
4245     }
4246   declareAsNew();
4247 }
4248
4249 /*!
4250  * Modify all elements of \a this array, so that
4251  * an element _x_ becomes \f$ val ^ x \f$.
4252  *  \param [in] val - the value used to apply pow on all array elements.
4253  *  \throw If \a this is not allocated.
4254  *  \throw If \a val < 0.
4255  *  \warning If an exception is thrown because of presence of 0 element in \a this 
4256  *           array, all elements processed before detection of the zero element remain
4257  *           modified.
4258  */
4259 void DataArrayDouble::applyRPow(double val)
4260 {
4261   checkAllocated();
4262   if(val<0.)
4263     throw INTERP_KERNEL::Exception("DataArrayDouble::applyRPow : the input value has to be >= 0 !");
4264   double *ptr=getPointer();
4265   std::size_t nbOfElems=getNbOfElems();
4266   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
4267     *ptr=pow(val,*ptr);
4268   declareAsNew();
4269 }
4270
4271 /*!
4272  * Returns a new DataArrayDouble created from \a this one by applying \a
4273  * FunctionToEvaluate to every tuple of \a this array. Textual data is not copied.
4274  * For more info see \ref MEDCouplingArrayApplyFunc
4275  *  \param [in] nbOfComp - number of components in the result array.
4276  *  \param [in] func - the \a FunctionToEvaluate declared as 
4277  *              \c bool (*\a func)(\c const \c double *\a pos, \c double *\a res), 
4278  *              where \a pos points to the first component of a tuple of \a this array
4279  *              and \a res points to the first component of a tuple of the result array.
4280  *              Note that length (number of components) of \a pos can differ from
4281  *              that of \a res.
4282  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
4283  *          same number of tuples as \a this array.
4284  *          The caller is to delete this result array using decrRef() as it is no more
4285  *          needed.
4286  *  \throw If \a this is not allocated.
4287  *  \throw If \a func returns \a false.
4288  */
4289 DataArrayDouble *DataArrayDouble::applyFunc(int nbOfComp, FunctionToEvaluate func) const
4290 {
4291   checkAllocated();
4292   DataArrayDouble *newArr=DataArrayDouble::New();
4293   int nbOfTuples=getNumberOfTuples();
4294   int oldNbOfComp=getNumberOfComponents();
4295   newArr->alloc(nbOfTuples,nbOfComp);
4296   const double *ptr=getConstPointer();
4297   double *ptrToFill=newArr->getPointer();
4298   for(int i=0;i<nbOfTuples;i++)
4299     {
4300       if(!func(ptr+i*oldNbOfComp,ptrToFill+i*nbOfComp))
4301         {
4302           std::ostringstream oss; oss << "For tuple # " << i << " with value (";
4303           std::copy(ptr+oldNbOfComp*i,ptr+oldNbOfComp*(i+1),std::ostream_iterator<double>(oss,", "));
4304           oss << ") : Evaluation of function failed !";
4305           newArr->decrRef();
4306           throw INTERP_KERNEL::Exception(oss.str().c_str());
4307         }
4308     }
4309   return newArr;
4310 }
4311
4312 /*!
4313  * Returns a new DataArrayDouble created from \a this one by applying a function to every
4314  * tuple of \a this array. Textual data is not copied.
4315  * For more info see \ref MEDCouplingArrayApplyFunc1.
4316  *  \param [in] nbOfComp - number of components in the result array.
4317  *  \param [in] func - the expression defining how to transform a tuple of \a this array.
4318  *              Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
4319  *  \param [in] isSafe - By default true. If true invalid operation (division by 0. acos of value > 1. ...) leads to a throw of an exception.
4320  *              If false the computation is carried on without any notification. When false the evaluation is a little faster.
4321  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
4322  *          same number of tuples as \a this array and \a nbOfComp components.
4323  *          The caller is to delete this result array using decrRef() as it is no more
4324  *          needed.
4325  *  \throw If \a this is not allocated.
4326  *  \throw If computing \a func fails.
4327  */
4328 DataArrayDouble *DataArrayDouble::applyFunc(int nbOfComp, const std::string& func, bool isSafe) const
4329 {
4330   INTERP_KERNEL::ExprParser expr(func);
4331   expr.parse();
4332   std::set<std::string> vars;
4333   expr.getTrueSetOfVars(vars);
4334   std::vector<std::string> varsV(vars.begin(),vars.end());
4335   return applyFunc3(nbOfComp,varsV,func,isSafe);
4336 }
4337
4338 /*!
4339  * Returns a new DataArrayDouble created from \a this one by applying a function to every
4340  * tuple of \a this array. Textual data is not copied. This method works by tuples (whatever its size).
4341  * If \a this is a one component array, call applyFuncOnThis instead that performs the same work faster.
4342  *
4343  * For more info see \ref MEDCouplingArrayApplyFunc0.
4344  *  \param [in] func - the expression defining how to transform a tuple of \a this array.
4345  *              Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
4346  *  \param [in] isSafe - By default true. If true invalid operation (division by 0. acos of value > 1. ...) leads to a throw of an exception.
4347  *                       If false the computation is carried on without any notification. When false the evaluation is a little faster.
4348  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
4349  *          same number of tuples and components as \a this array.
4350  *          The caller is to delete this result array using decrRef() as it is no more
4351  *          needed.
4352  *  \sa applyFuncOnThis
4353  *  \throw If \a this is not allocated.
4354  *  \throw If computing \a func fails.
4355  */
4356 DataArrayDouble *DataArrayDouble::applyFunc(const std::string& func, bool isSafe) const
4357 {
4358   int nbOfComp(getNumberOfComponents());
4359   if(nbOfComp<=0)
4360     throw INTERP_KERNEL::Exception("DataArrayDouble::applyFunc : output number of component must be > 0 !");
4361   checkAllocated();
4362   int nbOfTuples(getNumberOfTuples());
4363   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> newArr(DataArrayDouble::New());
4364   newArr->alloc(nbOfTuples,nbOfComp);
4365   INTERP_KERNEL::ExprParser expr(func);
4366   expr.parse();
4367   std::set<std::string> vars;
4368   expr.getTrueSetOfVars(vars);
4369   if((int)vars.size()>1)
4370     {
4371       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 applyFunc2 or applyFunc3 instead ! Vars in expr are : ";
4372       std::copy(vars.begin(),vars.end(),std::ostream_iterator<std::string>(oss," "));
4373       throw INTERP_KERNEL::Exception(oss.str().c_str());
4374     }
4375   if(vars.empty())
4376     {
4377       expr.prepareFastEvaluator();
4378       newArr->rearrange(1);
4379       newArr->fillWithValue(expr.evaluateDouble());
4380       newArr->rearrange(nbOfComp);
4381       return newArr.retn();
4382     }
4383   std::vector<std::string> vars2(vars.begin(),vars.end());
4384   double buff,*ptrToFill(newArr->getPointer());
4385   const double *ptr(begin());
4386   std::vector<double> stck;
4387   expr.prepareExprEvaluationDouble(vars2,1,1,0,&buff,&buff+1);
4388   expr.prepareFastEvaluator();
4389   if(!isSafe)
4390     {
4391       for(int i=0;i<nbOfTuples;i++)
4392         {
4393           for(int iComp=0;iComp<nbOfComp;iComp++,ptr++,ptrToFill++)
4394             {
4395               buff=*ptr;
4396               expr.evaluateDoubleInternal(stck);
4397               *ptrToFill=stck.back();
4398               stck.pop_back();
4399             }
4400         }
4401     }
4402   else
4403     {
4404       for(int i=0;i<nbOfTuples;i++)
4405         {
4406           for(int iComp=0;iComp<nbOfComp;iComp++,ptr++,ptrToFill++)
4407             {
4408               buff=*ptr;
4409               try
4410               {
4411                   expr.evaluateDoubleInternalSafe(stck);
4412               }
4413               catch(INTERP_KERNEL::Exception& e)
4414               {
4415                   std::ostringstream oss; oss << "For tuple # " << i << " component # " << iComp << " with value (";
4416                   oss << buff;
4417                   oss << ") : Evaluation of function failed !" << e.what();
4418                   throw INTERP_KERNEL::Exception(oss.str().c_str());
4419               }
4420               *ptrToFill=stck.back();
4421               stck.pop_back();
4422             }
4423         }
4424     }
4425   return newArr.retn();
4426 }
4427
4428 /*!
4429  * This method is a non const method that modify the array in \a this.
4430  * This method only works on one component array. It means that function \a func must
4431  * contain at most one variable.
4432  * This method is a specialization of applyFunc method with one parameter on one component array.
4433  *
4434  *  \param [in] func - the expression defining how to transform a tuple of \a this array.
4435  *              Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
4436  *  \param [in] isSafe - By default true. If true invalid operation (division by 0. acos of value > 1. ...) leads to a throw of an exception.
4437  *              If false the computation is carried on without any notification. When false the evaluation is a little faster.
4438  *
4439  * \sa applyFunc
4440  */
4441 void DataArrayDouble::applyFuncOnThis(const std::string& func, bool isSafe)
4442 {
4443   int nbOfComp(getNumberOfComponents());
4444   if(nbOfComp<=0)
4445     throw INTERP_KERNEL::Exception("DataArrayDouble::applyFuncOnThis : output number of component must be > 0 !");
4446   checkAllocated();
4447   int nbOfTuples(getNumberOfTuples());
4448   INTERP_KERNEL::ExprParser expr(func);
4449   expr.parse();
4450   std::set<std::string> vars;
4451   expr.getTrueSetOfVars(vars);
4452   if((int)vars.size()>1)
4453     {
4454       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 applyFunc2 or applyFunc3 instead ! Vars in expr are : ";
4455       std::copy(vars.begin(),vars.end(),std::ostream_iterator<std::string>(oss," "));
4456       throw INTERP_KERNEL::Exception(oss.str().c_str());
4457     }
4458   if(vars.empty())
4459     {
4460       expr.prepareFastEvaluator();
4461       std::vector<std::string> compInfo(getInfoOnComponents());
4462       rearrange(1);
4463       fillWithValue(expr.evaluateDouble());
4464       rearrange(nbOfComp);
4465       setInfoOnComponents(compInfo);
4466       return ;
4467     }
4468   std::vector<std::string> vars2(vars.begin(),vars.end());
4469   double buff,*ptrToFill(getPointer());
4470   const double *ptr(begin());
4471   std::vector<double> stck;
4472   expr.prepareExprEvaluationDouble(vars2,1,1,0,&buff,&buff+1);
4473   expr.prepareFastEvaluator();
4474   if(!isSafe)
4475     {
4476       for(int i=0;i<nbOfTuples;i++)
4477         {
4478           for(int iComp=0;iComp<nbOfComp;iComp++,ptr++,ptrToFill++)
4479             {
4480               buff=*ptr;
4481               expr.evaluateDoubleInternal(stck);
4482               *ptrToFill=stck.back();
4483               stck.pop_back();
4484             }
4485         }
4486     }
4487   else
4488     {
4489       for(int i=0;i<nbOfTuples;i++)
4490         {
4491           for(int iComp=0;iComp<nbOfComp;iComp++,ptr++,ptrToFill++)
4492             {
4493               buff=*ptr;
4494               try
4495               {
4496                   expr.evaluateDoubleInternalSafe(stck);
4497               }
4498               catch(INTERP_KERNEL::Exception& e)
4499               {
4500                   std::ostringstream oss; oss << "For tuple # " << i << " component # " << iComp << " with value (";
4501                   oss << buff;
4502                   oss << ") : Evaluation of function failed !" << e.what();
4503                   throw INTERP_KERNEL::Exception(oss.str().c_str());
4504               }
4505               *ptrToFill=stck.back();
4506               stck.pop_back();
4507             }
4508         }
4509     }
4510 }
4511
4512 /*!
4513  * Returns a new DataArrayDouble created from \a this one by applying a function to every
4514  * tuple of \a this array. Textual data is not copied.
4515  * For more info see \ref MEDCouplingArrayApplyFunc2.
4516  *  \param [in] nbOfComp - number of components in the result array.
4517  *  \param [in] func - the expression defining how to transform a tuple of \a this array.
4518  *              Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
4519  *  \param [in] isSafe - By default true. If true invalid operation (division by 0. acos of value > 1. ...) leads to a throw of an exception.
4520  *              If false the computation is carried on without any notification. When false the evaluation is a little faster.
4521  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
4522  *          same number of tuples as \a this array.
4523  *          The caller is to delete this result array using decrRef() as it is no more
4524  *          needed.
4525  *  \throw If \a this is not allocated.
4526  *  \throw If \a func contains vars that are not in \a this->getInfoOnComponent().
4527  *  \throw If computing \a func fails.
4528  */
4529 DataArrayDouble *DataArrayDouble::applyFunc2(int nbOfComp, const std::string& func, bool isSafe) const
4530 {
4531   return applyFunc3(nbOfComp,getVarsOnComponent(),func,isSafe);
4532 }
4533
4534 /*!
4535  * Returns a new DataArrayDouble created from \a this one by applying a function to every
4536  * tuple of \a this array. Textual data is not copied.
4537  * For more info see \ref MEDCouplingArrayApplyFunc3.
4538  *  \param [in] nbOfComp - number of components in the result array.
4539  *  \param [in] varsOrder - sequence of vars defining their order.
4540  *  \param [in] func - the expression defining how to transform a tuple of \a this array.
4541  *              Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
4542  *  \param [in] isSafe - By default true. If true invalid operation (division by 0. acos of value > 1. ...) leads to a throw of an exception.
4543  *              If false the computation is carried on without any notification. When false the evaluation is a little faster.
4544  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
4545  *          same number of tuples as \a this array.
4546  *          The caller is to delete this result array using decrRef() as it is no more
4547  *          needed.
4548  *  \throw If \a this is not allocated.
4549  *  \throw If \a func contains vars not in \a varsOrder.
4550  *  \throw If computing \a func fails.
4551  */
4552 DataArrayDouble *DataArrayDouble::applyFunc3(int nbOfComp, const std::vector<std::string>& varsOrder, const std::string& func, bool isSafe) const
4553 {
4554   if(nbOfComp<=0)
4555     throw INTERP_KERNEL::Exception("DataArrayDouble::applyFunc3 : output number of component must be > 0 !");
4556   std::vector<std::string> varsOrder2(varsOrder);
4557   int oldNbOfComp(getNumberOfComponents());
4558   for(int i=(int)varsOrder.size();i<oldNbOfComp;i++)
4559     varsOrder2.push_back(std::string());
4560   checkAllocated();
4561   int nbOfTuples(getNumberOfTuples());
4562   INTERP_KERNEL::ExprParser expr(func);
4563   expr.parse();
4564   std::set<std::string> vars;
4565   expr.getTrueSetOfVars(vars);
4566   if((int)vars.size()>oldNbOfComp)
4567     {
4568       std::ostringstream oss; oss << "The field has " << oldNbOfComp << " components and there are ";
4569       oss << vars.size() << " variables : ";
4570       std::copy(vars.begin(),vars.end(),std::ostream_iterator<std::string>(oss," "));
4571       throw INTERP_KERNEL::Exception(oss.str().c_str());
4572     }
4573   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> newArr(DataArrayDouble::New());
4574   newArr->alloc(nbOfTuples,nbOfComp);
4575   INTERP_KERNEL::AutoPtr<double> buff(new double[oldNbOfComp]);
4576   double *buffPtr(buff),*ptrToFill;
4577   std::vector<double> stck;
4578   for(int iComp=0;iComp<nbOfComp;iComp++)
4579     {
4580       expr.prepareExprEvaluationDouble(varsOrder2,oldNbOfComp,nbOfComp,iComp,buffPtr,buffPtr+oldNbOfComp);
4581       expr.prepareFastEvaluator();
4582       const double *ptr(getConstPointer());
4583       ptrToFill=newArr->getPointer()+iComp;
4584       if(!isSafe)
4585         {
4586           for(int i=0;i<nbOfTuples;i++,ptrToFill+=nbOfComp,ptr+=oldNbOfComp)
4587             {
4588               std::copy(ptr,ptr+oldNbOfComp,buffPtr);
4589               expr.evaluateDoubleInternal(stck);
4590               *ptrToFill=stck.back();
4591               stck.pop_back();
4592             }
4593         }
4594       else
4595         {
4596           for(int i=0;i<nbOfTuples;i++,ptrToFill+=nbOfComp,ptr+=oldNbOfComp)
4597             {
4598               std::copy(ptr,ptr+oldNbOfComp,buffPtr);
4599               try
4600               {
4601                   expr.evaluateDoubleInternalSafe(stck);
4602                   *ptrToFill=stck.back();
4603                   stck.pop_back();
4604               }
4605               catch(INTERP_KERNEL::Exception& e)
4606               {
4607                   std::ostringstream oss; oss << "For tuple # " << i << " with value (";
4608                   std::copy(ptr+oldNbOfComp*i,ptr+oldNbOfComp*(i+1),std::ostream_iterator<double>(oss,", "));
4609                   oss << ") : Evaluation of function failed !" << e.what();
4610                   throw INTERP_KERNEL::Exception(oss.str().c_str());
4611               }
4612             }
4613         }
4614     }
4615   return newArr.retn();
4616 }
4617
4618 void DataArrayDouble::applyFuncFast32(const std::string& func)
4619 {
4620   checkAllocated();
4621   INTERP_KERNEL::ExprParser expr(func);
4622   expr.parse();
4623   char *funcStr=expr.compileX86();
4624   MYFUNCPTR funcPtr;
4625   *((void **)&funcPtr)=funcStr;//he he...
4626   //
4627   double *ptr=getPointer();
4628   int nbOfComp=getNumberOfComponents();
4629   int nbOfTuples=getNumberOfTuples();
4630   int nbOfElems=nbOfTuples*nbOfComp;
4631   for(int i=0;i<nbOfElems;i++,ptr++)
4632     *ptr=funcPtr(*ptr);
4633   declareAsNew();
4634 }
4635
4636 void DataArrayDouble::applyFuncFast64(const std::string& func)
4637 {
4638   checkAllocated();
4639   INTERP_KERNEL::ExprParser expr(func);
4640   expr.parse();
4641   char *funcStr=expr.compileX86_64();
4642   MYFUNCPTR funcPtr;
4643   *((void **)&funcPtr)=funcStr;//he he...
4644   //
4645   double *ptr=getPointer();
4646   int nbOfComp=getNumberOfComponents();
4647   int nbOfTuples=getNumberOfTuples();
4648   int nbOfElems=nbOfTuples*nbOfComp;
4649   for(int i=0;i<nbOfElems;i++,ptr++)
4650     *ptr=funcPtr(*ptr);
4651   declareAsNew();
4652 }
4653
4654 DataArrayDoubleIterator *DataArrayDouble::iterator()
4655 {
4656   return new DataArrayDoubleIterator(this);
4657 }
4658
4659 /*!
4660  * Returns a new DataArrayInt contating indices of tuples of \a this one-dimensional
4661  * array whose values are within a given range. Textual data is not copied.
4662  *  \param [in] vmin - a lowest acceptable value (included).
4663  *  \param [in] vmax - a greatest acceptable value (included).
4664  *  \return DataArrayInt * - the new instance of DataArrayInt.
4665  *          The caller is to delete this result array using decrRef() as it is no more
4666  *          needed.
4667  *  \throw If \a this->getNumberOfComponents() != 1.
4668  *
4669  *  \sa DataArrayDouble::getIdsNotInRange
4670  *
4671  *  \if ENABLE_EXAMPLES
4672  *  \ref cpp_mcdataarraydouble_getidsinrange "Here is a C++ example".<br>
4673  *  \ref py_mcdataarraydouble_getidsinrange "Here is a Python example".
4674  *  \endif
4675  */
4676 DataArrayInt *DataArrayDouble::getIdsInRange(double vmin, double vmax) const
4677 {
4678   checkAllocated();
4679   if(getNumberOfComponents()!=1)
4680     throw INTERP_KERNEL::Exception("DataArrayDouble::getIdsInRange : this must have exactly one component !");
4681   const double *cptr(begin());
4682   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
4683   int nbOfTuples(getNumberOfTuples());
4684   for(int i=0;i<nbOfTuples;i++,cptr++)
4685     if(*cptr>=vmin && *cptr<=vmax)
4686       ret->pushBackSilent(i);
4687   return ret.retn();
4688 }
4689
4690 /*!
4691  * Returns a new DataArrayInt contating indices of tuples of \a this one-dimensional
4692  * array whose values are not within a given range. Textual data is not copied.
4693  *  \param [in] vmin - a lowest not acceptable value (excluded).
4694  *  \param [in] vmax - a greatest not acceptable value (excluded).
4695  *  \return DataArrayInt * - the new instance of DataArrayInt.
4696  *          The caller is to delete this result array using decrRef() as it is no more
4697  *          needed.
4698  *  \throw If \a this->getNumberOfComponents() != 1.
4699  *
4700  *  \sa DataArrayDouble::getIdsInRange
4701  */
4702 DataArrayInt *DataArrayDouble::getIdsNotInRange(double vmin, double vmax) const
4703 {
4704   checkAllocated();
4705   if(getNumberOfComponents()!=1)
4706     throw INTERP_KERNEL::Exception("DataArrayDouble::getIdsNotInRange : this must have exactly one component !");
4707   const double *cptr(begin());
4708   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
4709   int nbOfTuples(getNumberOfTuples());
4710   for(int i=0;i<nbOfTuples;i++,cptr++)
4711     if(*cptr<vmin || *cptr>vmax)
4712       ret->pushBackSilent(i);
4713   return ret.retn();
4714 }
4715
4716 /*!
4717  * Returns a new DataArrayDouble by concatenating two given arrays, so that (1) the number
4718  * of tuples in the result array is a sum of the number of tuples of given arrays and (2)
4719  * the number of component in the result array is same as that of each of given arrays.
4720  * Info on components is copied from the first of the given arrays. Number of components
4721  * in the given arrays must be  the same.
4722  *  \param [in] a1 - an array to include in the result array.
4723  *  \param [in] a2 - another array to include in the result array.
4724  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4725  *          The caller is to delete this result array using decrRef() as it is no more
4726  *          needed.
4727  *  \throw If both \a a1 and \a a2 are NULL.
4728  *  \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents().
4729  */
4730 DataArrayDouble *DataArrayDouble::Aggregate(const DataArrayDouble *a1, const DataArrayDouble *a2)
4731 {
4732   std::vector<const DataArrayDouble *> tmp(2);
4733   tmp[0]=a1; tmp[1]=a2;
4734   return Aggregate(tmp);
4735 }
4736
4737 /*!
4738  * Returns a new DataArrayDouble by concatenating all given arrays, so that (1) the number
4739  * of tuples in the result array is a sum of the number of tuples of given arrays and (2)
4740  * the number of component in the result array is same as that of each of given arrays.
4741  * Info on components is copied from the first of the given arrays. Number of components
4742  * in the given arrays must be  the same.
4743  * If the number of non null of elements in \a arr is equal to one the returned object is a copy of it
4744  * not the object itself.
4745  *  \param [in] arr - a sequence of arrays to include in the result array.
4746  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4747  *          The caller is to delete this result array using decrRef() as it is no more
4748  *          needed.
4749  *  \throw If all arrays within \a arr are NULL.
4750  *  \throw If getNumberOfComponents() of arrays within \a arr.
4751  */
4752 DataArrayDouble *DataArrayDouble::Aggregate(const std::vector<const DataArrayDouble *>& arr)
4753 {
4754   std::vector<const DataArrayDouble *> a;
4755   for(std::vector<const DataArrayDouble *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
4756     if(*it4)
4757       a.push_back(*it4);
4758   if(a.empty())
4759     throw INTERP_KERNEL::Exception("DataArrayDouble::Aggregate : input list must contain at least one NON EMPTY DataArrayDouble !");
4760   std::vector<const DataArrayDouble *>::const_iterator it=a.begin();
4761   int nbOfComp=(*it)->getNumberOfComponents();
4762   int nbt=(*it++)->getNumberOfTuples();
4763   for(int i=1;it!=a.end();it++,i++)
4764     {
4765       if((*it)->getNumberOfComponents()!=nbOfComp)
4766         throw INTERP_KERNEL::Exception("DataArrayDouble::Aggregate : Nb of components mismatch for array aggregation !");
4767       nbt+=(*it)->getNumberOfTuples();
4768     }
4769   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
4770   ret->alloc(nbt,nbOfComp);
4771   double *pt=ret->getPointer();
4772   for(it=a.begin();it!=a.end();it++)
4773     pt=std::copy((*it)->getConstPointer(),(*it)->getConstPointer()+(*it)->getNbOfElems(),pt);
4774   ret->copyStringInfoFrom(*(a[0]));
4775   return ret.retn();
4776 }
4777
4778 /*!
4779  * Returns a new DataArrayDouble by aggregating two given arrays, so that (1) the number
4780  * of components in the result array is a sum of the number of components of given arrays
4781  * and (2) the number of tuples in the result array is same as that of each of given
4782  * arrays. In other words the i-th tuple of result array includes all components of
4783  * i-th tuples of all given arrays.
4784  * Number of tuples in the given arrays must be  the same.
4785  *  \param [in] a1 - an array to include in the result array.
4786  *  \param [in] a2 - another array to include in the result array.
4787  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4788  *          The caller is to delete this result array using decrRef() as it is no more
4789  *          needed.
4790  *  \throw If both \a a1 and \a a2 are NULL.
4791  *  \throw If any given array is not allocated.
4792  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
4793  */
4794 DataArrayDouble *DataArrayDouble::Meld(const DataArrayDouble *a1, const DataArrayDouble *a2)
4795 {
4796   std::vector<const DataArrayDouble *> arr(2);
4797   arr[0]=a1; arr[1]=a2;
4798   return Meld(arr);
4799 }
4800
4801 /*!
4802  * Returns a new DataArrayDouble by aggregating all given arrays, so that (1) the number
4803  * of components in the result array is a sum of the number of components of given arrays
4804  * and (2) the number of tuples in the result array is same as that of each of given
4805  * arrays. In other words the i-th tuple of result array includes all components of
4806  * i-th tuples of all given arrays.
4807  * Number of tuples in the given arrays must be  the same.
4808  *  \param [in] arr - a sequence of arrays to include in the result array.
4809  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4810  *          The caller is to delete this result array using decrRef() as it is no more
4811  *          needed.
4812  *  \throw If all arrays within \a arr are NULL.
4813  *  \throw If any given array is not allocated.
4814  *  \throw If getNumberOfTuples() of arrays within \a arr is different.
4815  */
4816 DataArrayDouble *DataArrayDouble::Meld(const std::vector<const DataArrayDouble *>& arr)
4817 {
4818   std::vector<const DataArrayDouble *> a;
4819   for(std::vector<const DataArrayDouble *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
4820     if(*it4)
4821       a.push_back(*it4);
4822   if(a.empty())
4823     throw INTERP_KERNEL::Exception("DataArrayDouble::Meld : input list must contain at least one NON EMPTY DataArrayDouble !");
4824   std::vector<const DataArrayDouble *>::const_iterator it;
4825   for(it=a.begin();it!=a.end();it++)
4826     (*it)->checkAllocated();
4827   it=a.begin();
4828   int nbOfTuples=(*it)->getNumberOfTuples();
4829   std::vector<int> nbc(a.size());
4830   std::vector<const double *> pts(a.size());
4831   nbc[0]=(*it)->getNumberOfComponents();
4832   pts[0]=(*it++)->getConstPointer();
4833   for(int i=1;it!=a.end();it++,i++)
4834     {
4835       if(nbOfTuples!=(*it)->getNumberOfTuples())
4836         throw INTERP_KERNEL::Exception("DataArrayDouble::Meld : mismatch of number of tuples !");
4837       nbc[i]=(*it)->getNumberOfComponents();
4838       pts[i]=(*it)->getConstPointer();
4839     }
4840   int totalNbOfComp=std::accumulate(nbc.begin(),nbc.end(),0);
4841   DataArrayDouble *ret=DataArrayDouble::New();
4842   ret->alloc(nbOfTuples,totalNbOfComp);
4843   double *retPtr=ret->getPointer();
4844   for(int i=0;i<nbOfTuples;i++)
4845     for(int j=0;j<(int)a.size();j++)
4846       {
4847         retPtr=std::copy(pts[j],pts[j]+nbc[j],retPtr);
4848         pts[j]+=nbc[j];
4849       }
4850   int k=0;
4851   for(int i=0;i<(int)a.size();i++)
4852     for(int j=0;j<nbc[i];j++,k++)
4853       ret->setInfoOnComponent(k,a[i]->getInfoOnComponent(j));
4854   return ret;
4855 }
4856
4857 /*!
4858  * Returns a new DataArrayDouble containing a dot product of two given arrays, so that
4859  * the i-th tuple of the result array is a sum of products of j-th components of i-th
4860  * tuples of given arrays (\f$ a_i = \sum_{j=1}^n a1_j * a2_j \f$).
4861  * Info on components and name is copied from the first of the given arrays.
4862  * Number of tuples and components in the given arrays must be the same.
4863  *  \param [in] a1 - a given array.
4864  *  \param [in] a2 - another given array.
4865  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4866  *          The caller is to delete this result array using decrRef() as it is no more
4867  *          needed.
4868  *  \throw If either \a a1 or \a a2 is NULL.
4869  *  \throw If any given array is not allocated.
4870  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
4871  *  \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents()
4872  */
4873 DataArrayDouble *DataArrayDouble::Dot(const DataArrayDouble *a1, const DataArrayDouble *a2)
4874 {
4875   if(!a1 || !a2)
4876     throw INTERP_KERNEL::Exception("DataArrayDouble::Dot : input DataArrayDouble instance is NULL !");
4877   a1->checkAllocated();
4878   a2->checkAllocated();
4879   int nbOfComp=a1->getNumberOfComponents();
4880   if(nbOfComp!=a2->getNumberOfComponents())
4881     throw INTERP_KERNEL::Exception("Nb of components mismatch for array Dot !");
4882   int nbOfTuple=a1->getNumberOfTuples();
4883   if(nbOfTuple!=a2->getNumberOfTuples())
4884     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Dot !");
4885   DataArrayDouble *ret=DataArrayDouble::New();
4886   ret->alloc(nbOfTuple,1);
4887   double *retPtr=ret->getPointer();
4888   const double *a1Ptr=a1->getConstPointer();
4889   const double *a2Ptr=a2->getConstPointer();
4890   for(int i=0;i<nbOfTuple;i++)
4891     {
4892       double sum=0.;
4893       for(int j=0;j<nbOfComp;j++)
4894         sum+=a1Ptr[i*nbOfComp+j]*a2Ptr[i*nbOfComp+j];
4895       retPtr[i]=sum;
4896     }
4897   ret->setInfoOnComponent(0,a1->getInfoOnComponent(0));
4898   ret->setName(a1->getName());
4899   return ret;
4900 }
4901
4902 /*!
4903  * Returns a new DataArrayDouble containing a cross product of two given arrays, so that
4904  * the i-th tuple of the result array contains 3 components of a vector which is a cross
4905  * product of two vectors defined by the i-th tuples of given arrays.
4906  * Info on components is copied from the first of the given arrays.
4907  * Number of tuples in the given arrays must be the same.
4908  * Number of components in the given arrays must be 3.
4909  *  \param [in] a1 - a given array.
4910  *  \param [in] a2 - another given array.
4911  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4912  *          The caller is to delete this result array using decrRef() as it is no more
4913  *          needed.
4914  *  \throw If either \a a1 or \a a2 is NULL.
4915  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
4916  *  \throw If \a a1->getNumberOfComponents() != 3
4917  *  \throw If \a a2->getNumberOfComponents() != 3
4918  */
4919 DataArrayDouble *DataArrayDouble::CrossProduct(const DataArrayDouble *a1, const DataArrayDouble *a2)
4920 {
4921   if(!a1 || !a2)
4922     throw INTERP_KERNEL::Exception("DataArrayDouble::CrossProduct : input DataArrayDouble instance is NULL !");
4923   int nbOfComp=a1->getNumberOfComponents();
4924   if(nbOfComp!=a2->getNumberOfComponents())
4925     throw INTERP_KERNEL::Exception("Nb of components mismatch for array crossProduct !");
4926   if(nbOfComp!=3)
4927     throw INTERP_KERNEL::Exception("Nb of components must be equal to 3 for array crossProduct !");
4928   int nbOfTuple=a1->getNumberOfTuples();
4929   if(nbOfTuple!=a2->getNumberOfTuples())
4930     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array crossProduct !");
4931   DataArrayDouble *ret=DataArrayDouble::New();
4932   ret->alloc(nbOfTuple,3);
4933   double *retPtr=ret->getPointer();
4934   const double *a1Ptr=a1->getConstPointer();
4935   const double *a2Ptr=a2->getConstPointer();
4936   for(int i=0;i<nbOfTuple;i++)
4937     {
4938       retPtr[3*i]=a1Ptr[3*i+1]*a2Ptr[3*i+2]-a1Ptr[3*i+2]*a2Ptr[3*i+1];
4939       retPtr[3*i+1]=a1Ptr[3*i+2]*a2Ptr[3*i]-a1Ptr[3*i]*a2Ptr[3*i+2];
4940       retPtr[3*i+2]=a1Ptr[3*i]*a2Ptr[3*i+1]-a1Ptr[3*i+1]*a2Ptr[3*i];
4941     }
4942   ret->copyStringInfoFrom(*a1);
4943   return ret;
4944 }
4945
4946 /*!
4947  * Returns a new DataArrayDouble containing maximal values of two given arrays.
4948  * Info on components is copied from the first of the given arrays.
4949  * Number of tuples and components in the given arrays must be the same.
4950  *  \param [in] a1 - an array to compare values with another one.
4951  *  \param [in] a2 - another array to compare values with the first one.
4952  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4953  *          The caller is to delete this result array using decrRef() as it is no more
4954  *          needed.
4955  *  \throw If either \a a1 or \a a2 is NULL.
4956  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
4957  *  \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents()
4958  */
4959 DataArrayDouble *DataArrayDouble::Max(const DataArrayDouble *a1, const DataArrayDouble *a2)
4960 {
4961   if(!a1 || !a2)
4962     throw INTERP_KERNEL::Exception("DataArrayDouble::Max : input DataArrayDouble instance is NULL !");
4963   int nbOfComp=a1->getNumberOfComponents();
4964   if(nbOfComp!=a2->getNumberOfComponents())
4965     throw INTERP_KERNEL::Exception("Nb of components mismatch for array Max !");
4966   int nbOfTuple=a1->getNumberOfTuples();
4967   if(nbOfTuple!=a2->getNumberOfTuples())
4968     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Max !");
4969   DataArrayDouble *ret=DataArrayDouble::New();
4970   ret->alloc(nbOfTuple,nbOfComp);
4971   double *retPtr=ret->getPointer();
4972   const double *a1Ptr=a1->getConstPointer();
4973   const double *a2Ptr=a2->getConstPointer();
4974   int nbElem=nbOfTuple*nbOfComp;
4975   for(int i=0;i<nbElem;i++)
4976     retPtr[i]=std::max(a1Ptr[i],a2Ptr[i]);
4977   ret->copyStringInfoFrom(*a1);
4978   return ret;
4979 }
4980
4981 /*!
4982  * Returns a new DataArrayDouble containing minimal values of two given arrays.
4983  * Info on components is copied from the first of the given arrays.
4984  * Number of tuples and components in the given arrays must be the same.
4985  *  \param [in] a1 - an array to compare values with another one.
4986  *  \param [in] a2 - another array to compare values with the first one.
4987  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4988  *          The caller is to delete this result array using decrRef() as it is no more
4989  *          needed.
4990  *  \throw If either \a a1 or \a a2 is NULL.
4991  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
4992  *  \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents()
4993  */
4994 DataArrayDouble *DataArrayDouble::Min(const DataArrayDouble *a1, const DataArrayDouble *a2)
4995 {
4996   if(!a1 || !a2)
4997     throw INTERP_KERNEL::Exception("DataArrayDouble::Min : input DataArrayDouble instance is NULL !");
4998   int nbOfComp=a1->getNumberOfComponents();
4999   if(nbOfComp!=a2->getNumberOfComponents())
5000     throw INTERP_KERNEL::Exception("Nb of components mismatch for array min !");
5001   int nbOfTuple=a1->getNumberOfTuples();
5002   if(nbOfTuple!=a2->getNumberOfTuples())
5003     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array min !");
5004   DataArrayDouble *ret=DataArrayDouble::New();
5005   ret->alloc(nbOfTuple,nbOfComp);
5006   double *retPtr=ret->getPointer();
5007   const double *a1Ptr=a1->getConstPointer();
5008   const double *a2Ptr=a2->getConstPointer();
5009   int nbElem=nbOfTuple*nbOfComp;
5010   for(int i=0;i<nbElem;i++)
5011     retPtr[i]=std::min(a1Ptr[i],a2Ptr[i]);
5012   ret->copyStringInfoFrom(*a1);
5013   return ret;
5014 }
5015
5016 /*!
5017  * Returns a new DataArrayDouble that is a sum of two given arrays. There are 3
5018  * valid cases.
5019  * 1.  The arrays have same number of tuples and components. Then each value of
5020  *   the result array (_a_) is a sum of the corresponding values of \a a1 and \a a2,
5021  *   i.e.: _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ i, j ].
5022  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
5023  *   component. Then
5024  *   _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ i, 0 ].
5025  * 3.  The arrays have same number of components and one array, say _a2_, has one
5026  *   tuple. Then
5027  *   _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ 0, j ].
5028  *
5029  * Info on components is copied either from the first array (in the first case) or from
5030  * the array with maximal number of elements (getNbOfElems()).
5031  *  \param [in] a1 - an array to sum up.
5032  *  \param [in] a2 - another array to sum up.
5033  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
5034  *          The caller is to delete this result array using decrRef() as it is no more
5035  *          needed.
5036  *  \throw If either \a a1 or \a a2 is NULL.
5037  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
5038  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
5039  *         none of them has number of tuples or components equal to 1.
5040  */
5041 DataArrayDouble *DataArrayDouble::Add(const DataArrayDouble *a1, const DataArrayDouble *a2)
5042 {
5043   if(!a1 || !a2)
5044     throw INTERP_KERNEL::Exception("DataArrayDouble::Add : input DataArrayDouble instance is NULL !");
5045   int nbOfTuple=a1->getNumberOfTuples();
5046   int nbOfTuple2=a2->getNumberOfTuples();
5047   int nbOfComp=a1->getNumberOfComponents();
5048   int nbOfComp2=a2->getNumberOfComponents();
5049   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=0;
5050   if(nbOfTuple==nbOfTuple2)
5051     {
5052       if(nbOfComp==nbOfComp2)
5053         {
5054           ret=DataArrayDouble::New();
5055           ret->alloc(nbOfTuple,nbOfComp);
5056           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::plus<double>());
5057           ret->copyStringInfoFrom(*a1);
5058         }
5059       else
5060         {
5061           int nbOfCompMin,nbOfCompMax;
5062           const DataArrayDouble *aMin, *aMax;
5063           if(nbOfComp>nbOfComp2)
5064             {
5065               nbOfCompMin=nbOfComp2; nbOfCompMax=nbOfComp;
5066               aMin=a2; aMax=a1;
5067             }
5068           else
5069             {
5070               nbOfCompMin=nbOfComp; nbOfCompMax=nbOfComp2;
5071               aMin=a1; aMax=a2;
5072             }
5073           if(nbOfCompMin==1)
5074             {
5075               ret=DataArrayDouble::New();
5076               ret->alloc(nbOfTuple,nbOfCompMax);
5077               const double *aMinPtr=aMin->getConstPointer();
5078               const double *aMaxPtr=aMax->getConstPointer();
5079               double *res=ret->getPointer();
5080               for(int i=0;i<nbOfTuple;i++)
5081                 res=std::transform(aMaxPtr+i*nbOfCompMax,aMaxPtr+(i+1)*nbOfCompMax,res,std::bind2nd(std::plus<double>(),aMinPtr[i]));
5082               ret->copyStringInfoFrom(*aMax);
5083             }
5084           else
5085             throw INTERP_KERNEL::Exception("Nb of components mismatch for array Add !");
5086         }
5087     }
5088   else if((nbOfTuple==1 && nbOfTuple2>1) || (nbOfTuple>1 && nbOfTuple2==1))
5089     {
5090       if(nbOfComp==nbOfComp2)
5091         {
5092           int nbOfTupleMax=std::max(nbOfTuple,nbOfTuple2);
5093           const DataArrayDouble *aMin=nbOfTuple>nbOfTuple2?a2:a1;
5094           const DataArrayDouble *aMax=nbOfTuple>nbOfTuple2?a1:a2;
5095           const double *aMinPtr=aMin->getConstPointer(),*aMaxPtr=aMax->getConstPointer();
5096           ret=DataArrayDouble::New();
5097           ret->alloc(nbOfTupleMax,nbOfComp);
5098           double *res=ret->getPointer();
5099           for(int i=0;i<nbOfTupleMax;i++)
5100             res=std::transform(aMaxPtr+i*nbOfComp,aMaxPtr+(i+1)*nbOfComp,aMinPtr,res,std::plus<double>());
5101           ret->copyStringInfoFrom(*aMax);
5102         }
5103       else
5104         throw INTERP_KERNEL::Exception("Nb of components mismatch for array Add !");
5105     }
5106   else
5107     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Add !");
5108   return ret.retn();
5109 }
5110
5111 /*!
5112  * Adds values of another DataArrayDouble to values of \a this one. There are 3
5113  * valid cases.
5114  * 1.  The arrays have same number of tuples and components. Then each value of
5115  *   \a other array is added to the corresponding value of \a this array, i.e.:
5116  *   _a_ [ i, j ] += _other_ [ i, j ].
5117  * 2.  The arrays have same number of tuples and \a other array has one component. Then
5118  *   _a_ [ i, j ] += _other_ [ i, 0 ].
5119  * 3.  The arrays have same number of components and \a other array has one tuple. Then
5120  *   _a_ [ i, j ] += _a2_ [ 0, j ].
5121  *
5122  *  \param [in] other - an array to add to \a this one.
5123  *  \throw If \a other is NULL.
5124  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
5125  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
5126  *         \a other has number of both tuples and components not equal to 1.
5127  */
5128 void DataArrayDouble::addEqual(const DataArrayDouble *other)
5129 {
5130   if(!other)
5131     throw INTERP_KERNEL::Exception("DataArrayDouble::addEqual : input DataArrayDouble instance is NULL !");
5132   const char *msg="Nb of tuples mismatch for DataArrayDouble::addEqual  !";
5133   checkAllocated();
5134   other->checkAllocated();
5135   int nbOfTuple=getNumberOfTuples();
5136   int nbOfTuple2=other->getNumberOfTuples();
5137   int nbOfComp=getNumberOfComponents();
5138   int nbOfComp2=other->getNumberOfComponents();
5139   if(nbOfTuple==nbOfTuple2)
5140     {
5141       if(nbOfComp==nbOfComp2)
5142         {
5143           std::transform(begin(),end(),other->begin(),getPointer(),std::plus<double>());
5144         }
5145       else if(nbOfComp2==1)
5146         {
5147           double *ptr=getPointer();
5148           const double *ptrc=other->getConstPointer();
5149           for(int i=0;i<nbOfTuple;i++)
5150             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::plus<double>(),*ptrc++));
5151         }
5152       else
5153         throw INTERP_KERNEL::Exception(msg);
5154     }
5155   else if(nbOfTuple2==1)
5156     {
5157       if(nbOfComp2==nbOfComp)
5158         {
5159           double *ptr=getPointer();
5160           const double *ptrc=other->getConstPointer();
5161           for(int i=0;i<nbOfTuple;i++)
5162             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::plus<double>());
5163         }
5164       else
5165         throw INTERP_KERNEL::Exception(msg);
5166     }
5167   else
5168     throw INTERP_KERNEL::Exception(msg);
5169   declareAsNew();
5170 }
5171
5172 /*!
5173  * Returns a new DataArrayDouble that is a subtraction of two given arrays. There are 3
5174  * valid cases.
5175  * 1.  The arrays have same number of tuples and components. Then each value of
5176  *   the result array (_a_) is a subtraction of the corresponding values of \a a1 and
5177  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ i, j ].
5178  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
5179  *   component. Then
5180  *   _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ i, 0 ].
5181  * 3.  The arrays have same number of components and one array, say _a2_, has one
5182  *   tuple. Then
5183  *   _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ 0, j ].
5184  *
5185  * Info on components is copied either from the first array (in the first case) or from
5186  * the array with maximal number of elements (getNbOfElems()).
5187  *  \param [in] a1 - an array to subtract from.
5188  *  \param [in] a2 - an array to subtract.
5189  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
5190  *          The caller is to delete this result array using decrRef() as it is no more
5191  *          needed.
5192  *  \throw If either \a a1 or \a a2 is NULL.
5193  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
5194  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
5195  *         none of them has number of tuples or components equal to 1.
5196  */
5197 DataArrayDouble *DataArrayDouble::Substract(const DataArrayDouble *a1, const DataArrayDouble *a2)
5198 {
5199   if(!a1 || !a2)
5200     throw INTERP_KERNEL::Exception("DataArrayDouble::Substract : input DataArrayDouble instance is NULL !");
5201   int nbOfTuple1=a1->getNumberOfTuples();
5202   int nbOfTuple2=a2->getNumberOfTuples();
5203   int nbOfComp1=a1->getNumberOfComponents();
5204   int nbOfComp2=a2->getNumberOfComponents();
5205   if(nbOfTuple2==nbOfTuple1)
5206     {
5207       if(nbOfComp1==nbOfComp2)
5208         {
5209           MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
5210           ret->alloc(nbOfTuple2,nbOfComp1);
5211           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::minus<double>());
5212           ret->copyStringInfoFrom(*a1);
5213           return ret.retn();
5214         }
5215       else if(nbOfComp2==1)
5216         {
5217           MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
5218           ret->alloc(nbOfTuple1,nbOfComp1);
5219           const double *a2Ptr=a2->getConstPointer();
5220           const double *a1Ptr=a1->getConstPointer();
5221           double *res=ret->getPointer();
5222           for(int i=0;i<nbOfTuple1;i++)
5223             res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::minus<double>(),a2Ptr[i]));
5224           ret->copyStringInfoFrom(*a1);
5225           return ret.retn();
5226         }
5227       else
5228         {
5229           a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Substract !");
5230           return 0;
5231         }
5232     }
5233   else if(nbOfTuple2==1)
5234     {
5235       a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Substract !");
5236       MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
5237       ret->alloc(nbOfTuple1,nbOfComp1);
5238       const double *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
5239       double *pt=ret->getPointer();
5240       for(int i=0;i<nbOfTuple1;i++)
5241         pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::minus<double>());
5242       ret->copyStringInfoFrom(*a1);
5243       return ret.retn();
5244     }
5245   else
5246     {
5247       a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Substract !");//will always throw an exception
5248       return 0;
5249     }
5250 }
5251
5252 /*!
5253  * Subtract values of another DataArrayDouble from values of \a this one. There are 3
5254  * valid cases.
5255  * 1.  The arrays have same number of tuples and components. Then each value of
5256  *   \a other array is subtracted from the corresponding value of \a this array, i.e.:
5257  *   _a_ [ i, j ] -= _other_ [ i, j ].
5258  * 2.  The arrays have same number of tuples and \a other array has one component. Then
5259  *   _a_ [ i, j ] -= _other_ [ i, 0 ].
5260  * 3.  The arrays have same number of components and \a other array has one tuple. Then
5261  *   _a_ [ i, j ] -= _a2_ [ 0, j ].
5262  *
5263  *  \param [in] other - an array to subtract from \a this one.
5264  *  \throw If \a other is NULL.
5265  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
5266  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
5267  *         \a other has number of both tuples and components not equal to 1.
5268  */
5269 void DataArrayDouble::substractEqual(const DataArrayDouble *other)
5270 {
5271   if(!other)
5272     throw INTERP_KERNEL::Exception("DataArrayDouble::substractEqual : input DataArrayDouble instance is NULL !");
5273   const char *msg="Nb of tuples mismatch for DataArrayDouble::substractEqual  !";
5274   checkAllocated();
5275   other->checkAllocated();
5276   int nbOfTuple=getNumberOfTuples();
5277   int nbOfTuple2=other->getNumberOfTuples();
5278   int nbOfComp=getNumberOfComponents();
5279   int nbOfComp2=other->getNumberOfComponents();
5280   if(nbOfTuple==nbOfTuple2)
5281     {
5282       if(nbOfComp==nbOfComp2)
5283         {
5284           std::transform(begin(),end(),other->begin(),getPointer(),std::minus<double>());
5285         }
5286       else if(nbOfComp2==1)
5287         {
5288           double *ptr=getPointer();
5289           const double *ptrc=other->getConstPointer();
5290           for(int i=0;i<nbOfTuple;i++)
5291             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::minus<double>(),*ptrc++)); 
5292         }
5293       else
5294         throw INTERP_KERNEL::Exception(msg);
5295     }
5296   else if(nbOfTuple2==1)
5297     {
5298       if(nbOfComp2==nbOfComp)
5299         {
5300           double *ptr=getPointer();
5301           const double *ptrc=other->getConstPointer();
5302           for(int i=0;i<nbOfTuple;i++)
5303             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::minus<double>());
5304         }
5305       else
5306         throw INTERP_KERNEL::Exception(msg);
5307     }
5308   else
5309     throw INTERP_KERNEL::Exception(msg);
5310   declareAsNew();
5311 }
5312
5313 /*!
5314  * Returns a new DataArrayDouble that is a product of two given arrays. There are 3
5315  * valid cases.
5316  * 1.  The arrays have same number of tuples and components. Then each value of
5317  *   the result array (_a_) is a product of the corresponding values of \a a1 and
5318  *   \a a2, i.e. _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ i, j ].
5319  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
5320  *   component. Then
5321  *   _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ i, 0 ].
5322  * 3.  The arrays have same number of components and one array, say _a2_, has one
5323  *   tuple. Then
5324  *   _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ 0, j ].
5325  *
5326  * Info on components is copied either from the first array (in the first case) or from
5327  * the array with maximal number of elements (getNbOfElems()).
5328  *  \param [in] a1 - a factor array.
5329  *  \param [in] a2 - another factor array.
5330  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
5331  *          The caller is to delete this result array using decrRef() as it is no more
5332  *          needed.
5333  *  \throw If either \a a1 or \a a2 is NULL.
5334  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
5335  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
5336  *         none of them has number of tuples or components equal to 1.
5337  */
5338 DataArrayDouble *DataArrayDouble::Multiply(const DataArrayDouble *a1, const DataArrayDouble *a2)
5339 {
5340   if(!a1 || !a2)
5341     throw INTERP_KERNEL::Exception("DataArrayDouble::Multiply : input DataArrayDouble instance is NULL !");
5342   int nbOfTuple=a1->getNumberOfTuples();
5343   int nbOfTuple2=a2->getNumberOfTuples();
5344   int nbOfComp=a1->getNumberOfComponents();
5345   int nbOfComp2=a2->getNumberOfComponents();
5346   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=0;
5347   if(nbOfTuple==nbOfTuple2)
5348     {
5349       if(nbOfComp==nbOfComp2)
5350         {
5351           ret=DataArrayDouble::New();
5352           ret->alloc(nbOfTuple,nbOfComp);
5353           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::multiplies<double>());
5354           ret->copyStringInfoFrom(*a1);
5355         }
5356       else
5357         {
5358           int nbOfCompMin,nbOfCompMax;
5359           const DataArrayDouble *aMin, *aMax;
5360           if(nbOfComp>nbOfComp2)
5361             {
5362               nbOfCompMin=nbOfComp2; nbOfCompMax=nbOfComp;
5363               aMin=a2; aMax=a1;
5364             }
5365           else
5366             {
5367               nbOfCompMin=nbOfComp; nbOfCompMax=nbOfComp2;
5368               aMin=a1; aMax=a2;
5369             }
5370           if(nbOfCompMin==1)
5371             {
5372               ret=DataArrayDouble::New();
5373               ret->alloc(nbOfTuple,nbOfCompMax);
5374               const double *aMinPtr=aMin->getConstPointer();
5375               const double *aMaxPtr=aMax->getConstPointer();
5376               double *res=ret->getPointer();
5377               for(int i=0;i<nbOfTuple;i++)
5378                 res=std::transform(aMaxPtr+i*nbOfCompMax,aMaxPtr+(i+1)*nbOfCompMax,res,std::bind2nd(std::multiplies<double>(),aMinPtr[i]));
5379               ret->copyStringInfoFrom(*aMax);
5380             }
5381           else
5382             throw INTERP_KERNEL::Exception("Nb of components mismatch for array Multiply !");
5383         }
5384     }
5385   else if((nbOfTuple==1 && nbOfTuple2>1) || (nbOfTuple>1 && nbOfTuple2==1))
5386     {
5387       if(nbOfComp==nbOfComp2)
5388         {
5389           int nbOfTupleMax=std::max(nbOfTuple,nbOfTuple2);
5390           const DataArrayDouble *aMin=nbOfTuple>nbOfTuple2?a2:a1;
5391           const DataArrayDouble *aMax=nbOfTuple>nbOfTuple2?a1:a2;
5392           const double *aMinPtr=aMin->getConstPointer(),*aMaxPtr=aMax->getConstPointer();
5393           ret=DataArrayDouble::New();
5394           ret->alloc(nbOfTupleMax,nbOfComp);
5395           double *res=ret->getPointer();
5396           for(int i=0;i<nbOfTupleMax;i++)
5397             res=std::transform(aMaxPtr+i*nbOfComp,aMaxPtr+(i+1)*nbOfComp,aMinPtr,res,std::multiplies<double>());
5398           ret->copyStringInfoFrom(*aMax);
5399         }
5400       else
5401         throw INTERP_KERNEL::Exception("Nb of components mismatch for array Multiply !");
5402     }
5403   else
5404     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Multiply !");
5405   return ret.retn();
5406 }
5407
5408 /*!
5409  * Multiply values of another DataArrayDouble to values of \a this one. There are 3
5410  * valid cases.
5411  * 1.  The arrays have same number of tuples and components. Then each value of
5412  *   \a other array is multiplied to the corresponding value of \a this array, i.e.
5413  *   _this_ [ i, j ] *= _other_ [ i, j ].
5414  * 2.  The arrays have same number of tuples and \a other array has one component. Then
5415  *   _this_ [ i, j ] *= _other_ [ i, 0 ].
5416  * 3.  The arrays have same number of components and \a other array has one tuple. Then
5417  *   _this_ [ i, j ] *= _a2_ [ 0, j ].
5418  *
5419  *  \param [in] other - an array to multiply to \a this one.
5420  *  \throw If \a other is NULL.
5421  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
5422  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
5423  *         \a other has number of both tuples and components not equal to 1.
5424  */
5425 void DataArrayDouble::multiplyEqual(const DataArrayDouble *other)
5426 {
5427   if(!other)
5428     throw INTERP_KERNEL::Exception("DataArrayDouble::multiplyEqual : input DataArrayDouble instance is NULL !");
5429   const char *msg="Nb of tuples mismatch for DataArrayDouble::multiplyEqual !";
5430   checkAllocated();
5431   other->checkAllocated();
5432   int nbOfTuple=getNumberOfTuples();
5433   int nbOfTuple2=other->getNumberOfTuples();
5434   int nbOfComp=getNumberOfComponents();
5435   int nbOfComp2=other->getNumberOfComponents();
5436   if(nbOfTuple==nbOfTuple2)
5437     {
5438       if(nbOfComp==nbOfComp2)
5439         {
5440           std::transform(begin(),end(),other->begin(),getPointer(),std::multiplies<double>());
5441         }
5442       else if(nbOfComp2==1)
5443         {
5444           double *ptr=getPointer();
5445           const double *ptrc=other->getConstPointer();
5446           for(int i=0;i<nbOfTuple;i++)
5447             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::multiplies<double>(),*ptrc++));
5448         }
5449       else
5450         throw INTERP_KERNEL::Exception(msg);
5451     }
5452   else if(nbOfTuple2==1)
5453     {
5454       if(nbOfComp2==nbOfComp)
5455         {
5456           double *ptr=getPointer();
5457           const double *ptrc=other->getConstPointer();
5458           for(int i=0;i<nbOfTuple;i++)
5459             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::multiplies<double>());
5460         }
5461       else
5462         throw INTERP_KERNEL::Exception(msg);
5463     }
5464   else
5465     throw INTERP_KERNEL::Exception(msg);
5466   declareAsNew();
5467 }
5468
5469 /*!
5470  * Returns a new DataArrayDouble that is a division of two given arrays. There are 3
5471  * valid cases.
5472  * 1.  The arrays have same number of tuples and components. Then each value of
5473  *   the result array (_a_) is a division of the corresponding values of \a a1 and
5474  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ i, j ].
5475  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
5476  *   component. Then
5477  *   _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ i, 0 ].
5478  * 3.  The arrays have same number of components and one array, say _a2_, has one
5479  *   tuple. Then
5480  *   _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ 0, j ].
5481  *
5482  * Info on components is copied either from the first array (in the first case) or from
5483  * the array with maximal number of elements (getNbOfElems()).
5484  *  \warning No check of division by zero is performed!
5485  *  \param [in] a1 - a numerator array.
5486  *  \param [in] a2 - a denominator array.
5487  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
5488  *          The caller is to delete this result array using decrRef() as it is no more
5489  *          needed.
5490  *  \throw If either \a a1 or \a a2 is NULL.
5491  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
5492  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
5493  *         none of them has number of tuples or components equal to 1.
5494  */
5495 DataArrayDouble *DataArrayDouble::Divide(const DataArrayDouble *a1, const DataArrayDouble *a2)
5496 {
5497   if(!a1 || !a2)
5498     throw INTERP_KERNEL::Exception("DataArrayDouble::Divide : input DataArrayDouble instance is NULL !");
5499   int nbOfTuple1=a1->getNumberOfTuples();
5500   int nbOfTuple2=a2->getNumberOfTuples();
5501   int nbOfComp1=a1->getNumberOfComponents();
5502   int nbOfComp2=a2->getNumberOfComponents();
5503   if(nbOfTuple2==nbOfTuple1)
5504     {
5505       if(nbOfComp1==nbOfComp2)
5506         {
5507           MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
5508           ret->alloc(nbOfTuple2,nbOfComp1);
5509           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::divides<double>());
5510           ret->copyStringInfoFrom(*a1);
5511           return ret.retn();
5512         }
5513       else if(nbOfComp2==1)
5514         {
5515           MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
5516           ret->alloc(nbOfTuple1,nbOfComp1);
5517           const double *a2Ptr=a2->getConstPointer();
5518           const double *a1Ptr=a1->getConstPointer();
5519           double *res=ret->getPointer();
5520           for(int i=0;i<nbOfTuple1;i++)
5521             res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::divides<double>(),a2Ptr[i]));
5522           ret->copyStringInfoFrom(*a1);
5523           return ret.retn();
5524         }
5525       else
5526         {
5527           a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Divide !");
5528           return 0;
5529         }
5530     }
5531   else if(nbOfTuple2==1)
5532     {
5533       a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Divide !");
5534       MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
5535       ret->alloc(nbOfTuple1,nbOfComp1);
5536       const double *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
5537       double *pt=ret->getPointer();
5538       for(int i=0;i<nbOfTuple1;i++)
5539         pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::divides<double>());
5540       ret->copyStringInfoFrom(*a1);
5541       return ret.retn();
5542     }
5543   else
5544     {
5545       a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Divide !");//will always throw an exception
5546       return 0;
5547     }
5548 }
5549
5550 /*!
5551  * Divide values of \a this array by values of another DataArrayDouble. There are 3
5552  * valid cases.
5553  * 1.  The arrays have same number of tuples and components. Then each value of
5554  *    \a this array is divided by the corresponding value of \a other one, i.e.:
5555  *   _a_ [ i, j ] /= _other_ [ i, j ].
5556  * 2.  The arrays have same number of tuples and \a other array has one component. Then
5557  *   _a_ [ i, j ] /= _other_ [ i, 0 ].
5558  * 3.  The arrays have same number of components and \a other array has one tuple. Then
5559  *   _a_ [ i, j ] /= _a2_ [ 0, j ].
5560  *
5561  *  \warning No check of division by zero is performed!
5562  *  \param [in] other - an array to divide \a this one by.
5563  *  \throw If \a other is NULL.
5564  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
5565  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
5566  *         \a other has number of both tuples and components not equal to 1.
5567  */
5568 void DataArrayDouble::divideEqual(const DataArrayDouble *other)
5569 {
5570   if(!other)
5571     throw INTERP_KERNEL::Exception("DataArrayDouble::divideEqual : input DataArrayDouble instance is NULL !");
5572   const char *msg="Nb of tuples mismatch for DataArrayDouble::divideEqual !";
5573   checkAllocated();
5574   other->checkAllocated();
5575   int nbOfTuple=getNumberOfTuples();
5576   int nbOfTuple2=other->getNumberOfTuples();
5577   int nbOfComp=getNumberOfComponents();
5578   int nbOfComp2=other->getNumberOfComponents();
5579   if(nbOfTuple==nbOfTuple2)
5580     {
5581       if(nbOfComp==nbOfComp2)
5582         {
5583           std::transform(begin(),end(),other->begin(),getPointer(),std::divides<double>());
5584         }
5585       else if(nbOfComp2==1)
5586         {
5587           double *ptr=getPointer();
5588           const double *ptrc=other->getConstPointer();
5589           for(int i=0;i<nbOfTuple;i++)
5590             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::divides<double>(),*ptrc++));
5591         }
5592       else
5593         throw INTERP_KERNEL::Exception(msg);
5594     }
5595   else if(nbOfTuple2==1)
5596     {
5597       if(nbOfComp2==nbOfComp)
5598         {
5599           double *ptr=getPointer();
5600           const double *ptrc=other->getConstPointer();
5601           for(int i=0;i<nbOfTuple;i++)
5602             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::divides<double>());
5603         }
5604       else
5605         throw INTERP_KERNEL::Exception(msg);
5606     }
5607   else
5608     throw INTERP_KERNEL::Exception(msg);
5609   declareAsNew();
5610 }
5611
5612 /*!
5613  * Returns a new DataArrayDouble that is the result of pow of two given arrays. There are 3
5614  * valid cases.
5615  *
5616  *  \param [in] a1 - an array to pow up.
5617  *  \param [in] a2 - another array to sum up.
5618  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
5619  *          The caller is to delete this result array using decrRef() as it is no more
5620  *          needed.
5621  *  \throw If either \a a1 or \a a2 is NULL.
5622  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
5623  *  \throw If \a a1->getNumberOfComponents() != 1 or \a a2->getNumberOfComponents() != 1.
5624  *  \throw If there is a negative value in \a a1.
5625  */
5626 DataArrayDouble *DataArrayDouble::Pow(const DataArrayDouble *a1, const DataArrayDouble *a2)
5627 {
5628   if(!a1 || !a2)
5629     throw INTERP_KERNEL::Exception("DataArrayDouble::Pow : at least one of input instances is null !");
5630   int nbOfTuple=a1->getNumberOfTuples();
5631   int nbOfTuple2=a2->getNumberOfTuples();
5632   int nbOfComp=a1->getNumberOfComponents();
5633   int nbOfComp2=a2->getNumberOfComponents();
5634   if(nbOfTuple!=nbOfTuple2)
5635     throw INTERP_KERNEL::Exception("DataArrayDouble::Pow : number of tuples mismatches !");
5636   if(nbOfComp!=1 || nbOfComp2!=1)
5637     throw INTERP_KERNEL::Exception("DataArrayDouble::Pow : number of components of both arrays must be equal to 1 !");
5638   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New(); ret->alloc(nbOfTuple,1);
5639   const double *ptr1(a1->begin()),*ptr2(a2->begin());
5640   double *ptr=ret->getPointer();
5641   for(int i=0;i<nbOfTuple;i++,ptr1++,ptr2++,ptr++)
5642     {
5643       if(*ptr1>=0)
5644         {
5645           *ptr=pow(*ptr1,*ptr2);
5646         }
5647       else
5648         {
5649           std::ostringstream oss; oss << "DataArrayDouble::Pow : on tuple #" << i << " of a1 value is < 0 (" << *ptr1 << ") !";
5650           throw INTERP_KERNEL::Exception(oss.str().c_str());
5651         }
5652     }
5653   return ret.retn();
5654 }
5655
5656 /*!
5657  * Apply pow on values of another DataArrayDouble to values of \a this one.
5658  *
5659  *  \param [in] other - an array to pow to \a this one.
5660  *  \throw If \a other is NULL.
5661  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples()
5662  *  \throw If \a this->getNumberOfComponents() != 1 or \a other->getNumberOfComponents() != 1
5663  *  \throw If there is a negative value in \a this.
5664  */
5665 void DataArrayDouble::powEqual(const DataArrayDouble *other)
5666 {
5667   if(!other)
5668     throw INTERP_KERNEL::Exception("DataArrayDouble::powEqual : input instance is null !");
5669   int nbOfTuple=getNumberOfTuples();
5670   int nbOfTuple2=other->getNumberOfTuples();
5671   int nbOfComp=getNumberOfComponents();
5672   int nbOfComp2=other->getNumberOfComponents();
5673   if(nbOfTuple!=nbOfTuple2)
5674     throw INTERP_KERNEL::Exception("DataArrayDouble::powEqual : number of tuples mismatches !");
5675   if(nbOfComp!=1 || nbOfComp2!=1)
5676     throw INTERP_KERNEL::Exception("DataArrayDouble::powEqual : number of components of both arrays must be equal to 1 !");
5677   double *ptr=getPointer();
5678   const double *ptrc=other->begin();
5679   for(int i=0;i<nbOfTuple;i++,ptrc++,ptr++)
5680     {
5681       if(*ptr>=0)
5682         *ptr=pow(*ptr,*ptrc);
5683       else
5684         {
5685           std::ostringstream oss; oss << "DataArrayDouble::powEqual : on tuple #" << i << " of this value is < 0 (" << *ptr << ") !";
5686           throw INTERP_KERNEL::Exception(oss.str().c_str());
5687         }
5688     }
5689   declareAsNew();
5690 }
5691
5692 /*!
5693  * This method is \b NOT wrapped into python because it can be useful only for performance reasons in C++ context.
5694  * All values in \a this must be 0. or 1. within eps error. 0 means false, 1 means true.
5695  * If an another value than 0 or 1 appear (within eps precision) an INTERP_KERNEL::Exception will be thrown.
5696  *
5697  * \throw if \a this is not allocated.
5698  * \throw if \a this has not exactly one component.
5699  */
5700 std::vector<bool> DataArrayDouble::toVectorOfBool(double eps) const
5701 {
5702   checkAllocated();
5703   if(getNumberOfComponents()!=1)
5704     throw INTERP_KERNEL::Exception("DataArrayDouble::toVectorOfBool : must be applied on single component array !");
5705   int nbt(getNumberOfTuples());
5706   std::vector<bool> ret(nbt);
5707   const double *pt(begin());
5708   for(int i=0;i<nbt;i++)
5709     {
5710       if(fabs(pt[i])<eps)
5711         ret[i]=false;
5712       else if(fabs(pt[i]-1.)<eps)
5713         ret[i]=true;
5714       else
5715         {
5716           std::ostringstream oss; oss << "DataArrayDouble::toVectorOfBool : the tuple #" << i << " has value " << pt[i] << " is invalid ! must be 0. or 1. !";
5717           throw INTERP_KERNEL::Exception(oss.str().c_str());
5718         }
5719     }
5720   return ret;
5721 }
5722
5723 /*!
5724  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
5725  * Server side.
5726  */
5727 void DataArrayDouble::getTinySerializationIntInformation(std::vector<int>& tinyInfo) const
5728 {
5729   tinyInfo.resize(2);
5730   if(isAllocated())
5731     {
5732       tinyInfo[0]=getNumberOfTuples();
5733       tinyInfo[1]=getNumberOfComponents();
5734     }
5735   else
5736     {
5737       tinyInfo[0]=-1;
5738       tinyInfo[1]=-1;
5739     }
5740 }
5741
5742 /*!
5743  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
5744  * Server side.
5745  */
5746 void DataArrayDouble::getTinySerializationStrInformation(std::vector<std::string>& tinyInfo) const
5747 {
5748   if(isAllocated())
5749     {
5750       int nbOfCompo=getNumberOfComponents();
5751       tinyInfo.resize(nbOfCompo+1);
5752       tinyInfo[0]=getName();
5753       for(int i=0;i<nbOfCompo;i++)
5754         tinyInfo[i+1]=getInfoOnComponent(i);
5755     }
5756   else
5757     {
5758       tinyInfo.resize(1);
5759       tinyInfo[0]=getName();
5760     }
5761 }
5762
5763 /*!
5764  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
5765  * This method returns if a feeding is needed.
5766  */
5767 bool DataArrayDouble::resizeForUnserialization(const std::vector<int>& tinyInfoI)
5768 {
5769   int nbOfTuple=tinyInfoI[0];
5770   int nbOfComp=tinyInfoI[1];
5771   if(nbOfTuple!=-1 || nbOfComp!=-1)
5772     {
5773       alloc(nbOfTuple,nbOfComp);
5774       return true;
5775     }
5776   return false;
5777 }
5778
5779 /*!
5780  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
5781  */
5782 void DataArrayDouble::finishUnserialization(const std::vector<int>& tinyInfoI, const std::vector<std::string>& tinyInfoS)
5783 {
5784   setName(tinyInfoS[0]);
5785   if(isAllocated())
5786     {
5787       int nbOfCompo=getNumberOfComponents();
5788       for(int i=0;i<nbOfCompo;i++)
5789         setInfoOnComponent(i,tinyInfoS[i+1]);
5790     }
5791 }
5792
5793 DataArrayDoubleIterator::DataArrayDoubleIterator(DataArrayDouble *da):_da(da),_tuple_id(0),_nb_comp(0),_nb_tuple(0)
5794 {
5795   if(_da)
5796     {
5797       _da->incrRef();
5798       if(_da->isAllocated())
5799         {
5800           _nb_comp=da->getNumberOfComponents();
5801           _nb_tuple=da->getNumberOfTuples();
5802           _pt=da->getPointer();
5803         }
5804     }
5805 }
5806
5807 DataArrayDoubleIterator::~DataArrayDoubleIterator()
5808 {
5809   if(_da)
5810     _da->decrRef();
5811 }
5812
5813 DataArrayDoubleTuple *DataArrayDoubleIterator::nextt()
5814 {
5815   if(_tuple_id<_nb_tuple)
5816     {
5817       _tuple_id++;
5818       DataArrayDoubleTuple *ret=new DataArrayDoubleTuple(_pt,_nb_comp);
5819       _pt+=_nb_comp;
5820       return ret;
5821     }
5822   else
5823     return 0;
5824 }
5825
5826 DataArrayDoubleTuple::DataArrayDoubleTuple(double *pt, int nbOfComp):_pt(pt),_nb_of_compo(nbOfComp)
5827 {
5828 }
5829
5830
5831 std::string DataArrayDoubleTuple::repr() const
5832 {
5833   std::ostringstream oss; oss.precision(17); oss << "(";
5834   for(int i=0;i<_nb_of_compo-1;i++)
5835     oss << _pt[i] << ", ";
5836   oss << _pt[_nb_of_compo-1] << ")";
5837   return oss.str();
5838 }
5839
5840 double DataArrayDoubleTuple::doubleValue() const
5841 {
5842   if(_nb_of_compo==1)
5843     return *_pt;
5844   throw INTERP_KERNEL::Exception("DataArrayDoubleTuple::doubleValue : DataArrayDoubleTuple instance has not exactly 1 component -> Not possible to convert it into a double precision float !");
5845 }
5846
5847 /*!
5848  * This method returns a newly allocated instance the caller should dealed with by a ParaMEDMEM::DataArrayDouble::decrRef.
5849  * This method performs \b no copy of data. The content is only referenced using ParaMEDMEM::DataArrayDouble::useArray with ownership set to \b false.
5850  * 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
5851  * \b nbOfCompo=1 and \bnbOfTuples==this->_nb_of_elem.
5852  */
5853 DataArrayDouble *DataArrayDoubleTuple::buildDADouble(int nbOfTuples, int nbOfCompo) const
5854 {
5855   if((_nb_of_compo==nbOfCompo && nbOfTuples==1) || (_nb_of_compo==nbOfTuples && nbOfCompo==1))
5856     {
5857       DataArrayDouble *ret=DataArrayDouble::New();
5858       ret->useExternalArrayWithRWAccess(_pt,nbOfTuples,nbOfCompo);
5859       return ret;
5860     }
5861   else
5862     {
5863       std::ostringstream oss; oss << "DataArrayDoubleTuple::buildDADouble : unable to build a requested DataArrayDouble instance with nbofTuple=" << nbOfTuples << " and nbOfCompo=" << nbOfCompo;
5864       oss << ".\nBecause the number of elements in this is " << _nb_of_compo << " !";
5865       throw INTERP_KERNEL::Exception(oss.str().c_str());
5866     }
5867 }
5868
5869 /*!
5870  * Returns a new instance of DataArrayInt. The caller is to delete this array
5871  * using decrRef() as it is no more needed. 
5872  */
5873 DataArrayInt *DataArrayInt::New()
5874 {
5875   return new DataArrayInt;
5876 }
5877
5878 /*!
5879  * Checks if raw data is allocated. Read more on the raw data
5880  * in \ref MEDCouplingArrayBasicsTuplesAndCompo "DataArrays infos" for more information.
5881  *  \return bool - \a true if the raw data is allocated, \a false else.
5882  */
5883 bool DataArrayInt::isAllocated() const
5884 {
5885   return getConstPointer()!=0;
5886 }
5887
5888 /*!
5889  * Checks if raw data is allocated and throws an exception if it is not the case.
5890  *  \throw If the raw data is not allocated.
5891  */
5892 void DataArrayInt::checkAllocated() const
5893 {
5894   if(!isAllocated())
5895     throw INTERP_KERNEL::Exception("DataArrayInt::checkAllocated : Array is defined but not allocated ! Call alloc or setValues method first !");
5896 }
5897
5898 /*!
5899  * This method desallocated \a this without modification of informations relative to the components.
5900  * After call of this method, DataArrayInt::isAllocated will return false.
5901  * If \a this is already not allocated, \a this is let unchanged.
5902  */
5903 void DataArrayInt::desallocate()
5904 {
5905   _mem.destroy();
5906 }
5907
5908 std::size_t DataArrayInt::getHeapMemorySizeWithoutChildren() const
5909 {
5910   std::size_t sz(_mem.getNbOfElemAllocated());
5911   sz*=sizeof(int);
5912   return DataArray::getHeapMemorySizeWithoutChildren()+sz;
5913 }
5914
5915 /*!
5916  * Returns the only one value in \a this, if and only if number of elements
5917  * (nb of tuples * nb of components) is equal to 1, and that \a this is allocated.
5918  *  \return double - the sole value stored in \a this array.
5919  *  \throw If at least one of conditions stated above is not fulfilled.
5920  */
5921 int DataArrayInt::intValue() const
5922 {
5923   if(isAllocated())
5924     {
5925       if(getNbOfElems()==1)
5926         {
5927           return *getConstPointer();
5928         }
5929       else
5930         throw INTERP_KERNEL::Exception("DataArrayInt::intValue : DataArrayInt instance is allocated but number of elements is not equal to 1 !");
5931     }
5932   else
5933     throw INTERP_KERNEL::Exception("DataArrayInt::intValue : DataArrayInt instance is not allocated !");
5934 }
5935
5936 /*!
5937  * Returns an integer value characterizing \a this array, which is useful for a quick
5938  * comparison of many instances of DataArrayInt.
5939  *  \return int - the hash value.
5940  *  \throw If \a this is not allocated.
5941  */
5942 int DataArrayInt::getHashCode() const
5943 {
5944   checkAllocated();
5945   std::size_t nbOfElems=getNbOfElems();
5946   int ret=nbOfElems*65536;
5947   int delta=3;
5948   if(nbOfElems>48)
5949     delta=nbOfElems/8;
5950   int ret0=0;
5951   const int *pt=begin();
5952   for(std::size_t i=0;i<nbOfElems;i+=delta)
5953     ret0+=pt[i] & 0x1FFF;
5954   return ret+ret0;
5955 }
5956
5957 /*!
5958  * Checks the number of tuples.
5959  *  \return bool - \a true if getNumberOfTuples() == 0, \a false else.
5960  *  \throw If \a this is not allocated.
5961  */
5962 bool DataArrayInt::empty() const
5963 {
5964   checkAllocated();
5965   return getNumberOfTuples()==0;
5966 }
5967
5968 /*!
5969  * Returns a full copy of \a this. For more info on copying data arrays see
5970  * \ref MEDCouplingArrayBasicsCopyDeep.
5971  *  \return DataArrayInt * - a new instance of DataArrayInt.
5972  */
5973 DataArrayInt *DataArrayInt::deepCpy() const
5974 {
5975   return new DataArrayInt(*this);
5976 }
5977
5978 /*!
5979  * Returns either a \a deep or \a shallow copy of this array. For more info see
5980  * \ref MEDCouplingArrayBasicsCopyDeep and \ref MEDCouplingArrayBasicsCopyShallow.
5981  *  \param [in] dCpy - if \a true, a deep copy is returned, else, a shallow one.
5982  *  \return DataArrayInt * - either a new instance of DataArrayInt (if \a dCpy
5983  *          == \a true) or \a this instance (if \a dCpy == \a false).
5984  */
5985 DataArrayInt *DataArrayInt::performCpy(bool dCpy) const
5986 {
5987   if(dCpy)
5988     return deepCpy();
5989   else
5990     {
5991       incrRef();
5992       return const_cast<DataArrayInt *>(this);
5993     }
5994 }
5995
5996 /*!
5997  * Copies all the data from another DataArrayInt. For more info see
5998  * \ref MEDCouplingArrayBasicsCopyDeepAssign.
5999  *  \param [in] other - another instance of DataArrayInt to copy data from.
6000  *  \throw If the \a other is not allocated.
6001  */
6002 void DataArrayInt::cpyFrom(const DataArrayInt& other)
6003 {
6004   other.checkAllocated();
6005   int nbOfTuples=other.getNumberOfTuples();
6006   int nbOfComp=other.getNumberOfComponents();
6007   allocIfNecessary(nbOfTuples,nbOfComp);
6008   std::size_t nbOfElems=(std::size_t)nbOfTuples*nbOfComp;
6009   int *pt=getPointer();
6010   const int *ptI=other.getConstPointer();
6011   for(std::size_t i=0;i<nbOfElems;i++)
6012     pt[i]=ptI[i];
6013   copyStringInfoFrom(other);
6014 }
6015
6016 /*!
6017  * This method reserve nbOfElems elements in memory ( nbOfElems*4 bytes ) \b without impacting the number of tuples in \a this.
6018  * If \a this has already been allocated, this method checks that \a this has only one component. If not an INTERP_KERNEL::Exception will be thrown.
6019  * If \a this has not already been allocated, number of components is set to one.
6020  * This method allows to reduce number of reallocations on invokation of DataArrayInt::pushBackSilent and DataArrayInt::pushBackValsSilent on \a this.
6021  * 
6022  * \sa DataArrayInt::pack, DataArrayInt::pushBackSilent, DataArrayInt::pushBackValsSilent
6023  */
6024 void DataArrayInt::reserve(std::size_t nbOfElems)
6025 {
6026   int nbCompo=getNumberOfComponents();
6027   if(nbCompo==1)
6028     {
6029       _mem.reserve(nbOfElems);
6030     }
6031   else if(nbCompo==0)
6032     {
6033       _mem.reserve(nbOfElems);
6034       _info_on_compo.resize(1);
6035     }
6036   else
6037     throw INTERP_KERNEL::Exception("DataArrayInt::reserve : not available for DataArrayInt with number of components different than 1 !");
6038 }
6039
6040 /*!
6041  * This method adds at the end of \a this the single value \a val. This method do \b not update its time label to avoid useless incrementation
6042  * of counter. So the caller is expected to call TimeLabel::declareAsNew on \a this at the end of the push session.
6043  *
6044  * \param [in] val the value to be added in \a this
6045  * \throw If \a this has already been allocated with number of components different from one.
6046  * \sa DataArrayInt::pushBackValsSilent
6047  */
6048 void DataArrayInt::pushBackSilent(int val)
6049 {
6050   int nbCompo=getNumberOfComponents();
6051   if(nbCompo==1)
6052     _mem.pushBack(val);
6053   else if(nbCompo==0)
6054     {
6055       _info_on_compo.resize(1);
6056       _mem.pushBack(val);
6057     }
6058   else
6059     throw INTERP_KERNEL::Exception("DataArrayInt::pushBackSilent : not available for DataArrayInt with number of components different than 1 !");
6060 }
6061
6062 /*!
6063  * This method adds at the end of \a this a serie of values [\c valsBg,\c valsEnd). This method do \b not update its time label to avoid useless incrementation
6064  * of counter. So the caller is expected to call TimeLabel::declareAsNew on \a this at the end of the push session.
6065  *
6066  *  \param [in] valsBg - an array of values to push at the end of \this.
6067  *  \param [in] valsEnd - specifies the end of the array \a valsBg, so that
6068  *              the last value of \a valsBg is \a valsEnd[ -1 ].
6069  * \throw If \a this has already been allocated with number of components different from one.
6070  * \sa DataArrayInt::pushBackSilent
6071  */
6072 void DataArrayInt::pushBackValsSilent(const int *valsBg, const int *valsEnd)
6073 {
6074   int nbCompo=getNumberOfComponents();
6075   if(nbCompo==1)
6076     _mem.insertAtTheEnd(valsBg,valsEnd);
6077   else if(nbCompo==0)
6078     {
6079       _info_on_compo.resize(1);
6080       _mem.insertAtTheEnd(valsBg,valsEnd);
6081     }
6082   else
6083     throw INTERP_KERNEL::Exception("DataArrayInt::pushBackValsSilent : not available for DataArrayInt with number of components different than 1 !");
6084 }
6085
6086 /*!
6087  * This method returns silently ( without updating time label in \a this ) the last value, if any and suppress it.
6088  * \throw If \a this is already empty.
6089  * \throw If \a this has number of components different from one.
6090  */
6091 int DataArrayInt::popBackSilent()
6092 {
6093   if(getNumberOfComponents()==1)
6094     return _mem.popBack();
6095   else
6096     throw INTERP_KERNEL::Exception("DataArrayInt::popBackSilent : not available for DataArrayInt with number of components different than 1 !");
6097 }
6098
6099 /*!
6100  * This method \b do \b not modify content of \a this. It only modify its memory footprint if the allocated memory is to high regarding real data to store.
6101  *
6102  * \sa DataArrayInt::getHeapMemorySizeWithoutChildren, DataArrayInt::reserve
6103  */
6104 void DataArrayInt::pack() const
6105 {
6106   _mem.pack();
6107 }
6108
6109 /*!
6110  * Allocates the raw data in memory. If exactly as same memory as needed already
6111  * allocated, it is not re-allocated.
6112  *  \param [in] nbOfTuple - number of tuples of data to allocate.
6113  *  \param [in] nbOfCompo - number of components of data to allocate.
6114  *  \throw If \a nbOfTuple < 0 or \a nbOfCompo < 0.
6115  */
6116 void DataArrayInt::allocIfNecessary(int nbOfTuple, int nbOfCompo)
6117 {
6118   if(isAllocated())
6119     {
6120       if(nbOfTuple!=getNumberOfTuples() || nbOfCompo!=getNumberOfComponents())
6121         alloc(nbOfTuple,nbOfCompo);
6122     }
6123   else
6124     alloc(nbOfTuple,nbOfCompo);
6125 }
6126
6127 /*!
6128  * Allocates the raw data in memory. If the memory was already allocated, then it is
6129  * freed and re-allocated. See an example of this method use
6130  * \ref MEDCouplingArraySteps1WC "here".
6131  *  \param [in] nbOfTuple - number of tuples of data to allocate.
6132  *  \param [in] nbOfCompo - number of components of data to allocate.
6133  *  \throw If \a nbOfTuple < 0 or \a nbOfCompo < 0.
6134  */
6135 void DataArrayInt::alloc(int nbOfTuple, int nbOfCompo)
6136 {
6137   if(nbOfTuple<0 || nbOfCompo<0)
6138     throw INTERP_KERNEL::Exception("DataArrayInt::alloc : request for negative length of data !");
6139   _info_on_compo.resize(nbOfCompo);
6140   _mem.alloc(nbOfCompo*(std::size_t)nbOfTuple);
6141   declareAsNew();
6142 }
6143
6144 /*!
6145  * Assign zero to all values in \a this array. To know more on filling arrays see
6146  * \ref MEDCouplingArrayFill.
6147  * \throw If \a this is not allocated.
6148  */
6149 void DataArrayInt::fillWithZero()
6150 {
6151   checkAllocated();
6152   _mem.fillWithValue(0);
6153   declareAsNew();
6154 }
6155
6156 /*!
6157  * Assign \a val to all values in \a this array. To know more on filling arrays see
6158  * \ref MEDCouplingArrayFill.
6159  *  \param [in] val - the value to fill with.
6160  *  \throw If \a this is not allocated.
6161  */
6162 void DataArrayInt::fillWithValue(int val)
6163 {
6164   checkAllocated();
6165   _mem.fillWithValue(val);
6166   declareAsNew();
6167 }
6168
6169 /*!
6170  * Set all values in \a this array so that the i-th element equals to \a init + i
6171  * (i starts from zero). To know more on filling arrays see \ref MEDCouplingArrayFill.
6172  *  \param [in] init - value to assign to the first element of array.
6173  *  \throw If \a this->getNumberOfComponents() != 1
6174  *  \throw If \a this is not allocated.
6175  */
6176 void DataArrayInt::iota(int init)
6177 {
6178   checkAllocated();
6179   if(getNumberOfComponents()!=1)
6180     throw INTERP_KERNEL::Exception("DataArrayInt::iota : works only for arrays with only one component, you can call 'rearrange' method before !");
6181   int *ptr=getPointer();
6182   int ntuples=getNumberOfTuples();
6183   for(int i=0;i<ntuples;i++)
6184     ptr[i]=init+i;
6185   declareAsNew();
6186 }
6187
6188 /*!
6189  * Returns a textual and human readable representation of \a this instance of
6190  * DataArrayInt. This text is shown when a DataArrayInt is printed in Python.
6191  *  \return std::string - text describing \a this DataArrayInt.
6192  */
6193 std::string DataArrayInt::repr() const
6194 {
6195   std::ostringstream ret;
6196   reprStream(ret);
6197   return ret.str();
6198 }
6199
6200 std::string DataArrayInt::reprZip() const
6201 {
6202   std::ostringstream ret;
6203   reprZipStream(ret);
6204   return ret.str();
6205 }
6206
6207 void DataArrayInt::writeVTK(std::ostream& ofs, int indent, const std::string& type, const std::string& nameInFile, DataArrayByte *byteArr) const
6208 {
6209   static const char SPACE[4]={' ',' ',' ',' '};
6210   checkAllocated();
6211   std::string idt(indent,' ');
6212   ofs << idt << "<DataArray type=\"" << type << "\" Name=\"" << nameInFile << "\" NumberOfComponents=\"" << getNumberOfComponents() << "\"";
6213   if(byteArr)
6214     {
6215       ofs << " format=\"appended\" offset=\"" << byteArr->getNumberOfTuples() << "\">";
6216       if(std::string(type)=="Int32")
6217         {
6218           const char *data(reinterpret_cast<const char *>(begin()));
6219           std::size_t sz(getNbOfElems()*sizeof(int));
6220           byteArr->insertAtTheEnd(data,data+sz);
6221           byteArr->insertAtTheEnd(SPACE,SPACE+4);
6222         }
6223       else if(std::string(type)=="Int8")
6224         {
6225           INTERP_KERNEL::AutoPtr<char> tmp(new char[getNbOfElems()]);
6226           std::copy(begin(),end(),(char *)tmp);
6227           byteArr->insertAtTheEnd((char *)tmp,(char *)tmp+getNbOfElems());
6228           byteArr->insertAtTheEnd(SPACE,SPACE+4);
6229         }
6230       else if(std::string(type)=="UInt8")
6231         {
6232           INTERP_KERNEL::AutoPtr<unsigned char> tmp(new unsigned char[getNbOfElems()]);
6233           std::copy(begin(),end(),(unsigned char *)tmp);
6234           byteArr->insertAtTheEnd((unsigned char *)tmp,(unsigned char *)tmp+getNbOfElems());
6235           byteArr->insertAtTheEnd(SPACE,SPACE+4);
6236         }
6237       else
6238         throw INTERP_KERNEL::Exception("DataArrayInt::writeVTK : Only Int32, Int8 and UInt8 supported !");
6239     }
6240   else
6241     {
6242       ofs << " RangeMin=\"" << getMinValueInArray() << "\" RangeMax=\"" << getMaxValueInArray() << "\" format=\"ascii\">\n" << idt;
6243       std::copy(begin(),end(),std::ostream_iterator<int>(ofs," "));
6244     }
6245   ofs << std::endl << idt << "</DataArray>\n";
6246 }
6247
6248 void DataArrayInt::reprStream(std::ostream& stream) const
6249 {
6250   stream << "Name of int array : \"" << _name << "\"\n";
6251   reprWithoutNameStream(stream);
6252 }
6253
6254 void DataArrayInt::reprZipStream(std::ostream& stream) const
6255 {
6256   stream << "Name of int array : \"" << _name << "\"\n";
6257   reprZipWithoutNameStream(stream);
6258 }
6259
6260 void DataArrayInt::reprWithoutNameStream(std::ostream& stream) const
6261 {
6262   DataArray::reprWithoutNameStream(stream);
6263   _mem.repr(getNumberOfComponents(),stream);
6264 }
6265
6266 void DataArrayInt::reprZipWithoutNameStream(std::ostream& stream) const
6267 {
6268   DataArray::reprWithoutNameStream(stream);
6269   _mem.reprZip(getNumberOfComponents(),stream);
6270 }
6271
6272 void DataArrayInt::reprCppStream(const std::string& varName, std::ostream& stream) const
6273 {
6274   int nbTuples=getNumberOfTuples(),nbComp=getNumberOfComponents();
6275   const int *data=getConstPointer();
6276   stream << "DataArrayInt *" << varName << "=DataArrayInt::New();" << std::endl;
6277   if(nbTuples*nbComp>=1)
6278     {
6279       stream << "const int " << varName << "Data[" << nbTuples*nbComp << "]={";
6280       std::copy(data,data+nbTuples*nbComp-1,std::ostream_iterator<int>(stream,","));
6281       stream << data[nbTuples*nbComp-1] << "};" << std::endl;
6282       stream << varName << "->useArray(" << varName << "Data,false,CPP_DEALLOC," << nbTuples << "," << nbComp << ");" << std::endl;
6283     }
6284   else
6285     stream << varName << "->alloc(" << nbTuples << "," << nbComp << ");" << std::endl;
6286   stream << varName << "->setName(\"" << getName() << "\");" << std::endl;
6287 }
6288
6289 /*!
6290  * Method that gives a quick overvien of \a this for python.
6291  */
6292 void DataArrayInt::reprQuickOverview(std::ostream& stream) const
6293 {
6294   static const std::size_t MAX_NB_OF_BYTE_IN_REPR=300;
6295   stream << "DataArrayInt C++ instance at " << this << ". ";
6296   if(isAllocated())
6297     {
6298       int nbOfCompo=(int)_info_on_compo.size();
6299       if(nbOfCompo>=1)
6300         {
6301           int nbOfTuples=getNumberOfTuples();
6302           stream << "Number of tuples : " << nbOfTuples << ". Number of components : " << nbOfCompo << "." << std::endl;
6303           reprQuickOverviewData(stream,MAX_NB_OF_BYTE_IN_REPR);
6304         }
6305       else
6306         stream << "Number of components : 0.";
6307     }
6308   else
6309     stream << "*** No data allocated ****";
6310 }
6311
6312 void DataArrayInt::reprQuickOverviewData(std::ostream& stream, std::size_t maxNbOfByteInRepr) const
6313 {
6314   const int *data=begin();
6315   int nbOfTuples=getNumberOfTuples();
6316   int nbOfCompo=(int)_info_on_compo.size();
6317   std::ostringstream oss2; oss2 << "[";
6318   std::string oss2Str(oss2.str());
6319   bool isFinished=true;
6320   for(int i=0;i<nbOfTuples && isFinished;i++)
6321     {
6322       if(nbOfCompo>1)
6323         {
6324           oss2 << "(";
6325           for(int j=0;j<nbOfCompo;j++,data++)
6326             {
6327               oss2 << *data;
6328               if(j!=nbOfCompo-1) oss2 << ", ";
6329             }
6330           oss2 << ")";
6331         }
6332       else
6333         oss2 << *data++;
6334       if(i!=nbOfTuples-1) oss2 << ", ";
6335       std::string oss3Str(oss2.str());
6336       if(oss3Str.length()<maxNbOfByteInRepr)
6337         oss2Str=oss3Str;
6338       else
6339         isFinished=false;
6340     }
6341   stream << oss2Str;
6342   if(!isFinished)
6343     stream << "... ";
6344   stream << "]";
6345 }
6346
6347 /*!
6348  * Modifies in place \a this one-dimensional array so that each value \a v = \a indArrBg[ \a v ],
6349  * i.e. a current value is used as in index to get a new value from \a indArrBg.
6350  *  \param [in] indArrBg - pointer to the first element of array of new values to assign
6351  *         to \a this array.
6352  *  \param [in] indArrEnd - specifies the end of the array \a indArrBg, so that
6353  *              the last value of \a indArrBg is \a indArrEnd[ -1 ].
6354  *  \throw If \a this->getNumberOfComponents() != 1
6355  *  \throw If any value of \a this can't be used as a valid index for 
6356  *         [\a indArrBg, \a indArrEnd).
6357  *
6358  *  \sa replaceOneValByInThis
6359  */
6360 void DataArrayInt::transformWithIndArr(const int *indArrBg, const int *indArrEnd)
6361 {
6362   checkAllocated();
6363   if(getNumberOfComponents()!=1)
6364     throw INTERP_KERNEL::Exception("Call transformWithIndArr method on DataArrayInt with only one component, you can call 'rearrange' method before !");
6365   int nbElemsIn((int)std::distance(indArrBg,indArrEnd)),nbOfTuples(getNumberOfTuples()),*pt(getPointer());
6366   for(int i=0;i<nbOfTuples;i++,pt++)
6367     {
6368       if(*pt>=0 && *pt<nbElemsIn)
6369         *pt=indArrBg[*pt];
6370       else
6371         {
6372           std::ostringstream oss; oss << "DataArrayInt::transformWithIndArr : error on tuple #" << i << " of this value is " << *pt << ", should be in [0," << nbElemsIn << ") !";
6373           throw INTERP_KERNEL::Exception(oss.str().c_str());
6374         }
6375     }
6376   declareAsNew();
6377 }
6378
6379 /*!
6380  * Modifies in place \a this one-dimensional array like this : each id in \a this so that this[id] equal to \a valToBeReplaced will be replaced at the same place by \a replacedBy.
6381  *
6382  * \param [in] valToBeReplaced - the value in \a this to be replaced.
6383  * \param [in] replacedBy - the value taken by each tuple previously equal to \a valToBeReplaced.
6384  *
6385  * \sa DataArrayInt::transformWithIndArr
6386  */
6387 void DataArrayInt::replaceOneValByInThis(int valToBeReplaced, int replacedBy)
6388 {
6389   checkAllocated();
6390   if(getNumberOfComponents()!=1)
6391     throw INTERP_KERNEL::Exception("Call replaceOneValByInThis method on DataArrayInt with only one component, you can call 'rearrange' method before !");
6392   if(valToBeReplaced==replacedBy)
6393     return ;
6394   int nbOfTuples(getNumberOfTuples()),*pt(getPointer());
6395   for(int i=0;i<nbOfTuples;i++,pt++)
6396     {
6397       if(*pt==valToBeReplaced)
6398         *pt=replacedBy;
6399     }
6400 }
6401
6402 /*!
6403  * Computes distribution of values of \a this one-dimensional array between given value
6404  * ranges (casts). This method is typically useful for entity number spliting by types,
6405  * for example. 
6406  *  \warning The values contained in \a arrBg should be sorted ascendently. No
6407  *           check of this is be done. If not, the result is not warranted. 
6408  *  \param [in] arrBg - the array of ascending values defining the value ranges. The i-th
6409  *         value of \a arrBg (\a arrBg[ i ]) gives the lowest value of the i-th range,
6410  *         and the greatest value of the i-th range equals to \a arrBg[ i+1 ] - 1. \a
6411  *         arrBg containing \a n values defines \a n-1 ranges. The last value of \a arrBg
6412  *         should be more than every value in \a this array.
6413  *  \param [in] arrEnd - specifies the end of the array \a arrBg, so that
6414  *              the last value of \a arrBg is \a arrEnd[ -1 ].
6415  *  \param [out] castArr - a new instance of DataArrayInt, of same size as \a this array
6416  *         (same number of tuples and components), the caller is to delete 
6417  *         using decrRef() as it is no more needed.
6418  *         This array contains indices of ranges for every value of \a this array. I.e.
6419  *         the i-th value of \a castArr gives the index of range the i-th value of \a this
6420  *         belongs to. Or, in other words, this parameter contains for each tuple in \a
6421  *         this in which cast it holds.
6422  *  \param [out] rankInsideCast - a new instance of DataArrayInt, of same size as \a this
6423  *         array, the caller is to delete using decrRef() as it is no more needed.
6424  *         This array contains ranks of values of \a this array within ranges
6425  *         they belongs to. I.e. the i-th value of \a rankInsideCast gives the rank of
6426  *         the i-th value of \a this array within the \a castArr[ i ]-th range, to which
6427  *         the i-th value of \a this belongs to. Or, in other words, this param contains 
6428  *         for each tuple its rank inside its cast. The rank is computed as difference
6429  *         between the value and the lowest value of range.
6430  *  \param [out] castsPresent - a new instance of DataArrayInt, containing indices of
6431  *         ranges (casts) to which at least one value of \a this array belongs.
6432  *         Or, in other words, this param contains the casts that \a this contains.
6433  *         The caller is to delete this array using decrRef() as it is no more needed.
6434  *
6435  * \b Example: If \a this contains [6,5,0,3,2,7,8,1,4] and \a arrBg contains [0,4,9] then
6436  *            the output of this method will be : 
6437  * - \a castArr       : [1,1,0,0,0,1,1,0,1]
6438  * - \a rankInsideCast: [2,1,0,3,2,3,4,1,0]
6439  * - \a castsPresent  : [0,1]
6440  *
6441  * I.e. values of \a this array belong to 2 ranges: #0 and #1. Value 6 belongs to the
6442  * range #1 and its rank within this range is 2; etc.
6443  *
6444  *  \throw If \a this->getNumberOfComponents() != 1.
6445  *  \throw If \a arrEnd - arrBg < 2.
6446  *  \throw If any value of \a this is not less than \a arrEnd[-1].
6447  */
6448 void DataArrayInt::splitByValueRange(const int *arrBg, const int *arrEnd,
6449                                      DataArrayInt *& castArr, DataArrayInt *& rankInsideCast, DataArrayInt *& castsPresent) const
6450 {
6451   checkAllocated();
6452   if(getNumberOfComponents()!=1)
6453     throw INTERP_KERNEL::Exception("Call splitByValueRange  method on DataArrayInt with only one component, you can call 'rearrange' method before !");
6454   int nbOfTuples=getNumberOfTuples();
6455   std::size_t nbOfCast=std::distance(arrBg,arrEnd);
6456   if(nbOfCast<2)
6457     throw INTERP_KERNEL::Exception("DataArrayInt::splitByValueRange : The input array giving the cast range values should be of size >=2 !");
6458   nbOfCast--;
6459   const int *work=getConstPointer();
6460   typedef std::reverse_iterator<const int *> rintstart;
6461   rintstart bg(arrEnd);//OK no problem because size of 'arr' is greater or equal 2
6462   rintstart end2(arrBg);
6463   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret1=DataArrayInt::New();
6464   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret2=DataArrayInt::New();
6465   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret3=DataArrayInt::New();
6466   ret1->alloc(nbOfTuples,1);
6467   ret2->alloc(nbOfTuples,1);
6468   int *ret1Ptr=ret1->getPointer();
6469   int *ret2Ptr=ret2->getPointer();
6470   std::set<std::size_t> castsDetected;
6471   for(int i=0;i<nbOfTuples;i++)
6472     {
6473       rintstart res=std::find_if(bg,end2,std::bind2nd(std::less_equal<int>(), work[i]));
6474       std::size_t pos=std::distance(bg,res);
6475       std::size_t pos2=nbOfCast-pos;
6476       if(pos2<nbOfCast)
6477         {
6478           ret1Ptr[i]=(int)pos2;
6479           ret2Ptr[i]=work[i]-arrBg[pos2];
6480           castsDetected.insert(pos2);
6481         }
6482       else
6483         {
6484           std::ostringstream oss; oss << "DataArrayInt::splitByValueRange : At rank #" << i << " the value is " << work[i] << " should be in [0," << *bg << ") !";
6485           throw INTERP_KERNEL::Exception(oss.str().c_str());
6486         }
6487     }
6488   ret3->alloc((int)castsDetected.size(),1);
6489   std::copy(castsDetected.begin(),castsDetected.end(),ret3->getPointer());
6490   castArr=ret1.retn();
6491   rankInsideCast=ret2.retn();
6492   castsPresent=ret3.retn();
6493 }
6494
6495 /*!
6496  * 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 ).
6497  * 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 ).
6498  * This method works only if \a this is allocated and single component. If not an exception will be thrown.
6499  *
6500  * \param [out] strt - the start of the range (included) if true is returned.
6501  * \param [out] sttoopp - the end of the range (not included) if true is returned.
6502  * \param [out] stteepp - the step of the range if true is returned.
6503  * \return the verdict of the check.
6504  *
6505  * \sa DataArray::GetNumberOfItemGivenBES
6506  */
6507 bool DataArrayInt::isRange(int& strt, int& sttoopp, int& stteepp) const
6508 {
6509   checkAllocated();
6510   if(getNumberOfComponents()!=1)
6511     throw INTERP_KERNEL::Exception("DataArrayInt::isRange : this must be single component array !");
6512   int nbTuples(getNumberOfTuples());
6513   if(nbTuples==0)
6514     { strt=0; sttoopp=0; stteepp=1; return true; }
6515   const int *pt(begin());
6516   strt=*pt; 
6517   if(nbTuples==1)
6518     { sttoopp=strt+1; stteepp=1; return true; }
6519   strt=*pt; sttoopp=pt[nbTuples-1];
6520   if(strt==sttoopp)
6521     return false;
6522   if(sttoopp>strt)
6523     {
6524       sttoopp++;
6525       int a(sttoopp-1-strt),tmp(strt);
6526       if(a%(nbTuples-1)!=0)
6527         return false;
6528       stteepp=a/(nbTuples-1);
6529       for(int i=0;i<nbTuples;i++,tmp+=stteepp)
6530         if(pt[i]!=tmp)
6531           return false;
6532       return true;
6533     }
6534   else
6535     {
6536       sttoopp--;
6537       int a(strt-sttoopp-1),tmp(strt);
6538       if(a%(nbTuples-1)!=0)
6539         return false;
6540       stteepp=-(a/(nbTuples-1));
6541       for(int i=0;i<nbTuples;i++,tmp+=stteepp)
6542         if(pt[i]!=tmp)
6543           return false;
6544       return true;
6545     }
6546 }
6547
6548 /*!
6549  * Creates a one-dimensional DataArrayInt (\a res) whose contents are computed from 
6550  * values of \a this (\a a) and the given (\a indArr) arrays as follows:
6551  * \a res[ \a indArr[ \a a[ i ]]] = i. I.e. for each value in place i \a v = \a a[ i ],
6552  * new value in place \a indArr[ \a v ] is i.
6553  *  \param [in] indArrBg - the array holding indices within the result array to assign
6554  *         indices of values of \a this array pointing to values of \a indArrBg.
6555  *  \param [in] indArrEnd - specifies the end of the array \a indArrBg, so that
6556  *              the last value of \a indArrBg is \a indArrEnd[ -1 ].
6557  *  \return DataArrayInt * - the new instance of DataArrayInt.
6558  *          The caller is to delete this result array using decrRef() as it is no more
6559  *          needed.
6560  *  \throw If \a this->getNumberOfComponents() != 1.
6561  *  \throw If any value of \a this array is not a valid index for \a indArrBg array.
6562  *  \throw If any value of \a indArrBg is not a valid index for \a this array.
6563  */
6564 DataArrayInt *DataArrayInt::transformWithIndArrR(const int *indArrBg, const int *indArrEnd) const
6565 {
6566   checkAllocated();
6567   if(getNumberOfComponents()!=1)
6568     throw INTERP_KERNEL::Exception("Call transformWithIndArrR method on DataArrayInt with only one component, you can call 'rearrange' method before !");
6569   int nbElemsIn=(int)std::distance(indArrBg,indArrEnd);
6570   int nbOfTuples=getNumberOfTuples();
6571   const int *pt=getConstPointer();
6572   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6573   ret->alloc(nbOfTuples,1);
6574   ret->fillWithValue(-1);
6575   int *tmp=ret->getPointer();
6576   for(int i=0;i<nbOfTuples;i++,pt++)
6577     {
6578       if(*pt>=0 && *pt<nbElemsIn)
6579         {
6580           int pos=indArrBg[*pt];
6581           if(pos>=0 && pos<nbOfTuples)
6582             tmp[pos]=i;
6583           else
6584             {
6585               std::ostringstream oss; oss << "DataArrayInt::transformWithIndArrR : error on tuple #" << i << " value of new pos is " << pos << " ( indArrBg[" << *pt << "]) ! Should be in [0," << nbOfTuples << ") !";
6586               throw INTERP_KERNEL::Exception(oss.str().c_str());
6587             }
6588         }
6589       else
6590         {
6591           std::ostringstream oss; oss << "DataArrayInt::transformWithIndArrR : error on tuple #" << i << " value is " << *pt << " and indirectionnal array as a size equal to " << nbElemsIn << " !";
6592           throw INTERP_KERNEL::Exception(oss.str().c_str());
6593         }
6594     }
6595   return ret.retn();
6596 }
6597
6598 /*!
6599  * Creates a one-dimensional DataArrayInt of given length, whose contents are computed
6600  * from values of \a this array, which is supposed to contain a renumbering map in 
6601  * "Old to New" mode. The result array contains a renumbering map in "New to Old" mode.
6602  * To know how to use the renumbering maps see \ref MEDCouplingArrayRenumbering.
6603  *  \param [in] newNbOfElem - the number of tuples in the result array.
6604  *  \return DataArrayInt * - the new instance of DataArrayInt.
6605  *          The caller is to delete this result array using decrRef() as it is no more
6606  *          needed.
6607  * 
6608  *  \if ENABLE_EXAMPLES
6609  *  \ref cpp_mcdataarrayint_invertarrayo2n2n2o "Here is a C++ example".<br>
6610  *  \ref py_mcdataarrayint_invertarrayo2n2n2o  "Here is a Python example".
6611  *  \endif
6612  */
6613 DataArrayInt *DataArrayInt::invertArrayO2N2N2O(int newNbOfElem) const
6614 {
6615   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6616   ret->alloc(newNbOfElem,1);
6617   int nbOfOldNodes=getNumberOfTuples();
6618   const int *old2New=getConstPointer();
6619   int *pt=ret->getPointer();
6620   for(int i=0;i!=nbOfOldNodes;i++)
6621     {
6622       int newp(old2New[i]);
6623       if(newp!=-1)
6624         {
6625           if(newp>=0 && newp<newNbOfElem)
6626             pt[newp]=i;
6627           else
6628             {
6629               std::ostringstream oss; oss << "DataArrayInt::invertArrayO2N2N2O : At place #" << i << " the newplace is " << newp << " must be in [0," << newNbOfElem << ") !";
6630               throw INTERP_KERNEL::Exception(oss.str().c_str());
6631             }
6632         }
6633     }
6634   return ret.retn();
6635 }
6636
6637 /*!
6638  * This method is similar to DataArrayInt::invertArrayO2N2N2O except that 
6639  * 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]
6640  */
6641 DataArrayInt *DataArrayInt::invertArrayO2N2N2OBis(int newNbOfElem) const
6642 {
6643   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6644   ret->alloc(newNbOfElem,1);
6645   int nbOfOldNodes=getNumberOfTuples();
6646   const int *old2New=getConstPointer();
6647   int *pt=ret->getPointer();
6648   for(int i=nbOfOldNodes-1;i>=0;i--)
6649     {
6650       int newp(old2New[i]);
6651       if(newp!=-1)
6652         {
6653           if(newp>=0 && newp<newNbOfElem)
6654             pt[newp]=i;
6655           else
6656             {
6657               std::ostringstream oss; oss << "DataArrayInt::invertArrayO2N2N2OBis : At place #" << i << " the newplace is " << newp << " must be in [0," << newNbOfElem << ") !";
6658               throw INTERP_KERNEL::Exception(oss.str().c_str());
6659             }
6660         }
6661     }
6662   return ret.retn();
6663 }
6664
6665 /*!
6666  * Creates a one-dimensional DataArrayInt of given length, whose contents are computed
6667  * from values of \a this array, which is supposed to contain a renumbering map in 
6668  * "New to Old" mode. The result array contains a renumbering map in "Old to New" mode.
6669  * To know how to use the renumbering maps see \ref MEDCouplingArrayRenumbering.
6670  *  \param [in] newNbOfElem - the number of tuples in the result array.
6671  *  \return DataArrayInt * - the new instance of DataArrayInt.
6672  *          The caller is to delete this result array using decrRef() as it is no more
6673  *          needed.
6674  * 
6675  *  \if ENABLE_EXAMPLES
6676  *  \ref cpp_mcdataarrayint_invertarrayn2o2o2n "Here is a C++ example".
6677  *
6678  *  \ref py_mcdataarrayint_invertarrayn2o2o2n "Here is a Python example".
6679  *  \endif
6680  */
6681 DataArrayInt *DataArrayInt::invertArrayN2O2O2N(int oldNbOfElem) const
6682 {
6683   checkAllocated();
6684   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6685   ret->alloc(oldNbOfElem,1);
6686   const int *new2Old=getConstPointer();
6687   int *pt=ret->getPointer();
6688   std::fill(pt,pt+oldNbOfElem,-1);
6689   int nbOfNewElems=getNumberOfTuples();
6690   for(int i=0;i<nbOfNewElems;i++)
6691     {
6692       int v(new2Old[i]);
6693       if(v>=0 && v<oldNbOfElem)
6694         pt[v]=i;
6695       else
6696         {
6697           std::ostringstream oss; oss << "DataArrayInt::invertArrayN2O2O2N : in new id #" << i << " old value is " << v << " expected to be in [0," << oldNbOfElem << ") !";
6698           throw INTERP_KERNEL::Exception(oss.str().c_str());
6699         }
6700     }
6701   return ret.retn();
6702 }
6703
6704 /*!
6705  * Equivalent to DataArrayInt::isEqual except that if false the reason of
6706  * mismatch is given.
6707  * 
6708  * \param [in] other the instance to be compared with \a this
6709  * \param [out] reason In case of inequality returns the reason.
6710  * \sa DataArrayInt::isEqual
6711  */
6712 bool DataArrayInt::isEqualIfNotWhy(const DataArrayInt& other, std::string& reason) const
6713 {
6714   if(!areInfoEqualsIfNotWhy(other,reason))
6715     return false;
6716   return _mem.isEqual(other._mem,0,reason);
6717 }
6718
6719 /*!
6720  * Checks if \a this and another DataArrayInt are fully equal. For more info see
6721  * \ref MEDCouplingArrayBasicsCompare.
6722  *  \param [in] other - an instance of DataArrayInt to compare with \a this one.
6723  *  \return bool - \a true if the two arrays are equal, \a false else.
6724  */
6725 bool DataArrayInt::isEqual(const DataArrayInt& other) const
6726 {
6727   std::string tmp;
6728   return isEqualIfNotWhy(other,tmp);
6729 }
6730
6731 /*!
6732  * Checks if values of \a this and another DataArrayInt are equal. For more info see
6733  * \ref MEDCouplingArrayBasicsCompare.
6734  *  \param [in] other - an instance of DataArrayInt to compare with \a this one.
6735  *  \return bool - \a true if the values of two arrays are equal, \a false else.
6736  */
6737 bool DataArrayInt::isEqualWithoutConsideringStr(const DataArrayInt& other) const
6738 {
6739   std::string tmp;
6740   return _mem.isEqual(other._mem,0,tmp);
6741 }
6742
6743 /*!
6744  * Checks if values of \a this and another DataArrayInt are equal. Comparison is
6745  * performed on sorted value sequences.
6746  * For more info see\ref MEDCouplingArrayBasicsCompare.
6747  *  \param [in] other - an instance of DataArrayInt to compare with \a this one.
6748  *  \return bool - \a true if the sorted values of two arrays are equal, \a false else.
6749  */
6750 bool DataArrayInt::isEqualWithoutConsideringStrAndOrder(const DataArrayInt& other) const
6751 {
6752   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> a=deepCpy();
6753   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> b=other.deepCpy();
6754   a->sort();
6755   b->sort();
6756   return a->isEqualWithoutConsideringStr(*b);
6757 }
6758
6759 /*!
6760  * This method compares content of input vector \a v and \a this.
6761  * 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.
6762  * For performance reasons \a this is expected to be sorted ascendingly. If not an exception will be thrown.
6763  *
6764  * \param [in] v - the vector of 'flags' to be compared with \a this.
6765  *
6766  * \throw If \a this is not sorted ascendingly.
6767  * \throw If \a this has not exactly one component.
6768  * \throw If \a this is not allocated.
6769  */
6770 bool DataArrayInt::isFittingWith(const std::vector<bool>& v) const
6771 {
6772   checkAllocated();
6773   if(getNumberOfComponents()!=1)
6774     throw INTERP_KERNEL::Exception("DataArrayInt::isFittingWith : number of components of this should be equal to one !");
6775   const int *w(begin()),*end2(end());
6776   int refVal=-std::numeric_limits<int>::max();
6777   int i=0;
6778   std::vector<bool>::const_iterator it(v.begin());
6779   for(;it!=v.end();it++,i++)
6780     {
6781       if(*it)
6782         {
6783           if(w!=end2)
6784             {
6785               if(*w++==i)
6786                 {
6787                   if(i>refVal)
6788                     refVal=i;
6789                   else
6790                     {
6791                       std::ostringstream oss; oss << "DataArrayInt::isFittingWith : At pos #" << std::distance(begin(),w-1) << " this is not sorted ascendingly !";
6792                       throw INTERP_KERNEL::Exception(oss.str().c_str());
6793                     }
6794                 }
6795               else
6796                 return false;
6797             }
6798           else
6799             return false;
6800         }
6801     }
6802   return w==end2;
6803 }
6804
6805 /*!
6806  * Sorts values of the array.
6807  *  \param [in] asc - \a true means ascending order, \a false, descending.
6808  *  \throw If \a this is not allocated.
6809  *  \throw If \a this->getNumberOfComponents() != 1.
6810  */
6811 void DataArrayInt::sort(bool asc)
6812 {
6813   checkAllocated();
6814   if(getNumberOfComponents()!=1)
6815     throw INTERP_KERNEL::Exception("DataArrayInt::sort : only supported with 'this' array with ONE component !");
6816   _mem.sort(asc);
6817   declareAsNew();
6818 }
6819
6820 /*!
6821  * Computes for each tuple the sum of number of components values in the tuple and return it.
6822  * 
6823  * \return DataArrayInt * - the new instance of DataArrayInt containing the
6824  *          same number of tuples as \a this array and one component.
6825  *          The caller is to delete this result array using decrRef() as it is no more
6826  *          needed.
6827  *  \throw If \a this is not allocated.
6828  */
6829 DataArrayInt *DataArrayInt::sumPerTuple() const
6830 {
6831   checkAllocated();
6832   int nbOfComp(getNumberOfComponents()),nbOfTuple(getNumberOfTuples());
6833   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New());
6834   ret->alloc(nbOfTuple,1);
6835   const int *src(getConstPointer());
6836   int *dest(ret->getPointer());
6837   for(int i=0;i<nbOfTuple;i++,dest++,src+=nbOfComp)
6838     *dest=std::accumulate(src,src+nbOfComp,0);
6839   return ret.retn();
6840 }
6841
6842 /*!
6843  * Reverse the array values.
6844  *  \throw If \a this->getNumberOfComponents() < 1.
6845  *  \throw If \a this is not allocated.
6846  */
6847 void DataArrayInt::reverse()
6848 {
6849   checkAllocated();
6850   _mem.reverse(getNumberOfComponents());
6851   declareAsNew();
6852 }
6853
6854 /*!
6855  * Checks that \a this array is consistently **increasing** or **decreasing** in value.
6856  * If not an exception is thrown.
6857  *  \param [in] increasing - if \a true, the array values should be increasing.
6858  *  \throw If sequence of values is not strictly monotonic in agreement with \a
6859  *         increasing arg.
6860  *  \throw If \a this->getNumberOfComponents() != 1.
6861  *  \throw If \a this is not allocated.
6862  */
6863 void DataArrayInt::checkMonotonic(bool increasing) const
6864 {
6865   if(!isMonotonic(increasing))
6866     {
6867       if (increasing)
6868         throw INTERP_KERNEL::Exception("DataArrayInt::checkMonotonic : 'this' is not INCREASING monotonic !");
6869       else
6870         throw INTERP_KERNEL::Exception("DataArrayInt::checkMonotonic : 'this' is not DECREASING monotonic !");
6871     }
6872 }
6873
6874 /*!
6875  * Checks that \a this array is consistently **increasing** or **decreasing** in value.
6876  *  \param [in] increasing - if \a true, array values should be increasing.
6877  *  \return bool - \a true if values change in accordance with \a increasing arg.
6878  *  \throw If \a this->getNumberOfComponents() != 1.
6879  *  \throw If \a this is not allocated.
6880  */
6881 bool DataArrayInt::isMonotonic(bool increasing) const
6882 {
6883   checkAllocated();
6884   if(getNumberOfComponents()!=1)
6885     throw INTERP_KERNEL::Exception("DataArrayInt::isMonotonic : only supported with 'this' array with ONE component !");
6886   int nbOfElements=getNumberOfTuples();
6887   const int *ptr=getConstPointer();
6888   if(nbOfElements==0)
6889     return true;
6890   int ref=ptr[0];
6891   if(increasing)
6892     {
6893       for(int i=1;i<nbOfElements;i++)
6894         {
6895           if(ptr[i]>=ref)
6896             ref=ptr[i];
6897           else
6898             return false;
6899         }
6900     }
6901   else
6902     {
6903       for(int i=1;i<nbOfElements;i++)
6904         {
6905           if(ptr[i]<=ref)
6906             ref=ptr[i];
6907           else
6908             return false;
6909         }
6910     }
6911   return true;
6912 }
6913
6914 /*!
6915  * This method check that array consistently INCREASING or DECREASING in value.
6916  */
6917 bool DataArrayInt::isStrictlyMonotonic(bool increasing) const
6918 {
6919   checkAllocated();
6920   if(getNumberOfComponents()!=1)
6921     throw INTERP_KERNEL::Exception("DataArrayInt::isStrictlyMonotonic : only supported with 'this' array with ONE component !");
6922   int nbOfElements=getNumberOfTuples();
6923   const int *ptr=getConstPointer();
6924   if(nbOfElements==0)
6925     return true;
6926   int ref=ptr[0];
6927   if(increasing)
6928     {
6929       for(int i=1;i<nbOfElements;i++)
6930         {
6931           if(ptr[i]>ref)
6932             ref=ptr[i];
6933           else
6934             return false;
6935         }
6936     }
6937   else
6938     {
6939       for(int i=1;i<nbOfElements;i++)
6940         {
6941           if(ptr[i]<ref)
6942             ref=ptr[i];
6943           else
6944             return false;
6945         }
6946     }
6947   return true;
6948 }
6949
6950 /*!
6951  * This method check that array consistently INCREASING or DECREASING in value.
6952  */
6953 void DataArrayInt::checkStrictlyMonotonic(bool increasing) const
6954 {
6955   if(!isStrictlyMonotonic(increasing))
6956     {
6957       if (increasing)
6958         throw INTERP_KERNEL::Exception("DataArrayInt::checkStrictlyMonotonic : 'this' is not strictly INCREASING monotonic !");
6959       else
6960         throw INTERP_KERNEL::Exception("DataArrayInt::checkStrictlyMonotonic : 'this' is not strictly DECREASING monotonic !");
6961     }
6962 }
6963
6964 /*!
6965  * Creates a new one-dimensional DataArrayInt of the same size as \a this and a given
6966  * one-dimensional arrays that must be of the same length. The result array describes
6967  * correspondence between \a this and \a other arrays, so that 
6968  * <em> other.getIJ(i,0) == this->getIJ(ret->getIJ(i),0)</em>. If such a permutation is
6969  * not possible because some element in \a other is not in \a this, an exception is thrown.
6970  *  \param [in] other - an array to compute permutation to.
6971  *  \return DataArrayInt * - a new instance of DataArrayInt, which is a permutation array
6972  * from \a this to \a other. The caller is to delete this array using decrRef() as it is
6973  * no more needed.
6974  *  \throw If \a this->getNumberOfComponents() != 1.
6975  *  \throw If \a other->getNumberOfComponents() != 1.
6976  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples().
6977  *  \throw If \a other includes a value which is not in \a this array.
6978  * 
6979  *  \if ENABLE_EXAMPLES
6980  *  \ref cpp_mcdataarrayint_buildpermutationarr "Here is a C++ example".
6981  *
6982  *  \ref py_mcdataarrayint_buildpermutationarr "Here is a Python example".
6983  *  \endif
6984  */
6985 DataArrayInt *DataArrayInt::buildPermutationArr(const DataArrayInt& other) const
6986 {
6987   checkAllocated();
6988   if(getNumberOfComponents()!=1 || other.getNumberOfComponents()!=1)
6989     throw INTERP_KERNEL::Exception("DataArrayInt::buildPermutationArr : 'this' and 'other' have to have exactly ONE component !");
6990   int nbTuple=getNumberOfTuples();
6991   other.checkAllocated();
6992   if(nbTuple!=other.getNumberOfTuples())
6993     throw INTERP_KERNEL::Exception("DataArrayInt::buildPermutationArr : 'this' and 'other' must have the same number of tuple !");
6994   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6995   ret->alloc(nbTuple,1);
6996   ret->fillWithValue(-1);
6997   const int *pt=getConstPointer();
6998   std::map<int,int> mm;
6999   for(int i=0;i<nbTuple;i++)
7000     mm[pt[i]]=i;
7001   pt=other.getConstPointer();
7002   int *retToFill=ret->getPointer();
7003   for(int i=0;i<nbTuple;i++)
7004     {
7005       std::map<int,int>::const_iterator it=mm.find(pt[i]);
7006       if(it==mm.end())
7007         {
7008           std::ostringstream oss; oss << "DataArrayInt::buildPermutationArr : Arrays mismatch : element (" << pt[i] << ") in 'other' not findable in 'this' !";
7009           throw INTERP_KERNEL::Exception(oss.str().c_str());
7010         }
7011       retToFill[i]=(*it).second;
7012     }
7013   return ret.retn();
7014 }
7015
7016 /*!
7017  * Sets a C array to be used as raw data of \a this. The previously set info
7018  *  of components is retained and re-sized. 
7019  * For more info see \ref MEDCouplingArraySteps1.
7020  *  \param [in] array - the C array to be used as raw data of \a this.
7021  *  \param [in] ownership - if \a true, \a array will be deallocated at destruction of \a this.
7022  *  \param [in] type - specifies how to deallocate \a array. If \a type == ParaMEDMEM::CPP_DEALLOC,
7023  *                     \c delete [] \c array; will be called. If \a type == ParaMEDMEM::C_DEALLOC,
7024  *                     \c free(\c array ) will be called.
7025  *  \param [in] nbOfTuple - new number of tuples in \a this.
7026  *  \param [in] nbOfCompo - new number of components in \a this.
7027  */
7028 void DataArrayInt::useArray(const int *array, bool ownership,  DeallocType type, int nbOfTuple, int nbOfCompo)
7029 {
7030   _info_on_compo.resize(nbOfCompo);
7031   _mem.useArray(array,ownership,type,nbOfTuple*nbOfCompo);
7032   declareAsNew();
7033 }
7034
7035 void DataArrayInt::useExternalArrayWithRWAccess(const int *array, int nbOfTuple, int nbOfCompo)
7036 {
7037   _info_on_compo.resize(nbOfCompo);
7038   _mem.useExternalArrayWithRWAccess(array,nbOfTuple*nbOfCompo);
7039   declareAsNew();
7040 }
7041
7042 /*!
7043  * Returns a new DataArrayInt holding the same values as \a this array but differently
7044  * arranged in memory. If \a this array holds 2 components of 3 values:
7045  * \f$ x_0,x_1,x_2,y_0,y_1,y_2 \f$, then the result array holds these values arranged
7046  * as follows: \f$ x_0,y_0,x_1,y_1,x_2,y_2 \f$.
7047  *  \warning Do not confuse this method with transpose()!
7048  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
7049  *          is to delete using decrRef() as it is no more needed.
7050  *  \throw If \a this is not allocated.
7051  */
7052 DataArrayInt *DataArrayInt::fromNoInterlace() const
7053 {
7054   checkAllocated();
7055   if(_mem.isNull())
7056     throw INTERP_KERNEL::Exception("DataArrayInt::fromNoInterlace : Not defined array !");
7057   int *tab=_mem.fromNoInterlace(getNumberOfComponents());
7058   DataArrayInt *ret=DataArrayInt::New();
7059   ret->useArray(tab,true,C_DEALLOC,getNumberOfTuples(),getNumberOfComponents());
7060   return ret;
7061 }
7062
7063 /*!
7064  * Returns a new DataArrayInt holding the same values as \a this array but differently
7065  * arranged in memory. If \a this array holds 2 components of 3 values:
7066  * \f$ x_0,y_0,x_1,y_1,x_2,y_2 \f$, then the result array holds these values arranged
7067  * as follows: \f$ x_0,x_1,x_2,y_0,y_1,y_2 \f$.
7068  *  \warning Do not confuse this method with transpose()!
7069  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
7070  *          is to delete using decrRef() as it is no more needed.
7071  *  \throw If \a this is not allocated.
7072  */
7073 DataArrayInt *DataArrayInt::toNoInterlace() const
7074 {
7075   checkAllocated();
7076   if(_mem.isNull())
7077     throw INTERP_KERNEL::Exception("DataArrayInt::toNoInterlace : Not defined array !");
7078   int *tab=_mem.toNoInterlace(getNumberOfComponents());
7079   DataArrayInt *ret=DataArrayInt::New();
7080   ret->useArray(tab,true,C_DEALLOC,getNumberOfTuples(),getNumberOfComponents());
7081   return ret;
7082 }
7083
7084 /*!
7085  * Permutes values of \a this array as required by \a old2New array. The values are
7086  * permuted so that \c new[ \a old2New[ i ]] = \c old[ i ]. Number of tuples remains
7087  * the same as in \this one.
7088  * If a permutation reduction is needed, substr() or selectByTupleId() should be used.
7089  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
7090  *  \param [in] old2New - C array of length equal to \a this->getNumberOfTuples()
7091  *     giving a new position for i-th old value.
7092  */
7093 void DataArrayInt::renumberInPlace(const int *old2New)
7094 {
7095   checkAllocated();
7096   int nbTuples=getNumberOfTuples();
7097   int nbOfCompo=getNumberOfComponents();
7098   int *tmp=new int[nbTuples*nbOfCompo];
7099   const int *iptr=getConstPointer();
7100   for(int i=0;i<nbTuples;i++)
7101     {
7102       int v=old2New[i];
7103       if(v>=0 && v<nbTuples)
7104         std::copy(iptr+nbOfCompo*i,iptr+nbOfCompo*(i+1),tmp+nbOfCompo*v);
7105       else
7106         {
7107           std::ostringstream oss; oss << "DataArrayInt::renumberInPlace : At place #" << i << " value is " << v << " ! Should be in [0," << nbTuples << ") !";
7108           throw INTERP_KERNEL::Exception(oss.str().c_str());
7109         }
7110     }
7111   std::copy(tmp,tmp+nbTuples*nbOfCompo,getPointer());
7112   delete [] tmp;
7113   declareAsNew();
7114 }
7115
7116 /*!
7117  * Permutes values of \a this array as required by \a new2Old array. The values are
7118  * permuted so that \c new[ i ] = \c old[ \a new2Old[ i ]]. Number of tuples remains
7119  * the same as in \this one.
7120  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
7121  *  \param [in] new2Old - C array of length equal to \a this->getNumberOfTuples()
7122  *     giving a previous position of i-th new value.
7123  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
7124  *          is to delete using decrRef() as it is no more needed.
7125  */
7126 void DataArrayInt::renumberInPlaceR(const int *new2Old)
7127 {
7128   checkAllocated();
7129   int nbTuples=getNumberOfTuples();
7130   int nbOfCompo=getNumberOfComponents();
7131   int *tmp=new int[nbTuples*nbOfCompo];
7132   const int *iptr=getConstPointer();
7133   for(int i=0;i<nbTuples;i++)
7134     {
7135       int v=new2Old[i];
7136       if(v>=0 && v<nbTuples)
7137         std::copy(iptr+nbOfCompo*v,iptr+nbOfCompo*(v+1),tmp+nbOfCompo*i);
7138       else
7139         {
7140           std::ostringstream oss; oss << "DataArrayInt::renumberInPlaceR : At place #" << i << " value is " << v << " ! Should be in [0," << nbTuples << ") !";
7141           throw INTERP_KERNEL::Exception(oss.str().c_str());
7142         }
7143     }
7144   std::copy(tmp,tmp+nbTuples*nbOfCompo,getPointer());
7145   delete [] tmp;
7146   declareAsNew();
7147 }
7148
7149 /*!
7150  * Returns a copy of \a this array with values permuted as required by \a old2New array.
7151  * The values are permuted so that  \c new[ \a old2New[ i ]] = \c old[ i ].
7152  * Number of tuples in the result array remains the same as in \this one.
7153  * If a permutation reduction is needed, renumberAndReduce() should be used.
7154  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
7155  *  \param [in] old2New - C array of length equal to \a this->getNumberOfTuples()
7156  *          giving a new position for i-th old value.
7157  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
7158  *          is to delete using decrRef() as it is no more needed.
7159  *  \throw If \a this is not allocated.
7160  */
7161 DataArrayInt *DataArrayInt::renumber(const int *old2New) const
7162 {
7163   checkAllocated();
7164   int nbTuples=getNumberOfTuples();
7165   int nbOfCompo=getNumberOfComponents();
7166   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
7167   ret->alloc(nbTuples,nbOfCompo);
7168   ret->copyStringInfoFrom(*this);
7169   const int *iptr=getConstPointer();
7170   int *optr=ret->getPointer();
7171   for(int i=0;i<nbTuples;i++)
7172     std::copy(iptr+nbOfCompo*i,iptr+nbOfCompo*(i+1),optr+nbOfCompo*old2New[i]);
7173   ret->copyStringInfoFrom(*this);
7174   return ret.retn();
7175 }
7176
7177 /*!
7178  * Returns a copy of \a this array with values permuted as required by \a new2Old array.
7179  * The values are permuted so that  \c new[ i ] = \c old[ \a new2Old[ i ]]. Number of
7180  * tuples in the result array remains the same as in \this one.
7181  * If a permutation reduction is needed, substr() or selectByTupleId() should be used.
7182  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
7183  *  \param [in] new2Old - C array of length equal to \a this->getNumberOfTuples()
7184  *     giving a previous position of i-th new value.
7185  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
7186  *          is to delete using decrRef() as it is no more needed.
7187  */
7188 DataArrayInt *DataArrayInt::renumberR(const int *new2Old) const
7189 {
7190   checkAllocated();
7191   int nbTuples=getNumberOfTuples();
7192   int nbOfCompo=getNumberOfComponents();
7193   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
7194   ret->alloc(nbTuples,nbOfCompo);
7195   ret->copyStringInfoFrom(*this);
7196   const int *iptr=getConstPointer();
7197   int *optr=ret->getPointer();
7198   for(int i=0;i<nbTuples;i++)
7199     std::copy(iptr+nbOfCompo*new2Old[i],iptr+nbOfCompo*(new2Old[i]+1),optr+nbOfCompo*i);
7200   ret->copyStringInfoFrom(*this);
7201   return ret.retn();
7202 }
7203
7204 /*!
7205  * Returns a shorten and permuted copy of \a this array. The new DataArrayInt is
7206  * of size \a newNbOfTuple and it's values are permuted as required by \a old2New array.
7207  * The values are permuted so that  \c new[ \a old2New[ i ]] = \c old[ i ] for all
7208  * \a old2New[ i ] >= 0. In other words every i-th tuple in \a this array, for which 
7209  * \a old2New[ i ] is negative, is missing from the result array.
7210  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
7211  *  \param [in] old2New - C array of length equal to \a this->getNumberOfTuples()
7212  *     giving a new position for i-th old tuple and giving negative position for
7213  *     for i-th old tuple that should be omitted.
7214  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
7215  *          is to delete using decrRef() as it is no more needed.
7216  */
7217 DataArrayInt *DataArrayInt::renumberAndReduce(const int *old2New, int newNbOfTuple) const
7218 {
7219   checkAllocated();
7220   int nbTuples=getNumberOfTuples();
7221   int nbOfCompo=getNumberOfComponents();
7222   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
7223   ret->alloc(newNbOfTuple,nbOfCompo);
7224   const int *iptr=getConstPointer();
7225   int *optr=ret->getPointer();
7226   for(int i=0;i<nbTuples;i++)
7227     {
7228       int w=old2New[i];
7229       if(w>=0)
7230         std::copy(iptr+i*nbOfCompo,iptr+(i+1)*nbOfCompo,optr+w*nbOfCompo);
7231     }
7232   ret->copyStringInfoFrom(*this);
7233   return ret.retn();
7234 }
7235
7236 /*!
7237  * Returns a shorten and permuted copy of \a this array. The new DataArrayInt is
7238  * of size \a new2OldEnd - \a new2OldBg and it's values are permuted as required by
7239  * \a new2OldBg array.
7240  * The values are permuted so that  \c new[ i ] = \c old[ \a new2OldBg[ i ]].
7241  * This method is equivalent to renumberAndReduce() except that convention in input is
7242  * \c new2old and \b not \c old2new.
7243  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
7244  *  \param [in] new2OldBg - pointer to the beginning of a permutation array that gives a
7245  *              tuple index in \a this array to fill the i-th tuple in the new array.
7246  *  \param [in] new2OldEnd - specifies the end of the permutation array that starts at
7247  *              \a new2OldBg, so that pointer to a tuple index (\a pi) varies as this:
7248  *              \a new2OldBg <= \a pi < \a new2OldEnd.
7249  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
7250  *          is to delete using decrRef() as it is no more needed.
7251  */
7252 DataArrayInt *DataArrayInt::selectByTupleId(const int *new2OldBg, const int *new2OldEnd) const
7253 {
7254   checkAllocated();
7255   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
7256   int nbComp=getNumberOfComponents();
7257   ret->alloc((int)std::distance(new2OldBg,new2OldEnd),nbComp);
7258   ret->copyStringInfoFrom(*this);
7259   int *pt=ret->getPointer();
7260   const int *srcPt=getConstPointer();
7261   int i=0;
7262   for(const int *w=new2OldBg;w!=new2OldEnd;w++,i++)
7263     std::copy(srcPt+(*w)*nbComp,srcPt+((*w)+1)*nbComp,pt+i*nbComp);
7264   ret->copyStringInfoFrom(*this);
7265   return ret.retn();
7266 }
7267
7268 /*!
7269  * Returns a shorten and permuted copy of \a this array. The new DataArrayInt is
7270  * of size \a new2OldEnd - \a new2OldBg and it's values are permuted as required by
7271  * \a new2OldBg array.
7272  * The values are permuted so that  \c new[ i ] = \c old[ \a new2OldBg[ i ]].
7273  * This method is equivalent to renumberAndReduce() except that convention in input is
7274  * \c new2old and \b not \c old2new.
7275  * This method is equivalent to selectByTupleId() except that it prevents coping data
7276  * from behind the end of \a this array.
7277  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
7278  *  \param [in] new2OldBg - pointer to the beginning of a permutation array that gives a
7279  *              tuple index in \a this array to fill the i-th tuple in the new array.
7280  *  \param [in] new2OldEnd - specifies the end of the permutation array that starts at
7281  *              \a new2OldBg, so that pointer to a tuple index (\a pi) varies as this:
7282  *              \a new2OldBg <= \a pi < \a new2OldEnd.
7283  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
7284  *          is to delete using decrRef() as it is no more needed.
7285  *  \throw If \a new2OldEnd - \a new2OldBg > \a this->getNumberOfTuples().
7286  */
7287 DataArrayInt *DataArrayInt::selectByTupleIdSafe(const int *new2OldBg, const int *new2OldEnd) const
7288 {
7289   checkAllocated();
7290   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
7291   int nbComp=getNumberOfComponents();
7292   int oldNbOfTuples=getNumberOfTuples();
7293   ret->alloc((int)std::distance(new2OldBg,new2OldEnd),nbComp);
7294   ret->copyStringInfoFrom(*this);
7295   int *pt=ret->getPointer();
7296   const int *srcPt=getConstPointer();
7297   int i=0;
7298   for(const int *w=new2OldBg;w!=new2OldEnd;w++,i++)
7299     if(*w>=0 && *w<oldNbOfTuples)
7300       std::copy(srcPt+(*w)*nbComp,srcPt+((*w)+1)*nbComp,pt+i*nbComp);
7301     else
7302       throw INTERP_KERNEL::Exception("DataArrayInt::selectByTupleIdSafe : some ids has been detected to be out of [0,this->getNumberOfTuples) !");
7303   ret->copyStringInfoFrom(*this);
7304   return ret.retn();
7305 }
7306
7307 /*!
7308  * Returns a shorten copy of \a this array. The new DataArrayInt contains every
7309  * (\a bg + \c i * \a step)-th tuple of \a this array located before the \a end2-th
7310  * tuple. Indices of the selected tuples are the same as ones returned by the Python
7311  * command \c range( \a bg, \a end2, \a step ).
7312  * This method is equivalent to selectByTupleIdSafe() except that the input array is
7313  * not constructed explicitly.
7314  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
7315  *  \param [in] bg - index of the first tuple to copy from \a this array.
7316  *  \param [in] end2 - index of the tuple before which the tuples to copy are located.
7317  *  \param [in] step - index increment to get index of the next tuple to copy.
7318  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
7319  *          is to delete using decrRef() as it is no more needed.
7320  *  \sa DataArrayInt::substr.
7321  */
7322 DataArrayInt *DataArrayInt::selectByTupleId2(int bg, int end2, int step) const
7323 {
7324   checkAllocated();
7325   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
7326   int nbComp=getNumberOfComponents();
7327   int newNbOfTuples=GetNumberOfItemGivenBESRelative(bg,end2,step,"DataArrayInt::selectByTupleId2 : ");
7328   ret->alloc(newNbOfTuples,nbComp);
7329   int *pt=ret->getPointer();
7330   const int *srcPt=getConstPointer()+bg*nbComp;
7331   for(int i=0;i<newNbOfTuples;i++,srcPt+=step*nbComp)
7332     std::copy(srcPt,srcPt+nbComp,pt+i*nbComp);
7333   ret->copyStringInfoFrom(*this);
7334   return ret.retn();
7335 }
7336
7337 /*!
7338  * Returns a shorten copy of \a this array. The new DataArrayInt contains ranges
7339  * of tuples specified by \a ranges parameter.
7340  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
7341  *  \param [in] ranges - std::vector of std::pair's each of which defines a range
7342  *              of tuples in [\c begin,\c end) format.
7343  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
7344  *          is to delete using decrRef() as it is no more needed.
7345  *  \throw If \a end < \a begin.
7346  *  \throw If \a end > \a this->getNumberOfTuples().
7347  *  \throw If \a this is not allocated.
7348  */
7349 DataArray *DataArrayInt::selectByTupleRanges(const std::vector<std::pair<int,int> >& ranges) const
7350 {
7351   checkAllocated();
7352   int nbOfComp=getNumberOfComponents();
7353   int nbOfTuplesThis=getNumberOfTuples();
7354   if(ranges.empty())
7355     {
7356       MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
7357       ret->alloc(0,nbOfComp);
7358       ret->copyStringInfoFrom(*this);
7359       return ret.retn();
7360     }
7361   int ref=ranges.front().first;
7362   int nbOfTuples=0;
7363   bool isIncreasing=true;
7364   for(std::vector<std::pair<int,int> >::const_iterator it=ranges.begin();it!=ranges.end();it++)
7365     {
7366       if((*it).first<=(*it).second)
7367         {
7368           if((*it).first>=0 && (*it).second<=nbOfTuplesThis)
7369             {
7370               nbOfTuples+=(*it).second-(*it).first;
7371               if(isIncreasing)
7372                 isIncreasing=ref<=(*it).first;
7373               ref=(*it).second;
7374             }
7375           else
7376             {
7377               std::ostringstream oss; oss << "DataArrayInt::selectByTupleRanges : on range #" << std::distance(ranges.begin(),it);
7378               oss << " (" << (*it).first << "," << (*it).second << ") is greater than number of tuples of this :" << nbOfTuples << " !";
7379               throw INTERP_KERNEL::Exception(oss.str().c_str());
7380             }
7381         }
7382       else
7383         {
7384           std::ostringstream oss; oss << "DataArrayInt::selectByTupleRanges : on range #" << std::distance(ranges.begin(),it);
7385           oss << " (" << (*it).first << "," << (*it).second << ") end is before begin !";
7386           throw INTERP_KERNEL::Exception(oss.str().c_str());
7387         }
7388     }
7389   if(isIncreasing && nbOfTuplesThis==nbOfTuples)
7390     return deepCpy();
7391   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
7392   ret->alloc(nbOfTuples,nbOfComp);
7393   ret->copyStringInfoFrom(*this);
7394   const int *src=getConstPointer();
7395   int *work=ret->getPointer();
7396   for(std::vector<std::pair<int,int> >::const_iterator it=ranges.begin();it!=ranges.end();it++)
7397     work=std::copy(src+(*it).first*nbOfComp,src+(*it).second*nbOfComp,work);
7398   return ret.retn();
7399 }
7400
7401 /*!
7402  * Returns a new DataArrayInt containing a renumbering map in "Old to New" mode.
7403  * This map, if applied to \a this array, would make it sorted. For example, if
7404  * \a this array contents are [9,10,0,6,4,11,3,7] then the contents of the result array
7405  * are [5,6,0,3,2,7,1,4]; if this result array (\a res) is used as an argument in call
7406  * \a this->renumber(\a res) then the returned array contains [0,3,4,6,7,9,10,11].
7407  * This method is useful for renumbering (in MED file for example). For more info
7408  * on renumbering see \ref MEDCouplingArrayRenumbering.
7409  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
7410  *          array using decrRef() as it is no more needed.
7411  *  \throw If \a this is not allocated.
7412  *  \throw If \a this->getNumberOfComponents() != 1.
7413  *  \throw If there are equal values in \a this array.
7414  */
7415 DataArrayInt *DataArrayInt::checkAndPreparePermutation() const
7416 {
7417   checkAllocated();
7418   if(getNumberOfComponents()!=1)
7419     throw INTERP_KERNEL::Exception("DataArrayInt::checkAndPreparePermutation : number of components must == 1 !");
7420   int nbTuples=getNumberOfTuples();
7421   const int *pt=getConstPointer();
7422   int *pt2=CheckAndPreparePermutation(pt,pt+nbTuples);
7423   DataArrayInt *ret=DataArrayInt::New();
7424   ret->useArray(pt2,true,C_DEALLOC,nbTuples,1);
7425   return ret;
7426 }
7427
7428 /*!
7429  * 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
7430  * input array \a ids2.
7431  * \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.
7432  * 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
7433  * inversely.
7434  * In case of success (no throw) : \c ids1->renumber(ret)->isEqual(ids2) where \a ret is the return of this method.
7435  *
7436  * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
7437  *          array using decrRef() as it is no more needed.
7438  * \throw If either ids1 or ids2 is null not allocated or not with one components.
7439  * 
7440  */
7441 DataArrayInt *DataArrayInt::FindPermutationFromFirstToSecond(const DataArrayInt *ids1, const DataArrayInt *ids2)
7442 {
7443   if(!ids1 || !ids2)
7444     throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two input arrays must be not null !");
7445   if(!ids1->isAllocated() || !ids2->isAllocated())
7446     throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two input arrays must be allocated !");
7447   if(ids1->getNumberOfComponents()!=1 || ids2->getNumberOfComponents()!=1)
7448     throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two input arrays have exactly one component !");
7449   if(ids1->getNumberOfTuples()!=ids2->getNumberOfTuples())
7450     {
7451       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 !";
7452       throw INTERP_KERNEL::Exception(oss.str().c_str());
7453     }
7454   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> p1(ids1->deepCpy());
7455   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> p2(ids2->deepCpy());
7456   p1->sort(true); p2->sort(true);
7457   if(!p1->isEqualWithoutConsideringStr(*p2))
7458     throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two arrays are not lying on same ids ! Impossible to find a permutation between the 2 arrays !");
7459   p1=ids1->checkAndPreparePermutation();
7460   p2=ids2->checkAndPreparePermutation();
7461   p2=p2->invertArrayO2N2N2O(p2->getNumberOfTuples());
7462   p2=p2->selectByTupleIdSafe(p1->begin(),p1->end());
7463   return p2.retn();
7464 }
7465
7466 /*!
7467  * Returns two arrays describing a surjective mapping from \a this set of values (\a A)
7468  * onto a set of values of size \a targetNb (\a B). The surjective function is 
7469  * \a B[ \a A[ i ]] = i. That is to say that for each \a id in [0,\a targetNb), where \a
7470  * targetNb < \a this->getNumberOfTuples(), there exists at least one tupleId (\a tid) so
7471  * that <em> this->getIJ( tid, 0 ) == id</em>. <br>
7472  * The first of out arrays returns indices of elements of \a this array, grouped by their
7473  * place in the set \a B. The second out array is the index of the first one; it shows how
7474  * many elements of \a A are mapped into each element of \a B. <br>
7475  * For more info on
7476  * mapping and its usage in renumbering see \ref MEDCouplingArrayRenumbering. <br>
7477  * \b Example:
7478  * - \a this: [0,3,2,3,2,2,1,2]
7479  * - \a targetNb: 4
7480  * - \a arr:  [0,  6,  2,4,5,7,  1,3]
7481  * - \a arrI: [0,1,2,6,8]
7482  *
7483  * This result means: <br>
7484  * the element of \a B 0 encounters within \a A once (\a arrI[ 0+1 ] - \a arrI[ 0 ]) and
7485  * its index within \a A is 0 ( \a arr[ 0:1 ] == \a arr[ \a arrI[ 0 ] : \a arrI[ 0+1 ]]);<br>
7486  * the element of \a B 2 encounters within \a A 4 times (\a arrI[ 2+1 ] - \a arrI[ 2 ]) and
7487  * its indices within \a A are [2,4,5,7] ( \a arr[ 2:6 ] == \a arr[ \a arrI[ 2 ] : 
7488  * \a arrI[ 2+1 ]]); <br> etc.
7489  *  \param [in] targetNb - the size of the set \a B. \a targetNb must be equal or more
7490  *         than the maximal value of \a A.
7491  *  \param [out] arr - a new instance of DataArrayInt returning indices of
7492  *         elements of \a this, grouped by their place in the set \a B. The caller is to delete
7493  *         this array using decrRef() as it is no more needed.
7494  *  \param [out] arrI - a new instance of DataArrayInt returning size of groups of equal
7495  *         elements of \a this. The caller is to delete this array using decrRef() as it
7496  *         is no more needed.
7497  *  \throw If \a this is not allocated.
7498  *  \throw If \a this->getNumberOfComponents() != 1.
7499  *  \throw If any value in \a this is more or equal to \a targetNb.
7500  */
7501 void DataArrayInt::changeSurjectiveFormat(int targetNb, DataArrayInt *&arr, DataArrayInt *&arrI) const
7502 {
7503   checkAllocated();
7504   if(getNumberOfComponents()!=1)
7505     throw INTERP_KERNEL::Exception("DataArrayInt::changeSurjectiveFormat : number of components must == 1 !");
7506   int nbOfTuples=getNumberOfTuples();
7507   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New());
7508   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> retI(DataArrayInt::New());
7509   retI->alloc(targetNb+1,1);
7510   const int *input=getConstPointer();
7511   std::vector< std::vector<int> > tmp(targetNb);
7512   for(int i=0;i<nbOfTuples;i++)
7513     {
7514       int tmp2=input[i];
7515       if(tmp2>=0 && tmp2<targetNb)
7516         tmp[tmp2].push_back(i);
7517       else
7518         {
7519           std::ostringstream oss; oss << "DataArrayInt::changeSurjectiveFormat : At pos " << i << " presence of element " << tmp2 << " ! should be in [0," << targetNb << ") !";
7520           throw INTERP_KERNEL::Exception(oss.str().c_str());
7521         }
7522     }
7523   int *retIPtr=retI->getPointer();
7524   *retIPtr=0;
7525   for(std::vector< std::vector<int> >::const_iterator it1=tmp.begin();it1!=tmp.end();it1++,retIPtr++)
7526     retIPtr[1]=retIPtr[0]+(int)((*it1).size());
7527   if(nbOfTuples!=retI->getIJ(targetNb,0))
7528     throw INTERP_KERNEL::Exception("DataArrayInt::changeSurjectiveFormat : big problem should never happen !");
7529   ret->alloc(nbOfTuples,1);
7530   int *retPtr=ret->getPointer();
7531   for(std::vector< std::vector<int> >::const_iterator it1=tmp.begin();it1!=tmp.end();it1++)
7532     retPtr=std::copy((*it1).begin(),(*it1).end(),retPtr);
7533   arr=ret.retn();
7534   arrI=retI.retn();
7535 }
7536
7537
7538 /*!
7539  * Returns a new DataArrayInt containing a renumbering map in "Old to New" mode computed
7540  * from a zip representation of a surjective format (returned e.g. by
7541  * \ref ParaMEDMEM::DataArrayDouble::findCommonTuples() "DataArrayDouble::findCommonTuples()"
7542  * for example). The result array minimizes the permutation. <br>
7543  * For more info on renumbering see \ref MEDCouplingArrayRenumbering. <br>
7544  * \b Example: <br>
7545  * - \a nbOfOldTuples: 10 
7546  * - \a arr          : [0,3, 5,7,9]
7547  * - \a arrIBg       : [0,2,5]
7548  * - \a newNbOfTuples: 7
7549  * - result array    : [0,1,2,0,3,4,5,4,6,4]
7550  *
7551  *  \param [in] nbOfOldTuples - number of tuples in the initial array \a arr.
7552  *  \param [in] arr - the array of tuple indices grouped by \a arrIBg array.
7553  *  \param [in] arrIBg - the array dividing all indices stored in \a arr into groups of
7554  *         (indices of) equal values. Its every element (except the last one) points to
7555  *         the first element of a group of equal values.
7556  *  \param [in] arrIEnd - specifies the end of \a arrIBg, so that the last element of \a
7557  *          arrIBg is \a arrIEnd[ -1 ].
7558  *  \param [out] newNbOfTuples - number of tuples after surjection application.
7559  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
7560  *          array using decrRef() as it is no more needed.
7561  *  \throw If any value of \a arr breaks condition ( 0 <= \a arr[ i ] < \a nbOfOldTuples ).
7562  */
7563 DataArrayInt *DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2(int nbOfOldTuples, const int *arr, const int *arrIBg, const int *arrIEnd, int &newNbOfTuples)
7564 {
7565   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
7566   ret->alloc(nbOfOldTuples,1);
7567   int *pt=ret->getPointer();
7568   std::fill(pt,pt+nbOfOldTuples,-1);
7569   int nbOfGrps=((int)std::distance(arrIBg,arrIEnd))-1;
7570   const int *cIPtr=arrIBg;
7571   for(int i=0;i<nbOfGrps;i++)
7572     pt[arr[cIPtr[i]]]=-(i+2);
7573   int newNb=0;
7574   for(int iNode=0;iNode<nbOfOldTuples;iNode++)
7575     {
7576       if(pt[iNode]<0)
7577         {
7578           if(pt[iNode]==-1)
7579             pt[iNode]=newNb++;
7580           else
7581             {
7582               int grpId=-(pt[iNode]+2);
7583               for(int j=cIPtr[grpId];j<cIPtr[grpId+1];j++)
7584                 {
7585                   if(arr[j]>=0 && arr[j]<nbOfOldTuples)
7586                     pt[arr[j]]=newNb;
7587                   else
7588                     {
7589                       std::ostringstream oss; oss << "DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2 : With element #" << j << " value is " << arr[j] << " should be in [0," << nbOfOldTuples << ") !";
7590                       throw INTERP_KERNEL::Exception(oss.str().c_str());
7591                     }
7592                 }
7593               newNb++;
7594             }
7595         }
7596     }
7597   newNbOfTuples=newNb;
7598   return ret.retn();
7599 }
7600
7601 /*!
7602  * Returns a new DataArrayInt containing a renumbering map in "New to Old" mode,
7603  * which if applied to \a this array would make it sorted ascendingly.
7604  * For more info on renumbering see \ref MEDCouplingArrayRenumbering. <br>
7605  * \b Example: <br>
7606  * - \a this: [2,0,1,1,0,1,2,0,1,1,0,0]
7607  * - result: [10,0,5,6,1,7,11,2,8,9,3,4]
7608  * - after applying result to \a this: [0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2] 
7609  *
7610  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
7611  *          array using decrRef() as it is no more needed.
7612  *  \throw If \a this is not allocated.
7613  *  \throw If \a this->getNumberOfComponents() != 1.
7614  */
7615 DataArrayInt *DataArrayInt::buildPermArrPerLevel() const
7616 {
7617   checkAllocated();
7618   if(getNumberOfComponents()!=1)
7619     throw INTERP_KERNEL::Exception("DataArrayInt::buildPermArrPerLevel : number of components must == 1 !");
7620   int nbOfTuples=getNumberOfTuples();
7621   const int *pt=getConstPointer();
7622   std::map<int,int> m;
7623   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
7624   ret->alloc(nbOfTuples,1);
7625   int *opt=ret->getPointer();
7626   for(int i=0;i<nbOfTuples;i++,pt++,opt++)
7627     {
7628       int val=*pt;
7629       std::map<int,int>::iterator it=m.find(val);
7630       if(it!=m.end())
7631         {
7632           *opt=(*it).second;
7633           (*it).second++;
7634         }
7635       else
7636         {
7637           *opt=0;
7638           m.insert(std::pair<int,int>(val,1));
7639         }
7640     }
7641   int sum=0;
7642   for(std::map<int,int>::iterator it=m.begin();it!=m.end();it++)
7643     {
7644       int vt=(*it).second;
7645       (*it).second=sum;
7646       sum+=vt;
7647     }
7648   pt=getConstPointer();
7649   opt=ret->getPointer();
7650   for(int i=0;i<nbOfTuples;i++,pt++,opt++)
7651     *opt+=m[*pt];
7652   //
7653   return ret.retn();
7654 }
7655
7656 /*!
7657  * Checks if contents of \a this array are equal to that of an array filled with
7658  * iota(). This method is particularly useful for DataArrayInt instances that represent
7659  * a renumbering array to check the real need in renumbering. 
7660  *  \return bool - \a true if \a this array contents == \a range( \a this->getNumberOfTuples())
7661  *  \throw If \a this is not allocated.
7662  *  \throw If \a this->getNumberOfComponents() != 1.
7663  */
7664 bool DataArrayInt::isIdentity() const
7665 {
7666   checkAllocated();
7667   if(getNumberOfComponents()!=1)
7668     return false;
7669   int nbOfTuples=getNumberOfTuples();
7670   const int *pt=getConstPointer();
7671   for(int i=0;i<nbOfTuples;i++,pt++)
7672     if(*pt!=i)
7673       return false;
7674   return true;
7675 }
7676
7677 /*!
7678  * Checks if all values in \a this array are equal to \a val.
7679  *  \param [in] val - value to check equality of array values to.
7680  *  \return bool - \a true if all values are \a val.
7681  *  \throw If \a this is not allocated.
7682  *  \throw If \a this->getNumberOfComponents() != 1
7683  */
7684 bool DataArrayInt::isUniform(int val) const
7685 {
7686   checkAllocated();
7687   if(getNumberOfComponents()!=1)
7688     throw INTERP_KERNEL::Exception("DataArrayInt::isUniform : must be applied on DataArrayInt with only one component, you can call 'rearrange' method before !");
7689   int nbOfTuples=getNumberOfTuples();
7690   const int *w=getConstPointer();
7691   const int *end2=w+nbOfTuples;
7692   for(;w!=end2;w++)
7693     if(*w!=val)
7694       return false;
7695   return true;
7696 }
7697
7698 /*!
7699  * Creates a new DataArrayDouble and assigns all (textual and numerical) data of \a this
7700  * array to the new one.
7701  *  \return DataArrayDouble * - the new instance of DataArrayInt.
7702  */
7703 DataArrayDouble *DataArrayInt::convertToDblArr() const
7704 {
7705   checkAllocated();
7706   DataArrayDouble *ret=DataArrayDouble::New();
7707   ret->alloc(getNumberOfTuples(),getNumberOfComponents());
7708   std::size_t nbOfVals=getNbOfElems();
7709   const int *src=getConstPointer();
7710   double *dest=ret->getPointer();
7711   std::copy(src,src+nbOfVals,dest);
7712   ret->copyStringInfoFrom(*this);
7713   return ret;
7714 }
7715
7716 /*!
7717  * Returns a shorten copy of \a this array. The new DataArrayInt contains all
7718  * tuples starting from the \a tupleIdBg-th tuple and including all tuples located before
7719  * the \a tupleIdEnd-th one. This methods has a similar behavior as std::string::substr().
7720  * This method is a specialization of selectByTupleId2().
7721  *  \param [in] tupleIdBg - index of the first tuple to copy from \a this array.
7722  *  \param [in] tupleIdEnd - index of the tuple before which the tuples to copy are located.
7723  *          If \a tupleIdEnd == -1, all the tuples till the end of \a this array are copied.
7724  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
7725  *          is to delete using decrRef() as it is no more needed.
7726  *  \throw If \a tupleIdBg < 0.
7727  *  \throw If \a tupleIdBg > \a this->getNumberOfTuples().
7728     \throw If \a tupleIdEnd != -1 && \a tupleIdEnd < \a this->getNumberOfTuples().
7729  *  \sa DataArrayInt::selectByTupleId2
7730  */
7731 DataArrayInt *DataArrayInt::substr(int tupleIdBg, int tupleIdEnd) const
7732 {
7733   checkAllocated();
7734   int nbt=getNumberOfTuples();
7735   if(tupleIdBg<0)
7736     throw INTERP_KERNEL::Exception("DataArrayInt::substr : The tupleIdBg parameter must be greater than 0 !");
7737   if(tupleIdBg>nbt)
7738     throw INTERP_KERNEL::Exception("DataArrayInt::substr : The tupleIdBg parameter is greater than number of tuples !");
7739   int trueEnd=tupleIdEnd;
7740   if(tupleIdEnd!=-1)
7741     {
7742       if(tupleIdEnd>nbt)
7743         throw INTERP_KERNEL::Exception("DataArrayInt::substr : The tupleIdBg parameter is greater or equal than number of tuples !");
7744     }
7745   else
7746     trueEnd=nbt;
7747   int nbComp=getNumberOfComponents();
7748   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
7749   ret->alloc(trueEnd-tupleIdBg,nbComp);
7750   ret->copyStringInfoFrom(*this);
7751   std::copy(getConstPointer()+tupleIdBg*nbComp,getConstPointer()+trueEnd*nbComp,ret->getPointer());
7752   return ret.retn();
7753 }
7754
7755 /*!
7756  * Changes the number of components within \a this array so that its raw data **does
7757  * not** change, instead splitting this data into tuples changes.
7758  *  \warning This method erases all (name and unit) component info set before!
7759  *  \param [in] newNbOfComp - number of components for \a this array to have.
7760  *  \throw If \a this is not allocated
7761  *  \throw If getNbOfElems() % \a newNbOfCompo != 0.
7762  *  \throw If \a newNbOfCompo is lower than 1.
7763  *  \throw If the rearrange method would lead to a number of tuples higher than 2147483647 (maximal capacity of int32 !).
7764  *  \warning This method erases all (name and unit) component info set before!
7765  */
7766 void DataArrayInt::rearrange(int newNbOfCompo)
7767 {
7768   checkAllocated();
7769   if(newNbOfCompo<1)
7770     throw INTERP_KERNEL::Exception("DataArrayInt::rearrange : input newNbOfCompo must be > 0 !");
7771   std::size_t nbOfElems=getNbOfElems();
7772   if(nbOfElems%newNbOfCompo!=0)
7773     throw INTERP_KERNEL::Exception("DataArrayInt::rearrange : nbOfElems%newNbOfCompo!=0 !");
7774   if(nbOfElems/newNbOfCompo>(std::size_t)std::numeric_limits<int>::max())
7775     throw INTERP_KERNEL::Exception("DataArrayInt::rearrange : the rearrangement leads to too high number of tuples (> 2147483647) !");
7776   _info_on_compo.clear();
7777   _info_on_compo.resize(newNbOfCompo);
7778   declareAsNew();
7779 }
7780
7781 /*!
7782  * Changes the number of components within \a this array to be equal to its number
7783  * of tuples, and inversely its number of tuples to become equal to its number of 
7784  * components. So that its raw data **does not** change, instead splitting this
7785  * data into tuples changes.
7786  *  \warning This method erases all (name and unit) component info set before!
7787  *  \warning Do not confuse this method with fromNoInterlace() and toNoInterlace()!
7788  *  \throw If \a this is not allocated.
7789  *  \sa rearrange()
7790  */
7791 void DataArrayInt::transpose()
7792 {
7793   checkAllocated();
7794   int nbOfTuples=getNumberOfTuples();
7795   rearrange(nbOfTuples);
7796 }
7797
7798 /*!
7799  * Returns a shorten or extended copy of \a this array. If \a newNbOfComp is less
7800  * than \a this->getNumberOfComponents() then the result array is shorten as each tuple
7801  * is truncated to have \a newNbOfComp components, keeping first components. If \a
7802  * newNbOfComp is more than \a this->getNumberOfComponents() then the result array is
7803  * expanded as each tuple is populated with \a dftValue to have \a newNbOfComp
7804  * components.  
7805  *  \param [in] newNbOfComp - number of components for the new array to have.
7806  *  \param [in] dftValue - value assigned to new values added to the new array.
7807  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
7808  *          is to delete using decrRef() as it is no more needed.
7809  *  \throw If \a this is not allocated.
7810  */
7811 DataArrayInt *DataArrayInt::changeNbOfComponents(int newNbOfComp, int dftValue) const
7812 {
7813   checkAllocated();
7814   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
7815   ret->alloc(getNumberOfTuples(),newNbOfComp);
7816   const int *oldc=getConstPointer();
7817   int *nc=ret->getPointer();
7818   int nbOfTuples=getNumberOfTuples();
7819   int oldNbOfComp=getNumberOfComponents();
7820   int dim=std::min(oldNbOfComp,newNbOfComp);
7821   for(int i=0;i<nbOfTuples;i++)
7822     {
7823       int j=0;
7824       for(;j<dim;j++)
7825         nc[newNbOfComp*i+j]=oldc[i*oldNbOfComp+j];
7826       for(;j<newNbOfComp;j++)
7827         nc[newNbOfComp*i+j]=dftValue;
7828     }
7829   ret->setName(getName());
7830   for(int i=0;i<dim;i++)
7831     ret->setInfoOnComponent(i,getInfoOnComponent(i));
7832   ret->setName(getName());
7833   return ret.retn();
7834 }
7835
7836 /*!
7837  * Changes number of tuples in the array. If the new number of tuples is smaller
7838  * than the current number the array is truncated, otherwise the array is extended.
7839  *  \param [in] nbOfTuples - new number of tuples. 
7840  *  \throw If \a this is not allocated.
7841  *  \throw If \a nbOfTuples is negative.
7842  */
7843 void DataArrayInt::reAlloc(int nbOfTuples)
7844 {
7845   if(nbOfTuples<0)
7846     throw INTERP_KERNEL::Exception("DataArrayInt::reAlloc : input new number of tuples should be >=0 !");
7847   checkAllocated();
7848   _mem.reAlloc(getNumberOfComponents()*(std::size_t)nbOfTuples);
7849   declareAsNew();
7850 }
7851
7852
7853 /*!
7854  * Returns a copy of \a this array composed of selected components.
7855  * The new DataArrayInt has the same number of tuples but includes components
7856  * specified by \a compoIds parameter. So that getNbOfElems() of the result array
7857  * can be either less, same or more than \a this->getNbOfElems().
7858  *  \param [in] compoIds - sequence of zero based indices of components to include
7859  *              into the new array.
7860  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
7861  *          is to delete using decrRef() as it is no more needed.
7862  *  \throw If \a this is not allocated.
7863  *  \throw If a component index (\a i) is not valid: 
7864  *         \a i < 0 || \a i >= \a this->getNumberOfComponents().
7865  *
7866  *  \if ENABLE_EXAMPLES
7867  *  \ref py_mcdataarrayint_keepselectedcomponents "Here is a Python example".
7868  *  \endif
7869  */
7870 DataArrayInt *DataArrayInt::keepSelectedComponents(const std::vector<int>& compoIds) const
7871 {
7872   checkAllocated();
7873   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New());
7874   int newNbOfCompo=(int)compoIds.size();
7875   int oldNbOfCompo=getNumberOfComponents();
7876   for(std::vector<int>::const_iterator it=compoIds.begin();it!=compoIds.end();it++)
7877     DataArray::CheckValueInRange(oldNbOfCompo,(*it),"keepSelectedComponents invalid requested component");
7878   int nbOfTuples=getNumberOfTuples();
7879   ret->alloc(nbOfTuples,newNbOfCompo);
7880   ret->copyPartOfStringInfoFrom(*this,compoIds);
7881   const int *oldc=getConstPointer();
7882   int *nc=ret->getPointer();
7883   for(int i=0;i<nbOfTuples;i++)
7884     for(int j=0;j<newNbOfCompo;j++,nc++)
7885       *nc=oldc[i*oldNbOfCompo+compoIds[j]];
7886   return ret.retn();
7887 }
7888
7889 /*!
7890  * Appends components of another array to components of \a this one, tuple by tuple.
7891  * So that the number of tuples of \a this array remains the same and the number of 
7892  * components increases.
7893  *  \param [in] other - the DataArrayInt to append to \a this one.
7894  *  \throw If \a this is not allocated.
7895  *  \throw If \a this and \a other arrays have different number of tuples.
7896  *
7897  *  \if ENABLE_EXAMPLES
7898  *  \ref cpp_mcdataarrayint_meldwith "Here is a C++ example".
7899  *
7900  *  \ref py_mcdataarrayint_meldwith "Here is a Python example".
7901  *  \endif
7902  */
7903 void DataArrayInt::meldWith(const DataArrayInt *other)
7904 {
7905   if(!other)
7906     throw INTERP_KERNEL::Exception("DataArrayInt::meldWith : DataArrayInt pointer in input is NULL !");
7907   checkAllocated();
7908   other->checkAllocated();
7909   int nbOfTuples=getNumberOfTuples();
7910   if(nbOfTuples!=other->getNumberOfTuples())
7911     throw INTERP_KERNEL::Exception("DataArrayInt::meldWith : mismatch of number of tuples !");
7912   int nbOfComp1=getNumberOfComponents();
7913   int nbOfComp2=other->getNumberOfComponents();
7914   int *newArr=(int *)malloc(nbOfTuples*(nbOfComp1+nbOfComp2)*sizeof(int));
7915   int *w=newArr;
7916   const int *inp1=getConstPointer();
7917   const int *inp2=other->getConstPointer();
7918   for(int i=0;i<nbOfTuples;i++,inp1+=nbOfComp1,inp2+=nbOfComp2)
7919     {
7920       w=std::copy(inp1,inp1+nbOfComp1,w);
7921       w=std::copy(inp2,inp2+nbOfComp2,w);
7922     }
7923   useArray(newArr,true,C_DEALLOC,nbOfTuples,nbOfComp1+nbOfComp2);
7924   std::vector<int> compIds(nbOfComp2);
7925   for(int i=0;i<nbOfComp2;i++)
7926     compIds[i]=nbOfComp1+i;
7927   copyPartOfStringInfoFrom2(compIds,*other);
7928 }
7929
7930 /*!
7931  * Copy all components in a specified order from another DataArrayInt.
7932  * The specified components become the first ones in \a this array.
7933  * Both numerical and textual data is copied. The number of tuples in \a this and
7934  * the other array can be different.
7935  *  \param [in] a - the array to copy data from.
7936  *  \param [in] compoIds - sequence of zero based indices of components, data of which is
7937  *              to be copied.
7938  *  \throw If \a a is NULL.
7939  *  \throw If \a compoIds.size() != \a a->getNumberOfComponents().
7940  *  \throw If \a compoIds[i] < 0 or \a compoIds[i] > \a this->getNumberOfComponents().
7941  *
7942  *  \if ENABLE_EXAMPLES
7943  *  \ref py_mcdataarrayint_setselectedcomponents "Here is a Python example".
7944  *  \endif
7945  */
7946 void DataArrayInt::setSelectedComponents(const DataArrayInt *a, const std::vector<int>& compoIds)
7947 {
7948   if(!a)
7949     throw INTERP_KERNEL::Exception("DataArrayInt::setSelectedComponents : input DataArrayInt is NULL !");
7950   checkAllocated();
7951   a->checkAllocated();
7952   copyPartOfStringInfoFrom2(compoIds,*a);
7953   std::size_t partOfCompoSz=compoIds.size();
7954   int nbOfCompo=getNumberOfComponents();
7955   int nbOfTuples=std::min(getNumberOfTuples(),a->getNumberOfTuples());
7956   const int *ac=a->getConstPointer();
7957   int *nc=getPointer();
7958   for(int i=0;i<nbOfTuples;i++)
7959     for(std::size_t j=0;j<partOfCompoSz;j++,ac++)
7960       nc[nbOfCompo*i+compoIds[j]]=*ac;
7961 }
7962
7963 /*!
7964  * Copy all values from another DataArrayInt into specified tuples and components
7965  * of \a this array. Textual data is not copied.
7966  * The tree parameters defining set of indices of tuples and components are similar to
7967  * the tree parameters of the Python function \c range(\c start,\c stop,\c step).
7968  *  \param [in] a - the array to copy values from.
7969  *  \param [in] bgTuples - index of the first tuple of \a this array to assign values to.
7970  *  \param [in] endTuples - index of the tuple before which the tuples to assign to
7971  *              are located.
7972  *  \param [in] stepTuples - index increment to get index of the next tuple to assign to.
7973  *  \param [in] bgComp - index of the first component of \a this array to assign values to.
7974  *  \param [in] endComp - index of the component before which the components to assign
7975  *              to are located.
7976  *  \param [in] stepComp - index increment to get index of the next component to assign to.
7977  *  \param [in] strictCompoCompare - if \a true (by default), then \a a->getNumberOfComponents() 
7978  *              must be equal to the number of columns to assign to, else an
7979  *              exception is thrown; if \a false, then it is only required that \a
7980  *              a->getNbOfElems() equals to number of values to assign to (this condition
7981  *              must be respected even if \a strictCompoCompare is \a true). The number of 
7982  *              values to assign to is given by following Python expression:
7983  *              \a nbTargetValues = 
7984  *              \c len(\c range(\a bgTuples,\a endTuples,\a stepTuples)) *
7985  *              \c len(\c range(\a bgComp,\a endComp,\a stepComp)).
7986  *  \throw If \a a is NULL.
7987  *  \throw If \a a is not allocated.
7988  *  \throw If \a this is not allocated.
7989  *  \throw If parameters specifying tuples and components to assign to do not give a
7990  *            non-empty range of increasing indices.
7991  *  \throw If \a a->getNbOfElems() != \a nbTargetValues.
7992  *  \throw If \a strictCompoCompare == \a true && \a a->getNumberOfComponents() !=
7993  *            \c len(\c range(\a bgComp,\a endComp,\a stepComp)).
7994  *
7995  *  \if ENABLE_EXAMPLES
7996  *  \ref py_mcdataarrayint_setpartofvalues1 "Here is a Python example".
7997  *  \endif
7998  */
7999 void DataArrayInt::setPartOfValues1(const DataArrayInt *a, int bgTuples, int endTuples, int stepTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare)
8000 {
8001   if(!a)
8002     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValues1 : DataArrayInt pointer in input is NULL !");
8003   const char msg[]="DataArrayInt::setPartOfValues1";
8004   checkAllocated();
8005   a->checkAllocated();
8006   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
8007   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
8008   int nbComp=getNumberOfComponents();
8009   int nbOfTuples=getNumberOfTuples();
8010   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
8011   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
8012   bool assignTech=true;
8013   if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
8014     {
8015       if(strictCompoCompare)
8016         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
8017     }
8018   else
8019     {
8020       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
8021       assignTech=false;
8022     }
8023   int *pt=getPointer()+bgTuples*nbComp+bgComp;
8024   const int *srcPt=a->getConstPointer();
8025   if(assignTech)
8026     {
8027       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
8028         for(int j=0;j<newNbOfComp;j++,srcPt++)
8029           pt[j*stepComp]=*srcPt;
8030     }
8031   else
8032     {
8033       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
8034         {
8035           const int *srcPt2=srcPt;
8036           for(int j=0;j<newNbOfComp;j++,srcPt2++)
8037             pt[j*stepComp]=*srcPt2;
8038         }
8039     }
8040 }
8041
8042 /*!
8043  * Assign a given value to values at specified tuples and components of \a this array.
8044  * The tree parameters defining set of indices of tuples and components are similar to
8045  * the tree parameters of the Python function \c range(\c start,\c stop,\c step)..
8046  *  \param [in] a - the value to assign.
8047  *  \param [in] bgTuples - index of the first tuple of \a this array to assign to.
8048  *  \param [in] endTuples - index of the tuple before which the tuples to assign to
8049  *              are located.
8050  *  \param [in] stepTuples - index increment to get index of the next tuple to assign to.
8051  *  \param [in] bgComp - index of the first component of \a this array to assign to.
8052  *  \param [in] endComp - index of the component before which the components to assign
8053  *              to are located.
8054  *  \param [in] stepComp - index increment to get index of the next component to assign to.
8055  *  \throw If \a this is not allocated.
8056  *  \throw If parameters specifying tuples and components to assign to, do not give a
8057  *            non-empty range of increasing indices or indices are out of a valid range
8058  *            for \this array.
8059  *
8060  *  \if ENABLE_EXAMPLES
8061  *  \ref py_mcdataarrayint_setpartofvaluessimple1 "Here is a Python example".
8062  *  \endif
8063  */
8064 void DataArrayInt::setPartOfValuesSimple1(int a, int bgTuples, int endTuples, int stepTuples, int bgComp, int endComp, int stepComp)
8065 {
8066   const char msg[]="DataArrayInt::setPartOfValuesSimple1";
8067   checkAllocated();
8068   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
8069   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
8070   int nbComp=getNumberOfComponents();
8071   int nbOfTuples=getNumberOfTuples();
8072   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
8073   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
8074   int *pt=getPointer()+bgTuples*nbComp+bgComp;
8075   for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
8076     for(int j=0;j<newNbOfComp;j++)
8077       pt[j*stepComp]=a;
8078 }
8079
8080
8081 /*!
8082  * Copy all values from another DataArrayInt (\a a) into specified tuples and 
8083  * components of \a this array. Textual data is not copied.
8084  * The tuples and components to assign to are defined by C arrays of indices.
8085  * There are two *modes of usage*:
8086  * - If \a a->getNbOfElems() equals to number of values to assign to, then every value
8087  *   of \a a is assigned to its own location within \a this array. 
8088  * - If \a a includes one tuple, then all values of \a a are assigned to the specified
8089  *   components of every specified tuple of \a this array. In this mode it is required
8090  *   that \a a->getNumberOfComponents() equals to the number of specified components.
8091  * 
8092  *  \param [in] a - the array to copy values from.
8093  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
8094  *              assign values of \a a to.
8095  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
8096  *              pointer to a tuple index <em>(pi)</em> varies as this: 
8097  *              \a bgTuples <= \a pi < \a endTuples.
8098  *  \param [in] bgComp - pointer to an array of component indices of \a this array to
8099  *              assign values of \a a to.
8100  *  \param [in] endComp - specifies the end of the array \a bgTuples, so that
8101  *              pointer to a component index <em>(pi)</em> varies as this: 
8102  *              \a bgComp <= \a pi < \a endComp.
8103  *  \param [in] strictCompoCompare - this parameter is checked only if the
8104  *               *mode of usage* is the first; if it is \a true (default), 
8105  *               then \a a->getNumberOfComponents() must be equal 
8106  *               to the number of specified columns, else this is not required.
8107  *  \throw If \a a is NULL.
8108  *  \throw If \a a is not allocated.
8109  *  \throw If \a this is not allocated.
8110  *  \throw If any index of tuple/component given by <em>bgTuples / bgComp</em> is
8111  *         out of a valid range for \a this array.
8112  *  \throw In the first *mode of usage*, if <em>strictCompoCompare == true </em> and
8113  *         if <em> a->getNumberOfComponents() != (endComp - bgComp) </em>.
8114  *  \throw In the second *mode of usage*, if \a a->getNumberOfTuples() != 1 or
8115  *         <em> a->getNumberOfComponents() != (endComp - bgComp)</em>.
8116  *
8117  *  \if ENABLE_EXAMPLES
8118  *  \ref py_mcdataarrayint_setpartofvalues2 "Here is a Python example".
8119  *  \endif
8120  */
8121 void DataArrayInt::setPartOfValues2(const DataArrayInt *a, const int *bgTuples, const int *endTuples, const int *bgComp, const int *endComp, bool strictCompoCompare)
8122 {
8123   if(!a)
8124     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValues2 : DataArrayInt pointer in input is NULL !");
8125   const char msg[]="DataArrayInt::setPartOfValues2";
8126   checkAllocated();
8127   a->checkAllocated();
8128   int nbComp=getNumberOfComponents();
8129   int nbOfTuples=getNumberOfTuples();
8130   for(const int *z=bgComp;z!=endComp;z++)
8131     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
8132   int newNbOfTuples=(int)std::distance(bgTuples,endTuples);
8133   int newNbOfComp=(int)std::distance(bgComp,endComp);
8134   bool assignTech=true;
8135   if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
8136     {
8137       if(strictCompoCompare)
8138         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
8139     }
8140   else
8141     {
8142       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
8143       assignTech=false;
8144     }
8145   int *pt=getPointer();
8146   const int *srcPt=a->getConstPointer();
8147   if(assignTech)
8148     {    
8149       for(const int *w=bgTuples;w!=endTuples;w++)
8150         {
8151           DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
8152           for(const int *z=bgComp;z!=endComp;z++,srcPt++)
8153             {    
8154               pt[(std::size_t)(*w)*nbComp+(*z)]=*srcPt;
8155             }
8156         }
8157     }
8158   else
8159     {
8160       for(const int *w=bgTuples;w!=endTuples;w++)
8161         {
8162           const int *srcPt2=srcPt;
8163           DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
8164           for(const int *z=bgComp;z!=endComp;z++,srcPt2++)
8165             {    
8166               pt[(std::size_t)(*w)*nbComp+(*z)]=*srcPt2;
8167             }
8168         }
8169     }
8170 }
8171
8172 /*!
8173  * Assign a given value to values at specified tuples and components of \a this array.
8174  * The tuples and components to assign to are defined by C arrays of indices.
8175  *  \param [in] a - the value to assign.
8176  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
8177  *              assign \a a to.
8178  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
8179  *              pointer to a tuple index (\a pi) varies as this: 
8180  *              \a bgTuples <= \a pi < \a endTuples.
8181  *  \param [in] bgComp - pointer to an array of component indices of \a this array to
8182  *              assign \a a to.
8183  *  \param [in] endComp - specifies the end of the array \a bgTuples, so that
8184  *              pointer to a component index (\a pi) varies as this: 
8185  *              \a bgComp <= \a pi < \a endComp.
8186  *  \throw If \a this is not allocated.
8187  *  \throw If any index of tuple/component given by <em>bgTuples / bgComp</em> is
8188  *         out of a valid range for \a this array.
8189  *
8190  *  \if ENABLE_EXAMPLES
8191  *  \ref py_mcdataarrayint_setpartofvaluessimple2 "Here is a Python example".
8192  *  \endif
8193  */
8194 void DataArrayInt::setPartOfValuesSimple2(int a, const int *bgTuples, const int *endTuples, const int *bgComp, const int *endComp)
8195 {
8196   checkAllocated();
8197   int nbComp=getNumberOfComponents();
8198   int nbOfTuples=getNumberOfTuples();
8199   for(const int *z=bgComp;z!=endComp;z++)
8200     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
8201   int *pt=getPointer();
8202   for(const int *w=bgTuples;w!=endTuples;w++)
8203     for(const int *z=bgComp;z!=endComp;z++)
8204       {
8205         DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
8206         pt[(std::size_t)(*w)*nbComp+(*z)]=a;
8207       }
8208 }
8209
8210 /*!
8211  * Copy all values from another DataArrayInt (\a a) into specified tuples and 
8212  * components of \a this array. Textual data is not copied.
8213  * The tuples to assign to are defined by a C array of indices.
8214  * The components to assign to are defined by three values similar to parameters of
8215  * the Python function \c range(\c start,\c stop,\c step).
8216  * There are two *modes of usage*:
8217  * - If \a a->getNbOfElems() equals to number of values to assign to, then every value
8218  *   of \a a is assigned to its own location within \a this array. 
8219  * - If \a a includes one tuple, then all values of \a a are assigned to the specified
8220  *   components of every specified tuple of \a this array. In this mode it is required
8221  *   that \a a->getNumberOfComponents() equals to the number of specified components.
8222  *
8223  *  \param [in] a - the array to copy values from.
8224  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
8225  *              assign values of \a a to.
8226  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
8227  *              pointer to a tuple index <em>(pi)</em> varies as this: 
8228  *              \a bgTuples <= \a pi < \a endTuples.
8229  *  \param [in] bgComp - index of the first component of \a this array to assign to.
8230  *  \param [in] endComp - index of the component before which the components to assign
8231  *              to are located.
8232  *  \param [in] stepComp - index increment to get index of the next component to assign to.
8233  *  \param [in] strictCompoCompare - this parameter is checked only in the first
8234  *               *mode of usage*; if \a strictCompoCompare is \a true (default), 
8235  *               then \a a->getNumberOfComponents() must be equal 
8236  *               to the number of specified columns, else this is not required.
8237  *  \throw If \a a is NULL.
8238  *  \throw If \a a is not allocated.
8239  *  \throw If \a this is not allocated.
8240  *  \throw If any index of tuple given by \a bgTuples is out of a valid range for 
8241  *         \a this array.
8242  *  \throw In the first *mode of usage*, if <em>strictCompoCompare == true </em> and
8243  *         if <em> a->getNumberOfComponents()</em> is unequal to the number of components
8244  *         defined by <em>(bgComp,endComp,stepComp)</em>.
8245  *  \throw In the second *mode of usage*, if \a a->getNumberOfTuples() != 1 or
8246  *         <em> a->getNumberOfComponents()</em> is unequal to the number of components
8247  *         defined by <em>(bgComp,endComp,stepComp)</em>.
8248  *  \throw If parameters specifying components to assign to, do not give a
8249  *            non-empty range of increasing indices or indices are out of a valid range
8250  *            for \this array.
8251  *
8252  *  \if ENABLE_EXAMPLES
8253  *  \ref py_mcdataarrayint_setpartofvalues3 "Here is a Python example".
8254  *  \endif
8255  */
8256 void DataArrayInt::setPartOfValues3(const DataArrayInt *a, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare)
8257 {
8258   if(!a)
8259     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValues3 : DataArrayInt pointer in input is NULL !");
8260   const char msg[]="DataArrayInt::setPartOfValues3";
8261   checkAllocated();
8262   a->checkAllocated();
8263   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
8264   int nbComp=getNumberOfComponents();
8265   int nbOfTuples=getNumberOfTuples();
8266   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
8267   int newNbOfTuples=(int)std::distance(bgTuples,endTuples);
8268   bool assignTech=true;
8269   if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
8270     {
8271       if(strictCompoCompare)
8272         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
8273     }
8274   else
8275     {
8276       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
8277       assignTech=false;
8278     }
8279   int *pt=getPointer()+bgComp;
8280   const int *srcPt=a->getConstPointer();
8281   if(assignTech)
8282     {
8283       for(const int *w=bgTuples;w!=endTuples;w++)
8284         for(int j=0;j<newNbOfComp;j++,srcPt++)
8285           {
8286             DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
8287             pt[(std::size_t)(*w)*nbComp+j*stepComp]=*srcPt;
8288           }
8289     }
8290   else
8291     {
8292       for(const int *w=bgTuples;w!=endTuples;w++)
8293         {
8294           const int *srcPt2=srcPt;
8295           for(int j=0;j<newNbOfComp;j++,srcPt2++)
8296             {
8297               DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
8298               pt[(std::size_t)(*w)*nbComp+j*stepComp]=*srcPt2;
8299             }
8300         }
8301     }
8302 }
8303
8304 /*!
8305  * Assign a given value to values at specified tuples and components of \a this array.
8306  * The tuples to assign to are defined by a C array of indices.
8307  * The components to assign to are defined by three values similar to parameters of
8308  * the Python function \c range(\c start,\c stop,\c step).
8309  *  \param [in] a - the value to assign.
8310  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
8311  *              assign \a a to.
8312  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
8313  *              pointer to a tuple index <em>(pi)</em> varies as this: 
8314  *              \a bgTuples <= \a pi < \a endTuples.
8315  *  \param [in] bgComp - index of the first component of \a this array to assign to.
8316  *  \param [in] endComp - index of the component before which the components to assign
8317  *              to are located.
8318  *  \param [in] stepComp - index increment to get index of the next component to assign to.
8319  *  \throw If \a this is not allocated.
8320  *  \throw If any index of tuple given by \a bgTuples is out of a valid range for 
8321  *         \a this array.
8322  *  \throw If parameters specifying components to assign to, do not give a
8323  *            non-empty range of increasing indices or indices are out of a valid range
8324  *            for \this array.
8325  *
8326  *  \if ENABLE_EXAMPLES
8327  *  \ref py_mcdataarrayint_setpartofvaluessimple3 "Here is a Python example".
8328  *  \endif
8329  */
8330 void DataArrayInt::setPartOfValuesSimple3(int a, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp)
8331 {
8332   const char msg[]="DataArrayInt::setPartOfValuesSimple3";
8333   checkAllocated();
8334   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
8335   int nbComp=getNumberOfComponents();
8336   int nbOfTuples=getNumberOfTuples();
8337   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
8338   int *pt=getPointer()+bgComp;
8339   for(const int *w=bgTuples;w!=endTuples;w++)
8340     for(int j=0;j<newNbOfComp;j++)
8341       {
8342         DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
8343         pt[(std::size_t)(*w)*nbComp+j*stepComp]=a;
8344       }
8345 }
8346
8347 void DataArrayInt::setPartOfValues4(const DataArrayInt *a, int bgTuples, int endTuples, int stepTuples, const int *bgComp, const int *endComp, bool strictCompoCompare)
8348 {
8349   if(!a)
8350     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValues4 : input DataArrayInt is NULL !");
8351   const char msg[]="DataArrayInt::setPartOfValues4";
8352   checkAllocated();
8353   a->checkAllocated();
8354   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
8355   int newNbOfComp=(int)std::distance(bgComp,endComp);
8356   int nbComp=getNumberOfComponents();
8357   for(const int *z=bgComp;z!=endComp;z++)
8358     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
8359   int nbOfTuples=getNumberOfTuples();
8360   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
8361   bool assignTech=true;
8362   if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
8363     {
8364       if(strictCompoCompare)
8365         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
8366     }
8367   else
8368     {
8369       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
8370       assignTech=false;
8371     }
8372   const int *srcPt=a->getConstPointer();
8373   int *pt=getPointer()+bgTuples*nbComp;
8374   if(assignTech)
8375     {
8376       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
8377         for(const int *z=bgComp;z!=endComp;z++,srcPt++)
8378           pt[*z]=*srcPt;
8379     }
8380   else
8381     {
8382       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
8383         {
8384           const int *srcPt2=srcPt;
8385           for(const int *z=bgComp;z!=endComp;z++,srcPt2++)
8386             pt[*z]=*srcPt2;
8387         }
8388     }
8389 }
8390
8391 void DataArrayInt::setPartOfValuesSimple4(int a, int bgTuples, int endTuples, int stepTuples, const int *bgComp, const int *endComp)
8392 {
8393   const char msg[]="DataArrayInt::setPartOfValuesSimple4";
8394   checkAllocated();
8395   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
8396   int nbComp=getNumberOfComponents();
8397   for(const int *z=bgComp;z!=endComp;z++)
8398     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
8399   int nbOfTuples=getNumberOfTuples();
8400   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
8401   int *pt=getPointer()+bgTuples*nbComp;
8402   for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
8403     for(const int *z=bgComp;z!=endComp;z++)
8404       pt[*z]=a;
8405 }
8406
8407 /*!
8408  * Copy some tuples from another DataArrayInt into specified tuples
8409  * of \a this array. Textual data is not copied. Both arrays must have equal number of
8410  * components.
8411  * Both the tuples to assign and the tuples to assign to are defined by a DataArrayInt.
8412  * All components of selected tuples are copied.
8413  *  \param [in] a - the array to copy values from.
8414  *  \param [in] tuplesSelec - the array specifying both source tuples of \a a and
8415  *              target tuples of \a this. \a tuplesSelec has two components, and the
8416  *              first component specifies index of the source tuple and the second
8417  *              one specifies index of the target tuple.
8418  *  \throw If \a this is not allocated.
8419  *  \throw If \a a is NULL.
8420  *  \throw If \a a is not allocated.
8421  *  \throw If \a tuplesSelec is NULL.
8422  *  \throw If \a tuplesSelec is not allocated.
8423  *  \throw If <em>this->getNumberOfComponents() != a->getNumberOfComponents()</em>.
8424  *  \throw If \a tuplesSelec->getNumberOfComponents() != 2.
8425  *  \throw If any tuple index given by \a tuplesSelec is out of a valid range for 
8426  *         the corresponding (\a this or \a a) array.
8427  */
8428 void DataArrayInt::setPartOfValuesAdv(const DataArrayInt *a, const DataArrayInt *tuplesSelec)
8429 {
8430   if(!a || !tuplesSelec)
8431     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValuesAdv : DataArrayInt pointer in input is NULL !");
8432   checkAllocated();
8433   a->checkAllocated();
8434   tuplesSelec->checkAllocated();
8435   int nbOfComp=getNumberOfComponents();
8436   if(nbOfComp!=a->getNumberOfComponents())
8437     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValuesAdv : This and a do not have the same number of components !");
8438   if(tuplesSelec->getNumberOfComponents()!=2)
8439     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValuesAdv : Expecting to have a tuple selector DataArrayInt instance with exactly 2 components !");
8440   int thisNt=getNumberOfTuples();
8441   int aNt=a->getNumberOfTuples();
8442   int *valsToSet=getPointer();
8443   const int *valsSrc=a->getConstPointer();
8444   for(const int *tuple=tuplesSelec->begin();tuple!=tuplesSelec->end();tuple+=2)
8445     {
8446       if(tuple[1]>=0 && tuple[1]<aNt)
8447         {
8448           if(tuple[0]>=0 && tuple[0]<thisNt)
8449             std::copy(valsSrc+nbOfComp*tuple[1],valsSrc+nbOfComp*(tuple[1]+1),valsToSet+nbOfComp*tuple[0]);
8450           else
8451             {
8452               std::ostringstream oss; oss << "DataArrayInt::setPartOfValuesAdv : Tuple #" << std::distance(tuplesSelec->begin(),tuple)/2;
8453               oss << " of 'tuplesSelec' request of tuple id #" << tuple[0] << " in 'this' ! It should be in [0," << thisNt << ") !";
8454               throw INTERP_KERNEL::Exception(oss.str().c_str());
8455             }
8456         }
8457       else
8458         {
8459           std::ostringstream oss; oss << "DataArrayInt::setPartOfValuesAdv : Tuple #" << std::distance(tuplesSelec->begin(),tuple)/2;
8460           oss << " of 'tuplesSelec' request of tuple id #" << tuple[1] << " in 'a' ! It should be in [0," << aNt << ") !";
8461           throw INTERP_KERNEL::Exception(oss.str().c_str());
8462         }
8463     }
8464 }
8465
8466 /*!
8467  * Copy some tuples from another DataArrayInt (\a aBase) into contiguous tuples
8468  * of \a this array. Textual data is not copied. Both arrays must have equal number of
8469  * components.
8470  * The tuples to assign to are defined by index of the first tuple, and
8471  * their number is defined by \a tuplesSelec->getNumberOfTuples().
8472  * The tuples to copy are defined by values of a DataArrayInt.
8473  * All components of selected tuples are copied.
8474  *  \param [in] tupleIdStart - index of the first tuple of \a this array to assign
8475  *              values to.
8476  *  \param [in] aBase - the array to copy values from.
8477  *  \param [in] tuplesSelec - the array specifying tuples of \a aBase to copy.
8478  *  \throw If \a this is not allocated.
8479  *  \throw If \a aBase is NULL.
8480  *  \throw If \a aBase is not allocated.
8481  *  \throw If \a tuplesSelec is NULL.
8482  *  \throw If \a tuplesSelec is not allocated.
8483  *  \throw If <em>this->getNumberOfComponents() != a->getNumberOfComponents()</em>.
8484  *  \throw If \a tuplesSelec->getNumberOfComponents() != 1.
8485  *  \throw If <em>tupleIdStart + tuplesSelec->getNumberOfTuples() > this->getNumberOfTuples().</em>
8486  *  \throw If any tuple index given by \a tuplesSelec is out of a valid range for 
8487  *         \a aBase array.
8488  */
8489 void DataArrayInt::setContigPartOfSelectedValues(int tupleIdStart, const DataArray *aBase, const DataArrayInt *tuplesSelec)
8490 {
8491   if(!aBase || !tuplesSelec)
8492     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues : input DataArray is NULL !");
8493   const DataArrayInt *a=dynamic_cast<const DataArrayInt *>(aBase);
8494   if(!a)
8495     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues : input DataArray aBase is not a DataArrayInt !");
8496   checkAllocated();
8497   a->checkAllocated();
8498   tuplesSelec->checkAllocated();
8499   int nbOfComp=getNumberOfComponents();
8500   if(nbOfComp!=a->getNumberOfComponents())
8501     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues : This and a do not have the same number of components !");
8502   if(tuplesSelec->getNumberOfComponents()!=1)
8503     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues : Expecting to have a tuple selector DataArrayInt instance with exactly 1 component !");
8504   int thisNt=getNumberOfTuples();
8505   int aNt=a->getNumberOfTuples();
8506   int nbOfTupleToWrite=tuplesSelec->getNumberOfTuples();
8507   int *valsToSet=getPointer()+tupleIdStart*nbOfComp;
8508   if(tupleIdStart+nbOfTupleToWrite>thisNt)
8509     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues : invalid number range of values to write !");
8510   const int *valsSrc=a->getConstPointer();
8511   for(const int *tuple=tuplesSelec->begin();tuple!=tuplesSelec->end();tuple++,valsToSet+=nbOfComp)
8512     {
8513       if(*tuple>=0 && *tuple<aNt)
8514         {
8515           std::copy(valsSrc+nbOfComp*(*tuple),valsSrc+nbOfComp*(*tuple+1),valsToSet);
8516         }
8517       else
8518         {
8519           std::ostringstream oss; oss << "DataArrayInt::setContigPartOfSelectedValues : Tuple #" << std::distance(tuplesSelec->begin(),tuple);
8520           oss << " of 'tuplesSelec' request of tuple id #" << *tuple << " in 'a' ! It should be in [0," << aNt << ") !";
8521           throw INTERP_KERNEL::Exception(oss.str().c_str());
8522         }
8523     }
8524 }
8525
8526 /*!
8527  * Copy some tuples from another DataArrayInt (\a aBase) into contiguous tuples
8528  * of \a this array. Textual data is not copied. Both arrays must have equal number of
8529  * components.
8530  * The tuples to copy are defined by three values similar to parameters of
8531  * the Python function \c range(\c start,\c stop,\c step).
8532  * The tuples to assign to are defined by index of the first tuple, and
8533  * their number is defined by number of tuples to copy.
8534  * All components of selected tuples are copied.
8535  *  \param [in] tupleIdStart - index of the first tuple of \a this array to assign
8536  *              values to.
8537  *  \param [in] aBase - the array to copy values from.
8538  *  \param [in] bg - index of the first tuple to copy of the array \a aBase.
8539  *  \param [in] end2 - index of the tuple of \a aBase before which the tuples to copy
8540  *              are located.
8541  *  \param [in] step - index increment to get index of the next tuple to copy.
8542  *  \throw If \a this is not allocated.
8543  *  \throw If \a aBase is NULL.
8544  *  \throw If \a aBase is not allocated.
8545  *  \throw If <em>this->getNumberOfComponents() != aBase->getNumberOfComponents()</em>.
8546  *  \throw If <em>tupleIdStart + len(range(bg,end2,step)) > this->getNumberOfTuples().</em>
8547  *  \throw If parameters specifying tuples to copy, do not give a
8548  *            non-empty range of increasing indices or indices are out of a valid range
8549  *            for the array \a aBase.
8550  */
8551 void DataArrayInt::setContigPartOfSelectedValues2(int tupleIdStart, const DataArray *aBase, int bg, int end2, int step)
8552 {
8553   if(!aBase)
8554     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues2 : input DataArray is NULL !");
8555   const DataArrayInt *a=dynamic_cast<const DataArrayInt *>(aBase);
8556   if(!a)
8557     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues2 : input DataArray aBase is not a DataArrayInt !");
8558   checkAllocated();
8559   a->checkAllocated();
8560   int nbOfComp=getNumberOfComponents();
8561   const char msg[]="DataArrayInt::setContigPartOfSelectedValues2";
8562   int nbOfTupleToWrite=DataArray::GetNumberOfItemGivenBES(bg,end2,step,msg);
8563   if(nbOfComp!=a->getNumberOfComponents())
8564     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues2 : This and a do not have the same number of components !");
8565   int thisNt=getNumberOfTuples();
8566   int aNt=a->getNumberOfTuples();
8567   int *valsToSet=getPointer()+tupleIdStart*nbOfComp;
8568   if(tupleIdStart+nbOfTupleToWrite>thisNt)
8569     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues2 : invalid number range of values to write !");
8570   if(end2>aNt)
8571     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues2 : invalid range of values to read !");
8572   const int *valsSrc=a->getConstPointer()+bg*nbOfComp;
8573   for(int i=0;i<nbOfTupleToWrite;i++,valsToSet+=nbOfComp,valsSrc+=step*nbOfComp)
8574     {
8575       std::copy(valsSrc,valsSrc+nbOfComp,valsToSet);
8576     }
8577 }
8578
8579 /*!
8580  * Returns a value located at specified tuple and component.
8581  * This method is equivalent to DataArrayInt::getIJ() except that validity of
8582  * parameters is checked. So this method is safe but expensive if used to go through
8583  * all values of \a this.
8584  *  \param [in] tupleId - index of tuple of interest.
8585  *  \param [in] compoId - index of component of interest.
8586  *  \return double - value located by \a tupleId and \a compoId.
8587  *  \throw If \a this is not allocated.
8588  *  \throw If condition <em>( 0 <= tupleId < this->getNumberOfTuples() )</em> is violated.
8589  *  \throw If condition <em>( 0 <= compoId < this->getNumberOfComponents() )</em> is violated.
8590  */
8591 int DataArrayInt::getIJSafe(int tupleId, int compoId) const
8592 {
8593   checkAllocated();
8594   if(tupleId<0 || tupleId>=getNumberOfTuples())
8595     {
8596       std::ostringstream oss; oss << "DataArrayInt::getIJSafe : request for tupleId " << tupleId << " should be in [0," << getNumberOfTuples() << ") !";
8597       throw INTERP_KERNEL::Exception(oss.str().c_str());
8598     }
8599   if(compoId<0 || compoId>=getNumberOfComponents())
8600     {
8601       std::ostringstream oss; oss << "DataArrayInt::getIJSafe : request for compoId " << compoId << " should be in [0," << getNumberOfComponents() << ") !";
8602       throw INTERP_KERNEL::Exception(oss.str().c_str());
8603     }
8604   return _mem[tupleId*_info_on_compo.size()+compoId];
8605 }
8606
8607 /*!
8608  * Returns the first value of \a this. 
8609  *  \return int - the last value of \a this array.
8610  *  \throw If \a this is not allocated.
8611  *  \throw If \a this->getNumberOfComponents() != 1.
8612  *  \throw If \a this->getNumberOfTuples() < 1.
8613  */
8614 int DataArrayInt::front() const
8615 {
8616   checkAllocated();
8617   if(getNumberOfComponents()!=1)
8618     throw INTERP_KERNEL::Exception("DataArrayInt::front : number of components not equal to one !");
8619   int nbOfTuples=getNumberOfTuples();
8620   if(nbOfTuples<1)
8621     throw INTERP_KERNEL::Exception("DataArrayInt::front : number of tuples must be >= 1 !");
8622   return *(getConstPointer());
8623 }
8624
8625 /*!
8626  * Returns the last value of \a this. 
8627  *  \return int - the last value of \a this array.
8628  *  \throw If \a this is not allocated.
8629  *  \throw If \a this->getNumberOfComponents() != 1.
8630  *  \throw If \a this->getNumberOfTuples() < 1.
8631  */
8632 int DataArrayInt::back() const
8633 {
8634   checkAllocated();
8635   if(getNumberOfComponents()!=1)
8636     throw INTERP_KERNEL::Exception("DataArrayInt::back : number of components not equal to one !");
8637   int nbOfTuples=getNumberOfTuples();
8638   if(nbOfTuples<1)
8639     throw INTERP_KERNEL::Exception("DataArrayInt::back : number of tuples must be >= 1 !");
8640   return *(getConstPointer()+nbOfTuples-1);
8641 }
8642
8643 /*!
8644  * Assign pointer to one array to a pointer to another appay. Reference counter of
8645  * \a arrayToSet is incremented / decremented.
8646  *  \param [in] newArray - the pointer to array to assign to \a arrayToSet.
8647  *  \param [in,out] arrayToSet - the pointer to array to assign to.
8648  */
8649 void DataArrayInt::SetArrayIn(DataArrayInt *newArray, DataArrayInt* &arrayToSet)
8650 {
8651   if(newArray!=arrayToSet)
8652     {
8653       if(arrayToSet)
8654         arrayToSet->decrRef();
8655       arrayToSet=newArray;
8656       if(arrayToSet)
8657         arrayToSet->incrRef();
8658     }
8659 }
8660
8661 DataArrayIntIterator *DataArrayInt::iterator()
8662 {
8663   return new DataArrayIntIterator(this);
8664 }
8665
8666 /*!
8667  * Creates a new DataArrayInt containing IDs (indices) of tuples holding value equal to a
8668  * given one. The ids are sorted in the ascending order.
8669  *  \param [in] val - the value to find within \a this.
8670  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
8671  *          array using decrRef() as it is no more needed.
8672  *  \throw If \a this is not allocated.
8673  *  \throw If \a this->getNumberOfComponents() != 1.
8674  *  \sa DataArrayInt::getIdsEqualTuple
8675  */
8676 DataArrayInt *DataArrayInt::getIdsEqual(int val) const
8677 {
8678   checkAllocated();
8679   if(getNumberOfComponents()!=1)
8680     throw INTERP_KERNEL::Exception("DataArrayInt::getIdsEqual : the array must have only one component, you can call 'rearrange' method before !");
8681   const int *cptr(getConstPointer());
8682   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
8683   int nbOfTuples=getNumberOfTuples();
8684   for(int i=0;i<nbOfTuples;i++,cptr++)
8685     if(*cptr==val)
8686       ret->pushBackSilent(i);
8687   return ret.retn();
8688 }
8689
8690 /*!
8691  * Creates a new DataArrayInt containing IDs (indices) of tuples holding value \b not
8692  * equal to a given one. 
8693  *  \param [in] val - the value to ignore within \a this.
8694  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
8695  *          array using decrRef() as it is no more needed.
8696  *  \throw If \a this is not allocated.
8697  *  \throw If \a this->getNumberOfComponents() != 1.
8698  */
8699 DataArrayInt *DataArrayInt::getIdsNotEqual(int val) const
8700 {
8701   checkAllocated();
8702   if(getNumberOfComponents()!=1)
8703     throw INTERP_KERNEL::Exception("DataArrayInt::getIdsNotEqual : the array must have only one component, you can call 'rearrange' method before !");
8704   const int *cptr(getConstPointer());
8705   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
8706   int nbOfTuples=getNumberOfTuples();
8707   for(int i=0;i<nbOfTuples;i++,cptr++)
8708     if(*cptr!=val)
8709       ret->pushBackSilent(i);
8710   return ret.retn();
8711 }
8712
8713 /*!
8714  * Creates a new DataArrayInt containing IDs (indices) of tuples holding tuple equal to those defined by [ \a tupleBg , \a tupleEnd )
8715  * This method is an extension of  DataArrayInt::getIdsEqual method.
8716  *
8717  *  \param [in] tupleBg - the begin (included) of the input tuple to find within \a this.
8718  *  \param [in] tupleEnd - the end (excluded) of the input tuple to find within \a this.
8719  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
8720  *          array using decrRef() as it is no more needed.
8721  *  \throw If \a this is not allocated.
8722  *  \throw If \a this->getNumberOfComponents() != std::distance(tupleBg,tupleEnd).
8723  * \throw If \a this->getNumberOfComponents() is equal to 0.
8724  * \sa DataArrayInt::getIdsEqual
8725  */
8726 DataArrayInt *DataArrayInt::getIdsEqualTuple(const int *tupleBg, const int *tupleEnd) const
8727 {
8728   std::size_t nbOfCompoExp(std::distance(tupleBg,tupleEnd));
8729   checkAllocated();
8730   if(getNumberOfComponents()!=(int)nbOfCompoExp)
8731     {
8732       std::ostringstream oss; oss << "DataArrayInt::getIdsEqualTuple : mismatch of number of components. Input tuple has " << nbOfCompoExp << " whereas this array has " << getNumberOfComponents() << " components !";
8733       throw INTERP_KERNEL::Exception(oss.str().c_str());
8734     }
8735   if(nbOfCompoExp==0)
8736     throw INTERP_KERNEL::Exception("DataArrayInt::getIdsEqualTuple : number of components should be > 0 !");
8737   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
8738   const int *bg(begin()),*end2(end()),*work(begin());
8739   while(work!=end2)
8740     {
8741       work=std::search(work,end2,tupleBg,tupleEnd);
8742       if(work!=end2)
8743         {
8744           std::size_t pos(std::distance(bg,work));
8745           if(pos%nbOfCompoExp==0)
8746             ret->pushBackSilent(pos/nbOfCompoExp);
8747           work++;
8748         }
8749     }
8750   return ret.retn();
8751 }
8752
8753 /*!
8754  * Assigns \a newValue to all elements holding \a oldValue within \a this
8755  * one-dimensional array.
8756  *  \param [in] oldValue - the value to replace.
8757  *  \param [in] newValue - the value to assign.
8758  *  \return int - number of replacements performed.
8759  *  \throw If \a this is not allocated.
8760  *  \throw If \a this->getNumberOfComponents() != 1.
8761  */
8762 int DataArrayInt::changeValue(int oldValue, int newValue)
8763 {
8764   checkAllocated();
8765   if(getNumberOfComponents()!=1)
8766     throw INTERP_KERNEL::Exception("DataArrayInt::changeValue : the array must have only one component, you can call 'rearrange' method before !");
8767   int *start=getPointer();
8768   int *end2=start+getNbOfElems();
8769   int ret=0;
8770   for(int *val=start;val!=end2;val++)
8771     {
8772       if(*val==oldValue)
8773         {
8774           *val=newValue;
8775           ret++;
8776         }
8777     }
8778   return ret;
8779 }
8780
8781 /*!
8782  * Creates a new DataArrayInt containing IDs (indices) of tuples holding value equal to
8783  * one of given values.
8784  *  \param [in] valsBg - an array of values to find within \a this array.
8785  *  \param [in] valsEnd - specifies the end of the array \a valsBg, so that
8786  *              the last value of \a valsBg is \a valsEnd[ -1 ].
8787  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
8788  *          array using decrRef() as it is no more needed.
8789  *  \throw If \a this->getNumberOfComponents() != 1.
8790  */
8791 DataArrayInt *DataArrayInt::getIdsEqualList(const int *valsBg, const int *valsEnd) const
8792 {
8793   if(getNumberOfComponents()!=1)
8794     throw INTERP_KERNEL::Exception("DataArrayInt::getIdsEqualList : the array must have only one component, you can call 'rearrange' method before !");
8795   std::set<int> vals2(valsBg,valsEnd);
8796   const int *cptr=getConstPointer();
8797   std::vector<int> res;
8798   int nbOfTuples=getNumberOfTuples();
8799   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
8800   for(int i=0;i<nbOfTuples;i++,cptr++)
8801     if(vals2.find(*cptr)!=vals2.end())
8802       ret->pushBackSilent(i);
8803   return ret.retn();
8804 }
8805
8806 /*!
8807  * Creates a new DataArrayInt containing IDs (indices) of tuples holding values \b not
8808  * equal to any of given values.
8809  *  \param [in] valsBg - an array of values to ignore within \a this array.
8810  *  \param [in] valsEnd - specifies the end of the array \a valsBg, so that
8811  *              the last value of \a valsBg is \a valsEnd[ -1 ].
8812  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
8813  *          array using decrRef() as it is no more needed.
8814  *  \throw If \a this->getNumberOfComponents() != 1.
8815  */
8816 DataArrayInt *DataArrayInt::getIdsNotEqualList(const int *valsBg, const int *valsEnd) const
8817 {
8818   if(getNumberOfComponents()!=1)
8819     throw INTERP_KERNEL::Exception("DataArrayInt::getIdsNotEqualList : the array must have only one component, you can call 'rearrange' method before !");
8820   std::set<int> vals2(valsBg,valsEnd);
8821   const int *cptr=getConstPointer();
8822   std::vector<int> res;
8823   int nbOfTuples=getNumberOfTuples();
8824   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
8825   for(int i=0;i<nbOfTuples;i++,cptr++)
8826     if(vals2.find(*cptr)==vals2.end())
8827       ret->pushBackSilent(i);
8828   return ret.retn();
8829 }
8830
8831 /*!
8832  * This method is an extension of DataArrayInt::locateValue method because this method works for DataArrayInt with
8833  * any number of components excepted 0 (an INTERP_KERNEL::Exception is thrown in this case).
8834  * This method searches in \b this is there is a tuple that matched the input parameter \b tupl.
8835  * If any the tuple id is returned. If not -1 is returned.
8836  * 
8837  * This method throws an INTERP_KERNEL::Exception if the number of components in \b this mismatches with the size of
8838  * the input vector. An INTERP_KERNEL::Exception is thrown too if \b this is not allocated.
8839  *
8840  * \return tuple id where \b tupl is. -1 if no such tuple exists in \b this.
8841  * \sa DataArrayInt::search, DataArrayInt::presenceOfTuple.
8842  */
8843 int DataArrayInt::locateTuple(const std::vector<int>& tupl) const
8844 {
8845   checkAllocated();
8846   int nbOfCompo=getNumberOfComponents();
8847   if(nbOfCompo==0)
8848     throw INTERP_KERNEL::Exception("DataArrayInt::locateTuple : 0 components in 'this' !");
8849   if(nbOfCompo!=(int)tupl.size())
8850     {
8851       std::ostringstream oss; oss << "DataArrayInt::locateTuple : 'this' contains " << nbOfCompo << " components and searching for a tuple of length " << tupl.size() << " !";
8852       throw INTERP_KERNEL::Exception(oss.str().c_str());
8853     }
8854   const int *cptr=getConstPointer();
8855   std::size_t nbOfVals=getNbOfElems();
8856   for(const int *work=cptr;work!=cptr+nbOfVals;)
8857     {
8858       work=std::search(work,cptr+nbOfVals,tupl.begin(),tupl.end());
8859       if(work!=cptr+nbOfVals)
8860         {
8861           if(std::distance(cptr,work)%nbOfCompo!=0)
8862             work++;
8863           else
8864             return std::distance(cptr,work)/nbOfCompo;
8865         }
8866     }
8867   return -1;
8868 }
8869
8870 /*!
8871  * This method searches the sequence specified in input parameter \b vals in \b this.
8872  * This works only for DataArrayInt having number of components equal to one (if not an INTERP_KERNEL::Exception will be thrown).
8873  * This method differs from DataArrayInt::locateTuple in that the position is internal raw data is not considered here contrary to DataArrayInt::locateTuple.
8874  * \sa DataArrayInt::locateTuple
8875  */
8876 int DataArrayInt::search(const std::vector<int>& vals) const
8877 {
8878   checkAllocated();
8879   int nbOfCompo=getNumberOfComponents();
8880   if(nbOfCompo!=1)
8881     throw INTERP_KERNEL::Exception("DataArrayInt::search : works only for DataArrayInt instance with one component !");
8882   const int *cptr=getConstPointer();
8883   std::size_t nbOfVals=getNbOfElems();
8884   const int *loc=std::search(cptr,cptr+nbOfVals,vals.begin(),vals.end());
8885   if(loc!=cptr+nbOfVals)
8886     return std::distance(cptr,loc);
8887   return -1;
8888 }
8889
8890 /*!
8891  * This method expects to be called when number of components of this is equal to one.
8892  * This method returns the tuple id, if it exists, of the first tuple equal to \b value.
8893  * If not any tuple contains \b value -1 is returned.
8894  * \sa DataArrayInt::presenceOfValue
8895  */
8896 int DataArrayInt::locateValue(int value) const
8897 {
8898   checkAllocated();
8899   if(getNumberOfComponents()!=1)
8900     throw INTERP_KERNEL::Exception("DataArrayInt::presenceOfValue : the array must have only one component, you can call 'rearrange' method before !");
8901   const int *cptr=getConstPointer();
8902   int nbOfTuples=getNumberOfTuples();
8903   const int *ret=std::find(cptr,cptr+nbOfTuples,value);
8904   if(ret!=cptr+nbOfTuples)
8905     return std::distance(cptr,ret);
8906   return -1;
8907 }
8908
8909 /*!
8910  * This method expects to be called when number of components of this is equal to one.
8911  * This method returns the tuple id, if it exists, of the first tuple so that the value is contained in \b vals.
8912  * If not any tuple contains one of the values contained in 'vals' false is returned.
8913  * \sa DataArrayInt::presenceOfValue
8914  */
8915 int DataArrayInt::locateValue(const std::vector<int>& vals) const
8916 {
8917   checkAllocated();
8918   if(getNumberOfComponents()!=1)
8919     throw INTERP_KERNEL::Exception("DataArrayInt::presenceOfValue : the array must have only one component, you can call 'rearrange' method before !");
8920   std::set<int> vals2(vals.begin(),vals.end());
8921   const int *cptr=getConstPointer();
8922   int nbOfTuples=getNumberOfTuples();
8923   for(const int *w=cptr;w!=cptr+nbOfTuples;w++)
8924     if(vals2.find(*w)!=vals2.end())
8925       return std::distance(cptr,w);
8926   return -1;
8927 }
8928
8929 /*!
8930  * This method returns the number of values in \a this that are equals to input parameter \a value.
8931  * This method only works for single component array.
8932  *
8933  * \return a value in [ 0, \c this->getNumberOfTuples() )
8934  *
8935  * \throw If \a this is not allocated
8936  *
8937  */
8938 int DataArrayInt::count(int value) const
8939 {
8940   int ret=0;
8941   checkAllocated();
8942   if(getNumberOfComponents()!=1)
8943     throw INTERP_KERNEL::Exception("DataArrayInt::count : must be applied on DataArrayInt with only one component, you can call 'rearrange' method before !");
8944   const int *vals=begin();
8945   int nbOfTuples=getNumberOfTuples();
8946   for(int i=0;i<nbOfTuples;i++,vals++)
8947     if(*vals==value)
8948       ret++;
8949   return ret;
8950 }
8951
8952 /*!
8953  * This method is an extension of DataArrayInt::presenceOfValue method because this method works for DataArrayInt with
8954  * any number of components excepted 0 (an INTERP_KERNEL::Exception is thrown in this case).
8955  * This method searches in \b this is there is a tuple that matched the input parameter \b tupl.
8956  * This method throws an INTERP_KERNEL::Exception if the number of components in \b this mismatches with the size of
8957  * the input vector. An INTERP_KERNEL::Exception is thrown too if \b this is not allocated.
8958  * \sa DataArrayInt::locateTuple
8959  */
8960 bool DataArrayInt::presenceOfTuple(const std::vector<int>& tupl) const
8961 {
8962   return locateTuple(tupl)!=-1;
8963 }
8964
8965
8966 /*!
8967  * Returns \a true if a given value is present within \a this one-dimensional array.
8968  *  \param [in] value - the value to find within \a this array.
8969  *  \return bool - \a true in case if \a value is present within \a this array.
8970  *  \throw If \a this is not allocated.
8971  *  \throw If \a this->getNumberOfComponents() != 1.
8972  *  \sa locateValue()
8973  */
8974 bool DataArrayInt::presenceOfValue(int value) const
8975 {
8976   return locateValue(value)!=-1;
8977 }
8978
8979 /*!
8980  * This method expects to be called when number of components of this is equal to one.
8981  * This method returns true if it exists a tuple so that the value is contained in \b vals.
8982  * If not any tuple contains one of the values contained in 'vals' false is returned.
8983  * \sa DataArrayInt::locateValue
8984  */
8985 bool DataArrayInt::presenceOfValue(const std::vector<int>& vals) const
8986 {
8987   return locateValue(vals)!=-1;
8988 }
8989
8990 /*!
8991  * Accumulates values of each component of \a this array.
8992  *  \param [out] res - an array of length \a this->getNumberOfComponents(), allocated 
8993  *         by the caller, that is filled by this method with sum value for each
8994  *         component.
8995  *  \throw If \a this is not allocated.
8996  */
8997 void DataArrayInt::accumulate(int *res) const
8998 {
8999   checkAllocated();
9000   const int *ptr=getConstPointer();
9001   int nbTuple=getNumberOfTuples();
9002   int nbComps=getNumberOfComponents();
9003   std::fill(res,res+nbComps,0);
9004   for(int i=0;i<nbTuple;i++)
9005     std::transform(ptr+i*nbComps,ptr+(i+1)*nbComps,res,res,std::plus<int>());
9006 }
9007
9008 int DataArrayInt::accumulate(int compId) const
9009 {
9010   checkAllocated();
9011   const int *ptr=getConstPointer();
9012   int nbTuple=getNumberOfTuples();
9013   int nbComps=getNumberOfComponents();
9014   if(compId<0 || compId>=nbComps)
9015     throw INTERP_KERNEL::Exception("DataArrayInt::accumulate : Invalid compId specified : No such nb of components !");
9016   int ret=0;
9017   for(int i=0;i<nbTuple;i++)
9018     ret+=ptr[i*nbComps+compId];
9019   return ret;
9020 }
9021
9022 /*!
9023  * This method accumulate using addition tuples in \a this using input index array [ \a bgOfIndex, \a endOfIndex ).
9024  * The returned array will have same number of components than \a this and number of tuples equal to
9025  * \c std::distance(bgOfIndex,endOfIndex) \b minus \b one.
9026  *
9027  * The input index array is expected to be ascendingly sorted in which the all referenced ids should be in [0, \c this->getNumberOfTuples).
9028  *
9029  * \param [in] bgOfIndex - begin (included) of the input index array.
9030  * \param [in] endOfIndex - end (excluded) of the input index array.
9031  * \return DataArrayInt * - the new instance having the same number of components than \a this.
9032  * 
9033  * \throw If bgOfIndex or end is NULL.
9034  * \throw If input index array is not ascendingly sorted.
9035  * \throw If there is an id in [ \a bgOfIndex, \a endOfIndex ) not in [0, \c this->getNumberOfTuples).
9036  * \throw If std::distance(bgOfIndex,endOfIndex)==0.
9037  */
9038 DataArrayInt *DataArrayInt::accumulatePerChunck(const int *bgOfIndex, const int *endOfIndex) const
9039 {
9040   if(!bgOfIndex || !endOfIndex)
9041     throw INTERP_KERNEL::Exception("DataArrayInt::accumulatePerChunck : input pointer NULL !");
9042   checkAllocated();
9043   int nbCompo=getNumberOfComponents();
9044   int nbOfTuples=getNumberOfTuples();
9045   int sz=(int)std::distance(bgOfIndex,endOfIndex);
9046   if(sz<1)
9047     throw INTERP_KERNEL::Exception("DataArrayInt::accumulatePerChunck : invalid size of input index array !");
9048   sz--;
9049   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(sz,nbCompo);
9050   const int *w=bgOfIndex;
9051   if(*w<0 || *w>=nbOfTuples)
9052     throw INTERP_KERNEL::Exception("DataArrayInt::accumulatePerChunck : The first element of the input index not in [0,nbOfTuples) !");
9053   const int *srcPt=begin()+(*w)*nbCompo;
9054   int *tmp=ret->getPointer();
9055   for(int i=0;i<sz;i++,tmp+=nbCompo,w++)
9056     {
9057       std::fill(tmp,tmp+nbCompo,0);
9058       if(w[1]>=w[0])
9059         {
9060           for(int j=w[0];j<w[1];j++,srcPt+=nbCompo)
9061             {
9062               if(j>=0 && j<nbOfTuples)
9063                 std::transform(srcPt,srcPt+nbCompo,tmp,tmp,std::plus<int>());
9064               else
9065                 {
9066                   std::ostringstream oss; oss << "DataArrayInt::accumulatePerChunck : At rank #" << i << " the input index array points to id " << j << " should be in [0," << nbOfTuples << ") !";
9067                   throw INTERP_KERNEL::Exception(oss.str().c_str());
9068                 }
9069             }
9070         }
9071       else
9072         {
9073           std::ostringstream oss; oss << "DataArrayInt::accumulatePerChunck : At rank #" << i << " the input index array is not in ascendingly sorted.";
9074           throw INTERP_KERNEL::Exception(oss.str().c_str());
9075         }
9076     }
9077   ret->copyStringInfoFrom(*this);
9078   return ret.retn();
9079 }
9080
9081 /*!
9082  * Returns a new DataArrayInt by concatenating two given arrays, so that (1) the number
9083  * of tuples in the result array is <em> a1->getNumberOfTuples() + a2->getNumberOfTuples() -
9084  * offsetA2</em> and (2)
9085  * the number of component in the result array is same as that of each of given arrays.
9086  * First \a offsetA2 tuples of \a a2 are skipped and thus are missing from the result array.
9087  * Info on components is copied from the first of the given arrays. Number of components
9088  * in the given arrays must be the same.
9089  *  \param [in] a1 - an array to include in the result array.
9090  *  \param [in] a2 - another array to include in the result array.
9091  *  \param [in] offsetA2 - number of tuples of \a a2 to skip.
9092  *  \return DataArrayInt * - the new instance of DataArrayInt.
9093  *          The caller is to delete this result array using decrRef() as it is no more
9094  *          needed.
9095  *  \throw If either \a a1 or \a a2 is NULL.
9096  *  \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents().
9097  */
9098 DataArrayInt *DataArrayInt::Aggregate(const DataArrayInt *a1, const DataArrayInt *a2, int offsetA2)
9099 {
9100   if(!a1 || !a2)
9101     throw INTERP_KERNEL::Exception("DataArrayInt::Aggregate : input DataArrayInt instance is NULL !");
9102   int nbOfComp=a1->getNumberOfComponents();
9103   if(nbOfComp!=a2->getNumberOfComponents())
9104     throw INTERP_KERNEL::Exception("Nb of components mismatch for array Aggregation !");
9105   int nbOfTuple1=a1->getNumberOfTuples();
9106   int nbOfTuple2=a2->getNumberOfTuples();
9107   DataArrayInt *ret=DataArrayInt::New();
9108   ret->alloc(nbOfTuple1+nbOfTuple2-offsetA2,nbOfComp);
9109   int *pt=std::copy(a1->getConstPointer(),a1->getConstPointer()+nbOfTuple1*nbOfComp,ret->getPointer());
9110   std::copy(a2->getConstPointer()+offsetA2*nbOfComp,a2->getConstPointer()+nbOfTuple2*nbOfComp,pt);
9111   ret->copyStringInfoFrom(*a1);
9112   return ret;
9113 }
9114
9115 /*!
9116  * Returns a new DataArrayInt by concatenating all given arrays, so that (1) the number
9117  * of tuples in the result array is a sum of the number of tuples of given arrays and (2)
9118  * the number of component in the result array is same as that of each of given arrays.
9119  * Info on components is copied from the first of the given arrays. Number of components
9120  * in the given arrays must be  the same.
9121  * If the number of non null of elements in \a arr is equal to one the returned object is a copy of it
9122  * not the object itself.
9123  *  \param [in] arr - a sequence of arrays to include in the result array.
9124  *  \return DataArrayInt * - the new instance of DataArrayInt.
9125  *          The caller is to delete this result array using decrRef() as it is no more
9126  *          needed.
9127  *  \throw If all arrays within \a arr are NULL.
9128  *  \throw If getNumberOfComponents() of arrays within \a arr.
9129  */
9130 DataArrayInt *DataArrayInt::Aggregate(const std::vector<const DataArrayInt *>& arr)
9131 {
9132   std::vector<const DataArrayInt *> a;
9133   for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
9134     if(*it4)
9135       a.push_back(*it4);
9136   if(a.empty())
9137     throw INTERP_KERNEL::Exception("DataArrayInt::Aggregate : input list must be NON EMPTY !");
9138   std::vector<const DataArrayInt *>::const_iterator it=a.begin();
9139   int nbOfComp=(*it)->getNumberOfComponents();
9140   int nbt=(*it++)->getNumberOfTuples();
9141   for(int i=1;it!=a.end();it++,i++)
9142     {
9143       if((*it)->getNumberOfComponents()!=nbOfComp)
9144         throw INTERP_KERNEL::Exception("DataArrayInt::Aggregate : Nb of components mismatch for array aggregation !");
9145       nbt+=(*it)->getNumberOfTuples();
9146     }
9147   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
9148   ret->alloc(nbt,nbOfComp);
9149   int *pt=ret->getPointer();
9150   for(it=a.begin();it!=a.end();it++)
9151     pt=std::copy((*it)->getConstPointer(),(*it)->getConstPointer()+(*it)->getNbOfElems(),pt);
9152   ret->copyStringInfoFrom(*(a[0]));
9153   return ret.retn();
9154 }
9155
9156 /*!
9157  * This method takes as input a list of DataArrayInt instances \a arrs that represent each a packed index arrays.
9158  * A packed index array is an allocated array with one component, and at least one tuple. The first element
9159  * of each array in \a arrs must be 0. Each array in \a arrs is expected to be increasingly monotonic.
9160  * 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.
9161  * 
9162  * \return DataArrayInt * - a new object to be managed by the caller.
9163  */
9164 DataArrayInt *DataArrayInt::AggregateIndexes(const std::vector<const DataArrayInt *>& arrs)
9165 {
9166   int retSz=1;
9167   for(std::vector<const DataArrayInt *>::const_iterator it4=arrs.begin();it4!=arrs.end();it4++)
9168     {
9169       if(*it4)
9170         {
9171           (*it4)->checkAllocated();
9172           if((*it4)->getNumberOfComponents()!=1)
9173             {
9174               std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a DataArrayInt instance with nb of compo != 1 at pos " << std::distance(arrs.begin(),it4) << " !";
9175               throw INTERP_KERNEL::Exception(oss.str().c_str());
9176             }
9177           int nbTupl=(*it4)->getNumberOfTuples();
9178           if(nbTupl<1)
9179             {
9180               std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a DataArrayInt instance with nb of tuples < 1 at pos " << std::distance(arrs.begin(),it4) << " !";
9181               throw INTERP_KERNEL::Exception(oss.str().c_str());
9182             }
9183           if((*it4)->front()!=0)
9184             {
9185               std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a DataArrayInt instance with front value != 0 at pos " << std::distance(arrs.begin(),it4) << " !";
9186               throw INTERP_KERNEL::Exception(oss.str().c_str());
9187             }
9188           retSz+=nbTupl-1;
9189         }
9190       else
9191         {
9192           std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a null instance at pos " << std::distance(arrs.begin(),it4) << " !";
9193           throw INTERP_KERNEL::Exception(oss.str().c_str());
9194         }
9195     }
9196   if(arrs.empty())
9197     throw INTERP_KERNEL::Exception("DataArrayInt::AggregateIndexes : input list must be NON EMPTY !");
9198   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
9199   ret->alloc(retSz,1);
9200   int *pt=ret->getPointer(); *pt++=0;
9201   for(std::vector<const DataArrayInt *>::const_iterator it=arrs.begin();it!=arrs.end();it++)
9202     pt=std::transform((*it)->begin()+1,(*it)->end(),pt,std::bind2nd(std::plus<int>(),pt[-1]));
9203   ret->copyStringInfoFrom(*(arrs[0]));
9204   return ret.retn();
9205 }
9206
9207 /*!
9208  * Returns the maximal value and its location within \a this one-dimensional array.
9209  *  \param [out] tupleId - index of the tuple holding the maximal value.
9210  *  \return int - the maximal value among all values of \a this array.
9211  *  \throw If \a this->getNumberOfComponents() != 1
9212  *  \throw If \a this->getNumberOfTuples() < 1
9213  */
9214 int DataArrayInt::getMaxValue(int& tupleId) const
9215 {
9216   checkAllocated();
9217   if(getNumberOfComponents()!=1)
9218     throw INTERP_KERNEL::Exception("DataArrayInt::getMaxValue : must be applied on DataArrayInt with only one component !");
9219   int nbOfTuples=getNumberOfTuples();
9220   if(nbOfTuples<=0)
9221     throw INTERP_KERNEL::Exception("DataArrayInt::getMaxValue : array exists but number of tuples must be > 0 !");
9222   const int *vals=getConstPointer();
9223   const int *loc=std::max_element(vals,vals+nbOfTuples);
9224   tupleId=(int)std::distance(vals,loc);
9225   return *loc;
9226 }
9227
9228 /*!
9229  * Returns the maximal value within \a this array that is allowed to have more than
9230  *  one component.
9231  *  \return int - the maximal value among all values of \a this array.
9232  *  \throw If \a this is not allocated.
9233  */
9234 int DataArrayInt::getMaxValueInArray() const
9235 {
9236   checkAllocated();
9237   const int *loc=std::max_element(begin(),end());
9238   return *loc;
9239 }
9240
9241 /*!
9242  * Returns the minimal value and its location within \a this one-dimensional array.
9243  *  \param [out] tupleId - index of the tuple holding the minimal value.
9244  *  \return int - the minimal value among all values of \a this array.
9245  *  \throw If \a this->getNumberOfComponents() != 1
9246  *  \throw If \a this->getNumberOfTuples() < 1
9247  */
9248 int DataArrayInt::getMinValue(int& tupleId) const
9249 {
9250   checkAllocated();
9251   if(getNumberOfComponents()!=1)
9252     throw INTERP_KERNEL::Exception("DataArrayInt::getMaxValue : must be applied on DataArrayInt with only one component !");
9253   int nbOfTuples=getNumberOfTuples();
9254   if(nbOfTuples<=0)
9255     throw INTERP_KERNEL::Exception("DataArrayInt::getMaxValue : array exists but number of tuples must be > 0 !");
9256   const int *vals=getConstPointer();
9257   const int *loc=std::min_element(vals,vals+nbOfTuples);
9258   tupleId=(int)std::distance(vals,loc);
9259   return *loc;
9260 }
9261
9262 /*!
9263  * Returns the minimal value within \a this array that is allowed to have more than
9264  *  one component.
9265  *  \return int - the minimal value among all values of \a this array.
9266  *  \throw If \a this is not allocated.
9267  */
9268 int DataArrayInt::getMinValueInArray() const
9269 {
9270   checkAllocated();
9271   const int *loc=std::min_element(begin(),end());
9272   return *loc;
9273 }
9274
9275 /*!
9276  * Returns in a single walk in \a this the min value and the max value in \a this.
9277  * \a this is expected to be single component array.
9278  *
9279  * \param [out] minValue - the min value in \a this.
9280  * \param [out] maxValue - the max value in \a this.
9281  *
9282  * \sa getMinValueInArray, getMinValue, getMaxValueInArray, getMaxValue
9283  */
9284 void DataArrayInt::getMinMaxValues(int& minValue, int& maxValue) const
9285 {
9286   checkAllocated();
9287   if(getNumberOfComponents()!=1)
9288     throw INTERP_KERNEL::Exception("DataArrayInt::getMinMaxValues : must be applied on DataArrayInt with only one component !");
9289   int nbTuples(getNumberOfTuples());
9290   const int *pt(begin());
9291   minValue=std::numeric_limits<int>::max(); maxValue=-std::numeric_limits<int>::max();
9292   for(int i=0;i<nbTuples;i++,pt++)
9293     {
9294       if(*pt<minValue)
9295         minValue=*pt;
9296       if(*pt>maxValue)
9297         maxValue=*pt;
9298     }
9299 }
9300
9301 /*!
9302  * Converts every value of \a this array to its absolute value.
9303  * \b WARNING this method is non const. If a new DataArrayInt instance should be built containing the result of abs DataArrayInt::computeAbs
9304  * should be called instead.
9305  *
9306  * \throw If \a this is not allocated.
9307  * \sa DataArrayInt::computeAbs
9308  */
9309 void DataArrayInt::abs()
9310 {
9311   checkAllocated();
9312   int *ptr(getPointer());
9313   std::size_t nbOfElems(getNbOfElems());
9314   std::transform(ptr,ptr+nbOfElems,ptr,std::ptr_fun<int,int>(std::abs));
9315   declareAsNew();
9316 }
9317
9318 /*!
9319  * This method builds a new instance of \a this object containing the result of std::abs applied of all elements in \a this.
9320  * This method is a const method (that do not change any values in \a this) contrary to  DataArrayInt::abs method.
9321  *
9322  * \return DataArrayInt * - the new instance of DataArrayInt containing the
9323  *         same number of tuples and component as \a this array.
9324  *         The caller is to delete this result array using decrRef() as it is no more
9325  *         needed.
9326  * \throw If \a this is not allocated.
9327  * \sa DataArrayInt::abs
9328  */
9329 DataArrayInt *DataArrayInt::computeAbs() const
9330 {
9331   checkAllocated();
9332   DataArrayInt *newArr(DataArrayInt::New());
9333   int nbOfTuples(getNumberOfTuples());
9334   int nbOfComp(getNumberOfComponents());
9335   newArr->alloc(nbOfTuples,nbOfComp);
9336   std::transform(begin(),end(),newArr->getPointer(),std::ptr_fun<int,int>(std::abs));
9337   newArr->copyStringInfoFrom(*this);
9338   return newArr;
9339 }
9340
9341 /*!
9342  * Apply a liner function to a given component of \a this array, so that
9343  * an array element <em>(x)</em> becomes \f$ a * x + b \f$.
9344  *  \param [in] a - the first coefficient of the function.
9345  *  \param [in] b - the second coefficient of the function.
9346  *  \param [in] compoId - the index of component to modify.
9347  *  \throw If \a this is not allocated.
9348  */
9349 void DataArrayInt::applyLin(int a, int b, int compoId)
9350 {
9351   checkAllocated();
9352   int *ptr=getPointer()+compoId;
9353   int nbOfComp=getNumberOfComponents();
9354   int nbOfTuple=getNumberOfTuples();
9355   for(int i=0;i<nbOfTuple;i++,ptr+=nbOfComp)
9356     *ptr=a*(*ptr)+b;
9357   declareAsNew();
9358 }
9359
9360 /*!
9361  * Apply a liner function to all elements of \a this array, so that
9362  * an element _x_ becomes \f$ a * x + b \f$.
9363  *  \param [in] a - the first coefficient of the function.
9364  *  \param [in] b - the second coefficient of the function.
9365  *  \throw If \a this is not allocated.
9366  */
9367 void DataArrayInt::applyLin(int a, int b)
9368 {
9369   checkAllocated();
9370   int *ptr=getPointer();
9371   std::size_t nbOfElems=getNbOfElems();
9372   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
9373     *ptr=a*(*ptr)+b;
9374   declareAsNew();
9375 }
9376
9377 /*!
9378  * Returns a full copy of \a this array except that sign of all elements is reversed.
9379  *  \return DataArrayInt * - the new instance of DataArrayInt containing the
9380  *          same number of tuples and component as \a this array.
9381  *          The caller is to delete this result array using decrRef() as it is no more
9382  *          needed.
9383  *  \throw If \a this is not allocated.
9384  */
9385 DataArrayInt *DataArrayInt::negate() const
9386 {
9387   checkAllocated();
9388   DataArrayInt *newArr=DataArrayInt::New();
9389   int nbOfTuples=getNumberOfTuples();
9390   int nbOfComp=getNumberOfComponents();
9391   newArr->alloc(nbOfTuples,nbOfComp);
9392   const int *cptr=getConstPointer();
9393   std::transform(cptr,cptr+nbOfTuples*nbOfComp,newArr->getPointer(),std::negate<int>());
9394   newArr->copyStringInfoFrom(*this);
9395   return newArr;
9396 }
9397
9398 /*!
9399  * Modify all elements of \a this array, so that
9400  * an element _x_ becomes \f$ numerator / x \f$.
9401  *  \warning If an exception is thrown because of presence of 0 element in \a this 
9402  *           array, all elements processed before detection of the zero element remain
9403  *           modified.
9404  *  \param [in] numerator - the numerator used to modify array elements.
9405  *  \throw If \a this is not allocated.
9406  *  \throw If there is an element equal to 0 in \a this array.
9407  */
9408 void DataArrayInt::applyInv(int numerator)
9409 {
9410   checkAllocated();
9411   int *ptr=getPointer();
9412   std::size_t nbOfElems=getNbOfElems();
9413   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
9414     {
9415       if(*ptr!=0)
9416         {
9417           *ptr=numerator/(*ptr);
9418         }
9419       else
9420         {
9421           std::ostringstream oss; oss << "DataArrayInt::applyInv : presence of null value in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
9422           oss << " !";
9423           throw INTERP_KERNEL::Exception(oss.str().c_str());
9424         }
9425     }
9426   declareAsNew();
9427 }
9428
9429 /*!
9430  * Modify all elements of \a this array, so that
9431  * an element _x_ becomes \f$ x / val \f$.
9432  *  \param [in] val - the denominator used to modify array elements.
9433  *  \throw If \a this is not allocated.
9434  *  \throw If \a val == 0.
9435  */
9436 void DataArrayInt::applyDivideBy(int val)
9437 {
9438   if(val==0)
9439     throw INTERP_KERNEL::Exception("DataArrayInt::applyDivideBy : Trying to divide by 0 !");
9440   checkAllocated();
9441   int *ptr=getPointer();
9442   std::size_t nbOfElems=getNbOfElems();
9443   std::transform(ptr,ptr+nbOfElems,ptr,std::bind2nd(std::divides<int>(),val));
9444   declareAsNew();
9445 }
9446
9447 /*!
9448  * Modify all elements of \a this array, so that
9449  * an element _x_ becomes  <em> x % val </em>.
9450  *  \param [in] val - the divisor used to modify array elements.
9451  *  \throw If \a this is not allocated.
9452  *  \throw If \a val <= 0.
9453  */
9454 void DataArrayInt::applyModulus(int val)
9455 {
9456   if(val<=0)
9457     throw INTERP_KERNEL::Exception("DataArrayInt::applyDivideBy : Trying to operate modulus on value <= 0 !");
9458   checkAllocated();
9459   int *ptr=getPointer();
9460   std::size_t nbOfElems=getNbOfElems();
9461   std::transform(ptr,ptr+nbOfElems,ptr,std::bind2nd(std::modulus<int>(),val));
9462   declareAsNew();
9463 }
9464
9465 /*!
9466  * This method works only on data array with one component.
9467  * This method returns a newly allocated array storing stored ascendantly tuple ids in \b this so that
9468  * this[*id] in [\b vmin,\b vmax)
9469  * 
9470  * \param [in] vmin begin of range. This value is included in range (included).
9471  * \param [in] vmax end of range. This value is \b not included in range (excluded).
9472  * \return a newly allocated data array that the caller should deal with.
9473  *
9474  * \sa DataArrayInt::getIdsNotInRange , DataArrayInt::getIdsStrictlyNegative
9475  */
9476 DataArrayInt *DataArrayInt::getIdsInRange(int vmin, int vmax) const
9477 {
9478   checkAllocated();
9479   if(getNumberOfComponents()!=1)
9480     throw INTERP_KERNEL::Exception("DataArrayInt::getIdsInRange : this must have exactly one component !");
9481   const int *cptr(begin());
9482   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
9483   int nbOfTuples(getNumberOfTuples());
9484   for(int i=0;i<nbOfTuples;i++,cptr++)
9485     if(*cptr>=vmin && *cptr<vmax)
9486       ret->pushBackSilent(i);
9487   return ret.retn();
9488 }
9489
9490 /*!
9491  * This method works only on data array with one component.
9492  * This method returns a newly allocated array storing stored ascendantly tuple ids in \b this so that
9493  * this[*id] \b not in [\b vmin,\b vmax)
9494  * 
9495  * \param [in] vmin begin of range. This value is \b not included in range (excluded).
9496  * \param [in] vmax end of range. This value is included in range (included).
9497  * \return a newly allocated data array that the caller should deal with.
9498  * 
9499  * \sa DataArrayInt::getIdsInRange , DataArrayInt::getIdsStrictlyNegative
9500  */
9501 DataArrayInt *DataArrayInt::getIdsNotInRange(int vmin, int vmax) const
9502 {
9503   checkAllocated();
9504   if(getNumberOfComponents()!=1)
9505     throw INTERP_KERNEL::Exception("DataArrayInt::getIdsNotInRange : this must have exactly one component !");
9506   const int *cptr(getConstPointer());
9507   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
9508   int nbOfTuples(getNumberOfTuples());
9509   for(int i=0;i<nbOfTuples;i++,cptr++)
9510     if(*cptr<vmin || *cptr>=vmax)
9511       ret->pushBackSilent(i);
9512   return ret.retn();
9513 }
9514
9515 /*!
9516  * 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.
9517  *
9518  * \return a newly allocated data array that the caller should deal with.
9519  * \sa DataArrayInt::getIdsInRange
9520  */
9521 DataArrayInt *DataArrayInt::getIdsStrictlyNegative() const
9522 {
9523   checkAllocated();
9524   if(getNumberOfComponents()!=1)
9525     throw INTERP_KERNEL::Exception("DataArrayInt::getIdsStrictlyNegative : this must have exactly one component !");
9526   const int *cptr(getConstPointer());
9527   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
9528   int nbOfTuples(getNumberOfTuples());
9529   for(int i=0;i<nbOfTuples;i++,cptr++)
9530     if(*cptr<0)
9531       ret->pushBackSilent(i);
9532   return ret.retn();
9533 }
9534
9535 /*!
9536  * This method works only on data array with one component.
9537  * 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.
9538  * 
9539  * \param [in] vmin begin of range. This value is included in range (included).
9540  * \param [in] vmax end of range. This value is \b not included in range (excluded).
9541  * \return if all ids in \a this are so that (*this)[i]==i for all i in [ 0, \c this->getNumberOfTuples() ). */
9542 bool DataArrayInt::checkAllIdsInRange(int vmin, int vmax) const
9543 {
9544   checkAllocated();
9545   if(getNumberOfComponents()!=1)
9546     throw INTERP_KERNEL::Exception("DataArrayInt::checkAllIdsInRange : this must have exactly one component !");
9547   int nbOfTuples=getNumberOfTuples();
9548   bool ret=true;
9549   const int *cptr=getConstPointer();
9550   for(int i=0;i<nbOfTuples;i++,cptr++)
9551     {
9552       if(*cptr>=vmin && *cptr<vmax)
9553         { ret=ret && *cptr==i; }
9554       else
9555         {
9556           std::ostringstream oss; oss << "DataArrayInt::checkAllIdsInRange : tuple #" << i << " has value " << *cptr << " should be in [" << vmin << "," << vmax << ") !";
9557           throw INTERP_KERNEL::Exception(oss.str().c_str());
9558         }
9559     }
9560   return ret;
9561 }
9562
9563 /*!
9564  * Modify all elements of \a this array, so that
9565  * an element _x_ becomes <em> val % x </em>.
9566  *  \warning If an exception is thrown because of presence of an element <= 0 in \a this 
9567  *           array, all elements processed before detection of the zero element remain
9568  *           modified.
9569  *  \param [in] val - the divident used to modify array elements.
9570  *  \throw If \a this is not allocated.
9571  *  \throw If there is an element equal to or less than 0 in \a this array.
9572  */
9573 void DataArrayInt::applyRModulus(int val)
9574 {
9575   checkAllocated();
9576   int *ptr=getPointer();
9577   std::size_t nbOfElems=getNbOfElems();
9578   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
9579     {
9580       if(*ptr>0)
9581         {
9582           *ptr=val%(*ptr);
9583         }
9584       else
9585         {
9586           std::ostringstream oss; oss << "DataArrayInt::applyRModulus : presence of value <=0 in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
9587           oss << " !";
9588           throw INTERP_KERNEL::Exception(oss.str().c_str());
9589         }
9590     }
9591   declareAsNew();
9592 }
9593
9594 /*!
9595  * Modify all elements of \a this array, so that
9596  * an element _x_ becomes <em> val ^ x </em>.
9597  *  \param [in] val - the value used to apply pow on all array elements.
9598  *  \throw If \a this is not allocated.
9599  *  \throw If \a val < 0.
9600  */
9601 void DataArrayInt::applyPow(int val)
9602 {
9603   checkAllocated();
9604   if(val<0)
9605     throw INTERP_KERNEL::Exception("DataArrayInt::applyPow : input pow in < 0 !");
9606   int *ptr=getPointer();
9607   std::size_t nbOfElems=getNbOfElems();
9608   if(val==0)
9609     {
9610       std::fill(ptr,ptr+nbOfElems,1);
9611       return ;
9612     }
9613   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
9614     {
9615       int tmp=1;
9616       for(int j=0;j<val;j++)
9617         tmp*=*ptr;
9618       *ptr=tmp;
9619     }
9620   declareAsNew();
9621 }
9622
9623 /*!
9624  * Modify all elements of \a this array, so that
9625  * an element _x_ becomes \f$ val ^ x \f$.
9626  *  \param [in] val - the value used to apply pow on all array elements.
9627  *  \throw If \a this is not allocated.
9628  *  \throw If there is an element < 0 in \a this array.
9629  *  \warning If an exception is thrown because of presence of 0 element in \a this 
9630  *           array, all elements processed before detection of the zero element remain
9631  *           modified.
9632  */
9633 void DataArrayInt::applyRPow(int val)
9634 {
9635   checkAllocated();
9636   int *ptr=getPointer();
9637   std::size_t nbOfElems=getNbOfElems();
9638   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
9639     {
9640       if(*ptr>=0)
9641         {
9642           int tmp=1;
9643           for(int j=0;j<*ptr;j++)
9644             tmp*=val;
9645           *ptr=tmp;
9646         }
9647       else
9648         {
9649           std::ostringstream oss; oss << "DataArrayInt::applyRPow : presence of negative value in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
9650           oss << " !";
9651           throw INTERP_KERNEL::Exception(oss.str().c_str());
9652         }
9653     }
9654   declareAsNew();
9655 }
9656
9657 /*!
9658  * Returns a new DataArrayInt by aggregating two given arrays, so that (1) the number
9659  * of components in the result array is a sum of the number of components of given arrays
9660  * and (2) the number of tuples in the result array is same as that of each of given
9661  * arrays. In other words the i-th tuple of result array includes all components of
9662  * i-th tuples of all given arrays.
9663  * Number of tuples in the given arrays must be the same.
9664  *  \param [in] a1 - an array to include in the result array.
9665  *  \param [in] a2 - another array to include in the result array.
9666  *  \return DataArrayInt * - the new instance of DataArrayInt.
9667  *          The caller is to delete this result array using decrRef() as it is no more
9668  *          needed.
9669  *  \throw If both \a a1 and \a a2 are NULL.
9670  *  \throw If any given array is not allocated.
9671  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
9672  */
9673 DataArrayInt *DataArrayInt::Meld(const DataArrayInt *a1, const DataArrayInt *a2)
9674 {
9675   std::vector<const DataArrayInt *> arr(2);
9676   arr[0]=a1; arr[1]=a2;
9677   return Meld(arr);
9678 }
9679
9680 /*!
9681  * Returns a new DataArrayInt by aggregating all given arrays, so that (1) the number
9682  * of components in the result array is a sum of the number of components of given arrays
9683  * and (2) the number of tuples in the result array is same as that of each of given
9684  * arrays. In other words the i-th tuple of result array includes all components of
9685  * i-th tuples of all given arrays.
9686  * Number of tuples in the given arrays must be  the same.
9687  *  \param [in] arr - a sequence of arrays to include in the result array.
9688  *  \return DataArrayInt * - the new instance of DataArrayInt.
9689  *          The caller is to delete this result array using decrRef() as it is no more
9690  *          needed.
9691  *  \throw If all arrays within \a arr are NULL.
9692  *  \throw If any given array is not allocated.
9693  *  \throw If getNumberOfTuples() of arrays within \a arr is different.
9694  */
9695 DataArrayInt *DataArrayInt::Meld(const std::vector<const DataArrayInt *>& arr)
9696 {
9697   std::vector<const DataArrayInt *> a;
9698   for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
9699     if(*it4)
9700       a.push_back(*it4);
9701   if(a.empty())
9702     throw INTERP_KERNEL::Exception("DataArrayInt::Meld : array must be NON empty !");
9703   std::vector<const DataArrayInt *>::const_iterator it;
9704   for(it=a.begin();it!=a.end();it++)
9705     (*it)->checkAllocated();
9706   it=a.begin();
9707   int nbOfTuples=(*it)->getNumberOfTuples();
9708   std::vector<int> nbc(a.size());
9709   std::vector<const int *> pts(a.size());
9710   nbc[0]=(*it)->getNumberOfComponents();
9711   pts[0]=(*it++)->getConstPointer();
9712   for(int i=1;it!=a.end();it++,i++)
9713     {
9714       if(nbOfTuples!=(*it)->getNumberOfTuples())
9715         throw INTERP_KERNEL::Exception("DataArrayInt::meld : mismatch of number of tuples !");
9716       nbc[i]=(*it)->getNumberOfComponents();
9717       pts[i]=(*it)->getConstPointer();
9718     }
9719   int totalNbOfComp=std::accumulate(nbc.begin(),nbc.end(),0);
9720   DataArrayInt *ret=DataArrayInt::New();
9721   ret->alloc(nbOfTuples,totalNbOfComp);
9722   int *retPtr=ret->getPointer();
9723   for(int i=0;i<nbOfTuples;i++)
9724     for(int j=0;j<(int)a.size();j++)
9725       {
9726         retPtr=std::copy(pts[j],pts[j]+nbc[j],retPtr);
9727         pts[j]+=nbc[j];
9728       }
9729   int k=0;
9730   for(int i=0;i<(int)a.size();i++)
9731     for(int j=0;j<nbc[i];j++,k++)
9732       ret->setInfoOnComponent(k,a[i]->getInfoOnComponent(j));
9733   return ret;
9734 }
9735
9736 /*!
9737  * Returns a new DataArrayInt which is a minimal partition of elements of \a groups.
9738  * The i-th item of the result array is an ID of a set of elements belonging to a
9739  * unique set of groups, which the i-th element is a part of. This set of elements
9740  * belonging to a unique set of groups is called \a family, so the result array contains
9741  * IDs of families each element belongs to.
9742  *
9743  * \b Example: if we have two groups of elements: \a group1 [0,4] and \a group2 [ 0,1,2 ],
9744  * then there are 3 families:
9745  * - \a family1 (with ID 1) contains element [0] belonging to ( \a group1 + \a group2 ),
9746  * - \a family2 (with ID 2) contains elements [4] belonging to ( \a group1 ),
9747  * - \a family3 (with ID 3) contains element [1,2] belonging to ( \a group2 ), <br>
9748  * and the result array contains IDs of families [ 1,3,3,0,2 ]. <br> Note a family ID 0 which
9749  * stands for the element #3 which is in none of groups.
9750  *
9751  *  \param [in] groups - sequence of groups of element IDs.
9752  *  \param [in] newNb - total number of elements; it must be more than max ID of element
9753  *         in \a groups.
9754  *  \param [out] fidsOfGroups - IDs of families the elements of each group belong to.
9755  *  \return DataArrayInt * - a new instance of DataArrayInt containing IDs of families
9756  *         each element with ID from range [0, \a newNb ) belongs to. The caller is to
9757  *         delete this array using decrRef() as it is no more needed.
9758  *  \throw If any element ID in \a groups violates condition ( 0 <= ID < \a newNb ).
9759  */
9760 DataArrayInt *DataArrayInt::MakePartition(const std::vector<const DataArrayInt *>& groups, int newNb, std::vector< std::vector<int> >& fidsOfGroups)
9761 {
9762   std::vector<const DataArrayInt *> groups2;
9763   for(std::vector<const DataArrayInt *>::const_iterator it4=groups.begin();it4!=groups.end();it4++)
9764     if(*it4)
9765       groups2.push_back(*it4);
9766   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
9767   ret->alloc(newNb,1);
9768   int *retPtr=ret->getPointer();
9769   std::fill(retPtr,retPtr+newNb,0);
9770   int fid=1;
9771   for(std::vector<const DataArrayInt *>::const_iterator iter=groups2.begin();iter!=groups2.end();iter++)
9772     {
9773       const int *ptr=(*iter)->getConstPointer();
9774       std::size_t nbOfElem=(*iter)->getNbOfElems();
9775       int sfid=fid;
9776       for(int j=0;j<sfid;j++)
9777         {
9778           bool found=false;
9779           for(std::size_t i=0;i<nbOfElem;i++)
9780             {
9781               if(ptr[i]>=0 && ptr[i]<newNb)
9782                 {
9783                   if(retPtr[ptr[i]]==j)
9784                     {
9785                       retPtr[ptr[i]]=fid;
9786                       found=true;
9787                     }
9788                 }
9789               else
9790                 {
9791                   std::ostringstream oss; oss << "DataArrayInt::MakePartition : In group \"" << (*iter)->getName() << "\" in tuple #" << i << " value = " << ptr[i] << " ! Should be in [0," << newNb;
9792                   oss << ") !";
9793                   throw INTERP_KERNEL::Exception(oss.str().c_str());
9794                 }
9795             }
9796           if(found)
9797             fid++;
9798         }
9799     }
9800   fidsOfGroups.clear();
9801   fidsOfGroups.resize(groups2.size());
9802   int grId=0;
9803   for(std::vector<const DataArrayInt *>::const_iterator iter=groups2.begin();iter!=groups2.end();iter++,grId++)
9804     {
9805       std::set<int> tmp;
9806       const int *ptr=(*iter)->getConstPointer();
9807       std::size_t nbOfElem=(*iter)->getNbOfElems();
9808       for(const int *p=ptr;p!=ptr+nbOfElem;p++)
9809         tmp.insert(retPtr[*p]);
9810       fidsOfGroups[grId].insert(fidsOfGroups[grId].end(),tmp.begin(),tmp.end());
9811     }
9812   return ret.retn();
9813 }
9814
9815 /*!
9816  * Returns a new DataArrayInt which contains all elements of given one-dimensional
9817  * arrays. The result array does not contain any duplicates and its values
9818  * are sorted in ascending order.
9819  *  \param [in] arr - sequence of DataArrayInt's to unite.
9820  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
9821  *         array using decrRef() as it is no more needed.
9822  *  \throw If any \a arr[i] is not allocated.
9823  *  \throw If \a arr[i]->getNumberOfComponents() != 1.
9824  */
9825 DataArrayInt *DataArrayInt::BuildUnion(const std::vector<const DataArrayInt *>& arr)
9826 {
9827   std::vector<const DataArrayInt *> a;
9828   for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
9829     if(*it4)
9830       a.push_back(*it4);
9831   for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
9832     {
9833       (*it)->checkAllocated();
9834       if((*it)->getNumberOfComponents()!=1)
9835         throw INTERP_KERNEL::Exception("DataArrayInt::BuildUnion : only single component allowed !");
9836     }
9837   //
9838   std::set<int> r;
9839   for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
9840     {
9841       const int *pt=(*it)->getConstPointer();
9842       int nbOfTuples=(*it)->getNumberOfTuples();
9843       r.insert(pt,pt+nbOfTuples);
9844     }
9845   DataArrayInt *ret=DataArrayInt::New();
9846   ret->alloc((int)r.size(),1);
9847   std::copy(r.begin(),r.end(),ret->getPointer());
9848   return ret;
9849 }
9850
9851 /*!
9852  * Returns a new DataArrayInt which contains elements present in each of given one-dimensional
9853  * arrays. The result array does not contain any duplicates and its values
9854  * are sorted in ascending order.
9855  *  \param [in] arr - sequence of DataArrayInt's to intersect.
9856  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
9857  *         array using decrRef() as it is no more needed.
9858  *  \throw If any \a arr[i] is not allocated.
9859  *  \throw If \a arr[i]->getNumberOfComponents() != 1.
9860  */
9861 DataArrayInt *DataArrayInt::BuildIntersection(const std::vector<const DataArrayInt *>& arr)
9862 {
9863   std::vector<const DataArrayInt *> a;
9864   for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
9865     if(*it4)
9866       a.push_back(*it4);
9867   for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
9868     {
9869       (*it)->checkAllocated();
9870       if((*it)->getNumberOfComponents()!=1)
9871         throw INTERP_KERNEL::Exception("DataArrayInt::BuildIntersection : only single component allowed !");
9872     }
9873   //
9874   std::set<int> r;
9875   for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
9876     {
9877       const int *pt=(*it)->getConstPointer();
9878       int nbOfTuples=(*it)->getNumberOfTuples();
9879       std::set<int> s1(pt,pt+nbOfTuples);
9880       if(it!=a.begin())
9881         {
9882           std::set<int> r2;
9883           std::set_intersection(r.begin(),r.end(),s1.begin(),s1.end(),inserter(r2,r2.end()));
9884           r=r2;
9885         }
9886       else
9887         r=s1;
9888     }
9889   DataArrayInt *ret(DataArrayInt::New());
9890   ret->alloc((int)r.size(),1);
9891   std::copy(r.begin(),r.end(),ret->getPointer());
9892   return ret;
9893 }
9894
9895 /// @cond INTERNAL
9896 namespace ParaMEDMEMImpl
9897 {
9898   class OpSwitchedOn
9899   {
9900   public:
9901     OpSwitchedOn(int *pt):_pt(pt),_cnt(0) { }
9902     void operator()(const bool& b) { if(b) *_pt++=_cnt; _cnt++; }
9903   private:
9904     int *_pt;
9905     int _cnt;
9906   };
9907
9908   class OpSwitchedOff
9909   {
9910   public:
9911     OpSwitchedOff(int *pt):_pt(pt),_cnt(0) { }
9912     void operator()(const bool& b) { if(!b) *_pt++=_cnt; _cnt++; }
9913   private:
9914     int *_pt;
9915     int _cnt;
9916   };
9917 }
9918 /// @endcond
9919
9920 /*!
9921  * This method returns the list of ids in ascending mode so that v[id]==true.
9922  */
9923 DataArrayInt *DataArrayInt::BuildListOfSwitchedOn(const std::vector<bool>& v)
9924 {
9925   int sz((int)std::count(v.begin(),v.end(),true));
9926   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(sz,1);
9927   std::for_each(v.begin(),v.end(),ParaMEDMEMImpl::OpSwitchedOn(ret->getPointer()));
9928   return ret.retn();
9929 }
9930
9931 /*!
9932  * This method returns the list of ids in ascending mode so that v[id]==false.
9933  */
9934 DataArrayInt *DataArrayInt::BuildListOfSwitchedOff(const std::vector<bool>& v)
9935 {
9936   int sz((int)std::count(v.begin(),v.end(),false));
9937   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(sz,1);
9938   std::for_each(v.begin(),v.end(),ParaMEDMEMImpl::OpSwitchedOff(ret->getPointer()));
9939   return ret.retn();
9940 }
9941
9942 /*!
9943  * This method allows to put a vector of vector of integer into a more compact data stucture (skyline). 
9944  * This method is not available into python because no available optimized data structure available to map std::vector< std::vector<int> >.
9945  *
9946  * \param [in] v the input data structure to be translate into skyline format.
9947  * \param [out] data the first element of the skyline format. The user is expected to deal with newly allocated array.
9948  * \param [out] dataIndex the second element of the skyline format.
9949  */
9950 void DataArrayInt::PutIntoToSkylineFrmt(const std::vector< std::vector<int> >& v, DataArrayInt *& data, DataArrayInt *& dataIndex)
9951 {
9952   int sz((int)v.size());
9953   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret0(DataArrayInt::New()),ret1(DataArrayInt::New());
9954   ret1->alloc(sz+1,1);
9955   int *pt(ret1->getPointer()); *pt=0;
9956   for(int i=0;i<sz;i++,pt++)
9957     pt[1]=pt[0]+(int)v[i].size();
9958   ret0->alloc(ret1->back(),1);
9959   pt=ret0->getPointer();
9960   for(int i=0;i<sz;i++)
9961     pt=std::copy(v[i].begin(),v[i].end(),pt);
9962   data=ret0.retn(); dataIndex=ret1.retn();
9963 }
9964
9965 /*!
9966  * Returns a new DataArrayInt which contains a complement of elements of \a this
9967  * one-dimensional array. I.e. the result array contains all elements from the range [0,
9968  * \a nbOfElement) not present in \a this array.
9969  *  \param [in] nbOfElement - maximal size of the result array.
9970  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
9971  *         array using decrRef() as it is no more needed.
9972  *  \throw If \a this is not allocated.
9973  *  \throw If \a this->getNumberOfComponents() != 1.
9974  *  \throw If any element \a x of \a this array violates condition ( 0 <= \a x < \a
9975  *         nbOfElement ).
9976  */
9977 DataArrayInt *DataArrayInt::buildComplement(int nbOfElement) const
9978 {
9979   checkAllocated();
9980   if(getNumberOfComponents()!=1)
9981     throw INTERP_KERNEL::Exception("DataArrayInt::buildComplement : only single component allowed !");
9982   std::vector<bool> tmp(nbOfElement);
9983   const int *pt=getConstPointer();
9984   int nbOfTuples=getNumberOfTuples();
9985   for(const int *w=pt;w!=pt+nbOfTuples;w++)
9986     if(*w>=0 && *w<nbOfElement)
9987       tmp[*w]=true;
9988     else
9989       throw INTERP_KERNEL::Exception("DataArrayInt::buildComplement : an element is not in valid range : [0,nbOfElement) !");
9990   int nbOfRetVal=(int)std::count(tmp.begin(),tmp.end(),false);
9991   DataArrayInt *ret=DataArrayInt::New();
9992   ret->alloc(nbOfRetVal,1);
9993   int j=0;
9994   int *retPtr=ret->getPointer();
9995   for(int i=0;i<nbOfElement;i++)
9996     if(!tmp[i])
9997       retPtr[j++]=i;
9998   return ret;
9999 }
10000
10001 /*!
10002  * Returns a new DataArrayInt containing elements of \a this one-dimensional missing
10003  * from an \a other one-dimensional array.
10004  *  \param [in] other - a DataArrayInt containing elements not to include in the result array.
10005  *  \return DataArrayInt * - a new instance of DataArrayInt with one component. The
10006  *         caller is to delete this array using decrRef() as it is no more needed.
10007  *  \throw If \a other is NULL.
10008  *  \throw If \a other is not allocated.
10009  *  \throw If \a other->getNumberOfComponents() != 1.
10010  *  \throw If \a this is not allocated.
10011  *  \throw If \a this->getNumberOfComponents() != 1.
10012  *  \sa DataArrayInt::buildSubstractionOptimized()
10013  */
10014 DataArrayInt *DataArrayInt::buildSubstraction(const DataArrayInt *other) const
10015 {
10016   if(!other)
10017     throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstraction : DataArrayInt pointer in input is NULL !");
10018   checkAllocated();
10019   other->checkAllocated();
10020   if(getNumberOfComponents()!=1)
10021     throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstraction : only single component allowed !");
10022   if(other->getNumberOfComponents()!=1)
10023     throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstraction : only single component allowed for other type !");
10024   const int *pt=getConstPointer();
10025   int nbOfTuples=getNumberOfTuples();
10026   std::set<int> s1(pt,pt+nbOfTuples);
10027   pt=other->getConstPointer();
10028   nbOfTuples=other->getNumberOfTuples();
10029   std::set<int> s2(pt,pt+nbOfTuples);
10030   std::vector<int> r;
10031   std::set_difference(s1.begin(),s1.end(),s2.begin(),s2.end(),std::back_insert_iterator< std::vector<int> >(r));
10032   DataArrayInt *ret=DataArrayInt::New();
10033   ret->alloc((int)r.size(),1);
10034   std::copy(r.begin(),r.end(),ret->getPointer());
10035   return ret;
10036 }
10037
10038 /*!
10039  * \a this is expected to have one component and to be sorted ascendingly (as for \a other).
10040  * \a other is expected to be a part of \a this. If not DataArrayInt::buildSubstraction should be called instead.
10041  * 
10042  * \param [in] other an array with one component and expected to be sorted ascendingly.
10043  * \ret list of ids in \a this but not in \a other.
10044  * \sa DataArrayInt::buildSubstraction
10045  */
10046 DataArrayInt *DataArrayInt::buildSubstractionOptimized(const DataArrayInt *other) const
10047 {
10048   static const char *MSG="DataArrayInt::buildSubstractionOptimized : only single component allowed !";
10049   if(!other) throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstractionOptimized : NULL input array !");
10050   checkAllocated(); other->checkAllocated();
10051   if(getNumberOfComponents()!=1) throw INTERP_KERNEL::Exception(MSG);
10052   if(other->getNumberOfComponents()!=1) throw INTERP_KERNEL::Exception(MSG);
10053   const int *pt1Bg(begin()),*pt1End(end()),*pt2Bg(other->begin()),*pt2End(other->end());
10054   const int *work1(pt1Bg),*work2(pt2Bg);
10055   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
10056   for(;work1!=pt1End;work1++)
10057     {
10058       if(work2!=pt2End && *work1==*work2)
10059         work2++;
10060       else
10061         ret->pushBackSilent(*work1);
10062     }
10063   return ret.retn();
10064 }
10065
10066
10067 /*!
10068  * Returns a new DataArrayInt which contains all elements of \a this and a given
10069  * one-dimensional arrays. The result array does not contain any duplicates
10070  * and its values are sorted in ascending order.
10071  *  \param [in] other - an array to unite with \a this one.
10072  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
10073  *         array using decrRef() as it is no more needed.
10074  *  \throw If \a this or \a other is not allocated.
10075  *  \throw If \a this->getNumberOfComponents() != 1.
10076  *  \throw If \a other->getNumberOfComponents() != 1.
10077  */
10078 DataArrayInt *DataArrayInt::buildUnion(const DataArrayInt *other) const
10079 {
10080   std::vector<const DataArrayInt *>arrs(2);
10081   arrs[0]=this; arrs[1]=other;
10082   return BuildUnion(arrs);
10083 }
10084
10085
10086 /*!
10087  * Returns a new DataArrayInt which contains elements present in both \a this and a given
10088  * one-dimensional arrays. The result array does not contain any duplicates
10089  * and its values are sorted in ascending order.
10090  *  \param [in] other - an array to intersect with \a this one.
10091  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
10092  *         array using decrRef() as it is no more needed.
10093  *  \throw If \a this or \a other is not allocated.
10094  *  \throw If \a this->getNumberOfComponents() != 1.
10095  *  \throw If \a other->getNumberOfComponents() != 1.
10096  */
10097 DataArrayInt *DataArrayInt::buildIntersection(const DataArrayInt *other) const
10098 {
10099   std::vector<const DataArrayInt *>arrs(2);
10100   arrs[0]=this; arrs[1]=other;
10101   return BuildIntersection(arrs);
10102 }
10103
10104 /*!
10105  * This method can be applied on allocated with one component DataArrayInt instance.
10106  * This method is typically relevant for sorted arrays. All consecutive duplicated items in \a this will appear only once in returned DataArrayInt instance.
10107  * 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]
10108  * 
10109  * \return a newly allocated array that contain the result of the unique operation applied on \a this.
10110  * \throw if \a this is not allocated or if \a this has not exactly one component.
10111  * \sa DataArrayInt::buildUniqueNotSorted
10112  */
10113 DataArrayInt *DataArrayInt::buildUnique() const
10114 {
10115   checkAllocated();
10116   if(getNumberOfComponents()!=1)
10117     throw INTERP_KERNEL::Exception("DataArrayInt::buildUnique : only single component allowed !");
10118   int nbOfTuples=getNumberOfTuples();
10119   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp=deepCpy();
10120   int *data=tmp->getPointer();
10121   int *last=std::unique(data,data+nbOfTuples);
10122   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
10123   ret->alloc(std::distance(data,last),1);
10124   std::copy(data,last,ret->getPointer());
10125   return ret.retn();
10126 }
10127
10128 /*!
10129  * This method can be applied on allocated with one component DataArrayInt instance.
10130  * This method keep elements only once by keeping the same order in \a this that is not expected to be sorted.
10131  *
10132  * \return a newly allocated array that contain the result of the unique operation applied on \a this.
10133  *
10134  * \throw if \a this is not allocated or if \a this has not exactly one component.
10135  *
10136  * \sa DataArrayInt::buildUnique
10137  */
10138 DataArrayInt *DataArrayInt::buildUniqueNotSorted() const
10139 {
10140   checkAllocated();
10141     if(getNumberOfComponents()!=1)
10142       throw INTERP_KERNEL::Exception("DataArrayInt::buildUniqueNotSorted : only single component allowed !");
10143   int minVal,maxVal;
10144   getMinMaxValues(minVal,maxVal);
10145   std::vector<bool> b(maxVal-minVal+1,false);
10146   const int *ptBg(begin()),*endBg(end());
10147   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
10148   for(const int *pt=ptBg;pt!=endBg;pt++)
10149     {
10150       if(!b[*pt-minVal])
10151         {
10152           ret->pushBackSilent(*pt);
10153           b[*pt-minVal]=true;
10154         }
10155     }
10156   ret->copyStringInfoFrom(*this);
10157   return ret.retn();
10158 }
10159
10160 /*!
10161  * Returns a new DataArrayInt which contains size of every of groups described by \a this
10162  * "index" array. Such "index" array is returned for example by 
10163  * \ref ParaMEDMEM::MEDCouplingUMesh::buildDescendingConnectivity
10164  * "MEDCouplingUMesh::buildDescendingConnectivity" and
10165  * \ref ParaMEDMEM::MEDCouplingUMesh::getNodalConnectivityIndex
10166  * "MEDCouplingUMesh::getNodalConnectivityIndex" etc.
10167  * This method preforms the reverse operation of DataArrayInt::computeOffsets2.
10168  *  \return DataArrayInt * - a new instance of DataArrayInt, whose number of tuples
10169  *          equals to \a this->getNumberOfComponents() - 1, and number of components is 1.
10170  *          The caller is to delete this array using decrRef() as it is no more needed. 
10171  *  \throw If \a this is not allocated.
10172  *  \throw If \a this->getNumberOfComponents() != 1.
10173  *  \throw If \a this->getNumberOfTuples() < 2.
10174  *
10175  *  \b Example: <br> 
10176  *         - this contains [1,3,6,7,7,9,15]
10177  *         - result array contains [2,3,1,0,2,6],
10178  *          where 2 = 3 - 1, 3 = 6 - 3, 1 = 7 - 6 etc.
10179  *
10180  * \sa DataArrayInt::computeOffsets2
10181  */
10182 DataArrayInt *DataArrayInt::deltaShiftIndex() const
10183 {
10184   checkAllocated();
10185   if(getNumberOfComponents()!=1)
10186     throw INTERP_KERNEL::Exception("DataArrayInt::deltaShiftIndex : only single component allowed !");
10187   int nbOfTuples=getNumberOfTuples();
10188   if(nbOfTuples<2)
10189     throw INTERP_KERNEL::Exception("DataArrayInt::deltaShiftIndex : 1 tuple at least must be present in 'this' !");
10190   const int *ptr=getConstPointer();
10191   DataArrayInt *ret=DataArrayInt::New();
10192   ret->alloc(nbOfTuples-1,1);
10193   int *out=ret->getPointer();
10194   std::transform(ptr+1,ptr+nbOfTuples,ptr,out,std::minus<int>());
10195   return ret;
10196 }
10197
10198 /*!
10199  * Modifies \a this one-dimensional array so that value of each element \a x
10200  * of \a this array (\a a) is computed as \f$ x_i = \sum_{j=0}^{i-1} a[ j ] \f$.
10201  * Or: for each i>0 new[i]=new[i-1]+old[i-1] for i==0 new[i]=0. Number of tuples
10202  * and components remains the same.<br>
10203  * This method is useful for allToAllV in MPI with contiguous policy. This method
10204  * differs from computeOffsets2() in that the number of tuples is \b not changed by
10205  * this one.
10206  *  \throw If \a this is not allocated.
10207  *  \throw If \a this->getNumberOfComponents() != 1.
10208  *
10209  *  \b Example: <br>
10210  *          - Before \a this contains [3,5,1,2,0,8]
10211  *          - After \a this contains  [0,3,8,9,11,11]<br>
10212  *          Note that the last element 19 = 11 + 8 is missing because size of \a this
10213  *          array is retained and thus there is no space to store the last element.
10214  */
10215 void DataArrayInt::computeOffsets()
10216 {
10217   checkAllocated();
10218   if(getNumberOfComponents()!=1)
10219     throw INTERP_KERNEL::Exception("DataArrayInt::computeOffsets : only single component allowed !");
10220   int nbOfTuples=getNumberOfTuples();
10221   if(nbOfTuples==0)
10222     return ;
10223   int *work=getPointer();
10224   int tmp=work[0];
10225   work[0]=0;
10226   for(int i=1;i<nbOfTuples;i++)
10227     {
10228       int tmp2=work[i];
10229       work[i]=work[i-1]+tmp;
10230       tmp=tmp2;
10231     }
10232   declareAsNew();
10233 }
10234
10235
10236 /*!
10237  * Modifies \a this one-dimensional array so that value of each element \a x
10238  * of \a this array (\a a) is computed as \f$ x_i = \sum_{j=0}^{i-1} a[ j ] \f$.
10239  * Or: for each i>0 new[i]=new[i-1]+old[i-1] for i==0 new[i]=0. Number
10240  * components remains the same and number of tuples is inceamented by one.<br>
10241  * This method is useful for allToAllV in MPI with contiguous policy. This method
10242  * differs from computeOffsets() in that the number of tuples is changed by this one.
10243  * This method preforms the reverse operation of DataArrayInt::deltaShiftIndex.
10244  *  \throw If \a this is not allocated.
10245  *  \throw If \a this->getNumberOfComponents() != 1.
10246  *
10247  *  \b Example: <br>
10248  *          - Before \a this contains [3,5,1,2,0,8]
10249  *          - After \a this contains  [0,3,8,9,11,11,19]<br>
10250  * \sa DataArrayInt::deltaShiftIndex
10251  */
10252 void DataArrayInt::computeOffsets2()
10253 {
10254   checkAllocated();
10255   if(getNumberOfComponents()!=1)
10256     throw INTERP_KERNEL::Exception("DataArrayInt::computeOffsets2 : only single component allowed !");
10257   int nbOfTuples=getNumberOfTuples();
10258   int *ret=(int *)malloc((nbOfTuples+1)*sizeof(int));
10259   if(nbOfTuples==0)
10260     return ;
10261   const int *work=getConstPointer();
10262   ret[0]=0;
10263   for(int i=0;i<nbOfTuples;i++)
10264     ret[i+1]=work[i]+ret[i];
10265   useArray(ret,true,C_DEALLOC,nbOfTuples+1,1);
10266   declareAsNew();
10267 }
10268
10269 /*!
10270  * Returns two new DataArrayInt instances whose contents is computed from that of \a this and \a listOfIds arrays as follows.
10271  * \a this is expected to be an offset format ( as returned by DataArrayInt::computeOffsets2 ) that is to say with one component
10272  * and ** sorted strictly increasingly **. \a listOfIds is expected to be sorted ascendingly (not strictly needed for \a listOfIds).
10273  * This methods searches in \a this, considered as a set of contiguous \c this->getNumberOfComponents() ranges, all ids in \a listOfIds
10274  * filling completely one of the ranges in \a this.
10275  *
10276  * \param [in] listOfIds a list of ids that has to be sorted ascendingly.
10277  * \param [out] rangeIdsFetched the range ids fetched
10278  * \param [out] idsInInputListThatFetch contains the list of ids in \a listOfIds that are \b fully included in a range in \a this. So
10279  *              \a idsInInputListThatFetch is a part of input \a listOfIds.
10280  *
10281  * \sa DataArrayInt::computeOffsets2
10282  *
10283  *  \b Example: <br>
10284  *          - \a this : [0,3,7,9,15,18]
10285  *          - \a listOfIds contains  [0,1,2,3,7,8,15,16,17]
10286  *          - \a rangeIdsFetched result array: [0,2,4]
10287  *          - \a idsInInputListThatFetch result array: [0,1,2,7,8,15,16,17]
10288  * In this example id 3 in input \a listOfIds is alone so it do not appear in output \a idsInInputListThatFetch.
10289  * <br>
10290  */
10291 void DataArrayInt::searchRangesInListOfIds(const DataArrayInt *listOfIds, DataArrayInt *& rangeIdsFetched, DataArrayInt *& idsInInputListThatFetch) const
10292 {
10293   if(!listOfIds)
10294     throw INTERP_KERNEL::Exception("DataArrayInt::searchRangesInListOfIds : input list of ids is null !");
10295   listOfIds->checkAllocated(); checkAllocated();
10296   if(listOfIds->getNumberOfComponents()!=1)
10297     throw INTERP_KERNEL::Exception("DataArrayInt::searchRangesInListOfIds : input list of ids must have exactly one component !");
10298   if(getNumberOfComponents()!=1)
10299     throw INTERP_KERNEL::Exception("DataArrayInt::searchRangesInListOfIds : this must have exactly one component !");
10300   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret0=DataArrayInt::New(); ret0->alloc(0,1);
10301   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret1=DataArrayInt::New(); ret1->alloc(0,1);
10302   const int *tupEnd(listOfIds->end()),*offBg(begin()),*offEnd(end()-1);
10303   const int *tupPtr(listOfIds->begin()),*offPtr(offBg);
10304   while(tupPtr!=tupEnd && offPtr!=offEnd)
10305     {
10306       if(*tupPtr==*offPtr)
10307         {
10308           int i=offPtr[0];
10309           while(i<offPtr[1] && *tupPtr==i && tupPtr!=tupEnd) { i++; tupPtr++; }
10310           if(i==offPtr[1])
10311             {
10312               ret0->pushBackSilent((int)std::distance(offBg,offPtr));
10313               ret1->pushBackValsSilent(tupPtr-(offPtr[1]-offPtr[0]),tupPtr);
10314               offPtr++;
10315             }
10316         }
10317       else
10318         { if(*tupPtr<*offPtr) tupPtr++; else offPtr++; }
10319     }
10320   rangeIdsFetched=ret0.retn();
10321   idsInInputListThatFetch=ret1.retn();
10322 }
10323
10324 /*!
10325  * Returns a new DataArrayInt whose contents is computed from that of \a this and \a
10326  * offsets arrays as follows. \a offsets is a one-dimensional array considered as an
10327  * "index" array of a "iota" array, thus, whose each element gives an index of a group
10328  * beginning within the "iota" array. And \a this is a one-dimensional array
10329  * considered as a selector of groups described by \a offsets to include into the result array.
10330  *  \throw If \a offsets is NULL.
10331  *  \throw If \a offsets is not allocated.
10332  *  \throw If \a offsets->getNumberOfComponents() != 1.
10333  *  \throw If \a offsets is not monotonically increasing.
10334  *  \throw If \a this is not allocated.
10335  *  \throw If \a this->getNumberOfComponents() != 1.
10336  *  \throw If any element of \a this is not a valid index for \a offsets array.
10337  *
10338  *  \b Example: <br>
10339  *          - \a this: [0,2,3]
10340  *          - \a offsets: [0,3,6,10,14,20]
10341  *          - result array: [0,1,2,6,7,8,9,10,11,12,13] == <br>
10342  *            \c range(0,3) + \c range(6,10) + \c range(10,14) ==<br>
10343  *            \c range( \a offsets[ \a this[0] ], offsets[ \a this[0]+1 ]) + 
10344  *            \c range( \a offsets[ \a this[1] ], offsets[ \a this[1]+1 ]) + 
10345  *            \c range( \a offsets[ \a this[2] ], offsets[ \a this[2]+1 ])
10346  */
10347 DataArrayInt *DataArrayInt::buildExplicitArrByRanges(const DataArrayInt *offsets) const
10348 {
10349   if(!offsets)
10350     throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrByRanges : DataArrayInt pointer in input is NULL !");
10351   checkAllocated();
10352   if(getNumberOfComponents()!=1)
10353     throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrByRanges : only single component allowed !");
10354   offsets->checkAllocated();
10355   if(offsets->getNumberOfComponents()!=1)
10356     throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrByRanges : input array should have only single component !");
10357   int othNbTuples=offsets->getNumberOfTuples()-1;
10358   int nbOfTuples=getNumberOfTuples();
10359   int retNbOftuples=0;
10360   const int *work=getConstPointer();
10361   const int *offPtr=offsets->getConstPointer();
10362   for(int i=0;i<nbOfTuples;i++)
10363     {
10364       int val=work[i];
10365       if(val>=0 && val<othNbTuples)
10366         {
10367           int delta=offPtr[val+1]-offPtr[val];
10368           if(delta>=0)
10369             retNbOftuples+=delta;
10370           else
10371             {
10372               std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrByRanges : Tuple #" << val << " of offset array has a delta < 0 !";
10373               throw INTERP_KERNEL::Exception(oss.str().c_str());
10374             }
10375         }
10376       else
10377         {
10378           std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrByRanges : Tuple #" << i << " in this contains " << val;
10379           oss << " whereas offsets array is of size " << othNbTuples+1 << " !";
10380           throw INTERP_KERNEL::Exception(oss.str().c_str());
10381         }
10382     }
10383   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
10384   ret->alloc(retNbOftuples,1);
10385   int *retPtr=ret->getPointer();
10386   for(int i=0;i<nbOfTuples;i++)
10387     {
10388       int val=work[i];
10389       int start=offPtr[val];
10390       int off=offPtr[val+1]-start;
10391       for(int j=0;j<off;j++,retPtr++)
10392         *retPtr=start+j;
10393     }
10394   return ret.retn();
10395 }
10396
10397 /*!
10398  * Returns a new DataArrayInt whose contents is computed using \a this that must be a 
10399  * scaled array (monotonically increasing).
10400 from that of \a this and \a
10401  * offsets arrays as follows. \a offsets is a one-dimensional array considered as an
10402  * "index" array of a "iota" array, thus, whose each element gives an index of a group
10403  * beginning within the "iota" array. And \a this is a one-dimensional array
10404  * considered as a selector of groups described by \a offsets to include into the result array.
10405  *  \throw If \a  is NULL.
10406  *  \throw If \a this is not allocated.
10407  *  \throw If \a this->getNumberOfComponents() != 1.
10408  *  \throw If \a this->getNumberOfTuples() == 0.
10409  *  \throw If \a this is not monotonically increasing.
10410  *  \throw If any element of ids in ( \a bg \a stop \a step ) points outside the scale in \a this.
10411  *
10412  *  \b Example: <br>
10413  *          - \a bg , \a stop and \a step : (0,5,2)
10414  *          - \a this: [0,3,6,10,14,20]
10415  *          - result array: [0,0,0, 2,2,2,2, 4,4,4,4,4,4] == <br>
10416  */
10417 DataArrayInt *DataArrayInt::buildExplicitArrOfSliceOnScaledArr(int bg, int stop, int step) const
10418 {
10419   if(!isAllocated())
10420     throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrOfSliceOnScaledArr : not allocated array !");
10421   if(getNumberOfComponents()!=1)
10422     throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrOfSliceOnScaledArr : number of components is expected to be equal to one !");
10423   int nbOfTuples(getNumberOfTuples());
10424   if(nbOfTuples==0)
10425     throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrOfSliceOnScaledArr : number of tuples must be != 0 !");
10426   const int *ids(begin());
10427   int nbOfEltsInSlc(GetNumberOfItemGivenBESRelative(bg,stop,step,"DataArrayInt::buildExplicitArrOfSliceOnScaledArr")),sz(0),pos(bg);
10428   for(int i=0;i<nbOfEltsInSlc;i++,pos+=step)
10429     {
10430       if(pos>=0 && pos<nbOfTuples-1)
10431         {
10432           int delta(ids[pos+1]-ids[pos]);
10433           sz+=delta;
10434           if(delta<0)
10435             {
10436               std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrOfSliceOnScaledArr : At pos #" << i << " of input slice, value is " << pos << " and at this pos this is not monotonically increasing !";
10437               throw INTERP_KERNEL::Exception(oss.str().c_str());
10438             }          
10439         }
10440       else
10441         {
10442           std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrOfSliceOnScaledArr : At pos #" << i << " of input slice, value is " << pos << " should be in [0," << nbOfTuples-1 << ") !";  
10443           throw INTERP_KERNEL::Exception(oss.str().c_str());
10444         }
10445     }
10446   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(sz,1);
10447   int *retPtr(ret->getPointer());
10448   pos=bg;
10449   for(int i=0;i<nbOfEltsInSlc;i++,pos+=step)
10450     {
10451       int delta(ids[pos+1]-ids[pos]);
10452       for(int j=0;j<delta;j++,retPtr++)
10453         *retPtr=pos;
10454     }
10455   return ret.retn();
10456 }
10457
10458 /*!
10459  * 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.
10460  * 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
10461  * in tuple **i** of returned DataArrayInt.
10462  * If ranges overlapped (in theory it should not) this method do not detect it and always returns the first range.
10463  *
10464  * 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)]
10465  * The return DataArrayInt will contain : **[0,4,1,2,2,3]**
10466  * 
10467  * \param [in] ranges typically come from output of MEDCouplingUMesh::ComputeRangesFromTypeDistribution. Each range is specified like this : 1st component is
10468  *             for lower value included and 2nd component is the upper value of corresponding range **excluded**.
10469  * \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
10470  *        is thrown if no ranges in \a ranges contains value in \a this.
10471  * 
10472  * \sa DataArrayInt::findIdInRangeForEachTuple
10473  */
10474 DataArrayInt *DataArrayInt::findRangeIdForEachTuple(const DataArrayInt *ranges) const
10475 {
10476   if(!ranges)
10477     throw INTERP_KERNEL::Exception("DataArrayInt::findRangeIdForEachTuple : null input pointer !");
10478   if(ranges->getNumberOfComponents()!=2)
10479     throw INTERP_KERNEL::Exception("DataArrayInt::findRangeIdForEachTuple : input DataArrayInt instance should have 2 components !");
10480   checkAllocated();
10481   if(getNumberOfComponents()!=1)
10482     throw INTERP_KERNEL::Exception("DataArrayInt::findRangeIdForEachTuple : this should have only one component !");
10483   int nbTuples=getNumberOfTuples();
10484   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbTuples,1);
10485   int nbOfRanges=ranges->getNumberOfTuples();
10486   const int *rangesPtr=ranges->getConstPointer();
10487   int *retPtr=ret->getPointer();
10488   const int *inPtr=getConstPointer();
10489   for(int i=0;i<nbTuples;i++,retPtr++)
10490     {
10491       int val=inPtr[i];
10492       bool found=false;
10493       for(int j=0;j<nbOfRanges && !found;j++)
10494         if(val>=rangesPtr[2*j] && val<rangesPtr[2*j+1])
10495           { *retPtr=j; found=true; }
10496       if(found)
10497         continue;
10498       else
10499         {
10500           std::ostringstream oss; oss << "DataArrayInt::findRangeIdForEachTuple : tuple #" << i << " not found by any ranges !";
10501           throw INTERP_KERNEL::Exception(oss.str().c_str());
10502         }
10503     }
10504   return ret.retn();
10505 }
10506
10507 /*!
10508  * 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.
10509  * 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
10510  * in tuple **i** of returned DataArrayInt.
10511  * If ranges overlapped (in theory it should not) this method do not detect it and always returns the sub position of the first range.
10512  *
10513  * 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)]
10514  * The return DataArrayInt will contain : **[1,2,4,0,2,2]**
10515  * This method is often called in pair with DataArrayInt::findRangeIdForEachTuple method.
10516  * 
10517  * \param [in] ranges typically come from output of MEDCouplingUMesh::ComputeRangesFromTypeDistribution. Each range is specified like this : 1st component is
10518  *             for lower value included and 2nd component is the upper value of corresponding range **excluded**.
10519  * \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
10520  *        is thrown if no ranges in \a ranges contains value in \a this.
10521  * \sa DataArrayInt::findRangeIdForEachTuple
10522  */
10523 DataArrayInt *DataArrayInt::findIdInRangeForEachTuple(const DataArrayInt *ranges) const
10524 {
10525   if(!ranges)
10526     throw INTERP_KERNEL::Exception("DataArrayInt::findIdInRangeForEachTuple : null input pointer !");
10527   if(ranges->getNumberOfComponents()!=2)
10528     throw INTERP_KERNEL::Exception("DataArrayInt::findIdInRangeForEachTuple : input DataArrayInt instance should have 2 components !");
10529   checkAllocated();
10530   if(getNumberOfComponents()!=1)
10531     throw INTERP_KERNEL::Exception("DataArrayInt::findIdInRangeForEachTuple : this should have only one component !");
10532   int nbTuples=getNumberOfTuples();
10533   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbTuples,1);
10534   int nbOfRanges=ranges->getNumberOfTuples();
10535   const int *rangesPtr=ranges->getConstPointer();
10536   int *retPtr=ret->getPointer();
10537   const int *inPtr=getConstPointer();
10538   for(int i=0;i<nbTuples;i++,retPtr++)
10539     {
10540       int val=inPtr[i];
10541       bool found=false;
10542       for(int j=0;j<nbOfRanges && !found;j++)
10543         if(val>=rangesPtr[2*j] && val<rangesPtr[2*j+1])
10544           { *retPtr=val-rangesPtr[2*j]; found=true; }
10545       if(found)
10546         continue;
10547       else
10548         {
10549           std::ostringstream oss; oss << "DataArrayInt::findIdInRangeForEachTuple : tuple #" << i << " not found by any ranges !";
10550           throw INTERP_KERNEL::Exception(oss.str().c_str());
10551         }
10552     }
10553   return ret.retn();
10554 }
10555
10556 /*!
10557  * \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).
10558  * 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).
10559  * 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 !
10560  * If this method has correctly worked, \a this will be able to be considered as a linked list.
10561  * This method does nothing if number of tuples is lower of equal to 1.
10562  *
10563  * This method is useful for users having an unstructured mesh having only SEG2 to rearrange internaly the connectibity without any coordinates consideration.
10564  *
10565  * \sa MEDCouplingUMesh::orderConsecutiveCells1D
10566  */
10567 void DataArrayInt::sortEachPairToMakeALinkedList()
10568 {
10569   checkAllocated();
10570   if(getNumberOfComponents()!=2)
10571     throw INTERP_KERNEL::Exception("DataArrayInt::sortEachPairToMakeALinkedList : Only works on DataArrayInt instance with nb of components equal to 2 !");
10572   int nbOfTuples(getNumberOfTuples());
10573   if(nbOfTuples<=1)
10574     return ;
10575   int *conn(getPointer());
10576   for(int i=1;i<nbOfTuples;i++,conn+=2)
10577     {
10578       if(i>1)
10579         {
10580           if(conn[2]==conn[3])
10581             {
10582               std::ostringstream oss; oss << "DataArrayInt::sortEachPairToMakeALinkedList : In the tuple #" << i << " presence of a pair filled with same ids !";
10583               throw INTERP_KERNEL::Exception(oss.str().c_str());
10584             }
10585           if(conn[2]!=conn[1] && conn[3]==conn[1] && conn[2]!=conn[0])
10586             std::swap(conn[2],conn[3]);
10587           //not(conn[2]==conn[1] && conn[3]!=conn[1] && conn[3]!=conn[0])
10588           if(conn[2]!=conn[1] || conn[3]==conn[1] || conn[3]==conn[0])
10589             {
10590               std::ostringstream oss; oss << "DataArrayInt::sortEachPairToMakeALinkedList : In the tuple #" << i << " something is invalid !";
10591               throw INTERP_KERNEL::Exception(oss.str().c_str());
10592             }
10593         }
10594       else
10595         {
10596           if(conn[0]==conn[1] || conn[2]==conn[3])
10597             throw INTERP_KERNEL::Exception("DataArrayInt::sortEachPairToMakeALinkedList : In the 2 first tuples presence of a pair filled with same ids !");
10598           int tmp[4];
10599           std::set<int> s;
10600           s.insert(conn,conn+4);
10601           if(s.size()!=3)
10602             throw INTERP_KERNEL::Exception("DataArrayInt::sortEachPairToMakeALinkedList : This can't be considered as a linked list regarding 2 first tuples !");
10603           if(std::count(conn,conn+4,conn[0])==2)
10604             {
10605               tmp[0]=conn[1];
10606               tmp[1]=conn[0];
10607               tmp[2]=conn[0];
10608               if(conn[2]==conn[0])
10609                 { tmp[3]=conn[3]; }
10610               else
10611                 { tmp[3]=conn[2];}
10612               std::copy(tmp,tmp+4,conn);
10613             }
10614         }
10615     }
10616 }
10617
10618 /*!
10619  * 
10620  * \param [in] nbTimes specifies the nb of times each tuples in \a this will be duplicated contiguouly in returned DataArrayInt instance.
10621  *             \a nbTimes  should be at least equal to 1.
10622  * \return a newly allocated DataArrayInt having one component and number of tuples equal to \a nbTimes * \c this->getNumberOfTuples.
10623  * \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.
10624  */
10625 DataArrayInt *DataArrayInt::duplicateEachTupleNTimes(int nbTimes) const
10626 {
10627   checkAllocated();
10628   if(getNumberOfComponents()!=1)
10629     throw INTERP_KERNEL::Exception("DataArrayInt::duplicateEachTupleNTimes : this should have only one component !");
10630   if(nbTimes<1)
10631     throw INTERP_KERNEL::Exception("DataArrayInt::duplicateEachTupleNTimes : nb times should be >= 1 !");
10632   int nbTuples=getNumberOfTuples();
10633   const int *inPtr=getConstPointer();
10634   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbTimes*nbTuples,1);
10635   int *retPtr=ret->getPointer();
10636   for(int i=0;i<nbTuples;i++,inPtr++)
10637     {
10638       int val=*inPtr;
10639       for(int j=0;j<nbTimes;j++,retPtr++)
10640         *retPtr=val;
10641     }
10642   ret->copyStringInfoFrom(*this);
10643   return ret.retn();
10644 }
10645
10646 /*!
10647  * This method returns all different values found in \a this. This method throws if \a this has not been allocated.
10648  * But the number of components can be different from one.
10649  * \return a newly allocated array (that should be dealt by the caller) containing different values in \a this.
10650  */
10651 DataArrayInt *DataArrayInt::getDifferentValues() const
10652 {
10653   checkAllocated();
10654   std::set<int> ret;
10655   ret.insert(begin(),end());
10656   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret2=DataArrayInt::New(); ret2->alloc((int)ret.size(),1);
10657   std::copy(ret.begin(),ret.end(),ret2->getPointer());
10658   return ret2.retn();
10659 }
10660
10661 /*!
10662  * This method is a refinement of DataArrayInt::getDifferentValues because it returns not only different values in \a this but also, for each of
10663  * them it tells which tuple id have this id.
10664  * This method works only on arrays with one component (if it is not the case call DataArrayInt::rearrange(1) ).
10665  * This method returns two arrays having same size.
10666  * 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.
10667  * 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]]
10668  */
10669 std::vector<DataArrayInt *> DataArrayInt::partitionByDifferentValues(std::vector<int>& differentIds) const
10670 {
10671   checkAllocated();
10672   if(getNumberOfComponents()!=1)
10673     throw INTERP_KERNEL::Exception("DataArrayInt::partitionByDifferentValues : this should have only one component !");
10674   int id=0;
10675   std::map<int,int> m,m2,m3;
10676   for(const int *w=begin();w!=end();w++)
10677     m[*w]++;
10678   differentIds.resize(m.size());
10679   std::vector<DataArrayInt *> ret(m.size());
10680   std::vector<int *> retPtr(m.size());
10681   for(std::map<int,int>::const_iterator it=m.begin();it!=m.end();it++,id++)
10682     {
10683       m2[(*it).first]=id;
10684       ret[id]=DataArrayInt::New();
10685       ret[id]->alloc((*it).second,1);
10686       retPtr[id]=ret[id]->getPointer();
10687       differentIds[id]=(*it).first;
10688     }
10689   id=0;
10690   for(const int *w=begin();w!=end();w++,id++)
10691     {
10692       retPtr[m2[*w]][m3[*w]++]=id;
10693     }
10694   return ret;
10695 }
10696
10697 /*!
10698  * This method split ids in [0, \c this->getNumberOfTuples() ) using \a this array as a field of weight (>=0 each).
10699  * The aim of this method is to return a set of \a nbOfSlices chunk of contiguous ids as balanced as possible.
10700  *
10701  * \param [in] nbOfSlices - number of slices expected.
10702  * \return - a vector having a size equal to \a nbOfSlices giving the start (included) and the stop (excluded) of each chunks.
10703  * 
10704  * \sa DataArray::GetSlice
10705  * \throw If \a this is not allocated or not with exactly one component.
10706  * \throw If an element in \a this if < 0.
10707  */
10708 std::vector< std::pair<int,int> > DataArrayInt::splitInBalancedSlices(int nbOfSlices) const
10709 {
10710   if(!isAllocated() || getNumberOfComponents()!=1)
10711     throw INTERP_KERNEL::Exception("DataArrayInt::splitInBalancedSlices : this array should have number of components equal to one and must be allocated !");
10712   if(nbOfSlices<=0)
10713     throw INTERP_KERNEL::Exception("DataArrayInt::splitInBalancedSlices : number of slices must be >= 1 !");
10714   int sum(accumulate(0)),nbOfTuples(getNumberOfTuples());
10715   int sumPerSlc(sum/nbOfSlices),pos(0);
10716   const int *w(begin());
10717   std::vector< std::pair<int,int> > ret(nbOfSlices);
10718   for(int i=0;i<nbOfSlices;i++)
10719     {
10720       std::pair<int,int> p(pos,-1);
10721       int locSum(0);
10722       while(locSum<sumPerSlc && pos<nbOfTuples) { pos++; locSum+=*w++; }
10723       if(i!=nbOfSlices-1)
10724         p.second=pos;
10725       else
10726         p.second=nbOfTuples;
10727       ret[i]=p;
10728     }
10729   return ret;
10730 }
10731
10732 /*!
10733  * Returns a new DataArrayInt that is a sum of two given arrays. There are 3
10734  * valid cases.
10735  * 1.  The arrays have same number of tuples and components. Then each value of
10736  *   the result array (_a_) is a sum of the corresponding values of \a a1 and \a a2,
10737  *   i.e.: _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ i, j ].
10738  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
10739  *   component. Then
10740  *   _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ i, 0 ].
10741  * 3.  The arrays have same number of components and one array, say _a2_, has one
10742  *   tuple. Then
10743  *   _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ 0, j ].
10744  *
10745  * Info on components is copied either from the first array (in the first case) or from
10746  * the array with maximal number of elements (getNbOfElems()).
10747  *  \param [in] a1 - an array to sum up.
10748  *  \param [in] a2 - another array to sum up.
10749  *  \return DataArrayInt * - the new instance of DataArrayInt.
10750  *          The caller is to delete this result array using decrRef() as it is no more
10751  *          needed.
10752  *  \throw If either \a a1 or \a a2 is NULL.
10753  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
10754  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
10755  *         none of them has number of tuples or components equal to 1.
10756  */
10757 DataArrayInt *DataArrayInt::Add(const DataArrayInt *a1, const DataArrayInt *a2)
10758 {
10759   if(!a1 || !a2)
10760     throw INTERP_KERNEL::Exception("DataArrayInt::Add : input DataArrayInt instance is NULL !");
10761   int nbOfTuple=a1->getNumberOfTuples();
10762   int nbOfTuple2=a2->getNumberOfTuples();
10763   int nbOfComp=a1->getNumberOfComponents();
10764   int nbOfComp2=a2->getNumberOfComponents();
10765   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=0;
10766   if(nbOfTuple==nbOfTuple2)
10767     {
10768       if(nbOfComp==nbOfComp2)
10769         {
10770           ret=DataArrayInt::New();
10771           ret->alloc(nbOfTuple,nbOfComp);
10772           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::plus<int>());
10773           ret->copyStringInfoFrom(*a1);
10774         }
10775       else
10776         {
10777           int nbOfCompMin,nbOfCompMax;
10778           const DataArrayInt *aMin, *aMax;
10779           if(nbOfComp>nbOfComp2)
10780             {
10781               nbOfCompMin=nbOfComp2; nbOfCompMax=nbOfComp;
10782               aMin=a2; aMax=a1;
10783             }
10784           else
10785             {
10786               nbOfCompMin=nbOfComp; nbOfCompMax=nbOfComp2;
10787               aMin=a1; aMax=a2;
10788             }
10789           if(nbOfCompMin==1)
10790             {
10791               ret=DataArrayInt::New();
10792               ret->alloc(nbOfTuple,nbOfCompMax);
10793               const int *aMinPtr=aMin->getConstPointer();
10794               const int *aMaxPtr=aMax->getConstPointer();
10795               int *res=ret->getPointer();
10796               for(int i=0;i<nbOfTuple;i++)
10797                 res=std::transform(aMaxPtr+i*nbOfCompMax,aMaxPtr+(i+1)*nbOfCompMax,res,std::bind2nd(std::plus<int>(),aMinPtr[i]));
10798               ret->copyStringInfoFrom(*aMax);
10799             }
10800           else
10801             throw INTERP_KERNEL::Exception("Nb of components mismatch for array Add !");
10802         }
10803     }
10804   else if((nbOfTuple==1 && nbOfTuple2>1) || (nbOfTuple>1 && nbOfTuple2==1))
10805     {
10806       if(nbOfComp==nbOfComp2)
10807         {
10808           int nbOfTupleMax=std::max(nbOfTuple,nbOfTuple2);
10809           const DataArrayInt *aMin=nbOfTuple>nbOfTuple2?a2:a1;
10810           const DataArrayInt *aMax=nbOfTuple>nbOfTuple2?a1:a2;
10811           const int *aMinPtr=aMin->getConstPointer(),*aMaxPtr=aMax->getConstPointer();
10812           ret=DataArrayInt::New();
10813           ret->alloc(nbOfTupleMax,nbOfComp);
10814           int *res=ret->getPointer();
10815           for(int i=0;i<nbOfTupleMax;i++)
10816             res=std::transform(aMaxPtr+i*nbOfComp,aMaxPtr+(i+1)*nbOfComp,aMinPtr,res,std::plus<int>());
10817           ret->copyStringInfoFrom(*aMax);
10818         }
10819       else
10820         throw INTERP_KERNEL::Exception("Nb of components mismatch for array Add !");
10821     }
10822   else
10823     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Add !");
10824   return ret.retn();
10825 }
10826
10827 /*!
10828  * Adds values of another DataArrayInt to values of \a this one. There are 3
10829  * valid cases.
10830  * 1.  The arrays have same number of tuples and components. Then each value of
10831  *   \a other array is added to the corresponding value of \a this array, i.e.:
10832  *   _a_ [ i, j ] += _other_ [ i, j ].
10833  * 2.  The arrays have same number of tuples and \a other array has one component. Then
10834  *   _a_ [ i, j ] += _other_ [ i, 0 ].
10835  * 3.  The arrays have same number of components and \a other array has one tuple. Then
10836  *   _a_ [ i, j ] += _a2_ [ 0, j ].
10837  *
10838  *  \param [in] other - an array to add to \a this one.
10839  *  \throw If \a other is NULL.
10840  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
10841  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
10842  *         \a other has number of both tuples and components not equal to 1.
10843  */
10844 void DataArrayInt::addEqual(const DataArrayInt *other)
10845 {
10846   if(!other)
10847     throw INTERP_KERNEL::Exception("DataArrayInt::addEqual : input DataArrayInt instance is NULL !");
10848   const char *msg="Nb of tuples mismatch for DataArrayInt::addEqual  !";
10849   checkAllocated(); other->checkAllocated();
10850   int nbOfTuple=getNumberOfTuples();
10851   int nbOfTuple2=other->getNumberOfTuples();
10852   int nbOfComp=getNumberOfComponents();
10853   int nbOfComp2=other->getNumberOfComponents();
10854   if(nbOfTuple==nbOfTuple2)
10855     {
10856       if(nbOfComp==nbOfComp2)
10857         {
10858           std::transform(begin(),end(),other->begin(),getPointer(),std::plus<int>());
10859         }
10860       else if(nbOfComp2==1)
10861         {
10862           int *ptr=getPointer();
10863           const int *ptrc=other->getConstPointer();
10864           for(int i=0;i<nbOfTuple;i++)
10865             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::plus<int>(),*ptrc++));
10866         }
10867       else
10868         throw INTERP_KERNEL::Exception(msg);
10869     }
10870   else if(nbOfTuple2==1)
10871     {
10872       if(nbOfComp2==nbOfComp)
10873         {
10874           int *ptr=getPointer();
10875           const int *ptrc=other->getConstPointer();
10876           for(int i=0;i<nbOfTuple;i++)
10877             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::plus<int>());
10878         }
10879       else
10880         throw INTERP_KERNEL::Exception(msg);
10881     }
10882   else
10883     throw INTERP_KERNEL::Exception(msg);
10884   declareAsNew();
10885 }
10886
10887 /*!
10888  * Returns a new DataArrayInt that is a subtraction of two given arrays. There are 3
10889  * valid cases.
10890  * 1.  The arrays have same number of tuples and components. Then each value of
10891  *   the result array (_a_) is a subtraction of the corresponding values of \a a1 and
10892  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ i, j ].
10893  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
10894  *   component. Then
10895  *   _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ i, 0 ].
10896  * 3.  The arrays have same number of components and one array, say _a2_, has one
10897  *   tuple. Then
10898  *   _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ 0, j ].
10899  *
10900  * Info on components is copied either from the first array (in the first case) or from
10901  * the array with maximal number of elements (getNbOfElems()).
10902  *  \param [in] a1 - an array to subtract from.
10903  *  \param [in] a2 - an array to subtract.
10904  *  \return DataArrayInt * - the new instance of DataArrayInt.
10905  *          The caller is to delete this result array using decrRef() as it is no more
10906  *          needed.
10907  *  \throw If either \a a1 or \a a2 is NULL.
10908  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
10909  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
10910  *         none of them has number of tuples or components equal to 1.
10911  */
10912 DataArrayInt *DataArrayInt::Substract(const DataArrayInt *a1, const DataArrayInt *a2)
10913 {
10914   if(!a1 || !a2)
10915     throw INTERP_KERNEL::Exception("DataArrayInt::Substract : input DataArrayInt instance is NULL !");
10916   int nbOfTuple1=a1->getNumberOfTuples();
10917   int nbOfTuple2=a2->getNumberOfTuples();
10918   int nbOfComp1=a1->getNumberOfComponents();
10919   int nbOfComp2=a2->getNumberOfComponents();
10920   if(nbOfTuple2==nbOfTuple1)
10921     {
10922       if(nbOfComp1==nbOfComp2)
10923         {
10924           MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
10925           ret->alloc(nbOfTuple2,nbOfComp1);
10926           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::minus<int>());
10927           ret->copyStringInfoFrom(*a1);
10928           return ret.retn();
10929         }
10930       else if(nbOfComp2==1)
10931         {
10932           MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
10933           ret->alloc(nbOfTuple1,nbOfComp1);
10934           const int *a2Ptr=a2->getConstPointer();
10935           const int *a1Ptr=a1->getConstPointer();
10936           int *res=ret->getPointer();
10937           for(int i=0;i<nbOfTuple1;i++)
10938             res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::minus<int>(),a2Ptr[i]));
10939           ret->copyStringInfoFrom(*a1);
10940           return ret.retn();
10941         }
10942       else
10943         {
10944           a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Substract !");
10945           return 0;
10946         }
10947     }
10948   else if(nbOfTuple2==1)
10949     {
10950       a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Substract !");
10951       MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
10952       ret->alloc(nbOfTuple1,nbOfComp1);
10953       const int *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
10954       int *pt=ret->getPointer();
10955       for(int i=0;i<nbOfTuple1;i++)
10956         pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::minus<int>());
10957       ret->copyStringInfoFrom(*a1);
10958       return ret.retn();
10959     }
10960   else
10961     {
10962       a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Substract !");//will always throw an exception
10963       return 0;
10964     }
10965 }
10966
10967 /*!
10968  * Subtract values of another DataArrayInt from values of \a this one. There are 3
10969  * valid cases.
10970  * 1.  The arrays have same number of tuples and components. Then each value of
10971  *   \a other array is subtracted from the corresponding value of \a this array, i.e.:
10972  *   _a_ [ i, j ] -= _other_ [ i, j ].
10973  * 2.  The arrays have same number of tuples and \a other array has one component. Then
10974  *   _a_ [ i, j ] -= _other_ [ i, 0 ].
10975  * 3.  The arrays have same number of components and \a other array has one tuple. Then
10976  *   _a_ [ i, j ] -= _a2_ [ 0, j ].
10977  *
10978  *  \param [in] other - an array to subtract from \a this one.
10979  *  \throw If \a other is NULL.
10980  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
10981  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
10982  *         \a other has number of both tuples and components not equal to 1.
10983  */
10984 void DataArrayInt::substractEqual(const DataArrayInt *other)
10985 {
10986   if(!other)
10987     throw INTERP_KERNEL::Exception("DataArrayInt::substractEqual : input DataArrayInt instance is NULL !");
10988   const char *msg="Nb of tuples mismatch for DataArrayInt::substractEqual  !";
10989   checkAllocated(); other->checkAllocated();
10990   int nbOfTuple=getNumberOfTuples();
10991   int nbOfTuple2=other->getNumberOfTuples();
10992   int nbOfComp=getNumberOfComponents();
10993   int nbOfComp2=other->getNumberOfComponents();
10994   if(nbOfTuple==nbOfTuple2)
10995     {
10996       if(nbOfComp==nbOfComp2)
10997         {
10998           std::transform(begin(),end(),other->begin(),getPointer(),std::minus<int>());
10999         }
11000       else if(nbOfComp2==1)
11001         {
11002           int *ptr=getPointer();
11003           const int *ptrc=other->getConstPointer();
11004           for(int i=0;i<nbOfTuple;i++)
11005             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::minus<int>(),*ptrc++));
11006         }
11007       else
11008         throw INTERP_KERNEL::Exception(msg);
11009     }
11010   else if(nbOfTuple2==1)
11011     {
11012       int *ptr=getPointer();
11013       const int *ptrc=other->getConstPointer();
11014       for(int i=0;i<nbOfTuple;i++)
11015         std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::minus<int>());
11016     }
11017   else
11018     throw INTERP_KERNEL::Exception(msg);
11019   declareAsNew();
11020 }
11021
11022 /*!
11023  * Returns a new DataArrayInt that is a product of two given arrays. There are 3
11024  * valid cases.
11025  * 1.  The arrays have same number of tuples and components. Then each value of
11026  *   the result array (_a_) is a product of the corresponding values of \a a1 and
11027  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ i, j ].
11028  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
11029  *   component. Then
11030  *   _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ i, 0 ].
11031  * 3.  The arrays have same number of components and one array, say _a2_, has one
11032  *   tuple. Then
11033  *   _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ 0, j ].
11034  *
11035  * Info on components is copied either from the first array (in the first case) or from
11036  * the array with maximal number of elements (getNbOfElems()).
11037  *  \param [in] a1 - a factor array.
11038  *  \param [in] a2 - another factor array.
11039  *  \return DataArrayInt * - the new instance of DataArrayInt.
11040  *          The caller is to delete this result array using decrRef() as it is no more
11041  *          needed.
11042  *  \throw If either \a a1 or \a a2 is NULL.
11043  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
11044  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
11045  *         none of them has number of tuples or components equal to 1.
11046  */
11047 DataArrayInt *DataArrayInt::Multiply(const DataArrayInt *a1, const DataArrayInt *a2)
11048 {
11049   if(!a1 || !a2)
11050     throw INTERP_KERNEL::Exception("DataArrayInt::Multiply : input DataArrayInt instance is NULL !");
11051   int nbOfTuple=a1->getNumberOfTuples();
11052   int nbOfTuple2=a2->getNumberOfTuples();
11053   int nbOfComp=a1->getNumberOfComponents();
11054   int nbOfComp2=a2->getNumberOfComponents();
11055   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=0;
11056   if(nbOfTuple==nbOfTuple2)
11057     {
11058       if(nbOfComp==nbOfComp2)
11059         {
11060           ret=DataArrayInt::New();
11061           ret->alloc(nbOfTuple,nbOfComp);
11062           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::multiplies<int>());
11063           ret->copyStringInfoFrom(*a1);
11064         }
11065       else
11066         {
11067           int nbOfCompMin,nbOfCompMax;
11068           const DataArrayInt *aMin, *aMax;
11069           if(nbOfComp>nbOfComp2)
11070             {
11071               nbOfCompMin=nbOfComp2; nbOfCompMax=nbOfComp;
11072               aMin=a2; aMax=a1;
11073             }
11074           else
11075             {
11076               nbOfCompMin=nbOfComp; nbOfCompMax=nbOfComp2;
11077               aMin=a1; aMax=a2;
11078             }
11079           if(nbOfCompMin==1)
11080             {
11081               ret=DataArrayInt::New();
11082               ret->alloc(nbOfTuple,nbOfCompMax);
11083               const int *aMinPtr=aMin->getConstPointer();
11084               const int *aMaxPtr=aMax->getConstPointer();
11085               int *res=ret->getPointer();
11086               for(int i=0;i<nbOfTuple;i++)
11087                 res=std::transform(aMaxPtr+i*nbOfCompMax,aMaxPtr+(i+1)*nbOfCompMax,res,std::bind2nd(std::multiplies<int>(),aMinPtr[i]));
11088               ret->copyStringInfoFrom(*aMax);
11089             }
11090           else
11091             throw INTERP_KERNEL::Exception("Nb of components mismatch for array Multiply !");
11092         }
11093     }
11094   else if((nbOfTuple==1 && nbOfTuple2>1) || (nbOfTuple>1 && nbOfTuple2==1))
11095     {
11096       if(nbOfComp==nbOfComp2)
11097         {
11098           int nbOfTupleMax=std::max(nbOfTuple,nbOfTuple2);
11099           const DataArrayInt *aMin=nbOfTuple>nbOfTuple2?a2:a1;
11100           const DataArrayInt *aMax=nbOfTuple>nbOfTuple2?a1:a2;
11101           const int *aMinPtr=aMin->getConstPointer(),*aMaxPtr=aMax->getConstPointer();
11102           ret=DataArrayInt::New();
11103           ret->alloc(nbOfTupleMax,nbOfComp);
11104           int *res=ret->getPointer();
11105           for(int i=0;i<nbOfTupleMax;i++)
11106             res=std::transform(aMaxPtr+i*nbOfComp,aMaxPtr+(i+1)*nbOfComp,aMinPtr,res,std::multiplies<int>());
11107           ret->copyStringInfoFrom(*aMax);
11108         }
11109       else
11110         throw INTERP_KERNEL::Exception("Nb of components mismatch for array Multiply !");
11111     }
11112   else
11113     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Multiply !");
11114   return ret.retn();
11115 }
11116
11117
11118 /*!
11119  * Multiply values of another DataArrayInt to values of \a this one. There are 3
11120  * valid cases.
11121  * 1.  The arrays have same number of tuples and components. Then each value of
11122  *   \a other array is multiplied to the corresponding value of \a this array, i.e.:
11123  *   _a_ [ i, j ] *= _other_ [ i, j ].
11124  * 2.  The arrays have same number of tuples and \a other array has one component. Then
11125  *   _a_ [ i, j ] *= _other_ [ i, 0 ].
11126  * 3.  The arrays have same number of components and \a other array has one tuple. Then
11127  *   _a_ [ i, j ] *= _a2_ [ 0, j ].
11128  *
11129  *  \param [in] other - an array to multiply to \a this one.
11130  *  \throw If \a other is NULL.
11131  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
11132  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
11133  *         \a other has number of both tuples and components not equal to 1.
11134  */
11135 void DataArrayInt::multiplyEqual(const DataArrayInt *other)
11136 {
11137   if(!other)
11138     throw INTERP_KERNEL::Exception("DataArrayInt::multiplyEqual : input DataArrayInt instance is NULL !");
11139   const char *msg="Nb of tuples mismatch for DataArrayInt::multiplyEqual !";
11140   checkAllocated(); other->checkAllocated();
11141   int nbOfTuple=getNumberOfTuples();
11142   int nbOfTuple2=other->getNumberOfTuples();
11143   int nbOfComp=getNumberOfComponents();
11144   int nbOfComp2=other->getNumberOfComponents();
11145   if(nbOfTuple==nbOfTuple2)
11146     {
11147       if(nbOfComp==nbOfComp2)
11148         {
11149           std::transform(begin(),end(),other->begin(),getPointer(),std::multiplies<int>());
11150         }
11151       else if(nbOfComp2==1)
11152         {
11153           int *ptr=getPointer();
11154           const int *ptrc=other->getConstPointer();
11155           for(int i=0;i<nbOfTuple;i++)
11156             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::multiplies<int>(),*ptrc++));    
11157         }
11158       else
11159         throw INTERP_KERNEL::Exception(msg);
11160     }
11161   else if(nbOfTuple2==1)
11162     {
11163       if(nbOfComp2==nbOfComp)
11164         {
11165           int *ptr=getPointer();
11166           const int *ptrc=other->getConstPointer();
11167           for(int i=0;i<nbOfTuple;i++)
11168             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::multiplies<int>());
11169         }
11170       else
11171         throw INTERP_KERNEL::Exception(msg);
11172     }
11173   else
11174     throw INTERP_KERNEL::Exception(msg);
11175   declareAsNew();
11176 }
11177
11178
11179 /*!
11180  * Returns a new DataArrayInt that is a division of two given arrays. There are 3
11181  * valid cases.
11182  * 1.  The arrays have same number of tuples and components. Then each value of
11183  *   the result array (_a_) is a division of the corresponding values of \a a1 and
11184  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ i, j ].
11185  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
11186  *   component. Then
11187  *   _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ i, 0 ].
11188  * 3.  The arrays have same number of components and one array, say _a2_, has one
11189  *   tuple. Then
11190  *   _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ 0, j ].
11191  *
11192  * Info on components is copied either from the first array (in the first case) or from
11193  * the array with maximal number of elements (getNbOfElems()).
11194  *  \warning No check of division by zero is performed!
11195  *  \param [in] a1 - a numerator array.
11196  *  \param [in] a2 - a denominator array.
11197  *  \return DataArrayInt * - the new instance of DataArrayInt.
11198  *          The caller is to delete this result array using decrRef() as it is no more
11199  *          needed.
11200  *  \throw If either \a a1 or \a a2 is NULL.
11201  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
11202  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
11203  *         none of them has number of tuples or components equal to 1.
11204  */
11205 DataArrayInt *DataArrayInt::Divide(const DataArrayInt *a1, const DataArrayInt *a2)
11206 {
11207   if(!a1 || !a2)
11208     throw INTERP_KERNEL::Exception("DataArrayInt::Divide : input DataArrayInt instance is NULL !");
11209   int nbOfTuple1=a1->getNumberOfTuples();
11210   int nbOfTuple2=a2->getNumberOfTuples();
11211   int nbOfComp1=a1->getNumberOfComponents();
11212   int nbOfComp2=a2->getNumberOfComponents();
11213   if(nbOfTuple2==nbOfTuple1)
11214     {
11215       if(nbOfComp1==nbOfComp2)
11216         {
11217           MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
11218           ret->alloc(nbOfTuple2,nbOfComp1);
11219           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::divides<int>());
11220           ret->copyStringInfoFrom(*a1);
11221           return ret.retn();
11222         }
11223       else if(nbOfComp2==1)
11224         {
11225           MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
11226           ret->alloc(nbOfTuple1,nbOfComp1);
11227           const int *a2Ptr=a2->getConstPointer();
11228           const int *a1Ptr=a1->getConstPointer();
11229           int *res=ret->getPointer();
11230           for(int i=0;i<nbOfTuple1;i++)
11231             res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::divides<int>(),a2Ptr[i]));
11232           ret->copyStringInfoFrom(*a1);
11233           return ret.retn();
11234         }
11235       else
11236         {
11237           a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Divide !");
11238           return 0;
11239         }
11240     }
11241   else if(nbOfTuple2==1)
11242     {
11243       a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Divide !");
11244       MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
11245       ret->alloc(nbOfTuple1,nbOfComp1);
11246       const int *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
11247       int *pt=ret->getPointer();
11248       for(int i=0;i<nbOfTuple1;i++)
11249         pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::divides<int>());
11250       ret->copyStringInfoFrom(*a1);
11251       return ret.retn();
11252     }
11253   else
11254     {
11255       a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Divide !");//will always throw an exception
11256       return 0;
11257     }
11258 }
11259
11260 /*!
11261  * Divide values of \a this array by values of another DataArrayInt. There are 3
11262  * valid cases.
11263  * 1.  The arrays have same number of tuples and components. Then each value of
11264  *    \a this array is divided by the corresponding value of \a other one, i.e.:
11265  *   _a_ [ i, j ] /= _other_ [ i, j ].
11266  * 2.  The arrays have same number of tuples and \a other array has one component. Then
11267  *   _a_ [ i, j ] /= _other_ [ i, 0 ].
11268  * 3.  The arrays have same number of components and \a other array has one tuple. Then
11269  *   _a_ [ i, j ] /= _a2_ [ 0, j ].
11270  *
11271  *  \warning No check of division by zero is performed!
11272  *  \param [in] other - an array to divide \a this one by.
11273  *  \throw If \a other is NULL.
11274  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
11275  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
11276  *         \a other has number of both tuples and components not equal to 1.
11277  */
11278 void DataArrayInt::divideEqual(const DataArrayInt *other)
11279 {
11280   if(!other)
11281     throw INTERP_KERNEL::Exception("DataArrayInt::divideEqual : input DataArrayInt instance is NULL !");
11282   const char *msg="Nb of tuples mismatch for DataArrayInt::divideEqual !";
11283   checkAllocated(); other->checkAllocated();
11284   int nbOfTuple=getNumberOfTuples();
11285   int nbOfTuple2=other->getNumberOfTuples();
11286   int nbOfComp=getNumberOfComponents();
11287   int nbOfComp2=other->getNumberOfComponents();
11288   if(nbOfTuple==nbOfTuple2)
11289     {
11290       if(nbOfComp==nbOfComp2)
11291         {
11292           std::transform(begin(),end(),other->begin(),getPointer(),std::divides<int>());
11293         }
11294       else if(nbOfComp2==1)
11295         {
11296           int *ptr=getPointer();
11297           const int *ptrc=other->getConstPointer();
11298           for(int i=0;i<nbOfTuple;i++)
11299             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::divides<int>(),*ptrc++));
11300         }
11301       else
11302         throw INTERP_KERNEL::Exception(msg);
11303     }
11304   else if(nbOfTuple2==1)
11305     {
11306       if(nbOfComp2==nbOfComp)
11307         {
11308           int *ptr=getPointer();
11309           const int *ptrc=other->getConstPointer();
11310           for(int i=0;i<nbOfTuple;i++)
11311             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::divides<int>());
11312         }
11313       else
11314         throw INTERP_KERNEL::Exception(msg);
11315     }
11316   else
11317     throw INTERP_KERNEL::Exception(msg);
11318   declareAsNew();
11319 }
11320
11321
11322 /*!
11323  * Returns a new DataArrayInt that is a modulus of two given arrays. There are 3
11324  * valid cases.
11325  * 1.  The arrays have same number of tuples and components. Then each value of
11326  *   the result array (_a_) is a division of the corresponding values of \a a1 and
11327  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] % _a2_ [ i, j ].
11328  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
11329  *   component. Then
11330  *   _a_ [ i, j ] = _a1_ [ i, j ] % _a2_ [ i, 0 ].
11331  * 3.  The arrays have same number of components and one array, say _a2_, has one
11332  *   tuple. Then
11333  *   _a_ [ i, j ] = _a1_ [ i, j ] % _a2_ [ 0, j ].
11334  *
11335  * Info on components is copied either from the first array (in the first case) or from
11336  * the array with maximal number of elements (getNbOfElems()).
11337  *  \warning No check of division by zero is performed!
11338  *  \param [in] a1 - a dividend array.
11339  *  \param [in] a2 - a divisor array.
11340  *  \return DataArrayInt * - the new instance of DataArrayInt.
11341  *          The caller is to delete this result array using decrRef() as it is no more
11342  *          needed.
11343  *  \throw If either \a a1 or \a a2 is NULL.
11344  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
11345  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
11346  *         none of them has number of tuples or components equal to 1.
11347  */
11348 DataArrayInt *DataArrayInt::Modulus(const DataArrayInt *a1, const DataArrayInt *a2)
11349 {
11350   if(!a1 || !a2)
11351     throw INTERP_KERNEL::Exception("DataArrayInt::Modulus : input DataArrayInt instance is NULL !");
11352   int nbOfTuple1=a1->getNumberOfTuples();
11353   int nbOfTuple2=a2->getNumberOfTuples();
11354   int nbOfComp1=a1->getNumberOfComponents();
11355   int nbOfComp2=a2->getNumberOfComponents();
11356   if(nbOfTuple2==nbOfTuple1)
11357     {
11358       if(nbOfComp1==nbOfComp2)
11359         {
11360           MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
11361           ret->alloc(nbOfTuple2,nbOfComp1);
11362           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::modulus<int>());
11363           ret->copyStringInfoFrom(*a1);
11364           return ret.retn();
11365         }
11366       else if(nbOfComp2==1)
11367         {
11368           MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
11369           ret->alloc(nbOfTuple1,nbOfComp1);
11370           const int *a2Ptr=a2->getConstPointer();
11371           const int *a1Ptr=a1->getConstPointer();
11372           int *res=ret->getPointer();
11373           for(int i=0;i<nbOfTuple1;i++)
11374             res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::modulus<int>(),a2Ptr[i]));
11375           ret->copyStringInfoFrom(*a1);
11376           return ret.retn();
11377         }
11378       else
11379         {
11380           a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Modulus !");
11381           return 0;
11382         }
11383     }
11384   else if(nbOfTuple2==1)
11385     {
11386       a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Modulus !");
11387       MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
11388       ret->alloc(nbOfTuple1,nbOfComp1);
11389       const int *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
11390       int *pt=ret->getPointer();
11391       for(int i=0;i<nbOfTuple1;i++)
11392         pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::modulus<int>());
11393       ret->copyStringInfoFrom(*a1);
11394       return ret.retn();
11395     }
11396   else
11397     {
11398       a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Modulus !");//will always throw an exception
11399       return 0;
11400     }
11401 }
11402
11403 /*!
11404  * Modify \a this array so that each value becomes a modulus of division of this value by
11405  * a value of another DataArrayInt. There are 3 valid cases.
11406  * 1.  The arrays have same number of tuples and components. Then each value of
11407  *    \a this array is divided by the corresponding value of \a other one, i.e.:
11408  *   _a_ [ i, j ] %= _other_ [ i, j ].
11409  * 2.  The arrays have same number of tuples and \a other array has one component. Then
11410  *   _a_ [ i, j ] %= _other_ [ i, 0 ].
11411  * 3.  The arrays have same number of components and \a other array has one tuple. Then
11412  *   _a_ [ i, j ] %= _a2_ [ 0, j ].
11413  *
11414  *  \warning No check of division by zero is performed!
11415  *  \param [in] other - a divisor array.
11416  *  \throw If \a other is NULL.
11417  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
11418  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
11419  *         \a other has number of both tuples and components not equal to 1.
11420  */
11421 void DataArrayInt::modulusEqual(const DataArrayInt *other)
11422 {
11423   if(!other)
11424     throw INTERP_KERNEL::Exception("DataArrayInt::modulusEqual : input DataArrayInt instance is NULL !");
11425   const char *msg="Nb of tuples mismatch for DataArrayInt::modulusEqual !";
11426   checkAllocated(); other->checkAllocated();
11427   int nbOfTuple=getNumberOfTuples();
11428   int nbOfTuple2=other->getNumberOfTuples();
11429   int nbOfComp=getNumberOfComponents();
11430   int nbOfComp2=other->getNumberOfComponents();
11431   if(nbOfTuple==nbOfTuple2)
11432     {
11433       if(nbOfComp==nbOfComp2)
11434         {
11435           std::transform(begin(),end(),other->begin(),getPointer(),std::modulus<int>());
11436         }
11437       else if(nbOfComp2==1)
11438         {
11439           if(nbOfComp2==nbOfComp)
11440             {
11441               int *ptr=getPointer();
11442               const int *ptrc=other->getConstPointer();
11443               for(int i=0;i<nbOfTuple;i++)
11444                 std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::modulus<int>(),*ptrc++));
11445             }
11446           else
11447             throw INTERP_KERNEL::Exception(msg);
11448         }
11449       else
11450         throw INTERP_KERNEL::Exception(msg);
11451     }
11452   else if(nbOfTuple2==1)
11453     {
11454       int *ptr=getPointer();
11455       const int *ptrc=other->getConstPointer();
11456       for(int i=0;i<nbOfTuple;i++)
11457         std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::modulus<int>());
11458     }
11459   else
11460     throw INTERP_KERNEL::Exception(msg);
11461   declareAsNew();
11462 }
11463
11464 /*!
11465  * Returns a new DataArrayInt that is the result of pow of two given arrays. There are 3
11466  * valid cases.
11467  *
11468  *  \param [in] a1 - an array to pow up.
11469  *  \param [in] a2 - another array to sum up.
11470  *  \return DataArrayInt * - the new instance of DataArrayInt.
11471  *          The caller is to delete this result array using decrRef() as it is no more
11472  *          needed.
11473  *  \throw If either \a a1 or \a a2 is NULL.
11474  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
11475  *  \throw If \a a1->getNumberOfComponents() != 1 or \a a2->getNumberOfComponents() != 1.
11476  *  \throw If there is a negative value in \a a2.
11477  */
11478 DataArrayInt *DataArrayInt::Pow(const DataArrayInt *a1, const DataArrayInt *a2)
11479 {
11480   if(!a1 || !a2)
11481     throw INTERP_KERNEL::Exception("DataArrayInt::Pow : at least one of input instances is null !");
11482   int nbOfTuple=a1->getNumberOfTuples();
11483   int nbOfTuple2=a2->getNumberOfTuples();
11484   int nbOfComp=a1->getNumberOfComponents();
11485   int nbOfComp2=a2->getNumberOfComponents();
11486   if(nbOfTuple!=nbOfTuple2)
11487     throw INTERP_KERNEL::Exception("DataArrayInt::Pow : number of tuples mismatches !");
11488   if(nbOfComp!=1 || nbOfComp2!=1)
11489     throw INTERP_KERNEL::Exception("DataArrayInt::Pow : number of components of both arrays must be equal to 1 !");
11490   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbOfTuple,1);
11491   const int *ptr1(a1->begin()),*ptr2(a2->begin());
11492   int *ptr=ret->getPointer();
11493   for(int i=0;i<nbOfTuple;i++,ptr1++,ptr2++,ptr++)
11494     {
11495       if(*ptr2>=0)
11496         {
11497           int tmp=1;
11498           for(int j=0;j<*ptr2;j++)
11499             tmp*=*ptr1;
11500           *ptr=tmp;
11501         }
11502       else
11503         {
11504           std::ostringstream oss; oss << "DataArrayInt::Pow : on tuple #" << i << " of a2 value is < 0 (" << *ptr2 << ") !";
11505           throw INTERP_KERNEL::Exception(oss.str().c_str());
11506         }
11507     }
11508   return ret.retn();
11509 }
11510
11511 /*!
11512  * Apply pow on values of another DataArrayInt to values of \a this one.
11513  *
11514  *  \param [in] other - an array to pow to \a this one.
11515  *  \throw If \a other is NULL.
11516  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples()
11517  *  \throw If \a this->getNumberOfComponents() != 1 or \a other->getNumberOfComponents() != 1
11518  *  \throw If there is a negative value in \a other.
11519  */
11520 void DataArrayInt::powEqual(const DataArrayInt *other)
11521 {
11522   if(!other)
11523     throw INTERP_KERNEL::Exception("DataArrayInt::powEqual : input instance is null !");
11524   int nbOfTuple=getNumberOfTuples();
11525   int nbOfTuple2=other->getNumberOfTuples();
11526   int nbOfComp=getNumberOfComponents();
11527   int nbOfComp2=other->getNumberOfComponents();
11528   if(nbOfTuple!=nbOfTuple2)
11529     throw INTERP_KERNEL::Exception("DataArrayInt::powEqual : number of tuples mismatches !");
11530   if(nbOfComp!=1 || nbOfComp2!=1)
11531     throw INTERP_KERNEL::Exception("DataArrayInt::powEqual : number of components of both arrays must be equal to 1 !");
11532   int *ptr=getPointer();
11533   const int *ptrc=other->begin();
11534   for(int i=0;i<nbOfTuple;i++,ptrc++,ptr++)
11535     {
11536       if(*ptrc>=0)
11537         {
11538           int tmp=1;
11539           for(int j=0;j<*ptrc;j++)
11540             tmp*=*ptr;
11541           *ptr=tmp;
11542         }
11543       else
11544         {
11545           std::ostringstream oss; oss << "DataArrayInt::powEqual : on tuple #" << i << " of other value is < 0 (" << *ptrc << ") !";
11546           throw INTERP_KERNEL::Exception(oss.str().c_str());
11547         }
11548     }
11549   declareAsNew();
11550 }
11551
11552 /*!
11553  * Returns a C array which is a renumbering map in "Old to New" mode for the input array.
11554  * This map, if applied to \a start array, would make it sorted. For example, if
11555  * \a start array contents are [9,10,0,6,4,11,3,7] then the contents of the result array is
11556  * [5,6,0,3,2,7,1,4].
11557  *  \param [in] start - pointer to the first element of the array for which the
11558  *         permutation map is computed.
11559  *  \param [in] end - pointer specifying the end of the array \a start, so that
11560  *         the last value of \a start is \a end[ -1 ].
11561  *  \return int * - the result permutation array that the caller is to delete as it is no
11562  *         more needed.
11563  *  \throw If there are equal values in the input array.
11564  */
11565 int *DataArrayInt::CheckAndPreparePermutation(const int *start, const int *end)
11566 {
11567   std::size_t sz=std::distance(start,end);
11568   int *ret=(int *)malloc(sz*sizeof(int));
11569   int *work=new int[sz];
11570   std::copy(start,end,work);
11571   std::sort(work,work+sz);
11572   if(std::unique(work,work+sz)!=work+sz)
11573     {
11574       delete [] work;
11575       free(ret);
11576       throw INTERP_KERNEL::Exception("Some elements are equals in the specified array !");
11577     }
11578   std::map<int,int> m;
11579   for(int *workPt=work;workPt!=work+sz;workPt++)
11580     m[*workPt]=(int)std::distance(work,workPt);
11581   int *iter2=ret;
11582   for(const int *iter=start;iter!=end;iter++,iter2++)
11583     *iter2=m[*iter];
11584   delete [] work;
11585   return ret;
11586 }
11587
11588 /*!
11589  * Returns a new DataArrayInt containing an arithmetic progression
11590  * that is equal to the sequence returned by Python \c range(\a begin,\a  end,\a  step )
11591  * function.
11592  *  \param [in] begin - the start value of the result sequence.
11593  *  \param [in] end - limiting value, so that every value of the result array is less than
11594  *              \a end.
11595  *  \param [in] step - specifies the increment or decrement.
11596  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
11597  *          array using decrRef() as it is no more needed.
11598  *  \throw If \a step == 0.
11599  *  \throw If \a end < \a begin && \a step > 0.
11600  *  \throw If \a end > \a begin && \a step < 0.
11601  */
11602 DataArrayInt *DataArrayInt::Range(int begin, int end, int step)
11603 {
11604   int nbOfTuples=GetNumberOfItemGivenBESRelative(begin,end,step,"DataArrayInt::Range");
11605   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
11606   ret->alloc(nbOfTuples,1);
11607   int *ptr=ret->getPointer();
11608   if(step>0)
11609     {
11610       for(int i=begin;i<end;i+=step,ptr++)
11611         *ptr=i;
11612     }
11613   else
11614     {
11615       for(int i=begin;i>end;i+=step,ptr++)
11616         *ptr=i;
11617     }
11618   return ret.retn();
11619 }
11620
11621 /*!
11622  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
11623  * Server side.
11624  */
11625 void DataArrayInt::getTinySerializationIntInformation(std::vector<int>& tinyInfo) const
11626 {
11627   tinyInfo.resize(2);
11628   if(isAllocated())
11629     {
11630       tinyInfo[0]=getNumberOfTuples();
11631       tinyInfo[1]=getNumberOfComponents();
11632     }
11633   else
11634     {
11635       tinyInfo[0]=-1;
11636       tinyInfo[1]=-1;
11637     }
11638 }
11639
11640 /*!
11641  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
11642  * Server side.
11643  */
11644 void DataArrayInt::getTinySerializationStrInformation(std::vector<std::string>& tinyInfo) const
11645 {
11646   if(isAllocated())
11647     {
11648       int nbOfCompo=getNumberOfComponents();
11649       tinyInfo.resize(nbOfCompo+1);
11650       tinyInfo[0]=getName();
11651       for(int i=0;i<nbOfCompo;i++)
11652         tinyInfo[i+1]=getInfoOnComponent(i);
11653     }
11654   else
11655     {
11656       tinyInfo.resize(1);
11657       tinyInfo[0]=getName();
11658     }
11659 }
11660
11661 /*!
11662  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
11663  * This method returns if a feeding is needed.
11664  */
11665 bool DataArrayInt::resizeForUnserialization(const std::vector<int>& tinyInfoI)
11666 {
11667   int nbOfTuple=tinyInfoI[0];
11668   int nbOfComp=tinyInfoI[1];
11669   if(nbOfTuple!=-1 || nbOfComp!=-1)
11670     {
11671       alloc(nbOfTuple,nbOfComp);
11672       return true;
11673     }
11674   return false;
11675 }
11676
11677 /*!
11678  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
11679  * This method returns if a feeding is needed.
11680  */
11681 void DataArrayInt::finishUnserialization(const std::vector<int>& tinyInfoI, const std::vector<std::string>& tinyInfoS)
11682 {
11683   setName(tinyInfoS[0]);
11684   if(isAllocated())
11685     {
11686       int nbOfCompo=tinyInfoI[1];
11687       for(int i=0;i<nbOfCompo;i++)
11688         setInfoOnComponent(i,tinyInfoS[i+1]);
11689     }
11690 }
11691
11692 DataArrayIntIterator::DataArrayIntIterator(DataArrayInt *da):_da(da),_pt(0),_tuple_id(0),_nb_comp(0),_nb_tuple(0)
11693 {
11694   if(_da)
11695     {
11696       _da->incrRef();
11697       if(_da->isAllocated())
11698         {
11699           _nb_comp=da->getNumberOfComponents();
11700           _nb_tuple=da->getNumberOfTuples();
11701           _pt=da->getPointer();
11702         }
11703     }
11704 }
11705
11706 DataArrayIntIterator::~DataArrayIntIterator()
11707 {
11708   if(_da)
11709     _da->decrRef();
11710 }
11711
11712 DataArrayIntTuple *DataArrayIntIterator::nextt()
11713 {
11714   if(_tuple_id<_nb_tuple)
11715     {
11716       _tuple_id++;
11717       DataArrayIntTuple *ret=new DataArrayIntTuple(_pt,_nb_comp);
11718       _pt+=_nb_comp;
11719       return ret;
11720     }
11721   else
11722     return 0;
11723 }
11724
11725 DataArrayIntTuple::DataArrayIntTuple(int *pt, int nbOfComp):_pt(pt),_nb_of_compo(nbOfComp)
11726 {
11727 }
11728
11729 std::string DataArrayIntTuple::repr() const
11730 {
11731   std::ostringstream oss; oss << "(";
11732   for(int i=0;i<_nb_of_compo-1;i++)
11733     oss << _pt[i] << ", ";
11734   oss << _pt[_nb_of_compo-1] << ")";
11735   return oss.str();
11736 }
11737
11738 int DataArrayIntTuple::intValue() const
11739 {
11740   if(_nb_of_compo==1)
11741     return *_pt;
11742   throw INTERP_KERNEL::Exception("DataArrayIntTuple::intValue : DataArrayIntTuple instance has not exactly 1 component -> Not possible to convert it into an integer !");
11743 }
11744
11745 /*!
11746  * This method returns a newly allocated instance the caller should dealed with by a ParaMEDMEM::DataArrayInt::decrRef.
11747  * This method performs \b no copy of data. The content is only referenced using ParaMEDMEM::DataArrayInt::useArray with ownership set to \b false.
11748  * 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
11749  * \b nbOfCompo=1 and \bnbOfTuples==this->_nb_of_elem.
11750  */
11751 DataArrayInt *DataArrayIntTuple::buildDAInt(int nbOfTuples, int nbOfCompo) const
11752 {
11753   if((_nb_of_compo==nbOfCompo && nbOfTuples==1) || (_nb_of_compo==nbOfTuples && nbOfCompo==1))
11754     {
11755       DataArrayInt *ret=DataArrayInt::New();
11756       ret->useExternalArrayWithRWAccess(_pt,nbOfTuples,nbOfCompo);
11757       return ret;
11758     }
11759   else
11760     {
11761       std::ostringstream oss; oss << "DataArrayIntTuple::buildDAInt : unable to build a requested DataArrayInt instance with nbofTuple=" << nbOfTuples << " and nbOfCompo=" << nbOfCompo;
11762       oss << ".\nBecause the number of elements in this is " << _nb_of_compo << " !";
11763       throw INTERP_KERNEL::Exception(oss.str().c_str());
11764     }
11765 }