Salome HOME
d3f460529a0a2edb09ea81fa3377fd89b5b2c3c6
[tools/medcoupling.git] / src / MEDCoupling / MEDCouplingMemArray.cxx
1 // Copyright (C) 2007-2014  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 \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 void DataArrayInt::transformWithIndArr(const int *indArrBg, const int *indArrEnd)
6359 {
6360   checkAllocated();
6361   if(getNumberOfComponents()!=1)
6362     throw INTERP_KERNEL::Exception("Call transformWithIndArr method on DataArrayInt with only one component, you can call 'rearrange' method before !");
6363   int nbElemsIn=(int)std::distance(indArrBg,indArrEnd);
6364   int nbOfTuples=getNumberOfTuples();
6365   int *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  * Computes distribution of values of \a this one-dimensional array between given value
6381  * ranges (casts). This method is typically useful for entity number spliting by types,
6382  * for example. 
6383  *  \warning The values contained in \a arrBg should be sorted ascendently. No
6384  *           check of this is be done. If not, the result is not warranted. 
6385  *  \param [in] arrBg - the array of ascending values defining the value ranges. The i-th
6386  *         value of \a arrBg (\a arrBg[ i ]) gives the lowest value of the i-th range,
6387  *         and the greatest value of the i-th range equals to \a arrBg[ i+1 ] - 1. \a
6388  *         arrBg containing \a n values defines \a n-1 ranges. The last value of \a arrBg
6389  *         should be more than every value in \a this array.
6390  *  \param [in] arrEnd - specifies the end of the array \a arrBg, so that
6391  *              the last value of \a arrBg is \a arrEnd[ -1 ].
6392  *  \param [out] castArr - a new instance of DataArrayInt, of same size as \a this array
6393  *         (same number of tuples and components), the caller is to delete 
6394  *         using decrRef() as it is no more needed.
6395  *         This array contains indices of ranges for every value of \a this array. I.e.
6396  *         the i-th value of \a castArr gives the index of range the i-th value of \a this
6397  *         belongs to. Or, in other words, this parameter contains for each tuple in \a
6398  *         this in which cast it holds.
6399  *  \param [out] rankInsideCast - a new instance of DataArrayInt, of same size as \a this
6400  *         array, the caller is to delete using decrRef() as it is no more needed.
6401  *         This array contains ranks of values of \a this array within ranges
6402  *         they belongs to. I.e. the i-th value of \a rankInsideCast gives the rank of
6403  *         the i-th value of \a this array within the \a castArr[ i ]-th range, to which
6404  *         the i-th value of \a this belongs to. Or, in other words, this param contains 
6405  *         for each tuple its rank inside its cast. The rank is computed as difference
6406  *         between the value and the lowest value of range.
6407  *  \param [out] castsPresent - a new instance of DataArrayInt, containing indices of
6408  *         ranges (casts) to which at least one value of \a this array belongs.
6409  *         Or, in other words, this param contains the casts that \a this contains.
6410  *         The caller is to delete this array using decrRef() as it is no more needed.
6411  *
6412  * \b Example: If \a this contains [6,5,0,3,2,7,8,1,4] and \a arrBg contains [0,4,9] then
6413  *            the output of this method will be : 
6414  * - \a castArr       : [1,1,0,0,0,1,1,0,1]
6415  * - \a rankInsideCast: [2,1,0,3,2,3,4,1,0]
6416  * - \a castsPresent  : [0,1]
6417  *
6418  * I.e. values of \a this array belong to 2 ranges: #0 and #1. Value 6 belongs to the
6419  * range #1 and its rank within this range is 2; etc.
6420  *
6421  *  \throw If \a this->getNumberOfComponents() != 1.
6422  *  \throw If \a arrEnd - arrBg < 2.
6423  *  \throw If any value of \a this is not less than \a arrEnd[-1].
6424  */
6425 void DataArrayInt::splitByValueRange(const int *arrBg, const int *arrEnd,
6426                                      DataArrayInt *& castArr, DataArrayInt *& rankInsideCast, DataArrayInt *& castsPresent) const
6427 {
6428   checkAllocated();
6429   if(getNumberOfComponents()!=1)
6430     throw INTERP_KERNEL::Exception("Call splitByValueRange  method on DataArrayInt with only one component, you can call 'rearrange' method before !");
6431   int nbOfTuples=getNumberOfTuples();
6432   std::size_t nbOfCast=std::distance(arrBg,arrEnd);
6433   if(nbOfCast<2)
6434     throw INTERP_KERNEL::Exception("DataArrayInt::splitByValueRange : The input array giving the cast range values should be of size >=2 !");
6435   nbOfCast--;
6436   const int *work=getConstPointer();
6437   typedef std::reverse_iterator<const int *> rintstart;
6438   rintstart bg(arrEnd);//OK no problem because size of 'arr' is greater or equal 2
6439   rintstart end2(arrBg);
6440   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret1=DataArrayInt::New();
6441   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret2=DataArrayInt::New();
6442   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret3=DataArrayInt::New();
6443   ret1->alloc(nbOfTuples,1);
6444   ret2->alloc(nbOfTuples,1);
6445   int *ret1Ptr=ret1->getPointer();
6446   int *ret2Ptr=ret2->getPointer();
6447   std::set<std::size_t> castsDetected;
6448   for(int i=0;i<nbOfTuples;i++)
6449     {
6450       rintstart res=std::find_if(bg,end2,std::bind2nd(std::less_equal<int>(), work[i]));
6451       std::size_t pos=std::distance(bg,res);
6452       std::size_t pos2=nbOfCast-pos;
6453       if(pos2<nbOfCast)
6454         {
6455           ret1Ptr[i]=(int)pos2;
6456           ret2Ptr[i]=work[i]-arrBg[pos2];
6457           castsDetected.insert(pos2);
6458         }
6459       else
6460         {
6461           std::ostringstream oss; oss << "DataArrayInt::splitByValueRange : At rank #" << i << " the value is " << work[i] << " should be in [0," << *bg << ") !";
6462           throw INTERP_KERNEL::Exception(oss.str().c_str());
6463         }
6464     }
6465   ret3->alloc((int)castsDetected.size(),1);
6466   std::copy(castsDetected.begin(),castsDetected.end(),ret3->getPointer());
6467   castArr=ret1.retn();
6468   rankInsideCast=ret2.retn();
6469   castsPresent=ret3.retn();
6470 }
6471
6472 /*!
6473  * 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 ).
6474  * 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 ).
6475  * This method works only if \a this is allocated and single component. If not an exception will be thrown.
6476  *
6477  * \param [out] strt - the start of the range (included) if true is returned.
6478  * \param [out] sttoopp - the end of the range (not included) if true is returned.
6479  * \param [out] stteepp - the step of the range if true is returned.
6480  * \return the verdict of the check.
6481  *
6482  * \sa DataArray::GetNumberOfItemGivenBES
6483  */
6484 bool DataArrayInt::isRange(int& strt, int& sttoopp, int& stteepp) const
6485 {
6486   checkAllocated();
6487   if(getNumberOfComponents()!=1)
6488     throw INTERP_KERNEL::Exception("DataArrayInt::isRange : this must be single component array !");
6489   int nbTuples(getNumberOfTuples());
6490   if(nbTuples==0)
6491     { strt=0; sttoopp=0; stteepp=1; return true; }
6492   const int *pt(begin());
6493   strt=*pt; 
6494   if(nbTuples==1)
6495     { sttoopp=strt+1; stteepp=1; return true; }
6496   strt=*pt; sttoopp=pt[nbTuples-1];
6497   if(strt==sttoopp)
6498     return false;
6499   if(sttoopp>strt)
6500     {
6501       sttoopp++;
6502       int a(sttoopp-1-strt),tmp(strt);
6503       if(a%(nbTuples-1)!=0)
6504         return false;
6505       stteepp=a/(nbTuples-1);
6506       for(int i=0;i<nbTuples;i++,tmp+=stteepp)
6507         if(pt[i]!=tmp)
6508           return false;
6509       return true;
6510     }
6511   else
6512     {
6513       sttoopp--;
6514       int a(strt-sttoopp-1),tmp(strt);
6515       if(a%(nbTuples-1)!=0)
6516         return false;
6517       stteepp=-(a/(nbTuples-1));
6518       for(int i=0;i<nbTuples;i++,tmp+=stteepp)
6519         if(pt[i]!=tmp)
6520           return false;
6521       return true;
6522     }
6523 }
6524
6525 /*!
6526  * Creates a one-dimensional DataArrayInt (\a res) whose contents are computed from 
6527  * values of \a this (\a a) and the given (\a indArr) arrays as follows:
6528  * \a res[ \a indArr[ \a a[ i ]]] = i. I.e. for each value in place i \a v = \a a[ i ],
6529  * new value in place \a indArr[ \a v ] is i.
6530  *  \param [in] indArrBg - the array holding indices within the result array to assign
6531  *         indices of values of \a this array pointing to values of \a indArrBg.
6532  *  \param [in] indArrEnd - specifies the end of the array \a indArrBg, so that
6533  *              the last value of \a indArrBg is \a indArrEnd[ -1 ].
6534  *  \return DataArrayInt * - the new instance of DataArrayInt.
6535  *          The caller is to delete this result array using decrRef() as it is no more
6536  *          needed.
6537  *  \throw If \a this->getNumberOfComponents() != 1.
6538  *  \throw If any value of \a this array is not a valid index for \a indArrBg array.
6539  *  \throw If any value of \a indArrBg is not a valid index for \a this array.
6540  */
6541 DataArrayInt *DataArrayInt::transformWithIndArrR(const int *indArrBg, const int *indArrEnd) const
6542 {
6543   checkAllocated();
6544   if(getNumberOfComponents()!=1)
6545     throw INTERP_KERNEL::Exception("Call transformWithIndArrR method on DataArrayInt with only one component, you can call 'rearrange' method before !");
6546   int nbElemsIn=(int)std::distance(indArrBg,indArrEnd);
6547   int nbOfTuples=getNumberOfTuples();
6548   const int *pt=getConstPointer();
6549   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6550   ret->alloc(nbOfTuples,1);
6551   ret->fillWithValue(-1);
6552   int *tmp=ret->getPointer();
6553   for(int i=0;i<nbOfTuples;i++,pt++)
6554     {
6555       if(*pt>=0 && *pt<nbElemsIn)
6556         {
6557           int pos=indArrBg[*pt];
6558           if(pos>=0 && pos<nbOfTuples)
6559             tmp[pos]=i;
6560           else
6561             {
6562               std::ostringstream oss; oss << "DataArrayInt::transformWithIndArrR : error on tuple #" << i << " value of new pos is " << pos << " ( indArrBg[" << *pt << "]) ! Should be in [0," << nbOfTuples << ") !";
6563               throw INTERP_KERNEL::Exception(oss.str().c_str());
6564             }
6565         }
6566       else
6567         {
6568           std::ostringstream oss; oss << "DataArrayInt::transformWithIndArrR : error on tuple #" << i << " value is " << *pt << " and indirectionnal array as a size equal to " << nbElemsIn << " !";
6569           throw INTERP_KERNEL::Exception(oss.str().c_str());
6570         }
6571     }
6572   return ret.retn();
6573 }
6574
6575 /*!
6576  * Creates a one-dimensional DataArrayInt of given length, whose contents are computed
6577  * from values of \a this array, which is supposed to contain a renumbering map in 
6578  * "Old to New" mode. The result array contains a renumbering map in "New to Old" mode.
6579  * To know how to use the renumbering maps see \ref MEDCouplingArrayRenumbering.
6580  *  \param [in] newNbOfElem - the number of tuples in the result array.
6581  *  \return DataArrayInt * - the new instance of DataArrayInt.
6582  *          The caller is to delete this result array using decrRef() as it is no more
6583  *          needed.
6584  * 
6585  *  \if ENABLE_EXAMPLES
6586  *  \ref cpp_mcdataarrayint_invertarrayo2n2n2o "Here is a C++ example".<br>
6587  *  \ref py_mcdataarrayint_invertarrayo2n2n2o  "Here is a Python example".
6588  *  \endif
6589  */
6590 DataArrayInt *DataArrayInt::invertArrayO2N2N2O(int newNbOfElem) const
6591 {
6592   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6593   ret->alloc(newNbOfElem,1);
6594   int nbOfOldNodes=getNumberOfTuples();
6595   const int *old2New=getConstPointer();
6596   int *pt=ret->getPointer();
6597   for(int i=0;i!=nbOfOldNodes;i++)
6598     {
6599       int newp(old2New[i]);
6600       if(newp!=-1)
6601         {
6602           if(newp>=0 && newp<newNbOfElem)
6603             pt[newp]=i;
6604           else
6605             {
6606               std::ostringstream oss; oss << "DataArrayInt::invertArrayO2N2N2O : At place #" << i << " the newplace is " << newp << " must be in [0," << newNbOfElem << ") !";
6607               throw INTERP_KERNEL::Exception(oss.str().c_str());
6608             }
6609         }
6610     }
6611   return ret.retn();
6612 }
6613
6614 /*!
6615  * This method is similar to DataArrayInt::invertArrayO2N2N2O except that 
6616  * 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]
6617  */
6618 DataArrayInt *DataArrayInt::invertArrayO2N2N2OBis(int newNbOfElem) const
6619 {
6620   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6621   ret->alloc(newNbOfElem,1);
6622   int nbOfOldNodes=getNumberOfTuples();
6623   const int *old2New=getConstPointer();
6624   int *pt=ret->getPointer();
6625   for(int i=nbOfOldNodes-1;i>=0;i--)
6626     {
6627       int newp(old2New[i]);
6628       if(newp!=-1)
6629         {
6630           if(newp>=0 && newp<newNbOfElem)
6631             pt[newp]=i;
6632           else
6633             {
6634               std::ostringstream oss; oss << "DataArrayInt::invertArrayO2N2N2OBis : At place #" << i << " the newplace is " << newp << " must be in [0," << newNbOfElem << ") !";
6635               throw INTERP_KERNEL::Exception(oss.str().c_str());
6636             }
6637         }
6638     }
6639   return ret.retn();
6640 }
6641
6642 /*!
6643  * Creates a one-dimensional DataArrayInt of given length, whose contents are computed
6644  * from values of \a this array, which is supposed to contain a renumbering map in 
6645  * "New to Old" mode. The result array contains a renumbering map in "Old to New" mode.
6646  * To know how to use the renumbering maps see \ref MEDCouplingArrayRenumbering.
6647  *  \param [in] newNbOfElem - the number of tuples in the result array.
6648  *  \return DataArrayInt * - the new instance of DataArrayInt.
6649  *          The caller is to delete this result array using decrRef() as it is no more
6650  *          needed.
6651  * 
6652  *  \if ENABLE_EXAMPLES
6653  *  \ref cpp_mcdataarrayint_invertarrayn2o2o2n "Here is a C++ example".
6654  *
6655  *  \ref py_mcdataarrayint_invertarrayn2o2o2n "Here is a Python example".
6656  *  \endif
6657  */
6658 DataArrayInt *DataArrayInt::invertArrayN2O2O2N(int oldNbOfElem) const
6659 {
6660   checkAllocated();
6661   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6662   ret->alloc(oldNbOfElem,1);
6663   const int *new2Old=getConstPointer();
6664   int *pt=ret->getPointer();
6665   std::fill(pt,pt+oldNbOfElem,-1);
6666   int nbOfNewElems=getNumberOfTuples();
6667   for(int i=0;i<nbOfNewElems;i++)
6668     {
6669       int v(new2Old[i]);
6670       if(v>=0 && v<oldNbOfElem)
6671         pt[v]=i;
6672       else
6673         {
6674           std::ostringstream oss; oss << "DataArrayInt::invertArrayN2O2O2N : in new id #" << i << " old value is " << v << " expected to be in [0," << oldNbOfElem << ") !";
6675           throw INTERP_KERNEL::Exception(oss.str().c_str());
6676         }
6677     }
6678   return ret.retn();
6679 }
6680
6681 /*!
6682  * Equivalent to DataArrayInt::isEqual except that if false the reason of
6683  * mismatch is given.
6684  * 
6685  * \param [in] other the instance to be compared with \a this
6686  * \param [out] reason In case of inequality returns the reason.
6687  * \sa DataArrayInt::isEqual
6688  */
6689 bool DataArrayInt::isEqualIfNotWhy(const DataArrayInt& other, std::string& reason) const
6690 {
6691   if(!areInfoEqualsIfNotWhy(other,reason))
6692     return false;
6693   return _mem.isEqual(other._mem,0,reason);
6694 }
6695
6696 /*!
6697  * Checks if \a this and another DataArrayInt are fully equal. For more info see
6698  * \ref MEDCouplingArrayBasicsCompare.
6699  *  \param [in] other - an instance of DataArrayInt to compare with \a this one.
6700  *  \return bool - \a true if the two arrays are equal, \a false else.
6701  */
6702 bool DataArrayInt::isEqual(const DataArrayInt& other) const
6703 {
6704   std::string tmp;
6705   return isEqualIfNotWhy(other,tmp);
6706 }
6707
6708 /*!
6709  * Checks if values of \a this and another DataArrayInt are equal. For more info see
6710  * \ref MEDCouplingArrayBasicsCompare.
6711  *  \param [in] other - an instance of DataArrayInt to compare with \a this one.
6712  *  \return bool - \a true if the values of two arrays are equal, \a false else.
6713  */
6714 bool DataArrayInt::isEqualWithoutConsideringStr(const DataArrayInt& other) const
6715 {
6716   std::string tmp;
6717   return _mem.isEqual(other._mem,0,tmp);
6718 }
6719
6720 /*!
6721  * Checks if values of \a this and another DataArrayInt are equal. Comparison is
6722  * performed on sorted value sequences.
6723  * For more info see\ref MEDCouplingArrayBasicsCompare.
6724  *  \param [in] other - an instance of DataArrayInt to compare with \a this one.
6725  *  \return bool - \a true if the sorted values of two arrays are equal, \a false else.
6726  */
6727 bool DataArrayInt::isEqualWithoutConsideringStrAndOrder(const DataArrayInt& other) const
6728 {
6729   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> a=deepCpy();
6730   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> b=other.deepCpy();
6731   a->sort();
6732   b->sort();
6733   return a->isEqualWithoutConsideringStr(*b);
6734 }
6735
6736 /*!
6737  * This method compares content of input vector \a v and \a this.
6738  * 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.
6739  * For performance reasons \a this is expected to be sorted ascendingly. If not an exception will be thrown.
6740  *
6741  * \param [in] v - the vector of 'flags' to be compared with \a this.
6742  *
6743  * \throw If \a this is not sorted ascendingly.
6744  * \throw If \a this has not exactly one component.
6745  * \throw If \a this is not allocated.
6746  */
6747 bool DataArrayInt::isFittingWith(const std::vector<bool>& v) const
6748 {
6749   checkAllocated();
6750   if(getNumberOfComponents()!=1)
6751     throw INTERP_KERNEL::Exception("DataArrayInt::isFittingWith : number of components of this should be equal to one !");
6752   const int *w(begin()),*end2(end());
6753   int refVal=-std::numeric_limits<int>::max();
6754   int i=0;
6755   std::vector<bool>::const_iterator it(v.begin());
6756   for(;it!=v.end();it++,i++)
6757     {
6758       if(*it)
6759         {
6760           if(w!=end2)
6761             {
6762               if(*w++==i)
6763                 {
6764                   if(i>refVal)
6765                     refVal=i;
6766                   else
6767                     {
6768                       std::ostringstream oss; oss << "DataArrayInt::isFittingWith : At pos #" << std::distance(begin(),w-1) << " this is not sorted ascendingly !";
6769                       throw INTERP_KERNEL::Exception(oss.str().c_str());
6770                     }
6771                 }
6772               else
6773                 return false;
6774             }
6775           else
6776             return false;
6777         }
6778     }
6779   return w==end2;
6780 }
6781
6782 /*!
6783  * Sorts values of the array.
6784  *  \param [in] asc - \a true means ascending order, \a false, descending.
6785  *  \throw If \a this is not allocated.
6786  *  \throw If \a this->getNumberOfComponents() != 1.
6787  */
6788 void DataArrayInt::sort(bool asc)
6789 {
6790   checkAllocated();
6791   if(getNumberOfComponents()!=1)
6792     throw INTERP_KERNEL::Exception("DataArrayInt::sort : only supported with 'this' array with ONE component !");
6793   _mem.sort(asc);
6794   declareAsNew();
6795 }
6796
6797 /*!
6798  * Computes for each tuple the sum of number of components values in the tuple and return it.
6799  * 
6800  * \return DataArrayInt * - the new instance of DataArrayInt containing the
6801  *          same number of tuples as \a this array and one component.
6802  *          The caller is to delete this result array using decrRef() as it is no more
6803  *          needed.
6804  *  \throw If \a this is not allocated.
6805  */
6806 DataArrayInt *DataArrayInt::sumPerTuple() const
6807 {
6808   checkAllocated();
6809   int nbOfComp(getNumberOfComponents()),nbOfTuple(getNumberOfTuples());
6810   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New());
6811   ret->alloc(nbOfTuple,1);
6812   const int *src(getConstPointer());
6813   int *dest(ret->getPointer());
6814   for(int i=0;i<nbOfTuple;i++,dest++,src+=nbOfComp)
6815     *dest=std::accumulate(src,src+nbOfComp,0);
6816   return ret.retn();
6817 }
6818
6819 /*!
6820  * Reverse the array values.
6821  *  \throw If \a this->getNumberOfComponents() < 1.
6822  *  \throw If \a this is not allocated.
6823  */
6824 void DataArrayInt::reverse()
6825 {
6826   checkAllocated();
6827   _mem.reverse(getNumberOfComponents());
6828   declareAsNew();
6829 }
6830
6831 /*!
6832  * Checks that \a this array is consistently **increasing** or **decreasing** in value.
6833  * If not an exception is thrown.
6834  *  \param [in] increasing - if \a true, the array values should be increasing.
6835  *  \throw If sequence of values is not strictly monotonic in agreement with \a
6836  *         increasing arg.
6837  *  \throw If \a this->getNumberOfComponents() != 1.
6838  *  \throw If \a this is not allocated.
6839  */
6840 void DataArrayInt::checkMonotonic(bool increasing) const
6841 {
6842   if(!isMonotonic(increasing))
6843     {
6844       if (increasing)
6845         throw INTERP_KERNEL::Exception("DataArrayInt::checkMonotonic : 'this' is not INCREASING monotonic !");
6846       else
6847         throw INTERP_KERNEL::Exception("DataArrayInt::checkMonotonic : 'this' is not DECREASING monotonic !");
6848     }
6849 }
6850
6851 /*!
6852  * Checks that \a this array is consistently **increasing** or **decreasing** in value.
6853  *  \param [in] increasing - if \a true, array values should be increasing.
6854  *  \return bool - \a true if values change in accordance with \a increasing arg.
6855  *  \throw If \a this->getNumberOfComponents() != 1.
6856  *  \throw If \a this is not allocated.
6857  */
6858 bool DataArrayInt::isMonotonic(bool increasing) const
6859 {
6860   checkAllocated();
6861   if(getNumberOfComponents()!=1)
6862     throw INTERP_KERNEL::Exception("DataArrayInt::isMonotonic : only supported with 'this' array with ONE component !");
6863   int nbOfElements=getNumberOfTuples();
6864   const int *ptr=getConstPointer();
6865   if(nbOfElements==0)
6866     return true;
6867   int ref=ptr[0];
6868   if(increasing)
6869     {
6870       for(int i=1;i<nbOfElements;i++)
6871         {
6872           if(ptr[i]>=ref)
6873             ref=ptr[i];
6874           else
6875             return false;
6876         }
6877     }
6878   else
6879     {
6880       for(int i=1;i<nbOfElements;i++)
6881         {
6882           if(ptr[i]<=ref)
6883             ref=ptr[i];
6884           else
6885             return false;
6886         }
6887     }
6888   return true;
6889 }
6890
6891 /*!
6892  * This method check that array consistently INCREASING or DECREASING in value.
6893  */
6894 bool DataArrayInt::isStrictlyMonotonic(bool increasing) const
6895 {
6896   checkAllocated();
6897   if(getNumberOfComponents()!=1)
6898     throw INTERP_KERNEL::Exception("DataArrayInt::isStrictlyMonotonic : only supported with 'this' array with ONE component !");
6899   int nbOfElements=getNumberOfTuples();
6900   const int *ptr=getConstPointer();
6901   if(nbOfElements==0)
6902     return true;
6903   int ref=ptr[0];
6904   if(increasing)
6905     {
6906       for(int i=1;i<nbOfElements;i++)
6907         {
6908           if(ptr[i]>ref)
6909             ref=ptr[i];
6910           else
6911             return false;
6912         }
6913     }
6914   else
6915     {
6916       for(int i=1;i<nbOfElements;i++)
6917         {
6918           if(ptr[i]<ref)
6919             ref=ptr[i];
6920           else
6921             return false;
6922         }
6923     }
6924   return true;
6925 }
6926
6927 /*!
6928  * This method check that array consistently INCREASING or DECREASING in value.
6929  */
6930 void DataArrayInt::checkStrictlyMonotonic(bool increasing) const
6931 {
6932   if(!isStrictlyMonotonic(increasing))
6933     {
6934       if (increasing)
6935         throw INTERP_KERNEL::Exception("DataArrayInt::checkStrictlyMonotonic : 'this' is not strictly INCREASING monotonic !");
6936       else
6937         throw INTERP_KERNEL::Exception("DataArrayInt::checkStrictlyMonotonic : 'this' is not strictly DECREASING monotonic !");
6938     }
6939 }
6940
6941 /*!
6942  * Creates a new one-dimensional DataArrayInt of the same size as \a this and a given
6943  * one-dimensional arrays that must be of the same length. The result array describes
6944  * correspondence between \a this and \a other arrays, so that 
6945  * <em> other.getIJ(i,0) == this->getIJ(ret->getIJ(i),0)</em>. If such a permutation is
6946  * not possible because some element in \a other is not in \a this, an exception is thrown.
6947  *  \param [in] other - an array to compute permutation to.
6948  *  \return DataArrayInt * - a new instance of DataArrayInt, which is a permutation array
6949  * from \a this to \a other. The caller is to delete this array using decrRef() as it is
6950  * no more needed.
6951  *  \throw If \a this->getNumberOfComponents() != 1.
6952  *  \throw If \a other->getNumberOfComponents() != 1.
6953  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples().
6954  *  \throw If \a other includes a value which is not in \a this array.
6955  * 
6956  *  \if ENABLE_EXAMPLES
6957  *  \ref cpp_mcdataarrayint_buildpermutationarr "Here is a C++ example".
6958  *
6959  *  \ref py_mcdataarrayint_buildpermutationarr "Here is a Python example".
6960  *  \endif
6961  */
6962 DataArrayInt *DataArrayInt::buildPermutationArr(const DataArrayInt& other) const
6963 {
6964   checkAllocated();
6965   if(getNumberOfComponents()!=1 || other.getNumberOfComponents()!=1)
6966     throw INTERP_KERNEL::Exception("DataArrayInt::buildPermutationArr : 'this' and 'other' have to have exactly ONE component !");
6967   int nbTuple=getNumberOfTuples();
6968   other.checkAllocated();
6969   if(nbTuple!=other.getNumberOfTuples())
6970     throw INTERP_KERNEL::Exception("DataArrayInt::buildPermutationArr : 'this' and 'other' must have the same number of tuple !");
6971   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6972   ret->alloc(nbTuple,1);
6973   ret->fillWithValue(-1);
6974   const int *pt=getConstPointer();
6975   std::map<int,int> mm;
6976   for(int i=0;i<nbTuple;i++)
6977     mm[pt[i]]=i;
6978   pt=other.getConstPointer();
6979   int *retToFill=ret->getPointer();
6980   for(int i=0;i<nbTuple;i++)
6981     {
6982       std::map<int,int>::const_iterator it=mm.find(pt[i]);
6983       if(it==mm.end())
6984         {
6985           std::ostringstream oss; oss << "DataArrayInt::buildPermutationArr : Arrays mismatch : element (" << pt[i] << ") in 'other' not findable in 'this' !";
6986           throw INTERP_KERNEL::Exception(oss.str().c_str());
6987         }
6988       retToFill[i]=(*it).second;
6989     }
6990   return ret.retn();
6991 }
6992
6993 /*!
6994  * Sets a C array to be used as raw data of \a this. The previously set info
6995  *  of components is retained and re-sized. 
6996  * For more info see \ref MEDCouplingArraySteps1.
6997  *  \param [in] array - the C array to be used as raw data of \a this.
6998  *  \param [in] ownership - if \a true, \a array will be deallocated at destruction of \a this.
6999  *  \param [in] type - specifies how to deallocate \a array. If \a type == ParaMEDMEM::CPP_DEALLOC,
7000  *                     \c delete [] \c array; will be called. If \a type == ParaMEDMEM::C_DEALLOC,
7001  *                     \c free(\c array ) will be called.
7002  *  \param [in] nbOfTuple - new number of tuples in \a this.
7003  *  \param [in] nbOfCompo - new number of components in \a this.
7004  */
7005 void DataArrayInt::useArray(const int *array, bool ownership,  DeallocType type, int nbOfTuple, int nbOfCompo)
7006 {
7007   _info_on_compo.resize(nbOfCompo);
7008   _mem.useArray(array,ownership,type,nbOfTuple*nbOfCompo);
7009   declareAsNew();
7010 }
7011
7012 void DataArrayInt::useExternalArrayWithRWAccess(const int *array, int nbOfTuple, int nbOfCompo)
7013 {
7014   _info_on_compo.resize(nbOfCompo);
7015   _mem.useExternalArrayWithRWAccess(array,nbOfTuple*nbOfCompo);
7016   declareAsNew();
7017 }
7018
7019 /*!
7020  * Returns a new DataArrayInt holding the same values as \a this array but differently
7021  * arranged in memory. If \a this array holds 2 components of 3 values:
7022  * \f$ x_0,x_1,x_2,y_0,y_1,y_2 \f$, then the result array holds these values arranged
7023  * as follows: \f$ x_0,y_0,x_1,y_1,x_2,y_2 \f$.
7024  *  \warning Do not confuse this method with transpose()!
7025  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
7026  *          is to delete using decrRef() as it is no more needed.
7027  *  \throw If \a this is not allocated.
7028  */
7029 DataArrayInt *DataArrayInt::fromNoInterlace() const
7030 {
7031   checkAllocated();
7032   if(_mem.isNull())
7033     throw INTERP_KERNEL::Exception("DataArrayInt::fromNoInterlace : Not defined array !");
7034   int *tab=_mem.fromNoInterlace(getNumberOfComponents());
7035   DataArrayInt *ret=DataArrayInt::New();
7036   ret->useArray(tab,true,C_DEALLOC,getNumberOfTuples(),getNumberOfComponents());
7037   return ret;
7038 }
7039
7040 /*!
7041  * Returns a new DataArrayInt holding the same values as \a this array but differently
7042  * arranged in memory. If \a this array holds 2 components of 3 values:
7043  * \f$ x_0,y_0,x_1,y_1,x_2,y_2 \f$, then the result array holds these values arranged
7044  * as follows: \f$ x_0,x_1,x_2,y_0,y_1,y_2 \f$.
7045  *  \warning Do not confuse this method with transpose()!
7046  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
7047  *          is to delete using decrRef() as it is no more needed.
7048  *  \throw If \a this is not allocated.
7049  */
7050 DataArrayInt *DataArrayInt::toNoInterlace() const
7051 {
7052   checkAllocated();
7053   if(_mem.isNull())
7054     throw INTERP_KERNEL::Exception("DataArrayInt::toNoInterlace : Not defined array !");
7055   int *tab=_mem.toNoInterlace(getNumberOfComponents());
7056   DataArrayInt *ret=DataArrayInt::New();
7057   ret->useArray(tab,true,C_DEALLOC,getNumberOfTuples(),getNumberOfComponents());
7058   return ret;
7059 }
7060
7061 /*!
7062  * Permutes values of \a this array as required by \a old2New array. The values are
7063  * permuted so that \c new[ \a old2New[ i ]] = \c old[ i ]. Number of tuples remains
7064  * the same as in \this one.
7065  * If a permutation reduction is needed, substr() or selectByTupleId() should be used.
7066  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
7067  *  \param [in] old2New - C array of length equal to \a this->getNumberOfTuples()
7068  *     giving a new position for i-th old value.
7069  */
7070 void DataArrayInt::renumberInPlace(const int *old2New)
7071 {
7072   checkAllocated();
7073   int nbTuples=getNumberOfTuples();
7074   int nbOfCompo=getNumberOfComponents();
7075   int *tmp=new int[nbTuples*nbOfCompo];
7076   const int *iptr=getConstPointer();
7077   for(int i=0;i<nbTuples;i++)
7078     {
7079       int v=old2New[i];
7080       if(v>=0 && v<nbTuples)
7081         std::copy(iptr+nbOfCompo*i,iptr+nbOfCompo*(i+1),tmp+nbOfCompo*v);
7082       else
7083         {
7084           std::ostringstream oss; oss << "DataArrayInt::renumberInPlace : At place #" << i << " value is " << v << " ! Should be in [0," << nbTuples << ") !";
7085           throw INTERP_KERNEL::Exception(oss.str().c_str());
7086         }
7087     }
7088   std::copy(tmp,tmp+nbTuples*nbOfCompo,getPointer());
7089   delete [] tmp;
7090   declareAsNew();
7091 }
7092
7093 /*!
7094  * Permutes values of \a this array as required by \a new2Old array. The values are
7095  * permuted so that \c new[ i ] = \c old[ \a new2Old[ i ]]. Number of tuples remains
7096  * the same as in \this one.
7097  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
7098  *  \param [in] new2Old - C array of length equal to \a this->getNumberOfTuples()
7099  *     giving a previous position of i-th new value.
7100  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
7101  *          is to delete using decrRef() as it is no more needed.
7102  */
7103 void DataArrayInt::renumberInPlaceR(const int *new2Old)
7104 {
7105   checkAllocated();
7106   int nbTuples=getNumberOfTuples();
7107   int nbOfCompo=getNumberOfComponents();
7108   int *tmp=new int[nbTuples*nbOfCompo];
7109   const int *iptr=getConstPointer();
7110   for(int i=0;i<nbTuples;i++)
7111     {
7112       int v=new2Old[i];
7113       if(v>=0 && v<nbTuples)
7114         std::copy(iptr+nbOfCompo*v,iptr+nbOfCompo*(v+1),tmp+nbOfCompo*i);
7115       else
7116         {
7117           std::ostringstream oss; oss << "DataArrayInt::renumberInPlaceR : At place #" << i << " value is " << v << " ! Should be in [0," << nbTuples << ") !";
7118           throw INTERP_KERNEL::Exception(oss.str().c_str());
7119         }
7120     }
7121   std::copy(tmp,tmp+nbTuples*nbOfCompo,getPointer());
7122   delete [] tmp;
7123   declareAsNew();
7124 }
7125
7126 /*!
7127  * Returns a copy of \a this array with values permuted as required by \a old2New array.
7128  * The values are permuted so that  \c new[ \a old2New[ i ]] = \c old[ i ].
7129  * Number of tuples in the result array remains the same as in \this one.
7130  * If a permutation reduction is needed, renumberAndReduce() should be used.
7131  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
7132  *  \param [in] old2New - C array of length equal to \a this->getNumberOfTuples()
7133  *          giving a new position for i-th old value.
7134  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
7135  *          is to delete using decrRef() as it is no more needed.
7136  *  \throw If \a this is not allocated.
7137  */
7138 DataArrayInt *DataArrayInt::renumber(const int *old2New) const
7139 {
7140   checkAllocated();
7141   int nbTuples=getNumberOfTuples();
7142   int nbOfCompo=getNumberOfComponents();
7143   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
7144   ret->alloc(nbTuples,nbOfCompo);
7145   ret->copyStringInfoFrom(*this);
7146   const int *iptr=getConstPointer();
7147   int *optr=ret->getPointer();
7148   for(int i=0;i<nbTuples;i++)
7149     std::copy(iptr+nbOfCompo*i,iptr+nbOfCompo*(i+1),optr+nbOfCompo*old2New[i]);
7150   ret->copyStringInfoFrom(*this);
7151   return ret.retn();
7152 }
7153
7154 /*!
7155  * Returns a copy of \a this array with values permuted as required by \a new2Old array.
7156  * The values are permuted so that  \c new[ i ] = \c old[ \a new2Old[ i ]]. Number of
7157  * tuples in the result array remains the same as in \this one.
7158  * If a permutation reduction is needed, substr() or selectByTupleId() should be used.
7159  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
7160  *  \param [in] new2Old - C array of length equal to \a this->getNumberOfTuples()
7161  *     giving a previous position of i-th new value.
7162  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
7163  *          is to delete using decrRef() as it is no more needed.
7164  */
7165 DataArrayInt *DataArrayInt::renumberR(const int *new2Old) const
7166 {
7167   checkAllocated();
7168   int nbTuples=getNumberOfTuples();
7169   int nbOfCompo=getNumberOfComponents();
7170   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
7171   ret->alloc(nbTuples,nbOfCompo);
7172   ret->copyStringInfoFrom(*this);
7173   const int *iptr=getConstPointer();
7174   int *optr=ret->getPointer();
7175   for(int i=0;i<nbTuples;i++)
7176     std::copy(iptr+nbOfCompo*new2Old[i],iptr+nbOfCompo*(new2Old[i]+1),optr+nbOfCompo*i);
7177   ret->copyStringInfoFrom(*this);
7178   return ret.retn();
7179 }
7180
7181 /*!
7182  * Returns a shorten and permuted copy of \a this array. The new DataArrayInt is
7183  * of size \a newNbOfTuple and it's values are permuted as required by \a old2New array.
7184  * The values are permuted so that  \c new[ \a old2New[ i ]] = \c old[ i ] for all
7185  * \a old2New[ i ] >= 0. In other words every i-th tuple in \a this array, for which 
7186  * \a old2New[ i ] is negative, is missing from the result array.
7187  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
7188  *  \param [in] old2New - C array of length equal to \a this->getNumberOfTuples()
7189  *     giving a new position for i-th old tuple and giving negative position for
7190  *     for i-th old tuple that should be omitted.
7191  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
7192  *          is to delete using decrRef() as it is no more needed.
7193  */
7194 DataArrayInt *DataArrayInt::renumberAndReduce(const int *old2New, int newNbOfTuple) const
7195 {
7196   checkAllocated();
7197   int nbTuples=getNumberOfTuples();
7198   int nbOfCompo=getNumberOfComponents();
7199   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
7200   ret->alloc(newNbOfTuple,nbOfCompo);
7201   const int *iptr=getConstPointer();
7202   int *optr=ret->getPointer();
7203   for(int i=0;i<nbTuples;i++)
7204     {
7205       int w=old2New[i];
7206       if(w>=0)
7207         std::copy(iptr+i*nbOfCompo,iptr+(i+1)*nbOfCompo,optr+w*nbOfCompo);
7208     }
7209   ret->copyStringInfoFrom(*this);
7210   return ret.retn();
7211 }
7212
7213 /*!
7214  * Returns a shorten and permuted copy of \a this array. The new DataArrayInt is
7215  * of size \a new2OldEnd - \a new2OldBg and it's values are permuted as required by
7216  * \a new2OldBg array.
7217  * The values are permuted so that  \c new[ i ] = \c old[ \a new2OldBg[ i ]].
7218  * This method is equivalent to renumberAndReduce() except that convention in input is
7219  * \c new2old and \b not \c old2new.
7220  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
7221  *  \param [in] new2OldBg - pointer to the beginning of a permutation array that gives a
7222  *              tuple index in \a this array to fill the i-th tuple in the new array.
7223  *  \param [in] new2OldEnd - specifies the end of the permutation array that starts at
7224  *              \a new2OldBg, so that pointer to a tuple index (\a pi) varies as this:
7225  *              \a new2OldBg <= \a pi < \a new2OldEnd.
7226  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
7227  *          is to delete using decrRef() as it is no more needed.
7228  */
7229 DataArrayInt *DataArrayInt::selectByTupleId(const int *new2OldBg, const int *new2OldEnd) const
7230 {
7231   checkAllocated();
7232   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
7233   int nbComp=getNumberOfComponents();
7234   ret->alloc((int)std::distance(new2OldBg,new2OldEnd),nbComp);
7235   ret->copyStringInfoFrom(*this);
7236   int *pt=ret->getPointer();
7237   const int *srcPt=getConstPointer();
7238   int i=0;
7239   for(const int *w=new2OldBg;w!=new2OldEnd;w++,i++)
7240     std::copy(srcPt+(*w)*nbComp,srcPt+((*w)+1)*nbComp,pt+i*nbComp);
7241   ret->copyStringInfoFrom(*this);
7242   return ret.retn();
7243 }
7244
7245 /*!
7246  * Returns a shorten and permuted copy of \a this array. The new DataArrayInt is
7247  * of size \a new2OldEnd - \a new2OldBg and it's values are permuted as required by
7248  * \a new2OldBg array.
7249  * The values are permuted so that  \c new[ i ] = \c old[ \a new2OldBg[ i ]].
7250  * This method is equivalent to renumberAndReduce() except that convention in input is
7251  * \c new2old and \b not \c old2new.
7252  * This method is equivalent to selectByTupleId() except that it prevents coping data
7253  * from behind the end of \a this array.
7254  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
7255  *  \param [in] new2OldBg - pointer to the beginning of a permutation array that gives a
7256  *              tuple index in \a this array to fill the i-th tuple in the new array.
7257  *  \param [in] new2OldEnd - specifies the end of the permutation array that starts at
7258  *              \a new2OldBg, so that pointer to a tuple index (\a pi) varies as this:
7259  *              \a new2OldBg <= \a pi < \a new2OldEnd.
7260  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
7261  *          is to delete using decrRef() as it is no more needed.
7262  *  \throw If \a new2OldEnd - \a new2OldBg > \a this->getNumberOfTuples().
7263  */
7264 DataArrayInt *DataArrayInt::selectByTupleIdSafe(const int *new2OldBg, const int *new2OldEnd) const
7265 {
7266   checkAllocated();
7267   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
7268   int nbComp=getNumberOfComponents();
7269   int oldNbOfTuples=getNumberOfTuples();
7270   ret->alloc((int)std::distance(new2OldBg,new2OldEnd),nbComp);
7271   ret->copyStringInfoFrom(*this);
7272   int *pt=ret->getPointer();
7273   const int *srcPt=getConstPointer();
7274   int i=0;
7275   for(const int *w=new2OldBg;w!=new2OldEnd;w++,i++)
7276     if(*w>=0 && *w<oldNbOfTuples)
7277       std::copy(srcPt+(*w)*nbComp,srcPt+((*w)+1)*nbComp,pt+i*nbComp);
7278     else
7279       throw INTERP_KERNEL::Exception("DataArrayInt::selectByTupleIdSafe : some ids has been detected to be out of [0,this->getNumberOfTuples) !");
7280   ret->copyStringInfoFrom(*this);
7281   return ret.retn();
7282 }
7283
7284 /*!
7285  * Returns a shorten copy of \a this array. The new DataArrayInt contains every
7286  * (\a bg + \c i * \a step)-th tuple of \a this array located before the \a end2-th
7287  * tuple. Indices of the selected tuples are the same as ones returned by the Python
7288  * command \c range( \a bg, \a end2, \a step ).
7289  * This method is equivalent to selectByTupleIdSafe() except that the input array is
7290  * not constructed explicitly.
7291  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
7292  *  \param [in] bg - index of the first tuple to copy from \a this array.
7293  *  \param [in] end2 - index of the tuple before which the tuples to copy are located.
7294  *  \param [in] step - index increment to get index of the next tuple to copy.
7295  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
7296  *          is to delete using decrRef() as it is no more needed.
7297  *  \sa DataArrayInt::substr.
7298  */
7299 DataArrayInt *DataArrayInt::selectByTupleId2(int bg, int end2, int step) const
7300 {
7301   checkAllocated();
7302   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
7303   int nbComp=getNumberOfComponents();
7304   int newNbOfTuples=GetNumberOfItemGivenBESRelative(bg,end2,step,"DataArrayInt::selectByTupleId2 : ");
7305   ret->alloc(newNbOfTuples,nbComp);
7306   int *pt=ret->getPointer();
7307   const int *srcPt=getConstPointer()+bg*nbComp;
7308   for(int i=0;i<newNbOfTuples;i++,srcPt+=step*nbComp)
7309     std::copy(srcPt,srcPt+nbComp,pt+i*nbComp);
7310   ret->copyStringInfoFrom(*this);
7311   return ret.retn();
7312 }
7313
7314 /*!
7315  * Returns a shorten copy of \a this array. The new DataArrayInt contains ranges
7316  * of tuples specified by \a ranges parameter.
7317  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
7318  *  \param [in] ranges - std::vector of std::pair's each of which defines a range
7319  *              of tuples in [\c begin,\c end) format.
7320  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
7321  *          is to delete using decrRef() as it is no more needed.
7322  *  \throw If \a end < \a begin.
7323  *  \throw If \a end > \a this->getNumberOfTuples().
7324  *  \throw If \a this is not allocated.
7325  */
7326 DataArray *DataArrayInt::selectByTupleRanges(const std::vector<std::pair<int,int> >& ranges) const
7327 {
7328   checkAllocated();
7329   int nbOfComp=getNumberOfComponents();
7330   int nbOfTuplesThis=getNumberOfTuples();
7331   if(ranges.empty())
7332     {
7333       MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
7334       ret->alloc(0,nbOfComp);
7335       ret->copyStringInfoFrom(*this);
7336       return ret.retn();
7337     }
7338   int ref=ranges.front().first;
7339   int nbOfTuples=0;
7340   bool isIncreasing=true;
7341   for(std::vector<std::pair<int,int> >::const_iterator it=ranges.begin();it!=ranges.end();it++)
7342     {
7343       if((*it).first<=(*it).second)
7344         {
7345           if((*it).first>=0 && (*it).second<=nbOfTuplesThis)
7346             {
7347               nbOfTuples+=(*it).second-(*it).first;
7348               if(isIncreasing)
7349                 isIncreasing=ref<=(*it).first;
7350               ref=(*it).second;
7351             }
7352           else
7353             {
7354               std::ostringstream oss; oss << "DataArrayInt::selectByTupleRanges : on range #" << std::distance(ranges.begin(),it);
7355               oss << " (" << (*it).first << "," << (*it).second << ") is greater than number of tuples of this :" << nbOfTuples << " !";
7356               throw INTERP_KERNEL::Exception(oss.str().c_str());
7357             }
7358         }
7359       else
7360         {
7361           std::ostringstream oss; oss << "DataArrayInt::selectByTupleRanges : on range #" << std::distance(ranges.begin(),it);
7362           oss << " (" << (*it).first << "," << (*it).second << ") end is before begin !";
7363           throw INTERP_KERNEL::Exception(oss.str().c_str());
7364         }
7365     }
7366   if(isIncreasing && nbOfTuplesThis==nbOfTuples)
7367     return deepCpy();
7368   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
7369   ret->alloc(nbOfTuples,nbOfComp);
7370   ret->copyStringInfoFrom(*this);
7371   const int *src=getConstPointer();
7372   int *work=ret->getPointer();
7373   for(std::vector<std::pair<int,int> >::const_iterator it=ranges.begin();it!=ranges.end();it++)
7374     work=std::copy(src+(*it).first*nbOfComp,src+(*it).second*nbOfComp,work);
7375   return ret.retn();
7376 }
7377
7378 /*!
7379  * Returns a new DataArrayInt containing a renumbering map in "Old to New" mode.
7380  * This map, if applied to \a this array, would make it sorted. For example, if
7381  * \a this array contents are [9,10,0,6,4,11,3,7] then the contents of the result array
7382  * are [5,6,0,3,2,7,1,4]; if this result array (\a res) is used as an argument in call
7383  * \a this->renumber(\a res) then the returned array contains [0,3,4,6,7,9,10,11].
7384  * This method is useful for renumbering (in MED file for example). For more info
7385  * on renumbering see \ref MEDCouplingArrayRenumbering.
7386  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
7387  *          array using decrRef() as it is no more needed.
7388  *  \throw If \a this is not allocated.
7389  *  \throw If \a this->getNumberOfComponents() != 1.
7390  *  \throw If there are equal values in \a this array.
7391  */
7392 DataArrayInt *DataArrayInt::checkAndPreparePermutation() const
7393 {
7394   checkAllocated();
7395   if(getNumberOfComponents()!=1)
7396     throw INTERP_KERNEL::Exception("DataArrayInt::checkAndPreparePermutation : number of components must == 1 !");
7397   int nbTuples=getNumberOfTuples();
7398   const int *pt=getConstPointer();
7399   int *pt2=CheckAndPreparePermutation(pt,pt+nbTuples);
7400   DataArrayInt *ret=DataArrayInt::New();
7401   ret->useArray(pt2,true,C_DEALLOC,nbTuples,1);
7402   return ret;
7403 }
7404
7405 /*!
7406  * 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
7407  * input array \a ids2.
7408  * \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.
7409  * 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
7410  * inversely.
7411  * In case of success (no throw) : \c ids1->renumber(ret)->isEqual(ids2) where \a ret is the return of this method.
7412  *
7413  * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
7414  *          array using decrRef() as it is no more needed.
7415  * \throw If either ids1 or ids2 is null not allocated or not with one components.
7416  * 
7417  */
7418 DataArrayInt *DataArrayInt::FindPermutationFromFirstToSecond(const DataArrayInt *ids1, const DataArrayInt *ids2)
7419 {
7420   if(!ids1 || !ids2)
7421     throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two input arrays must be not null !");
7422   if(!ids1->isAllocated() || !ids2->isAllocated())
7423     throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two input arrays must be allocated !");
7424   if(ids1->getNumberOfComponents()!=1 || ids2->getNumberOfComponents()!=1)
7425     throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two input arrays have exactly one component !");
7426   if(ids1->getNumberOfTuples()!=ids2->getNumberOfTuples())
7427     {
7428       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 !";
7429       throw INTERP_KERNEL::Exception(oss.str().c_str());
7430     }
7431   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> p1(ids1->deepCpy());
7432   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> p2(ids2->deepCpy());
7433   p1->sort(true); p2->sort(true);
7434   if(!p1->isEqualWithoutConsideringStr(*p2))
7435     throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two arrays are not lying on same ids ! Impossible to find a permutation between the 2 arrays !");
7436   p1=ids1->checkAndPreparePermutation();
7437   p2=ids2->checkAndPreparePermutation();
7438   p2=p2->invertArrayO2N2N2O(p2->getNumberOfTuples());
7439   p2=p2->selectByTupleIdSafe(p1->begin(),p1->end());
7440   return p2.retn();
7441 }
7442
7443 /*!
7444  * Returns two arrays describing a surjective mapping from \a this set of values (\a A)
7445  * onto a set of values of size \a targetNb (\a B). The surjective function is 
7446  * \a B[ \a A[ i ]] = i. That is to say that for each \a id in [0,\a targetNb), where \a
7447  * targetNb < \a this->getNumberOfTuples(), there exists at least one tupleId (\a tid) so
7448  * that <em> this->getIJ( tid, 0 ) == id</em>. <br>
7449  * The first of out arrays returns indices of elements of \a this array, grouped by their
7450  * place in the set \a B. The second out array is the index of the first one; it shows how
7451  * many elements of \a A are mapped into each element of \a B. <br>
7452  * For more info on
7453  * mapping and its usage in renumbering see \ref MEDCouplingArrayRenumbering. <br>
7454  * \b Example:
7455  * - \a this: [0,3,2,3,2,2,1,2]
7456  * - \a targetNb: 4
7457  * - \a arr:  [0,  6,  2,4,5,7,  1,3]
7458  * - \a arrI: [0,1,2,6,8]
7459  *
7460  * This result means: <br>
7461  * the element of \a B 0 encounters within \a A once (\a arrI[ 0+1 ] - \a arrI[ 0 ]) and
7462  * its index within \a A is 0 ( \a arr[ 0:1 ] == \a arr[ \a arrI[ 0 ] : \a arrI[ 0+1 ]]);<br>
7463  * the element of \a B 2 encounters within \a A 4 times (\a arrI[ 2+1 ] - \a arrI[ 2 ]) and
7464  * its indices within \a A are [2,4,5,7] ( \a arr[ 2:6 ] == \a arr[ \a arrI[ 2 ] : 
7465  * \a arrI[ 2+1 ]]); <br> etc.
7466  *  \param [in] targetNb - the size of the set \a B. \a targetNb must be equal or more
7467  *         than the maximal value of \a A.
7468  *  \param [out] arr - a new instance of DataArrayInt returning indices of
7469  *         elements of \a this, grouped by their place in the set \a B. The caller is to delete
7470  *         this array using decrRef() as it is no more needed.
7471  *  \param [out] arrI - a new instance of DataArrayInt returning size of groups of equal
7472  *         elements of \a this. The caller is to delete this array using decrRef() as it
7473  *         is no more needed.
7474  *  \throw If \a this is not allocated.
7475  *  \throw If \a this->getNumberOfComponents() != 1.
7476  *  \throw If any value in \a this is more or equal to \a targetNb.
7477  */
7478 void DataArrayInt::changeSurjectiveFormat(int targetNb, DataArrayInt *&arr, DataArrayInt *&arrI) const
7479 {
7480   checkAllocated();
7481   if(getNumberOfComponents()!=1)
7482     throw INTERP_KERNEL::Exception("DataArrayInt::changeSurjectiveFormat : number of components must == 1 !");
7483   int nbOfTuples=getNumberOfTuples();
7484   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New());
7485   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> retI(DataArrayInt::New());
7486   retI->alloc(targetNb+1,1);
7487   const int *input=getConstPointer();
7488   std::vector< std::vector<int> > tmp(targetNb);
7489   for(int i=0;i<nbOfTuples;i++)
7490     {
7491       int tmp2=input[i];
7492       if(tmp2>=0 && tmp2<targetNb)
7493         tmp[tmp2].push_back(i);
7494       else
7495         {
7496           std::ostringstream oss; oss << "DataArrayInt::changeSurjectiveFormat : At pos " << i << " presence of element " << tmp2 << " ! should be in [0," << targetNb << ") !";
7497           throw INTERP_KERNEL::Exception(oss.str().c_str());
7498         }
7499     }
7500   int *retIPtr=retI->getPointer();
7501   *retIPtr=0;
7502   for(std::vector< std::vector<int> >::const_iterator it1=tmp.begin();it1!=tmp.end();it1++,retIPtr++)
7503     retIPtr[1]=retIPtr[0]+(int)((*it1).size());
7504   if(nbOfTuples!=retI->getIJ(targetNb,0))
7505     throw INTERP_KERNEL::Exception("DataArrayInt::changeSurjectiveFormat : big problem should never happen !");
7506   ret->alloc(nbOfTuples,1);
7507   int *retPtr=ret->getPointer();
7508   for(std::vector< std::vector<int> >::const_iterator it1=tmp.begin();it1!=tmp.end();it1++)
7509     retPtr=std::copy((*it1).begin(),(*it1).end(),retPtr);
7510   arr=ret.retn();
7511   arrI=retI.retn();
7512 }
7513
7514
7515 /*!
7516  * Returns a new DataArrayInt containing a renumbering map in "Old to New" mode computed
7517  * from a zip representation of a surjective format (returned e.g. by
7518  * \ref ParaMEDMEM::DataArrayDouble::findCommonTuples() "DataArrayDouble::findCommonTuples()"
7519  * for example). The result array minimizes the permutation. <br>
7520  * For more info on renumbering see \ref MEDCouplingArrayRenumbering. <br>
7521  * \b Example: <br>
7522  * - \a nbOfOldTuples: 10 
7523  * - \a arr          : [0,3, 5,7,9]
7524  * - \a arrIBg       : [0,2,5]
7525  * - \a newNbOfTuples: 7
7526  * - result array    : [0,1,2,0,3,4,5,4,6,4]
7527  *
7528  *  \param [in] nbOfOldTuples - number of tuples in the initial array \a arr.
7529  *  \param [in] arr - the array of tuple indices grouped by \a arrIBg array.
7530  *  \param [in] arrIBg - the array dividing all indices stored in \a arr into groups of
7531  *         (indices of) equal values. Its every element (except the last one) points to
7532  *         the first element of a group of equal values.
7533  *  \param [in] arrIEnd - specifies the end of \a arrIBg, so that the last element of \a
7534  *          arrIBg is \a arrIEnd[ -1 ].
7535  *  \param [out] newNbOfTuples - number of tuples after surjection application.
7536  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
7537  *          array using decrRef() as it is no more needed.
7538  *  \throw If any value of \a arr breaks condition ( 0 <= \a arr[ i ] < \a nbOfOldTuples ).
7539  */
7540 DataArrayInt *DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2(int nbOfOldTuples, const int *arr, const int *arrIBg, const int *arrIEnd, int &newNbOfTuples)
7541 {
7542   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
7543   ret->alloc(nbOfOldTuples,1);
7544   int *pt=ret->getPointer();
7545   std::fill(pt,pt+nbOfOldTuples,-1);
7546   int nbOfGrps=((int)std::distance(arrIBg,arrIEnd))-1;
7547   const int *cIPtr=arrIBg;
7548   for(int i=0;i<nbOfGrps;i++)
7549     pt[arr[cIPtr[i]]]=-(i+2);
7550   int newNb=0;
7551   for(int iNode=0;iNode<nbOfOldTuples;iNode++)
7552     {
7553       if(pt[iNode]<0)
7554         {
7555           if(pt[iNode]==-1)
7556             pt[iNode]=newNb++;
7557           else
7558             {
7559               int grpId=-(pt[iNode]+2);
7560               for(int j=cIPtr[grpId];j<cIPtr[grpId+1];j++)
7561                 {
7562                   if(arr[j]>=0 && arr[j]<nbOfOldTuples)
7563                     pt[arr[j]]=newNb;
7564                   else
7565                     {
7566                       std::ostringstream oss; oss << "DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2 : With element #" << j << " value is " << arr[j] << " should be in [0," << nbOfOldTuples << ") !";
7567                       throw INTERP_KERNEL::Exception(oss.str().c_str());
7568                     }
7569                 }
7570               newNb++;
7571             }
7572         }
7573     }
7574   newNbOfTuples=newNb;
7575   return ret.retn();
7576 }
7577
7578 /*!
7579  * Returns a new DataArrayInt containing a renumbering map in "New to Old" mode,
7580  * which if applied to \a this array would make it sorted ascendingly.
7581  * For more info on renumbering see \ref MEDCouplingArrayRenumbering. <br>
7582  * \b Example: <br>
7583  * - \a this: [2,0,1,1,0,1,2,0,1,1,0,0]
7584  * - result: [10,0,5,6,1,7,11,2,8,9,3,4]
7585  * - after applying result to \a this: [0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2] 
7586  *
7587  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
7588  *          array using decrRef() as it is no more needed.
7589  *  \throw If \a this is not allocated.
7590  *  \throw If \a this->getNumberOfComponents() != 1.
7591  */
7592 DataArrayInt *DataArrayInt::buildPermArrPerLevel() const
7593 {
7594   checkAllocated();
7595   if(getNumberOfComponents()!=1)
7596     throw INTERP_KERNEL::Exception("DataArrayInt::buildPermArrPerLevel : number of components must == 1 !");
7597   int nbOfTuples=getNumberOfTuples();
7598   const int *pt=getConstPointer();
7599   std::map<int,int> m;
7600   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
7601   ret->alloc(nbOfTuples,1);
7602   int *opt=ret->getPointer();
7603   for(int i=0;i<nbOfTuples;i++,pt++,opt++)
7604     {
7605       int val=*pt;
7606       std::map<int,int>::iterator it=m.find(val);
7607       if(it!=m.end())
7608         {
7609           *opt=(*it).second;
7610           (*it).second++;
7611         }
7612       else
7613         {
7614           *opt=0;
7615           m.insert(std::pair<int,int>(val,1));
7616         }
7617     }
7618   int sum=0;
7619   for(std::map<int,int>::iterator it=m.begin();it!=m.end();it++)
7620     {
7621       int vt=(*it).second;
7622       (*it).second=sum;
7623       sum+=vt;
7624     }
7625   pt=getConstPointer();
7626   opt=ret->getPointer();
7627   for(int i=0;i<nbOfTuples;i++,pt++,opt++)
7628     *opt+=m[*pt];
7629   //
7630   return ret.retn();
7631 }
7632
7633 /*!
7634  * Checks if contents of \a this array are equal to that of an array filled with
7635  * iota(). This method is particularly useful for DataArrayInt instances that represent
7636  * a renumbering array to check the real need in renumbering. 
7637  *  \return bool - \a true if \a this array contents == \a range( \a this->getNumberOfTuples())
7638  *  \throw If \a this is not allocated.
7639  *  \throw If \a this->getNumberOfComponents() != 1.
7640  */
7641 bool DataArrayInt::isIdentity() const
7642 {
7643   checkAllocated();
7644   if(getNumberOfComponents()!=1)
7645     return false;
7646   int nbOfTuples=getNumberOfTuples();
7647   const int *pt=getConstPointer();
7648   for(int i=0;i<nbOfTuples;i++,pt++)
7649     if(*pt!=i)
7650       return false;
7651   return true;
7652 }
7653
7654 /*!
7655  * Checks if all values in \a this array are equal to \a val.
7656  *  \param [in] val - value to check equality of array values to.
7657  *  \return bool - \a true if all values are \a val.
7658  *  \throw If \a this is not allocated.
7659  *  \throw If \a this->getNumberOfComponents() != 1
7660  */
7661 bool DataArrayInt::isUniform(int val) const
7662 {
7663   checkAllocated();
7664   if(getNumberOfComponents()!=1)
7665     throw INTERP_KERNEL::Exception("DataArrayInt::isUniform : must be applied on DataArrayInt with only one component, you can call 'rearrange' method before !");
7666   int nbOfTuples=getNumberOfTuples();
7667   const int *w=getConstPointer();
7668   const int *end2=w+nbOfTuples;
7669   for(;w!=end2;w++)
7670     if(*w!=val)
7671       return false;
7672   return true;
7673 }
7674
7675 /*!
7676  * Creates a new DataArrayDouble and assigns all (textual and numerical) data of \a this
7677  * array to the new one.
7678  *  \return DataArrayDouble * - the new instance of DataArrayInt.
7679  */
7680 DataArrayDouble *DataArrayInt::convertToDblArr() const
7681 {
7682   checkAllocated();
7683   DataArrayDouble *ret=DataArrayDouble::New();
7684   ret->alloc(getNumberOfTuples(),getNumberOfComponents());
7685   std::size_t nbOfVals=getNbOfElems();
7686   const int *src=getConstPointer();
7687   double *dest=ret->getPointer();
7688   std::copy(src,src+nbOfVals,dest);
7689   ret->copyStringInfoFrom(*this);
7690   return ret;
7691 }
7692
7693 /*!
7694  * Returns a shorten copy of \a this array. The new DataArrayInt contains all
7695  * tuples starting from the \a tupleIdBg-th tuple and including all tuples located before
7696  * the \a tupleIdEnd-th one. This methods has a similar behavior as std::string::substr().
7697  * This method is a specialization of selectByTupleId2().
7698  *  \param [in] tupleIdBg - index of the first tuple to copy from \a this array.
7699  *  \param [in] tupleIdEnd - index of the tuple before which the tuples to copy are located.
7700  *          If \a tupleIdEnd == -1, all the tuples till the end of \a this array are copied.
7701  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
7702  *          is to delete using decrRef() as it is no more needed.
7703  *  \throw If \a tupleIdBg < 0.
7704  *  \throw If \a tupleIdBg > \a this->getNumberOfTuples().
7705     \throw If \a tupleIdEnd != -1 && \a tupleIdEnd < \a this->getNumberOfTuples().
7706  *  \sa DataArrayInt::selectByTupleId2
7707  */
7708 DataArrayInt *DataArrayInt::substr(int tupleIdBg, int tupleIdEnd) const
7709 {
7710   checkAllocated();
7711   int nbt=getNumberOfTuples();
7712   if(tupleIdBg<0)
7713     throw INTERP_KERNEL::Exception("DataArrayInt::substr : The tupleIdBg parameter must be greater than 0 !");
7714   if(tupleIdBg>nbt)
7715     throw INTERP_KERNEL::Exception("DataArrayInt::substr : The tupleIdBg parameter is greater than number of tuples !");
7716   int trueEnd=tupleIdEnd;
7717   if(tupleIdEnd!=-1)
7718     {
7719       if(tupleIdEnd>nbt)
7720         throw INTERP_KERNEL::Exception("DataArrayInt::substr : The tupleIdBg parameter is greater or equal than number of tuples !");
7721     }
7722   else
7723     trueEnd=nbt;
7724   int nbComp=getNumberOfComponents();
7725   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
7726   ret->alloc(trueEnd-tupleIdBg,nbComp);
7727   ret->copyStringInfoFrom(*this);
7728   std::copy(getConstPointer()+tupleIdBg*nbComp,getConstPointer()+trueEnd*nbComp,ret->getPointer());
7729   return ret.retn();
7730 }
7731
7732 /*!
7733  * Changes the number of components within \a this array so that its raw data **does
7734  * not** change, instead splitting this data into tuples changes.
7735  *  \warning This method erases all (name and unit) component info set before!
7736  *  \param [in] newNbOfComp - number of components for \a this array to have.
7737  *  \throw If \a this is not allocated
7738  *  \throw If getNbOfElems() % \a newNbOfCompo != 0.
7739  *  \throw If \a newNbOfCompo is lower than 1.
7740  *  \throw If the rearrange method would lead to a number of tuples higher than 2147483647 (maximal capacity of int32 !).
7741  *  \warning This method erases all (name and unit) component info set before!
7742  */
7743 void DataArrayInt::rearrange(int newNbOfCompo)
7744 {
7745   checkAllocated();
7746   if(newNbOfCompo<1)
7747     throw INTERP_KERNEL::Exception("DataArrayInt::rearrange : input newNbOfCompo must be > 0 !");
7748   std::size_t nbOfElems=getNbOfElems();
7749   if(nbOfElems%newNbOfCompo!=0)
7750     throw INTERP_KERNEL::Exception("DataArrayInt::rearrange : nbOfElems%newNbOfCompo!=0 !");
7751   if(nbOfElems/newNbOfCompo>(std::size_t)std::numeric_limits<int>::max())
7752     throw INTERP_KERNEL::Exception("DataArrayInt::rearrange : the rearrangement leads to too high number of tuples (> 2147483647) !");
7753   _info_on_compo.clear();
7754   _info_on_compo.resize(newNbOfCompo);
7755   declareAsNew();
7756 }
7757
7758 /*!
7759  * Changes the number of components within \a this array to be equal to its number
7760  * of tuples, and inversely its number of tuples to become equal to its number of 
7761  * components. So that its raw data **does not** change, instead splitting this
7762  * data into tuples changes.
7763  *  \warning This method erases all (name and unit) component info set before!
7764  *  \warning Do not confuse this method with fromNoInterlace() and toNoInterlace()!
7765  *  \throw If \a this is not allocated.
7766  *  \sa rearrange()
7767  */
7768 void DataArrayInt::transpose()
7769 {
7770   checkAllocated();
7771   int nbOfTuples=getNumberOfTuples();
7772   rearrange(nbOfTuples);
7773 }
7774
7775 /*!
7776  * Returns a shorten or extended copy of \a this array. If \a newNbOfComp is less
7777  * than \a this->getNumberOfComponents() then the result array is shorten as each tuple
7778  * is truncated to have \a newNbOfComp components, keeping first components. If \a
7779  * newNbOfComp is more than \a this->getNumberOfComponents() then the result array is
7780  * expanded as each tuple is populated with \a dftValue to have \a newNbOfComp
7781  * components.  
7782  *  \param [in] newNbOfComp - number of components for the new array to have.
7783  *  \param [in] dftValue - value assigned to new values added to the new array.
7784  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
7785  *          is to delete using decrRef() as it is no more needed.
7786  *  \throw If \a this is not allocated.
7787  */
7788 DataArrayInt *DataArrayInt::changeNbOfComponents(int newNbOfComp, int dftValue) const
7789 {
7790   checkAllocated();
7791   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
7792   ret->alloc(getNumberOfTuples(),newNbOfComp);
7793   const int *oldc=getConstPointer();
7794   int *nc=ret->getPointer();
7795   int nbOfTuples=getNumberOfTuples();
7796   int oldNbOfComp=getNumberOfComponents();
7797   int dim=std::min(oldNbOfComp,newNbOfComp);
7798   for(int i=0;i<nbOfTuples;i++)
7799     {
7800       int j=0;
7801       for(;j<dim;j++)
7802         nc[newNbOfComp*i+j]=oldc[i*oldNbOfComp+j];
7803       for(;j<newNbOfComp;j++)
7804         nc[newNbOfComp*i+j]=dftValue;
7805     }
7806   ret->setName(getName());
7807   for(int i=0;i<dim;i++)
7808     ret->setInfoOnComponent(i,getInfoOnComponent(i));
7809   ret->setName(getName());
7810   return ret.retn();
7811 }
7812
7813 /*!
7814  * Changes number of tuples in the array. If the new number of tuples is smaller
7815  * than the current number the array is truncated, otherwise the array is extended.
7816  *  \param [in] nbOfTuples - new number of tuples. 
7817  *  \throw If \a this is not allocated.
7818  *  \throw If \a nbOfTuples is negative.
7819  */
7820 void DataArrayInt::reAlloc(int nbOfTuples)
7821 {
7822   if(nbOfTuples<0)
7823     throw INTERP_KERNEL::Exception("DataArrayInt::reAlloc : input new number of tuples should be >=0 !");
7824   checkAllocated();
7825   _mem.reAlloc(getNumberOfComponents()*(std::size_t)nbOfTuples);
7826   declareAsNew();
7827 }
7828
7829
7830 /*!
7831  * Returns a copy of \a this array composed of selected components.
7832  * The new DataArrayInt has the same number of tuples but includes components
7833  * specified by \a compoIds parameter. So that getNbOfElems() of the result array
7834  * can be either less, same or more than \a this->getNbOfElems().
7835  *  \param [in] compoIds - sequence of zero based indices of components to include
7836  *              into the new array.
7837  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
7838  *          is to delete using decrRef() as it is no more needed.
7839  *  \throw If \a this is not allocated.
7840  *  \throw If a component index (\a i) is not valid: 
7841  *         \a i < 0 || \a i >= \a this->getNumberOfComponents().
7842  *
7843  *  \if ENABLE_EXAMPLES
7844  *  \ref py_mcdataarrayint_keepselectedcomponents "Here is a Python example".
7845  *  \endif
7846  */
7847 DataArrayInt *DataArrayInt::keepSelectedComponents(const std::vector<int>& compoIds) const
7848 {
7849   checkAllocated();
7850   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New());
7851   int newNbOfCompo=(int)compoIds.size();
7852   int oldNbOfCompo=getNumberOfComponents();
7853   for(std::vector<int>::const_iterator it=compoIds.begin();it!=compoIds.end();it++)
7854     DataArray::CheckValueInRange(oldNbOfCompo,(*it),"keepSelectedComponents invalid requested component");
7855   int nbOfTuples=getNumberOfTuples();
7856   ret->alloc(nbOfTuples,newNbOfCompo);
7857   ret->copyPartOfStringInfoFrom(*this,compoIds);
7858   const int *oldc=getConstPointer();
7859   int *nc=ret->getPointer();
7860   for(int i=0;i<nbOfTuples;i++)
7861     for(int j=0;j<newNbOfCompo;j++,nc++)
7862       *nc=oldc[i*oldNbOfCompo+compoIds[j]];
7863   return ret.retn();
7864 }
7865
7866 /*!
7867  * Appends components of another array to components of \a this one, tuple by tuple.
7868  * So that the number of tuples of \a this array remains the same and the number of 
7869  * components increases.
7870  *  \param [in] other - the DataArrayInt to append to \a this one.
7871  *  \throw If \a this is not allocated.
7872  *  \throw If \a this and \a other arrays have different number of tuples.
7873  *
7874  *  \if ENABLE_EXAMPLES
7875  *  \ref cpp_mcdataarrayint_meldwith "Here is a C++ example".
7876  *
7877  *  \ref py_mcdataarrayint_meldwith "Here is a Python example".
7878  *  \endif
7879  */
7880 void DataArrayInt::meldWith(const DataArrayInt *other)
7881 {
7882   if(!other)
7883     throw INTERP_KERNEL::Exception("DataArrayInt::meldWith : DataArrayInt pointer in input is NULL !");
7884   checkAllocated();
7885   other->checkAllocated();
7886   int nbOfTuples=getNumberOfTuples();
7887   if(nbOfTuples!=other->getNumberOfTuples())
7888     throw INTERP_KERNEL::Exception("DataArrayInt::meldWith : mismatch of number of tuples !");
7889   int nbOfComp1=getNumberOfComponents();
7890   int nbOfComp2=other->getNumberOfComponents();
7891   int *newArr=(int *)malloc(nbOfTuples*(nbOfComp1+nbOfComp2)*sizeof(int));
7892   int *w=newArr;
7893   const int *inp1=getConstPointer();
7894   const int *inp2=other->getConstPointer();
7895   for(int i=0;i<nbOfTuples;i++,inp1+=nbOfComp1,inp2+=nbOfComp2)
7896     {
7897       w=std::copy(inp1,inp1+nbOfComp1,w);
7898       w=std::copy(inp2,inp2+nbOfComp2,w);
7899     }
7900   useArray(newArr,true,C_DEALLOC,nbOfTuples,nbOfComp1+nbOfComp2);
7901   std::vector<int> compIds(nbOfComp2);
7902   for(int i=0;i<nbOfComp2;i++)
7903     compIds[i]=nbOfComp1+i;
7904   copyPartOfStringInfoFrom2(compIds,*other);
7905 }
7906
7907 /*!
7908  * Copy all components in a specified order from another DataArrayInt.
7909  * The specified components become the first ones in \a this array.
7910  * Both numerical and textual data is copied. The number of tuples in \a this and
7911  * the other array can be different.
7912  *  \param [in] a - the array to copy data from.
7913  *  \param [in] compoIds - sequence of zero based indices of components, data of which is
7914  *              to be copied.
7915  *  \throw If \a a is NULL.
7916  *  \throw If \a compoIds.size() != \a a->getNumberOfComponents().
7917  *  \throw If \a compoIds[i] < 0 or \a compoIds[i] > \a this->getNumberOfComponents().
7918  *
7919  *  \if ENABLE_EXAMPLES
7920  *  \ref py_mcdataarrayint_setselectedcomponents "Here is a Python example".
7921  *  \endif
7922  */
7923 void DataArrayInt::setSelectedComponents(const DataArrayInt *a, const std::vector<int>& compoIds)
7924 {
7925   if(!a)
7926     throw INTERP_KERNEL::Exception("DataArrayInt::setSelectedComponents : input DataArrayInt is NULL !");
7927   checkAllocated();
7928   a->checkAllocated();
7929   copyPartOfStringInfoFrom2(compoIds,*a);
7930   std::size_t partOfCompoSz=compoIds.size();
7931   int nbOfCompo=getNumberOfComponents();
7932   int nbOfTuples=std::min(getNumberOfTuples(),a->getNumberOfTuples());
7933   const int *ac=a->getConstPointer();
7934   int *nc=getPointer();
7935   for(int i=0;i<nbOfTuples;i++)
7936     for(std::size_t j=0;j<partOfCompoSz;j++,ac++)
7937       nc[nbOfCompo*i+compoIds[j]]=*ac;
7938 }
7939
7940 /*!
7941  * Copy all values from another DataArrayInt into specified tuples and components
7942  * of \a this array. Textual data is not copied.
7943  * The tree parameters defining set of indices of tuples and components are similar to
7944  * the tree parameters of the Python function \c range(\c start,\c stop,\c step).
7945  *  \param [in] a - the array to copy values from.
7946  *  \param [in] bgTuples - index of the first tuple of \a this array to assign values to.
7947  *  \param [in] endTuples - index of the tuple before which the tuples to assign to
7948  *              are located.
7949  *  \param [in] stepTuples - index increment to get index of the next tuple to assign to.
7950  *  \param [in] bgComp - index of the first component of \a this array to assign values to.
7951  *  \param [in] endComp - index of the component before which the components to assign
7952  *              to are located.
7953  *  \param [in] stepComp - index increment to get index of the next component to assign to.
7954  *  \param [in] strictCompoCompare - if \a true (by default), then \a a->getNumberOfComponents() 
7955  *              must be equal to the number of columns to assign to, else an
7956  *              exception is thrown; if \a false, then it is only required that \a
7957  *              a->getNbOfElems() equals to number of values to assign to (this condition
7958  *              must be respected even if \a strictCompoCompare is \a true). The number of 
7959  *              values to assign to is given by following Python expression:
7960  *              \a nbTargetValues = 
7961  *              \c len(\c range(\a bgTuples,\a endTuples,\a stepTuples)) *
7962  *              \c len(\c range(\a bgComp,\a endComp,\a stepComp)).
7963  *  \throw If \a a is NULL.
7964  *  \throw If \a a is not allocated.
7965  *  \throw If \a this is not allocated.
7966  *  \throw If parameters specifying tuples and components to assign to do not give a
7967  *            non-empty range of increasing indices.
7968  *  \throw If \a a->getNbOfElems() != \a nbTargetValues.
7969  *  \throw If \a strictCompoCompare == \a true && \a a->getNumberOfComponents() !=
7970  *            \c len(\c range(\a bgComp,\a endComp,\a stepComp)).
7971  *
7972  *  \if ENABLE_EXAMPLES
7973  *  \ref py_mcdataarrayint_setpartofvalues1 "Here is a Python example".
7974  *  \endif
7975  */
7976 void DataArrayInt::setPartOfValues1(const DataArrayInt *a, int bgTuples, int endTuples, int stepTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare)
7977 {
7978   if(!a)
7979     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValues1 : DataArrayInt pointer in input is NULL !");
7980   const char msg[]="DataArrayInt::setPartOfValues1";
7981   checkAllocated();
7982   a->checkAllocated();
7983   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
7984   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
7985   int nbComp=getNumberOfComponents();
7986   int nbOfTuples=getNumberOfTuples();
7987   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
7988   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
7989   bool assignTech=true;
7990   if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
7991     {
7992       if(strictCompoCompare)
7993         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
7994     }
7995   else
7996     {
7997       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
7998       assignTech=false;
7999     }
8000   int *pt=getPointer()+bgTuples*nbComp+bgComp;
8001   const int *srcPt=a->getConstPointer();
8002   if(assignTech)
8003     {
8004       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
8005         for(int j=0;j<newNbOfComp;j++,srcPt++)
8006           pt[j*stepComp]=*srcPt;
8007     }
8008   else
8009     {
8010       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
8011         {
8012           const int *srcPt2=srcPt;
8013           for(int j=0;j<newNbOfComp;j++,srcPt2++)
8014             pt[j*stepComp]=*srcPt2;
8015         }
8016     }
8017 }
8018
8019 /*!
8020  * Assign a given value to values at specified tuples and components of \a this array.
8021  * The tree parameters defining set of indices of tuples and components are similar to
8022  * the tree parameters of the Python function \c range(\c start,\c stop,\c step)..
8023  *  \param [in] a - the value to assign.
8024  *  \param [in] bgTuples - index of the first tuple of \a this array to assign to.
8025  *  \param [in] endTuples - index of the tuple before which the tuples to assign to
8026  *              are located.
8027  *  \param [in] stepTuples - index increment to get index of the next tuple to assign to.
8028  *  \param [in] bgComp - index of the first component of \a this array to assign to.
8029  *  \param [in] endComp - index of the component before which the components to assign
8030  *              to are located.
8031  *  \param [in] stepComp - index increment to get index of the next component to assign to.
8032  *  \throw If \a this is not allocated.
8033  *  \throw If parameters specifying tuples and components to assign to, do not give a
8034  *            non-empty range of increasing indices or indices are out of a valid range
8035  *            for \this array.
8036  *
8037  *  \if ENABLE_EXAMPLES
8038  *  \ref py_mcdataarrayint_setpartofvaluessimple1 "Here is a Python example".
8039  *  \endif
8040  */
8041 void DataArrayInt::setPartOfValuesSimple1(int a, int bgTuples, int endTuples, int stepTuples, int bgComp, int endComp, int stepComp)
8042 {
8043   const char msg[]="DataArrayInt::setPartOfValuesSimple1";
8044   checkAllocated();
8045   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
8046   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
8047   int nbComp=getNumberOfComponents();
8048   int nbOfTuples=getNumberOfTuples();
8049   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
8050   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
8051   int *pt=getPointer()+bgTuples*nbComp+bgComp;
8052   for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
8053     for(int j=0;j<newNbOfComp;j++)
8054       pt[j*stepComp]=a;
8055 }
8056
8057
8058 /*!
8059  * Copy all values from another DataArrayInt (\a a) into specified tuples and 
8060  * components of \a this array. Textual data is not copied.
8061  * The tuples and components to assign to are defined by C arrays of indices.
8062  * There are two *modes of usage*:
8063  * - If \a a->getNbOfElems() equals to number of values to assign to, then every value
8064  *   of \a a is assigned to its own location within \a this array. 
8065  * - If \a a includes one tuple, then all values of \a a are assigned to the specified
8066  *   components of every specified tuple of \a this array. In this mode it is required
8067  *   that \a a->getNumberOfComponents() equals to the number of specified components.
8068  * 
8069  *  \param [in] a - the array to copy values from.
8070  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
8071  *              assign values of \a a to.
8072  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
8073  *              pointer to a tuple index <em>(pi)</em> varies as this: 
8074  *              \a bgTuples <= \a pi < \a endTuples.
8075  *  \param [in] bgComp - pointer to an array of component indices of \a this array to
8076  *              assign values of \a a to.
8077  *  \param [in] endComp - specifies the end of the array \a bgTuples, so that
8078  *              pointer to a component index <em>(pi)</em> varies as this: 
8079  *              \a bgComp <= \a pi < \a endComp.
8080  *  \param [in] strictCompoCompare - this parameter is checked only if the
8081  *               *mode of usage* is the first; if it is \a true (default), 
8082  *               then \a a->getNumberOfComponents() must be equal 
8083  *               to the number of specified columns, else this is not required.
8084  *  \throw If \a a is NULL.
8085  *  \throw If \a a is not allocated.
8086  *  \throw If \a this is not allocated.
8087  *  \throw If any index of tuple/component given by <em>bgTuples / bgComp</em> is
8088  *         out of a valid range for \a this array.
8089  *  \throw In the first *mode of usage*, if <em>strictCompoCompare == true </em> and
8090  *         if <em> a->getNumberOfComponents() != (endComp - bgComp) </em>.
8091  *  \throw In the second *mode of usage*, if \a a->getNumberOfTuples() != 1 or
8092  *         <em> a->getNumberOfComponents() != (endComp - bgComp)</em>.
8093  *
8094  *  \if ENABLE_EXAMPLES
8095  *  \ref py_mcdataarrayint_setpartofvalues2 "Here is a Python example".
8096  *  \endif
8097  */
8098 void DataArrayInt::setPartOfValues2(const DataArrayInt *a, const int *bgTuples, const int *endTuples, const int *bgComp, const int *endComp, bool strictCompoCompare)
8099 {
8100   if(!a)
8101     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValues2 : DataArrayInt pointer in input is NULL !");
8102   const char msg[]="DataArrayInt::setPartOfValues2";
8103   checkAllocated();
8104   a->checkAllocated();
8105   int nbComp=getNumberOfComponents();
8106   int nbOfTuples=getNumberOfTuples();
8107   for(const int *z=bgComp;z!=endComp;z++)
8108     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
8109   int newNbOfTuples=(int)std::distance(bgTuples,endTuples);
8110   int newNbOfComp=(int)std::distance(bgComp,endComp);
8111   bool assignTech=true;
8112   if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
8113     {
8114       if(strictCompoCompare)
8115         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
8116     }
8117   else
8118     {
8119       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
8120       assignTech=false;
8121     }
8122   int *pt=getPointer();
8123   const int *srcPt=a->getConstPointer();
8124   if(assignTech)
8125     {    
8126       for(const int *w=bgTuples;w!=endTuples;w++)
8127         {
8128           DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
8129           for(const int *z=bgComp;z!=endComp;z++,srcPt++)
8130             {    
8131               pt[(std::size_t)(*w)*nbComp+(*z)]=*srcPt;
8132             }
8133         }
8134     }
8135   else
8136     {
8137       for(const int *w=bgTuples;w!=endTuples;w++)
8138         {
8139           const int *srcPt2=srcPt;
8140           DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
8141           for(const int *z=bgComp;z!=endComp;z++,srcPt2++)
8142             {    
8143               pt[(std::size_t)(*w)*nbComp+(*z)]=*srcPt2;
8144             }
8145         }
8146     }
8147 }
8148
8149 /*!
8150  * Assign a given value to values at specified tuples and components of \a this array.
8151  * The tuples and components to assign to are defined by C arrays of indices.
8152  *  \param [in] a - the value to assign.
8153  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
8154  *              assign \a a to.
8155  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
8156  *              pointer to a tuple index (\a pi) varies as this: 
8157  *              \a bgTuples <= \a pi < \a endTuples.
8158  *  \param [in] bgComp - pointer to an array of component indices of \a this array to
8159  *              assign \a a to.
8160  *  \param [in] endComp - specifies the end of the array \a bgTuples, so that
8161  *              pointer to a component index (\a pi) varies as this: 
8162  *              \a bgComp <= \a pi < \a endComp.
8163  *  \throw If \a this is not allocated.
8164  *  \throw If any index of tuple/component given by <em>bgTuples / bgComp</em> is
8165  *         out of a valid range for \a this array.
8166  *
8167  *  \if ENABLE_EXAMPLES
8168  *  \ref py_mcdataarrayint_setpartofvaluessimple2 "Here is a Python example".
8169  *  \endif
8170  */
8171 void DataArrayInt::setPartOfValuesSimple2(int a, const int *bgTuples, const int *endTuples, const int *bgComp, const int *endComp)
8172 {
8173   checkAllocated();
8174   int nbComp=getNumberOfComponents();
8175   int nbOfTuples=getNumberOfTuples();
8176   for(const int *z=bgComp;z!=endComp;z++)
8177     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
8178   int *pt=getPointer();
8179   for(const int *w=bgTuples;w!=endTuples;w++)
8180     for(const int *z=bgComp;z!=endComp;z++)
8181       {
8182         DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
8183         pt[(std::size_t)(*w)*nbComp+(*z)]=a;
8184       }
8185 }
8186
8187 /*!
8188  * Copy all values from another DataArrayInt (\a a) into specified tuples and 
8189  * components of \a this array. Textual data is not copied.
8190  * The tuples to assign to are defined by a C array of indices.
8191  * The components to assign to are defined by three values similar to parameters of
8192  * the Python function \c range(\c start,\c stop,\c step).
8193  * There are two *modes of usage*:
8194  * - If \a a->getNbOfElems() equals to number of values to assign to, then every value
8195  *   of \a a is assigned to its own location within \a this array. 
8196  * - If \a a includes one tuple, then all values of \a a are assigned to the specified
8197  *   components of every specified tuple of \a this array. In this mode it is required
8198  *   that \a a->getNumberOfComponents() equals to the number of specified components.
8199  *
8200  *  \param [in] a - the array to copy values from.
8201  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
8202  *              assign values of \a a to.
8203  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
8204  *              pointer to a tuple index <em>(pi)</em> varies as this: 
8205  *              \a bgTuples <= \a pi < \a endTuples.
8206  *  \param [in] bgComp - index of the first component of \a this array to assign to.
8207  *  \param [in] endComp - index of the component before which the components to assign
8208  *              to are located.
8209  *  \param [in] stepComp - index increment to get index of the next component to assign to.
8210  *  \param [in] strictCompoCompare - this parameter is checked only in the first
8211  *               *mode of usage*; if \a strictCompoCompare is \a true (default), 
8212  *               then \a a->getNumberOfComponents() must be equal 
8213  *               to the number of specified columns, else this is not required.
8214  *  \throw If \a a is NULL.
8215  *  \throw If \a a is not allocated.
8216  *  \throw If \a this is not allocated.
8217  *  \throw If any index of tuple given by \a bgTuples is out of a valid range for 
8218  *         \a this array.
8219  *  \throw In the first *mode of usage*, if <em>strictCompoCompare == true </em> and
8220  *         if <em> a->getNumberOfComponents()</em> is unequal to the number of components
8221  *         defined by <em>(bgComp,endComp,stepComp)</em>.
8222  *  \throw In the second *mode of usage*, if \a a->getNumberOfTuples() != 1 or
8223  *         <em> a->getNumberOfComponents()</em> is unequal to the number of components
8224  *         defined by <em>(bgComp,endComp,stepComp)</em>.
8225  *  \throw If parameters specifying components to assign to, do not give a
8226  *            non-empty range of increasing indices or indices are out of a valid range
8227  *            for \this array.
8228  *
8229  *  \if ENABLE_EXAMPLES
8230  *  \ref py_mcdataarrayint_setpartofvalues3 "Here is a Python example".
8231  *  \endif
8232  */
8233 void DataArrayInt::setPartOfValues3(const DataArrayInt *a, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare)
8234 {
8235   if(!a)
8236     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValues3 : DataArrayInt pointer in input is NULL !");
8237   const char msg[]="DataArrayInt::setPartOfValues3";
8238   checkAllocated();
8239   a->checkAllocated();
8240   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
8241   int nbComp=getNumberOfComponents();
8242   int nbOfTuples=getNumberOfTuples();
8243   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
8244   int newNbOfTuples=(int)std::distance(bgTuples,endTuples);
8245   bool assignTech=true;
8246   if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
8247     {
8248       if(strictCompoCompare)
8249         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
8250     }
8251   else
8252     {
8253       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
8254       assignTech=false;
8255     }
8256   int *pt=getPointer()+bgComp;
8257   const int *srcPt=a->getConstPointer();
8258   if(assignTech)
8259     {
8260       for(const int *w=bgTuples;w!=endTuples;w++)
8261         for(int j=0;j<newNbOfComp;j++,srcPt++)
8262           {
8263             DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
8264             pt[(std::size_t)(*w)*nbComp+j*stepComp]=*srcPt;
8265           }
8266     }
8267   else
8268     {
8269       for(const int *w=bgTuples;w!=endTuples;w++)
8270         {
8271           const int *srcPt2=srcPt;
8272           for(int j=0;j<newNbOfComp;j++,srcPt2++)
8273             {
8274               DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
8275               pt[(std::size_t)(*w)*nbComp+j*stepComp]=*srcPt2;
8276             }
8277         }
8278     }
8279 }
8280
8281 /*!
8282  * Assign a given value to values at specified tuples and components of \a this array.
8283  * The tuples to assign to are defined by a C array of indices.
8284  * The components to assign to are defined by three values similar to parameters of
8285  * the Python function \c range(\c start,\c stop,\c step).
8286  *  \param [in] a - the value to assign.
8287  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
8288  *              assign \a a to.
8289  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
8290  *              pointer to a tuple index <em>(pi)</em> varies as this: 
8291  *              \a bgTuples <= \a pi < \a endTuples.
8292  *  \param [in] bgComp - index of the first component of \a this array to assign to.
8293  *  \param [in] endComp - index of the component before which the components to assign
8294  *              to are located.
8295  *  \param [in] stepComp - index increment to get index of the next component to assign to.
8296  *  \throw If \a this is not allocated.
8297  *  \throw If any index of tuple given by \a bgTuples is out of a valid range for 
8298  *         \a this array.
8299  *  \throw If parameters specifying components to assign to, do not give a
8300  *            non-empty range of increasing indices or indices are out of a valid range
8301  *            for \this array.
8302  *
8303  *  \if ENABLE_EXAMPLES
8304  *  \ref py_mcdataarrayint_setpartofvaluessimple3 "Here is a Python example".
8305  *  \endif
8306  */
8307 void DataArrayInt::setPartOfValuesSimple3(int a, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp)
8308 {
8309   const char msg[]="DataArrayInt::setPartOfValuesSimple3";
8310   checkAllocated();
8311   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
8312   int nbComp=getNumberOfComponents();
8313   int nbOfTuples=getNumberOfTuples();
8314   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
8315   int *pt=getPointer()+bgComp;
8316   for(const int *w=bgTuples;w!=endTuples;w++)
8317     for(int j=0;j<newNbOfComp;j++)
8318       {
8319         DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
8320         pt[(std::size_t)(*w)*nbComp+j*stepComp]=a;
8321       }
8322 }
8323
8324 void DataArrayInt::setPartOfValues4(const DataArrayInt *a, int bgTuples, int endTuples, int stepTuples, const int *bgComp, const int *endComp, bool strictCompoCompare)
8325 {
8326   if(!a)
8327     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValues4 : input DataArrayInt is NULL !");
8328   const char msg[]="DataArrayInt::setPartOfValues4";
8329   checkAllocated();
8330   a->checkAllocated();
8331   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
8332   int newNbOfComp=(int)std::distance(bgComp,endComp);
8333   int nbComp=getNumberOfComponents();
8334   for(const int *z=bgComp;z!=endComp;z++)
8335     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
8336   int nbOfTuples=getNumberOfTuples();
8337   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
8338   bool assignTech=true;
8339   if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
8340     {
8341       if(strictCompoCompare)
8342         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
8343     }
8344   else
8345     {
8346       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
8347       assignTech=false;
8348     }
8349   const int *srcPt=a->getConstPointer();
8350   int *pt=getPointer()+bgTuples*nbComp;
8351   if(assignTech)
8352     {
8353       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
8354         for(const int *z=bgComp;z!=endComp;z++,srcPt++)
8355           pt[*z]=*srcPt;
8356     }
8357   else
8358     {
8359       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
8360         {
8361           const int *srcPt2=srcPt;
8362           for(const int *z=bgComp;z!=endComp;z++,srcPt2++)
8363             pt[*z]=*srcPt2;
8364         }
8365     }
8366 }
8367
8368 void DataArrayInt::setPartOfValuesSimple4(int a, int bgTuples, int endTuples, int stepTuples, const int *bgComp, const int *endComp)
8369 {
8370   const char msg[]="DataArrayInt::setPartOfValuesSimple4";
8371   checkAllocated();
8372   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
8373   int nbComp=getNumberOfComponents();
8374   for(const int *z=bgComp;z!=endComp;z++)
8375     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
8376   int nbOfTuples=getNumberOfTuples();
8377   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
8378   int *pt=getPointer()+bgTuples*nbComp;
8379   for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
8380     for(const int *z=bgComp;z!=endComp;z++)
8381       pt[*z]=a;
8382 }
8383
8384 /*!
8385  * Copy some tuples from another DataArrayInt into specified tuples
8386  * of \a this array. Textual data is not copied. Both arrays must have equal number of
8387  * components.
8388  * Both the tuples to assign and the tuples to assign to are defined by a DataArrayInt.
8389  * All components of selected tuples are copied.
8390  *  \param [in] a - the array to copy values from.
8391  *  \param [in] tuplesSelec - the array specifying both source tuples of \a a and
8392  *              target tuples of \a this. \a tuplesSelec has two components, and the
8393  *              first component specifies index of the source tuple and the second
8394  *              one specifies index of the target tuple.
8395  *  \throw If \a this is not allocated.
8396  *  \throw If \a a is NULL.
8397  *  \throw If \a a is not allocated.
8398  *  \throw If \a tuplesSelec is NULL.
8399  *  \throw If \a tuplesSelec is not allocated.
8400  *  \throw If <em>this->getNumberOfComponents() != a->getNumberOfComponents()</em>.
8401  *  \throw If \a tuplesSelec->getNumberOfComponents() != 2.
8402  *  \throw If any tuple index given by \a tuplesSelec is out of a valid range for 
8403  *         the corresponding (\a this or \a a) array.
8404  */
8405 void DataArrayInt::setPartOfValuesAdv(const DataArrayInt *a, const DataArrayInt *tuplesSelec)
8406 {
8407   if(!a || !tuplesSelec)
8408     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValuesAdv : DataArrayInt pointer in input is NULL !");
8409   checkAllocated();
8410   a->checkAllocated();
8411   tuplesSelec->checkAllocated();
8412   int nbOfComp=getNumberOfComponents();
8413   if(nbOfComp!=a->getNumberOfComponents())
8414     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValuesAdv : This and a do not have the same number of components !");
8415   if(tuplesSelec->getNumberOfComponents()!=2)
8416     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValuesAdv : Expecting to have a tuple selector DataArrayInt instance with exactly 2 components !");
8417   int thisNt=getNumberOfTuples();
8418   int aNt=a->getNumberOfTuples();
8419   int *valsToSet=getPointer();
8420   const int *valsSrc=a->getConstPointer();
8421   for(const int *tuple=tuplesSelec->begin();tuple!=tuplesSelec->end();tuple+=2)
8422     {
8423       if(tuple[1]>=0 && tuple[1]<aNt)
8424         {
8425           if(tuple[0]>=0 && tuple[0]<thisNt)
8426             std::copy(valsSrc+nbOfComp*tuple[1],valsSrc+nbOfComp*(tuple[1]+1),valsToSet+nbOfComp*tuple[0]);
8427           else
8428             {
8429               std::ostringstream oss; oss << "DataArrayInt::setPartOfValuesAdv : Tuple #" << std::distance(tuplesSelec->begin(),tuple)/2;
8430               oss << " of 'tuplesSelec' request of tuple id #" << tuple[0] << " in 'this' ! It should be in [0," << thisNt << ") !";
8431               throw INTERP_KERNEL::Exception(oss.str().c_str());
8432             }
8433         }
8434       else
8435         {
8436           std::ostringstream oss; oss << "DataArrayInt::setPartOfValuesAdv : Tuple #" << std::distance(tuplesSelec->begin(),tuple)/2;
8437           oss << " of 'tuplesSelec' request of tuple id #" << tuple[1] << " in 'a' ! It should be in [0," << aNt << ") !";
8438           throw INTERP_KERNEL::Exception(oss.str().c_str());
8439         }
8440     }
8441 }
8442
8443 /*!
8444  * Copy some tuples from another DataArrayInt (\a aBase) into contiguous tuples
8445  * of \a this array. Textual data is not copied. Both arrays must have equal number of
8446  * components.
8447  * The tuples to assign to are defined by index of the first tuple, and
8448  * their number is defined by \a tuplesSelec->getNumberOfTuples().
8449  * The tuples to copy are defined by values of a DataArrayInt.
8450  * All components of selected tuples are copied.
8451  *  \param [in] tupleIdStart - index of the first tuple of \a this array to assign
8452  *              values to.
8453  *  \param [in] aBase - the array to copy values from.
8454  *  \param [in] tuplesSelec - the array specifying tuples of \a aBase to copy.
8455  *  \throw If \a this is not allocated.
8456  *  \throw If \a aBase is NULL.
8457  *  \throw If \a aBase is not allocated.
8458  *  \throw If \a tuplesSelec is NULL.
8459  *  \throw If \a tuplesSelec is not allocated.
8460  *  \throw If <em>this->getNumberOfComponents() != a->getNumberOfComponents()</em>.
8461  *  \throw If \a tuplesSelec->getNumberOfComponents() != 1.
8462  *  \throw If <em>tupleIdStart + tuplesSelec->getNumberOfTuples() > this->getNumberOfTuples().</em>
8463  *  \throw If any tuple index given by \a tuplesSelec is out of a valid range for 
8464  *         \a aBase array.
8465  */
8466 void DataArrayInt::setContigPartOfSelectedValues(int tupleIdStart, const DataArray *aBase, const DataArrayInt *tuplesSelec)
8467 {
8468   if(!aBase || !tuplesSelec)
8469     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues : input DataArray is NULL !");
8470   const DataArrayInt *a=dynamic_cast<const DataArrayInt *>(aBase);
8471   if(!a)
8472     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues : input DataArray aBase is not a DataArrayInt !");
8473   checkAllocated();
8474   a->checkAllocated();
8475   tuplesSelec->checkAllocated();
8476   int nbOfComp=getNumberOfComponents();
8477   if(nbOfComp!=a->getNumberOfComponents())
8478     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues : This and a do not have the same number of components !");
8479   if(tuplesSelec->getNumberOfComponents()!=1)
8480     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues : Expecting to have a tuple selector DataArrayInt instance with exactly 1 component !");
8481   int thisNt=getNumberOfTuples();
8482   int aNt=a->getNumberOfTuples();
8483   int nbOfTupleToWrite=tuplesSelec->getNumberOfTuples();
8484   int *valsToSet=getPointer()+tupleIdStart*nbOfComp;
8485   if(tupleIdStart+nbOfTupleToWrite>thisNt)
8486     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues : invalid number range of values to write !");
8487   const int *valsSrc=a->getConstPointer();
8488   for(const int *tuple=tuplesSelec->begin();tuple!=tuplesSelec->end();tuple++,valsToSet+=nbOfComp)
8489     {
8490       if(*tuple>=0 && *tuple<aNt)
8491         {
8492           std::copy(valsSrc+nbOfComp*(*tuple),valsSrc+nbOfComp*(*tuple+1),valsToSet);
8493         }
8494       else
8495         {
8496           std::ostringstream oss; oss << "DataArrayInt::setContigPartOfSelectedValues : Tuple #" << std::distance(tuplesSelec->begin(),tuple);
8497           oss << " of 'tuplesSelec' request of tuple id #" << *tuple << " in 'a' ! It should be in [0," << aNt << ") !";
8498           throw INTERP_KERNEL::Exception(oss.str().c_str());
8499         }
8500     }
8501 }
8502
8503 /*!
8504  * Copy some tuples from another DataArrayInt (\a aBase) into contiguous tuples
8505  * of \a this array. Textual data is not copied. Both arrays must have equal number of
8506  * components.
8507  * The tuples to copy are defined by three values similar to parameters of
8508  * the Python function \c range(\c start,\c stop,\c step).
8509  * The tuples to assign to are defined by index of the first tuple, and
8510  * their number is defined by number of tuples to copy.
8511  * All components of selected tuples are copied.
8512  *  \param [in] tupleIdStart - index of the first tuple of \a this array to assign
8513  *              values to.
8514  *  \param [in] aBase - the array to copy values from.
8515  *  \param [in] bg - index of the first tuple to copy of the array \a aBase.
8516  *  \param [in] end2 - index of the tuple of \a aBase before which the tuples to copy
8517  *              are located.
8518  *  \param [in] step - index increment to get index of the next tuple to copy.
8519  *  \throw If \a this is not allocated.
8520  *  \throw If \a aBase is NULL.
8521  *  \throw If \a aBase is not allocated.
8522  *  \throw If <em>this->getNumberOfComponents() != aBase->getNumberOfComponents()</em>.
8523  *  \throw If <em>tupleIdStart + len(range(bg,end2,step)) > this->getNumberOfTuples().</em>
8524  *  \throw If parameters specifying tuples to copy, do not give a
8525  *            non-empty range of increasing indices or indices are out of a valid range
8526  *            for the array \a aBase.
8527  */
8528 void DataArrayInt::setContigPartOfSelectedValues2(int tupleIdStart, const DataArray *aBase, int bg, int end2, int step)
8529 {
8530   if(!aBase)
8531     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues2 : input DataArray is NULL !");
8532   const DataArrayInt *a=dynamic_cast<const DataArrayInt *>(aBase);
8533   if(!a)
8534     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues2 : input DataArray aBase is not a DataArrayInt !");
8535   checkAllocated();
8536   a->checkAllocated();
8537   int nbOfComp=getNumberOfComponents();
8538   const char msg[]="DataArrayInt::setContigPartOfSelectedValues2";
8539   int nbOfTupleToWrite=DataArray::GetNumberOfItemGivenBES(bg,end2,step,msg);
8540   if(nbOfComp!=a->getNumberOfComponents())
8541     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues2 : This and a do not have the same number of components !");
8542   int thisNt=getNumberOfTuples();
8543   int aNt=a->getNumberOfTuples();
8544   int *valsToSet=getPointer()+tupleIdStart*nbOfComp;
8545   if(tupleIdStart+nbOfTupleToWrite>thisNt)
8546     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues2 : invalid number range of values to write !");
8547   if(end2>aNt)
8548     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues2 : invalid range of values to read !");
8549   const int *valsSrc=a->getConstPointer()+bg*nbOfComp;
8550   for(int i=0;i<nbOfTupleToWrite;i++,valsToSet+=nbOfComp,valsSrc+=step*nbOfComp)
8551     {
8552       std::copy(valsSrc,valsSrc+nbOfComp,valsToSet);
8553     }
8554 }
8555
8556 /*!
8557  * Returns a value located at specified tuple and component.
8558  * This method is equivalent to DataArrayInt::getIJ() except that validity of
8559  * parameters is checked. So this method is safe but expensive if used to go through
8560  * all values of \a this.
8561  *  \param [in] tupleId - index of tuple of interest.
8562  *  \param [in] compoId - index of component of interest.
8563  *  \return double - value located by \a tupleId and \a compoId.
8564  *  \throw If \a this is not allocated.
8565  *  \throw If condition <em>( 0 <= tupleId < this->getNumberOfTuples() )</em> is violated.
8566  *  \throw If condition <em>( 0 <= compoId < this->getNumberOfComponents() )</em> is violated.
8567  */
8568 int DataArrayInt::getIJSafe(int tupleId, int compoId) const
8569 {
8570   checkAllocated();
8571   if(tupleId<0 || tupleId>=getNumberOfTuples())
8572     {
8573       std::ostringstream oss; oss << "DataArrayInt::getIJSafe : request for tupleId " << tupleId << " should be in [0," << getNumberOfTuples() << ") !";
8574       throw INTERP_KERNEL::Exception(oss.str().c_str());
8575     }
8576   if(compoId<0 || compoId>=getNumberOfComponents())
8577     {
8578       std::ostringstream oss; oss << "DataArrayInt::getIJSafe : request for compoId " << compoId << " should be in [0," << getNumberOfComponents() << ") !";
8579       throw INTERP_KERNEL::Exception(oss.str().c_str());
8580     }
8581   return _mem[tupleId*_info_on_compo.size()+compoId];
8582 }
8583
8584 /*!
8585  * Returns the first value of \a this. 
8586  *  \return int - the last value of \a this array.
8587  *  \throw If \a this is not allocated.
8588  *  \throw If \a this->getNumberOfComponents() != 1.
8589  *  \throw If \a this->getNumberOfTuples() < 1.
8590  */
8591 int DataArrayInt::front() const
8592 {
8593   checkAllocated();
8594   if(getNumberOfComponents()!=1)
8595     throw INTERP_KERNEL::Exception("DataArrayInt::front : number of components not equal to one !");
8596   int nbOfTuples=getNumberOfTuples();
8597   if(nbOfTuples<1)
8598     throw INTERP_KERNEL::Exception("DataArrayInt::front : number of tuples must be >= 1 !");
8599   return *(getConstPointer());
8600 }
8601
8602 /*!
8603  * Returns the last value of \a this. 
8604  *  \return int - the last value of \a this array.
8605  *  \throw If \a this is not allocated.
8606  *  \throw If \a this->getNumberOfComponents() != 1.
8607  *  \throw If \a this->getNumberOfTuples() < 1.
8608  */
8609 int DataArrayInt::back() const
8610 {
8611   checkAllocated();
8612   if(getNumberOfComponents()!=1)
8613     throw INTERP_KERNEL::Exception("DataArrayInt::back : number of components not equal to one !");
8614   int nbOfTuples=getNumberOfTuples();
8615   if(nbOfTuples<1)
8616     throw INTERP_KERNEL::Exception("DataArrayInt::back : number of tuples must be >= 1 !");
8617   return *(getConstPointer()+nbOfTuples-1);
8618 }
8619
8620 /*!
8621  * Assign pointer to one array to a pointer to another appay. Reference counter of
8622  * \a arrayToSet is incremented / decremented.
8623  *  \param [in] newArray - the pointer to array to assign to \a arrayToSet.
8624  *  \param [in,out] arrayToSet - the pointer to array to assign to.
8625  */
8626 void DataArrayInt::SetArrayIn(DataArrayInt *newArray, DataArrayInt* &arrayToSet)
8627 {
8628   if(newArray!=arrayToSet)
8629     {
8630       if(arrayToSet)
8631         arrayToSet->decrRef();
8632       arrayToSet=newArray;
8633       if(arrayToSet)
8634         arrayToSet->incrRef();
8635     }
8636 }
8637
8638 DataArrayIntIterator *DataArrayInt::iterator()
8639 {
8640   return new DataArrayIntIterator(this);
8641 }
8642
8643 /*!
8644  * Creates a new DataArrayInt containing IDs (indices) of tuples holding value equal to a
8645  * given one. The ids are sorted in the ascending order.
8646  *  \param [in] val - the value to find within \a this.
8647  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
8648  *          array using decrRef() as it is no more needed.
8649  *  \throw If \a this is not allocated.
8650  *  \throw If \a this->getNumberOfComponents() != 1.
8651  *  \sa DataArrayInt::getIdsEqualTuple
8652  */
8653 DataArrayInt *DataArrayInt::getIdsEqual(int val) const
8654 {
8655   checkAllocated();
8656   if(getNumberOfComponents()!=1)
8657     throw INTERP_KERNEL::Exception("DataArrayInt::getIdsEqual : the array must have only one component, you can call 'rearrange' method before !");
8658   const int *cptr(getConstPointer());
8659   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
8660   int nbOfTuples=getNumberOfTuples();
8661   for(int i=0;i<nbOfTuples;i++,cptr++)
8662     if(*cptr==val)
8663       ret->pushBackSilent(i);
8664   return ret.retn();
8665 }
8666
8667 /*!
8668  * Creates a new DataArrayInt containing IDs (indices) of tuples holding value \b not
8669  * equal to a given one. 
8670  *  \param [in] val - the value to ignore within \a this.
8671  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
8672  *          array using decrRef() as it is no more needed.
8673  *  \throw If \a this is not allocated.
8674  *  \throw If \a this->getNumberOfComponents() != 1.
8675  */
8676 DataArrayInt *DataArrayInt::getIdsNotEqual(int val) const
8677 {
8678   checkAllocated();
8679   if(getNumberOfComponents()!=1)
8680     throw INTERP_KERNEL::Exception("DataArrayInt::getIdsNotEqual : 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 tuple equal to those defined by [ \a tupleBg , \a tupleEnd )
8692  * This method is an extension of  DataArrayInt::getIdsEqual method.
8693  *
8694  *  \param [in] tupleBg - the begin (included) of the input tuple to find within \a this.
8695  *  \param [in] tupleEnd - the end (excluded) of the input tuple to find within \a this.
8696  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
8697  *          array using decrRef() as it is no more needed.
8698  *  \throw If \a this is not allocated.
8699  *  \throw If \a this->getNumberOfComponents() != std::distance(tupleBg,tupleEnd).
8700  * \throw If \a this->getNumberOfComponents() is equal to 0.
8701  * \sa DataArrayInt::getIdsEqual
8702  */
8703 DataArrayInt *DataArrayInt::getIdsEqualTuple(const int *tupleBg, const int *tupleEnd) const
8704 {
8705   std::size_t nbOfCompoExp(std::distance(tupleBg,tupleEnd));
8706   checkAllocated();
8707   if(getNumberOfComponents()!=(int)nbOfCompoExp)
8708     {
8709       std::ostringstream oss; oss << "DataArrayInt::getIdsEqualTuple : mismatch of number of components. Input tuple has " << nbOfCompoExp << " whereas this array has " << getNumberOfComponents() << " components !";
8710       throw INTERP_KERNEL::Exception(oss.str().c_str());
8711     }
8712   if(nbOfCompoExp==0)
8713     throw INTERP_KERNEL::Exception("DataArrayInt::getIdsEqualTuple : number of components should be > 0 !");
8714   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
8715   const int *bg(begin()),*end2(end()),*work(begin());
8716   while(work!=end2)
8717     {
8718       work=std::search(work,end2,tupleBg,tupleEnd);
8719       if(work!=end2)
8720         {
8721           std::size_t pos(std::distance(bg,work));
8722           if(pos%nbOfCompoExp==0)
8723             ret->pushBackSilent(pos/nbOfCompoExp);
8724           work++;
8725         }
8726     }
8727   return ret.retn();
8728 }
8729
8730 /*!
8731  * Assigns \a newValue to all elements holding \a oldValue within \a this
8732  * one-dimensional array.
8733  *  \param [in] oldValue - the value to replace.
8734  *  \param [in] newValue - the value to assign.
8735  *  \return int - number of replacements performed.
8736  *  \throw If \a this is not allocated.
8737  *  \throw If \a this->getNumberOfComponents() != 1.
8738  */
8739 int DataArrayInt::changeValue(int oldValue, int newValue)
8740 {
8741   checkAllocated();
8742   if(getNumberOfComponents()!=1)
8743     throw INTERP_KERNEL::Exception("DataArrayInt::changeValue : the array must have only one component, you can call 'rearrange' method before !");
8744   int *start=getPointer();
8745   int *end2=start+getNbOfElems();
8746   int ret=0;
8747   for(int *val=start;val!=end2;val++)
8748     {
8749       if(*val==oldValue)
8750         {
8751           *val=newValue;
8752           ret++;
8753         }
8754     }
8755   return ret;
8756 }
8757
8758 /*!
8759  * Creates a new DataArrayInt containing IDs (indices) of tuples holding value equal to
8760  * one of given values.
8761  *  \param [in] valsBg - an array of values to find within \a this array.
8762  *  \param [in] valsEnd - specifies the end of the array \a valsBg, so that
8763  *              the last value of \a valsBg is \a valsEnd[ -1 ].
8764  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
8765  *          array using decrRef() as it is no more needed.
8766  *  \throw If \a this->getNumberOfComponents() != 1.
8767  */
8768 DataArrayInt *DataArrayInt::getIdsEqualList(const int *valsBg, const int *valsEnd) const
8769 {
8770   if(getNumberOfComponents()!=1)
8771     throw INTERP_KERNEL::Exception("DataArrayInt::getIdsEqualList : the array must have only one component, you can call 'rearrange' method before !");
8772   std::set<int> vals2(valsBg,valsEnd);
8773   const int *cptr=getConstPointer();
8774   std::vector<int> res;
8775   int nbOfTuples=getNumberOfTuples();
8776   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
8777   for(int i=0;i<nbOfTuples;i++,cptr++)
8778     if(vals2.find(*cptr)!=vals2.end())
8779       ret->pushBackSilent(i);
8780   return ret.retn();
8781 }
8782
8783 /*!
8784  * Creates a new DataArrayInt containing IDs (indices) of tuples holding values \b not
8785  * equal to any of given values.
8786  *  \param [in] valsBg - an array of values to ignore within \a this array.
8787  *  \param [in] valsEnd - specifies the end of the array \a valsBg, so that
8788  *              the last value of \a valsBg is \a valsEnd[ -1 ].
8789  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
8790  *          array using decrRef() as it is no more needed.
8791  *  \throw If \a this->getNumberOfComponents() != 1.
8792  */
8793 DataArrayInt *DataArrayInt::getIdsNotEqualList(const int *valsBg, const int *valsEnd) const
8794 {
8795   if(getNumberOfComponents()!=1)
8796     throw INTERP_KERNEL::Exception("DataArrayInt::getIdsNotEqualList : the array must have only one component, you can call 'rearrange' method before !");
8797   std::set<int> vals2(valsBg,valsEnd);
8798   const int *cptr=getConstPointer();
8799   std::vector<int> res;
8800   int nbOfTuples=getNumberOfTuples();
8801   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
8802   for(int i=0;i<nbOfTuples;i++,cptr++)
8803     if(vals2.find(*cptr)==vals2.end())
8804       ret->pushBackSilent(i);
8805   return ret.retn();
8806 }
8807
8808 /*!
8809  * This method is an extension of DataArrayInt::locateValue method because this method works for DataArrayInt with
8810  * any number of components excepted 0 (an INTERP_KERNEL::Exception is thrown in this case).
8811  * This method searches in \b this is there is a tuple that matched the input parameter \b tupl.
8812  * If any the tuple id is returned. If not -1 is returned.
8813  * 
8814  * This method throws an INTERP_KERNEL::Exception if the number of components in \b this mismatches with the size of
8815  * the input vector. An INTERP_KERNEL::Exception is thrown too if \b this is not allocated.
8816  *
8817  * \return tuple id where \b tupl is. -1 if no such tuple exists in \b this.
8818  * \sa DataArrayInt::search, DataArrayInt::presenceOfTuple.
8819  */
8820 int DataArrayInt::locateTuple(const std::vector<int>& tupl) const
8821 {
8822   checkAllocated();
8823   int nbOfCompo=getNumberOfComponents();
8824   if(nbOfCompo==0)
8825     throw INTERP_KERNEL::Exception("DataArrayInt::locateTuple : 0 components in 'this' !");
8826   if(nbOfCompo!=(int)tupl.size())
8827     {
8828       std::ostringstream oss; oss << "DataArrayInt::locateTuple : 'this' contains " << nbOfCompo << " components and searching for a tuple of length " << tupl.size() << " !";
8829       throw INTERP_KERNEL::Exception(oss.str().c_str());
8830     }
8831   const int *cptr=getConstPointer();
8832   std::size_t nbOfVals=getNbOfElems();
8833   for(const int *work=cptr;work!=cptr+nbOfVals;)
8834     {
8835       work=std::search(work,cptr+nbOfVals,tupl.begin(),tupl.end());
8836       if(work!=cptr+nbOfVals)
8837         {
8838           if(std::distance(cptr,work)%nbOfCompo!=0)
8839             work++;
8840           else
8841             return std::distance(cptr,work)/nbOfCompo;
8842         }
8843     }
8844   return -1;
8845 }
8846
8847 /*!
8848  * This method searches the sequence specified in input parameter \b vals in \b this.
8849  * This works only for DataArrayInt having number of components equal to one (if not an INTERP_KERNEL::Exception will be thrown).
8850  * This method differs from DataArrayInt::locateTuple in that the position is internal raw data is not considered here contrary to DataArrayInt::locateTuple.
8851  * \sa DataArrayInt::locateTuple
8852  */
8853 int DataArrayInt::search(const std::vector<int>& vals) const
8854 {
8855   checkAllocated();
8856   int nbOfCompo=getNumberOfComponents();
8857   if(nbOfCompo!=1)
8858     throw INTERP_KERNEL::Exception("DataArrayInt::search : works only for DataArrayInt instance with one component !");
8859   const int *cptr=getConstPointer();
8860   std::size_t nbOfVals=getNbOfElems();
8861   const int *loc=std::search(cptr,cptr+nbOfVals,vals.begin(),vals.end());
8862   if(loc!=cptr+nbOfVals)
8863     return std::distance(cptr,loc);
8864   return -1;
8865 }
8866
8867 /*!
8868  * This method expects to be called when number of components of this is equal to one.
8869  * This method returns the tuple id, if it exists, of the first tuple equal to \b value.
8870  * If not any tuple contains \b value -1 is returned.
8871  * \sa DataArrayInt::presenceOfValue
8872  */
8873 int DataArrayInt::locateValue(int value) const
8874 {
8875   checkAllocated();
8876   if(getNumberOfComponents()!=1)
8877     throw INTERP_KERNEL::Exception("DataArrayInt::presenceOfValue : the array must have only one component, you can call 'rearrange' method before !");
8878   const int *cptr=getConstPointer();
8879   int nbOfTuples=getNumberOfTuples();
8880   const int *ret=std::find(cptr,cptr+nbOfTuples,value);
8881   if(ret!=cptr+nbOfTuples)
8882     return std::distance(cptr,ret);
8883   return -1;
8884 }
8885
8886 /*!
8887  * This method expects to be called when number of components of this is equal to one.
8888  * This method returns the tuple id, if it exists, of the first tuple so that the value is contained in \b vals.
8889  * If not any tuple contains one of the values contained in 'vals' false is returned.
8890  * \sa DataArrayInt::presenceOfValue
8891  */
8892 int DataArrayInt::locateValue(const std::vector<int>& vals) const
8893 {
8894   checkAllocated();
8895   if(getNumberOfComponents()!=1)
8896     throw INTERP_KERNEL::Exception("DataArrayInt::presenceOfValue : the array must have only one component, you can call 'rearrange' method before !");
8897   std::set<int> vals2(vals.begin(),vals.end());
8898   const int *cptr=getConstPointer();
8899   int nbOfTuples=getNumberOfTuples();
8900   for(const int *w=cptr;w!=cptr+nbOfTuples;w++)
8901     if(vals2.find(*w)!=vals2.end())
8902       return std::distance(cptr,w);
8903   return -1;
8904 }
8905
8906 /*!
8907  * This method returns the number of values in \a this that are equals to input parameter \a value.
8908  * This method only works for single component array.
8909  *
8910  * \return a value in [ 0, \c this->getNumberOfTuples() )
8911  *
8912  * \throw If \a this is not allocated
8913  *
8914  */
8915 int DataArrayInt::count(int value) const
8916 {
8917   int ret=0;
8918   checkAllocated();
8919   if(getNumberOfComponents()!=1)
8920     throw INTERP_KERNEL::Exception("DataArrayInt::count : must be applied on DataArrayInt with only one component, you can call 'rearrange' method before !");
8921   const int *vals=begin();
8922   int nbOfTuples=getNumberOfTuples();
8923   for(int i=0;i<nbOfTuples;i++,vals++)
8924     if(*vals==value)
8925       ret++;
8926   return ret;
8927 }
8928
8929 /*!
8930  * This method is an extension of DataArrayInt::presenceOfValue method because this method works for DataArrayInt with
8931  * any number of components excepted 0 (an INTERP_KERNEL::Exception is thrown in this case).
8932  * This method searches in \b this is there is a tuple that matched the input parameter \b tupl.
8933  * This method throws an INTERP_KERNEL::Exception if the number of components in \b this mismatches with the size of
8934  * the input vector. An INTERP_KERNEL::Exception is thrown too if \b this is not allocated.
8935  * \sa DataArrayInt::locateTuple
8936  */
8937 bool DataArrayInt::presenceOfTuple(const std::vector<int>& tupl) const
8938 {
8939   return locateTuple(tupl)!=-1;
8940 }
8941
8942
8943 /*!
8944  * Returns \a true if a given value is present within \a this one-dimensional array.
8945  *  \param [in] value - the value to find within \a this array.
8946  *  \return bool - \a true in case if \a value is present within \a this array.
8947  *  \throw If \a this is not allocated.
8948  *  \throw If \a this->getNumberOfComponents() != 1.
8949  *  \sa locateValue()
8950  */
8951 bool DataArrayInt::presenceOfValue(int value) const
8952 {
8953   return locateValue(value)!=-1;
8954 }
8955
8956 /*!
8957  * This method expects to be called when number of components of this is equal to one.
8958  * This method returns true if it exists a tuple so that the value is contained in \b vals.
8959  * If not any tuple contains one of the values contained in 'vals' false is returned.
8960  * \sa DataArrayInt::locateValue
8961  */
8962 bool DataArrayInt::presenceOfValue(const std::vector<int>& vals) const
8963 {
8964   return locateValue(vals)!=-1;
8965 }
8966
8967 /*!
8968  * Accumulates values of each component of \a this array.
8969  *  \param [out] res - an array of length \a this->getNumberOfComponents(), allocated 
8970  *         by the caller, that is filled by this method with sum value for each
8971  *         component.
8972  *  \throw If \a this is not allocated.
8973  */
8974 void DataArrayInt::accumulate(int *res) const
8975 {
8976   checkAllocated();
8977   const int *ptr=getConstPointer();
8978   int nbTuple=getNumberOfTuples();
8979   int nbComps=getNumberOfComponents();
8980   std::fill(res,res+nbComps,0);
8981   for(int i=0;i<nbTuple;i++)
8982     std::transform(ptr+i*nbComps,ptr+(i+1)*nbComps,res,res,std::plus<int>());
8983 }
8984
8985 int DataArrayInt::accumulate(int compId) const
8986 {
8987   checkAllocated();
8988   const int *ptr=getConstPointer();
8989   int nbTuple=getNumberOfTuples();
8990   int nbComps=getNumberOfComponents();
8991   if(compId<0 || compId>=nbComps)
8992     throw INTERP_KERNEL::Exception("DataArrayInt::accumulate : Invalid compId specified : No such nb of components !");
8993   int ret=0;
8994   for(int i=0;i<nbTuple;i++)
8995     ret+=ptr[i*nbComps+compId];
8996   return ret;
8997 }
8998
8999 /*!
9000  * This method accumulate using addition tuples in \a this using input index array [ \a bgOfIndex, \a endOfIndex ).
9001  * The returned array will have same number of components than \a this and number of tuples equal to
9002  * \c std::distance(bgOfIndex,endOfIndex) \b minus \b one.
9003  *
9004  * The input index array is expected to be ascendingly sorted in which the all referenced ids should be in [0, \c this->getNumberOfTuples).
9005  *
9006  * \param [in] bgOfIndex - begin (included) of the input index array.
9007  * \param [in] endOfIndex - end (excluded) of the input index array.
9008  * \return DataArrayInt * - the new instance having the same number of components than \a this.
9009  * 
9010  * \throw If bgOfIndex or end is NULL.
9011  * \throw If input index array is not ascendingly sorted.
9012  * \throw If there is an id in [ \a bgOfIndex, \a endOfIndex ) not in [0, \c this->getNumberOfTuples).
9013  * \throw If std::distance(bgOfIndex,endOfIndex)==0.
9014  */
9015 DataArrayInt *DataArrayInt::accumulatePerChunck(const int *bgOfIndex, const int *endOfIndex) const
9016 {
9017   if(!bgOfIndex || !endOfIndex)
9018     throw INTERP_KERNEL::Exception("DataArrayInt::accumulatePerChunck : input pointer NULL !");
9019   checkAllocated();
9020   int nbCompo=getNumberOfComponents();
9021   int nbOfTuples=getNumberOfTuples();
9022   int sz=(int)std::distance(bgOfIndex,endOfIndex);
9023   if(sz<1)
9024     throw INTERP_KERNEL::Exception("DataArrayInt::accumulatePerChunck : invalid size of input index array !");
9025   sz--;
9026   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(sz,nbCompo);
9027   const int *w=bgOfIndex;
9028   if(*w<0 || *w>=nbOfTuples)
9029     throw INTERP_KERNEL::Exception("DataArrayInt::accumulatePerChunck : The first element of the input index not in [0,nbOfTuples) !");
9030   const int *srcPt=begin()+(*w)*nbCompo;
9031   int *tmp=ret->getPointer();
9032   for(int i=0;i<sz;i++,tmp+=nbCompo,w++)
9033     {
9034       std::fill(tmp,tmp+nbCompo,0);
9035       if(w[1]>=w[0])
9036         {
9037           for(int j=w[0];j<w[1];j++,srcPt+=nbCompo)
9038             {
9039               if(j>=0 && j<nbOfTuples)
9040                 std::transform(srcPt,srcPt+nbCompo,tmp,tmp,std::plus<int>());
9041               else
9042                 {
9043                   std::ostringstream oss; oss << "DataArrayInt::accumulatePerChunck : At rank #" << i << " the input index array points to id " << j << " should be in [0," << nbOfTuples << ") !";
9044                   throw INTERP_KERNEL::Exception(oss.str().c_str());
9045                 }
9046             }
9047         }
9048       else
9049         {
9050           std::ostringstream oss; oss << "DataArrayInt::accumulatePerChunck : At rank #" << i << " the input index array is not in ascendingly sorted.";
9051           throw INTERP_KERNEL::Exception(oss.str().c_str());
9052         }
9053     }
9054   ret->copyStringInfoFrom(*this);
9055   return ret.retn();
9056 }
9057
9058 /*!
9059  * Returns a new DataArrayInt by concatenating two given arrays, so that (1) the number
9060  * of tuples in the result array is <em> a1->getNumberOfTuples() + a2->getNumberOfTuples() -
9061  * offsetA2</em> and (2)
9062  * the number of component in the result array is same as that of each of given arrays.
9063  * First \a offsetA2 tuples of \a a2 are skipped and thus are missing from the result array.
9064  * Info on components is copied from the first of the given arrays. Number of components
9065  * in the given arrays must be the same.
9066  *  \param [in] a1 - an array to include in the result array.
9067  *  \param [in] a2 - another array to include in the result array.
9068  *  \param [in] offsetA2 - number of tuples of \a a2 to skip.
9069  *  \return DataArrayInt * - the new instance of DataArrayInt.
9070  *          The caller is to delete this result array using decrRef() as it is no more
9071  *          needed.
9072  *  \throw If either \a a1 or \a a2 is NULL.
9073  *  \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents().
9074  */
9075 DataArrayInt *DataArrayInt::Aggregate(const DataArrayInt *a1, const DataArrayInt *a2, int offsetA2)
9076 {
9077   if(!a1 || !a2)
9078     throw INTERP_KERNEL::Exception("DataArrayInt::Aggregate : input DataArrayInt instance is NULL !");
9079   int nbOfComp=a1->getNumberOfComponents();
9080   if(nbOfComp!=a2->getNumberOfComponents())
9081     throw INTERP_KERNEL::Exception("Nb of components mismatch for array Aggregation !");
9082   int nbOfTuple1=a1->getNumberOfTuples();
9083   int nbOfTuple2=a2->getNumberOfTuples();
9084   DataArrayInt *ret=DataArrayInt::New();
9085   ret->alloc(nbOfTuple1+nbOfTuple2-offsetA2,nbOfComp);
9086   int *pt=std::copy(a1->getConstPointer(),a1->getConstPointer()+nbOfTuple1*nbOfComp,ret->getPointer());
9087   std::copy(a2->getConstPointer()+offsetA2*nbOfComp,a2->getConstPointer()+nbOfTuple2*nbOfComp,pt);
9088   ret->copyStringInfoFrom(*a1);
9089   return ret;
9090 }
9091
9092 /*!
9093  * Returns a new DataArrayInt by concatenating all given arrays, so that (1) the number
9094  * of tuples in the result array is a sum of the number of tuples of given arrays and (2)
9095  * the number of component in the result array is same as that of each of given arrays.
9096  * Info on components is copied from the first of the given arrays. Number of components
9097  * in the given arrays must be  the same.
9098  * If the number of non null of elements in \a arr is equal to one the returned object is a copy of it
9099  * not the object itself.
9100  *  \param [in] arr - a sequence of arrays to include in the result array.
9101  *  \return DataArrayInt * - the new instance of DataArrayInt.
9102  *          The caller is to delete this result array using decrRef() as it is no more
9103  *          needed.
9104  *  \throw If all arrays within \a arr are NULL.
9105  *  \throw If getNumberOfComponents() of arrays within \a arr.
9106  */
9107 DataArrayInt *DataArrayInt::Aggregate(const std::vector<const DataArrayInt *>& arr)
9108 {
9109   std::vector<const DataArrayInt *> a;
9110   for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
9111     if(*it4)
9112       a.push_back(*it4);
9113   if(a.empty())
9114     throw INTERP_KERNEL::Exception("DataArrayInt::Aggregate : input list must be NON EMPTY !");
9115   std::vector<const DataArrayInt *>::const_iterator it=a.begin();
9116   int nbOfComp=(*it)->getNumberOfComponents();
9117   int nbt=(*it++)->getNumberOfTuples();
9118   for(int i=1;it!=a.end();it++,i++)
9119     {
9120       if((*it)->getNumberOfComponents()!=nbOfComp)
9121         throw INTERP_KERNEL::Exception("DataArrayInt::Aggregate : Nb of components mismatch for array aggregation !");
9122       nbt+=(*it)->getNumberOfTuples();
9123     }
9124   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
9125   ret->alloc(nbt,nbOfComp);
9126   int *pt=ret->getPointer();
9127   for(it=a.begin();it!=a.end();it++)
9128     pt=std::copy((*it)->getConstPointer(),(*it)->getConstPointer()+(*it)->getNbOfElems(),pt);
9129   ret->copyStringInfoFrom(*(a[0]));
9130   return ret.retn();
9131 }
9132
9133 /*!
9134  * This method takes as input a list of DataArrayInt instances \a arrs that represent each a packed index arrays.
9135  * A packed index array is an allocated array with one component, and at least one tuple. The first element
9136  * of each array in \a arrs must be 0. Each array in \a arrs is expected to be increasingly monotonic.
9137  * 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.
9138  * 
9139  * \return DataArrayInt * - a new object to be managed by the caller.
9140  */
9141 DataArrayInt *DataArrayInt::AggregateIndexes(const std::vector<const DataArrayInt *>& arrs)
9142 {
9143   int retSz=1;
9144   for(std::vector<const DataArrayInt *>::const_iterator it4=arrs.begin();it4!=arrs.end();it4++)
9145     {
9146       if(*it4)
9147         {
9148           (*it4)->checkAllocated();
9149           if((*it4)->getNumberOfComponents()!=1)
9150             {
9151               std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a DataArrayInt instance with nb of compo != 1 at pos " << std::distance(arrs.begin(),it4) << " !";
9152               throw INTERP_KERNEL::Exception(oss.str().c_str());
9153             }
9154           int nbTupl=(*it4)->getNumberOfTuples();
9155           if(nbTupl<1)
9156             {
9157               std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a DataArrayInt instance with nb of tuples < 1 at pos " << std::distance(arrs.begin(),it4) << " !";
9158               throw INTERP_KERNEL::Exception(oss.str().c_str());
9159             }
9160           if((*it4)->front()!=0)
9161             {
9162               std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a DataArrayInt instance with front value != 0 at pos " << std::distance(arrs.begin(),it4) << " !";
9163               throw INTERP_KERNEL::Exception(oss.str().c_str());
9164             }
9165           retSz+=nbTupl-1;
9166         }
9167       else
9168         {
9169           std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a null instance at pos " << std::distance(arrs.begin(),it4) << " !";
9170           throw INTERP_KERNEL::Exception(oss.str().c_str());
9171         }
9172     }
9173   if(arrs.empty())
9174     throw INTERP_KERNEL::Exception("DataArrayInt::AggregateIndexes : input list must be NON EMPTY !");
9175   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
9176   ret->alloc(retSz,1);
9177   int *pt=ret->getPointer(); *pt++=0;
9178   for(std::vector<const DataArrayInt *>::const_iterator it=arrs.begin();it!=arrs.end();it++)
9179     pt=std::transform((*it)->begin()+1,(*it)->end(),pt,std::bind2nd(std::plus<int>(),pt[-1]));
9180   ret->copyStringInfoFrom(*(arrs[0]));
9181   return ret.retn();
9182 }
9183
9184 /*!
9185  * Returns the maximal value and its location within \a this one-dimensional array.
9186  *  \param [out] tupleId - index of the tuple holding the maximal value.
9187  *  \return int - the maximal value among all values of \a this array.
9188  *  \throw If \a this->getNumberOfComponents() != 1
9189  *  \throw If \a this->getNumberOfTuples() < 1
9190  */
9191 int DataArrayInt::getMaxValue(int& tupleId) const
9192 {
9193   checkAllocated();
9194   if(getNumberOfComponents()!=1)
9195     throw INTERP_KERNEL::Exception("DataArrayInt::getMaxValue : must be applied on DataArrayInt with only one component !");
9196   int nbOfTuples=getNumberOfTuples();
9197   if(nbOfTuples<=0)
9198     throw INTERP_KERNEL::Exception("DataArrayInt::getMaxValue : array exists but number of tuples must be > 0 !");
9199   const int *vals=getConstPointer();
9200   const int *loc=std::max_element(vals,vals+nbOfTuples);
9201   tupleId=(int)std::distance(vals,loc);
9202   return *loc;
9203 }
9204
9205 /*!
9206  * Returns the maximal value within \a this array that is allowed to have more than
9207  *  one component.
9208  *  \return int - the maximal value among all values of \a this array.
9209  *  \throw If \a this is not allocated.
9210  */
9211 int DataArrayInt::getMaxValueInArray() const
9212 {
9213   checkAllocated();
9214   const int *loc=std::max_element(begin(),end());
9215   return *loc;
9216 }
9217
9218 /*!
9219  * Returns the minimal value and its location within \a this one-dimensional array.
9220  *  \param [out] tupleId - index of the tuple holding the minimal value.
9221  *  \return int - the minimal value among all values of \a this array.
9222  *  \throw If \a this->getNumberOfComponents() != 1
9223  *  \throw If \a this->getNumberOfTuples() < 1
9224  */
9225 int DataArrayInt::getMinValue(int& tupleId) const
9226 {
9227   checkAllocated();
9228   if(getNumberOfComponents()!=1)
9229     throw INTERP_KERNEL::Exception("DataArrayInt::getMaxValue : must be applied on DataArrayInt with only one component !");
9230   int nbOfTuples=getNumberOfTuples();
9231   if(nbOfTuples<=0)
9232     throw INTERP_KERNEL::Exception("DataArrayInt::getMaxValue : array exists but number of tuples must be > 0 !");
9233   const int *vals=getConstPointer();
9234   const int *loc=std::min_element(vals,vals+nbOfTuples);
9235   tupleId=(int)std::distance(vals,loc);
9236   return *loc;
9237 }
9238
9239 /*!
9240  * Returns the minimal value within \a this array that is allowed to have more than
9241  *  one component.
9242  *  \return int - the minimal value among all values of \a this array.
9243  *  \throw If \a this is not allocated.
9244  */
9245 int DataArrayInt::getMinValueInArray() const
9246 {
9247   checkAllocated();
9248   const int *loc=std::min_element(begin(),end());
9249   return *loc;
9250 }
9251
9252 /*!
9253  * Converts every value of \a this array to its absolute value.
9254  * \b WARNING this method is non const. If a new DataArrayInt instance should be built containing the result of abs DataArrayInt::computeAbs
9255  * should be called instead.
9256  *
9257  * \throw If \a this is not allocated.
9258  * \sa DataArrayInt::computeAbs
9259  */
9260 void DataArrayInt::abs()
9261 {
9262   checkAllocated();
9263   int *ptr(getPointer());
9264   std::size_t nbOfElems(getNbOfElems());
9265   std::transform(ptr,ptr+nbOfElems,ptr,std::ptr_fun<int,int>(std::abs));
9266   declareAsNew();
9267 }
9268
9269 /*!
9270  * This method builds a new instance of \a this object containing the result of std::abs applied of all elements in \a this.
9271  * This method is a const method (that do not change any values in \a this) contrary to  DataArrayInt::abs method.
9272  *
9273  * \return DataArrayInt * - the new instance of DataArrayInt containing the
9274  *         same number of tuples and component as \a this array.
9275  *         The caller is to delete this result array using decrRef() as it is no more
9276  *         needed.
9277  * \throw If \a this is not allocated.
9278  * \sa DataArrayInt::abs
9279  */
9280 DataArrayInt *DataArrayInt::computeAbs() const
9281 {
9282   checkAllocated();
9283   DataArrayInt *newArr(DataArrayInt::New());
9284   int nbOfTuples(getNumberOfTuples());
9285   int nbOfComp(getNumberOfComponents());
9286   newArr->alloc(nbOfTuples,nbOfComp);
9287   std::transform(begin(),end(),newArr->getPointer(),std::ptr_fun<int,int>(std::abs));
9288   newArr->copyStringInfoFrom(*this);
9289   return newArr;
9290 }
9291
9292 /*!
9293  * Apply a liner function to a given component of \a this array, so that
9294  * an array element <em>(x)</em> becomes \f$ a * x + b \f$.
9295  *  \param [in] a - the first coefficient of the function.
9296  *  \param [in] b - the second coefficient of the function.
9297  *  \param [in] compoId - the index of component to modify.
9298  *  \throw If \a this is not allocated.
9299  */
9300 void DataArrayInt::applyLin(int a, int b, int compoId)
9301 {
9302   checkAllocated();
9303   int *ptr=getPointer()+compoId;
9304   int nbOfComp=getNumberOfComponents();
9305   int nbOfTuple=getNumberOfTuples();
9306   for(int i=0;i<nbOfTuple;i++,ptr+=nbOfComp)
9307     *ptr=a*(*ptr)+b;
9308   declareAsNew();
9309 }
9310
9311 /*!
9312  * Apply a liner function to all elements of \a this array, so that
9313  * an element _x_ becomes \f$ a * x + b \f$.
9314  *  \param [in] a - the first coefficient of the function.
9315  *  \param [in] b - the second coefficient of the function.
9316  *  \throw If \a this is not allocated.
9317  */
9318 void DataArrayInt::applyLin(int a, int b)
9319 {
9320   checkAllocated();
9321   int *ptr=getPointer();
9322   std::size_t nbOfElems=getNbOfElems();
9323   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
9324     *ptr=a*(*ptr)+b;
9325   declareAsNew();
9326 }
9327
9328 /*!
9329  * Returns a full copy of \a this array except that sign of all elements is reversed.
9330  *  \return DataArrayInt * - the new instance of DataArrayInt containing the
9331  *          same number of tuples and component as \a this array.
9332  *          The caller is to delete this result array using decrRef() as it is no more
9333  *          needed.
9334  *  \throw If \a this is not allocated.
9335  */
9336 DataArrayInt *DataArrayInt::negate() const
9337 {
9338   checkAllocated();
9339   DataArrayInt *newArr=DataArrayInt::New();
9340   int nbOfTuples=getNumberOfTuples();
9341   int nbOfComp=getNumberOfComponents();
9342   newArr->alloc(nbOfTuples,nbOfComp);
9343   const int *cptr=getConstPointer();
9344   std::transform(cptr,cptr+nbOfTuples*nbOfComp,newArr->getPointer(),std::negate<int>());
9345   newArr->copyStringInfoFrom(*this);
9346   return newArr;
9347 }
9348
9349 /*!
9350  * Modify all elements of \a this array, so that
9351  * an element _x_ becomes \f$ numerator / x \f$.
9352  *  \warning If an exception is thrown because of presence of 0 element in \a this 
9353  *           array, all elements processed before detection of the zero element remain
9354  *           modified.
9355  *  \param [in] numerator - the numerator used to modify array elements.
9356  *  \throw If \a this is not allocated.
9357  *  \throw If there is an element equal to 0 in \a this array.
9358  */
9359 void DataArrayInt::applyInv(int numerator)
9360 {
9361   checkAllocated();
9362   int *ptr=getPointer();
9363   std::size_t nbOfElems=getNbOfElems();
9364   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
9365     {
9366       if(*ptr!=0)
9367         {
9368           *ptr=numerator/(*ptr);
9369         }
9370       else
9371         {
9372           std::ostringstream oss; oss << "DataArrayInt::applyInv : presence of null value in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
9373           oss << " !";
9374           throw INTERP_KERNEL::Exception(oss.str().c_str());
9375         }
9376     }
9377   declareAsNew();
9378 }
9379
9380 /*!
9381  * Modify all elements of \a this array, so that
9382  * an element _x_ becomes \f$ x / val \f$.
9383  *  \param [in] val - the denominator used to modify array elements.
9384  *  \throw If \a this is not allocated.
9385  *  \throw If \a val == 0.
9386  */
9387 void DataArrayInt::applyDivideBy(int val)
9388 {
9389   if(val==0)
9390     throw INTERP_KERNEL::Exception("DataArrayInt::applyDivideBy : Trying to divide by 0 !");
9391   checkAllocated();
9392   int *ptr=getPointer();
9393   std::size_t nbOfElems=getNbOfElems();
9394   std::transform(ptr,ptr+nbOfElems,ptr,std::bind2nd(std::divides<int>(),val));
9395   declareAsNew();
9396 }
9397
9398 /*!
9399  * Modify all elements of \a this array, so that
9400  * an element _x_ becomes  <em> x % val </em>.
9401  *  \param [in] val - the divisor used to modify array elements.
9402  *  \throw If \a this is not allocated.
9403  *  \throw If \a val <= 0.
9404  */
9405 void DataArrayInt::applyModulus(int val)
9406 {
9407   if(val<=0)
9408     throw INTERP_KERNEL::Exception("DataArrayInt::applyDivideBy : Trying to operate modulus on value <= 0 !");
9409   checkAllocated();
9410   int *ptr=getPointer();
9411   std::size_t nbOfElems=getNbOfElems();
9412   std::transform(ptr,ptr+nbOfElems,ptr,std::bind2nd(std::modulus<int>(),val));
9413   declareAsNew();
9414 }
9415
9416 /*!
9417  * This method works only on data array with one component.
9418  * This method returns a newly allocated array storing stored ascendantly tuple ids in \b this so that
9419  * this[*id] in [\b vmin,\b vmax)
9420  * 
9421  * \param [in] vmin begin of range. This value is included in range (included).
9422  * \param [in] vmax end of range. This value is \b not included in range (excluded).
9423  * \return a newly allocated data array that the caller should deal with.
9424  *
9425  * \sa DataArrayInt::getIdsNotInRange
9426  */
9427 DataArrayInt *DataArrayInt::getIdsInRange(int vmin, int vmax) const
9428 {
9429   checkAllocated();
9430   if(getNumberOfComponents()!=1)
9431     throw INTERP_KERNEL::Exception("DataArrayInt::getIdsInRange : this must have exactly one component !");
9432   const int *cptr(begin());
9433   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
9434   int nbOfTuples(getNumberOfTuples());
9435   for(int i=0;i<nbOfTuples;i++,cptr++)
9436     if(*cptr>=vmin && *cptr<vmax)
9437       ret->pushBackSilent(i);
9438   return ret.retn();
9439 }
9440
9441 /*!
9442  * This method works only on data array with one component.
9443  * This method returns a newly allocated array storing stored ascendantly tuple ids in \b this so that
9444  * this[*id] \b not in [\b vmin,\b vmax)
9445  * 
9446  * \param [in] vmin begin of range. This value is \b not included in range (excluded).
9447  * \param [in] vmax end of range. This value is included in range (included).
9448  * \return a newly allocated data array that the caller should deal with.
9449  * 
9450  * \sa DataArrayInt::getIdsInRange
9451  */
9452 DataArrayInt *DataArrayInt::getIdsNotInRange(int vmin, int vmax) const
9453 {
9454   checkAllocated();
9455   if(getNumberOfComponents()!=1)
9456     throw INTERP_KERNEL::Exception("DataArrayInt::getIdsNotInRange : this must have exactly one component !");
9457   const int *cptr(getConstPointer());
9458   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
9459   int nbOfTuples(getNumberOfTuples());
9460   for(int i=0;i<nbOfTuples;i++,cptr++)
9461     if(*cptr<vmin || *cptr>=vmax)
9462       ret->pushBackSilent(i);
9463   return ret.retn();
9464 }
9465
9466 /*!
9467  * This method works only on data array with one component.
9468  * 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.
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 if all ids in \a this are so that (*this)[i]==i for all i in [ 0, \c this->getNumberOfTuples() ). */
9473 bool DataArrayInt::checkAllIdsInRange(int vmin, int vmax) const
9474 {
9475   checkAllocated();
9476   if(getNumberOfComponents()!=1)
9477     throw INTERP_KERNEL::Exception("DataArrayInt::checkAllIdsInRange : this must have exactly one component !");
9478   int nbOfTuples=getNumberOfTuples();
9479   bool ret=true;
9480   const int *cptr=getConstPointer();
9481   for(int i=0;i<nbOfTuples;i++,cptr++)
9482     {
9483       if(*cptr>=vmin && *cptr<vmax)
9484         { ret=ret && *cptr==i; }
9485       else
9486         {
9487           std::ostringstream oss; oss << "DataArrayInt::checkAllIdsInRange : tuple #" << i << " has value " << *cptr << " should be in [" << vmin << "," << vmax << ") !";
9488           throw INTERP_KERNEL::Exception(oss.str().c_str());
9489         }
9490     }
9491   return ret;
9492 }
9493
9494 /*!
9495  * Modify all elements of \a this array, so that
9496  * an element _x_ becomes <em> val % x </em>.
9497  *  \warning If an exception is thrown because of presence of an element <= 0 in \a this 
9498  *           array, all elements processed before detection of the zero element remain
9499  *           modified.
9500  *  \param [in] val - the divident used to modify array elements.
9501  *  \throw If \a this is not allocated.
9502  *  \throw If there is an element equal to or less than 0 in \a this array.
9503  */
9504 void DataArrayInt::applyRModulus(int val)
9505 {
9506   checkAllocated();
9507   int *ptr=getPointer();
9508   std::size_t nbOfElems=getNbOfElems();
9509   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
9510     {
9511       if(*ptr>0)
9512         {
9513           *ptr=val%(*ptr);
9514         }
9515       else
9516         {
9517           std::ostringstream oss; oss << "DataArrayInt::applyRModulus : presence of value <=0 in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
9518           oss << " !";
9519           throw INTERP_KERNEL::Exception(oss.str().c_str());
9520         }
9521     }
9522   declareAsNew();
9523 }
9524
9525 /*!
9526  * Modify all elements of \a this array, so that
9527  * an element _x_ becomes <em> val ^ x </em>.
9528  *  \param [in] val - the value used to apply pow on all array elements.
9529  *  \throw If \a this is not allocated.
9530  *  \throw If \a val < 0.
9531  */
9532 void DataArrayInt::applyPow(int val)
9533 {
9534   checkAllocated();
9535   if(val<0)
9536     throw INTERP_KERNEL::Exception("DataArrayInt::applyPow : input pow in < 0 !");
9537   int *ptr=getPointer();
9538   std::size_t nbOfElems=getNbOfElems();
9539   if(val==0)
9540     {
9541       std::fill(ptr,ptr+nbOfElems,1);
9542       return ;
9543     }
9544   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
9545     {
9546       int tmp=1;
9547       for(int j=0;j<val;j++)
9548         tmp*=*ptr;
9549       *ptr=tmp;
9550     }
9551   declareAsNew();
9552 }
9553
9554 /*!
9555  * Modify all elements of \a this array, so that
9556  * an element _x_ becomes \f$ val ^ x \f$.
9557  *  \param [in] val - the value used to apply pow on all array elements.
9558  *  \throw If \a this is not allocated.
9559  *  \throw If there is an element < 0 in \a this array.
9560  *  \warning If an exception is thrown because of presence of 0 element in \a this 
9561  *           array, all elements processed before detection of the zero element remain
9562  *           modified.
9563  */
9564 void DataArrayInt::applyRPow(int val)
9565 {
9566   checkAllocated();
9567   int *ptr=getPointer();
9568   std::size_t nbOfElems=getNbOfElems();
9569   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
9570     {
9571       if(*ptr>=0)
9572         {
9573           int tmp=1;
9574           for(int j=0;j<*ptr;j++)
9575             tmp*=val;
9576           *ptr=tmp;
9577         }
9578       else
9579         {
9580           std::ostringstream oss; oss << "DataArrayInt::applyRPow : presence of negative value in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
9581           oss << " !";
9582           throw INTERP_KERNEL::Exception(oss.str().c_str());
9583         }
9584     }
9585   declareAsNew();
9586 }
9587
9588 /*!
9589  * Returns a new DataArrayInt by aggregating two given arrays, so that (1) the number
9590  * of components in the result array is a sum of the number of components of given arrays
9591  * and (2) the number of tuples in the result array is same as that of each of given
9592  * arrays. In other words the i-th tuple of result array includes all components of
9593  * i-th tuples of all given arrays.
9594  * Number of tuples in the given arrays must be the same.
9595  *  \param [in] a1 - an array to include in the result array.
9596  *  \param [in] a2 - another array to include in the result array.
9597  *  \return DataArrayInt * - the new instance of DataArrayInt.
9598  *          The caller is to delete this result array using decrRef() as it is no more
9599  *          needed.
9600  *  \throw If both \a a1 and \a a2 are NULL.
9601  *  \throw If any given array is not allocated.
9602  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
9603  */
9604 DataArrayInt *DataArrayInt::Meld(const DataArrayInt *a1, const DataArrayInt *a2)
9605 {
9606   std::vector<const DataArrayInt *> arr(2);
9607   arr[0]=a1; arr[1]=a2;
9608   return Meld(arr);
9609 }
9610
9611 /*!
9612  * Returns a new DataArrayInt by aggregating all given arrays, so that (1) the number
9613  * of components in the result array is a sum of the number of components of given arrays
9614  * and (2) the number of tuples in the result array is same as that of each of given
9615  * arrays. In other words the i-th tuple of result array includes all components of
9616  * i-th tuples of all given arrays.
9617  * Number of tuples in the given arrays must be  the same.
9618  *  \param [in] arr - a sequence of arrays to include in the result array.
9619  *  \return DataArrayInt * - the new instance of DataArrayInt.
9620  *          The caller is to delete this result array using decrRef() as it is no more
9621  *          needed.
9622  *  \throw If all arrays within \a arr are NULL.
9623  *  \throw If any given array is not allocated.
9624  *  \throw If getNumberOfTuples() of arrays within \a arr is different.
9625  */
9626 DataArrayInt *DataArrayInt::Meld(const std::vector<const DataArrayInt *>& arr)
9627 {
9628   std::vector<const DataArrayInt *> a;
9629   for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
9630     if(*it4)
9631       a.push_back(*it4);
9632   if(a.empty())
9633     throw INTERP_KERNEL::Exception("DataArrayInt::Meld : array must be NON empty !");
9634   std::vector<const DataArrayInt *>::const_iterator it;
9635   for(it=a.begin();it!=a.end();it++)
9636     (*it)->checkAllocated();
9637   it=a.begin();
9638   int nbOfTuples=(*it)->getNumberOfTuples();
9639   std::vector<int> nbc(a.size());
9640   std::vector<const int *> pts(a.size());
9641   nbc[0]=(*it)->getNumberOfComponents();
9642   pts[0]=(*it++)->getConstPointer();
9643   for(int i=1;it!=a.end();it++,i++)
9644     {
9645       if(nbOfTuples!=(*it)->getNumberOfTuples())
9646         throw INTERP_KERNEL::Exception("DataArrayInt::meld : mismatch of number of tuples !");
9647       nbc[i]=(*it)->getNumberOfComponents();
9648       pts[i]=(*it)->getConstPointer();
9649     }
9650   int totalNbOfComp=std::accumulate(nbc.begin(),nbc.end(),0);
9651   DataArrayInt *ret=DataArrayInt::New();
9652   ret->alloc(nbOfTuples,totalNbOfComp);
9653   int *retPtr=ret->getPointer();
9654   for(int i=0;i<nbOfTuples;i++)
9655     for(int j=0;j<(int)a.size();j++)
9656       {
9657         retPtr=std::copy(pts[j],pts[j]+nbc[j],retPtr);
9658         pts[j]+=nbc[j];
9659       }
9660   int k=0;
9661   for(int i=0;i<(int)a.size();i++)
9662     for(int j=0;j<nbc[i];j++,k++)
9663       ret->setInfoOnComponent(k,a[i]->getInfoOnComponent(j));
9664   return ret;
9665 }
9666
9667 /*!
9668  * Returns a new DataArrayInt which is a minimal partition of elements of \a groups.
9669  * The i-th item of the result array is an ID of a set of elements belonging to a
9670  * unique set of groups, which the i-th element is a part of. This set of elements
9671  * belonging to a unique set of groups is called \a family, so the result array contains
9672  * IDs of families each element belongs to.
9673  *
9674  * \b Example: if we have two groups of elements: \a group1 [0,4] and \a group2 [ 0,1,2 ],
9675  * then there are 3 families:
9676  * - \a family1 (with ID 1) contains element [0] belonging to ( \a group1 + \a group2 ),
9677  * - \a family2 (with ID 2) contains elements [4] belonging to ( \a group1 ),
9678  * - \a family3 (with ID 3) contains element [1,2] belonging to ( \a group2 ), <br>
9679  * and the result array contains IDs of families [ 1,3,3,0,2 ]. <br> Note a family ID 0 which
9680  * stands for the element #3 which is in none of groups.
9681  *
9682  *  \param [in] groups - sequence of groups of element IDs.
9683  *  \param [in] newNb - total number of elements; it must be more than max ID of element
9684  *         in \a groups.
9685  *  \param [out] fidsOfGroups - IDs of families the elements of each group belong to.
9686  *  \return DataArrayInt * - a new instance of DataArrayInt containing IDs of families
9687  *         each element with ID from range [0, \a newNb ) belongs to. The caller is to
9688  *         delete this array using decrRef() as it is no more needed.
9689  *  \throw If any element ID in \a groups violates condition ( 0 <= ID < \a newNb ).
9690  */
9691 DataArrayInt *DataArrayInt::MakePartition(const std::vector<const DataArrayInt *>& groups, int newNb, std::vector< std::vector<int> >& fidsOfGroups)
9692 {
9693   std::vector<const DataArrayInt *> groups2;
9694   for(std::vector<const DataArrayInt *>::const_iterator it4=groups.begin();it4!=groups.end();it4++)
9695     if(*it4)
9696       groups2.push_back(*it4);
9697   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
9698   ret->alloc(newNb,1);
9699   int *retPtr=ret->getPointer();
9700   std::fill(retPtr,retPtr+newNb,0);
9701   int fid=1;
9702   for(std::vector<const DataArrayInt *>::const_iterator iter=groups2.begin();iter!=groups2.end();iter++)
9703     {
9704       const int *ptr=(*iter)->getConstPointer();
9705       std::size_t nbOfElem=(*iter)->getNbOfElems();
9706       int sfid=fid;
9707       for(int j=0;j<sfid;j++)
9708         {
9709           bool found=false;
9710           for(std::size_t i=0;i<nbOfElem;i++)
9711             {
9712               if(ptr[i]>=0 && ptr[i]<newNb)
9713                 {
9714                   if(retPtr[ptr[i]]==j)
9715                     {
9716                       retPtr[ptr[i]]=fid;
9717                       found=true;
9718                     }
9719                 }
9720               else
9721                 {
9722                   std::ostringstream oss; oss << "DataArrayInt::MakePartition : In group \"" << (*iter)->getName() << "\" in tuple #" << i << " value = " << ptr[i] << " ! Should be in [0," << newNb;
9723                   oss << ") !";
9724                   throw INTERP_KERNEL::Exception(oss.str().c_str());
9725                 }
9726             }
9727           if(found)
9728             fid++;
9729         }
9730     }
9731   fidsOfGroups.clear();
9732   fidsOfGroups.resize(groups2.size());
9733   int grId=0;
9734   for(std::vector<const DataArrayInt *>::const_iterator iter=groups2.begin();iter!=groups2.end();iter++,grId++)
9735     {
9736       std::set<int> tmp;
9737       const int *ptr=(*iter)->getConstPointer();
9738       std::size_t nbOfElem=(*iter)->getNbOfElems();
9739       for(const int *p=ptr;p!=ptr+nbOfElem;p++)
9740         tmp.insert(retPtr[*p]);
9741       fidsOfGroups[grId].insert(fidsOfGroups[grId].end(),tmp.begin(),tmp.end());
9742     }
9743   return ret.retn();
9744 }
9745
9746 /*!
9747  * Returns a new DataArrayInt which contains all elements of given one-dimensional
9748  * arrays. The result array does not contain any duplicates and its values
9749  * are sorted in ascending order.
9750  *  \param [in] arr - sequence of DataArrayInt's to unite.
9751  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
9752  *         array using decrRef() as it is no more needed.
9753  *  \throw If any \a arr[i] is not allocated.
9754  *  \throw If \a arr[i]->getNumberOfComponents() != 1.
9755  */
9756 DataArrayInt *DataArrayInt::BuildUnion(const std::vector<const DataArrayInt *>& arr)
9757 {
9758   std::vector<const DataArrayInt *> a;
9759   for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
9760     if(*it4)
9761       a.push_back(*it4);
9762   for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
9763     {
9764       (*it)->checkAllocated();
9765       if((*it)->getNumberOfComponents()!=1)
9766         throw INTERP_KERNEL::Exception("DataArrayInt::BuildUnion : only single component allowed !");
9767     }
9768   //
9769   std::set<int> r;
9770   for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
9771     {
9772       const int *pt=(*it)->getConstPointer();
9773       int nbOfTuples=(*it)->getNumberOfTuples();
9774       r.insert(pt,pt+nbOfTuples);
9775     }
9776   DataArrayInt *ret=DataArrayInt::New();
9777   ret->alloc((int)r.size(),1);
9778   std::copy(r.begin(),r.end(),ret->getPointer());
9779   return ret;
9780 }
9781
9782 /*!
9783  * Returns a new DataArrayInt which contains elements present in each of given one-dimensional
9784  * arrays. The result array does not contain any duplicates and its values
9785  * are sorted in ascending order.
9786  *  \param [in] arr - sequence of DataArrayInt's to intersect.
9787  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
9788  *         array using decrRef() as it is no more needed.
9789  *  \throw If any \a arr[i] is not allocated.
9790  *  \throw If \a arr[i]->getNumberOfComponents() != 1.
9791  */
9792 DataArrayInt *DataArrayInt::BuildIntersection(const std::vector<const DataArrayInt *>& arr)
9793 {
9794   std::vector<const DataArrayInt *> a;
9795   for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
9796     if(*it4)
9797       a.push_back(*it4);
9798   for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
9799     {
9800       (*it)->checkAllocated();
9801       if((*it)->getNumberOfComponents()!=1)
9802         throw INTERP_KERNEL::Exception("DataArrayInt::BuildIntersection : only single component allowed !");
9803     }
9804   //
9805   std::set<int> r;
9806   for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
9807     {
9808       const int *pt=(*it)->getConstPointer();
9809       int nbOfTuples=(*it)->getNumberOfTuples();
9810       std::set<int> s1(pt,pt+nbOfTuples);
9811       if(it!=a.begin())
9812         {
9813           std::set<int> r2;
9814           std::set_intersection(r.begin(),r.end(),s1.begin(),s1.end(),inserter(r2,r2.end()));
9815           r=r2;
9816         }
9817       else
9818         r=s1;
9819     }
9820   DataArrayInt *ret(DataArrayInt::New());
9821   ret->alloc((int)r.size(),1);
9822   std::copy(r.begin(),r.end(),ret->getPointer());
9823   return ret;
9824 }
9825
9826 /// @cond INTERNAL
9827 namespace ParaMEDMEMImpl
9828 {
9829   class OpSwitchedOn
9830   {
9831   public:
9832     OpSwitchedOn(int *pt):_pt(pt),_cnt(0) { }
9833     void operator()(const bool& b) { if(b) *_pt++=_cnt; _cnt++; }
9834   private:
9835     int *_pt;
9836     int _cnt;
9837   };
9838
9839   class OpSwitchedOff
9840   {
9841   public:
9842     OpSwitchedOff(int *pt):_pt(pt),_cnt(0) { }
9843     void operator()(const bool& b) { if(!b) *_pt++=_cnt; _cnt++; }
9844   private:
9845     int *_pt;
9846     int _cnt;
9847   };
9848 }
9849 /// @endcond
9850
9851 /*!
9852  * This method returns the list of ids in ascending mode so that v[id]==true.
9853  */
9854 DataArrayInt *DataArrayInt::BuildListOfSwitchedOn(const std::vector<bool>& v)
9855 {
9856   int sz((int)std::count(v.begin(),v.end(),true));
9857   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(sz,1);
9858   std::for_each(v.begin(),v.end(),ParaMEDMEMImpl::OpSwitchedOn(ret->getPointer()));
9859   return ret.retn();
9860 }
9861
9862 /*!
9863  * This method returns the list of ids in ascending mode so that v[id]==false.
9864  */
9865 DataArrayInt *DataArrayInt::BuildListOfSwitchedOff(const std::vector<bool>& v)
9866 {
9867   int sz((int)std::count(v.begin(),v.end(),false));
9868   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(sz,1);
9869   std::for_each(v.begin(),v.end(),ParaMEDMEMImpl::OpSwitchedOff(ret->getPointer()));
9870   return ret.retn();
9871 }
9872
9873 /*!
9874  * This method allows to put a vector of vector of integer into a more compact data stucture (skyline). 
9875  * This method is not available into python because no available optimized data structure available to map std::vector< std::vector<int> >.
9876  *
9877  * \param [in] v the input data structure to be translate into skyline format.
9878  * \param [out] data the first element of the skyline format. The user is expected to deal with newly allocated array.
9879  * \param [out] dataIndex the second element of the skyline format.
9880  */
9881 void DataArrayInt::PutIntoToSkylineFrmt(const std::vector< std::vector<int> >& v, DataArrayInt *& data, DataArrayInt *& dataIndex)
9882 {
9883   int sz((int)v.size());
9884   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret0(DataArrayInt::New()),ret1(DataArrayInt::New());
9885   ret1->alloc(sz+1,1);
9886   int *pt(ret1->getPointer()); *pt=0;
9887   for(int i=0;i<sz;i++,pt++)
9888     pt[1]=pt[0]+(int)v[i].size();
9889   ret0->alloc(ret1->back(),1);
9890   pt=ret0->getPointer();
9891   for(int i=0;i<sz;i++)
9892     pt=std::copy(v[i].begin(),v[i].end(),pt);
9893   data=ret0.retn(); dataIndex=ret1.retn();
9894 }
9895
9896 /*!
9897  * Returns a new DataArrayInt which contains a complement of elements of \a this
9898  * one-dimensional array. I.e. the result array contains all elements from the range [0,
9899  * \a nbOfElement) not present in \a this array.
9900  *  \param [in] nbOfElement - maximal size of the result array.
9901  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
9902  *         array using decrRef() as it is no more needed.
9903  *  \throw If \a this is not allocated.
9904  *  \throw If \a this->getNumberOfComponents() != 1.
9905  *  \throw If any element \a x of \a this array violates condition ( 0 <= \a x < \a
9906  *         nbOfElement ).
9907  */
9908 DataArrayInt *DataArrayInt::buildComplement(int nbOfElement) const
9909 {
9910   checkAllocated();
9911   if(getNumberOfComponents()!=1)
9912     throw INTERP_KERNEL::Exception("DataArrayInt::buildComplement : only single component allowed !");
9913   std::vector<bool> tmp(nbOfElement);
9914   const int *pt=getConstPointer();
9915   int nbOfTuples=getNumberOfTuples();
9916   for(const int *w=pt;w!=pt+nbOfTuples;w++)
9917     if(*w>=0 && *w<nbOfElement)
9918       tmp[*w]=true;
9919     else
9920       throw INTERP_KERNEL::Exception("DataArrayInt::buildComplement : an element is not in valid range : [0,nbOfElement) !");
9921   int nbOfRetVal=(int)std::count(tmp.begin(),tmp.end(),false);
9922   DataArrayInt *ret=DataArrayInt::New();
9923   ret->alloc(nbOfRetVal,1);
9924   int j=0;
9925   int *retPtr=ret->getPointer();
9926   for(int i=0;i<nbOfElement;i++)
9927     if(!tmp[i])
9928       retPtr[j++]=i;
9929   return ret;
9930 }
9931
9932 /*!
9933  * Returns a new DataArrayInt containing elements of \a this one-dimensional missing
9934  * from an \a other one-dimensional array.
9935  *  \param [in] other - a DataArrayInt containing elements not to include in the result array.
9936  *  \return DataArrayInt * - a new instance of DataArrayInt with one component. The
9937  *         caller is to delete this array using decrRef() as it is no more needed.
9938  *  \throw If \a other is NULL.
9939  *  \throw If \a other is not allocated.
9940  *  \throw If \a other->getNumberOfComponents() != 1.
9941  *  \throw If \a this is not allocated.
9942  *  \throw If \a this->getNumberOfComponents() != 1.
9943  *  \sa DataArrayInt::buildSubstractionOptimized()
9944  */
9945 DataArrayInt *DataArrayInt::buildSubstraction(const DataArrayInt *other) const
9946 {
9947   if(!other)
9948     throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstraction : DataArrayInt pointer in input is NULL !");
9949   checkAllocated();
9950   other->checkAllocated();
9951   if(getNumberOfComponents()!=1)
9952     throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstraction : only single component allowed !");
9953   if(other->getNumberOfComponents()!=1)
9954     throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstraction : only single component allowed for other type !");
9955   const int *pt=getConstPointer();
9956   int nbOfTuples=getNumberOfTuples();
9957   std::set<int> s1(pt,pt+nbOfTuples);
9958   pt=other->getConstPointer();
9959   nbOfTuples=other->getNumberOfTuples();
9960   std::set<int> s2(pt,pt+nbOfTuples);
9961   std::vector<int> r;
9962   std::set_difference(s1.begin(),s1.end(),s2.begin(),s2.end(),std::back_insert_iterator< std::vector<int> >(r));
9963   DataArrayInt *ret=DataArrayInt::New();
9964   ret->alloc((int)r.size(),1);
9965   std::copy(r.begin(),r.end(),ret->getPointer());
9966   return ret;
9967 }
9968
9969 /*!
9970  * \a this is expected to have one component and to be sorted ascendingly (as for \a other).
9971  * \a other is expected to be a part of \a this. If not DataArrayInt::buildSubstraction should be called instead.
9972  * 
9973  * \param [in] other an array with one component and expected to be sorted ascendingly.
9974  * \ret list of ids in \a this but not in \a other.
9975  * \sa DataArrayInt::buildSubstraction
9976  */
9977 DataArrayInt *DataArrayInt::buildSubstractionOptimized(const DataArrayInt *other) const
9978 {
9979   static const char *MSG="DataArrayInt::buildSubstractionOptimized : only single component allowed !";
9980   if(!other) throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstractionOptimized : NULL input array !");
9981   checkAllocated(); other->checkAllocated();
9982   if(getNumberOfComponents()!=1) throw INTERP_KERNEL::Exception(MSG);
9983   if(other->getNumberOfComponents()!=1) throw INTERP_KERNEL::Exception(MSG);
9984   const int *pt1Bg(begin()),*pt1End(end()),*pt2Bg(other->begin()),*pt2End(other->end());
9985   const int *work1(pt1Bg),*work2(pt2Bg);
9986   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
9987   for(;work1!=pt1End;work1++)
9988     {
9989       if(work2!=pt2End && *work1==*work2)
9990         work2++;
9991       else
9992         ret->pushBackSilent(*work1);
9993     }
9994   return ret.retn();
9995 }
9996
9997
9998 /*!
9999  * Returns a new DataArrayInt which contains all elements of \a this and a given
10000  * one-dimensional arrays. The result array does not contain any duplicates
10001  * and its values are sorted in ascending order.
10002  *  \param [in] other - an array to unite with \a this one.
10003  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
10004  *         array using decrRef() as it is no more needed.
10005  *  \throw If \a this or \a other is not allocated.
10006  *  \throw If \a this->getNumberOfComponents() != 1.
10007  *  \throw If \a other->getNumberOfComponents() != 1.
10008  */
10009 DataArrayInt *DataArrayInt::buildUnion(const DataArrayInt *other) const
10010 {
10011   std::vector<const DataArrayInt *>arrs(2);
10012   arrs[0]=this; arrs[1]=other;
10013   return BuildUnion(arrs);
10014 }
10015
10016
10017 /*!
10018  * Returns a new DataArrayInt which contains elements present in both \a this and a given
10019  * one-dimensional arrays. The result array does not contain any duplicates
10020  * and its values are sorted in ascending order.
10021  *  \param [in] other - an array to intersect with \a this one.
10022  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
10023  *         array using decrRef() as it is no more needed.
10024  *  \throw If \a this or \a other is not allocated.
10025  *  \throw If \a this->getNumberOfComponents() != 1.
10026  *  \throw If \a other->getNumberOfComponents() != 1.
10027  */
10028 DataArrayInt *DataArrayInt::buildIntersection(const DataArrayInt *other) const
10029 {
10030   std::vector<const DataArrayInt *>arrs(2);
10031   arrs[0]=this; arrs[1]=other;
10032   return BuildIntersection(arrs);
10033 }
10034
10035 /*!
10036  * This method can be applied on allocated with one component DataArrayInt instance.
10037  * This method is typically relevant for sorted arrays. All consecutive duplicated items in \a this will appear only once in returned DataArrayInt instance.
10038  * 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]
10039  * 
10040  * \return a newly allocated array that contain the result of the unique operation applied on \a this.
10041  * \throw if \a this is not allocated or if \a this has not exactly one component.
10042  */
10043 DataArrayInt *DataArrayInt::buildUnique() const
10044 {
10045   checkAllocated();
10046   if(getNumberOfComponents()!=1)
10047     throw INTERP_KERNEL::Exception("DataArrayInt::buildUnique : only single component allowed !");
10048   int nbOfTuples=getNumberOfTuples();
10049   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp=deepCpy();
10050   int *data=tmp->getPointer();
10051   int *last=std::unique(data,data+nbOfTuples);
10052   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
10053   ret->alloc(std::distance(data,last),1);
10054   std::copy(data,last,ret->getPointer());
10055   return ret.retn();
10056 }
10057
10058 /*!
10059  * Returns a new DataArrayInt which contains size of every of groups described by \a this
10060  * "index" array. Such "index" array is returned for example by 
10061  * \ref ParaMEDMEM::MEDCouplingUMesh::buildDescendingConnectivity
10062  * "MEDCouplingUMesh::buildDescendingConnectivity" and
10063  * \ref ParaMEDMEM::MEDCouplingUMesh::getNodalConnectivityIndex
10064  * "MEDCouplingUMesh::getNodalConnectivityIndex" etc.
10065  * This method preforms the reverse operation of DataArrayInt::computeOffsets2.
10066  *  \return DataArrayInt * - a new instance of DataArrayInt, whose number of tuples
10067  *          equals to \a this->getNumberOfComponents() - 1, and number of components is 1.
10068  *          The caller is to delete this array using decrRef() as it is no more needed. 
10069  *  \throw If \a this is not allocated.
10070  *  \throw If \a this->getNumberOfComponents() != 1.
10071  *  \throw If \a this->getNumberOfTuples() < 2.
10072  *
10073  *  \b Example: <br> 
10074  *         - this contains [1,3,6,7,7,9,15]
10075  *         - result array contains [2,3,1,0,2,6],
10076  *          where 2 = 3 - 1, 3 = 6 - 3, 1 = 7 - 6 etc.
10077  *
10078  * \sa DataArrayInt::computeOffsets2
10079  */
10080 DataArrayInt *DataArrayInt::deltaShiftIndex() const
10081 {
10082   checkAllocated();
10083   if(getNumberOfComponents()!=1)
10084     throw INTERP_KERNEL::Exception("DataArrayInt::deltaShiftIndex : only single component allowed !");
10085   int nbOfTuples=getNumberOfTuples();
10086   if(nbOfTuples<2)
10087     throw INTERP_KERNEL::Exception("DataArrayInt::deltaShiftIndex : 1 tuple at least must be present in 'this' !");
10088   const int *ptr=getConstPointer();
10089   DataArrayInt *ret=DataArrayInt::New();
10090   ret->alloc(nbOfTuples-1,1);
10091   int *out=ret->getPointer();
10092   std::transform(ptr+1,ptr+nbOfTuples,ptr,out,std::minus<int>());
10093   return ret;
10094 }
10095
10096 /*!
10097  * Modifies \a this one-dimensional array so that value of each element \a x
10098  * of \a this array (\a a) is computed as \f$ x_i = \sum_{j=0}^{i-1} a[ j ] \f$.
10099  * Or: for each i>0 new[i]=new[i-1]+old[i-1] for i==0 new[i]=0. Number of tuples
10100  * and components remains the same.<br>
10101  * This method is useful for allToAllV in MPI with contiguous policy. This method
10102  * differs from computeOffsets2() in that the number of tuples is \b not changed by
10103  * this one.
10104  *  \throw If \a this is not allocated.
10105  *  \throw If \a this->getNumberOfComponents() != 1.
10106  *
10107  *  \b Example: <br>
10108  *          - Before \a this contains [3,5,1,2,0,8]
10109  *          - After \a this contains  [0,3,8,9,11,11]<br>
10110  *          Note that the last element 19 = 11 + 8 is missing because size of \a this
10111  *          array is retained and thus there is no space to store the last element.
10112  */
10113 void DataArrayInt::computeOffsets()
10114 {
10115   checkAllocated();
10116   if(getNumberOfComponents()!=1)
10117     throw INTERP_KERNEL::Exception("DataArrayInt::computeOffsets : only single component allowed !");
10118   int nbOfTuples=getNumberOfTuples();
10119   if(nbOfTuples==0)
10120     return ;
10121   int *work=getPointer();
10122   int tmp=work[0];
10123   work[0]=0;
10124   for(int i=1;i<nbOfTuples;i++)
10125     {
10126       int tmp2=work[i];
10127       work[i]=work[i-1]+tmp;
10128       tmp=tmp2;
10129     }
10130   declareAsNew();
10131 }
10132
10133
10134 /*!
10135  * Modifies \a this one-dimensional array so that value of each element \a x
10136  * of \a this array (\a a) is computed as \f$ x_i = \sum_{j=0}^{i-1} a[ j ] \f$.
10137  * Or: for each i>0 new[i]=new[i-1]+old[i-1] for i==0 new[i]=0. Number
10138  * components remains the same and number of tuples is inceamented by one.<br>
10139  * This method is useful for allToAllV in MPI with contiguous policy. This method
10140  * differs from computeOffsets() in that the number of tuples is changed by this one.
10141  * This method preforms the reverse operation of DataArrayInt::deltaShiftIndex.
10142  *  \throw If \a this is not allocated.
10143  *  \throw If \a this->getNumberOfComponents() != 1.
10144  *
10145  *  \b Example: <br>
10146  *          - Before \a this contains [3,5,1,2,0,8]
10147  *          - After \a this contains  [0,3,8,9,11,11,19]<br>
10148  * \sa DataArrayInt::deltaShiftIndex
10149  */
10150 void DataArrayInt::computeOffsets2()
10151 {
10152   checkAllocated();
10153   if(getNumberOfComponents()!=1)
10154     throw INTERP_KERNEL::Exception("DataArrayInt::computeOffsets2 : only single component allowed !");
10155   int nbOfTuples=getNumberOfTuples();
10156   int *ret=(int *)malloc((nbOfTuples+1)*sizeof(int));
10157   if(nbOfTuples==0)
10158     return ;
10159   const int *work=getConstPointer();
10160   ret[0]=0;
10161   for(int i=0;i<nbOfTuples;i++)
10162     ret[i+1]=work[i]+ret[i];
10163   useArray(ret,true,C_DEALLOC,nbOfTuples+1,1);
10164   declareAsNew();
10165 }
10166
10167 /*!
10168  * Returns two new DataArrayInt instances whose contents is computed from that of \a this and \a listOfIds arrays as follows.
10169  * \a this is expected to be an offset format ( as returned by DataArrayInt::computeOffsets2 ) that is to say with one component
10170  * and ** sorted strictly increasingly **. \a listOfIds is expected to be sorted ascendingly (not strictly needed for \a listOfIds).
10171  * This methods searches in \a this, considered as a set of contiguous \c this->getNumberOfComponents() ranges, all ids in \a listOfIds
10172  * filling completely one of the ranges in \a this.
10173  *
10174  * \param [in] listOfIds a list of ids that has to be sorted ascendingly.
10175  * \param [out] rangeIdsFetched the range ids fetched
10176  * \param [out] idsInInputListThatFetch contains the list of ids in \a listOfIds that are \b fully included in a range in \a this. So
10177  *              \a idsInInputListThatFetch is a part of input \a listOfIds.
10178  *
10179  * \sa DataArrayInt::computeOffsets2
10180  *
10181  *  \b Example: <br>
10182  *          - \a this : [0,3,7,9,15,18]
10183  *          - \a listOfIds contains  [0,1,2,3,7,8,15,16,17]
10184  *          - \a rangeIdsFetched result array: [0,2,4]
10185  *          - \a idsInInputListThatFetch result array: [0,1,2,7,8,15,16,17]
10186  * In this example id 3 in input \a listOfIds is alone so it do not appear in output \a idsInInputListThatFetch.
10187  * <br>
10188  */
10189 void DataArrayInt::searchRangesInListOfIds(const DataArrayInt *listOfIds, DataArrayInt *& rangeIdsFetched, DataArrayInt *& idsInInputListThatFetch) const
10190 {
10191   if(!listOfIds)
10192     throw INTERP_KERNEL::Exception("DataArrayInt::searchRangesInListOfIds : input list of ids is null !");
10193   listOfIds->checkAllocated(); checkAllocated();
10194   if(listOfIds->getNumberOfComponents()!=1)
10195     throw INTERP_KERNEL::Exception("DataArrayInt::searchRangesInListOfIds : input list of ids must have exactly one component !");
10196   if(getNumberOfComponents()!=1)
10197     throw INTERP_KERNEL::Exception("DataArrayInt::searchRangesInListOfIds : this must have exactly one component !");
10198   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret0=DataArrayInt::New(); ret0->alloc(0,1);
10199   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret1=DataArrayInt::New(); ret1->alloc(0,1);
10200   const int *tupEnd(listOfIds->end()),*offBg(begin()),*offEnd(end()-1);
10201   const int *tupPtr(listOfIds->begin()),*offPtr(offBg);
10202   while(tupPtr!=tupEnd && offPtr!=offEnd)
10203     {
10204       if(*tupPtr==*offPtr)
10205         {
10206           int i=offPtr[0];
10207           while(i<offPtr[1] && *tupPtr==i && tupPtr!=tupEnd) { i++; tupPtr++; }
10208           if(i==offPtr[1])
10209             {
10210               ret0->pushBackSilent((int)std::distance(offBg,offPtr));
10211               ret1->pushBackValsSilent(tupPtr-(offPtr[1]-offPtr[0]),tupPtr);
10212               offPtr++;
10213             }
10214         }
10215       else
10216         { if(*tupPtr<*offPtr) tupPtr++; else offPtr++; }
10217     }
10218   rangeIdsFetched=ret0.retn();
10219   idsInInputListThatFetch=ret1.retn();
10220 }
10221
10222 /*!
10223  * Returns a new DataArrayInt whose contents is computed from that of \a this and \a
10224  * offsets arrays as follows. \a offsets is a one-dimensional array considered as an
10225  * "index" array of a "iota" array, thus, whose each element gives an index of a group
10226  * beginning within the "iota" array. And \a this is a one-dimensional array
10227  * considered as a selector of groups described by \a offsets to include into the result array.
10228  *  \throw If \a offsets is NULL.
10229  *  \throw If \a offsets is not allocated.
10230  *  \throw If \a offsets->getNumberOfComponents() != 1.
10231  *  \throw If \a offsets is not monotonically increasing.
10232  *  \throw If \a this is not allocated.
10233  *  \throw If \a this->getNumberOfComponents() != 1.
10234  *  \throw If any element of \a this is not a valid index for \a offsets array.
10235  *
10236  *  \b Example: <br>
10237  *          - \a this: [0,2,3]
10238  *          - \a offsets: [0,3,6,10,14,20]
10239  *          - result array: [0,1,2,6,7,8,9,10,11,12,13] == <br>
10240  *            \c range(0,3) + \c range(6,10) + \c range(10,14) ==<br>
10241  *            \c range( \a offsets[ \a this[0] ], offsets[ \a this[0]+1 ]) + 
10242  *            \c range( \a offsets[ \a this[1] ], offsets[ \a this[1]+1 ]) + 
10243  *            \c range( \a offsets[ \a this[2] ], offsets[ \a this[2]+1 ])
10244  */
10245 DataArrayInt *DataArrayInt::buildExplicitArrByRanges(const DataArrayInt *offsets) const
10246 {
10247   if(!offsets)
10248     throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrByRanges : DataArrayInt pointer in input is NULL !");
10249   checkAllocated();
10250   if(getNumberOfComponents()!=1)
10251     throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrByRanges : only single component allowed !");
10252   offsets->checkAllocated();
10253   if(offsets->getNumberOfComponents()!=1)
10254     throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrByRanges : input array should have only single component !");
10255   int othNbTuples=offsets->getNumberOfTuples()-1;
10256   int nbOfTuples=getNumberOfTuples();
10257   int retNbOftuples=0;
10258   const int *work=getConstPointer();
10259   const int *offPtr=offsets->getConstPointer();
10260   for(int i=0;i<nbOfTuples;i++)
10261     {
10262       int val=work[i];
10263       if(val>=0 && val<othNbTuples)
10264         {
10265           int delta=offPtr[val+1]-offPtr[val];
10266           if(delta>=0)
10267             retNbOftuples+=delta;
10268           else
10269             {
10270               std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrByRanges : Tuple #" << val << " of offset array has a delta < 0 !";
10271               throw INTERP_KERNEL::Exception(oss.str().c_str());
10272             }
10273         }
10274       else
10275         {
10276           std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrByRanges : Tuple #" << i << " in this contains " << val;
10277           oss << " whereas offsets array is of size " << othNbTuples+1 << " !";
10278           throw INTERP_KERNEL::Exception(oss.str().c_str());
10279         }
10280     }
10281   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
10282   ret->alloc(retNbOftuples,1);
10283   int *retPtr=ret->getPointer();
10284   for(int i=0;i<nbOfTuples;i++)
10285     {
10286       int val=work[i];
10287       int start=offPtr[val];
10288       int off=offPtr[val+1]-start;
10289       for(int j=0;j<off;j++,retPtr++)
10290         *retPtr=start+j;
10291     }
10292   return ret.retn();
10293 }
10294
10295 /*!
10296  * Returns a new DataArrayInt whose contents is computed using \a this that must be a 
10297  * scaled array (monotonically increasing).
10298 from that of \a this and \a
10299  * offsets arrays as follows. \a offsets is a one-dimensional array considered as an
10300  * "index" array of a "iota" array, thus, whose each element gives an index of a group
10301  * beginning within the "iota" array. And \a this is a one-dimensional array
10302  * considered as a selector of groups described by \a offsets to include into the result array.
10303  *  \throw If \a  is NULL.
10304  *  \throw If \a this is not allocated.
10305  *  \throw If \a this->getNumberOfComponents() != 1.
10306  *  \throw If \a this->getNumberOfTuples() == 0.
10307  *  \throw If \a this is not monotonically increasing.
10308  *  \throw If any element of ids in ( \a bg \a stop \a step ) points outside the scale in \a this.
10309  *
10310  *  \b Example: <br>
10311  *          - \a bg , \a stop and \a step : (0,5,2)
10312  *          - \a this: [0,3,6,10,14,20]
10313  *          - result array: [0,0,0, 2,2,2,2, 4,4,4,4,4,4] == <br>
10314  */
10315 DataArrayInt *DataArrayInt::buildExplicitArrOfSliceOnScaledArr(int bg, int stop, int step) const
10316 {
10317   if(!isAllocated())
10318     throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrOfSliceOnScaledArr : not allocated array !");
10319   if(getNumberOfComponents()!=1)
10320     throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrOfSliceOnScaledArr : number of components is expected to be equal to one !");
10321   int nbOfTuples(getNumberOfTuples());
10322   if(nbOfTuples==0)
10323     throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrOfSliceOnScaledArr : number of tuples must be != 0 !");
10324   const int *ids(begin());
10325   int nbOfEltsInSlc(GetNumberOfItemGivenBESRelative(bg,stop,step,"DataArrayInt::buildExplicitArrOfSliceOnScaledArr")),sz(0),pos(bg);
10326   for(int i=0;i<nbOfEltsInSlc;i++,pos+=step)
10327     {
10328       if(pos>=0 && pos<nbOfTuples-1)
10329         {
10330           int delta(ids[pos+1]-ids[pos]);
10331           sz+=delta;
10332           if(delta<0)
10333             {
10334               std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrOfSliceOnScaledArr : At pos #" << i << " of input slice, value is " << pos << " and at this pos this is not monotonically increasing !";
10335               throw INTERP_KERNEL::Exception(oss.str().c_str());
10336             }          
10337         }
10338       else
10339         {
10340           std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrOfSliceOnScaledArr : At pos #" << i << " of input slice, value is " << pos << " should be in [0," << nbOfTuples-1 << ") !";  
10341           throw INTERP_KERNEL::Exception(oss.str().c_str());
10342         }
10343     }
10344   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(sz,1);
10345   int *retPtr(ret->getPointer());
10346   pos=bg;
10347   for(int i=0;i<nbOfEltsInSlc;i++,pos+=step)
10348     {
10349       int delta(ids[pos+1]-ids[pos]);
10350       for(int j=0;j<delta;j++,retPtr++)
10351         *retPtr=pos;
10352     }
10353   return ret.retn();
10354 }
10355
10356 /*!
10357  * 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.
10358  * 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
10359  * in tuple **i** of returned DataArrayInt.
10360  * If ranges overlapped (in theory it should not) this method do not detect it and always returns the first range.
10361  *
10362  * 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)]
10363  * The return DataArrayInt will contain : **[0,4,1,2,2,3]**
10364  * 
10365  * \param [in] ranges typically come from output of MEDCouplingUMesh::ComputeRangesFromTypeDistribution. Each range is specified like this : 1st component is
10366  *             for lower value included and 2nd component is the upper value of corresponding range **excluded**.
10367  * \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
10368  *        is thrown if no ranges in \a ranges contains value in \a this.
10369  * 
10370  * \sa DataArrayInt::findIdInRangeForEachTuple
10371  */
10372 DataArrayInt *DataArrayInt::findRangeIdForEachTuple(const DataArrayInt *ranges) const
10373 {
10374   if(!ranges)
10375     throw INTERP_KERNEL::Exception("DataArrayInt::findRangeIdForEachTuple : null input pointer !");
10376   if(ranges->getNumberOfComponents()!=2)
10377     throw INTERP_KERNEL::Exception("DataArrayInt::findRangeIdForEachTuple : input DataArrayInt instance should have 2 components !");
10378   checkAllocated();
10379   if(getNumberOfComponents()!=1)
10380     throw INTERP_KERNEL::Exception("DataArrayInt::findRangeIdForEachTuple : this should have only one component !");
10381   int nbTuples=getNumberOfTuples();
10382   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbTuples,1);
10383   int nbOfRanges=ranges->getNumberOfTuples();
10384   const int *rangesPtr=ranges->getConstPointer();
10385   int *retPtr=ret->getPointer();
10386   const int *inPtr=getConstPointer();
10387   for(int i=0;i<nbTuples;i++,retPtr++)
10388     {
10389       int val=inPtr[i];
10390       bool found=false;
10391       for(int j=0;j<nbOfRanges && !found;j++)
10392         if(val>=rangesPtr[2*j] && val<rangesPtr[2*j+1])
10393           { *retPtr=j; found=true; }
10394       if(found)
10395         continue;
10396       else
10397         {
10398           std::ostringstream oss; oss << "DataArrayInt::findRangeIdForEachTuple : tuple #" << i << " not found by any ranges !";
10399           throw INTERP_KERNEL::Exception(oss.str().c_str());
10400         }
10401     }
10402   return ret.retn();
10403 }
10404
10405 /*!
10406  * 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.
10407  * 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
10408  * in tuple **i** of returned DataArrayInt.
10409  * If ranges overlapped (in theory it should not) this method do not detect it and always returns the sub position of the first range.
10410  *
10411  * 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)]
10412  * The return DataArrayInt will contain : **[1,2,4,0,2,2]**
10413  * This method is often called in pair with DataArrayInt::findRangeIdForEachTuple method.
10414  * 
10415  * \param [in] ranges typically come from output of MEDCouplingUMesh::ComputeRangesFromTypeDistribution. Each range is specified like this : 1st component is
10416  *             for lower value included and 2nd component is the upper value of corresponding range **excluded**.
10417  * \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
10418  *        is thrown if no ranges in \a ranges contains value in \a this.
10419  * \sa DataArrayInt::findRangeIdForEachTuple
10420  */
10421 DataArrayInt *DataArrayInt::findIdInRangeForEachTuple(const DataArrayInt *ranges) const
10422 {
10423   if(!ranges)
10424     throw INTERP_KERNEL::Exception("DataArrayInt::findIdInRangeForEachTuple : null input pointer !");
10425   if(ranges->getNumberOfComponents()!=2)
10426     throw INTERP_KERNEL::Exception("DataArrayInt::findIdInRangeForEachTuple : input DataArrayInt instance should have 2 components !");
10427   checkAllocated();
10428   if(getNumberOfComponents()!=1)
10429     throw INTERP_KERNEL::Exception("DataArrayInt::findIdInRangeForEachTuple : this should have only one component !");
10430   int nbTuples=getNumberOfTuples();
10431   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbTuples,1);
10432   int nbOfRanges=ranges->getNumberOfTuples();
10433   const int *rangesPtr=ranges->getConstPointer();
10434   int *retPtr=ret->getPointer();
10435   const int *inPtr=getConstPointer();
10436   for(int i=0;i<nbTuples;i++,retPtr++)
10437     {
10438       int val=inPtr[i];
10439       bool found=false;
10440       for(int j=0;j<nbOfRanges && !found;j++)
10441         if(val>=rangesPtr[2*j] && val<rangesPtr[2*j+1])
10442           { *retPtr=val-rangesPtr[2*j]; found=true; }
10443       if(found)
10444         continue;
10445       else
10446         {
10447           std::ostringstream oss; oss << "DataArrayInt::findIdInRangeForEachTuple : tuple #" << i << " not found by any ranges !";
10448           throw INTERP_KERNEL::Exception(oss.str().c_str());
10449         }
10450     }
10451   return ret.retn();
10452 }
10453
10454 /*!
10455  * \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).
10456  * 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).
10457  * 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 !
10458  * If this method has correctly worked, \a this will be able to be considered as a linked list.
10459  * This method does nothing if number of tuples is lower of equal to 1.
10460  *
10461  * This method is useful for users having an unstructured mesh having only SEG2 to rearrange internaly the connectibity without any coordinates consideration.
10462  *
10463  * \sa MEDCouplingUMesh::orderConsecutiveCells1D
10464  */
10465 void DataArrayInt::sortEachPairToMakeALinkedList()
10466 {
10467   checkAllocated();
10468   if(getNumberOfComponents()!=2)
10469     throw INTERP_KERNEL::Exception("DataArrayInt::sortEachPairToMakeALinkedList : Only works on DataArrayInt instance with nb of components equal to 2 !");
10470   int nbOfTuples(getNumberOfTuples());
10471   if(nbOfTuples<=1)
10472     return ;
10473   int *conn(getPointer());
10474   for(int i=1;i<nbOfTuples;i++,conn+=2)
10475     {
10476       if(i>1)
10477         {
10478           if(conn[2]==conn[3])
10479             {
10480               std::ostringstream oss; oss << "DataArrayInt::sortEachPairToMakeALinkedList : In the tuple #" << i << " presence of a pair filled with same ids !";
10481               throw INTERP_KERNEL::Exception(oss.str().c_str());
10482             }
10483           if(conn[2]!=conn[1] && conn[3]==conn[1] && conn[2]!=conn[0])
10484             std::swap(conn[2],conn[3]);
10485           //not(conn[2]==conn[1] && conn[3]!=conn[1] && conn[3]!=conn[0])
10486           if(conn[2]!=conn[1] || conn[3]==conn[1] || conn[3]==conn[0])
10487             {
10488               std::ostringstream oss; oss << "DataArrayInt::sortEachPairToMakeALinkedList : In the tuple #" << i << " something is invalid !";
10489               throw INTERP_KERNEL::Exception(oss.str().c_str());
10490             }
10491         }
10492       else
10493         {
10494           if(conn[0]==conn[1] || conn[2]==conn[3])
10495             throw INTERP_KERNEL::Exception("DataArrayInt::sortEachPairToMakeALinkedList : In the 2 first tuples presence of a pair filled with same ids !");
10496           int tmp[4];
10497           std::set<int> s;
10498           s.insert(conn,conn+4);
10499           if(s.size()!=3)
10500             throw INTERP_KERNEL::Exception("DataArrayInt::sortEachPairToMakeALinkedList : This can't be considered as a linked list regarding 2 first tuples !");
10501           if(std::count(conn,conn+4,conn[0])==2)
10502             {
10503               tmp[0]=conn[1];
10504               tmp[1]=conn[0];
10505               tmp[2]=conn[0];
10506               if(conn[2]==conn[0])
10507                 { tmp[3]=conn[3]; }
10508               else
10509                 { tmp[3]=conn[2];}
10510               std::copy(tmp,tmp+4,conn);
10511             }
10512         }
10513     }
10514 }
10515
10516 /*!
10517  * 
10518  * \param [in] nbTimes specifies the nb of times each tuples in \a this will be duplicated contiguouly in returned DataArrayInt instance.
10519  *             \a nbTimes  should be at least equal to 1.
10520  * \return a newly allocated DataArrayInt having one component and number of tuples equal to \a nbTimes * \c this->getNumberOfTuples.
10521  * \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.
10522  */
10523 DataArrayInt *DataArrayInt::duplicateEachTupleNTimes(int nbTimes) const
10524 {
10525   checkAllocated();
10526   if(getNumberOfComponents()!=1)
10527     throw INTERP_KERNEL::Exception("DataArrayInt::duplicateEachTupleNTimes : this should have only one component !");
10528   if(nbTimes<1)
10529     throw INTERP_KERNEL::Exception("DataArrayInt::duplicateEachTupleNTimes : nb times should be >= 1 !");
10530   int nbTuples=getNumberOfTuples();
10531   const int *inPtr=getConstPointer();
10532   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbTimes*nbTuples,1);
10533   int *retPtr=ret->getPointer();
10534   for(int i=0;i<nbTuples;i++,inPtr++)
10535     {
10536       int val=*inPtr;
10537       for(int j=0;j<nbTimes;j++,retPtr++)
10538         *retPtr=val;
10539     }
10540   ret->copyStringInfoFrom(*this);
10541   return ret.retn();
10542 }
10543
10544 /*!
10545  * This method returns all different values found in \a this. This method throws if \a this has not been allocated.
10546  * But the number of components can be different from one.
10547  * \return a newly allocated array (that should be dealt by the caller) containing different values in \a this.
10548  */
10549 DataArrayInt *DataArrayInt::getDifferentValues() const
10550 {
10551   checkAllocated();
10552   std::set<int> ret;
10553   ret.insert(begin(),end());
10554   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret2=DataArrayInt::New(); ret2->alloc((int)ret.size(),1);
10555   std::copy(ret.begin(),ret.end(),ret2->getPointer());
10556   return ret2.retn();
10557 }
10558
10559 /*!
10560  * This method is a refinement of DataArrayInt::getDifferentValues because it returns not only different values in \a this but also, for each of
10561  * them it tells which tuple id have this id.
10562  * This method works only on arrays with one component (if it is not the case call DataArrayInt::rearrange(1) ).
10563  * This method returns two arrays having same size.
10564  * 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.
10565  * 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]]
10566  */
10567 std::vector<DataArrayInt *> DataArrayInt::partitionByDifferentValues(std::vector<int>& differentIds) const
10568 {
10569   checkAllocated();
10570   if(getNumberOfComponents()!=1)
10571     throw INTERP_KERNEL::Exception("DataArrayInt::partitionByDifferentValues : this should have only one component !");
10572   int id=0;
10573   std::map<int,int> m,m2,m3;
10574   for(const int *w=begin();w!=end();w++)
10575     m[*w]++;
10576   differentIds.resize(m.size());
10577   std::vector<DataArrayInt *> ret(m.size());
10578   std::vector<int *> retPtr(m.size());
10579   for(std::map<int,int>::const_iterator it=m.begin();it!=m.end();it++,id++)
10580     {
10581       m2[(*it).first]=id;
10582       ret[id]=DataArrayInt::New();
10583       ret[id]->alloc((*it).second,1);
10584       retPtr[id]=ret[id]->getPointer();
10585       differentIds[id]=(*it).first;
10586     }
10587   id=0;
10588   for(const int *w=begin();w!=end();w++,id++)
10589     {
10590       retPtr[m2[*w]][m3[*w]++]=id;
10591     }
10592   return ret;
10593 }
10594
10595 /*!
10596  * This method split ids in [0, \c this->getNumberOfTuples() ) using \a this array as a field of weight (>=0 each).
10597  * The aim of this method is to return a set of \a nbOfSlices chunk of contiguous ids as balanced as possible.
10598  *
10599  * \param [in] nbOfSlices - number of slices expected.
10600  * \return - a vector having a size equal to \a nbOfSlices giving the start (included) and the stop (excluded) of each chunks.
10601  * 
10602  * \sa DataArray::GetSlice
10603  * \throw If \a this is not allocated or not with exactly one component.
10604  * \throw If an element in \a this if < 0.
10605  */
10606 std::vector< std::pair<int,int> > DataArrayInt::splitInBalancedSlices(int nbOfSlices) const
10607 {
10608   if(!isAllocated() || getNumberOfComponents()!=1)
10609     throw INTERP_KERNEL::Exception("DataArrayInt::splitInBalancedSlices : this array should have number of components equal to one and must be allocated !");
10610   if(nbOfSlices<=0)
10611     throw INTERP_KERNEL::Exception("DataArrayInt::splitInBalancedSlices : number of slices must be >= 1 !");
10612   int sum(accumulate(0)),nbOfTuples(getNumberOfTuples());
10613   int sumPerSlc(sum/nbOfSlices),pos(0);
10614   const int *w(begin());
10615   std::vector< std::pair<int,int> > ret(nbOfSlices);
10616   for(int i=0;i<nbOfSlices;i++)
10617     {
10618       std::pair<int,int> p(pos,-1);
10619       int locSum(0);
10620       while(locSum<sumPerSlc && pos<nbOfTuples) { pos++; locSum+=*w++; }
10621       if(i!=nbOfSlices-1)
10622         p.second=pos;
10623       else
10624         p.second=nbOfTuples;
10625       ret[i]=p;
10626     }
10627   return ret;
10628 }
10629
10630 /*!
10631  * Returns a new DataArrayInt that is a sum of two given arrays. There are 3
10632  * valid cases.
10633  * 1.  The arrays have same number of tuples and components. Then each value of
10634  *   the result array (_a_) is a sum of the corresponding values of \a a1 and \a a2,
10635  *   i.e.: _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ i, j ].
10636  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
10637  *   component. Then
10638  *   _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ i, 0 ].
10639  * 3.  The arrays have same number of components and one array, say _a2_, has one
10640  *   tuple. Then
10641  *   _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ 0, j ].
10642  *
10643  * Info on components is copied either from the first array (in the first case) or from
10644  * the array with maximal number of elements (getNbOfElems()).
10645  *  \param [in] a1 - an array to sum up.
10646  *  \param [in] a2 - another array to sum up.
10647  *  \return DataArrayInt * - the new instance of DataArrayInt.
10648  *          The caller is to delete this result array using decrRef() as it is no more
10649  *          needed.
10650  *  \throw If either \a a1 or \a a2 is NULL.
10651  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
10652  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
10653  *         none of them has number of tuples or components equal to 1.
10654  */
10655 DataArrayInt *DataArrayInt::Add(const DataArrayInt *a1, const DataArrayInt *a2)
10656 {
10657   if(!a1 || !a2)
10658     throw INTERP_KERNEL::Exception("DataArrayInt::Add : input DataArrayInt instance is NULL !");
10659   int nbOfTuple=a1->getNumberOfTuples();
10660   int nbOfTuple2=a2->getNumberOfTuples();
10661   int nbOfComp=a1->getNumberOfComponents();
10662   int nbOfComp2=a2->getNumberOfComponents();
10663   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=0;
10664   if(nbOfTuple==nbOfTuple2)
10665     {
10666       if(nbOfComp==nbOfComp2)
10667         {
10668           ret=DataArrayInt::New();
10669           ret->alloc(nbOfTuple,nbOfComp);
10670           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::plus<int>());
10671           ret->copyStringInfoFrom(*a1);
10672         }
10673       else
10674         {
10675           int nbOfCompMin,nbOfCompMax;
10676           const DataArrayInt *aMin, *aMax;
10677           if(nbOfComp>nbOfComp2)
10678             {
10679               nbOfCompMin=nbOfComp2; nbOfCompMax=nbOfComp;
10680               aMin=a2; aMax=a1;
10681             }
10682           else
10683             {
10684               nbOfCompMin=nbOfComp; nbOfCompMax=nbOfComp2;
10685               aMin=a1; aMax=a2;
10686             }
10687           if(nbOfCompMin==1)
10688             {
10689               ret=DataArrayInt::New();
10690               ret->alloc(nbOfTuple,nbOfCompMax);
10691               const int *aMinPtr=aMin->getConstPointer();
10692               const int *aMaxPtr=aMax->getConstPointer();
10693               int *res=ret->getPointer();
10694               for(int i=0;i<nbOfTuple;i++)
10695                 res=std::transform(aMaxPtr+i*nbOfCompMax,aMaxPtr+(i+1)*nbOfCompMax,res,std::bind2nd(std::plus<int>(),aMinPtr[i]));
10696               ret->copyStringInfoFrom(*aMax);
10697             }
10698           else
10699             throw INTERP_KERNEL::Exception("Nb of components mismatch for array Add !");
10700         }
10701     }
10702   else if((nbOfTuple==1 && nbOfTuple2>1) || (nbOfTuple>1 && nbOfTuple2==1))
10703     {
10704       if(nbOfComp==nbOfComp2)
10705         {
10706           int nbOfTupleMax=std::max(nbOfTuple,nbOfTuple2);
10707           const DataArrayInt *aMin=nbOfTuple>nbOfTuple2?a2:a1;
10708           const DataArrayInt *aMax=nbOfTuple>nbOfTuple2?a1:a2;
10709           const int *aMinPtr=aMin->getConstPointer(),*aMaxPtr=aMax->getConstPointer();
10710           ret=DataArrayInt::New();
10711           ret->alloc(nbOfTupleMax,nbOfComp);
10712           int *res=ret->getPointer();
10713           for(int i=0;i<nbOfTupleMax;i++)
10714             res=std::transform(aMaxPtr+i*nbOfComp,aMaxPtr+(i+1)*nbOfComp,aMinPtr,res,std::plus<int>());
10715           ret->copyStringInfoFrom(*aMax);
10716         }
10717       else
10718         throw INTERP_KERNEL::Exception("Nb of components mismatch for array Add !");
10719     }
10720   else
10721     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Add !");
10722   return ret.retn();
10723 }
10724
10725 /*!
10726  * Adds values of another DataArrayInt to values of \a this one. There are 3
10727  * valid cases.
10728  * 1.  The arrays have same number of tuples and components. Then each value of
10729  *   \a other array is added to the corresponding value of \a this array, i.e.:
10730  *   _a_ [ i, j ] += _other_ [ i, j ].
10731  * 2.  The arrays have same number of tuples and \a other array has one component. Then
10732  *   _a_ [ i, j ] += _other_ [ i, 0 ].
10733  * 3.  The arrays have same number of components and \a other array has one tuple. Then
10734  *   _a_ [ i, j ] += _a2_ [ 0, j ].
10735  *
10736  *  \param [in] other - an array to add to \a this one.
10737  *  \throw If \a other is NULL.
10738  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
10739  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
10740  *         \a other has number of both tuples and components not equal to 1.
10741  */
10742 void DataArrayInt::addEqual(const DataArrayInt *other)
10743 {
10744   if(!other)
10745     throw INTERP_KERNEL::Exception("DataArrayInt::addEqual : input DataArrayInt instance is NULL !");
10746   const char *msg="Nb of tuples mismatch for DataArrayInt::addEqual  !";
10747   checkAllocated(); other->checkAllocated();
10748   int nbOfTuple=getNumberOfTuples();
10749   int nbOfTuple2=other->getNumberOfTuples();
10750   int nbOfComp=getNumberOfComponents();
10751   int nbOfComp2=other->getNumberOfComponents();
10752   if(nbOfTuple==nbOfTuple2)
10753     {
10754       if(nbOfComp==nbOfComp2)
10755         {
10756           std::transform(begin(),end(),other->begin(),getPointer(),std::plus<int>());
10757         }
10758       else if(nbOfComp2==1)
10759         {
10760           int *ptr=getPointer();
10761           const int *ptrc=other->getConstPointer();
10762           for(int i=0;i<nbOfTuple;i++)
10763             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::plus<int>(),*ptrc++));
10764         }
10765       else
10766         throw INTERP_KERNEL::Exception(msg);
10767     }
10768   else if(nbOfTuple2==1)
10769     {
10770       if(nbOfComp2==nbOfComp)
10771         {
10772           int *ptr=getPointer();
10773           const int *ptrc=other->getConstPointer();
10774           for(int i=0;i<nbOfTuple;i++)
10775             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::plus<int>());
10776         }
10777       else
10778         throw INTERP_KERNEL::Exception(msg);
10779     }
10780   else
10781     throw INTERP_KERNEL::Exception(msg);
10782   declareAsNew();
10783 }
10784
10785 /*!
10786  * Returns a new DataArrayInt that is a subtraction of two given arrays. There are 3
10787  * valid cases.
10788  * 1.  The arrays have same number of tuples and components. Then each value of
10789  *   the result array (_a_) is a subtraction of the corresponding values of \a a1 and
10790  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ i, j ].
10791  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
10792  *   component. Then
10793  *   _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ i, 0 ].
10794  * 3.  The arrays have same number of components and one array, say _a2_, has one
10795  *   tuple. Then
10796  *   _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ 0, j ].
10797  *
10798  * Info on components is copied either from the first array (in the first case) or from
10799  * the array with maximal number of elements (getNbOfElems()).
10800  *  \param [in] a1 - an array to subtract from.
10801  *  \param [in] a2 - an array to subtract.
10802  *  \return DataArrayInt * - the new instance of DataArrayInt.
10803  *          The caller is to delete this result array using decrRef() as it is no more
10804  *          needed.
10805  *  \throw If either \a a1 or \a a2 is NULL.
10806  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
10807  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
10808  *         none of them has number of tuples or components equal to 1.
10809  */
10810 DataArrayInt *DataArrayInt::Substract(const DataArrayInt *a1, const DataArrayInt *a2)
10811 {
10812   if(!a1 || !a2)
10813     throw INTERP_KERNEL::Exception("DataArrayInt::Substract : input DataArrayInt instance is NULL !");
10814   int nbOfTuple1=a1->getNumberOfTuples();
10815   int nbOfTuple2=a2->getNumberOfTuples();
10816   int nbOfComp1=a1->getNumberOfComponents();
10817   int nbOfComp2=a2->getNumberOfComponents();
10818   if(nbOfTuple2==nbOfTuple1)
10819     {
10820       if(nbOfComp1==nbOfComp2)
10821         {
10822           MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
10823           ret->alloc(nbOfTuple2,nbOfComp1);
10824           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::minus<int>());
10825           ret->copyStringInfoFrom(*a1);
10826           return ret.retn();
10827         }
10828       else if(nbOfComp2==1)
10829         {
10830           MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
10831           ret->alloc(nbOfTuple1,nbOfComp1);
10832           const int *a2Ptr=a2->getConstPointer();
10833           const int *a1Ptr=a1->getConstPointer();
10834           int *res=ret->getPointer();
10835           for(int i=0;i<nbOfTuple1;i++)
10836             res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::minus<int>(),a2Ptr[i]));
10837           ret->copyStringInfoFrom(*a1);
10838           return ret.retn();
10839         }
10840       else
10841         {
10842           a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Substract !");
10843           return 0;
10844         }
10845     }
10846   else if(nbOfTuple2==1)
10847     {
10848       a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Substract !");
10849       MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
10850       ret->alloc(nbOfTuple1,nbOfComp1);
10851       const int *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
10852       int *pt=ret->getPointer();
10853       for(int i=0;i<nbOfTuple1;i++)
10854         pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::minus<int>());
10855       ret->copyStringInfoFrom(*a1);
10856       return ret.retn();
10857     }
10858   else
10859     {
10860       a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Substract !");//will always throw an exception
10861       return 0;
10862     }
10863 }
10864
10865 /*!
10866  * Subtract values of another DataArrayInt from values of \a this one. There are 3
10867  * valid cases.
10868  * 1.  The arrays have same number of tuples and components. Then each value of
10869  *   \a other array is subtracted from the corresponding value of \a this array, i.e.:
10870  *   _a_ [ i, j ] -= _other_ [ i, j ].
10871  * 2.  The arrays have same number of tuples and \a other array has one component. Then
10872  *   _a_ [ i, j ] -= _other_ [ i, 0 ].
10873  * 3.  The arrays have same number of components and \a other array has one tuple. Then
10874  *   _a_ [ i, j ] -= _a2_ [ 0, j ].
10875  *
10876  *  \param [in] other - an array to subtract from \a this one.
10877  *  \throw If \a other is NULL.
10878  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
10879  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
10880  *         \a other has number of both tuples and components not equal to 1.
10881  */
10882 void DataArrayInt::substractEqual(const DataArrayInt *other)
10883 {
10884   if(!other)
10885     throw INTERP_KERNEL::Exception("DataArrayInt::substractEqual : input DataArrayInt instance is NULL !");
10886   const char *msg="Nb of tuples mismatch for DataArrayInt::substractEqual  !";
10887   checkAllocated(); other->checkAllocated();
10888   int nbOfTuple=getNumberOfTuples();
10889   int nbOfTuple2=other->getNumberOfTuples();
10890   int nbOfComp=getNumberOfComponents();
10891   int nbOfComp2=other->getNumberOfComponents();
10892   if(nbOfTuple==nbOfTuple2)
10893     {
10894       if(nbOfComp==nbOfComp2)
10895         {
10896           std::transform(begin(),end(),other->begin(),getPointer(),std::minus<int>());
10897         }
10898       else if(nbOfComp2==1)
10899         {
10900           int *ptr=getPointer();
10901           const int *ptrc=other->getConstPointer();
10902           for(int i=0;i<nbOfTuple;i++)
10903             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::minus<int>(),*ptrc++));
10904         }
10905       else
10906         throw INTERP_KERNEL::Exception(msg);
10907     }
10908   else if(nbOfTuple2==1)
10909     {
10910       int *ptr=getPointer();
10911       const int *ptrc=other->getConstPointer();
10912       for(int i=0;i<nbOfTuple;i++)
10913         std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::minus<int>());
10914     }
10915   else
10916     throw INTERP_KERNEL::Exception(msg);
10917   declareAsNew();
10918 }
10919
10920 /*!
10921  * Returns a new DataArrayInt that is a product of two given arrays. There are 3
10922  * valid cases.
10923  * 1.  The arrays have same number of tuples and components. Then each value of
10924  *   the result array (_a_) is a product of the corresponding values of \a a1 and
10925  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ i, j ].
10926  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
10927  *   component. Then
10928  *   _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ i, 0 ].
10929  * 3.  The arrays have same number of components and one array, say _a2_, has one
10930  *   tuple. Then
10931  *   _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ 0, j ].
10932  *
10933  * Info on components is copied either from the first array (in the first case) or from
10934  * the array with maximal number of elements (getNbOfElems()).
10935  *  \param [in] a1 - a factor array.
10936  *  \param [in] a2 - another factor array.
10937  *  \return DataArrayInt * - the new instance of DataArrayInt.
10938  *          The caller is to delete this result array using decrRef() as it is no more
10939  *          needed.
10940  *  \throw If either \a a1 or \a a2 is NULL.
10941  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
10942  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
10943  *         none of them has number of tuples or components equal to 1.
10944  */
10945 DataArrayInt *DataArrayInt::Multiply(const DataArrayInt *a1, const DataArrayInt *a2)
10946 {
10947   if(!a1 || !a2)
10948     throw INTERP_KERNEL::Exception("DataArrayInt::Multiply : input DataArrayInt instance is NULL !");
10949   int nbOfTuple=a1->getNumberOfTuples();
10950   int nbOfTuple2=a2->getNumberOfTuples();
10951   int nbOfComp=a1->getNumberOfComponents();
10952   int nbOfComp2=a2->getNumberOfComponents();
10953   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=0;
10954   if(nbOfTuple==nbOfTuple2)
10955     {
10956       if(nbOfComp==nbOfComp2)
10957         {
10958           ret=DataArrayInt::New();
10959           ret->alloc(nbOfTuple,nbOfComp);
10960           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::multiplies<int>());
10961           ret->copyStringInfoFrom(*a1);
10962         }
10963       else
10964         {
10965           int nbOfCompMin,nbOfCompMax;
10966           const DataArrayInt *aMin, *aMax;
10967           if(nbOfComp>nbOfComp2)
10968             {
10969               nbOfCompMin=nbOfComp2; nbOfCompMax=nbOfComp;
10970               aMin=a2; aMax=a1;
10971             }
10972           else
10973             {
10974               nbOfCompMin=nbOfComp; nbOfCompMax=nbOfComp2;
10975               aMin=a1; aMax=a2;
10976             }
10977           if(nbOfCompMin==1)
10978             {
10979               ret=DataArrayInt::New();
10980               ret->alloc(nbOfTuple,nbOfCompMax);
10981               const int *aMinPtr=aMin->getConstPointer();
10982               const int *aMaxPtr=aMax->getConstPointer();
10983               int *res=ret->getPointer();
10984               for(int i=0;i<nbOfTuple;i++)
10985                 res=std::transform(aMaxPtr+i*nbOfCompMax,aMaxPtr+(i+1)*nbOfCompMax,res,std::bind2nd(std::multiplies<int>(),aMinPtr[i]));
10986               ret->copyStringInfoFrom(*aMax);
10987             }
10988           else
10989             throw INTERP_KERNEL::Exception("Nb of components mismatch for array Multiply !");
10990         }
10991     }
10992   else if((nbOfTuple==1 && nbOfTuple2>1) || (nbOfTuple>1 && nbOfTuple2==1))
10993     {
10994       if(nbOfComp==nbOfComp2)
10995         {
10996           int nbOfTupleMax=std::max(nbOfTuple,nbOfTuple2);
10997           const DataArrayInt *aMin=nbOfTuple>nbOfTuple2?a2:a1;
10998           const DataArrayInt *aMax=nbOfTuple>nbOfTuple2?a1:a2;
10999           const int *aMinPtr=aMin->getConstPointer(),*aMaxPtr=aMax->getConstPointer();
11000           ret=DataArrayInt::New();
11001           ret->alloc(nbOfTupleMax,nbOfComp);
11002           int *res=ret->getPointer();
11003           for(int i=0;i<nbOfTupleMax;i++)
11004             res=std::transform(aMaxPtr+i*nbOfComp,aMaxPtr+(i+1)*nbOfComp,aMinPtr,res,std::multiplies<int>());
11005           ret->copyStringInfoFrom(*aMax);
11006         }
11007       else
11008         throw INTERP_KERNEL::Exception("Nb of components mismatch for array Multiply !");
11009     }
11010   else
11011     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Multiply !");
11012   return ret.retn();
11013 }
11014
11015
11016 /*!
11017  * Multiply values of another DataArrayInt to values of \a this one. There are 3
11018  * valid cases.
11019  * 1.  The arrays have same number of tuples and components. Then each value of
11020  *   \a other array is multiplied to the corresponding value of \a this array, i.e.:
11021  *   _a_ [ i, j ] *= _other_ [ i, j ].
11022  * 2.  The arrays have same number of tuples and \a other array has one component. Then
11023  *   _a_ [ i, j ] *= _other_ [ i, 0 ].
11024  * 3.  The arrays have same number of components and \a other array has one tuple. Then
11025  *   _a_ [ i, j ] *= _a2_ [ 0, j ].
11026  *
11027  *  \param [in] other - an array to multiply to \a this one.
11028  *  \throw If \a other is NULL.
11029  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
11030  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
11031  *         \a other has number of both tuples and components not equal to 1.
11032  */
11033 void DataArrayInt::multiplyEqual(const DataArrayInt *other)
11034 {
11035   if(!other)
11036     throw INTERP_KERNEL::Exception("DataArrayInt::multiplyEqual : input DataArrayInt instance is NULL !");
11037   const char *msg="Nb of tuples mismatch for DataArrayInt::multiplyEqual !";
11038   checkAllocated(); other->checkAllocated();
11039   int nbOfTuple=getNumberOfTuples();
11040   int nbOfTuple2=other->getNumberOfTuples();
11041   int nbOfComp=getNumberOfComponents();
11042   int nbOfComp2=other->getNumberOfComponents();
11043   if(nbOfTuple==nbOfTuple2)
11044     {
11045       if(nbOfComp==nbOfComp2)
11046         {
11047           std::transform(begin(),end(),other->begin(),getPointer(),std::multiplies<int>());
11048         }
11049       else if(nbOfComp2==1)
11050         {
11051           int *ptr=getPointer();
11052           const int *ptrc=other->getConstPointer();
11053           for(int i=0;i<nbOfTuple;i++)
11054             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::multiplies<int>(),*ptrc++));    
11055         }
11056       else
11057         throw INTERP_KERNEL::Exception(msg);
11058     }
11059   else if(nbOfTuple2==1)
11060     {
11061       if(nbOfComp2==nbOfComp)
11062         {
11063           int *ptr=getPointer();
11064           const int *ptrc=other->getConstPointer();
11065           for(int i=0;i<nbOfTuple;i++)
11066             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::multiplies<int>());
11067         }
11068       else
11069         throw INTERP_KERNEL::Exception(msg);
11070     }
11071   else
11072     throw INTERP_KERNEL::Exception(msg);
11073   declareAsNew();
11074 }
11075
11076
11077 /*!
11078  * Returns a new DataArrayInt that is a division of two given arrays. There are 3
11079  * valid cases.
11080  * 1.  The arrays have same number of tuples and components. Then each value of
11081  *   the result array (_a_) is a division of the corresponding values of \a a1 and
11082  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ i, j ].
11083  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
11084  *   component. Then
11085  *   _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ i, 0 ].
11086  * 3.  The arrays have same number of components and one array, say _a2_, has one
11087  *   tuple. Then
11088  *   _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ 0, j ].
11089  *
11090  * Info on components is copied either from the first array (in the first case) or from
11091  * the array with maximal number of elements (getNbOfElems()).
11092  *  \warning No check of division by zero is performed!
11093  *  \param [in] a1 - a numerator array.
11094  *  \param [in] a2 - a denominator array.
11095  *  \return DataArrayInt * - the new instance of DataArrayInt.
11096  *          The caller is to delete this result array using decrRef() as it is no more
11097  *          needed.
11098  *  \throw If either \a a1 or \a a2 is NULL.
11099  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
11100  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
11101  *         none of them has number of tuples or components equal to 1.
11102  */
11103 DataArrayInt *DataArrayInt::Divide(const DataArrayInt *a1, const DataArrayInt *a2)
11104 {
11105   if(!a1 || !a2)
11106     throw INTERP_KERNEL::Exception("DataArrayInt::Divide : input DataArrayInt instance is NULL !");
11107   int nbOfTuple1=a1->getNumberOfTuples();
11108   int nbOfTuple2=a2->getNumberOfTuples();
11109   int nbOfComp1=a1->getNumberOfComponents();
11110   int nbOfComp2=a2->getNumberOfComponents();
11111   if(nbOfTuple2==nbOfTuple1)
11112     {
11113       if(nbOfComp1==nbOfComp2)
11114         {
11115           MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
11116           ret->alloc(nbOfTuple2,nbOfComp1);
11117           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::divides<int>());
11118           ret->copyStringInfoFrom(*a1);
11119           return ret.retn();
11120         }
11121       else if(nbOfComp2==1)
11122         {
11123           MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
11124           ret->alloc(nbOfTuple1,nbOfComp1);
11125           const int *a2Ptr=a2->getConstPointer();
11126           const int *a1Ptr=a1->getConstPointer();
11127           int *res=ret->getPointer();
11128           for(int i=0;i<nbOfTuple1;i++)
11129             res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::divides<int>(),a2Ptr[i]));
11130           ret->copyStringInfoFrom(*a1);
11131           return ret.retn();
11132         }
11133       else
11134         {
11135           a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Divide !");
11136           return 0;
11137         }
11138     }
11139   else if(nbOfTuple2==1)
11140     {
11141       a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Divide !");
11142       MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
11143       ret->alloc(nbOfTuple1,nbOfComp1);
11144       const int *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
11145       int *pt=ret->getPointer();
11146       for(int i=0;i<nbOfTuple1;i++)
11147         pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::divides<int>());
11148       ret->copyStringInfoFrom(*a1);
11149       return ret.retn();
11150     }
11151   else
11152     {
11153       a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Divide !");//will always throw an exception
11154       return 0;
11155     }
11156 }
11157
11158 /*!
11159  * Divide values of \a this array by values of another DataArrayInt. There are 3
11160  * valid cases.
11161  * 1.  The arrays have same number of tuples and components. Then each value of
11162  *    \a this array is divided by the corresponding value of \a other one, i.e.:
11163  *   _a_ [ i, j ] /= _other_ [ i, j ].
11164  * 2.  The arrays have same number of tuples and \a other array has one component. Then
11165  *   _a_ [ i, j ] /= _other_ [ i, 0 ].
11166  * 3.  The arrays have same number of components and \a other array has one tuple. Then
11167  *   _a_ [ i, j ] /= _a2_ [ 0, j ].
11168  *
11169  *  \warning No check of division by zero is performed!
11170  *  \param [in] other - an array to divide \a this one by.
11171  *  \throw If \a other is NULL.
11172  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
11173  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
11174  *         \a other has number of both tuples and components not equal to 1.
11175  */
11176 void DataArrayInt::divideEqual(const DataArrayInt *other)
11177 {
11178   if(!other)
11179     throw INTERP_KERNEL::Exception("DataArrayInt::divideEqual : input DataArrayInt instance is NULL !");
11180   const char *msg="Nb of tuples mismatch for DataArrayInt::divideEqual !";
11181   checkAllocated(); other->checkAllocated();
11182   int nbOfTuple=getNumberOfTuples();
11183   int nbOfTuple2=other->getNumberOfTuples();
11184   int nbOfComp=getNumberOfComponents();
11185   int nbOfComp2=other->getNumberOfComponents();
11186   if(nbOfTuple==nbOfTuple2)
11187     {
11188       if(nbOfComp==nbOfComp2)
11189         {
11190           std::transform(begin(),end(),other->begin(),getPointer(),std::divides<int>());
11191         }
11192       else if(nbOfComp2==1)
11193         {
11194           int *ptr=getPointer();
11195           const int *ptrc=other->getConstPointer();
11196           for(int i=0;i<nbOfTuple;i++)
11197             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::divides<int>(),*ptrc++));
11198         }
11199       else
11200         throw INTERP_KERNEL::Exception(msg);
11201     }
11202   else if(nbOfTuple2==1)
11203     {
11204       if(nbOfComp2==nbOfComp)
11205         {
11206           int *ptr=getPointer();
11207           const int *ptrc=other->getConstPointer();
11208           for(int i=0;i<nbOfTuple;i++)
11209             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::divides<int>());
11210         }
11211       else
11212         throw INTERP_KERNEL::Exception(msg);
11213     }
11214   else
11215     throw INTERP_KERNEL::Exception(msg);
11216   declareAsNew();
11217 }
11218
11219
11220 /*!
11221  * Returns a new DataArrayInt that is a modulus of two given arrays. There are 3
11222  * valid cases.
11223  * 1.  The arrays have same number of tuples and components. Then each value of
11224  *   the result array (_a_) is a division of the corresponding values of \a a1 and
11225  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] % _a2_ [ i, j ].
11226  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
11227  *   component. Then
11228  *   _a_ [ i, j ] = _a1_ [ i, j ] % _a2_ [ i, 0 ].
11229  * 3.  The arrays have same number of components and one array, say _a2_, has one
11230  *   tuple. Then
11231  *   _a_ [ i, j ] = _a1_ [ i, j ] % _a2_ [ 0, j ].
11232  *
11233  * Info on components is copied either from the first array (in the first case) or from
11234  * the array with maximal number of elements (getNbOfElems()).
11235  *  \warning No check of division by zero is performed!
11236  *  \param [in] a1 - a dividend array.
11237  *  \param [in] a2 - a divisor array.
11238  *  \return DataArrayInt * - the new instance of DataArrayInt.
11239  *          The caller is to delete this result array using decrRef() as it is no more
11240  *          needed.
11241  *  \throw If either \a a1 or \a a2 is NULL.
11242  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
11243  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
11244  *         none of them has number of tuples or components equal to 1.
11245  */
11246 DataArrayInt *DataArrayInt::Modulus(const DataArrayInt *a1, const DataArrayInt *a2)
11247 {
11248   if(!a1 || !a2)
11249     throw INTERP_KERNEL::Exception("DataArrayInt::Modulus : input DataArrayInt instance is NULL !");
11250   int nbOfTuple1=a1->getNumberOfTuples();
11251   int nbOfTuple2=a2->getNumberOfTuples();
11252   int nbOfComp1=a1->getNumberOfComponents();
11253   int nbOfComp2=a2->getNumberOfComponents();
11254   if(nbOfTuple2==nbOfTuple1)
11255     {
11256       if(nbOfComp1==nbOfComp2)
11257         {
11258           MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
11259           ret->alloc(nbOfTuple2,nbOfComp1);
11260           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::modulus<int>());
11261           ret->copyStringInfoFrom(*a1);
11262           return ret.retn();
11263         }
11264       else if(nbOfComp2==1)
11265         {
11266           MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
11267           ret->alloc(nbOfTuple1,nbOfComp1);
11268           const int *a2Ptr=a2->getConstPointer();
11269           const int *a1Ptr=a1->getConstPointer();
11270           int *res=ret->getPointer();
11271           for(int i=0;i<nbOfTuple1;i++)
11272             res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::modulus<int>(),a2Ptr[i]));
11273           ret->copyStringInfoFrom(*a1);
11274           return ret.retn();
11275         }
11276       else
11277         {
11278           a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Modulus !");
11279           return 0;
11280         }
11281     }
11282   else if(nbOfTuple2==1)
11283     {
11284       a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Modulus !");
11285       MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
11286       ret->alloc(nbOfTuple1,nbOfComp1);
11287       const int *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
11288       int *pt=ret->getPointer();
11289       for(int i=0;i<nbOfTuple1;i++)
11290         pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::modulus<int>());
11291       ret->copyStringInfoFrom(*a1);
11292       return ret.retn();
11293     }
11294   else
11295     {
11296       a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Modulus !");//will always throw an exception
11297       return 0;
11298     }
11299 }
11300
11301 /*!
11302  * Modify \a this array so that each value becomes a modulus of division of this value by
11303  * a value of another DataArrayInt. There are 3 valid cases.
11304  * 1.  The arrays have same number of tuples and components. Then each value of
11305  *    \a this array is divided by the corresponding value of \a other one, i.e.:
11306  *   _a_ [ i, j ] %= _other_ [ i, j ].
11307  * 2.  The arrays have same number of tuples and \a other array has one component. Then
11308  *   _a_ [ i, j ] %= _other_ [ i, 0 ].
11309  * 3.  The arrays have same number of components and \a other array has one tuple. Then
11310  *   _a_ [ i, j ] %= _a2_ [ 0, j ].
11311  *
11312  *  \warning No check of division by zero is performed!
11313  *  \param [in] other - a divisor array.
11314  *  \throw If \a other is NULL.
11315  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
11316  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
11317  *         \a other has number of both tuples and components not equal to 1.
11318  */
11319 void DataArrayInt::modulusEqual(const DataArrayInt *other)
11320 {
11321   if(!other)
11322     throw INTERP_KERNEL::Exception("DataArrayInt::modulusEqual : input DataArrayInt instance is NULL !");
11323   const char *msg="Nb of tuples mismatch for DataArrayInt::modulusEqual !";
11324   checkAllocated(); other->checkAllocated();
11325   int nbOfTuple=getNumberOfTuples();
11326   int nbOfTuple2=other->getNumberOfTuples();
11327   int nbOfComp=getNumberOfComponents();
11328   int nbOfComp2=other->getNumberOfComponents();
11329   if(nbOfTuple==nbOfTuple2)
11330     {
11331       if(nbOfComp==nbOfComp2)
11332         {
11333           std::transform(begin(),end(),other->begin(),getPointer(),std::modulus<int>());
11334         }
11335       else if(nbOfComp2==1)
11336         {
11337           if(nbOfComp2==nbOfComp)
11338             {
11339               int *ptr=getPointer();
11340               const int *ptrc=other->getConstPointer();
11341               for(int i=0;i<nbOfTuple;i++)
11342                 std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::modulus<int>(),*ptrc++));
11343             }
11344           else
11345             throw INTERP_KERNEL::Exception(msg);
11346         }
11347       else
11348         throw INTERP_KERNEL::Exception(msg);
11349     }
11350   else if(nbOfTuple2==1)
11351     {
11352       int *ptr=getPointer();
11353       const int *ptrc=other->getConstPointer();
11354       for(int i=0;i<nbOfTuple;i++)
11355         std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::modulus<int>());
11356     }
11357   else
11358     throw INTERP_KERNEL::Exception(msg);
11359   declareAsNew();
11360 }
11361
11362 /*!
11363  * Returns a new DataArrayInt that is the result of pow of two given arrays. There are 3
11364  * valid cases.
11365  *
11366  *  \param [in] a1 - an array to pow up.
11367  *  \param [in] a2 - another array to sum up.
11368  *  \return DataArrayInt * - the new instance of DataArrayInt.
11369  *          The caller is to delete this result array using decrRef() as it is no more
11370  *          needed.
11371  *  \throw If either \a a1 or \a a2 is NULL.
11372  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
11373  *  \throw If \a a1->getNumberOfComponents() != 1 or \a a2->getNumberOfComponents() != 1.
11374  *  \throw If there is a negative value in \a a2.
11375  */
11376 DataArrayInt *DataArrayInt::Pow(const DataArrayInt *a1, const DataArrayInt *a2)
11377 {
11378   if(!a1 || !a2)
11379     throw INTERP_KERNEL::Exception("DataArrayInt::Pow : at least one of input instances is null !");
11380   int nbOfTuple=a1->getNumberOfTuples();
11381   int nbOfTuple2=a2->getNumberOfTuples();
11382   int nbOfComp=a1->getNumberOfComponents();
11383   int nbOfComp2=a2->getNumberOfComponents();
11384   if(nbOfTuple!=nbOfTuple2)
11385     throw INTERP_KERNEL::Exception("DataArrayInt::Pow : number of tuples mismatches !");
11386   if(nbOfComp!=1 || nbOfComp2!=1)
11387     throw INTERP_KERNEL::Exception("DataArrayInt::Pow : number of components of both arrays must be equal to 1 !");
11388   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbOfTuple,1);
11389   const int *ptr1(a1->begin()),*ptr2(a2->begin());
11390   int *ptr=ret->getPointer();
11391   for(int i=0;i<nbOfTuple;i++,ptr1++,ptr2++,ptr++)
11392     {
11393       if(*ptr2>=0)
11394         {
11395           int tmp=1;
11396           for(int j=0;j<*ptr2;j++)
11397             tmp*=*ptr1;
11398           *ptr=tmp;
11399         }
11400       else
11401         {
11402           std::ostringstream oss; oss << "DataArrayInt::Pow : on tuple #" << i << " of a2 value is < 0 (" << *ptr2 << ") !";
11403           throw INTERP_KERNEL::Exception(oss.str().c_str());
11404         }
11405     }
11406   return ret.retn();
11407 }
11408
11409 /*!
11410  * Apply pow on values of another DataArrayInt to values of \a this one.
11411  *
11412  *  \param [in] other - an array to pow to \a this one.
11413  *  \throw If \a other is NULL.
11414  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples()
11415  *  \throw If \a this->getNumberOfComponents() != 1 or \a other->getNumberOfComponents() != 1
11416  *  \throw If there is a negative value in \a other.
11417  */
11418 void DataArrayInt::powEqual(const DataArrayInt *other)
11419 {
11420   if(!other)
11421     throw INTERP_KERNEL::Exception("DataArrayInt::powEqual : input instance is null !");
11422   int nbOfTuple=getNumberOfTuples();
11423   int nbOfTuple2=other->getNumberOfTuples();
11424   int nbOfComp=getNumberOfComponents();
11425   int nbOfComp2=other->getNumberOfComponents();
11426   if(nbOfTuple!=nbOfTuple2)
11427     throw INTERP_KERNEL::Exception("DataArrayInt::powEqual : number of tuples mismatches !");
11428   if(nbOfComp!=1 || nbOfComp2!=1)
11429     throw INTERP_KERNEL::Exception("DataArrayInt::powEqual : number of components of both arrays must be equal to 1 !");
11430   int *ptr=getPointer();
11431   const int *ptrc=other->begin();
11432   for(int i=0;i<nbOfTuple;i++,ptrc++,ptr++)
11433     {
11434       if(*ptrc>=0)
11435         {
11436           int tmp=1;
11437           for(int j=0;j<*ptrc;j++)
11438             tmp*=*ptr;
11439           *ptr=tmp;
11440         }
11441       else
11442         {
11443           std::ostringstream oss; oss << "DataArrayInt::powEqual : on tuple #" << i << " of other value is < 0 (" << *ptrc << ") !";
11444           throw INTERP_KERNEL::Exception(oss.str().c_str());
11445         }
11446     }
11447   declareAsNew();
11448 }
11449
11450 /*!
11451  * Returns a C array which is a renumbering map in "Old to New" mode for the input array.
11452  * This map, if applied to \a start array, would make it sorted. For example, if
11453  * \a start array contents are [9,10,0,6,4,11,3,7] then the contents of the result array is
11454  * [5,6,0,3,2,7,1,4].
11455  *  \param [in] start - pointer to the first element of the array for which the
11456  *         permutation map is computed.
11457  *  \param [in] end - pointer specifying the end of the array \a start, so that
11458  *         the last value of \a start is \a end[ -1 ].
11459  *  \return int * - the result permutation array that the caller is to delete as it is no
11460  *         more needed.
11461  *  \throw If there are equal values in the input array.
11462  */
11463 int *DataArrayInt::CheckAndPreparePermutation(const int *start, const int *end)
11464 {
11465   std::size_t sz=std::distance(start,end);
11466   int *ret=(int *)malloc(sz*sizeof(int));
11467   int *work=new int[sz];
11468   std::copy(start,end,work);
11469   std::sort(work,work+sz);
11470   if(std::unique(work,work+sz)!=work+sz)
11471     {
11472       delete [] work;
11473       free(ret);
11474       throw INTERP_KERNEL::Exception("Some elements are equals in the specified array !");
11475     }
11476   std::map<int,int> m;
11477   for(int *workPt=work;workPt!=work+sz;workPt++)
11478     m[*workPt]=(int)std::distance(work,workPt);
11479   int *iter2=ret;
11480   for(const int *iter=start;iter!=end;iter++,iter2++)
11481     *iter2=m[*iter];
11482   delete [] work;
11483   return ret;
11484 }
11485
11486 /*!
11487  * Returns a new DataArrayInt containing an arithmetic progression
11488  * that is equal to the sequence returned by Python \c range(\a begin,\a  end,\a  step )
11489  * function.
11490  *  \param [in] begin - the start value of the result sequence.
11491  *  \param [in] end - limiting value, so that every value of the result array is less than
11492  *              \a end.
11493  *  \param [in] step - specifies the increment or decrement.
11494  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
11495  *          array using decrRef() as it is no more needed.
11496  *  \throw If \a step == 0.
11497  *  \throw If \a end < \a begin && \a step > 0.
11498  *  \throw If \a end > \a begin && \a step < 0.
11499  */
11500 DataArrayInt *DataArrayInt::Range(int begin, int end, int step)
11501 {
11502   int nbOfTuples=GetNumberOfItemGivenBESRelative(begin,end,step,"DataArrayInt::Range");
11503   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
11504   ret->alloc(nbOfTuples,1);
11505   int *ptr=ret->getPointer();
11506   if(step>0)
11507     {
11508       for(int i=begin;i<end;i+=step,ptr++)
11509         *ptr=i;
11510     }
11511   else
11512     {
11513       for(int i=begin;i>end;i+=step,ptr++)
11514         *ptr=i;
11515     }
11516   return ret.retn();
11517 }
11518
11519 /*!
11520  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
11521  * Server side.
11522  */
11523 void DataArrayInt::getTinySerializationIntInformation(std::vector<int>& tinyInfo) const
11524 {
11525   tinyInfo.resize(2);
11526   if(isAllocated())
11527     {
11528       tinyInfo[0]=getNumberOfTuples();
11529       tinyInfo[1]=getNumberOfComponents();
11530     }
11531   else
11532     {
11533       tinyInfo[0]=-1;
11534       tinyInfo[1]=-1;
11535     }
11536 }
11537
11538 /*!
11539  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
11540  * Server side.
11541  */
11542 void DataArrayInt::getTinySerializationStrInformation(std::vector<std::string>& tinyInfo) const
11543 {
11544   if(isAllocated())
11545     {
11546       int nbOfCompo=getNumberOfComponents();
11547       tinyInfo.resize(nbOfCompo+1);
11548       tinyInfo[0]=getName();
11549       for(int i=0;i<nbOfCompo;i++)
11550         tinyInfo[i+1]=getInfoOnComponent(i);
11551     }
11552   else
11553     {
11554       tinyInfo.resize(1);
11555       tinyInfo[0]=getName();
11556     }
11557 }
11558
11559 /*!
11560  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
11561  * This method returns if a feeding is needed.
11562  */
11563 bool DataArrayInt::resizeForUnserialization(const std::vector<int>& tinyInfoI)
11564 {
11565   int nbOfTuple=tinyInfoI[0];
11566   int nbOfComp=tinyInfoI[1];
11567   if(nbOfTuple!=-1 || nbOfComp!=-1)
11568     {
11569       alloc(nbOfTuple,nbOfComp);
11570       return true;
11571     }
11572   return false;
11573 }
11574
11575 /*!
11576  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
11577  * This method returns if a feeding is needed.
11578  */
11579 void DataArrayInt::finishUnserialization(const std::vector<int>& tinyInfoI, const std::vector<std::string>& tinyInfoS)
11580 {
11581   setName(tinyInfoS[0]);
11582   if(isAllocated())
11583     {
11584       int nbOfCompo=tinyInfoI[1];
11585       for(int i=0;i<nbOfCompo;i++)
11586         setInfoOnComponent(i,tinyInfoS[i+1]);
11587     }
11588 }
11589
11590 DataArrayIntIterator::DataArrayIntIterator(DataArrayInt *da):_da(da),_pt(0),_tuple_id(0),_nb_comp(0),_nb_tuple(0)
11591 {
11592   if(_da)
11593     {
11594       _da->incrRef();
11595       if(_da->isAllocated())
11596         {
11597           _nb_comp=da->getNumberOfComponents();
11598           _nb_tuple=da->getNumberOfTuples();
11599           _pt=da->getPointer();
11600         }
11601     }
11602 }
11603
11604 DataArrayIntIterator::~DataArrayIntIterator()
11605 {
11606   if(_da)
11607     _da->decrRef();
11608 }
11609
11610 DataArrayIntTuple *DataArrayIntIterator::nextt()
11611 {
11612   if(_tuple_id<_nb_tuple)
11613     {
11614       _tuple_id++;
11615       DataArrayIntTuple *ret=new DataArrayIntTuple(_pt,_nb_comp);
11616       _pt+=_nb_comp;
11617       return ret;
11618     }
11619   else
11620     return 0;
11621 }
11622
11623 DataArrayIntTuple::DataArrayIntTuple(int *pt, int nbOfComp):_pt(pt),_nb_of_compo(nbOfComp)
11624 {
11625 }
11626
11627 std::string DataArrayIntTuple::repr() const
11628 {
11629   std::ostringstream oss; oss << "(";
11630   for(int i=0;i<_nb_of_compo-1;i++)
11631     oss << _pt[i] << ", ";
11632   oss << _pt[_nb_of_compo-1] << ")";
11633   return oss.str();
11634 }
11635
11636 int DataArrayIntTuple::intValue() const
11637 {
11638   if(_nb_of_compo==1)
11639     return *_pt;
11640   throw INTERP_KERNEL::Exception("DataArrayIntTuple::intValue : DataArrayIntTuple instance has not exactly 1 component -> Not possible to convert it into an integer !");
11641 }
11642
11643 /*!
11644  * This method returns a newly allocated instance the caller should dealed with by a ParaMEDMEM::DataArrayInt::decrRef.
11645  * This method performs \b no copy of data. The content is only referenced using ParaMEDMEM::DataArrayInt::useArray with ownership set to \b false.
11646  * 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
11647  * \b nbOfCompo=1 and \bnbOfTuples==this->_nb_of_elem.
11648  */
11649 DataArrayInt *DataArrayIntTuple::buildDAInt(int nbOfTuples, int nbOfCompo) const
11650 {
11651   if((_nb_of_compo==nbOfCompo && nbOfTuples==1) || (_nb_of_compo==nbOfTuples && nbOfCompo==1))
11652     {
11653       DataArrayInt *ret=DataArrayInt::New();
11654       ret->useExternalArrayWithRWAccess(_pt,nbOfTuples,nbOfCompo);
11655       return ret;
11656     }
11657   else
11658     {
11659       std::ostringstream oss; oss << "DataArrayIntTuple::buildDAInt : unable to build a requested DataArrayInt instance with nbofTuple=" << nbOfTuples << " and nbOfCompo=" << nbOfCompo;
11660       oss << ".\nBecause the number of elements in this is " << _nb_of_compo << " !";
11661       throw INTERP_KERNEL::Exception(oss.str().c_str());
11662     }
11663 }