Salome HOME
Boost of expression evaluator DataArrayDouble::applyFunc* + DataArrayDouble::applyFun...
[modules/med.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   if(byteArr)
1173     {
1174       ofs << " format=\"appended\" offset=\"" << byteArr->getNumberOfTuples() << "\">";
1175       INTERP_KERNEL::AutoPtr<float> tmp(new float[getNbOfElems()]);
1176       float *pt(tmp);
1177       // to make Visual C++ happy : instead of std::copy(begin(),end(),(float *)tmp);
1178       for(const double *src=begin();src!=end();src++,pt++)
1179         *pt=float(*src);
1180       const char *data(reinterpret_cast<const char *>((float *)tmp));
1181       std::size_t sz(getNbOfElems()*sizeof(float));
1182       byteArr->insertAtTheEnd(data,data+sz);
1183       byteArr->insertAtTheEnd(SPACE,SPACE+4);
1184     }
1185   else
1186     {
1187       ofs << " RangeMin=\"" << getMinValueInArray() << "\" RangeMax=\"" << getMaxValueInArray() << "\" format=\"ascii\">\n" << idt;
1188       std::copy(begin(),end(),std::ostream_iterator<double>(ofs," "));
1189     }
1190   ofs << std::endl << idt << "</DataArray>\n";
1191 }
1192
1193 void DataArrayDouble::reprStream(std::ostream& stream) const
1194 {
1195   stream << "Name of double array : \"" << _name << "\"\n";
1196   reprWithoutNameStream(stream);
1197 }
1198
1199 void DataArrayDouble::reprZipStream(std::ostream& stream) const
1200 {
1201   stream << "Name of double array : \"" << _name << "\"\n";
1202   reprZipWithoutNameStream(stream);
1203 }
1204
1205 void DataArrayDouble::reprWithoutNameStream(std::ostream& stream) const
1206 {
1207   DataArray::reprWithoutNameStream(stream);
1208   stream.precision(17);
1209   _mem.repr(getNumberOfComponents(),stream);
1210 }
1211
1212 void DataArrayDouble::reprZipWithoutNameStream(std::ostream& stream) const
1213 {
1214   DataArray::reprWithoutNameStream(stream);
1215   stream.precision(17);
1216   _mem.reprZip(getNumberOfComponents(),stream);
1217 }
1218
1219 void DataArrayDouble::reprCppStream(const std::string& varName, std::ostream& stream) const
1220 {
1221   int nbTuples=getNumberOfTuples(),nbComp=getNumberOfComponents();
1222   const double *data=getConstPointer();
1223   stream.precision(17);
1224   stream << "DataArrayDouble *" << varName << "=DataArrayDouble::New();" << std::endl;
1225   if(nbTuples*nbComp>=1)
1226     {
1227       stream << "const double " << varName << "Data[" << nbTuples*nbComp << "]={";
1228       std::copy(data,data+nbTuples*nbComp-1,std::ostream_iterator<double>(stream,","));
1229       stream << data[nbTuples*nbComp-1] << "};" << std::endl;
1230       stream << varName << "->useArray(" << varName << "Data,false,CPP_DEALLOC," << nbTuples << "," << nbComp << ");" << std::endl;
1231     }
1232   else
1233     stream << varName << "->alloc(" << nbTuples << "," << nbComp << ");" << std::endl;
1234   stream << varName << "->setName(\"" << getName() << "\");" << std::endl;
1235 }
1236
1237 /*!
1238  * Method that gives a quick overvien of \a this for python.
1239  */
1240 void DataArrayDouble::reprQuickOverview(std::ostream& stream) const
1241 {
1242   static const std::size_t MAX_NB_OF_BYTE_IN_REPR=300;
1243   stream << "DataArrayDouble C++ instance at " << this << ". ";
1244   if(isAllocated())
1245     {
1246       int nbOfCompo=(int)_info_on_compo.size();
1247       if(nbOfCompo>=1)
1248         {
1249           int nbOfTuples=getNumberOfTuples();
1250           stream << "Number of tuples : " << nbOfTuples << ". Number of components : " << nbOfCompo << "." << std::endl;
1251           reprQuickOverviewData(stream,MAX_NB_OF_BYTE_IN_REPR);
1252         }
1253       else
1254         stream << "Number of components : 0.";
1255     }
1256   else
1257     stream << "*** No data allocated ****";
1258 }
1259
1260 void DataArrayDouble::reprQuickOverviewData(std::ostream& stream, std::size_t maxNbOfByteInRepr) const
1261 {
1262   const double *data=begin();
1263   int nbOfTuples=getNumberOfTuples();
1264   int nbOfCompo=(int)_info_on_compo.size();
1265   std::ostringstream oss2; oss2 << "[";
1266   oss2.precision(17);
1267   std::string oss2Str(oss2.str());
1268   bool isFinished=true;
1269   for(int i=0;i<nbOfTuples && isFinished;i++)
1270     {
1271       if(nbOfCompo>1)
1272         {
1273           oss2 << "(";
1274           for(int j=0;j<nbOfCompo;j++,data++)
1275             {
1276               oss2 << *data;
1277               if(j!=nbOfCompo-1) oss2 << ", ";
1278             }
1279           oss2 << ")";
1280         }
1281       else
1282         oss2 << *data++;
1283       if(i!=nbOfTuples-1) oss2 << ", ";
1284       std::string oss3Str(oss2.str());
1285       if(oss3Str.length()<maxNbOfByteInRepr)
1286         oss2Str=oss3Str;
1287       else
1288         isFinished=false;
1289     }
1290   stream << oss2Str;
1291   if(!isFinished)
1292     stream << "... ";
1293   stream << "]";
1294 }
1295
1296 /*!
1297  * Equivalent to DataArrayDouble::isEqual except that if false the reason of
1298  * mismatch is given.
1299  * 
1300  * \param [in] other the instance to be compared with \a this
1301  * \param [in] prec the precision to compare numeric data of the arrays.
1302  * \param [out] reason In case of inequality returns the reason.
1303  * \sa DataArrayDouble::isEqual
1304  */
1305 bool DataArrayDouble::isEqualIfNotWhy(const DataArrayDouble& other, double prec, std::string& reason) const
1306 {
1307   if(!areInfoEqualsIfNotWhy(other,reason))
1308     return false;
1309   return _mem.isEqual(other._mem,prec,reason);
1310 }
1311
1312 /*!
1313  * Checks if \a this and another DataArrayDouble are fully equal. For more info see
1314  * \ref MEDCouplingArrayBasicsCompare.
1315  *  \param [in] other - an instance of DataArrayDouble to compare with \a this one.
1316  *  \param [in] prec - precision value to compare numeric data of the arrays.
1317  *  \return bool - \a true if the two arrays are equal, \a false else.
1318  */
1319 bool DataArrayDouble::isEqual(const DataArrayDouble& other, double prec) const
1320 {
1321   std::string tmp;
1322   return isEqualIfNotWhy(other,prec,tmp);
1323 }
1324
1325 /*!
1326  * Checks if values of \a this and another DataArrayDouble are equal. For more info see
1327  * \ref MEDCouplingArrayBasicsCompare.
1328  *  \param [in] other - an instance of DataArrayDouble to compare with \a this one.
1329  *  \param [in] prec - precision value to compare numeric data of the arrays.
1330  *  \return bool - \a true if the values of two arrays are equal, \a false else.
1331  */
1332 bool DataArrayDouble::isEqualWithoutConsideringStr(const DataArrayDouble& other, double prec) const
1333 {
1334   std::string tmp;
1335   return _mem.isEqual(other._mem,prec,tmp);
1336 }
1337
1338 /*!
1339  * Changes number of tuples in the array. If the new number of tuples is smaller
1340  * than the current number the array is truncated, otherwise the array is extended.
1341  *  \param [in] nbOfTuples - new number of tuples. 
1342  *  \throw If \a this is not allocated.
1343  *  \throw If \a nbOfTuples is negative.
1344  */
1345 void DataArrayDouble::reAlloc(int nbOfTuples)
1346 {
1347   if(nbOfTuples<0)
1348     throw INTERP_KERNEL::Exception("DataArrayDouble::reAlloc : input new number of tuples should be >=0 !");
1349   checkAllocated();
1350   _mem.reAlloc(getNumberOfComponents()*(std::size_t)nbOfTuples);
1351   declareAsNew();
1352 }
1353
1354 /*!
1355  * Creates a new DataArrayInt and assigns all (textual and numerical) data of \a this
1356  * array to the new one.
1357  *  \return DataArrayInt * - the new instance of DataArrayInt.
1358  */
1359 DataArrayInt *DataArrayDouble::convertToIntArr() const
1360 {
1361   DataArrayInt *ret=DataArrayInt::New();
1362   ret->alloc(getNumberOfTuples(),getNumberOfComponents());
1363   int *dest=ret->getPointer();
1364   // to make Visual C++ happy : instead of std::size_t nbOfVals=getNbOfElems(); std::copy(src,src+nbOfVals,dest);
1365   for(const double *src=begin();src!=end();src++,dest++)
1366     *dest=(int)*src;
1367   ret->copyStringInfoFrom(*this);
1368   return ret;
1369 }
1370
1371 /*!
1372  * Returns a new DataArrayDouble holding the same values as \a this array but differently
1373  * arranged in memory. If \a this array holds 2 components of 3 values:
1374  * \f$ x_0,x_1,x_2,y_0,y_1,y_2 \f$, then the result array holds these values arranged
1375  * as follows: \f$ x_0,y_0,x_1,y_1,x_2,y_2 \f$.
1376  *  \warning Do not confuse this method with transpose()!
1377  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1378  *          is to delete using decrRef() as it is no more needed.
1379  *  \throw If \a this is not allocated.
1380  */
1381 DataArrayDouble *DataArrayDouble::fromNoInterlace() const
1382 {
1383   if(_mem.isNull())
1384     throw INTERP_KERNEL::Exception("DataArrayDouble::fromNoInterlace : Not defined array !");
1385   double *tab=_mem.fromNoInterlace(getNumberOfComponents());
1386   DataArrayDouble *ret=DataArrayDouble::New();
1387   ret->useArray(tab,true,C_DEALLOC,getNumberOfTuples(),getNumberOfComponents());
1388   return ret;
1389 }
1390
1391 /*!
1392  * Returns a new DataArrayDouble holding the same values as \a this array but differently
1393  * arranged in memory. If \a this array holds 2 components of 3 values:
1394  * \f$ x_0,y_0,x_1,y_1,x_2,y_2 \f$, then the result array holds these values arranged
1395  * as follows: \f$ x_0,x_1,x_2,y_0,y_1,y_2 \f$.
1396  *  \warning Do not confuse this method with transpose()!
1397  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1398  *          is to delete using decrRef() as it is no more needed.
1399  *  \throw If \a this is not allocated.
1400  */
1401 DataArrayDouble *DataArrayDouble::toNoInterlace() const
1402 {
1403   if(_mem.isNull())
1404     throw INTERP_KERNEL::Exception("DataArrayDouble::toNoInterlace : Not defined array !");
1405   double *tab=_mem.toNoInterlace(getNumberOfComponents());
1406   DataArrayDouble *ret=DataArrayDouble::New();
1407   ret->useArray(tab,true,C_DEALLOC,getNumberOfTuples(),getNumberOfComponents());
1408   return ret;
1409 }
1410
1411 /*!
1412  * Permutes values of \a this array as required by \a old2New array. The values are
1413  * permuted so that \c new[ \a old2New[ i ]] = \c old[ i ]. Number of tuples remains
1414  * the same as in \this one.
1415  * If a permutation reduction is needed, substr() or selectByTupleId() should be used.
1416  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
1417  *  \param [in] old2New - C array of length equal to \a this->getNumberOfTuples()
1418  *     giving a new position for i-th old value.
1419  */
1420 void DataArrayDouble::renumberInPlace(const int *old2New)
1421 {
1422   checkAllocated();
1423   int nbTuples=getNumberOfTuples();
1424   int nbOfCompo=getNumberOfComponents();
1425   double *tmp=new double[nbTuples*nbOfCompo];
1426   const double *iptr=getConstPointer();
1427   for(int i=0;i<nbTuples;i++)
1428     {
1429       int v=old2New[i];
1430       if(v>=0 && v<nbTuples)
1431         std::copy(iptr+nbOfCompo*i,iptr+nbOfCompo*(i+1),tmp+nbOfCompo*v);
1432       else
1433         {
1434           std::ostringstream oss; oss << "DataArrayDouble::renumberInPlace : At place #" << i << " value is " << v << " ! Should be in [0," << nbTuples << ") !";
1435           throw INTERP_KERNEL::Exception(oss.str().c_str());
1436         }
1437     }
1438   std::copy(tmp,tmp+nbTuples*nbOfCompo,getPointer());
1439   delete [] tmp;
1440   declareAsNew();
1441 }
1442
1443 /*!
1444  * Permutes values of \a this array as required by \a new2Old array. The values are
1445  * permuted so that \c new[ i ] = \c old[ \a new2Old[ i ]]. Number of tuples remains
1446  * the same as in \this one.
1447  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
1448  *  \param [in] new2Old - C array of length equal to \a this->getNumberOfTuples()
1449  *     giving a previous position of i-th new value.
1450  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1451  *          is to delete using decrRef() as it is no more needed.
1452  */
1453 void DataArrayDouble::renumberInPlaceR(const int *new2Old)
1454 {
1455   checkAllocated();
1456   int nbTuples=getNumberOfTuples();
1457   int nbOfCompo=getNumberOfComponents();
1458   double *tmp=new double[nbTuples*nbOfCompo];
1459   const double *iptr=getConstPointer();
1460   for(int i=0;i<nbTuples;i++)
1461     {
1462       int v=new2Old[i];
1463       if(v>=0 && v<nbTuples)
1464         std::copy(iptr+nbOfCompo*v,iptr+nbOfCompo*(v+1),tmp+nbOfCompo*i);
1465       else
1466         {
1467           std::ostringstream oss; oss << "DataArrayDouble::renumberInPlaceR : At place #" << i << " value is " << v << " ! Should be in [0," << nbTuples << ") !";
1468           throw INTERP_KERNEL::Exception(oss.str().c_str());
1469         }
1470     }
1471   std::copy(tmp,tmp+nbTuples*nbOfCompo,getPointer());
1472   delete [] tmp;
1473   declareAsNew();
1474 }
1475
1476 /*!
1477  * Returns a copy of \a this array with values permuted as required by \a old2New array.
1478  * The values are permuted so that  \c new[ \a old2New[ i ]] = \c old[ i ].
1479  * Number of tuples in the result array remains the same as in \this one.
1480  * If a permutation reduction is needed, renumberAndReduce() should be used.
1481  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
1482  *  \param [in] old2New - C array of length equal to \a this->getNumberOfTuples()
1483  *          giving a new position for i-th old value.
1484  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1485  *          is to delete using decrRef() as it is no more needed.
1486  *  \throw If \a this is not allocated.
1487  */
1488 DataArrayDouble *DataArrayDouble::renumber(const int *old2New) const
1489 {
1490   checkAllocated();
1491   int nbTuples=getNumberOfTuples();
1492   int nbOfCompo=getNumberOfComponents();
1493   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
1494   ret->alloc(nbTuples,nbOfCompo);
1495   ret->copyStringInfoFrom(*this);
1496   const double *iptr=getConstPointer();
1497   double *optr=ret->getPointer();
1498   for(int i=0;i<nbTuples;i++)
1499     std::copy(iptr+nbOfCompo*i,iptr+nbOfCompo*(i+1),optr+nbOfCompo*old2New[i]);
1500   ret->copyStringInfoFrom(*this);
1501   return ret.retn();
1502 }
1503
1504 /*!
1505  * Returns a copy of \a this array with values permuted as required by \a new2Old array.
1506  * The values are permuted so that  \c new[ i ] = \c old[ \a new2Old[ i ]]. Number of
1507  * tuples in the result array remains the same as in \this one.
1508  * If a permutation reduction is needed, substr() or selectByTupleId() should be used.
1509  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
1510  *  \param [in] new2Old - C array of length equal to \a this->getNumberOfTuples()
1511  *     giving a previous position of i-th new value.
1512  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1513  *          is to delete using decrRef() as it is no more needed.
1514  */
1515 DataArrayDouble *DataArrayDouble::renumberR(const int *new2Old) const
1516 {
1517   checkAllocated();
1518   int nbTuples=getNumberOfTuples();
1519   int nbOfCompo=getNumberOfComponents();
1520   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
1521   ret->alloc(nbTuples,nbOfCompo);
1522   ret->copyStringInfoFrom(*this);
1523   const double *iptr=getConstPointer();
1524   double *optr=ret->getPointer();
1525   for(int i=0;i<nbTuples;i++)
1526     std::copy(iptr+nbOfCompo*new2Old[i],iptr+nbOfCompo*(new2Old[i]+1),optr+i*nbOfCompo);
1527   ret->copyStringInfoFrom(*this);
1528   return ret.retn();
1529 }
1530
1531 /*!
1532  * Returns a shorten and permuted copy of \a this array. The new DataArrayDouble is
1533  * of size \a newNbOfTuple and it's values are permuted as required by \a old2New array.
1534  * The values are permuted so that  \c new[ \a old2New[ i ]] = \c old[ i ] for all
1535  * \a old2New[ i ] >= 0. In other words every i-th tuple in \a this array, for which 
1536  * \a old2New[ i ] is negative, is missing from the result array.
1537  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
1538  *  \param [in] old2New - C array of length equal to \a this->getNumberOfTuples()
1539  *     giving a new position for i-th old tuple and giving negative position for
1540  *     for i-th old tuple that should be omitted.
1541  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1542  *          is to delete using decrRef() as it is no more needed.
1543  */
1544 DataArrayDouble *DataArrayDouble::renumberAndReduce(const int *old2New, int newNbOfTuple) const
1545 {
1546   checkAllocated();
1547   int nbTuples=getNumberOfTuples();
1548   int nbOfCompo=getNumberOfComponents();
1549   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
1550   ret->alloc(newNbOfTuple,nbOfCompo);
1551   const double *iptr=getConstPointer();
1552   double *optr=ret->getPointer();
1553   for(int i=0;i<nbTuples;i++)
1554     {
1555       int w=old2New[i];
1556       if(w>=0)
1557         std::copy(iptr+i*nbOfCompo,iptr+(i+1)*nbOfCompo,optr+w*nbOfCompo);
1558     }
1559   ret->copyStringInfoFrom(*this);
1560   return ret.retn();
1561 }
1562
1563 /*!
1564  * Returns a shorten and permuted copy of \a this array. The new DataArrayDouble is
1565  * of size \a new2OldEnd - \a new2OldBg and it's values are permuted as required by
1566  * \a new2OldBg array.
1567  * The values are permuted so that  \c new[ i ] = \c old[ \a new2OldBg[ i ]].
1568  * This method is equivalent to renumberAndReduce() except that convention in input is
1569  * \c new2old and \b not \c old2new.
1570  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
1571  *  \param [in] new2OldBg - pointer to the beginning of a permutation array that gives a
1572  *              tuple index in \a this array to fill the i-th tuple in the new array.
1573  *  \param [in] new2OldEnd - specifies the end of the permutation array that starts at
1574  *              \a new2OldBg, so that pointer to a tuple index (\a pi) varies as this:
1575  *              \a new2OldBg <= \a pi < \a new2OldEnd.
1576  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1577  *          is to delete using decrRef() as it is no more needed.
1578  */
1579 DataArrayDouble *DataArrayDouble::selectByTupleId(const int *new2OldBg, const int *new2OldEnd) const
1580 {
1581   checkAllocated();
1582   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
1583   int nbComp=getNumberOfComponents();
1584   ret->alloc((int)std::distance(new2OldBg,new2OldEnd),nbComp);
1585   ret->copyStringInfoFrom(*this);
1586   double *pt=ret->getPointer();
1587   const double *srcPt=getConstPointer();
1588   int i=0;
1589   for(const int *w=new2OldBg;w!=new2OldEnd;w++,i++)
1590     std::copy(srcPt+(*w)*nbComp,srcPt+((*w)+1)*nbComp,pt+i*nbComp);
1591   ret->copyStringInfoFrom(*this);
1592   return ret.retn();
1593 }
1594
1595 /*!
1596  * Returns a shorten and permuted copy of \a this array. The new DataArrayDouble is
1597  * of size \a new2OldEnd - \a new2OldBg and it's values are permuted as required by
1598  * \a new2OldBg array.
1599  * The values are permuted so that  \c new[ i ] = \c old[ \a new2OldBg[ i ]].
1600  * This method is equivalent to renumberAndReduce() except that convention in input is
1601  * \c new2old and \b not \c old2new.
1602  * This method is equivalent to selectByTupleId() except that it prevents coping data
1603  * from behind the end of \a this array.
1604  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
1605  *  \param [in] new2OldBg - pointer to the beginning of a permutation array that gives a
1606  *              tuple index in \a this array to fill the i-th tuple in the new array.
1607  *  \param [in] new2OldEnd - specifies the end of the permutation array that starts at
1608  *              \a new2OldBg, so that pointer to a tuple index (\a pi) varies as this:
1609  *              \a new2OldBg <= \a pi < \a new2OldEnd.
1610  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1611  *          is to delete using decrRef() as it is no more needed.
1612  *  \throw If \a new2OldEnd - \a new2OldBg > \a this->getNumberOfTuples().
1613  */
1614 DataArrayDouble *DataArrayDouble::selectByTupleIdSafe(const int *new2OldBg, const int *new2OldEnd) const
1615 {
1616   checkAllocated();
1617   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
1618   int nbComp=getNumberOfComponents();
1619   int oldNbOfTuples=getNumberOfTuples();
1620   ret->alloc((int)std::distance(new2OldBg,new2OldEnd),nbComp);
1621   ret->copyStringInfoFrom(*this);
1622   double *pt=ret->getPointer();
1623   const double *srcPt=getConstPointer();
1624   int i=0;
1625   for(const int *w=new2OldBg;w!=new2OldEnd;w++,i++)
1626     if(*w>=0 && *w<oldNbOfTuples)
1627       std::copy(srcPt+(*w)*nbComp,srcPt+((*w)+1)*nbComp,pt+i*nbComp);
1628     else
1629       throw INTERP_KERNEL::Exception("DataArrayDouble::selectByTupleIdSafe : some ids has been detected to be out of [0,this->getNumberOfTuples) !");
1630   ret->copyStringInfoFrom(*this);
1631   return ret.retn();
1632 }
1633
1634 /*!
1635  * Returns a shorten copy of \a this array. The new DataArrayDouble contains every
1636  * (\a bg + \c i * \a step)-th tuple of \a this array located before the \a end2-th
1637  * tuple. Indices of the selected tuples are the same as ones returned by the Python
1638  * command \c range( \a bg, \a end2, \a step ).
1639  * This method is equivalent to selectByTupleIdSafe() except that the input array is
1640  * not constructed explicitly.
1641  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
1642  *  \param [in] bg - index of the first tuple to copy from \a this array.
1643  *  \param [in] end2 - index of the tuple before which the tuples to copy are located.
1644  *  \param [in] step - index increment to get index of the next tuple to copy.
1645  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1646  *          is to delete using decrRef() as it is no more needed.
1647  *  \sa DataArrayDouble::substr.
1648  */
1649 DataArrayDouble *DataArrayDouble::selectByTupleId2(int bg, int end2, int step) const
1650 {
1651   checkAllocated();
1652   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
1653   int nbComp=getNumberOfComponents();
1654   int newNbOfTuples=GetNumberOfItemGivenBESRelative(bg,end2,step,"DataArrayDouble::selectByTupleId2 : ");
1655   ret->alloc(newNbOfTuples,nbComp);
1656   double *pt=ret->getPointer();
1657   const double *srcPt=getConstPointer()+bg*nbComp;
1658   for(int i=0;i<newNbOfTuples;i++,srcPt+=step*nbComp)
1659     std::copy(srcPt,srcPt+nbComp,pt+i*nbComp);
1660   ret->copyStringInfoFrom(*this);
1661   return ret.retn();
1662 }
1663
1664 /*!
1665  * Returns a shorten copy of \a this array. The new DataArrayDouble contains ranges
1666  * of tuples specified by \a ranges parameter.
1667  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
1668  *  \param [in] ranges - std::vector of std::pair's each of which defines a range
1669  *              of tuples in [\c begin,\c end) format.
1670  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1671  *          is to delete using decrRef() as it is no more needed.
1672  *  \throw If \a end < \a begin.
1673  *  \throw If \a end > \a this->getNumberOfTuples().
1674  *  \throw If \a this is not allocated.
1675  */
1676 DataArray *DataArrayDouble::selectByTupleRanges(const std::vector<std::pair<int,int> >& ranges) const
1677 {
1678   checkAllocated();
1679   int nbOfComp=getNumberOfComponents();
1680   int nbOfTuplesThis=getNumberOfTuples();
1681   if(ranges.empty())
1682     {
1683       DataArrayDouble *ret=DataArrayDouble::New();
1684       ret->alloc(0,nbOfComp);
1685       ret->copyStringInfoFrom(*this);
1686       return ret;
1687     }
1688   int ref=ranges.front().first;
1689   int nbOfTuples=0;
1690   bool isIncreasing=true;
1691   for(std::vector<std::pair<int,int> >::const_iterator it=ranges.begin();it!=ranges.end();it++)
1692     {
1693       if((*it).first<=(*it).second)
1694         {
1695           if((*it).first>=0 && (*it).second<=nbOfTuplesThis)
1696             {
1697               nbOfTuples+=(*it).second-(*it).first;
1698               if(isIncreasing)
1699                 isIncreasing=ref<=(*it).first;
1700               ref=(*it).second;
1701             }
1702           else
1703             {
1704               std::ostringstream oss; oss << "DataArrayDouble::selectByTupleRanges : on range #" << std::distance(ranges.begin(),it);
1705               oss << " (" << (*it).first << "," << (*it).second << ") is greater than number of tuples of this :" << nbOfTuples << " !";
1706               throw INTERP_KERNEL::Exception(oss.str().c_str());
1707             }
1708         }
1709       else
1710         {
1711           std::ostringstream oss; oss << "DataArrayDouble::selectByTupleRanges : on range #" << std::distance(ranges.begin(),it);
1712           oss << " (" << (*it).first << "," << (*it).second << ") end is before begin !";
1713           throw INTERP_KERNEL::Exception(oss.str().c_str());
1714         }
1715     }
1716   if(isIncreasing && nbOfTuplesThis==nbOfTuples)
1717     return deepCpy();
1718   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
1719   ret->alloc(nbOfTuples,nbOfComp);
1720   ret->copyStringInfoFrom(*this);
1721   const double *src=getConstPointer();
1722   double *work=ret->getPointer();
1723   for(std::vector<std::pair<int,int> >::const_iterator it=ranges.begin();it!=ranges.end();it++)
1724     work=std::copy(src+(*it).first*nbOfComp,src+(*it).second*nbOfComp,work);
1725   return ret.retn();
1726 }
1727
1728 /*!
1729  * Returns a shorten copy of \a this array. The new DataArrayDouble contains all
1730  * tuples starting from the \a tupleIdBg-th tuple and including all tuples located before
1731  * the \a tupleIdEnd-th one. This methods has a similar behavior as std::string::substr().
1732  * This method is a specialization of selectByTupleId2().
1733  *  \param [in] tupleIdBg - index of the first tuple to copy from \a this array.
1734  *  \param [in] tupleIdEnd - index of the tuple before which the tuples to copy are located.
1735  *          If \a tupleIdEnd == -1, all the tuples till the end of \a this array are copied.
1736  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1737  *          is to delete using decrRef() as it is no more needed.
1738  *  \throw If \a tupleIdBg < 0.
1739  *  \throw If \a tupleIdBg > \a this->getNumberOfTuples().
1740     \throw If \a tupleIdEnd != -1 && \a tupleIdEnd < \a this->getNumberOfTuples().
1741  *  \sa DataArrayDouble::selectByTupleId2
1742  */
1743 DataArrayDouble *DataArrayDouble::substr(int tupleIdBg, int tupleIdEnd) const
1744 {
1745   checkAllocated();
1746   int nbt=getNumberOfTuples();
1747   if(tupleIdBg<0)
1748     throw INTERP_KERNEL::Exception("DataArrayDouble::substr : The tupleIdBg parameter must be greater than 0 !");
1749   if(tupleIdBg>nbt)
1750     throw INTERP_KERNEL::Exception("DataArrayDouble::substr : The tupleIdBg parameter is greater than number of tuples !");
1751   int trueEnd=tupleIdEnd;
1752   if(tupleIdEnd!=-1)
1753     {
1754       if(tupleIdEnd>nbt)
1755         throw INTERP_KERNEL::Exception("DataArrayDouble::substr : The tupleIdBg parameter is greater or equal than number of tuples !");
1756     }
1757   else
1758     trueEnd=nbt;
1759   int nbComp=getNumberOfComponents();
1760   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
1761   ret->alloc(trueEnd-tupleIdBg,nbComp);
1762   ret->copyStringInfoFrom(*this);
1763   std::copy(getConstPointer()+tupleIdBg*nbComp,getConstPointer()+trueEnd*nbComp,ret->getPointer());
1764   return ret.retn();
1765 }
1766
1767 /*!
1768  * Returns a shorten or extended copy of \a this array. If \a newNbOfComp is less
1769  * than \a this->getNumberOfComponents() then the result array is shorten as each tuple
1770  * is truncated to have \a newNbOfComp components, keeping first components. If \a
1771  * newNbOfComp is more than \a this->getNumberOfComponents() then the result array is
1772  * expanded as each tuple is populated with \a dftValue to have \a newNbOfComp
1773  * components.  
1774  *  \param [in] newNbOfComp - number of components for the new array to have.
1775  *  \param [in] dftValue - value assigned to new values added to the new array.
1776  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1777  *          is to delete using decrRef() as it is no more needed.
1778  *  \throw If \a this is not allocated.
1779  */
1780 DataArrayDouble *DataArrayDouble::changeNbOfComponents(int newNbOfComp, double dftValue) const
1781 {
1782   checkAllocated();
1783   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
1784   ret->alloc(getNumberOfTuples(),newNbOfComp);
1785   const double *oldc=getConstPointer();
1786   double *nc=ret->getPointer();
1787   int nbOfTuples=getNumberOfTuples();
1788   int oldNbOfComp=getNumberOfComponents();
1789   int dim=std::min(oldNbOfComp,newNbOfComp);
1790   for(int i=0;i<nbOfTuples;i++)
1791     {
1792       int j=0;
1793       for(;j<dim;j++)
1794         nc[newNbOfComp*i+j]=oldc[i*oldNbOfComp+j];
1795       for(;j<newNbOfComp;j++)
1796         nc[newNbOfComp*i+j]=dftValue;
1797     }
1798   ret->setName(getName());
1799   for(int i=0;i<dim;i++)
1800     ret->setInfoOnComponent(i,getInfoOnComponent(i));
1801   ret->setName(getName());
1802   return ret.retn();
1803 }
1804
1805 /*!
1806  * Changes the number of components within \a this array so that its raw data **does
1807  * not** change, instead splitting this data into tuples changes.
1808  *  \warning This method erases all (name and unit) component info set before!
1809  *  \param [in] newNbOfComp - number of components for \a this array to have.
1810  *  \throw If \a this is not allocated
1811  *  \throw If getNbOfElems() % \a newNbOfCompo != 0.
1812  *  \throw If \a newNbOfCompo is lower than 1.
1813  *  \throw If the rearrange method would lead to a number of tuples higher than 2147483647 (maximal capacity of int32 !).
1814  *  \warning This method erases all (name and unit) component info set before!
1815  */
1816 void DataArrayDouble::rearrange(int newNbOfCompo)
1817 {
1818   checkAllocated();
1819   if(newNbOfCompo<1)
1820     throw INTERP_KERNEL::Exception("DataArrayDouble::rearrange : input newNbOfCompo must be > 0 !");
1821   std::size_t nbOfElems=getNbOfElems();
1822   if(nbOfElems%newNbOfCompo!=0)
1823     throw INTERP_KERNEL::Exception("DataArrayDouble::rearrange : nbOfElems%newNbOfCompo!=0 !");
1824   if(nbOfElems/newNbOfCompo>(std::size_t)std::numeric_limits<int>::max())
1825     throw INTERP_KERNEL::Exception("DataArrayDouble::rearrange : the rearrangement leads to too high number of tuples (> 2147483647) !");
1826   _info_on_compo.clear();
1827   _info_on_compo.resize(newNbOfCompo);
1828   declareAsNew();
1829 }
1830
1831 /*!
1832  * Changes the number of components within \a this array to be equal to its number
1833  * of tuples, and inversely its number of tuples to become equal to its number of 
1834  * components. So that its raw data **does not** change, instead splitting this
1835  * data into tuples changes.
1836  *  \warning This method erases all (name and unit) component info set before!
1837  *  \warning Do not confuse this method with fromNoInterlace() and toNoInterlace()!
1838  *  \throw If \a this is not allocated.
1839  *  \sa rearrange()
1840  */
1841 void DataArrayDouble::transpose()
1842 {
1843   checkAllocated();
1844   int nbOfTuples=getNumberOfTuples();
1845   rearrange(nbOfTuples);
1846 }
1847
1848 /*!
1849  * Returns a copy of \a this array composed of selected components.
1850  * The new DataArrayDouble has the same number of tuples but includes components
1851  * specified by \a compoIds parameter. So that getNbOfElems() of the result array
1852  * can be either less, same or more than \a this->getNbOfElems().
1853  *  \param [in] compoIds - sequence of zero based indices of components to include
1854  *              into the new array.
1855  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1856  *          is to delete using decrRef() as it is no more needed.
1857  *  \throw If \a this is not allocated.
1858  *  \throw If a component index (\a i) is not valid: 
1859  *         \a i < 0 || \a i >= \a this->getNumberOfComponents().
1860  *
1861  *  \if ENABLE_EXAMPLES
1862  *  \ref py_mcdataarraydouble_KeepSelectedComponents "Here is a Python example".
1863  *  \endif
1864  */
1865 DataArrayDouble *DataArrayDouble::keepSelectedComponents(const std::vector<int>& compoIds) const
1866 {
1867   checkAllocated();
1868   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret(DataArrayDouble::New());
1869   std::size_t newNbOfCompo=compoIds.size();
1870   int oldNbOfCompo=getNumberOfComponents();
1871   for(std::vector<int>::const_iterator it=compoIds.begin();it!=compoIds.end();it++)
1872     if((*it)<0 || (*it)>=oldNbOfCompo)
1873       {
1874         std::ostringstream oss; oss << "DataArrayDouble::keepSelectedComponents : invalid requested component : " << *it << " whereas it should be in [0," << oldNbOfCompo << ") !";
1875         throw INTERP_KERNEL::Exception(oss.str().c_str());
1876       }
1877   int nbOfTuples=getNumberOfTuples();
1878   ret->alloc(nbOfTuples,(int)newNbOfCompo);
1879   ret->copyPartOfStringInfoFrom(*this,compoIds);
1880   const double *oldc=getConstPointer();
1881   double *nc=ret->getPointer();
1882   for(int i=0;i<nbOfTuples;i++)
1883     for(std::size_t j=0;j<newNbOfCompo;j++,nc++)
1884       *nc=oldc[i*oldNbOfCompo+compoIds[j]];
1885   return ret.retn();
1886 }
1887
1888 /*!
1889  * Appends components of another array to components of \a this one, tuple by tuple.
1890  * So that the number of tuples of \a this array remains the same and the number of 
1891  * components increases.
1892  *  \param [in] other - the DataArrayDouble to append to \a this one.
1893  *  \throw If \a this is not allocated.
1894  *  \throw If \a this and \a other arrays have different number of tuples.
1895  *
1896  *  \if ENABLE_EXAMPLES
1897  *  \ref cpp_mcdataarraydouble_meldwith "Here is a C++ example".
1898  *
1899  *  \ref py_mcdataarraydouble_meldwith "Here is a Python example".
1900  *  \endif
1901  */
1902 void DataArrayDouble::meldWith(const DataArrayDouble *other)
1903 {
1904   checkAllocated();
1905   other->checkAllocated();
1906   int nbOfTuples=getNumberOfTuples();
1907   if(nbOfTuples!=other->getNumberOfTuples())
1908     throw INTERP_KERNEL::Exception("DataArrayDouble::meldWith : mismatch of number of tuples !");
1909   int nbOfComp1=getNumberOfComponents();
1910   int nbOfComp2=other->getNumberOfComponents();
1911   double *newArr=(double *)malloc((nbOfTuples*(nbOfComp1+nbOfComp2))*sizeof(double));
1912   double *w=newArr;
1913   const double *inp1=getConstPointer();
1914   const double *inp2=other->getConstPointer();
1915   for(int i=0;i<nbOfTuples;i++,inp1+=nbOfComp1,inp2+=nbOfComp2)
1916     {
1917       w=std::copy(inp1,inp1+nbOfComp1,w);
1918       w=std::copy(inp2,inp2+nbOfComp2,w);
1919     }
1920   useArray(newArr,true,C_DEALLOC,nbOfTuples,nbOfComp1+nbOfComp2);
1921   std::vector<int> compIds(nbOfComp2);
1922   for(int i=0;i<nbOfComp2;i++)
1923     compIds[i]=nbOfComp1+i;
1924   copyPartOfStringInfoFrom2(compIds,*other);
1925 }
1926
1927 /*!
1928  * This method checks that all tuples in \a other are in \a this.
1929  * If true, the output param \a tupleIds contains the tuples ids of \a this that correspond to tupes in \a this.
1930  * 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.
1931  *
1932  * \param [in] other - the array having the same number of components than \a this.
1933  * \param [out] tupleIds - the tuple ids containing the same number of tuples than \a other has.
1934  * \sa DataArrayDouble::findCommonTuples
1935  */
1936 bool DataArrayDouble::areIncludedInMe(const DataArrayDouble *other, double prec, DataArrayInt *&tupleIds) const
1937 {
1938   if(!other)
1939     throw INTERP_KERNEL::Exception("DataArrayDouble::areIncludedInMe : input array is NULL !");
1940   checkAllocated(); other->checkAllocated();
1941   if(getNumberOfComponents()!=other->getNumberOfComponents())
1942     throw INTERP_KERNEL::Exception("DataArrayDouble::areIncludedInMe : the number of components does not match !");
1943   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> a=DataArrayDouble::Aggregate(this,other);
1944   DataArrayInt *c=0,*ci=0;
1945   a->findCommonTuples(prec,getNumberOfTuples(),c,ci);
1946   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cSafe(c),ciSafe(ci);
1947   int newNbOfTuples=-1;
1948   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ids=DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2(a->getNumberOfTuples(),c->begin(),ci->begin(),ci->end(),newNbOfTuples);
1949   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret1=ids->selectByTupleId2(getNumberOfTuples(),a->getNumberOfTuples(),1);
1950   tupleIds=ret1.retn();
1951   return newNbOfTuples==getNumberOfTuples();
1952 }
1953
1954 /*!
1955  * Searches for tuples coincident within \a prec tolerance. Each tuple is considered
1956  * as coordinates of a point in getNumberOfComponents()-dimensional space. The
1957  * distance separating two points is computed with the infinite norm.
1958  *
1959  * Indices of coincident tuples are stored in output arrays.
1960  * A pair of arrays (\a comm, \a commIndex) is called "Surjective Format 2".
1961  *
1962  * This method is typically used by MEDCouplingPointSet::findCommonNodes() and
1963  * MEDCouplingUMesh::mergeNodes().
1964  *  \param [in] prec - minimal absolute distance between two tuples (infinite norm) at which they are
1965  *              considered not coincident.
1966  *  \param [in] limitTupleId - limit tuple id. If all tuples within a group of coincident
1967  *              tuples have id strictly lower than \a limitTupleId then they are not returned.
1968  *  \param [out] comm - the array holding ids (== indices) of coincident tuples. 
1969  *               \a comm->getNumberOfComponents() == 1. 
1970  *               \a comm->getNumberOfTuples() == \a commIndex->back().
1971  *  \param [out] commIndex - the array dividing all indices stored in \a comm into
1972  *               groups of (indices of) coincident tuples. Its every value is a tuple
1973  *               index where a next group of tuples begins. For example the second
1974  *               group of tuples in \a comm is described by following range of indices:
1975  *               [ \a commIndex[1], \a commIndex[2] ). \a commIndex->getNumberOfTuples()-1
1976  *               gives the number of groups of coincident tuples.
1977  *  \throw If \a this is not allocated.
1978  *  \throw If the number of components is not in [1,2,3,4].
1979  *
1980  *  \if ENABLE_EXAMPLES
1981  *  \ref cpp_mcdataarraydouble_findcommontuples "Here is a C++ example".
1982  *
1983  *  \ref py_mcdataarraydouble_findcommontuples  "Here is a Python example".
1984  *  \endif
1985  *  \sa DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2(), DataArrayDouble::areIncludedInMe
1986  */
1987 void DataArrayDouble::findCommonTuples(double prec, int limitTupleId, DataArrayInt *&comm, DataArrayInt *&commIndex) const
1988 {
1989   checkAllocated();
1990   int nbOfCompo=getNumberOfComponents();
1991   if ((nbOfCompo<1) || (nbOfCompo>4)) //test before work
1992     throw INTERP_KERNEL::Exception("DataArrayDouble::findCommonTuples : Unexpected spacedim of coords. Must be 1, 2, 3 or 4.");
1993
1994   int nbOfTuples=getNumberOfTuples();
1995   //
1996   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> c(DataArrayInt::New()),cI(DataArrayInt::New()); c->alloc(0,1); cI->pushBackSilent(0);
1997   switch(nbOfCompo)
1998   {
1999     case 4:
2000       findCommonTuplesAlg<4>(begin(),nbOfTuples,limitTupleId,prec,c,cI);
2001       break;
2002     case 3:
2003       findCommonTuplesAlg<3>(begin(),nbOfTuples,limitTupleId,prec,c,cI);
2004       break;
2005     case 2:
2006       findCommonTuplesAlg<2>(begin(),nbOfTuples,limitTupleId,prec,c,cI);
2007       break;
2008     case 1:
2009       findCommonTuplesAlg<1>(begin(),nbOfTuples,limitTupleId,prec,c,cI);
2010       break;
2011     default:
2012       throw INTERP_KERNEL::Exception("DataArrayDouble::findCommonTuples : nb of components managed are 1,2,3 and 4 ! not implemented for other number of components !");
2013   }
2014   comm=c.retn();
2015   commIndex=cI.retn();
2016 }
2017
2018 /*!
2019  * 
2020  * \param [in] nbTimes specifies the nb of times each tuples in \a this will be duplicated contiguouly in returned DataArrayDouble instance.
2021  *             \a nbTimes  should be at least equal to 1.
2022  * \return a newly allocated DataArrayDouble having one component and number of tuples equal to \a nbTimes * \c this->getNumberOfTuples.
2023  * \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.
2024  */
2025 DataArrayDouble *DataArrayDouble::duplicateEachTupleNTimes(int nbTimes) const
2026 {
2027   checkAllocated();
2028   if(getNumberOfComponents()!=1)
2029     throw INTERP_KERNEL::Exception("DataArrayDouble::duplicateEachTupleNTimes : this should have only one component !");
2030   if(nbTimes<1)
2031     throw INTERP_KERNEL::Exception("DataArrayDouble::duplicateEachTupleNTimes : nb times should be >= 1 !");
2032   int nbTuples=getNumberOfTuples();
2033   const double *inPtr=getConstPointer();
2034   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New(); ret->alloc(nbTimes*nbTuples,1);
2035   double *retPtr=ret->getPointer();
2036   for(int i=0;i<nbTuples;i++,inPtr++)
2037     {
2038       double val=*inPtr;
2039       for(int j=0;j<nbTimes;j++,retPtr++)
2040         *retPtr=val;
2041     }
2042   ret->copyStringInfoFrom(*this);
2043   return ret.retn();
2044 }
2045
2046 /*!
2047  * This methods returns the minimal distance between the two set of points \a this and \a other.
2048  * So \a this and \a other have to have the same number of components. If not an INTERP_KERNEL::Exception will be thrown.
2049  * This method works only if number of components of \a this (equal to those of \a other) is in 1, 2 or 3.
2050  *
2051  * \param [out] thisTupleId the tuple id in \a this corresponding to the returned minimal distance
2052  * \param [out] otherTupleId the tuple id in \a other corresponding to the returned minimal distance
2053  * \return the minimal distance between the two set of points \a this and \a other.
2054  * \sa DataArrayDouble::findClosestTupleId
2055  */
2056 double DataArrayDouble::minimalDistanceTo(const DataArrayDouble *other, int& thisTupleId, int& otherTupleId) const
2057 {
2058   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> part1=findClosestTupleId(other);
2059   int nbOfCompo(getNumberOfComponents());
2060   int otherNbTuples(other->getNumberOfTuples());
2061   const double *thisPt(begin()),*otherPt(other->begin());
2062   const int *part1Pt(part1->begin());
2063   double ret=std::numeric_limits<double>::max();
2064   for(int i=0;i<otherNbTuples;i++,part1Pt++,otherPt+=nbOfCompo)
2065     {
2066       double tmp(0.);
2067       for(int j=0;j<nbOfCompo;j++)
2068         tmp+=(otherPt[j]-thisPt[nbOfCompo*(*part1Pt)+j])*(otherPt[j]-thisPt[nbOfCompo*(*part1Pt)+j]);
2069       if(tmp<ret)
2070         { ret=tmp; thisTupleId=*part1Pt; otherTupleId=i; }
2071     }
2072   return sqrt(ret);
2073 }
2074
2075 /*!
2076  * This methods returns for each tuple in \a other which tuple in \a this is the closest.
2077  * So \a this and \a other have to have the same number of components. If not an INTERP_KERNEL::Exception will be thrown.
2078  * This method works only if number of components of \a this (equal to those of \a other) is in 1, 2 or 3.
2079  *
2080  * \return a newly allocated (new object to be dealt by the caller) DataArrayInt having \c other->getNumberOfTuples() tuples and one components.
2081  * \sa DataArrayDouble::minimalDistanceTo
2082  */
2083 DataArrayInt *DataArrayDouble::findClosestTupleId(const DataArrayDouble *other) const
2084 {
2085   if(!other)
2086     throw INTERP_KERNEL::Exception("DataArrayDouble::findClosestTupleId : other instance is NULL !");
2087   checkAllocated(); other->checkAllocated();
2088   int nbOfCompo=getNumberOfComponents();
2089   if(nbOfCompo!=other->getNumberOfComponents())
2090     {
2091       std::ostringstream oss; oss << "DataArrayDouble::findClosestTupleId : number of components in this is " << nbOfCompo;
2092       oss << ", whereas number of components in other is " << other->getNumberOfComponents() << "! Should be equal !";
2093       throw INTERP_KERNEL::Exception(oss.str().c_str());
2094     }
2095   int nbOfTuples=other->getNumberOfTuples();
2096   int thisNbOfTuples=getNumberOfTuples();
2097   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbOfTuples,1);
2098   double bounds[6];
2099   getMinMaxPerComponent(bounds);
2100   switch(nbOfCompo)
2101   {
2102     case 3:
2103       {
2104         double xDelta(fabs(bounds[1]-bounds[0])),yDelta(fabs(bounds[3]-bounds[2])),zDelta(fabs(bounds[5]-bounds[4]));
2105         double delta=std::max(xDelta,yDelta); delta=std::max(delta,zDelta);
2106         double characSize=pow((delta*delta*delta)/((double)thisNbOfTuples),1./3.);
2107         BBTreePts<3,int> myTree(begin(),0,0,getNumberOfTuples(),characSize*1e-12);
2108         FindClosestTupleIdAlg<3>(myTree,3.*characSize*characSize,other->begin(),nbOfTuples,begin(),thisNbOfTuples,ret->getPointer());
2109         break;
2110       }
2111     case 2:
2112       {
2113         double xDelta(fabs(bounds[1]-bounds[0])),yDelta(fabs(bounds[3]-bounds[2]));
2114         double delta=std::max(xDelta,yDelta);
2115         double characSize=sqrt(delta/(double)thisNbOfTuples);
2116         BBTreePts<2,int> myTree(begin(),0,0,getNumberOfTuples(),characSize*1e-12);
2117         FindClosestTupleIdAlg<2>(myTree,2.*characSize*characSize,other->begin(),nbOfTuples,begin(),thisNbOfTuples,ret->getPointer());
2118         break;
2119       }
2120     case 1:
2121       {
2122         double characSize=fabs(bounds[1]-bounds[0])/thisNbOfTuples;
2123         BBTreePts<1,int> myTree(begin(),0,0,getNumberOfTuples(),characSize*1e-12);
2124         FindClosestTupleIdAlg<1>(myTree,1.*characSize*characSize,other->begin(),nbOfTuples,begin(),thisNbOfTuples,ret->getPointer());
2125         break;
2126       }
2127     default:
2128       throw INTERP_KERNEL::Exception("Unexpected spacedim of coords for findClosestTupleId. Must be 1, 2 or 3.");
2129   }
2130   return ret.retn();
2131 }
2132
2133 /*!
2134  * This method expects that \a this and \a otherBBoxFrmt arrays are bounding box arrays ( as the output of MEDCouplingPointSet::getBoundingBoxForBBTree method ).
2135  * 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
2136  * how many bounding boxes in \a otherBBoxFrmt.
2137  * So, this method expects that \a this and \a otherBBoxFrmt have the same number of components.
2138  *
2139  * \param [in] otherBBoxFrmt - It is an array .
2140  * \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.
2141  * \sa MEDCouplingPointSet::getBoundingBoxForBBTree
2142  * \throw If \a this and \a otherBBoxFrmt have not the same number of components.
2143  * \throw If \a this and \a otherBBoxFrmt number of components is not even (BBox format).
2144  */
2145 DataArrayInt *DataArrayDouble::computeNbOfInteractionsWith(const DataArrayDouble *otherBBoxFrmt, double eps) const
2146 {
2147   if(!otherBBoxFrmt)
2148     throw INTERP_KERNEL::Exception("DataArrayDouble::computeNbOfInteractionsWith : input array is NULL !");
2149   if(!isAllocated() || !otherBBoxFrmt->isAllocated())
2150     throw INTERP_KERNEL::Exception("DataArrayDouble::computeNbOfInteractionsWith : this and input array must be allocated !");
2151   int nbOfComp(getNumberOfComponents()),nbOfTuples(getNumberOfTuples());
2152   if(nbOfComp!=otherBBoxFrmt->getNumberOfComponents())
2153     {
2154       std::ostringstream oss; oss << "DataArrayDouble::computeNbOfInteractionsWith : this number of components (" << nbOfComp << ") must be equal to the number of components of input array (" << otherBBoxFrmt->getNumberOfComponents() << ") !";
2155       throw INTERP_KERNEL::Exception(oss.str().c_str());
2156     }
2157   if(nbOfComp%2!=0)
2158     {
2159       std::ostringstream oss; oss << "DataArrayDouble::computeNbOfInteractionsWith : Number of components (" << nbOfComp << ") is not even ! It should be to be compatible with bbox format !";
2160       throw INTERP_KERNEL::Exception(oss.str().c_str());
2161     }
2162   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(nbOfTuples,1);
2163   const double *thisBBPtr(begin());
2164   int *retPtr(ret->getPointer());
2165   switch(nbOfComp/2)
2166   {
2167     case 3:
2168       {
2169         BBTree<3,int> bbt(otherBBoxFrmt->begin(),0,0,otherBBoxFrmt->getNumberOfTuples(),eps);
2170         for(int i=0;i<nbOfTuples;i++,retPtr++,thisBBPtr+=nbOfComp)
2171           *retPtr=bbt.getNbOfIntersectingElems(thisBBPtr);
2172         break;
2173       }
2174     case 2:
2175       {
2176         BBTree<2,int> bbt(otherBBoxFrmt->begin(),0,0,otherBBoxFrmt->getNumberOfTuples(),eps);
2177         for(int i=0;i<nbOfTuples;i++,retPtr++,thisBBPtr+=nbOfComp)
2178           *retPtr=bbt.getNbOfIntersectingElems(thisBBPtr);
2179         break;
2180       }
2181     case 1:
2182       {
2183         BBTree<1,int> bbt(otherBBoxFrmt->begin(),0,0,otherBBoxFrmt->getNumberOfTuples(),eps);
2184         for(int i=0;i<nbOfTuples;i++,retPtr++,thisBBPtr+=nbOfComp)
2185           *retPtr=bbt.getNbOfIntersectingElems(thisBBPtr);
2186         break;
2187       }
2188     default:
2189       throw INTERP_KERNEL::Exception("DataArrayDouble::computeNbOfInteractionsWith : space dimension supported are [1,2,3] !");
2190   }
2191
2192   return ret.retn();
2193 }
2194
2195 /*!
2196  * Returns a copy of \a this array by excluding coincident tuples. Each tuple is
2197  * considered as coordinates of a point in getNumberOfComponents()-dimensional
2198  * space. The distance between tuples is computed using norm2. If several tuples are
2199  * not far each from other than \a prec, only one of them remains in the result
2200  * array. The order of tuples in the result array is same as in \a this one except
2201  * that coincident tuples are excluded.
2202  *  \param [in] prec - minimal absolute distance between two tuples at which they are
2203  *              considered not coincident.
2204  *  \param [in] limitTupleId - limit tuple id. If all tuples within a group of coincident
2205  *              tuples have id strictly lower than \a limitTupleId then they are not excluded.
2206  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
2207  *          is to delete using decrRef() as it is no more needed.
2208  *  \throw If \a this is not allocated.
2209  *  \throw If the number of components is not in [1,2,3,4].
2210  *
2211  *  \if ENABLE_EXAMPLES
2212  *  \ref py_mcdataarraydouble_getdifferentvalues "Here is a Python example".
2213  *  \endif
2214  */
2215 DataArrayDouble *DataArrayDouble::getDifferentValues(double prec, int limitTupleId) const
2216 {
2217   checkAllocated();
2218   DataArrayInt *c0=0,*cI0=0;
2219   findCommonTuples(prec,limitTupleId,c0,cI0);
2220   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> c(c0),cI(cI0);
2221   int newNbOfTuples=-1;
2222   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> o2n=DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2(getNumberOfTuples(),c0->begin(),cI0->begin(),cI0->end(),newNbOfTuples);
2223   return renumberAndReduce(o2n->getConstPointer(),newNbOfTuples);
2224 }
2225
2226 /*!
2227  * Copy all components in a specified order from another DataArrayDouble.
2228  * Both numerical and textual data is copied. The number of tuples in \a this and
2229  * the other array can be different.
2230  *  \param [in] a - the array to copy data from.
2231  *  \param [in] compoIds - sequence of zero based indices of components, data of which is
2232  *              to be copied.
2233  *  \throw If \a a is NULL.
2234  *  \throw If \a compoIds.size() != \a a->getNumberOfComponents().
2235  *  \throw If \a compoIds[i] < 0 or \a compoIds[i] > \a this->getNumberOfComponents().
2236  *
2237  *  \if ENABLE_EXAMPLES
2238  *  \ref py_mcdataarraydouble_setselectedcomponents "Here is a Python example".
2239  *  \endif
2240  */
2241 void DataArrayDouble::setSelectedComponents(const DataArrayDouble *a, const std::vector<int>& compoIds)
2242 {
2243   if(!a)
2244     throw INTERP_KERNEL::Exception("DataArrayDouble::setSelectedComponents : input DataArrayDouble is NULL !");
2245   checkAllocated();
2246   copyPartOfStringInfoFrom2(compoIds,*a);
2247   std::size_t partOfCompoSz=compoIds.size();
2248   int nbOfCompo=getNumberOfComponents();
2249   int nbOfTuples=std::min(getNumberOfTuples(),a->getNumberOfTuples());
2250   const double *ac=a->getConstPointer();
2251   double *nc=getPointer();
2252   for(int i=0;i<nbOfTuples;i++)
2253     for(std::size_t j=0;j<partOfCompoSz;j++,ac++)
2254       nc[nbOfCompo*i+compoIds[j]]=*ac;
2255 }
2256
2257 /*!
2258  * Copy all values from another DataArrayDouble into specified tuples and components
2259  * of \a this array. Textual data is not copied.
2260  * The tree parameters defining set of indices of tuples and components are similar to
2261  * the tree parameters of the Python function \c range(\c start,\c stop,\c step).
2262  *  \param [in] a - the array to copy values from.
2263  *  \param [in] bgTuples - index of the first tuple of \a this array to assign values to.
2264  *  \param [in] endTuples - index of the tuple before which the tuples to assign to
2265  *              are located.
2266  *  \param [in] stepTuples - index increment to get index of the next tuple to assign to.
2267  *  \param [in] bgComp - index of the first component of \a this array to assign values to.
2268  *  \param [in] endComp - index of the component before which the components to assign
2269  *              to are located.
2270  *  \param [in] stepComp - index increment to get index of the next component to assign to.
2271  *  \param [in] strictCompoCompare - if \a true (by default), then \a a->getNumberOfComponents() 
2272  *              must be equal to the number of columns to assign to, else an
2273  *              exception is thrown; if \a false, then it is only required that \a
2274  *              a->getNbOfElems() equals to number of values to assign to (this condition
2275  *              must be respected even if \a strictCompoCompare is \a true). The number of 
2276  *              values to assign to is given by following Python expression:
2277  *              \a nbTargetValues = 
2278  *              \c len(\c range(\a bgTuples,\a endTuples,\a stepTuples)) *
2279  *              \c len(\c range(\a bgComp,\a endComp,\a stepComp)).
2280  *  \throw If \a a is NULL.
2281  *  \throw If \a a is not allocated.
2282  *  \throw If \a this is not allocated.
2283  *  \throw If parameters specifying tuples and components to assign to do not give a
2284  *            non-empty range of increasing indices.
2285  *  \throw If \a a->getNbOfElems() != \a nbTargetValues.
2286  *  \throw If \a strictCompoCompare == \a true && \a a->getNumberOfComponents() !=
2287  *            \c len(\c range(\a bgComp,\a endComp,\a stepComp)).
2288  *
2289  *  \if ENABLE_EXAMPLES
2290  *  \ref py_mcdataarraydouble_setpartofvalues1 "Here is a Python example".
2291  *  \endif
2292  */
2293 void DataArrayDouble::setPartOfValues1(const DataArrayDouble *a, int bgTuples, int endTuples, int stepTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare)
2294 {
2295   if(!a)
2296     throw INTERP_KERNEL::Exception("DataArrayDouble::setPartOfValues1 : input DataArrayDouble is NULL !");
2297   const char msg[]="DataArrayDouble::setPartOfValues1";
2298   checkAllocated();
2299   a->checkAllocated();
2300   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
2301   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
2302   int nbComp=getNumberOfComponents();
2303   int nbOfTuples=getNumberOfTuples();
2304   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
2305   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
2306   bool assignTech=true;
2307   if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
2308     {
2309       if(strictCompoCompare)
2310         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
2311     }
2312   else
2313     {
2314       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
2315       assignTech=false;
2316     }
2317   const double *srcPt=a->getConstPointer();
2318   double *pt=getPointer()+bgTuples*nbComp+bgComp;
2319   if(assignTech)
2320     {
2321       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
2322         for(int j=0;j<newNbOfComp;j++,srcPt++)
2323           pt[j*stepComp]=*srcPt;
2324     }
2325   else
2326     {
2327       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
2328         {
2329           const double *srcPt2=srcPt;
2330           for(int j=0;j<newNbOfComp;j++,srcPt2++)
2331             pt[j*stepComp]=*srcPt2;
2332         }
2333     }
2334 }
2335
2336 /*!
2337  * Assign a given value to values at specified tuples and components of \a this array.
2338  * The tree parameters defining set of indices of tuples and components are similar to
2339  * the tree parameters of the Python function \c range(\c start,\c stop,\c step)..
2340  *  \param [in] a - the value to assign.
2341  *  \param [in] bgTuples - index of the first tuple of \a this array to assign to.
2342  *  \param [in] endTuples - index of the tuple before which the tuples to assign to
2343  *              are located.
2344  *  \param [in] stepTuples - index increment to get index of the next tuple to assign to.
2345  *  \param [in] bgComp - index of the first component of \a this array to assign to.
2346  *  \param [in] endComp - index of the component before which the components to assign
2347  *              to are located.
2348  *  \param [in] stepComp - index increment to get index of the next component to assign to.
2349  *  \throw If \a this is not allocated.
2350  *  \throw If parameters specifying tuples and components to assign to, do not give a
2351  *            non-empty range of increasing indices or indices are out of a valid range
2352  *            for \this array.
2353  *
2354  *  \if ENABLE_EXAMPLES
2355  *  \ref py_mcdataarraydouble_setpartofvaluessimple1 "Here is a Python example".
2356  *  \endif
2357  */
2358 void DataArrayDouble::setPartOfValuesSimple1(double a, int bgTuples, int endTuples, int stepTuples, int bgComp, int endComp, int stepComp)
2359 {
2360   const char msg[]="DataArrayDouble::setPartOfValuesSimple1";
2361   checkAllocated();
2362   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
2363   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
2364   int nbComp=getNumberOfComponents();
2365   int nbOfTuples=getNumberOfTuples();
2366   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
2367   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
2368   double *pt=getPointer()+bgTuples*nbComp+bgComp;
2369   for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
2370     for(int j=0;j<newNbOfComp;j++)
2371       pt[j*stepComp]=a;
2372 }
2373
2374 /*!
2375  * Copy all values from another DataArrayDouble (\a a) into specified tuples and 
2376  * components of \a this array. Textual data is not copied.
2377  * The tuples and components to assign to are defined by C arrays of indices.
2378  * There are two *modes of usage*:
2379  * - If \a a->getNbOfElems() equals to number of values to assign to, then every value
2380  *   of \a a is assigned to its own location within \a this array. 
2381  * - If \a a includes one tuple, then all values of \a a are assigned to the specified
2382  *   components of every specified tuple of \a this array. In this mode it is required
2383  *   that \a a->getNumberOfComponents() equals to the number of specified components.
2384  *
2385  *  \param [in] a - the array to copy values from.
2386  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
2387  *              assign values of \a a to.
2388  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
2389  *              pointer to a tuple index <em>(pi)</em> varies as this: 
2390  *              \a bgTuples <= \a pi < \a endTuples.
2391  *  \param [in] bgComp - pointer to an array of component indices of \a this array to
2392  *              assign values of \a a to.
2393  *  \param [in] endComp - specifies the end of the array \a bgTuples, so that
2394  *              pointer to a component index <em>(pi)</em> varies as this: 
2395  *              \a bgComp <= \a pi < \a endComp.
2396  *  \param [in] strictCompoCompare - this parameter is checked only if the
2397  *               *mode of usage* is the first; if it is \a true (default), 
2398  *               then \a a->getNumberOfComponents() must be equal 
2399  *               to the number of specified columns, else this is not required.
2400  *  \throw If \a a is NULL.
2401  *  \throw If \a a is not allocated.
2402  *  \throw If \a this is not allocated.
2403  *  \throw If any index of tuple/component given by <em>bgTuples / bgComp</em> is
2404  *         out of a valid range for \a this array.
2405  *  \throw In the first *mode of usage*, if <em>strictCompoCompare == true </em> and
2406  *         if <em> a->getNumberOfComponents() != (endComp - bgComp) </em>.
2407  *  \throw In the second *mode of usage*, if \a a->getNumberOfTuples() != 1 or
2408  *         <em> a->getNumberOfComponents() != (endComp - bgComp)</em>.
2409  *
2410  *  \if ENABLE_EXAMPLES
2411  *  \ref py_mcdataarraydouble_setpartofvalues2 "Here is a Python example".
2412  *  \endif
2413  */
2414 void DataArrayDouble::setPartOfValues2(const DataArrayDouble *a, const int *bgTuples, const int *endTuples, const int *bgComp, const int *endComp, bool strictCompoCompare)
2415 {
2416   if(!a)
2417     throw INTERP_KERNEL::Exception("DataArrayDouble::setPartOfValues2 : input DataArrayDouble is NULL !");
2418   const char msg[]="DataArrayDouble::setPartOfValues2";
2419   checkAllocated();
2420   a->checkAllocated();
2421   int nbComp=getNumberOfComponents();
2422   int nbOfTuples=getNumberOfTuples();
2423   for(const int *z=bgComp;z!=endComp;z++)
2424     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
2425   int newNbOfTuples=(int)std::distance(bgTuples,endTuples);
2426   int newNbOfComp=(int)std::distance(bgComp,endComp);
2427   bool assignTech=true;
2428   if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
2429     {
2430       if(strictCompoCompare)
2431         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
2432     }
2433   else
2434     {
2435       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
2436       assignTech=false;
2437     }
2438   double *pt=getPointer();
2439   const double *srcPt=a->getConstPointer();
2440   if(assignTech)
2441     {    
2442       for(const int *w=bgTuples;w!=endTuples;w++)
2443         {
2444           DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
2445           for(const int *z=bgComp;z!=endComp;z++,srcPt++)
2446             {    
2447               pt[(std::size_t)(*w)*nbComp+(*z)]=*srcPt;
2448             }
2449         }
2450     }
2451   else
2452     {
2453       for(const int *w=bgTuples;w!=endTuples;w++)
2454         {
2455           const double *srcPt2=srcPt;
2456           DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
2457           for(const int *z=bgComp;z!=endComp;z++,srcPt2++)
2458             {    
2459               pt[(std::size_t)(*w)*nbComp+(*z)]=*srcPt2;
2460             }
2461         }
2462     }
2463 }
2464
2465 /*!
2466  * Assign a given value to values at specified tuples and components of \a this array.
2467  * The tuples and components to assign to are defined by C arrays of indices.
2468  *  \param [in] a - the value to assign.
2469  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
2470  *              assign \a a to.
2471  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
2472  *              pointer to a tuple index (\a pi) varies as this: 
2473  *              \a bgTuples <= \a pi < \a endTuples.
2474  *  \param [in] bgComp - pointer to an array of component indices of \a this array to
2475  *              assign \a a to.
2476  *  \param [in] endComp - specifies the end of the array \a bgTuples, so that
2477  *              pointer to a component index (\a pi) varies as this: 
2478  *              \a bgComp <= \a pi < \a endComp.
2479  *  \throw If \a this is not allocated.
2480  *  \throw If any index of tuple/component given by <em>bgTuples / bgComp</em> is
2481  *         out of a valid range for \a this array.
2482  *
2483  *  \if ENABLE_EXAMPLES
2484  *  \ref py_mcdataarraydouble_setpartofvaluessimple2 "Here is a Python example".
2485  *  \endif
2486  */
2487 void DataArrayDouble::setPartOfValuesSimple2(double a, const int *bgTuples, const int *endTuples, const int *bgComp, const int *endComp)
2488 {
2489   checkAllocated();
2490   int nbComp=getNumberOfComponents();
2491   int nbOfTuples=getNumberOfTuples();
2492   for(const int *z=bgComp;z!=endComp;z++)
2493     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
2494   double *pt=getPointer();
2495   for(const int *w=bgTuples;w!=endTuples;w++)
2496     for(const int *z=bgComp;z!=endComp;z++)
2497       {
2498         DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
2499         pt[(std::size_t)(*w)*nbComp+(*z)]=a;
2500       }
2501 }
2502
2503 /*!
2504  * Copy all values from another DataArrayDouble (\a a) into specified tuples and 
2505  * components of \a this array. Textual data is not copied.
2506  * The tuples to assign to are defined by a C array of indices.
2507  * The components to assign to are defined by three values similar to parameters of
2508  * the Python function \c range(\c start,\c stop,\c step).
2509  * There are two *modes of usage*:
2510  * - If \a a->getNbOfElems() equals to number of values to assign to, then every value
2511  *   of \a a is assigned to its own location within \a this array. 
2512  * - If \a a includes one tuple, then all values of \a a are assigned to the specified
2513  *   components of every specified tuple of \a this array. In this mode it is required
2514  *   that \a a->getNumberOfComponents() equals to the number of specified components.
2515  *
2516  *  \param [in] a - the array to copy values from.
2517  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
2518  *              assign values of \a a to.
2519  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
2520  *              pointer to a tuple index <em>(pi)</em> varies as this: 
2521  *              \a bgTuples <= \a pi < \a endTuples.
2522  *  \param [in] bgComp - index of the first component of \a this array to assign to.
2523  *  \param [in] endComp - index of the component before which the components to assign
2524  *              to are located.
2525  *  \param [in] stepComp - index increment to get index of the next component to assign to.
2526  *  \param [in] strictCompoCompare - this parameter is checked only in the first
2527  *               *mode of usage*; if \a strictCompoCompare is \a true (default), 
2528  *               then \a a->getNumberOfComponents() must be equal 
2529  *               to the number of specified columns, else this is not required.
2530  *  \throw If \a a is NULL.
2531  *  \throw If \a a is not allocated.
2532  *  \throw If \a this is not allocated.
2533  *  \throw If any index of tuple given by \a bgTuples is out of a valid range for 
2534  *         \a this array.
2535  *  \throw In the first *mode of usage*, if <em>strictCompoCompare == true </em> and
2536  *         if <em> a->getNumberOfComponents()</em> is unequal to the number of components
2537  *         defined by <em>(bgComp,endComp,stepComp)</em>.
2538  *  \throw In the second *mode of usage*, if \a a->getNumberOfTuples() != 1 or
2539  *         <em> a->getNumberOfComponents()</em> is unequal to the number of components
2540  *         defined by <em>(bgComp,endComp,stepComp)</em>.
2541  *  \throw If parameters specifying components to assign to, do not give a
2542  *            non-empty range of increasing indices or indices are out of a valid range
2543  *            for \this array.
2544  *
2545  *  \if ENABLE_EXAMPLES
2546  *  \ref py_mcdataarraydouble_setpartofvalues3 "Here is a Python example".
2547  *  \endif
2548  */
2549 void DataArrayDouble::setPartOfValues3(const DataArrayDouble *a, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare)
2550 {
2551   if(!a)
2552     throw INTERP_KERNEL::Exception("DataArrayDouble::setPartOfValues3 : input DataArrayDouble is NULL !");
2553   const char msg[]="DataArrayDouble::setPartOfValues3";
2554   checkAllocated();
2555   a->checkAllocated();
2556   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
2557   int nbComp=getNumberOfComponents();
2558   int nbOfTuples=getNumberOfTuples();
2559   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
2560   int newNbOfTuples=(int)std::distance(bgTuples,endTuples);
2561   bool assignTech=true;
2562   if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
2563     {
2564       if(strictCompoCompare)
2565         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
2566     }
2567   else
2568     {
2569       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
2570       assignTech=false;
2571     }
2572   double *pt=getPointer()+bgComp;
2573   const double *srcPt=a->getConstPointer();
2574   if(assignTech)
2575     {
2576       for(const int *w=bgTuples;w!=endTuples;w++)
2577         for(int j=0;j<newNbOfComp;j++,srcPt++)
2578           {
2579             DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
2580             pt[(std::size_t)(*w)*nbComp+j*stepComp]=*srcPt;
2581           }
2582     }
2583   else
2584     {
2585       for(const int *w=bgTuples;w!=endTuples;w++)
2586         {
2587           const double *srcPt2=srcPt;
2588           for(int j=0;j<newNbOfComp;j++,srcPt2++)
2589             {
2590               DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
2591               pt[(std::size_t)(*w)*nbComp+j*stepComp]=*srcPt2;
2592             }
2593         }
2594     }
2595 }
2596
2597 /*!
2598  * Assign a given value to values at specified tuples and components of \a this array.
2599  * The tuples to assign to are defined by a C array of indices.
2600  * The components to assign to are defined by three values similar to parameters of
2601  * the Python function \c range(\c start,\c stop,\c step).
2602  *  \param [in] a - the value to assign.
2603  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
2604  *              assign \a a to.
2605  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
2606  *              pointer to a tuple index <em>(pi)</em> varies as this: 
2607  *              \a bgTuples <= \a pi < \a endTuples.
2608  *  \param [in] bgComp - index of the first component of \a this array to assign to.
2609  *  \param [in] endComp - index of the component before which the components to assign
2610  *              to are located.
2611  *  \param [in] stepComp - index increment to get index of the next component to assign to.
2612  *  \throw If \a this is not allocated.
2613  *  \throw If any index of tuple given by \a bgTuples is out of a valid range for 
2614  *         \a this array.
2615  *  \throw If parameters specifying components to assign to, do not give a
2616  *            non-empty range of increasing indices or indices are out of a valid range
2617  *            for \this array.
2618  *
2619  *  \if ENABLE_EXAMPLES
2620  *  \ref py_mcdataarraydouble_setpartofvaluessimple3 "Here is a Python example".
2621  *  \endif
2622  */
2623 void DataArrayDouble::setPartOfValuesSimple3(double a, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp)
2624 {
2625   const char msg[]="DataArrayDouble::setPartOfValuesSimple3";
2626   checkAllocated();
2627   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
2628   int nbComp=getNumberOfComponents();
2629   int nbOfTuples=getNumberOfTuples();
2630   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
2631   double *pt=getPointer()+bgComp;
2632   for(const int *w=bgTuples;w!=endTuples;w++)
2633     for(int j=0;j<newNbOfComp;j++)
2634       {
2635         DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
2636         pt[(std::size_t)(*w)*nbComp+j*stepComp]=a;
2637       }
2638 }
2639
2640 /*!
2641  * Copy all values from another DataArrayDouble into specified tuples and components
2642  * of \a this array. Textual data is not copied.
2643  * The tree parameters defining set of indices of tuples and components are similar to
2644  * the tree parameters of the Python function \c range(\c start,\c stop,\c step).
2645  *  \param [in] a - the array to copy values from.
2646  *  \param [in] bgTuples - index of the first tuple of \a this array to assign values to.
2647  *  \param [in] endTuples - index of the tuple before which the tuples to assign to
2648  *              are located.
2649  *  \param [in] stepTuples - index increment to get index of the next tuple to assign to.
2650  *  \param [in] bgComp - pointer to an array of component indices of \a this array to
2651  *              assign \a a to.
2652  *  \param [in] endComp - specifies the end of the array \a bgTuples, so that
2653  *              pointer to a component index (\a pi) varies as this: 
2654  *              \a bgComp <= \a pi < \a endComp.
2655  *  \param [in] strictCompoCompare - if \a true (by default), then \a a->getNumberOfComponents() 
2656  *              must be equal to the number of columns to assign to, else an
2657  *              exception is thrown; if \a false, then it is only required that \a
2658  *              a->getNbOfElems() equals to number of values to assign to (this condition
2659  *              must be respected even if \a strictCompoCompare is \a true). The number of 
2660  *              values to assign to is given by following Python expression:
2661  *              \a nbTargetValues = 
2662  *              \c len(\c range(\a bgTuples,\a endTuples,\a stepTuples)) *
2663  *              \c len(\c range(\a bgComp,\a endComp,\a stepComp)).
2664  *  \throw If \a a is NULL.
2665  *  \throw If \a a is not allocated.
2666  *  \throw If \a this is not allocated.
2667  *  \throw If parameters specifying tuples and components to assign to do not give a
2668  *            non-empty range of increasing indices.
2669  *  \throw If \a a->getNbOfElems() != \a nbTargetValues.
2670  *  \throw If \a strictCompoCompare == \a true && \a a->getNumberOfComponents() !=
2671  *            \c len(\c range(\a bgComp,\a endComp,\a stepComp)).
2672  *
2673  */
2674 void DataArrayDouble::setPartOfValues4(const DataArrayDouble *a, int bgTuples, int endTuples, int stepTuples, const int *bgComp, const int *endComp, bool strictCompoCompare)
2675 {
2676   if(!a)
2677     throw INTERP_KERNEL::Exception("DataArrayDouble::setPartOfValues4 : input DataArrayDouble is NULL !");
2678   const char msg[]="DataArrayDouble::setPartOfValues4";
2679   checkAllocated();
2680   a->checkAllocated();
2681   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
2682   int newNbOfComp=(int)std::distance(bgComp,endComp);
2683   int nbComp=getNumberOfComponents();
2684   for(const int *z=bgComp;z!=endComp;z++)
2685     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
2686   int nbOfTuples=getNumberOfTuples();
2687   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
2688   bool assignTech=true;
2689   if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
2690     {
2691       if(strictCompoCompare)
2692         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
2693     }
2694   else
2695     {
2696       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
2697       assignTech=false;
2698     }
2699   const double *srcPt=a->getConstPointer();
2700   double *pt=getPointer()+bgTuples*nbComp;
2701   if(assignTech)
2702     {
2703       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
2704         for(const int *z=bgComp;z!=endComp;z++,srcPt++)
2705           pt[*z]=*srcPt;
2706     }
2707   else
2708     {
2709       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
2710         {
2711           const double *srcPt2=srcPt;
2712           for(const int *z=bgComp;z!=endComp;z++,srcPt2++)
2713             pt[*z]=*srcPt2;
2714         }
2715     }
2716 }
2717
2718 void DataArrayDouble::setPartOfValuesSimple4(double a, int bgTuples, int endTuples, int stepTuples, const int *bgComp, const int *endComp)
2719 {
2720   const char msg[]="DataArrayDouble::setPartOfValuesSimple4";
2721   checkAllocated();
2722   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
2723   int nbComp=getNumberOfComponents();
2724   for(const int *z=bgComp;z!=endComp;z++)
2725     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
2726   int nbOfTuples=getNumberOfTuples();
2727   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
2728   double *pt=getPointer()+bgTuples*nbComp;
2729   for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
2730     for(const int *z=bgComp;z!=endComp;z++)
2731       pt[*z]=a;
2732 }
2733
2734 /*!
2735  * Copy some tuples from another DataArrayDouble into specified tuples
2736  * of \a this array. Textual data is not copied. Both arrays must have equal number of
2737  * components.
2738  * Both the tuples to assign and the tuples to assign to are defined by a DataArrayInt.
2739  * All components of selected tuples are copied.
2740  *  \param [in] a - the array to copy values from.
2741  *  \param [in] tuplesSelec - the array specifying both source tuples of \a a and
2742  *              target tuples of \a this. \a tuplesSelec has two components, and the
2743  *              first component specifies index of the source tuple and the second
2744  *              one specifies index of the target tuple.
2745  *  \throw If \a this is not allocated.
2746  *  \throw If \a a is NULL.
2747  *  \throw If \a a is not allocated.
2748  *  \throw If \a tuplesSelec is NULL.
2749  *  \throw If \a tuplesSelec is not allocated.
2750  *  \throw If <em>this->getNumberOfComponents() != a->getNumberOfComponents()</em>.
2751  *  \throw If \a tuplesSelec->getNumberOfComponents() != 2.
2752  *  \throw If any tuple index given by \a tuplesSelec is out of a valid range for 
2753  *         the corresponding (\a this or \a a) array.
2754  */
2755 void DataArrayDouble::setPartOfValuesAdv(const DataArrayDouble *a, const DataArrayInt *tuplesSelec)
2756 {
2757   if(!a || !tuplesSelec)
2758     throw INTERP_KERNEL::Exception("DataArrayDouble::setPartOfValuesAdv : input DataArrayDouble is NULL !");
2759   checkAllocated();
2760   a->checkAllocated();
2761   tuplesSelec->checkAllocated();
2762   int nbOfComp=getNumberOfComponents();
2763   if(nbOfComp!=a->getNumberOfComponents())
2764     throw INTERP_KERNEL::Exception("DataArrayDouble::setPartOfValuesAdv : This and a do not have the same number of components !");
2765   if(tuplesSelec->getNumberOfComponents()!=2)
2766     throw INTERP_KERNEL::Exception("DataArrayDouble::setPartOfValuesAdv : Expecting to have a tuple selector DataArrayInt instance with exactly 2 components !");
2767   int thisNt=getNumberOfTuples();
2768   int aNt=a->getNumberOfTuples();
2769   double *valsToSet=getPointer();
2770   const double *valsSrc=a->getConstPointer();
2771   for(const int *tuple=tuplesSelec->begin();tuple!=tuplesSelec->end();tuple+=2)
2772     {
2773       if(tuple[1]>=0 && tuple[1]<aNt)
2774         {
2775           if(tuple[0]>=0 && tuple[0]<thisNt)
2776             std::copy(valsSrc+nbOfComp*tuple[1],valsSrc+nbOfComp*(tuple[1]+1),valsToSet+nbOfComp*tuple[0]);
2777           else
2778             {
2779               std::ostringstream oss; oss << "DataArrayDouble::setPartOfValuesAdv : Tuple #" << std::distance(tuplesSelec->begin(),tuple)/2;
2780               oss << " of 'tuplesSelec' request of tuple id #" << tuple[0] << " in 'this' ! It should be in [0," << thisNt << ") !";
2781               throw INTERP_KERNEL::Exception(oss.str().c_str());
2782             }
2783         }
2784       else
2785         {
2786           std::ostringstream oss; oss << "DataArrayDouble::setPartOfValuesAdv : Tuple #" << std::distance(tuplesSelec->begin(),tuple)/2;
2787           oss << " of 'tuplesSelec' request of tuple id #" << tuple[1] << " in 'a' ! It should be in [0," << aNt << ") !";
2788           throw INTERP_KERNEL::Exception(oss.str().c_str());
2789         }
2790     }
2791 }
2792
2793 /*!
2794  * Copy some tuples from another DataArrayDouble (\a aBase) into contiguous tuples
2795  * of \a this array. Textual data is not copied. Both arrays must have equal number of
2796  * components.
2797  * The tuples to assign to are defined by index of the first tuple, and
2798  * their number is defined by \a tuplesSelec->getNumberOfTuples().
2799  * The tuples to copy are defined by values of a DataArrayInt.
2800  * All components of selected tuples are copied.
2801  *  \param [in] tupleIdStart - index of the first tuple of \a this array to assign
2802  *              values to.
2803  *  \param [in] aBase - the array to copy values from.
2804  *  \param [in] tuplesSelec - the array specifying tuples of \a a to copy.
2805  *  \throw If \a this is not allocated.
2806  *  \throw If \a aBase is NULL.
2807  *  \throw If \a aBase is not allocated.
2808  *  \throw If \a tuplesSelec is NULL.
2809  *  \throw If \a tuplesSelec is not allocated.
2810  *  \throw If <em>this->getNumberOfComponents() != aBase->getNumberOfComponents()</em>.
2811  *  \throw If \a tuplesSelec->getNumberOfComponents() != 1.
2812  *  \throw If <em>tupleIdStart + tuplesSelec->getNumberOfTuples() > this->getNumberOfTuples().</em>
2813  *  \throw If any tuple index given by \a tuplesSelec is out of a valid range for 
2814  *         \a aBase array.
2815  */
2816 void DataArrayDouble::setContigPartOfSelectedValues(int tupleIdStart, const DataArray *aBase, const DataArrayInt *tuplesSelec)
2817 {
2818   if(!aBase || !tuplesSelec)
2819     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues : input DataArray is NULL !");
2820   const DataArrayDouble *a=dynamic_cast<const DataArrayDouble *>(aBase);
2821   if(!a)
2822     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues : input DataArray aBase is not a DataArrayDouble !");
2823   checkAllocated();
2824   a->checkAllocated();
2825   tuplesSelec->checkAllocated();
2826   int nbOfComp=getNumberOfComponents();
2827   if(nbOfComp!=a->getNumberOfComponents())
2828     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues : This and a do not have the same number of components !");
2829   if(tuplesSelec->getNumberOfComponents()!=1)
2830     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues : Expecting to have a tuple selector DataArrayInt instance with exactly 1 component !");
2831   int thisNt=getNumberOfTuples();
2832   int aNt=a->getNumberOfTuples();
2833   int nbOfTupleToWrite=tuplesSelec->getNumberOfTuples();
2834   double *valsToSet=getPointer()+tupleIdStart*nbOfComp;
2835   if(tupleIdStart+nbOfTupleToWrite>thisNt)
2836     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues : invalid number range of values to write !");
2837   const double *valsSrc=a->getConstPointer();
2838   for(const int *tuple=tuplesSelec->begin();tuple!=tuplesSelec->end();tuple++,valsToSet+=nbOfComp)
2839     {
2840       if(*tuple>=0 && *tuple<aNt)
2841         {
2842           std::copy(valsSrc+nbOfComp*(*tuple),valsSrc+nbOfComp*(*tuple+1),valsToSet);
2843         }
2844       else
2845         {
2846           std::ostringstream oss; oss << "DataArrayDouble::setContigPartOfSelectedValues : Tuple #" << std::distance(tuplesSelec->begin(),tuple);
2847           oss << " of 'tuplesSelec' request of tuple id #" << *tuple << " in 'a' ! It should be in [0," << aNt << ") !";
2848           throw INTERP_KERNEL::Exception(oss.str().c_str());
2849         }
2850     }
2851 }
2852
2853 /*!
2854  * Copy some tuples from another DataArrayDouble (\a aBase) into contiguous tuples
2855  * of \a this array. Textual data is not copied. Both arrays must have equal number of
2856  * components.
2857  * The tuples to copy are defined by three values similar to parameters of
2858  * the Python function \c range(\c start,\c stop,\c step).
2859  * The tuples to assign to are defined by index of the first tuple, and
2860  * their number is defined by number of tuples to copy.
2861  * All components of selected tuples are copied.
2862  *  \param [in] tupleIdStart - index of the first tuple of \a this array to assign
2863  *              values to.
2864  *  \param [in] aBase - the array to copy values from.
2865  *  \param [in] bg - index of the first tuple to copy of the array \a aBase.
2866  *  \param [in] end2 - index of the tuple of \a aBase before which the tuples to copy
2867  *              are located.
2868  *  \param [in] step - index increment to get index of the next tuple to copy.
2869  *  \throw If \a this is not allocated.
2870  *  \throw If \a aBase is NULL.
2871  *  \throw If \a aBase is not allocated.
2872  *  \throw If <em>this->getNumberOfComponents() != aBase->getNumberOfComponents()</em>.
2873  *  \throw If <em>tupleIdStart + len(range(bg,end2,step)) > this->getNumberOfTuples().</em>
2874  *  \throw If parameters specifying tuples to copy, do not give a
2875  *            non-empty range of increasing indices or indices are out of a valid range
2876  *            for the array \a aBase.
2877  */
2878 void DataArrayDouble::setContigPartOfSelectedValues2(int tupleIdStart, const DataArray *aBase, int bg, int end2, int step)
2879 {
2880   if(!aBase)
2881     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues2 : input DataArray is NULL !");
2882   const DataArrayDouble *a=dynamic_cast<const DataArrayDouble *>(aBase);
2883   if(!a)
2884     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues2 : input DataArray aBase is not a DataArrayDouble !");
2885   checkAllocated();
2886   a->checkAllocated();
2887   int nbOfComp=getNumberOfComponents();
2888   const char msg[]="DataArrayDouble::setContigPartOfSelectedValues2";
2889   int nbOfTupleToWrite=DataArray::GetNumberOfItemGivenBES(bg,end2,step,msg);
2890   if(nbOfComp!=a->getNumberOfComponents())
2891     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues2 : This and a do not have the same number of components !");
2892   int thisNt=getNumberOfTuples();
2893   int aNt=a->getNumberOfTuples();
2894   double *valsToSet=getPointer()+tupleIdStart*nbOfComp;
2895   if(tupleIdStart+nbOfTupleToWrite>thisNt)
2896     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues2 : invalid number range of values to write !");
2897   if(end2>aNt)
2898     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues2 : invalid range of values to read !");
2899   const double *valsSrc=a->getConstPointer()+bg*nbOfComp;
2900   for(int i=0;i<nbOfTupleToWrite;i++,valsToSet+=nbOfComp,valsSrc+=step*nbOfComp)
2901     {
2902       std::copy(valsSrc,valsSrc+nbOfComp,valsToSet);
2903     }
2904 }
2905
2906 /*!
2907  * Returns a value located at specified tuple and component.
2908  * This method is equivalent to DataArrayDouble::getIJ() except that validity of
2909  * parameters is checked. So this method is safe but expensive if used to go through
2910  * all values of \a this.
2911  *  \param [in] tupleId - index of tuple of interest.
2912  *  \param [in] compoId - index of component of interest.
2913  *  \return double - value located by \a tupleId and \a compoId.
2914  *  \throw If \a this is not allocated.
2915  *  \throw If condition <em>( 0 <= tupleId < this->getNumberOfTuples() )</em> is violated.
2916  *  \throw If condition <em>( 0 <= compoId < this->getNumberOfComponents() )</em> is violated.
2917  */
2918 double DataArrayDouble::getIJSafe(int tupleId, int compoId) const
2919 {
2920   checkAllocated();
2921   if(tupleId<0 || tupleId>=getNumberOfTuples())
2922     {
2923       std::ostringstream oss; oss << "DataArrayDouble::getIJSafe : request for tupleId " << tupleId << " should be in [0," << getNumberOfTuples() << ") !";
2924       throw INTERP_KERNEL::Exception(oss.str().c_str());
2925     }
2926   if(compoId<0 || compoId>=getNumberOfComponents())
2927     {
2928       std::ostringstream oss; oss << "DataArrayDouble::getIJSafe : request for compoId " << compoId << " should be in [0," << getNumberOfComponents() << ") !";
2929       throw INTERP_KERNEL::Exception(oss.str().c_str());
2930     }
2931   return _mem[tupleId*_info_on_compo.size()+compoId];
2932 }
2933
2934 /*!
2935  * Returns the first value of \a this. 
2936  *  \return double - the last value of \a this array.
2937  *  \throw If \a this is not allocated.
2938  *  \throw If \a this->getNumberOfComponents() != 1.
2939  *  \throw If \a this->getNumberOfTuples() < 1.
2940  */
2941 double DataArrayDouble::front() const
2942 {
2943   checkAllocated();
2944   if(getNumberOfComponents()!=1)
2945     throw INTERP_KERNEL::Exception("DataArrayDouble::front : number of components not equal to one !");
2946   int nbOfTuples=getNumberOfTuples();
2947   if(nbOfTuples<1)
2948     throw INTERP_KERNEL::Exception("DataArrayDouble::front : number of tuples must be >= 1 !");
2949   return *(getConstPointer());
2950 }
2951
2952 /*!
2953  * Returns the last value of \a this. 
2954  *  \return double - the last value of \a this array.
2955  *  \throw If \a this is not allocated.
2956  *  \throw If \a this->getNumberOfComponents() != 1.
2957  *  \throw If \a this->getNumberOfTuples() < 1.
2958  */
2959 double DataArrayDouble::back() const
2960 {
2961   checkAllocated();
2962   if(getNumberOfComponents()!=1)
2963     throw INTERP_KERNEL::Exception("DataArrayDouble::back : number of components not equal to one !");
2964   int nbOfTuples=getNumberOfTuples();
2965   if(nbOfTuples<1)
2966     throw INTERP_KERNEL::Exception("DataArrayDouble::back : number of tuples must be >= 1 !");
2967   return *(getConstPointer()+nbOfTuples-1);
2968 }
2969
2970 void DataArrayDouble::SetArrayIn(DataArrayDouble *newArray, DataArrayDouble* &arrayToSet)
2971 {
2972   if(newArray!=arrayToSet)
2973     {
2974       if(arrayToSet)
2975         arrayToSet->decrRef();
2976       arrayToSet=newArray;
2977       if(arrayToSet)
2978         arrayToSet->incrRef();
2979     }
2980 }
2981
2982 /*!
2983  * Sets a C array to be used as raw data of \a this. The previously set info
2984  *  of components is retained and re-sized. 
2985  * For more info see \ref MEDCouplingArraySteps1.
2986  *  \param [in] array - the C array to be used as raw data of \a this.
2987  *  \param [in] ownership - if \a true, \a array will be deallocated at destruction of \a this.
2988  *  \param [in] type - specifies how to deallocate \a array. If \a type == ParaMEDMEM::CPP_DEALLOC,
2989  *                     \c delete [] \c array; will be called. If \a type == ParaMEDMEM::C_DEALLOC,
2990  *                     \c free(\c array ) will be called.
2991  *  \param [in] nbOfTuple - new number of tuples in \a this.
2992  *  \param [in] nbOfCompo - new number of components in \a this.
2993  */
2994 void DataArrayDouble::useArray(const double *array, bool ownership, DeallocType type, int nbOfTuple, int nbOfCompo)
2995 {
2996   _info_on_compo.resize(nbOfCompo);
2997   _mem.useArray(array,ownership,type,(std::size_t)nbOfTuple*nbOfCompo);
2998   declareAsNew();
2999 }
3000
3001 void DataArrayDouble::useExternalArrayWithRWAccess(const double *array, int nbOfTuple, int nbOfCompo)
3002 {
3003   _info_on_compo.resize(nbOfCompo);
3004   _mem.useExternalArrayWithRWAccess(array,(std::size_t)nbOfTuple*nbOfCompo);
3005   declareAsNew();
3006 }
3007
3008 /*!
3009  * Checks if 0.0 value is present in \a this array. If it is the case, an exception
3010  * is thrown.
3011  * \throw If zero is found in \a this array.
3012  */
3013 void DataArrayDouble::checkNoNullValues() const
3014 {
3015   const double *tmp=getConstPointer();
3016   std::size_t nbOfElems=getNbOfElems();
3017   const double *where=std::find(tmp,tmp+nbOfElems,0.);
3018   if(where!=tmp+nbOfElems)
3019     throw INTERP_KERNEL::Exception("A value 0.0 have been detected !");
3020 }
3021
3022 /*!
3023  * Computes minimal and maximal value in each component. An output array is filled
3024  * with \c 2 * \a this->getNumberOfComponents() values, so the caller is to allocate
3025  * enough memory before calling this method.
3026  *  \param [out] bounds - array of size at least 2 *\a this->getNumberOfComponents().
3027  *               It is filled as follows:<br>
3028  *               \a bounds[0] = \c min_of_component_0 <br>
3029  *               \a bounds[1] = \c max_of_component_0 <br>
3030  *               \a bounds[2] = \c min_of_component_1 <br>
3031  *               \a bounds[3] = \c max_of_component_1 <br>
3032  *               ...
3033  */
3034 void DataArrayDouble::getMinMaxPerComponent(double *bounds) const
3035 {
3036   checkAllocated();
3037   int dim=getNumberOfComponents();
3038   for (int idim=0; idim<dim; idim++)
3039     {
3040       bounds[idim*2]=std::numeric_limits<double>::max();
3041       bounds[idim*2+1]=-std::numeric_limits<double>::max();
3042     } 
3043   const double *ptr=getConstPointer();
3044   int nbOfTuples=getNumberOfTuples();
3045   for(int i=0;i<nbOfTuples;i++)
3046     {
3047       for(int idim=0;idim<dim;idim++)
3048         {
3049           if(bounds[idim*2]>ptr[i*dim+idim])
3050             {
3051               bounds[idim*2]=ptr[i*dim+idim];
3052             }
3053           if(bounds[idim*2+1]<ptr[i*dim+idim])
3054             {
3055               bounds[idim*2+1]=ptr[i*dim+idim];
3056             }
3057         }
3058     }
3059 }
3060
3061 /*!
3062  * This method retrieves a newly allocated DataArrayDouble instance having same number of tuples than \a this and twice number of components than \a this
3063  * to store both the min and max per component of each tuples. 
3064  * \param [in] epsilon the width of the bbox (identical in each direction) - 0.0 by default
3065  *
3066  * \return a newly created DataArrayDouble instance having \c this->getNumberOfTuples() tuples and 2 * \c this->getNumberOfComponent() components
3067  *
3068  * \throw If \a this is not allocated yet.
3069  */
3070 DataArrayDouble *DataArrayDouble::computeBBoxPerTuple(double epsilon) const
3071 {
3072   checkAllocated();
3073   const double *dataPtr=getConstPointer();
3074   int nbOfCompo=getNumberOfComponents();
3075   int nbTuples=getNumberOfTuples();
3076   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> bbox=DataArrayDouble::New();
3077   bbox->alloc(nbTuples,2*nbOfCompo);
3078   double *bboxPtr=bbox->getPointer();
3079   for(int i=0;i<nbTuples;i++)
3080     {
3081       for(int j=0;j<nbOfCompo;j++)
3082         {
3083           bboxPtr[2*nbOfCompo*i+2*j]=dataPtr[nbOfCompo*i+j]-epsilon;
3084           bboxPtr[2*nbOfCompo*i+2*j+1]=dataPtr[nbOfCompo*i+j]+epsilon;
3085         }
3086     }
3087   return bbox.retn();
3088 }
3089
3090 /*!
3091  * For each tuples **t** in \a other, this method retrieves tuples in \a this that are equal to **t**.
3092  * Two tuples are considered equal if the euclidian distance between the two tuples is lower than \a eps.
3093  * 
3094  * \param [in] other a DataArrayDouble having same number of components than \a this.
3095  * \param [in] eps absolute precision representing distance (using infinite norm) between 2 tuples behind which 2 tuples are considered equal.
3096  * \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.
3097  *             \a cI allows to extract information in \a c.
3098  * \param [out] cI is an indirection array that allows to extract the data contained in \a c.
3099  *
3100  * \throw In case of:
3101  *  - \a this is not allocated
3102  *  - \a other is not allocated or null
3103  *  - \a this and \a other do not have the same number of components
3104  *  - if number of components of \a this is not in [1,2,3]
3105  *
3106  * \sa MEDCouplingPointSet::getNodeIdsNearPoints, DataArrayDouble::getDifferentValues
3107  */
3108 void DataArrayDouble::computeTupleIdsNearTuples(const DataArrayDouble *other, double eps, DataArrayInt *& c, DataArrayInt *& cI) const
3109 {
3110   if(!other)
3111     throw INTERP_KERNEL::Exception("DataArrayDouble::computeTupleIdsNearTuples : input pointer other is null !");
3112   checkAllocated();
3113   other->checkAllocated();
3114   int nbOfCompo=getNumberOfComponents();
3115   int otherNbOfCompo=other->getNumberOfComponents();
3116   if(nbOfCompo!=otherNbOfCompo)
3117     throw INTERP_KERNEL::Exception("DataArrayDouble::computeTupleIdsNearTuples : number of components should be equal between this and other !");
3118   int nbOfTuplesOther=other->getNumberOfTuples();
3119   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cArr(DataArrayInt::New()),cIArr(DataArrayInt::New()); cArr->alloc(0,1); cIArr->pushBackSilent(0);
3120   switch(nbOfCompo)
3121   {
3122     case 3:
3123       {
3124         BBTreePts<3,int> myTree(begin(),0,0,getNumberOfTuples(),eps);
3125         FindTupleIdsNearTuplesAlg<3>(myTree,other->getConstPointer(),nbOfTuplesOther,eps,cArr,cIArr);
3126         break;
3127       }
3128     case 2:
3129       {
3130         BBTreePts<2,int> myTree(begin(),0,0,getNumberOfTuples(),eps);
3131         FindTupleIdsNearTuplesAlg<2>(myTree,other->getConstPointer(),nbOfTuplesOther,eps,cArr,cIArr);
3132         break;
3133       }
3134     case 1:
3135       {
3136         BBTreePts<1,int> myTree(begin(),0,0,getNumberOfTuples(),eps);
3137         FindTupleIdsNearTuplesAlg<1>(myTree,other->getConstPointer(),nbOfTuplesOther,eps,cArr,cIArr);
3138         break;
3139       }
3140     default:
3141       throw INTERP_KERNEL::Exception("Unexpected spacedim of coords for computeTupleIdsNearTuples. Must be 1, 2 or 3.");
3142   }
3143   c=cArr.retn(); cI=cIArr.retn();
3144 }
3145
3146 /*!
3147  * 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
3148  * around origin of 'radius' 1.
3149  * 
3150  * \param [in] eps absolute epsilon. under that value of delta between max and min no scale is performed.
3151  */
3152 void DataArrayDouble::recenterForMaxPrecision(double eps)
3153 {
3154   checkAllocated();
3155   int dim=getNumberOfComponents();
3156   std::vector<double> bounds(2*dim);
3157   getMinMaxPerComponent(&bounds[0]);
3158   for(int i=0;i<dim;i++)
3159     {
3160       double delta=bounds[2*i+1]-bounds[2*i];
3161       double offset=(bounds[2*i]+bounds[2*i+1])/2.;
3162       if(delta>eps)
3163         applyLin(1./delta,-offset/delta,i);
3164       else
3165         applyLin(1.,-offset,i);
3166     }
3167 }
3168
3169 /*!
3170  * Returns the maximal value and its location within \a this one-dimensional array.
3171  *  \param [out] tupleId - index of the tuple holding the maximal value.
3172  *  \return double - the maximal value among all values of \a this array.
3173  *  \throw If \a this->getNumberOfComponents() != 1
3174  *  \throw If \a this->getNumberOfTuples() < 1
3175  */
3176 double DataArrayDouble::getMaxValue(int& tupleId) const
3177 {
3178   checkAllocated();
3179   if(getNumberOfComponents()!=1)
3180     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 !");
3181   int nbOfTuples=getNumberOfTuples();
3182   if(nbOfTuples<=0)
3183     throw INTERP_KERNEL::Exception("DataArrayDouble::getMaxValue : array exists but number of tuples must be > 0 !");
3184   const double *vals=getConstPointer();
3185   const double *loc=std::max_element(vals,vals+nbOfTuples);
3186   tupleId=(int)std::distance(vals,loc);
3187   return *loc;
3188 }
3189
3190 /*!
3191  * Returns the maximal value within \a this array that is allowed to have more than
3192  *  one component.
3193  *  \return double - the maximal value among all values of \a this array.
3194  *  \throw If \a this is not allocated.
3195  */
3196 double DataArrayDouble::getMaxValueInArray() const
3197 {
3198   checkAllocated();
3199   const double *loc=std::max_element(begin(),end());
3200   return *loc;
3201 }
3202
3203 /*!
3204  * Returns the maximal value and all its locations within \a this one-dimensional array.
3205  *  \param [out] tupleIds - a new instance of DataArrayInt containg indices of
3206  *               tuples holding the maximal value. The caller is to delete it using
3207  *               decrRef() as it is no more needed.
3208  *  \return double - the maximal value among all values of \a this array.
3209  *  \throw If \a this->getNumberOfComponents() != 1
3210  *  \throw If \a this->getNumberOfTuples() < 1
3211  */
3212 double DataArrayDouble::getMaxValue2(DataArrayInt*& tupleIds) const
3213 {
3214   int tmp;
3215   tupleIds=0;
3216   double ret=getMaxValue(tmp);
3217   tupleIds=getIdsInRange(ret,ret);
3218   return ret;
3219 }
3220
3221 /*!
3222  * Returns the minimal value and its location within \a this one-dimensional array.
3223  *  \param [out] tupleId - index of the tuple holding the minimal value.
3224  *  \return double - the minimal value among all values of \a this array.
3225  *  \throw If \a this->getNumberOfComponents() != 1
3226  *  \throw If \a this->getNumberOfTuples() < 1
3227  */
3228 double DataArrayDouble::getMinValue(int& tupleId) const
3229 {
3230   checkAllocated();
3231   if(getNumberOfComponents()!=1)
3232     throw INTERP_KERNEL::Exception("DataArrayDouble::getMinValue : must be applied on DataArrayDouble with only one component, you can call 'rearrange' method before call 'getMinValueInArray' method !");
3233   int nbOfTuples=getNumberOfTuples();
3234   if(nbOfTuples<=0)
3235     throw INTERP_KERNEL::Exception("DataArrayDouble::getMinValue : array exists but number of tuples must be > 0 !");
3236   const double *vals=getConstPointer();
3237   const double *loc=std::min_element(vals,vals+nbOfTuples);
3238   tupleId=(int)std::distance(vals,loc);
3239   return *loc;
3240 }
3241
3242 /*!
3243  * Returns the minimal value within \a this array that is allowed to have more than
3244  *  one component.
3245  *  \return double - the minimal value among all values of \a this array.
3246  *  \throw If \a this is not allocated.
3247  */
3248 double DataArrayDouble::getMinValueInArray() const
3249 {
3250   checkAllocated();
3251   const double *loc=std::min_element(begin(),end());
3252   return *loc;
3253 }
3254
3255 /*!
3256  * Returns the minimal value and all its locations within \a this one-dimensional array.
3257  *  \param [out] tupleIds - a new instance of DataArrayInt containg indices of
3258  *               tuples holding the minimal value. The caller is to delete it using
3259  *               decrRef() as it is no more needed.
3260  *  \return double - the minimal value among all values of \a this array.
3261  *  \throw If \a this->getNumberOfComponents() != 1
3262  *  \throw If \a this->getNumberOfTuples() < 1
3263  */
3264 double DataArrayDouble::getMinValue2(DataArrayInt*& tupleIds) const
3265 {
3266   int tmp;
3267   tupleIds=0;
3268   double ret=getMinValue(tmp);
3269   tupleIds=getIdsInRange(ret,ret);
3270   return ret;
3271 }
3272
3273 /*!
3274  * 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.
3275  * This method only works for single component array.
3276  *
3277  * \return a value in [ 0, \c this->getNumberOfTuples() )
3278  *
3279  * \throw If \a this is not allocated
3280  *
3281  */
3282 int DataArrayDouble::count(double value, double eps) const
3283 {
3284   int ret=0;
3285   checkAllocated();
3286   if(getNumberOfComponents()!=1)
3287     throw INTERP_KERNEL::Exception("DataArrayDouble::count : must be applied on DataArrayDouble with only one component, you can call 'rearrange' method before !");
3288   const double *vals=begin();
3289   int nbOfTuples=getNumberOfTuples();
3290   for(int i=0;i<nbOfTuples;i++,vals++)
3291     if(fabs(*vals-value)<=eps)
3292       ret++;
3293   return ret;
3294 }
3295
3296 /*!
3297  * Returns the average value of \a this one-dimensional array.
3298  *  \return double - the average value over all values of \a this array.
3299  *  \throw If \a this->getNumberOfComponents() != 1
3300  *  \throw If \a this->getNumberOfTuples() < 1
3301  */
3302 double DataArrayDouble::getAverageValue() const
3303 {
3304   if(getNumberOfComponents()!=1)
3305     throw INTERP_KERNEL::Exception("DataArrayDouble::getAverageValue : must be applied on DataArrayDouble with only one component, you can call 'rearrange' method before !");
3306   int nbOfTuples=getNumberOfTuples();
3307   if(nbOfTuples<=0)
3308     throw INTERP_KERNEL::Exception("DataArrayDouble::getAverageValue : array exists but number of tuples must be > 0 !");
3309   const double *vals=getConstPointer();
3310   double ret=std::accumulate(vals,vals+nbOfTuples,0.);
3311   return ret/nbOfTuples;
3312 }
3313
3314 /*!
3315  * Returns the Euclidean norm of the vector defined by \a this array.
3316  *  \return double - the value of the Euclidean norm, i.e.
3317  *          the square root of the inner product of vector.
3318  *  \throw If \a this is not allocated.
3319  */
3320 double DataArrayDouble::norm2() const
3321 {
3322   checkAllocated();
3323   double ret=0.;
3324   std::size_t nbOfElems=getNbOfElems();
3325   const double *pt=getConstPointer();
3326   for(std::size_t i=0;i<nbOfElems;i++,pt++)
3327     ret+=(*pt)*(*pt);
3328   return sqrt(ret);
3329 }
3330
3331 /*!
3332  * Returns the maximum norm of the vector defined by \a this array.
3333  * This method works even if the number of components is diferent from one.
3334  * If the number of elements in \a this is 0, -1. is returned.
3335  *  \return double - the value of the maximum norm, i.e.
3336  *          the maximal absolute value among values of \a this array (whatever its number of components).
3337  *  \throw If \a this is not allocated.
3338  */
3339 double DataArrayDouble::normMax() const
3340 {
3341   checkAllocated();
3342   double ret(-1.);
3343   std::size_t nbOfElems(getNbOfElems());
3344   const double *pt(getConstPointer());
3345   for(std::size_t i=0;i<nbOfElems;i++,pt++)
3346     {
3347       double val(std::abs(*pt));
3348       if(val>ret)
3349         ret=val;
3350     }
3351   return ret;
3352 }
3353
3354 /*!
3355  * Returns the minimum norm (absolute value) of the vector defined by \a this array.
3356  * This method works even if the number of components is diferent from one.
3357  * If the number of elements in \a this is 0, std::numeric_limits<double>::max() is returned.
3358  *  \return double - the value of the minimum norm, i.e.
3359  *          the minimal absolute value among values of \a this array (whatever its number of components).
3360  *  \throw If \a this is not allocated.
3361  */
3362 double DataArrayDouble::normMin() const
3363 {
3364   checkAllocated();
3365   double ret(std::numeric_limits<double>::max());
3366   std::size_t nbOfElems(getNbOfElems());
3367   const double *pt(getConstPointer());
3368   for(std::size_t i=0;i<nbOfElems;i++,pt++)
3369     {
3370       double val(std::abs(*pt));
3371       if(val<ret)
3372         ret=val;
3373     }
3374   return ret;
3375 }
3376
3377 /*!
3378  * Accumulates values of each component of \a this array.
3379  *  \param [out] res - an array of length \a this->getNumberOfComponents(), allocated 
3380  *         by the caller, that is filled by this method with sum value for each
3381  *         component.
3382  *  \throw If \a this is not allocated.
3383  */
3384 void DataArrayDouble::accumulate(double *res) const
3385 {
3386   checkAllocated();
3387   const double *ptr=getConstPointer();
3388   int nbTuple=getNumberOfTuples();
3389   int nbComps=getNumberOfComponents();
3390   std::fill(res,res+nbComps,0.);
3391   for(int i=0;i<nbTuple;i++)
3392     std::transform(ptr+i*nbComps,ptr+(i+1)*nbComps,res,res,std::plus<double>());
3393 }
3394
3395 /*!
3396  * This method returns the min distance from an external tuple defined by [ \a tupleBg , \a tupleEnd ) to \a this and
3397  * the first tuple in \a this that matches the returned distance. If there is no tuples in \a this an exception will be thrown.
3398  *
3399  *
3400  * \a this is expected to be allocated and expected to have a number of components equal to the distance from \a tupleBg to
3401  * \a tupleEnd. If not an exception will be thrown.
3402  *
3403  * \param [in] tupleBg start pointer (included) of input external tuple
3404  * \param [in] tupleEnd end pointer (not included) of input external tuple
3405  * \param [out] tupleId the tuple id in \a this that matches the min of distance between \a this and input external tuple
3406  * \return the min distance.
3407  * \sa MEDCouplingUMesh::distanceToPoint
3408  */
3409 double DataArrayDouble::distanceToTuple(const double *tupleBg, const double *tupleEnd, int& tupleId) const
3410 {
3411   checkAllocated();
3412   int nbTuple=getNumberOfTuples();
3413   int nbComps=getNumberOfComponents();
3414   if(nbComps!=(int)std::distance(tupleBg,tupleEnd))
3415     { 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()); }
3416   if(nbTuple==0)
3417     throw INTERP_KERNEL::Exception("DataArrayDouble::distanceToTuple : no tuple in this ! No distance to compute !");
3418   double ret0=std::numeric_limits<double>::max();
3419   tupleId=-1;
3420   const double *work=getConstPointer();
3421   for(int i=0;i<nbTuple;i++)
3422     {
3423       double val=0.;
3424       for(int j=0;j<nbComps;j++,work++) 
3425         val+=(*work-tupleBg[j])*((*work-tupleBg[j]));
3426       if(val>=ret0)
3427         continue;
3428       else
3429         { ret0=val; tupleId=i; }
3430     }
3431   return sqrt(ret0);
3432 }
3433
3434 /*!
3435  * Accumulate values of the given component of \a this array.
3436  *  \param [in] compId - the index of the component of interest.
3437  *  \return double - a sum value of \a compId-th component.
3438  *  \throw If \a this is not allocated.
3439  *  \throw If \a the condition ( 0 <= \a compId < \a this->getNumberOfComponents() ) is
3440  *         not respected.
3441  */
3442 double DataArrayDouble::accumulate(int compId) const
3443 {
3444   checkAllocated();
3445   const double *ptr=getConstPointer();
3446   int nbTuple=getNumberOfTuples();
3447   int nbComps=getNumberOfComponents();
3448   if(compId<0 || compId>=nbComps)
3449     throw INTERP_KERNEL::Exception("DataArrayDouble::accumulate : Invalid compId specified : No such nb of components !");
3450   double ret=0.;
3451   for(int i=0;i<nbTuple;i++)
3452     ret+=ptr[i*nbComps+compId];
3453   return ret;
3454 }
3455
3456 /*!
3457  * This method accumulate using addition tuples in \a this using input index array [ \a bgOfIndex, \a endOfIndex ).
3458  * The returned array will have same number of components than \a this and number of tuples equal to
3459  * \c std::distance(bgOfIndex,endOfIndex) \b minus \b one.
3460  *
3461  * The input index array is expected to be ascendingly sorted in which the all referenced ids should be in [0, \c this->getNumberOfTuples).
3462  * 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.
3463  *
3464  * \param [in] bgOfIndex - begin (included) of the input index array.
3465  * \param [in] endOfIndex - end (excluded) of the input index array.
3466  * \return DataArrayDouble * - the new instance having the same number of components than \a this.
3467  * 
3468  * \throw If bgOfIndex or end is NULL.
3469  * \throw If input index array is not ascendingly sorted.
3470  * \throw If there is an id in [ \a bgOfIndex, \a endOfIndex ) not in [0, \c this->getNumberOfTuples).
3471  * \throw If std::distance(bgOfIndex,endOfIndex)==0.
3472  */
3473 DataArrayDouble *DataArrayDouble::accumulatePerChunck(const int *bgOfIndex, const int *endOfIndex) const
3474 {
3475   if(!bgOfIndex || !endOfIndex)
3476     throw INTERP_KERNEL::Exception("DataArrayDouble::accumulatePerChunck : input pointer NULL !");
3477   checkAllocated();
3478   int nbCompo=getNumberOfComponents();
3479   int nbOfTuples=getNumberOfTuples();
3480   int sz=(int)std::distance(bgOfIndex,endOfIndex);
3481   if(sz<1)
3482     throw INTERP_KERNEL::Exception("DataArrayDouble::accumulatePerChunck : invalid size of input index array !");
3483   sz--;
3484   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New(); ret->alloc(sz,nbCompo);
3485   const int *w=bgOfIndex;
3486   if(*w<0 || *w>=nbOfTuples)
3487     throw INTERP_KERNEL::Exception("DataArrayDouble::accumulatePerChunck : The first element of the input index not in [0,nbOfTuples) !");
3488   const double *srcPt=begin()+(*w)*nbCompo;
3489   double *tmp=ret->getPointer();
3490   for(int i=0;i<sz;i++,tmp+=nbCompo,w++)
3491     {
3492       std::fill(tmp,tmp+nbCompo,0.);
3493       if(w[1]>=w[0])
3494         {
3495           for(int j=w[0];j<w[1];j++,srcPt+=nbCompo)
3496             {
3497               if(j>=0 && j<nbOfTuples)
3498                 std::transform(srcPt,srcPt+nbCompo,tmp,tmp,std::plus<double>());
3499               else
3500                 {
3501                   std::ostringstream oss; oss << "DataArrayDouble::accumulatePerChunck : At rank #" << i << " the input index array points to id " << j << " should be in [0," << nbOfTuples << ") !";
3502                   throw INTERP_KERNEL::Exception(oss.str().c_str());
3503                 }
3504             }
3505         }
3506       else
3507         {
3508           std::ostringstream oss; oss << "DataArrayDouble::accumulatePerChunck : At rank #" << i << " the input index array is not in ascendingly sorted.";
3509           throw INTERP_KERNEL::Exception(oss.str().c_str());
3510         }
3511     }
3512   ret->copyStringInfoFrom(*this);
3513   return ret.retn();
3514 }
3515
3516 /*!
3517  * Converts each 2D point defined by the tuple of \a this array from the Polar to the
3518  * Cartesian coordinate system. The two components of the tuple of \a this array are 
3519  * considered to contain (1) radius and (2) angle of the point in the Polar CS.
3520  *  \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
3521  *          contains X and Y coordinates of the point in the Cartesian CS. The caller
3522  *          is to delete this array using decrRef() as it is no more needed. The array
3523  *          does not contain any textual info on components.
3524  *  \throw If \a this->getNumberOfComponents() != 2.
3525  */
3526 DataArrayDouble *DataArrayDouble::fromPolarToCart() const
3527 {
3528   checkAllocated();
3529   int nbOfComp=getNumberOfComponents();
3530   if(nbOfComp!=2)
3531     throw INTERP_KERNEL::Exception("DataArrayDouble::fromPolarToCart : must be an array with exactly 2 components !");
3532   int nbOfTuple=getNumberOfTuples();
3533   DataArrayDouble *ret=DataArrayDouble::New();
3534   ret->alloc(nbOfTuple,2);
3535   double *w=ret->getPointer();
3536   const double *wIn=getConstPointer();
3537   for(int i=0;i<nbOfTuple;i++,w+=2,wIn+=2)
3538     {
3539       w[0]=wIn[0]*cos(wIn[1]);
3540       w[1]=wIn[0]*sin(wIn[1]);
3541     }
3542   return ret;
3543 }
3544
3545 /*!
3546  * Converts each 3D point defined by the tuple of \a this array from the Cylindrical to
3547  * the Cartesian coordinate system. The three components of the tuple of \a this array 
3548  * are considered to contain (1) radius, (2) azimuth and (3) altitude of the point in
3549  * the Cylindrical CS.
3550  *  \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
3551  *          contains X, Y and Z coordinates of the point in the Cartesian CS. The info
3552  *          on the third component is copied from \a this array. The caller
3553  *          is to delete this array using decrRef() as it is no more needed. 
3554  *  \throw If \a this->getNumberOfComponents() != 3.
3555  */
3556 DataArrayDouble *DataArrayDouble::fromCylToCart() const
3557 {
3558   checkAllocated();
3559   int nbOfComp=getNumberOfComponents();
3560   if(nbOfComp!=3)
3561     throw INTERP_KERNEL::Exception("DataArrayDouble::fromCylToCart : must be an array with exactly 3 components !");
3562   int nbOfTuple=getNumberOfTuples();
3563   DataArrayDouble *ret=DataArrayDouble::New();
3564   ret->alloc(getNumberOfTuples(),3);
3565   double *w=ret->getPointer();
3566   const double *wIn=getConstPointer();
3567   for(int i=0;i<nbOfTuple;i++,w+=3,wIn+=3)
3568     {
3569       w[0]=wIn[0]*cos(wIn[1]);
3570       w[1]=wIn[0]*sin(wIn[1]);
3571       w[2]=wIn[2];
3572     }
3573   ret->setInfoOnComponent(2,getInfoOnComponent(2));
3574   return ret;
3575 }
3576
3577 /*!
3578  * Converts each 3D point defined by the tuple of \a this array from the Spherical to
3579  * the Cartesian coordinate system. The three components of the tuple of \a this array 
3580  * are considered to contain (1) radius, (2) polar angle and (3) azimuthal angle of the
3581  * point in the Cylindrical CS.
3582  *  \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
3583  *          contains X, Y and Z coordinates of the point in the Cartesian CS. The info
3584  *          on the third component is copied from \a this array. The caller
3585  *          is to delete this array using decrRef() as it is no more needed.
3586  *  \throw If \a this->getNumberOfComponents() != 3.
3587  */
3588 DataArrayDouble *DataArrayDouble::fromSpherToCart() const
3589 {
3590   checkAllocated();
3591   int nbOfComp=getNumberOfComponents();
3592   if(nbOfComp!=3)
3593     throw INTERP_KERNEL::Exception("DataArrayDouble::fromSpherToCart : must be an array with exactly 3 components !");
3594   int nbOfTuple=getNumberOfTuples();
3595   DataArrayDouble *ret=DataArrayDouble::New();
3596   ret->alloc(getNumberOfTuples(),3);
3597   double *w=ret->getPointer();
3598   const double *wIn=getConstPointer();
3599   for(int i=0;i<nbOfTuple;i++,w+=3,wIn+=3)
3600     {
3601       w[0]=wIn[0]*cos(wIn[2])*sin(wIn[1]);
3602       w[1]=wIn[0]*sin(wIn[2])*sin(wIn[1]);
3603       w[2]=wIn[0]*cos(wIn[1]);
3604     }
3605   return ret;
3606 }
3607
3608 /*!
3609  * Computes the doubly contracted product of every tensor defined by the tuple of \a this
3610  * array contating 6 components.
3611  *  \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
3612  *          is calculated from the tuple <em>(t)</em> of \a this array as follows:
3613  *          \f$ t[0]^2+t[1]^2+t[2]^2+2*t[3]^2+2*t[4]^2+2*t[5]^2\f$.
3614  *         The caller is to delete this result array using decrRef() as it is no more needed. 
3615  *  \throw If \a this->getNumberOfComponents() != 6.
3616  */
3617 DataArrayDouble *DataArrayDouble::doublyContractedProduct() const
3618 {
3619   checkAllocated();
3620   int nbOfComp=getNumberOfComponents();
3621   if(nbOfComp!=6)
3622     throw INTERP_KERNEL::Exception("DataArrayDouble::doublyContractedProduct : must be an array with exactly 6 components !");
3623   DataArrayDouble *ret=DataArrayDouble::New();
3624   int nbOfTuple=getNumberOfTuples();
3625   ret->alloc(nbOfTuple,1);
3626   const double *src=getConstPointer();
3627   double *dest=ret->getPointer();
3628   for(int i=0;i<nbOfTuple;i++,dest++,src+=6)
3629     *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];
3630   return ret;
3631 }
3632
3633 /*!
3634  * Computes the determinant of every square matrix defined by the tuple of \a this
3635  * array, which contains either 4, 6 or 9 components. The case of 6 components
3636  * corresponds to that of the upper triangular matrix.
3637  *  \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
3638  *          is the determinant of matrix of the corresponding tuple of \a this array.
3639  *          The caller is to delete this result array using decrRef() as it is no more
3640  *          needed. 
3641  *  \throw If \a this->getNumberOfComponents() is not in [4,6,9].
3642  */
3643 DataArrayDouble *DataArrayDouble::determinant() const
3644 {
3645   checkAllocated();
3646   DataArrayDouble *ret=DataArrayDouble::New();
3647   int nbOfTuple=getNumberOfTuples();
3648   ret->alloc(nbOfTuple,1);
3649   const double *src=getConstPointer();
3650   double *dest=ret->getPointer();
3651   switch(getNumberOfComponents())
3652   {
3653     case 6:
3654       for(int i=0;i<nbOfTuple;i++,dest++,src+=6)
3655         *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];
3656       return ret;
3657     case 4:
3658       for(int i=0;i<nbOfTuple;i++,dest++,src+=4)
3659         *dest=src[0]*src[3]-src[1]*src[2];
3660       return ret;
3661     case 9:
3662       for(int i=0;i<nbOfTuple;i++,dest++,src+=9)
3663         *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];
3664       return ret;
3665     default:
3666       ret->decrRef();
3667       throw INTERP_KERNEL::Exception("DataArrayDouble::determinant : Invalid number of components ! must be in 4,6,9 !");
3668   }
3669 }
3670
3671 /*!
3672  * Computes 3 eigenvalues of every upper triangular matrix defined by the tuple of
3673  * \a this array, which contains 6 components.
3674  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing 3
3675  *          components, whose each tuple contains the eigenvalues of the matrix of
3676  *          corresponding tuple of \a this array. 
3677  *          The caller is to delete this result array using decrRef() as it is no more
3678  *          needed. 
3679  *  \throw If \a this->getNumberOfComponents() != 6.
3680  */
3681 DataArrayDouble *DataArrayDouble::eigenValues() const
3682 {
3683   checkAllocated();
3684   int nbOfComp=getNumberOfComponents();
3685   if(nbOfComp!=6)
3686     throw INTERP_KERNEL::Exception("DataArrayDouble::eigenValues : must be an array with exactly 6 components !");
3687   DataArrayDouble *ret=DataArrayDouble::New();
3688   int nbOfTuple=getNumberOfTuples();
3689   ret->alloc(nbOfTuple,3);
3690   const double *src=getConstPointer();
3691   double *dest=ret->getPointer();
3692   for(int i=0;i<nbOfTuple;i++,dest+=3,src+=6)
3693     INTERP_KERNEL::computeEigenValues6(src,dest);
3694   return ret;
3695 }
3696
3697 /*!
3698  * Computes 3 eigenvectors of every upper triangular matrix defined by the tuple of
3699  * \a this array, which contains 6 components.
3700  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing 9
3701  *          components, whose each tuple contains 3 eigenvectors of the matrix of
3702  *          corresponding tuple of \a this array.
3703  *          The caller is to delete this result array using decrRef() as it is no more
3704  *          needed.
3705  *  \throw If \a this->getNumberOfComponents() != 6.
3706  */
3707 DataArrayDouble *DataArrayDouble::eigenVectors() const
3708 {
3709   checkAllocated();
3710   int nbOfComp=getNumberOfComponents();
3711   if(nbOfComp!=6)
3712     throw INTERP_KERNEL::Exception("DataArrayDouble::eigenVectors : must be an array with exactly 6 components !");
3713   DataArrayDouble *ret=DataArrayDouble::New();
3714   int nbOfTuple=getNumberOfTuples();
3715   ret->alloc(nbOfTuple,9);
3716   const double *src=getConstPointer();
3717   double *dest=ret->getPointer();
3718   for(int i=0;i<nbOfTuple;i++,src+=6)
3719     {
3720       double tmp[3];
3721       INTERP_KERNEL::computeEigenValues6(src,tmp);
3722       for(int j=0;j<3;j++,dest+=3)
3723         INTERP_KERNEL::computeEigenVectorForEigenValue6(src,tmp[j],1e-12,dest);
3724     }
3725   return ret;
3726 }
3727
3728 /*!
3729  * Computes the inverse matrix of every matrix defined by the tuple of \a this
3730  * array, which contains either 4, 6 or 9 components. The case of 6 components
3731  * corresponds to that of the upper triangular matrix.
3732  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
3733  *          same number of components as \a this one, whose each tuple is the inverse
3734  *          matrix of the matrix of corresponding tuple of \a this array. 
3735  *          The caller is to delete this result array using decrRef() as it is no more
3736  *          needed. 
3737  *  \throw If \a this->getNumberOfComponents() is not in [4,6,9].
3738  */
3739 DataArrayDouble *DataArrayDouble::inverse() const
3740 {
3741   checkAllocated();
3742   int nbOfComp=getNumberOfComponents();
3743   if(nbOfComp!=6 && nbOfComp!=9 && nbOfComp!=4)
3744     throw INTERP_KERNEL::Exception("DataArrayDouble::inversion : must be an array with 4,6 or 9 components !");
3745   DataArrayDouble *ret=DataArrayDouble::New();
3746   int nbOfTuple=getNumberOfTuples();
3747   ret->alloc(nbOfTuple,nbOfComp);
3748   const double *src=getConstPointer();
3749   double *dest=ret->getPointer();
3750   if(nbOfComp==6)
3751     for(int i=0;i<nbOfTuple;i++,dest+=6,src+=6)
3752       {
3753         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];
3754         dest[0]=(src[1]*src[2]-src[4]*src[4])/det;
3755         dest[1]=(src[0]*src[2]-src[5]*src[5])/det;
3756         dest[2]=(src[0]*src[1]-src[3]*src[3])/det;
3757         dest[3]=(src[5]*src[4]-src[3]*src[2])/det;
3758         dest[4]=(src[5]*src[3]-src[0]*src[4])/det;
3759         dest[5]=(src[3]*src[4]-src[1]*src[5])/det;
3760       }
3761   else if(nbOfComp==4)
3762     for(int i=0;i<nbOfTuple;i++,dest+=4,src+=4)
3763       {
3764         double det=src[0]*src[3]-src[1]*src[2];
3765         dest[0]=src[3]/det;
3766         dest[1]=-src[1]/det;
3767         dest[2]=-src[2]/det;
3768         dest[3]=src[0]/det;
3769       }
3770   else
3771     for(int i=0;i<nbOfTuple;i++,dest+=9,src+=9)
3772       {
3773         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];
3774         dest[0]=(src[4]*src[8]-src[7]*src[5])/det;
3775         dest[1]=(src[7]*src[2]-src[1]*src[8])/det;
3776         dest[2]=(src[1]*src[5]-src[4]*src[2])/det;
3777         dest[3]=(src[6]*src[5]-src[3]*src[8])/det;
3778         dest[4]=(src[0]*src[8]-src[6]*src[2])/det;
3779         dest[5]=(src[2]*src[3]-src[0]*src[5])/det;
3780         dest[6]=(src[3]*src[7]-src[6]*src[4])/det;
3781         dest[7]=(src[6]*src[1]-src[0]*src[7])/det;
3782         dest[8]=(src[0]*src[4]-src[1]*src[3])/det;
3783       }
3784   return ret;
3785 }
3786
3787 /*!
3788  * Computes the trace of every matrix defined by the tuple of \a this
3789  * array, which contains either 4, 6 or 9 components. The case of 6 components
3790  * corresponds to that of the upper triangular matrix.
3791  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing 
3792  *          1 component, whose each tuple is the trace of
3793  *          the matrix of corresponding tuple of \a this array. 
3794  *          The caller is to delete this result array using decrRef() as it is no more
3795  *          needed. 
3796  *  \throw If \a this->getNumberOfComponents() is not in [4,6,9].
3797  */
3798 DataArrayDouble *DataArrayDouble::trace() const
3799 {
3800   checkAllocated();
3801   int nbOfComp=getNumberOfComponents();
3802   if(nbOfComp!=6 && nbOfComp!=9 && nbOfComp!=4)
3803     throw INTERP_KERNEL::Exception("DataArrayDouble::trace : must be an array with 4,6 or 9 components !");
3804   DataArrayDouble *ret=DataArrayDouble::New();
3805   int nbOfTuple=getNumberOfTuples();
3806   ret->alloc(nbOfTuple,1);
3807   const double *src=getConstPointer();
3808   double *dest=ret->getPointer();
3809   if(nbOfComp==6)
3810     for(int i=0;i<nbOfTuple;i++,dest++,src+=6)
3811       *dest=src[0]+src[1]+src[2];
3812   else if(nbOfComp==4)
3813     for(int i=0;i<nbOfTuple;i++,dest++,src+=4)
3814       *dest=src[0]+src[3];
3815   else
3816     for(int i=0;i<nbOfTuple;i++,dest++,src+=9)
3817       *dest=src[0]+src[4]+src[8];
3818   return ret;
3819 }
3820
3821 /*!
3822  * Computes the stress deviator tensor of every stress tensor defined by the tuple of
3823  * \a this array, which contains 6 components.
3824  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
3825  *          same number of components and tuples as \a this array.
3826  *          The caller is to delete this result array using decrRef() as it is no more
3827  *          needed.
3828  *  \throw If \a this->getNumberOfComponents() != 6.
3829  */
3830 DataArrayDouble *DataArrayDouble::deviator() const
3831 {
3832   checkAllocated();
3833   int nbOfComp=getNumberOfComponents();
3834   if(nbOfComp!=6)
3835     throw INTERP_KERNEL::Exception("DataArrayDouble::deviator : must be an array with exactly 6 components !");
3836   DataArrayDouble *ret=DataArrayDouble::New();
3837   int nbOfTuple=getNumberOfTuples();
3838   ret->alloc(nbOfTuple,6);
3839   const double *src=getConstPointer();
3840   double *dest=ret->getPointer();
3841   for(int i=0;i<nbOfTuple;i++,dest+=6,src+=6)
3842     {
3843       double tr=(src[0]+src[1]+src[2])/3.;
3844       dest[0]=src[0]-tr;
3845       dest[1]=src[1]-tr;
3846       dest[2]=src[2]-tr;
3847       dest[3]=src[3];
3848       dest[4]=src[4];
3849       dest[5]=src[5];
3850     }
3851   return ret;
3852 }
3853
3854 /*!
3855  * Computes the magnitude of every vector defined by the tuple of
3856  * \a this array.
3857  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
3858  *          same number of tuples as \a this array and one component.
3859  *          The caller is to delete this result array using decrRef() as it is no more
3860  *          needed.
3861  *  \throw If \a this is not allocated.
3862  */
3863 DataArrayDouble *DataArrayDouble::magnitude() const
3864 {
3865   checkAllocated();
3866   int nbOfComp=getNumberOfComponents();
3867   DataArrayDouble *ret=DataArrayDouble::New();
3868   int nbOfTuple=getNumberOfTuples();
3869   ret->alloc(nbOfTuple,1);
3870   const double *src=getConstPointer();
3871   double *dest=ret->getPointer();
3872   for(int i=0;i<nbOfTuple;i++,dest++)
3873     {
3874       double sum=0.;
3875       for(int j=0;j<nbOfComp;j++,src++)
3876         sum+=(*src)*(*src);
3877       *dest=sqrt(sum);
3878     }
3879   return ret;
3880 }
3881
3882 /*!
3883  * Computes for each tuple the sum of number of components values in the tuple and return it.
3884  * 
3885  * \return DataArrayDouble * - the new instance of DataArrayDouble containing the
3886  *          same number of tuples as \a this array and one component.
3887  *          The caller is to delete this result array using decrRef() as it is no more
3888  *          needed.
3889  *  \throw If \a this is not allocated.
3890  */
3891 DataArrayDouble *DataArrayDouble::sumPerTuple() const
3892 {
3893   checkAllocated();
3894   int nbOfComp(getNumberOfComponents()),nbOfTuple(getNumberOfTuples());
3895   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret(DataArrayDouble::New());
3896   ret->alloc(nbOfTuple,1);
3897   const double *src(getConstPointer());
3898   double *dest(ret->getPointer());
3899   for(int i=0;i<nbOfTuple;i++,dest++,src+=nbOfComp)
3900     *dest=std::accumulate(src,src+nbOfComp,0.);
3901   return ret.retn();
3902 }
3903
3904 /*!
3905  * Computes the maximal value within every tuple of \a this array.
3906  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
3907  *          same number of tuples as \a this array and one component.
3908  *          The caller is to delete this result array using decrRef() as it is no more
3909  *          needed.
3910  *  \throw If \a this is not allocated.
3911  *  \sa DataArrayDouble::maxPerTupleWithCompoId
3912  */
3913 DataArrayDouble *DataArrayDouble::maxPerTuple() const
3914 {
3915   checkAllocated();
3916   int nbOfComp=getNumberOfComponents();
3917   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
3918   int nbOfTuple=getNumberOfTuples();
3919   ret->alloc(nbOfTuple,1);
3920   const double *src=getConstPointer();
3921   double *dest=ret->getPointer();
3922   for(int i=0;i<nbOfTuple;i++,dest++,src+=nbOfComp)
3923     *dest=*std::max_element(src,src+nbOfComp);
3924   return ret.retn();
3925 }
3926
3927 /*!
3928  * Computes the maximal value within every tuple of \a this array and it returns the first component
3929  * id for each tuple that corresponds to the maximal value within the tuple.
3930  * 
3931  *  \param [out] compoIdOfMaxPerTuple - the new new instance of DataArrayInt containing the
3932  *          same number of tuples and only one component.
3933  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
3934  *          same number of tuples as \a this array and one component.
3935  *          The caller is to delete this result array using decrRef() as it is no more
3936  *          needed.
3937  *  \throw If \a this is not allocated.
3938  *  \sa DataArrayDouble::maxPerTuple
3939  */
3940 DataArrayDouble *DataArrayDouble::maxPerTupleWithCompoId(DataArrayInt* &compoIdOfMaxPerTuple) const
3941 {
3942   checkAllocated();
3943   int nbOfComp=getNumberOfComponents();
3944   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret0=DataArrayDouble::New();
3945   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret1=DataArrayInt::New();
3946   int nbOfTuple=getNumberOfTuples();
3947   ret0->alloc(nbOfTuple,1); ret1->alloc(nbOfTuple,1);
3948   const double *src=getConstPointer();
3949   double *dest=ret0->getPointer(); int *dest1=ret1->getPointer();
3950   for(int i=0;i<nbOfTuple;i++,dest++,dest1++,src+=nbOfComp)
3951     {
3952       const double *loc=std::max_element(src,src+nbOfComp);
3953       *dest=*loc;
3954       *dest1=(int)std::distance(src,loc);
3955     }
3956   compoIdOfMaxPerTuple=ret1.retn();
3957   return ret0.retn();
3958 }
3959
3960 /*!
3961  * This method returns a newly allocated DataArrayDouble instance having one component and \c this->getNumberOfTuples() * \c this->getNumberOfTuples() tuples.
3962  * \n This returned array contains the euclidian distance for each tuple in \a this. 
3963  * \n So the returned array can be seen as a dense symmetrical matrix whose diagonal elements are equal to 0.
3964  * \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)
3965  *
3966  * \warning use this method with care because it can leads to big amount of consumed memory !
3967  * 
3968  * \return A newly allocated (huge) ParaMEDMEM::DataArrayDouble instance that the caller should deal with.
3969  *
3970  * \throw If \a this is not allocated.
3971  *
3972  * \sa DataArrayDouble::buildEuclidianDistanceDenseMatrixWith
3973  */
3974 DataArrayDouble *DataArrayDouble::buildEuclidianDistanceDenseMatrix() const
3975 {
3976   checkAllocated();
3977   int nbOfComp=getNumberOfComponents();
3978   int nbOfTuples=getNumberOfTuples();
3979   const double *inData=getConstPointer();
3980   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
3981   ret->alloc(nbOfTuples*nbOfTuples,1);
3982   double *outData=ret->getPointer();
3983   for(int i=0;i<nbOfTuples;i++)
3984     {
3985       outData[i*nbOfTuples+i]=0.;
3986       for(int j=i+1;j<nbOfTuples;j++)
3987         {
3988           double dist=0.;
3989           for(int k=0;k<nbOfComp;k++)
3990             { double delta=inData[i*nbOfComp+k]-inData[j*nbOfComp+k]; dist+=delta*delta; }
3991           dist=sqrt(dist);
3992           outData[i*nbOfTuples+j]=dist;
3993           outData[j*nbOfTuples+i]=dist;
3994         }
3995     }
3996   return ret.retn();
3997 }
3998
3999 /*!
4000  * This method returns a newly allocated DataArrayDouble instance having one component and \c this->getNumberOfTuples() * \c other->getNumberOfTuples() tuples.
4001  * \n This returned array contains the euclidian distance for each tuple in \a other with each tuple in \a this. 
4002  * \n So the returned array can be seen as a dense rectangular matrix with \c other->getNumberOfTuples() rows and \c this->getNumberOfTuples() columns.
4003  * \n Output rectangular matrix is sorted along rows.
4004  * \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)
4005  *
4006  * \warning use this method with care because it can leads to big amount of consumed memory !
4007  * 
4008  * \param [in] other DataArrayDouble instance having same number of components than \a this.
4009  * \return A newly allocated (huge) ParaMEDMEM::DataArrayDouble instance that the caller should deal with.
4010  *
4011  * \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.
4012  *
4013  * \sa DataArrayDouble::buildEuclidianDistanceDenseMatrix
4014  */
4015 DataArrayDouble *DataArrayDouble::buildEuclidianDistanceDenseMatrixWith(const DataArrayDouble *other) const
4016 {
4017   if(!other)
4018     throw INTERP_KERNEL::Exception("DataArrayDouble::buildEuclidianDistanceDenseMatrixWith : input parameter is null !");
4019   checkAllocated();
4020   other->checkAllocated();
4021   int nbOfComp=getNumberOfComponents();
4022   int otherNbOfComp=other->getNumberOfComponents();
4023   if(nbOfComp!=otherNbOfComp)
4024     {
4025       std::ostringstream oss; oss << "DataArrayDouble::buildEuclidianDistanceDenseMatrixWith : this nb of compo=" << nbOfComp << " and other nb of compo=" << otherNbOfComp << ". It should match !";
4026       throw INTERP_KERNEL::Exception(oss.str().c_str());
4027     }
4028   int nbOfTuples=getNumberOfTuples();
4029   int otherNbOfTuples=other->getNumberOfTuples();
4030   const double *inData=getConstPointer();
4031   const double *inDataOther=other->getConstPointer();
4032   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
4033   ret->alloc(otherNbOfTuples*nbOfTuples,1);
4034   double *outData=ret->getPointer();
4035   for(int i=0;i<otherNbOfTuples;i++,inDataOther+=nbOfComp)
4036     {
4037       for(int j=0;j<nbOfTuples;j++)
4038         {
4039           double dist=0.;
4040           for(int k=0;k<nbOfComp;k++)
4041             { double delta=inDataOther[k]-inData[j*nbOfComp+k]; dist+=delta*delta; }
4042           dist=sqrt(dist);
4043           outData[i*nbOfTuples+j]=dist;
4044         }
4045     }
4046   return ret.retn();
4047 }
4048
4049 /*!
4050  * Sorts value within every tuple of \a this array.
4051  *  \param [in] asc - if \a true, the values are sorted in ascending order, else,
4052  *              in descending order.
4053  *  \throw If \a this is not allocated.
4054  */
4055 void DataArrayDouble::sortPerTuple(bool asc)
4056 {
4057   checkAllocated();
4058   double *pt=getPointer();
4059   int nbOfTuple=getNumberOfTuples();
4060   int nbOfComp=getNumberOfComponents();
4061   if(asc)
4062     for(int i=0;i<nbOfTuple;i++,pt+=nbOfComp)
4063       std::sort(pt,pt+nbOfComp);
4064   else
4065     for(int i=0;i<nbOfTuple;i++,pt+=nbOfComp)
4066       std::sort(pt,pt+nbOfComp,std::greater<double>());
4067   declareAsNew();
4068 }
4069
4070 /*!
4071  * Converts every value of \a this array to its absolute value.
4072  * \b WARNING this method is non const. If a new DataArrayDouble instance should be built containing the result of abs DataArrayDouble::computeAbs
4073  * should be called instead.
4074  *
4075  * \throw If \a this is not allocated.
4076  * \sa DataArrayDouble::computeAbs
4077  */
4078 void DataArrayDouble::abs()
4079 {
4080   checkAllocated();
4081   double *ptr(getPointer());
4082   std::size_t nbOfElems(getNbOfElems());
4083   std::transform(ptr,ptr+nbOfElems,ptr,std::ptr_fun<double,double>(fabs));
4084   declareAsNew();
4085 }
4086
4087 /*!
4088  * This method builds a new instance of \a this object containing the result of std::abs applied of all elements in \a this.
4089  * This method is a const method (that do not change any values in \a this) contrary to  DataArrayDouble::abs method.
4090  *
4091  * \return DataArrayDouble * - the new instance of DataArrayDouble containing the
4092  *         same number of tuples and component as \a this array.
4093  *         The caller is to delete this result array using decrRef() as it is no more
4094  *         needed.
4095  * \throw If \a this is not allocated.
4096  * \sa DataArrayDouble::abs
4097  */
4098 DataArrayDouble *DataArrayDouble::computeAbs() const
4099 {
4100   checkAllocated();
4101   DataArrayDouble *newArr(DataArrayDouble::New());
4102   int nbOfTuples(getNumberOfTuples());
4103   int nbOfComp(getNumberOfComponents());
4104   newArr->alloc(nbOfTuples,nbOfComp);
4105   std::transform(begin(),end(),newArr->getPointer(),std::ptr_fun<double,double>(fabs));
4106   newArr->copyStringInfoFrom(*this);
4107   return newArr;
4108 }
4109
4110 /*!
4111  * Apply a linear function to a given component of \a this array, so that
4112  * an array element <em>(x)</em> becomes \f$ a * x + b \f$.
4113  *  \param [in] a - the first coefficient of the function.
4114  *  \param [in] b - the second coefficient of the function.
4115  *  \param [in] compoId - the index of component to modify.
4116  *  \throw If \a this is not allocated, or \a compoId is not in [0,\c this->getNumberOfComponents() ).
4117  */
4118 void DataArrayDouble::applyLin(double a, double b, int compoId)
4119 {
4120   checkAllocated();
4121   double *ptr(getPointer()+compoId);
4122   int nbOfComp(getNumberOfComponents()),nbOfTuple(getNumberOfTuples());
4123   if(compoId<0 || compoId>=nbOfComp)
4124     {
4125       std::ostringstream oss; oss << "DataArrayDouble::applyLin : The compoId requested (" << compoId << ") is not valid ! Must be in [0," << nbOfComp << ") !";
4126       throw INTERP_KERNEL::Exception(oss.str().c_str());
4127     }
4128   for(int i=0;i<nbOfTuple;i++,ptr+=nbOfComp)
4129     *ptr=a*(*ptr)+b;
4130   declareAsNew();
4131 }
4132
4133 /*!
4134  * Apply a linear function to all elements of \a this array, so that
4135  * an element _x_ becomes \f$ a * x + b \f$.
4136  *  \param [in] a - the first coefficient of the function.
4137  *  \param [in] b - the second coefficient of the function.
4138  *  \throw If \a this is not allocated.
4139  */
4140 void DataArrayDouble::applyLin(double a, double b)
4141 {
4142   checkAllocated();
4143   double *ptr=getPointer();
4144   std::size_t nbOfElems=getNbOfElems();
4145   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
4146     *ptr=a*(*ptr)+b;
4147   declareAsNew();
4148 }
4149
4150 /*!
4151  * Modify all elements of \a this array, so that
4152  * an element _x_ becomes \f$ numerator / x \f$.
4153  *  \warning If an exception is thrown because of presence of 0.0 element in \a this 
4154  *           array, all elements processed before detection of the zero element remain
4155  *           modified.
4156  *  \param [in] numerator - the numerator used to modify array elements.
4157  *  \throw If \a this is not allocated.
4158  *  \throw If there is an element equal to 0.0 in \a this array.
4159  */
4160 void DataArrayDouble::applyInv(double numerator)
4161 {
4162   checkAllocated();
4163   double *ptr=getPointer();
4164   std::size_t nbOfElems=getNbOfElems();
4165   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
4166     {
4167       if(std::abs(*ptr)>std::numeric_limits<double>::min())
4168         {
4169           *ptr=numerator/(*ptr);
4170         }
4171       else
4172         {
4173           std::ostringstream oss; oss << "DataArrayDouble::applyInv : presence of null value in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
4174           oss << " !";
4175           throw INTERP_KERNEL::Exception(oss.str().c_str());
4176         }
4177     }
4178   declareAsNew();
4179 }
4180
4181 /*!
4182  * Returns a full copy of \a this array except that sign of all elements is reversed.
4183  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
4184  *          same number of tuples and component as \a this array.
4185  *          The caller is to delete this result array using decrRef() as it is no more
4186  *          needed.
4187  *  \throw If \a this is not allocated.
4188  */
4189 DataArrayDouble *DataArrayDouble::negate() const
4190 {
4191   checkAllocated();
4192   DataArrayDouble *newArr=DataArrayDouble::New();
4193   int nbOfTuples=getNumberOfTuples();
4194   int nbOfComp=getNumberOfComponents();
4195   newArr->alloc(nbOfTuples,nbOfComp);
4196   const double *cptr=getConstPointer();
4197   std::transform(cptr,cptr+nbOfTuples*nbOfComp,newArr->getPointer(),std::negate<double>());
4198   newArr->copyStringInfoFrom(*this);
4199   return newArr;
4200 }
4201
4202 /*!
4203  * Modify all elements of \a this array, so that
4204  * an element _x_ becomes <em> val ^ x </em>. Contrary to DataArrayInt::applyPow
4205  * all values in \a this have to be >= 0 if val is \b not integer.
4206  *  \param [in] val - the value used to apply pow on all array elements.
4207  *  \throw If \a this is not allocated.
4208  *  \warning If an exception is thrown because of presence of 0 element in \a this 
4209  *           array and \a val is \b not integer, all elements processed before detection of the zero element remain
4210  *           modified.
4211  */
4212 void DataArrayDouble::applyPow(double val)
4213 {
4214   checkAllocated();
4215   double *ptr=getPointer();
4216   std::size_t nbOfElems=getNbOfElems();
4217   int val2=(int)val;
4218   bool isInt=((double)val2)==val;
4219   if(!isInt)
4220     {
4221       for(std::size_t i=0;i<nbOfElems;i++,ptr++)
4222         {
4223           if(*ptr>=0)
4224             *ptr=pow(*ptr,val);
4225           else
4226             {
4227               std::ostringstream oss; oss << "DataArrayDouble::applyPow (double) : At elem # " << i << " value is " << *ptr << " ! must be >=0. !";
4228               throw INTERP_KERNEL::Exception(oss.str().c_str());
4229             }
4230         }
4231     }
4232   else
4233     {
4234       for(std::size_t i=0;i<nbOfElems;i++,ptr++)
4235         *ptr=pow(*ptr,val2);
4236     }
4237   declareAsNew();
4238 }
4239
4240 /*!
4241  * Modify all elements of \a this array, so that
4242  * an element _x_ becomes \f$ val ^ x \f$.
4243  *  \param [in] val - the value used to apply pow on all array elements.
4244  *  \throw If \a this is not allocated.
4245  *  \throw If \a val < 0.
4246  *  \warning If an exception is thrown because of presence of 0 element in \a this 
4247  *           array, all elements processed before detection of the zero element remain
4248  *           modified.
4249  */
4250 void DataArrayDouble::applyRPow(double val)
4251 {
4252   checkAllocated();
4253   if(val<0.)
4254     throw INTERP_KERNEL::Exception("DataArrayDouble::applyRPow : the input value has to be >= 0 !");
4255   double *ptr=getPointer();
4256   std::size_t nbOfElems=getNbOfElems();
4257   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
4258     *ptr=pow(val,*ptr);
4259   declareAsNew();
4260 }
4261
4262 /*!
4263  * Returns a new DataArrayDouble created from \a this one by applying \a
4264  * FunctionToEvaluate to every tuple of \a this array. Textual data is not copied.
4265  * For more info see \ref MEDCouplingArrayApplyFunc
4266  *  \param [in] nbOfComp - number of components in the result array.
4267  *  \param [in] func - the \a FunctionToEvaluate declared as 
4268  *              \c bool (*\a func)(\c const \c double *\a pos, \c double *\a res), 
4269  *              where \a pos points to the first component of a tuple of \a this array
4270  *              and \a res points to the first component of a tuple of the result array.
4271  *              Note that length (number of components) of \a pos can differ from
4272  *              that of \a res.
4273  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
4274  *          same number of tuples as \a this array.
4275  *          The caller is to delete this result array using decrRef() as it is no more
4276  *          needed.
4277  *  \throw If \a this is not allocated.
4278  *  \throw If \a func returns \a false.
4279  */
4280 DataArrayDouble *DataArrayDouble::applyFunc(int nbOfComp, FunctionToEvaluate func) const
4281 {
4282   checkAllocated();
4283   DataArrayDouble *newArr=DataArrayDouble::New();
4284   int nbOfTuples=getNumberOfTuples();
4285   int oldNbOfComp=getNumberOfComponents();
4286   newArr->alloc(nbOfTuples,nbOfComp);
4287   const double *ptr=getConstPointer();
4288   double *ptrToFill=newArr->getPointer();
4289   for(int i=0;i<nbOfTuples;i++)
4290     {
4291       if(!func(ptr+i*oldNbOfComp,ptrToFill+i*nbOfComp))
4292         {
4293           std::ostringstream oss; oss << "For tuple # " << i << " with value (";
4294           std::copy(ptr+oldNbOfComp*i,ptr+oldNbOfComp*(i+1),std::ostream_iterator<double>(oss,", "));
4295           oss << ") : Evaluation of function failed !";
4296           newArr->decrRef();
4297           throw INTERP_KERNEL::Exception(oss.str().c_str());
4298         }
4299     }
4300   return newArr;
4301 }
4302
4303 /*!
4304  * Returns a new DataArrayDouble created from \a this one by applying a function to every
4305  * tuple of \a this array. Textual data is not copied.
4306  * For more info see \ref MEDCouplingArrayApplyFunc1.
4307  *  \param [in] nbOfComp - number of components in the result array.
4308  *  \param [in] func - the expression defining how to transform a tuple of \a this array.
4309  *              Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
4310  *  \param [in] isSafe - By default true. If true invalid operation (division by 0. acos of value > 1. ...) leads to a throw of an exception.
4311  *              If false the computation is carried on without any notification. When false the evaluation is a little faster.
4312  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
4313  *          same number of tuples as \a this array and \a nbOfComp components.
4314  *          The caller is to delete this result array using decrRef() as it is no more
4315  *          needed.
4316  *  \throw If \a this is not allocated.
4317  *  \throw If computing \a func fails.
4318  */
4319 DataArrayDouble *DataArrayDouble::applyFunc(int nbOfComp, const std::string& func, bool isSafe) const
4320 {
4321   INTERP_KERNEL::ExprParser expr(func);
4322   expr.parse();
4323   std::set<std::string> vars;
4324   expr.getTrueSetOfVars(vars);
4325   std::vector<std::string> varsV(vars.begin(),vars.end());
4326   return applyFunc3(nbOfComp,varsV,func,isSafe);
4327 }
4328
4329 /*!
4330  * Returns a new DataArrayDouble created from \a this one by applying a function to every
4331  * tuple of \a this array. Textual data is not copied. This method works by tuples (whatever its size).
4332  * If \a this is a one component array, call applyFuncOnThis instead that performs the same work faster.
4333  *
4334  * For more info see \ref MEDCouplingArrayApplyFunc0.
4335  *  \param [in] func - the expression defining how to transform a tuple of \a this array.
4336  *              Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
4337  *  \param [in] isSafe - By default true. If true invalid operation (division by 0. acos of value > 1. ...) leads to a throw of an exception.
4338  *                       If false the computation is carried on without any notification. When false the evaluation is a little faster.
4339  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
4340  *          same number of tuples and components as \a this array.
4341  *          The caller is to delete this result array using decrRef() as it is no more
4342  *          needed.
4343  *  \sa applyFuncOnThis
4344  *  \throw If \a this is not allocated.
4345  *  \throw If computing \a func fails.
4346  */
4347 DataArrayDouble *DataArrayDouble::applyFunc(const std::string& func, bool isSafe) const
4348 {
4349   int nbOfComp(getNumberOfComponents());
4350   if(nbOfComp<=0)
4351     throw INTERP_KERNEL::Exception("DataArrayDouble::applyFunc : output number of component must be > 0 !");
4352   checkAllocated();
4353   int nbOfTuples(getNumberOfTuples());
4354   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> newArr(DataArrayDouble::New());
4355   newArr->alloc(nbOfTuples,nbOfComp);
4356   INTERP_KERNEL::ExprParser expr(func);
4357   expr.parse();
4358   std::set<std::string> vars;
4359   expr.getTrueSetOfVars(vars);
4360   if((int)vars.size()>1)
4361     {
4362       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 : ";
4363       std::copy(vars.begin(),vars.end(),std::ostream_iterator<std::string>(oss," "));
4364       throw INTERP_KERNEL::Exception(oss.str().c_str());
4365     }
4366   if(vars.empty())
4367     {
4368       expr.prepareFastEvaluator();
4369       newArr->rearrange(1);
4370       newArr->fillWithValue(expr.evaluateDouble());
4371       newArr->rearrange(nbOfComp);
4372       return newArr.retn();
4373     }
4374   std::vector<std::string> vars2(vars.begin(),vars.end());
4375   double buff,*ptrToFill(newArr->getPointer());
4376   const double *ptr(begin());
4377   std::vector<double> stck;
4378   expr.prepareExprEvaluationDouble(vars2,1,1,0,&buff,&buff+1);
4379   expr.prepareFastEvaluator();
4380   if(!isSafe)
4381     {
4382       for(int i=0;i<nbOfTuples;i++)
4383         {
4384           for(int iComp=0;iComp<nbOfComp;iComp++,ptr++,ptrToFill++)
4385             {
4386               buff=*ptr;
4387               expr.evaluateDoubleInternal(stck);
4388               *ptrToFill=stck.back();
4389               stck.pop_back();
4390             }
4391         }
4392     }
4393   else
4394     {
4395       for(int i=0;i<nbOfTuples;i++)
4396         {
4397           for(int iComp=0;iComp<nbOfComp;iComp++,ptr++,ptrToFill++)
4398             {
4399               buff=*ptr;
4400               try
4401               {
4402                   expr.evaluateDoubleInternalSafe(stck);
4403               }
4404               catch(INTERP_KERNEL::Exception& e)
4405               {
4406                   std::ostringstream oss; oss << "For tuple # " << i << " component # " << iComp << " with value (";
4407                   oss << buff;
4408                   oss << ") : Evaluation of function failed !" << e.what();
4409                   throw INTERP_KERNEL::Exception(oss.str().c_str());
4410               }
4411               *ptrToFill=stck.back();
4412               stck.pop_back();
4413             }
4414         }
4415     }
4416   return newArr.retn();
4417 }
4418
4419 /*!
4420  * This method is a non const method that modify the array in \a this.
4421  * This method only works on one component array. It means that function \a func must
4422  * contain at most one variable.
4423  * This method is a specialization of applyFunc method with one parameter on one component array.
4424  *
4425  *  \param [in] func - the expression defining how to transform a tuple of \a this array.
4426  *              Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
4427  *  \param [in] isSafe - By default true. If true invalid operation (division by 0. acos of value > 1. ...) leads to a throw of an exception.
4428  *              If false the computation is carried on without any notification. When false the evaluation is a little faster.
4429  *
4430  * \sa applyFunc
4431  */
4432 void DataArrayDouble::applyFuncOnThis(const std::string& func, bool isSafe)
4433 {
4434   int nbOfComp(getNumberOfComponents());
4435   if(nbOfComp<=0)
4436     throw INTERP_KERNEL::Exception("DataArrayDouble::applyFuncOnThis : output number of component must be > 0 !");
4437   checkAllocated();
4438   int nbOfTuples(getNumberOfTuples());
4439   INTERP_KERNEL::ExprParser expr(func);
4440   expr.parse();
4441   std::set<std::string> vars;
4442   expr.getTrueSetOfVars(vars);
4443   if((int)vars.size()>1)
4444     {
4445       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 : ";
4446       std::copy(vars.begin(),vars.end(),std::ostream_iterator<std::string>(oss," "));
4447       throw INTERP_KERNEL::Exception(oss.str().c_str());
4448     }
4449   if(vars.empty())
4450     {
4451       expr.prepareFastEvaluator();
4452       std::vector<std::string> compInfo(getInfoOnComponents());
4453       rearrange(1);
4454       fillWithValue(expr.evaluateDouble());
4455       rearrange(nbOfComp);
4456       setInfoOnComponents(compInfo);
4457       return ;
4458     }
4459   std::vector<std::string> vars2(vars.begin(),vars.end());
4460   double buff,*ptrToFill(getPointer());
4461   const double *ptr(begin());
4462   std::vector<double> stck;
4463   expr.prepareExprEvaluationDouble(vars2,1,1,0,&buff,&buff+1);
4464   expr.prepareFastEvaluator();
4465   if(!isSafe)
4466     {
4467       for(int i=0;i<nbOfTuples;i++)
4468         {
4469           for(int iComp=0;iComp<nbOfComp;iComp++,ptr++,ptrToFill++)
4470             {
4471               buff=*ptr;
4472               expr.evaluateDoubleInternal(stck);
4473               *ptrToFill=stck.back();
4474               stck.pop_back();
4475             }
4476         }
4477     }
4478   else
4479     {
4480       for(int i=0;i<nbOfTuples;i++)
4481         {
4482           for(int iComp=0;iComp<nbOfComp;iComp++,ptr++,ptrToFill++)
4483             {
4484               buff=*ptr;
4485               try
4486               {
4487                   expr.evaluateDoubleInternalSafe(stck);
4488               }
4489               catch(INTERP_KERNEL::Exception& e)
4490               {
4491                   std::ostringstream oss; oss << "For tuple # " << i << " component # " << iComp << " with value (";
4492                   oss << buff;
4493                   oss << ") : Evaluation of function failed !" << e.what();
4494                   throw INTERP_KERNEL::Exception(oss.str().c_str());
4495               }
4496               *ptrToFill=stck.back();
4497               stck.pop_back();
4498             }
4499         }
4500     }
4501 }
4502
4503 /*!
4504  * Returns a new DataArrayDouble created from \a this one by applying a function to every
4505  * tuple of \a this array. Textual data is not copied.
4506  * For more info see \ref MEDCouplingArrayApplyFunc2.
4507  *  \param [in] nbOfComp - number of components in the result array.
4508  *  \param [in] func - the expression defining how to transform a tuple of \a this array.
4509  *              Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
4510  *  \param [in] isSafe - By default true. If true invalid operation (division by 0. acos of value > 1. ...) leads to a throw of an exception.
4511  *              If false the computation is carried on without any notification. When false the evaluation is a little faster.
4512  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
4513  *          same number of tuples as \a this array.
4514  *          The caller is to delete this result array using decrRef() as it is no more
4515  *          needed.
4516  *  \throw If \a this is not allocated.
4517  *  \throw If \a func contains vars that are not in \a this->getInfoOnComponent().
4518  *  \throw If computing \a func fails.
4519  */
4520 DataArrayDouble *DataArrayDouble::applyFunc2(int nbOfComp, const std::string& func, bool isSafe) const
4521 {
4522   return applyFunc3(nbOfComp,getVarsOnComponent(),func,isSafe);
4523 }
4524
4525 /*!
4526  * Returns a new DataArrayDouble created from \a this one by applying a function to every
4527  * tuple of \a this array. Textual data is not copied.
4528  * For more info see \ref MEDCouplingArrayApplyFunc3.
4529  *  \param [in] nbOfComp - number of components in the result array.
4530  *  \param [in] varsOrder - sequence of vars defining their order.
4531  *  \param [in] func - the expression defining how to transform a tuple of \a this array.
4532  *              Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
4533  *  \param [in] isSafe - By default true. If true invalid operation (division by 0. acos of value > 1. ...) leads to a throw of an exception.
4534  *              If false the computation is carried on without any notification. When false the evaluation is a little faster.
4535  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
4536  *          same number of tuples as \a this array.
4537  *          The caller is to delete this result array using decrRef() as it is no more
4538  *          needed.
4539  *  \throw If \a this is not allocated.
4540  *  \throw If \a func contains vars not in \a varsOrder.
4541  *  \throw If computing \a func fails.
4542  */
4543 DataArrayDouble *DataArrayDouble::applyFunc3(int nbOfComp, const std::vector<std::string>& varsOrder, const std::string& func, bool isSafe) const
4544 {
4545   if(nbOfComp<=0)
4546     throw INTERP_KERNEL::Exception("DataArrayDouble::applyFunc3 : output number of component must be > 0 !");
4547   std::vector<std::string> varsOrder2(varsOrder);
4548   int oldNbOfComp(getNumberOfComponents());
4549   for(int i=(int)varsOrder.size();i<oldNbOfComp;i++)
4550     varsOrder2.push_back(std::string());
4551   checkAllocated();
4552   int nbOfTuples(getNumberOfTuples());
4553   INTERP_KERNEL::ExprParser expr(func);
4554   expr.parse();
4555   std::set<std::string> vars;
4556   expr.getTrueSetOfVars(vars);
4557   if((int)vars.size()>oldNbOfComp)
4558     {
4559       std::ostringstream oss; oss << "The field has " << oldNbOfComp << " components and there are ";
4560       oss << vars.size() << " variables : ";
4561       std::copy(vars.begin(),vars.end(),std::ostream_iterator<std::string>(oss," "));
4562       throw INTERP_KERNEL::Exception(oss.str().c_str());
4563     }
4564   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> newArr(DataArrayDouble::New());
4565   newArr->alloc(nbOfTuples,nbOfComp);
4566   INTERP_KERNEL::AutoPtr<double> buff(new double[oldNbOfComp]);
4567   double *buffPtr(buff),*ptrToFill;
4568   std::vector<double> stck;
4569   for(int iComp=0;iComp<nbOfComp;iComp++)
4570     {
4571       expr.prepareExprEvaluationDouble(varsOrder2,oldNbOfComp,nbOfComp,iComp,buffPtr,buffPtr+oldNbOfComp);
4572       expr.prepareFastEvaluator();
4573       const double *ptr(getConstPointer());
4574       ptrToFill=newArr->getPointer()+iComp;
4575       if(!isSafe)
4576         {
4577           for(int i=0;i<nbOfTuples;i++,ptrToFill+=nbOfComp,ptr+=oldNbOfComp)
4578             {
4579               std::copy(ptr,ptr+oldNbOfComp,buffPtr);
4580               expr.evaluateDoubleInternal(stck);
4581               *ptrToFill=stck.back();
4582               stck.pop_back();
4583             }
4584         }
4585       else
4586         {
4587           for(int i=0;i<nbOfTuples;i++,ptrToFill+=nbOfComp,ptr+=oldNbOfComp)
4588             {
4589               std::copy(ptr,ptr+oldNbOfComp,buffPtr);
4590               try
4591               {
4592                   expr.evaluateDoubleInternalSafe(stck);
4593                   *ptrToFill=stck.back();
4594                   stck.pop_back();
4595               }
4596               catch(INTERP_KERNEL::Exception& e)
4597               {
4598                   std::ostringstream oss; oss << "For tuple # " << i << " with value (";
4599                   std::copy(ptr+oldNbOfComp*i,ptr+oldNbOfComp*(i+1),std::ostream_iterator<double>(oss,", "));
4600                   oss << ") : Evaluation of function failed !" << e.what();
4601                   throw INTERP_KERNEL::Exception(oss.str().c_str());
4602               }
4603             }
4604         }
4605     }
4606   return newArr.retn();
4607 }
4608
4609 void DataArrayDouble::applyFuncFast32(const std::string& func)
4610 {
4611   checkAllocated();
4612   INTERP_KERNEL::ExprParser expr(func);
4613   expr.parse();
4614   char *funcStr=expr.compileX86();
4615   MYFUNCPTR funcPtr;
4616   *((void **)&funcPtr)=funcStr;//he he...
4617   //
4618   double *ptr=getPointer();
4619   int nbOfComp=getNumberOfComponents();
4620   int nbOfTuples=getNumberOfTuples();
4621   int nbOfElems=nbOfTuples*nbOfComp;
4622   for(int i=0;i<nbOfElems;i++,ptr++)
4623     *ptr=funcPtr(*ptr);
4624   declareAsNew();
4625 }
4626
4627 void DataArrayDouble::applyFuncFast64(const std::string& func)
4628 {
4629   checkAllocated();
4630   INTERP_KERNEL::ExprParser expr(func);
4631   expr.parse();
4632   char *funcStr=expr.compileX86_64();
4633   MYFUNCPTR funcPtr;
4634   *((void **)&funcPtr)=funcStr;//he he...
4635   //
4636   double *ptr=getPointer();
4637   int nbOfComp=getNumberOfComponents();
4638   int nbOfTuples=getNumberOfTuples();
4639   int nbOfElems=nbOfTuples*nbOfComp;
4640   for(int i=0;i<nbOfElems;i++,ptr++)
4641     *ptr=funcPtr(*ptr);
4642   declareAsNew();
4643 }
4644
4645 DataArrayDoubleIterator *DataArrayDouble::iterator()
4646 {
4647   return new DataArrayDoubleIterator(this);
4648 }
4649
4650 /*!
4651  * Returns a new DataArrayInt contating indices of tuples of \a this one-dimensional
4652  * array whose values are within a given range. Textual data is not copied.
4653  *  \param [in] vmin - a lowest acceptable value (included).
4654  *  \param [in] vmax - a greatest acceptable value (included).
4655  *  \return DataArrayInt * - the new instance of DataArrayInt.
4656  *          The caller is to delete this result array using decrRef() as it is no more
4657  *          needed.
4658  *  \throw If \a this->getNumberOfComponents() != 1.
4659  *
4660  *  \sa DataArrayDouble::getIdsNotInRange
4661  *
4662  *  \if ENABLE_EXAMPLES
4663  *  \ref cpp_mcdataarraydouble_getidsinrange "Here is a C++ example".<br>
4664  *  \ref py_mcdataarraydouble_getidsinrange "Here is a Python example".
4665  *  \endif
4666  */
4667 DataArrayInt *DataArrayDouble::getIdsInRange(double vmin, double vmax) const
4668 {
4669   checkAllocated();
4670   if(getNumberOfComponents()!=1)
4671     throw INTERP_KERNEL::Exception("DataArrayDouble::getIdsInRange : this must have exactly one component !");
4672   const double *cptr(begin());
4673   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
4674   int nbOfTuples(getNumberOfTuples());
4675   for(int i=0;i<nbOfTuples;i++,cptr++)
4676     if(*cptr>=vmin && *cptr<=vmax)
4677       ret->pushBackSilent(i);
4678   return ret.retn();
4679 }
4680
4681 /*!
4682  * Returns a new DataArrayInt contating indices of tuples of \a this one-dimensional
4683  * array whose values are not within a given range. Textual data is not copied.
4684  *  \param [in] vmin - a lowest not acceptable value (excluded).
4685  *  \param [in] vmax - a greatest not acceptable value (excluded).
4686  *  \return DataArrayInt * - the new instance of DataArrayInt.
4687  *          The caller is to delete this result array using decrRef() as it is no more
4688  *          needed.
4689  *  \throw If \a this->getNumberOfComponents() != 1.
4690  *
4691  *  \sa DataArrayDouble::getIdsInRange
4692  */
4693 DataArrayInt *DataArrayDouble::getIdsNotInRange(double vmin, double vmax) const
4694 {
4695   checkAllocated();
4696   if(getNumberOfComponents()!=1)
4697     throw INTERP_KERNEL::Exception("DataArrayDouble::getIdsNotInRange : this must have exactly one component !");
4698   const double *cptr(begin());
4699   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
4700   int nbOfTuples(getNumberOfTuples());
4701   for(int i=0;i<nbOfTuples;i++,cptr++)
4702     if(*cptr<vmin || *cptr>vmax)
4703       ret->pushBackSilent(i);
4704   return ret.retn();
4705 }
4706
4707 /*!
4708  * Returns a new DataArrayDouble by concatenating two given arrays, so that (1) the number
4709  * of tuples in the result array is a sum of the number of tuples of given arrays and (2)
4710  * the number of component in the result array is same as that of each of given arrays.
4711  * Info on components is copied from the first of the given arrays. Number of components
4712  * in the given arrays must be  the same.
4713  *  \param [in] a1 - an array to include in the result array.
4714  *  \param [in] a2 - another array to include in the result array.
4715  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4716  *          The caller is to delete this result array using decrRef() as it is no more
4717  *          needed.
4718  *  \throw If both \a a1 and \a a2 are NULL.
4719  *  \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents().
4720  */
4721 DataArrayDouble *DataArrayDouble::Aggregate(const DataArrayDouble *a1, const DataArrayDouble *a2)
4722 {
4723   std::vector<const DataArrayDouble *> tmp(2);
4724   tmp[0]=a1; tmp[1]=a2;
4725   return Aggregate(tmp);
4726 }
4727
4728 /*!
4729  * Returns a new DataArrayDouble by concatenating all given arrays, so that (1) the number
4730  * of tuples in the result array is a sum of the number of tuples of given arrays and (2)
4731  * the number of component in the result array is same as that of each of given arrays.
4732  * Info on components is copied from the first of the given arrays. Number of components
4733  * in the given arrays must be  the same.
4734  * If the number of non null of elements in \a arr is equal to one the returned object is a copy of it
4735  * not the object itself.
4736  *  \param [in] arr - a sequence of arrays to include in the result array.
4737  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4738  *          The caller is to delete this result array using decrRef() as it is no more
4739  *          needed.
4740  *  \throw If all arrays within \a arr are NULL.
4741  *  \throw If getNumberOfComponents() of arrays within \a arr.
4742  */
4743 DataArrayDouble *DataArrayDouble::Aggregate(const std::vector<const DataArrayDouble *>& arr)
4744 {
4745   std::vector<const DataArrayDouble *> a;
4746   for(std::vector<const DataArrayDouble *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
4747     if(*it4)
4748       a.push_back(*it4);
4749   if(a.empty())
4750     throw INTERP_KERNEL::Exception("DataArrayDouble::Aggregate : input list must contain at least one NON EMPTY DataArrayDouble !");
4751   std::vector<const DataArrayDouble *>::const_iterator it=a.begin();
4752   int nbOfComp=(*it)->getNumberOfComponents();
4753   int nbt=(*it++)->getNumberOfTuples();
4754   for(int i=1;it!=a.end();it++,i++)
4755     {
4756       if((*it)->getNumberOfComponents()!=nbOfComp)
4757         throw INTERP_KERNEL::Exception("DataArrayDouble::Aggregate : Nb of components mismatch for array aggregation !");
4758       nbt+=(*it)->getNumberOfTuples();
4759     }
4760   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
4761   ret->alloc(nbt,nbOfComp);
4762   double *pt=ret->getPointer();
4763   for(it=a.begin();it!=a.end();it++)
4764     pt=std::copy((*it)->getConstPointer(),(*it)->getConstPointer()+(*it)->getNbOfElems(),pt);
4765   ret->copyStringInfoFrom(*(a[0]));
4766   return ret.retn();
4767 }
4768
4769 /*!
4770  * Returns a new DataArrayDouble by aggregating two given arrays, so that (1) the number
4771  * of components in the result array is a sum of the number of components of given arrays
4772  * and (2) the number of tuples in the result array is same as that of each of given
4773  * arrays. In other words the i-th tuple of result array includes all components of
4774  * i-th tuples of all given arrays.
4775  * Number of tuples in the given arrays must be  the same.
4776  *  \param [in] a1 - an array to include in the result array.
4777  *  \param [in] a2 - another array to include in the result array.
4778  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4779  *          The caller is to delete this result array using decrRef() as it is no more
4780  *          needed.
4781  *  \throw If both \a a1 and \a a2 are NULL.
4782  *  \throw If any given array is not allocated.
4783  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
4784  */
4785 DataArrayDouble *DataArrayDouble::Meld(const DataArrayDouble *a1, const DataArrayDouble *a2)
4786 {
4787   std::vector<const DataArrayDouble *> arr(2);
4788   arr[0]=a1; arr[1]=a2;
4789   return Meld(arr);
4790 }
4791
4792 /*!
4793  * Returns a new DataArrayDouble by aggregating all given arrays, so that (1) the number
4794  * of components in the result array is a sum of the number of components of given arrays
4795  * and (2) the number of tuples in the result array is same as that of each of given
4796  * arrays. In other words the i-th tuple of result array includes all components of
4797  * i-th tuples of all given arrays.
4798  * Number of tuples in the given arrays must be  the same.
4799  *  \param [in] arr - a sequence of arrays to include in the result array.
4800  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4801  *          The caller is to delete this result array using decrRef() as it is no more
4802  *          needed.
4803  *  \throw If all arrays within \a arr are NULL.
4804  *  \throw If any given array is not allocated.
4805  *  \throw If getNumberOfTuples() of arrays within \a arr is different.
4806  */
4807 DataArrayDouble *DataArrayDouble::Meld(const std::vector<const DataArrayDouble *>& arr)
4808 {
4809   std::vector<const DataArrayDouble *> a;
4810   for(std::vector<const DataArrayDouble *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
4811     if(*it4)
4812       a.push_back(*it4);
4813   if(a.empty())
4814     throw INTERP_KERNEL::Exception("DataArrayDouble::Meld : input list must contain at least one NON EMPTY DataArrayDouble !");
4815   std::vector<const DataArrayDouble *>::const_iterator it;
4816   for(it=a.begin();it!=a.end();it++)
4817     (*it)->checkAllocated();
4818   it=a.begin();
4819   int nbOfTuples=(*it)->getNumberOfTuples();
4820   std::vector<int> nbc(a.size());
4821   std::vector<const double *> pts(a.size());
4822   nbc[0]=(*it)->getNumberOfComponents();
4823   pts[0]=(*it++)->getConstPointer();
4824   for(int i=1;it!=a.end();it++,i++)
4825     {
4826       if(nbOfTuples!=(*it)->getNumberOfTuples())
4827         throw INTERP_KERNEL::Exception("DataArrayDouble::Meld : mismatch of number of tuples !");
4828       nbc[i]=(*it)->getNumberOfComponents();
4829       pts[i]=(*it)->getConstPointer();
4830     }
4831   int totalNbOfComp=std::accumulate(nbc.begin(),nbc.end(),0);
4832   DataArrayDouble *ret=DataArrayDouble::New();
4833   ret->alloc(nbOfTuples,totalNbOfComp);
4834   double *retPtr=ret->getPointer();
4835   for(int i=0;i<nbOfTuples;i++)
4836     for(int j=0;j<(int)a.size();j++)
4837       {
4838         retPtr=std::copy(pts[j],pts[j]+nbc[j],retPtr);
4839         pts[j]+=nbc[j];
4840       }
4841   int k=0;
4842   for(int i=0;i<(int)a.size();i++)
4843     for(int j=0;j<nbc[i];j++,k++)
4844       ret->setInfoOnComponent(k,a[i]->getInfoOnComponent(j));
4845   return ret;
4846 }
4847
4848 /*!
4849  * Returns a new DataArrayDouble containing a dot product of two given arrays, so that
4850  * the i-th tuple of the result array is a sum of products of j-th components of i-th
4851  * tuples of given arrays (\f$ a_i = \sum_{j=1}^n a1_j * a2_j \f$).
4852  * Info on components and name is copied from the first of the given arrays.
4853  * Number of tuples and components in the given arrays must be the same.
4854  *  \param [in] a1 - a given array.
4855  *  \param [in] a2 - another given array.
4856  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4857  *          The caller is to delete this result array using decrRef() as it is no more
4858  *          needed.
4859  *  \throw If either \a a1 or \a a2 is NULL.
4860  *  \throw If any given array is not allocated.
4861  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
4862  *  \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents()
4863  */
4864 DataArrayDouble *DataArrayDouble::Dot(const DataArrayDouble *a1, const DataArrayDouble *a2)
4865 {
4866   if(!a1 || !a2)
4867     throw INTERP_KERNEL::Exception("DataArrayDouble::Dot : input DataArrayDouble instance is NULL !");
4868   a1->checkAllocated();
4869   a2->checkAllocated();
4870   int nbOfComp=a1->getNumberOfComponents();
4871   if(nbOfComp!=a2->getNumberOfComponents())
4872     throw INTERP_KERNEL::Exception("Nb of components mismatch for array Dot !");
4873   int nbOfTuple=a1->getNumberOfTuples();
4874   if(nbOfTuple!=a2->getNumberOfTuples())
4875     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Dot !");
4876   DataArrayDouble *ret=DataArrayDouble::New();
4877   ret->alloc(nbOfTuple,1);
4878   double *retPtr=ret->getPointer();
4879   const double *a1Ptr=a1->getConstPointer();
4880   const double *a2Ptr=a2->getConstPointer();
4881   for(int i=0;i<nbOfTuple;i++)
4882     {
4883       double sum=0.;
4884       for(int j=0;j<nbOfComp;j++)
4885         sum+=a1Ptr[i*nbOfComp+j]*a2Ptr[i*nbOfComp+j];
4886       retPtr[i]=sum;
4887     }
4888   ret->setInfoOnComponent(0,a1->getInfoOnComponent(0));
4889   ret->setName(a1->getName());
4890   return ret;
4891 }
4892
4893 /*!
4894  * Returns a new DataArrayDouble containing a cross product of two given arrays, so that
4895  * the i-th tuple of the result array contains 3 components of a vector which is a cross
4896  * product of two vectors defined by the i-th tuples of given arrays.
4897  * Info on components is copied from the first of the given arrays.
4898  * Number of tuples in the given arrays must be the same.
4899  * Number of components in the given arrays must be 3.
4900  *  \param [in] a1 - a given array.
4901  *  \param [in] a2 - another given array.
4902  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4903  *          The caller is to delete this result array using decrRef() as it is no more
4904  *          needed.
4905  *  \throw If either \a a1 or \a a2 is NULL.
4906  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
4907  *  \throw If \a a1->getNumberOfComponents() != 3
4908  *  \throw If \a a2->getNumberOfComponents() != 3
4909  */
4910 DataArrayDouble *DataArrayDouble::CrossProduct(const DataArrayDouble *a1, const DataArrayDouble *a2)
4911 {
4912   if(!a1 || !a2)
4913     throw INTERP_KERNEL::Exception("DataArrayDouble::CrossProduct : input DataArrayDouble instance is NULL !");
4914   int nbOfComp=a1->getNumberOfComponents();
4915   if(nbOfComp!=a2->getNumberOfComponents())
4916     throw INTERP_KERNEL::Exception("Nb of components mismatch for array crossProduct !");
4917   if(nbOfComp!=3)
4918     throw INTERP_KERNEL::Exception("Nb of components must be equal to 3 for array crossProduct !");
4919   int nbOfTuple=a1->getNumberOfTuples();
4920   if(nbOfTuple!=a2->getNumberOfTuples())
4921     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array crossProduct !");
4922   DataArrayDouble *ret=DataArrayDouble::New();
4923   ret->alloc(nbOfTuple,3);
4924   double *retPtr=ret->getPointer();
4925   const double *a1Ptr=a1->getConstPointer();
4926   const double *a2Ptr=a2->getConstPointer();
4927   for(int i=0;i<nbOfTuple;i++)
4928     {
4929       retPtr[3*i]=a1Ptr[3*i+1]*a2Ptr[3*i+2]-a1Ptr[3*i+2]*a2Ptr[3*i+1];
4930       retPtr[3*i+1]=a1Ptr[3*i+2]*a2Ptr[3*i]-a1Ptr[3*i]*a2Ptr[3*i+2];
4931       retPtr[3*i+2]=a1Ptr[3*i]*a2Ptr[3*i+1]-a1Ptr[3*i+1]*a2Ptr[3*i];
4932     }
4933   ret->copyStringInfoFrom(*a1);
4934   return ret;
4935 }
4936
4937 /*!
4938  * Returns a new DataArrayDouble containing maximal values of two given arrays.
4939  * Info on components is copied from the first of the given arrays.
4940  * Number of tuples and components in the given arrays must be the same.
4941  *  \param [in] a1 - an array to compare values with another one.
4942  *  \param [in] a2 - another array to compare values with the first one.
4943  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4944  *          The caller is to delete this result array using decrRef() as it is no more
4945  *          needed.
4946  *  \throw If either \a a1 or \a a2 is NULL.
4947  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
4948  *  \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents()
4949  */
4950 DataArrayDouble *DataArrayDouble::Max(const DataArrayDouble *a1, const DataArrayDouble *a2)
4951 {
4952   if(!a1 || !a2)
4953     throw INTERP_KERNEL::Exception("DataArrayDouble::Max : input DataArrayDouble instance is NULL !");
4954   int nbOfComp=a1->getNumberOfComponents();
4955   if(nbOfComp!=a2->getNumberOfComponents())
4956     throw INTERP_KERNEL::Exception("Nb of components mismatch for array Max !");
4957   int nbOfTuple=a1->getNumberOfTuples();
4958   if(nbOfTuple!=a2->getNumberOfTuples())
4959     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Max !");
4960   DataArrayDouble *ret=DataArrayDouble::New();
4961   ret->alloc(nbOfTuple,nbOfComp);
4962   double *retPtr=ret->getPointer();
4963   const double *a1Ptr=a1->getConstPointer();
4964   const double *a2Ptr=a2->getConstPointer();
4965   int nbElem=nbOfTuple*nbOfComp;
4966   for(int i=0;i<nbElem;i++)
4967     retPtr[i]=std::max(a1Ptr[i],a2Ptr[i]);
4968   ret->copyStringInfoFrom(*a1);
4969   return ret;
4970 }
4971
4972 /*!
4973  * Returns a new DataArrayDouble containing minimal values of two given arrays.
4974  * Info on components is copied from the first of the given arrays.
4975  * Number of tuples and components in the given arrays must be the same.
4976  *  \param [in] a1 - an array to compare values with another one.
4977  *  \param [in] a2 - another array to compare values with the first one.
4978  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4979  *          The caller is to delete this result array using decrRef() as it is no more
4980  *          needed.
4981  *  \throw If either \a a1 or \a a2 is NULL.
4982  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
4983  *  \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents()
4984  */
4985 DataArrayDouble *DataArrayDouble::Min(const DataArrayDouble *a1, const DataArrayDouble *a2)
4986 {
4987   if(!a1 || !a2)
4988     throw INTERP_KERNEL::Exception("DataArrayDouble::Min : input DataArrayDouble instance is NULL !");
4989   int nbOfComp=a1->getNumberOfComponents();
4990   if(nbOfComp!=a2->getNumberOfComponents())
4991     throw INTERP_KERNEL::Exception("Nb of components mismatch for array min !");
4992   int nbOfTuple=a1->getNumberOfTuples();
4993   if(nbOfTuple!=a2->getNumberOfTuples())
4994     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array min !");
4995   DataArrayDouble *ret=DataArrayDouble::New();
4996   ret->alloc(nbOfTuple,nbOfComp);
4997   double *retPtr=ret->getPointer();
4998   const double *a1Ptr=a1->getConstPointer();
4999   const double *a2Ptr=a2->getConstPointer();
5000   int nbElem=nbOfTuple*nbOfComp;
5001   for(int i=0;i<nbElem;i++)
5002     retPtr[i]=std::min(a1Ptr[i],a2Ptr[i]);
5003   ret->copyStringInfoFrom(*a1);
5004   return ret;
5005 }
5006
5007 /*!
5008  * Returns a new DataArrayDouble that is a sum of two given arrays. There are 3
5009  * valid cases.
5010  * 1.  The arrays have same number of tuples and components. Then each value of
5011  *   the result array (_a_) is a sum of the corresponding values of \a a1 and \a a2,
5012  *   i.e.: _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ i, j ].
5013  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
5014  *   component. Then
5015  *   _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ i, 0 ].
5016  * 3.  The arrays have same number of components and one array, say _a2_, has one
5017  *   tuple. Then
5018  *   _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ 0, j ].
5019  *
5020  * Info on components is copied either from the first array (in the first case) or from
5021  * the array with maximal number of elements (getNbOfElems()).
5022  *  \param [in] a1 - an array to sum up.
5023  *  \param [in] a2 - another array to sum up.
5024  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
5025  *          The caller is to delete this result array using decrRef() as it is no more
5026  *          needed.
5027  *  \throw If either \a a1 or \a a2 is NULL.
5028  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
5029  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
5030  *         none of them has number of tuples or components equal to 1.
5031  */
5032 DataArrayDouble *DataArrayDouble::Add(const DataArrayDouble *a1, const DataArrayDouble *a2)
5033 {
5034   if(!a1 || !a2)
5035     throw INTERP_KERNEL::Exception("DataArrayDouble::Add : input DataArrayDouble instance is NULL !");
5036   int nbOfTuple=a1->getNumberOfTuples();
5037   int nbOfTuple2=a2->getNumberOfTuples();
5038   int nbOfComp=a1->getNumberOfComponents();
5039   int nbOfComp2=a2->getNumberOfComponents();
5040   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=0;
5041   if(nbOfTuple==nbOfTuple2)
5042     {
5043       if(nbOfComp==nbOfComp2)
5044         {
5045           ret=DataArrayDouble::New();
5046           ret->alloc(nbOfTuple,nbOfComp);
5047           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::plus<double>());
5048           ret->copyStringInfoFrom(*a1);
5049         }
5050       else
5051         {
5052           int nbOfCompMin,nbOfCompMax;
5053           const DataArrayDouble *aMin, *aMax;
5054           if(nbOfComp>nbOfComp2)
5055             {
5056               nbOfCompMin=nbOfComp2; nbOfCompMax=nbOfComp;
5057               aMin=a2; aMax=a1;
5058             }
5059           else
5060             {
5061               nbOfCompMin=nbOfComp; nbOfCompMax=nbOfComp2;
5062               aMin=a1; aMax=a2;
5063             }
5064           if(nbOfCompMin==1)
5065             {
5066               ret=DataArrayDouble::New();
5067               ret->alloc(nbOfTuple,nbOfCompMax);
5068               const double *aMinPtr=aMin->getConstPointer();
5069               const double *aMaxPtr=aMax->getConstPointer();
5070               double *res=ret->getPointer();
5071               for(int i=0;i<nbOfTuple;i++)
5072                 res=std::transform(aMaxPtr+i*nbOfCompMax,aMaxPtr+(i+1)*nbOfCompMax,res,std::bind2nd(std::plus<double>(),aMinPtr[i]));
5073               ret->copyStringInfoFrom(*aMax);
5074             }
5075           else
5076             throw INTERP_KERNEL::Exception("Nb of components mismatch for array Add !");
5077         }
5078     }
5079   else if((nbOfTuple==1 && nbOfTuple2>1) || (nbOfTuple>1 && nbOfTuple2==1))
5080     {
5081       if(nbOfComp==nbOfComp2)
5082         {
5083           int nbOfTupleMax=std::max(nbOfTuple,nbOfTuple2);
5084           const DataArrayDouble *aMin=nbOfTuple>nbOfTuple2?a2:a1;
5085           const DataArrayDouble *aMax=nbOfTuple>nbOfTuple2?a1:a2;
5086           const double *aMinPtr=aMin->getConstPointer(),*aMaxPtr=aMax->getConstPointer();
5087           ret=DataArrayDouble::New();
5088           ret->alloc(nbOfTupleMax,nbOfComp);
5089           double *res=ret->getPointer();
5090           for(int i=0;i<nbOfTupleMax;i++)
5091             res=std::transform(aMaxPtr+i*nbOfComp,aMaxPtr+(i+1)*nbOfComp,aMinPtr,res,std::plus<double>());
5092           ret->copyStringInfoFrom(*aMax);
5093         }
5094       else
5095         throw INTERP_KERNEL::Exception("Nb of components mismatch for array Add !");
5096     }
5097   else
5098     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Add !");
5099   return ret.retn();
5100 }
5101
5102 /*!
5103  * Adds values of another DataArrayDouble to values of \a this one. There are 3
5104  * valid cases.
5105  * 1.  The arrays have same number of tuples and components. Then each value of
5106  *   \a other array is added to the corresponding value of \a this array, i.e.:
5107  *   _a_ [ i, j ] += _other_ [ i, j ].
5108  * 2.  The arrays have same number of tuples and \a other array has one component. Then
5109  *   _a_ [ i, j ] += _other_ [ i, 0 ].
5110  * 3.  The arrays have same number of components and \a other array has one tuple. Then
5111  *   _a_ [ i, j ] += _a2_ [ 0, j ].
5112  *
5113  *  \param [in] other - an array to add to \a this one.
5114  *  \throw If \a other is NULL.
5115  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
5116  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
5117  *         \a other has number of both tuples and components not equal to 1.
5118  */
5119 void DataArrayDouble::addEqual(const DataArrayDouble *other)
5120 {
5121   if(!other)
5122     throw INTERP_KERNEL::Exception("DataArrayDouble::addEqual : input DataArrayDouble instance is NULL !");
5123   const char *msg="Nb of tuples mismatch for DataArrayDouble::addEqual  !";
5124   checkAllocated();
5125   other->checkAllocated();
5126   int nbOfTuple=getNumberOfTuples();
5127   int nbOfTuple2=other->getNumberOfTuples();
5128   int nbOfComp=getNumberOfComponents();
5129   int nbOfComp2=other->getNumberOfComponents();
5130   if(nbOfTuple==nbOfTuple2)
5131     {
5132       if(nbOfComp==nbOfComp2)
5133         {
5134           std::transform(begin(),end(),other->begin(),getPointer(),std::plus<double>());
5135         }
5136       else if(nbOfComp2==1)
5137         {
5138           double *ptr=getPointer();
5139           const double *ptrc=other->getConstPointer();
5140           for(int i=0;i<nbOfTuple;i++)
5141             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::plus<double>(),*ptrc++));
5142         }
5143       else
5144         throw INTERP_KERNEL::Exception(msg);
5145     }
5146   else if(nbOfTuple2==1)
5147     {
5148       if(nbOfComp2==nbOfComp)
5149         {
5150           double *ptr=getPointer();
5151           const double *ptrc=other->getConstPointer();
5152           for(int i=0;i<nbOfTuple;i++)
5153             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::plus<double>());
5154         }
5155       else
5156         throw INTERP_KERNEL::Exception(msg);
5157     }
5158   else
5159     throw INTERP_KERNEL::Exception(msg);
5160   declareAsNew();
5161 }
5162
5163 /*!
5164  * Returns a new DataArrayDouble that is a subtraction of two given arrays. There are 3
5165  * valid cases.
5166  * 1.  The arrays have same number of tuples and components. Then each value of
5167  *   the result array (_a_) is a subtraction of the corresponding values of \a a1 and
5168  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ i, j ].
5169  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
5170  *   component. Then
5171  *   _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ i, 0 ].
5172  * 3.  The arrays have same number of components and one array, say _a2_, has one
5173  *   tuple. Then
5174  *   _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ 0, j ].
5175  *
5176  * Info on components is copied either from the first array (in the first case) or from
5177  * the array with maximal number of elements (getNbOfElems()).
5178  *  \param [in] a1 - an array to subtract from.
5179  *  \param [in] a2 - an array to subtract.
5180  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
5181  *          The caller is to delete this result array using decrRef() as it is no more
5182  *          needed.
5183  *  \throw If either \a a1 or \a a2 is NULL.
5184  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
5185  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
5186  *         none of them has number of tuples or components equal to 1.
5187  */
5188 DataArrayDouble *DataArrayDouble::Substract(const DataArrayDouble *a1, const DataArrayDouble *a2)
5189 {
5190   if(!a1 || !a2)
5191     throw INTERP_KERNEL::Exception("DataArrayDouble::Substract : input DataArrayDouble instance is NULL !");
5192   int nbOfTuple1=a1->getNumberOfTuples();
5193   int nbOfTuple2=a2->getNumberOfTuples();
5194   int nbOfComp1=a1->getNumberOfComponents();
5195   int nbOfComp2=a2->getNumberOfComponents();
5196   if(nbOfTuple2==nbOfTuple1)
5197     {
5198       if(nbOfComp1==nbOfComp2)
5199         {
5200           MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
5201           ret->alloc(nbOfTuple2,nbOfComp1);
5202           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::minus<double>());
5203           ret->copyStringInfoFrom(*a1);
5204           return ret.retn();
5205         }
5206       else if(nbOfComp2==1)
5207         {
5208           MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
5209           ret->alloc(nbOfTuple1,nbOfComp1);
5210           const double *a2Ptr=a2->getConstPointer();
5211           const double *a1Ptr=a1->getConstPointer();
5212           double *res=ret->getPointer();
5213           for(int i=0;i<nbOfTuple1;i++)
5214             res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::minus<double>(),a2Ptr[i]));
5215           ret->copyStringInfoFrom(*a1);
5216           return ret.retn();
5217         }
5218       else
5219         {
5220           a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Substract !");
5221           return 0;
5222         }
5223     }
5224   else if(nbOfTuple2==1)
5225     {
5226       a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Substract !");
5227       MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
5228       ret->alloc(nbOfTuple1,nbOfComp1);
5229       const double *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
5230       double *pt=ret->getPointer();
5231       for(int i=0;i<nbOfTuple1;i++)
5232         pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::minus<double>());
5233       ret->copyStringInfoFrom(*a1);
5234       return ret.retn();
5235     }
5236   else
5237     {
5238       a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Substract !");//will always throw an exception
5239       return 0;
5240     }
5241 }
5242
5243 /*!
5244  * Subtract values of another DataArrayDouble from values of \a this one. There are 3
5245  * valid cases.
5246  * 1.  The arrays have same number of tuples and components. Then each value of
5247  *   \a other array is subtracted from the corresponding value of \a this array, i.e.:
5248  *   _a_ [ i, j ] -= _other_ [ i, j ].
5249  * 2.  The arrays have same number of tuples and \a other array has one component. Then
5250  *   _a_ [ i, j ] -= _other_ [ i, 0 ].
5251  * 3.  The arrays have same number of components and \a other array has one tuple. Then
5252  *   _a_ [ i, j ] -= _a2_ [ 0, j ].
5253  *
5254  *  \param [in] other - an array to subtract from \a this one.
5255  *  \throw If \a other is NULL.
5256  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
5257  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
5258  *         \a other has number of both tuples and components not equal to 1.
5259  */
5260 void DataArrayDouble::substractEqual(const DataArrayDouble *other)
5261 {
5262   if(!other)
5263     throw INTERP_KERNEL::Exception("DataArrayDouble::substractEqual : input DataArrayDouble instance is NULL !");
5264   const char *msg="Nb of tuples mismatch for DataArrayDouble::substractEqual  !";
5265   checkAllocated();
5266   other->checkAllocated();
5267   int nbOfTuple=getNumberOfTuples();
5268   int nbOfTuple2=other->getNumberOfTuples();
5269   int nbOfComp=getNumberOfComponents();
5270   int nbOfComp2=other->getNumberOfComponents();
5271   if(nbOfTuple==nbOfTuple2)
5272     {
5273       if(nbOfComp==nbOfComp2)
5274         {
5275           std::transform(begin(),end(),other->begin(),getPointer(),std::minus<double>());
5276         }
5277       else if(nbOfComp2==1)
5278         {
5279           double *ptr=getPointer();
5280           const double *ptrc=other->getConstPointer();
5281           for(int i=0;i<nbOfTuple;i++)
5282             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::minus<double>(),*ptrc++)); 
5283         }
5284       else
5285         throw INTERP_KERNEL::Exception(msg);
5286     }
5287   else if(nbOfTuple2==1)
5288     {
5289       if(nbOfComp2==nbOfComp)
5290         {
5291           double *ptr=getPointer();
5292           const double *ptrc=other->getConstPointer();
5293           for(int i=0;i<nbOfTuple;i++)
5294             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::minus<double>());
5295         }
5296       else
5297         throw INTERP_KERNEL::Exception(msg);
5298     }
5299   else
5300     throw INTERP_KERNEL::Exception(msg);
5301   declareAsNew();
5302 }
5303
5304 /*!
5305  * Returns a new DataArrayDouble that is a product of two given arrays. There are 3
5306  * valid cases.
5307  * 1.  The arrays have same number of tuples and components. Then each value of
5308  *   the result array (_a_) is a product of the corresponding values of \a a1 and
5309  *   \a a2, i.e. _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ i, j ].
5310  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
5311  *   component. Then
5312  *   _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ i, 0 ].
5313  * 3.  The arrays have same number of components and one array, say _a2_, has one
5314  *   tuple. Then
5315  *   _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ 0, j ].
5316  *
5317  * Info on components is copied either from the first array (in the first case) or from
5318  * the array with maximal number of elements (getNbOfElems()).
5319  *  \param [in] a1 - a factor array.
5320  *  \param [in] a2 - another factor array.
5321  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
5322  *          The caller is to delete this result array using decrRef() as it is no more
5323  *          needed.
5324  *  \throw If either \a a1 or \a a2 is NULL.
5325  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
5326  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
5327  *         none of them has number of tuples or components equal to 1.
5328  */
5329 DataArrayDouble *DataArrayDouble::Multiply(const DataArrayDouble *a1, const DataArrayDouble *a2)
5330 {
5331   if(!a1 || !a2)
5332     throw INTERP_KERNEL::Exception("DataArrayDouble::Multiply : input DataArrayDouble instance is NULL !");
5333   int nbOfTuple=a1->getNumberOfTuples();
5334   int nbOfTuple2=a2->getNumberOfTuples();
5335   int nbOfComp=a1->getNumberOfComponents();
5336   int nbOfComp2=a2->getNumberOfComponents();
5337   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=0;
5338   if(nbOfTuple==nbOfTuple2)
5339     {
5340       if(nbOfComp==nbOfComp2)
5341         {
5342           ret=DataArrayDouble::New();
5343           ret->alloc(nbOfTuple,nbOfComp);
5344           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::multiplies<double>());
5345           ret->copyStringInfoFrom(*a1);
5346         }
5347       else
5348         {
5349           int nbOfCompMin,nbOfCompMax;
5350           const DataArrayDouble *aMin, *aMax;
5351           if(nbOfComp>nbOfComp2)
5352             {
5353               nbOfCompMin=nbOfComp2; nbOfCompMax=nbOfComp;
5354               aMin=a2; aMax=a1;
5355             }
5356           else
5357             {
5358               nbOfCompMin=nbOfComp; nbOfCompMax=nbOfComp2;
5359               aMin=a1; aMax=a2;
5360             }
5361           if(nbOfCompMin==1)
5362             {
5363               ret=DataArrayDouble::New();
5364               ret->alloc(nbOfTuple,nbOfCompMax);
5365               const double *aMinPtr=aMin->getConstPointer();
5366               const double *aMaxPtr=aMax->getConstPointer();
5367               double *res=ret->getPointer();
5368               for(int i=0;i<nbOfTuple;i++)
5369                 res=std::transform(aMaxPtr+i*nbOfCompMax,aMaxPtr+(i+1)*nbOfCompMax,res,std::bind2nd(std::multiplies<double>(),aMinPtr[i]));
5370               ret->copyStringInfoFrom(*aMax);
5371             }
5372           else
5373             throw INTERP_KERNEL::Exception("Nb of components mismatch for array Multiply !");
5374         }
5375     }
5376   else if((nbOfTuple==1 && nbOfTuple2>1) || (nbOfTuple>1 && nbOfTuple2==1))
5377     {
5378       if(nbOfComp==nbOfComp2)
5379         {
5380           int nbOfTupleMax=std::max(nbOfTuple,nbOfTuple2);
5381           const DataArrayDouble *aMin=nbOfTuple>nbOfTuple2?a2:a1;
5382           const DataArrayDouble *aMax=nbOfTuple>nbOfTuple2?a1:a2;
5383           const double *aMinPtr=aMin->getConstPointer(),*aMaxPtr=aMax->getConstPointer();
5384           ret=DataArrayDouble::New();
5385           ret->alloc(nbOfTupleMax,nbOfComp);
5386           double *res=ret->getPointer();
5387           for(int i=0;i<nbOfTupleMax;i++)
5388             res=std::transform(aMaxPtr+i*nbOfComp,aMaxPtr+(i+1)*nbOfComp,aMinPtr,res,std::multiplies<double>());
5389           ret->copyStringInfoFrom(*aMax);
5390         }
5391       else
5392         throw INTERP_KERNEL::Exception("Nb of components mismatch for array Multiply !");
5393     }
5394   else
5395     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Multiply !");
5396   return ret.retn();
5397 }
5398
5399 /*!
5400  * Multiply values of another DataArrayDouble to values of \a this one. There are 3
5401  * valid cases.
5402  * 1.  The arrays have same number of tuples and components. Then each value of
5403  *   \a other array is multiplied to the corresponding value of \a this array, i.e.
5404  *   _this_ [ i, j ] *= _other_ [ i, j ].
5405  * 2.  The arrays have same number of tuples and \a other array has one component. Then
5406  *   _this_ [ i, j ] *= _other_ [ i, 0 ].
5407  * 3.  The arrays have same number of components and \a other array has one tuple. Then
5408  *   _this_ [ i, j ] *= _a2_ [ 0, j ].
5409  *
5410  *  \param [in] other - an array to multiply to \a this one.
5411  *  \throw If \a other is NULL.
5412  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
5413  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
5414  *         \a other has number of both tuples and components not equal to 1.
5415  */
5416 void DataArrayDouble::multiplyEqual(const DataArrayDouble *other)
5417 {
5418   if(!other)
5419     throw INTERP_KERNEL::Exception("DataArrayDouble::multiplyEqual : input DataArrayDouble instance is NULL !");
5420   const char *msg="Nb of tuples mismatch for DataArrayDouble::multiplyEqual !";
5421   checkAllocated();
5422   other->checkAllocated();
5423   int nbOfTuple=getNumberOfTuples();
5424   int nbOfTuple2=other->getNumberOfTuples();
5425   int nbOfComp=getNumberOfComponents();
5426   int nbOfComp2=other->getNumberOfComponents();
5427   if(nbOfTuple==nbOfTuple2)
5428     {
5429       if(nbOfComp==nbOfComp2)
5430         {
5431           std::transform(begin(),end(),other->begin(),getPointer(),std::multiplies<double>());
5432         }
5433       else if(nbOfComp2==1)
5434         {
5435           double *ptr=getPointer();
5436           const double *ptrc=other->getConstPointer();
5437           for(int i=0;i<nbOfTuple;i++)
5438             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::multiplies<double>(),*ptrc++));
5439         }
5440       else
5441         throw INTERP_KERNEL::Exception(msg);
5442     }
5443   else if(nbOfTuple2==1)
5444     {
5445       if(nbOfComp2==nbOfComp)
5446         {
5447           double *ptr=getPointer();
5448           const double *ptrc=other->getConstPointer();
5449           for(int i=0;i<nbOfTuple;i++)
5450             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::multiplies<double>());
5451         }
5452       else
5453         throw INTERP_KERNEL::Exception(msg);
5454     }
5455   else
5456     throw INTERP_KERNEL::Exception(msg);
5457   declareAsNew();
5458 }
5459
5460 /*!
5461  * Returns a new DataArrayDouble that is a division of two given arrays. There are 3
5462  * valid cases.
5463  * 1.  The arrays have same number of tuples and components. Then each value of
5464  *   the result array (_a_) is a division of the corresponding values of \a a1 and
5465  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ i, j ].
5466  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
5467  *   component. Then
5468  *   _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ i, 0 ].
5469  * 3.  The arrays have same number of components and one array, say _a2_, has one
5470  *   tuple. Then
5471  *   _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ 0, j ].
5472  *
5473  * Info on components is copied either from the first array (in the first case) or from
5474  * the array with maximal number of elements (getNbOfElems()).
5475  *  \warning No check of division by zero is performed!
5476  *  \param [in] a1 - a numerator array.
5477  *  \param [in] a2 - a denominator array.
5478  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
5479  *          The caller is to delete this result array using decrRef() as it is no more
5480  *          needed.
5481  *  \throw If either \a a1 or \a a2 is NULL.
5482  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
5483  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
5484  *         none of them has number of tuples or components equal to 1.
5485  */
5486 DataArrayDouble *DataArrayDouble::Divide(const DataArrayDouble *a1, const DataArrayDouble *a2)
5487 {
5488   if(!a1 || !a2)
5489     throw INTERP_KERNEL::Exception("DataArrayDouble::Divide : input DataArrayDouble instance is NULL !");
5490   int nbOfTuple1=a1->getNumberOfTuples();
5491   int nbOfTuple2=a2->getNumberOfTuples();
5492   int nbOfComp1=a1->getNumberOfComponents();
5493   int nbOfComp2=a2->getNumberOfComponents();
5494   if(nbOfTuple2==nbOfTuple1)
5495     {
5496       if(nbOfComp1==nbOfComp2)
5497         {
5498           MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
5499           ret->alloc(nbOfTuple2,nbOfComp1);
5500           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::divides<double>());
5501           ret->copyStringInfoFrom(*a1);
5502           return ret.retn();
5503         }
5504       else if(nbOfComp2==1)
5505         {
5506           MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
5507           ret->alloc(nbOfTuple1,nbOfComp1);
5508           const double *a2Ptr=a2->getConstPointer();
5509           const double *a1Ptr=a1->getConstPointer();
5510           double *res=ret->getPointer();
5511           for(int i=0;i<nbOfTuple1;i++)
5512             res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::divides<double>(),a2Ptr[i]));
5513           ret->copyStringInfoFrom(*a1);
5514           return ret.retn();
5515         }
5516       else
5517         {
5518           a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Divide !");
5519           return 0;
5520         }
5521     }
5522   else if(nbOfTuple2==1)
5523     {
5524       a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Divide !");
5525       MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
5526       ret->alloc(nbOfTuple1,nbOfComp1);
5527       const double *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
5528       double *pt=ret->getPointer();
5529       for(int i=0;i<nbOfTuple1;i++)
5530         pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::divides<double>());
5531       ret->copyStringInfoFrom(*a1);
5532       return ret.retn();
5533     }
5534   else
5535     {
5536       a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Divide !");//will always throw an exception
5537       return 0;
5538     }
5539 }
5540
5541 /*!
5542  * Divide values of \a this array by values of another DataArrayDouble. There are 3
5543  * valid cases.
5544  * 1.  The arrays have same number of tuples and components. Then each value of
5545  *    \a this array is divided by the corresponding value of \a other one, i.e.:
5546  *   _a_ [ i, j ] /= _other_ [ i, j ].
5547  * 2.  The arrays have same number of tuples and \a other array has one component. Then
5548  *   _a_ [ i, j ] /= _other_ [ i, 0 ].
5549  * 3.  The arrays have same number of components and \a other array has one tuple. Then
5550  *   _a_ [ i, j ] /= _a2_ [ 0, j ].
5551  *
5552  *  \warning No check of division by zero is performed!
5553  *  \param [in] other - an array to divide \a this one by.
5554  *  \throw If \a other is NULL.
5555  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
5556  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
5557  *         \a other has number of both tuples and components not equal to 1.
5558  */
5559 void DataArrayDouble::divideEqual(const DataArrayDouble *other)
5560 {
5561   if(!other)
5562     throw INTERP_KERNEL::Exception("DataArrayDouble::divideEqual : input DataArrayDouble instance is NULL !");
5563   const char *msg="Nb of tuples mismatch for DataArrayDouble::divideEqual !";
5564   checkAllocated();
5565   other->checkAllocated();
5566   int nbOfTuple=getNumberOfTuples();
5567   int nbOfTuple2=other->getNumberOfTuples();
5568   int nbOfComp=getNumberOfComponents();
5569   int nbOfComp2=other->getNumberOfComponents();
5570   if(nbOfTuple==nbOfTuple2)
5571     {
5572       if(nbOfComp==nbOfComp2)
5573         {
5574           std::transform(begin(),end(),other->begin(),getPointer(),std::divides<double>());
5575         }
5576       else if(nbOfComp2==1)
5577         {
5578           double *ptr=getPointer();
5579           const double *ptrc=other->getConstPointer();
5580           for(int i=0;i<nbOfTuple;i++)
5581             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::divides<double>(),*ptrc++));
5582         }
5583       else
5584         throw INTERP_KERNEL::Exception(msg);
5585     }
5586   else if(nbOfTuple2==1)
5587     {
5588       if(nbOfComp2==nbOfComp)
5589         {
5590           double *ptr=getPointer();
5591           const double *ptrc=other->getConstPointer();
5592           for(int i=0;i<nbOfTuple;i++)
5593             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::divides<double>());
5594         }
5595       else
5596         throw INTERP_KERNEL::Exception(msg);
5597     }
5598   else
5599     throw INTERP_KERNEL::Exception(msg);
5600   declareAsNew();
5601 }
5602
5603 /*!
5604  * Returns a new DataArrayDouble that is the result of pow of two given arrays. There are 3
5605  * valid cases.
5606  *
5607  *  \param [in] a1 - an array to pow up.
5608  *  \param [in] a2 - another array to sum up.
5609  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
5610  *          The caller is to delete this result array using decrRef() as it is no more
5611  *          needed.
5612  *  \throw If either \a a1 or \a a2 is NULL.
5613  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
5614  *  \throw If \a a1->getNumberOfComponents() != 1 or \a a2->getNumberOfComponents() != 1.
5615  *  \throw If there is a negative value in \a a1.
5616  */
5617 DataArrayDouble *DataArrayDouble::Pow(const DataArrayDouble *a1, const DataArrayDouble *a2)
5618 {
5619   if(!a1 || !a2)
5620     throw INTERP_KERNEL::Exception("DataArrayDouble::Pow : at least one of input instances is null !");
5621   int nbOfTuple=a1->getNumberOfTuples();
5622   int nbOfTuple2=a2->getNumberOfTuples();
5623   int nbOfComp=a1->getNumberOfComponents();
5624   int nbOfComp2=a2->getNumberOfComponents();
5625   if(nbOfTuple!=nbOfTuple2)
5626     throw INTERP_KERNEL::Exception("DataArrayDouble::Pow : number of tuples mismatches !");
5627   if(nbOfComp!=1 || nbOfComp2!=1)
5628     throw INTERP_KERNEL::Exception("DataArrayDouble::Pow : number of components of both arrays must be equal to 1 !");
5629   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New(); ret->alloc(nbOfTuple,1);
5630   const double *ptr1(a1->begin()),*ptr2(a2->begin());
5631   double *ptr=ret->getPointer();
5632   for(int i=0;i<nbOfTuple;i++,ptr1++,ptr2++,ptr++)
5633     {
5634       if(*ptr1>=0)
5635         {
5636           *ptr=pow(*ptr1,*ptr2);
5637         }
5638       else
5639         {
5640           std::ostringstream oss; oss << "DataArrayDouble::Pow : on tuple #" << i << " of a1 value is < 0 (" << *ptr1 << ") !";
5641           throw INTERP_KERNEL::Exception(oss.str().c_str());
5642         }
5643     }
5644   return ret.retn();
5645 }
5646
5647 /*!
5648  * Apply pow on values of another DataArrayDouble to values of \a this one.
5649  *
5650  *  \param [in] other - an array to pow to \a this one.
5651  *  \throw If \a other is NULL.
5652  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples()
5653  *  \throw If \a this->getNumberOfComponents() != 1 or \a other->getNumberOfComponents() != 1
5654  *  \throw If there is a negative value in \a this.
5655  */
5656 void DataArrayDouble::powEqual(const DataArrayDouble *other)
5657 {
5658   if(!other)
5659     throw INTERP_KERNEL::Exception("DataArrayDouble::powEqual : input instance is null !");
5660   int nbOfTuple=getNumberOfTuples();
5661   int nbOfTuple2=other->getNumberOfTuples();
5662   int nbOfComp=getNumberOfComponents();
5663   int nbOfComp2=other->getNumberOfComponents();
5664   if(nbOfTuple!=nbOfTuple2)
5665     throw INTERP_KERNEL::Exception("DataArrayDouble::powEqual : number of tuples mismatches !");
5666   if(nbOfComp!=1 || nbOfComp2!=1)
5667     throw INTERP_KERNEL::Exception("DataArrayDouble::powEqual : number of components of both arrays must be equal to 1 !");
5668   double *ptr=getPointer();
5669   const double *ptrc=other->begin();
5670   for(int i=0;i<nbOfTuple;i++,ptrc++,ptr++)
5671     {
5672       if(*ptr>=0)
5673         *ptr=pow(*ptr,*ptrc);
5674       else
5675         {
5676           std::ostringstream oss; oss << "DataArrayDouble::powEqual : on tuple #" << i << " of this value is < 0 (" << *ptr << ") !";
5677           throw INTERP_KERNEL::Exception(oss.str().c_str());
5678         }
5679     }
5680   declareAsNew();
5681 }
5682
5683 /*!
5684  * This method is \b NOT wrapped into python because it can be useful only for performance reasons in C++ context.
5685  * All values in \a this must be 0. or 1. within eps error. 0 means false, 1 means true.
5686  * If an another value than 0 or 1 appear (within eps precision) an INTERP_KERNEL::Exception will be thrown.
5687  *
5688  * \throw if \a this is not allocated.
5689  * \throw if \a this has not exactly one component.
5690  */
5691 std::vector<bool> DataArrayDouble::toVectorOfBool(double eps) const
5692 {
5693   checkAllocated();
5694   if(getNumberOfComponents()!=1)
5695     throw INTERP_KERNEL::Exception("DataArrayDouble::toVectorOfBool : must be applied on single component array !");
5696   int nbt(getNumberOfTuples());
5697   std::vector<bool> ret(nbt);
5698   const double *pt(begin());
5699   for(int i=0;i<nbt;i++)
5700     {
5701       if(fabs(pt[i])<eps)
5702         ret[i]=false;
5703       else if(fabs(pt[i]-1.)<eps)
5704         ret[i]=true;
5705       else
5706         {
5707           std::ostringstream oss; oss << "DataArrayDouble::toVectorOfBool : the tuple #" << i << " has value " << pt[i] << " is invalid ! must be 0. or 1. !";
5708           throw INTERP_KERNEL::Exception(oss.str().c_str());
5709         }
5710     }
5711   return ret;
5712 }
5713
5714 /*!
5715  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
5716  * Server side.
5717  */
5718 void DataArrayDouble::getTinySerializationIntInformation(std::vector<int>& tinyInfo) const
5719 {
5720   tinyInfo.resize(2);
5721   if(isAllocated())
5722     {
5723       tinyInfo[0]=getNumberOfTuples();
5724       tinyInfo[1]=getNumberOfComponents();
5725     }
5726   else
5727     {
5728       tinyInfo[0]=-1;
5729       tinyInfo[1]=-1;
5730     }
5731 }
5732
5733 /*!
5734  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
5735  * Server side.
5736  */
5737 void DataArrayDouble::getTinySerializationStrInformation(std::vector<std::string>& tinyInfo) const
5738 {
5739   if(isAllocated())
5740     {
5741       int nbOfCompo=getNumberOfComponents();
5742       tinyInfo.resize(nbOfCompo+1);
5743       tinyInfo[0]=getName();
5744       for(int i=0;i<nbOfCompo;i++)
5745         tinyInfo[i+1]=getInfoOnComponent(i);
5746     }
5747   else
5748     {
5749       tinyInfo.resize(1);
5750       tinyInfo[0]=getName();
5751     }
5752 }
5753
5754 /*!
5755  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
5756  * This method returns if a feeding is needed.
5757  */
5758 bool DataArrayDouble::resizeForUnserialization(const std::vector<int>& tinyInfoI)
5759 {
5760   int nbOfTuple=tinyInfoI[0];
5761   int nbOfComp=tinyInfoI[1];
5762   if(nbOfTuple!=-1 || nbOfComp!=-1)
5763     {
5764       alloc(nbOfTuple,nbOfComp);
5765       return true;
5766     }
5767   return false;
5768 }
5769
5770 /*!
5771  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
5772  */
5773 void DataArrayDouble::finishUnserialization(const std::vector<int>& tinyInfoI, const std::vector<std::string>& tinyInfoS)
5774 {
5775   setName(tinyInfoS[0]);
5776   if(isAllocated())
5777     {
5778       int nbOfCompo=getNumberOfComponents();
5779       for(int i=0;i<nbOfCompo;i++)
5780         setInfoOnComponent(i,tinyInfoS[i+1]);
5781     }
5782 }
5783
5784 DataArrayDoubleIterator::DataArrayDoubleIterator(DataArrayDouble *da):_da(da),_tuple_id(0),_nb_comp(0),_nb_tuple(0)
5785 {
5786   if(_da)
5787     {
5788       _da->incrRef();
5789       if(_da->isAllocated())
5790         {
5791           _nb_comp=da->getNumberOfComponents();
5792           _nb_tuple=da->getNumberOfTuples();
5793           _pt=da->getPointer();
5794         }
5795     }
5796 }
5797
5798 DataArrayDoubleIterator::~DataArrayDoubleIterator()
5799 {
5800   if(_da)
5801     _da->decrRef();
5802 }
5803
5804 DataArrayDoubleTuple *DataArrayDoubleIterator::nextt()
5805 {
5806   if(_tuple_id<_nb_tuple)
5807     {
5808       _tuple_id++;
5809       DataArrayDoubleTuple *ret=new DataArrayDoubleTuple(_pt,_nb_comp);
5810       _pt+=_nb_comp;
5811       return ret;
5812     }
5813   else
5814     return 0;
5815 }
5816
5817 DataArrayDoubleTuple::DataArrayDoubleTuple(double *pt, int nbOfComp):_pt(pt),_nb_of_compo(nbOfComp)
5818 {
5819 }
5820
5821
5822 std::string DataArrayDoubleTuple::repr() const
5823 {
5824   std::ostringstream oss; oss.precision(17); oss << "(";
5825   for(int i=0;i<_nb_of_compo-1;i++)
5826     oss << _pt[i] << ", ";
5827   oss << _pt[_nb_of_compo-1] << ")";
5828   return oss.str();
5829 }
5830
5831 double DataArrayDoubleTuple::doubleValue() const
5832 {
5833   if(_nb_of_compo==1)
5834     return *_pt;
5835   throw INTERP_KERNEL::Exception("DataArrayDoubleTuple::doubleValue : DataArrayDoubleTuple instance has not exactly 1 component -> Not possible to convert it into a double precision float !");
5836 }
5837
5838 /*!
5839  * This method returns a newly allocated instance the caller should dealed with by a ParaMEDMEM::DataArrayDouble::decrRef.
5840  * This method performs \b no copy of data. The content is only referenced using ParaMEDMEM::DataArrayDouble::useArray with ownership set to \b false.
5841  * 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
5842  * \b nbOfCompo=1 and \bnbOfTuples==this->_nb_of_elem.
5843  */
5844 DataArrayDouble *DataArrayDoubleTuple::buildDADouble(int nbOfTuples, int nbOfCompo) const
5845 {
5846   if((_nb_of_compo==nbOfCompo && nbOfTuples==1) || (_nb_of_compo==nbOfTuples && nbOfCompo==1))
5847     {
5848       DataArrayDouble *ret=DataArrayDouble::New();
5849       ret->useExternalArrayWithRWAccess(_pt,nbOfTuples,nbOfCompo);
5850       return ret;
5851     }
5852   else
5853     {
5854       std::ostringstream oss; oss << "DataArrayDoubleTuple::buildDADouble : unable to build a requested DataArrayDouble instance with nbofTuple=" << nbOfTuples << " and nbOfCompo=" << nbOfCompo;
5855       oss << ".\nBecause the number of elements in this is " << _nb_of_compo << " !";
5856       throw INTERP_KERNEL::Exception(oss.str().c_str());
5857     }
5858 }
5859
5860 /*!
5861  * Returns a new instance of DataArrayInt. The caller is to delete this array
5862  * using decrRef() as it is no more needed. 
5863  */
5864 DataArrayInt *DataArrayInt::New()
5865 {
5866   return new DataArrayInt;
5867 }
5868
5869 /*!
5870  * Checks if raw data is allocated. Read more on the raw data
5871  * in \ref MEDCouplingArrayBasicsTuplesAndCompo "DataArrays infos" for more information.
5872  *  \return bool - \a true if the raw data is allocated, \a false else.
5873  */
5874 bool DataArrayInt::isAllocated() const
5875 {
5876   return getConstPointer()!=0;
5877 }
5878
5879 /*!
5880  * Checks if raw data is allocated and throws an exception if it is not the case.
5881  *  \throw If the raw data is not allocated.
5882  */
5883 void DataArrayInt::checkAllocated() const
5884 {
5885   if(!isAllocated())
5886     throw INTERP_KERNEL::Exception("DataArrayInt::checkAllocated : Array is defined but not allocated ! Call alloc or setValues method first !");
5887 }
5888
5889 /*!
5890  * This method desallocated \a this without modification of informations relative to the components.
5891  * After call of this method, DataArrayInt::isAllocated will return false.
5892  * If \a this is already not allocated, \a this is let unchanged.
5893  */
5894 void DataArrayInt::desallocate()
5895 {
5896   _mem.destroy();
5897 }
5898
5899 std::size_t DataArrayInt::getHeapMemorySizeWithoutChildren() const
5900 {
5901   std::size_t sz(_mem.getNbOfElemAllocated());
5902   sz*=sizeof(int);
5903   return DataArray::getHeapMemorySizeWithoutChildren()+sz;
5904 }
5905
5906 /*!
5907  * Returns the only one value in \a this, if and only if number of elements
5908  * (nb of tuples * nb of components) is equal to 1, and that \a this is allocated.
5909  *  \return double - the sole value stored in \a this array.
5910  *  \throw If at least one of conditions stated above is not fulfilled.
5911  */
5912 int DataArrayInt::intValue() const
5913 {
5914   if(isAllocated())
5915     {
5916       if(getNbOfElems()==1)
5917         {
5918           return *getConstPointer();
5919         }
5920       else
5921         throw INTERP_KERNEL::Exception("DataArrayInt::intValue : DataArrayInt instance is allocated but number of elements is not equal to 1 !");
5922     }
5923   else
5924     throw INTERP_KERNEL::Exception("DataArrayInt::intValue : DataArrayInt instance is not allocated !");
5925 }
5926
5927 /*!
5928  * Returns an integer value characterizing \a this array, which is useful for a quick
5929  * comparison of many instances of DataArrayInt.
5930  *  \return int - the hash value.
5931  *  \throw If \a this is not allocated.
5932  */
5933 int DataArrayInt::getHashCode() const
5934 {
5935   checkAllocated();
5936   std::size_t nbOfElems=getNbOfElems();
5937   int ret=nbOfElems*65536;
5938   int delta=3;
5939   if(nbOfElems>48)
5940     delta=nbOfElems/8;
5941   int ret0=0;
5942   const int *pt=begin();
5943   for(std::size_t i=0;i<nbOfElems;i+=delta)
5944     ret0+=pt[i] & 0x1FFF;
5945   return ret+ret0;
5946 }
5947
5948 /*!
5949  * Checks the number of tuples.
5950  *  \return bool - \a true if getNumberOfTuples() == 0, \a false else.
5951  *  \throw If \a this is not allocated.
5952  */
5953 bool DataArrayInt::empty() const
5954 {
5955   checkAllocated();
5956   return getNumberOfTuples()==0;
5957 }
5958
5959 /*!
5960  * Returns a full copy of \a this. For more info on copying data arrays see
5961  * \ref MEDCouplingArrayBasicsCopyDeep.
5962  *  \return DataArrayInt * - a new instance of DataArrayInt.
5963  */
5964 DataArrayInt *DataArrayInt::deepCpy() const
5965 {
5966   return new DataArrayInt(*this);
5967 }
5968
5969 /*!
5970  * Returns either a \a deep or \a shallow copy of this array. For more info see
5971  * \ref MEDCouplingArrayBasicsCopyDeep and \ref MEDCouplingArrayBasicsCopyShallow.
5972  *  \param [in] dCpy - if \a true, a deep copy is returned, else, a shallow one.
5973  *  \return DataArrayInt * - either a new instance of DataArrayInt (if \a dCpy
5974  *          == \a true) or \a this instance (if \a dCpy == \a false).
5975  */
5976 DataArrayInt *DataArrayInt::performCpy(bool dCpy) const
5977 {
5978   if(dCpy)
5979     return deepCpy();
5980   else
5981     {
5982       incrRef();
5983       return const_cast<DataArrayInt *>(this);
5984     }
5985 }
5986
5987 /*!
5988  * Copies all the data from another DataArrayInt. For more info see
5989  * \ref MEDCouplingArrayBasicsCopyDeepAssign.
5990  *  \param [in] other - another instance of DataArrayInt to copy data from.
5991  *  \throw If the \a other is not allocated.
5992  */
5993 void DataArrayInt::cpyFrom(const DataArrayInt& other)
5994 {
5995   other.checkAllocated();
5996   int nbOfTuples=other.getNumberOfTuples();
5997   int nbOfComp=other.getNumberOfComponents();
5998   allocIfNecessary(nbOfTuples,nbOfComp);
5999   std::size_t nbOfElems=(std::size_t)nbOfTuples*nbOfComp;
6000   int *pt=getPointer();
6001   const int *ptI=other.getConstPointer();
6002   for(std::size_t i=0;i<nbOfElems;i++)
6003     pt[i]=ptI[i];
6004   copyStringInfoFrom(other);
6005 }
6006
6007 /*!
6008  * This method reserve nbOfElems elements in memory ( nbOfElems*4 bytes ) \b without impacting the number of tuples in \a this.
6009  * 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.
6010  * If \a this has not already been allocated, number of components is set to one.
6011  * This method allows to reduce number of reallocations on invokation of DataArrayInt::pushBackSilent and DataArrayInt::pushBackValsSilent on \a this.
6012  * 
6013  * \sa DataArrayInt::pack, DataArrayInt::pushBackSilent, DataArrayInt::pushBackValsSilent
6014  */
6015 void DataArrayInt::reserve(std::size_t nbOfElems)
6016 {
6017   int nbCompo=getNumberOfComponents();
6018   if(nbCompo==1)
6019     {
6020       _mem.reserve(nbOfElems);
6021     }
6022   else if(nbCompo==0)
6023     {
6024       _mem.reserve(nbOfElems);
6025       _info_on_compo.resize(1);
6026     }
6027   else
6028     throw INTERP_KERNEL::Exception("DataArrayInt::reserve : not available for DataArrayInt with number of components different than 1 !");
6029 }
6030
6031 /*!
6032  * 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
6033  * of counter. So the caller is expected to call TimeLabel::declareAsNew on \a this at the end of the push session.
6034  *
6035  * \param [in] val the value to be added in \a this
6036  * \throw If \a this has already been allocated with number of components different from one.
6037  * \sa DataArrayInt::pushBackValsSilent
6038  */
6039 void DataArrayInt::pushBackSilent(int val)
6040 {
6041   int nbCompo=getNumberOfComponents();
6042   if(nbCompo==1)
6043     _mem.pushBack(val);
6044   else if(nbCompo==0)
6045     {
6046       _info_on_compo.resize(1);
6047       _mem.pushBack(val);
6048     }
6049   else
6050     throw INTERP_KERNEL::Exception("DataArrayInt::pushBackSilent : not available for DataArrayInt with number of components different than 1 !");
6051 }
6052
6053 /*!
6054  * 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
6055  * of counter. So the caller is expected to call TimeLabel::declareAsNew on \a this at the end of the push session.
6056  *
6057  *  \param [in] valsBg - an array of values to push at the end of \this.
6058  *  \param [in] valsEnd - specifies the end of the array \a valsBg, so that
6059  *              the last value of \a valsBg is \a valsEnd[ -1 ].
6060  * \throw If \a this has already been allocated with number of components different from one.
6061  * \sa DataArrayInt::pushBackSilent
6062  */
6063 void DataArrayInt::pushBackValsSilent(const int *valsBg, const int *valsEnd)
6064 {
6065   int nbCompo=getNumberOfComponents();
6066   if(nbCompo==1)
6067     _mem.insertAtTheEnd(valsBg,valsEnd);
6068   else if(nbCompo==0)
6069     {
6070       _info_on_compo.resize(1);
6071       _mem.insertAtTheEnd(valsBg,valsEnd);
6072     }
6073   else
6074     throw INTERP_KERNEL::Exception("DataArrayInt::pushBackValsSilent : not available for DataArrayInt with number of components different than 1 !");
6075 }
6076
6077 /*!
6078  * This method returns silently ( without updating time label in \a this ) the last value, if any and suppress it.
6079  * \throw If \a this is already empty.
6080  * \throw If \a this has number of components different from one.
6081  */
6082 int DataArrayInt::popBackSilent()
6083 {
6084   if(getNumberOfComponents()==1)
6085     return _mem.popBack();
6086   else
6087     throw INTERP_KERNEL::Exception("DataArrayInt::popBackSilent : not available for DataArrayInt with number of components different than 1 !");
6088 }
6089
6090 /*!
6091  * 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.
6092  *
6093  * \sa DataArrayInt::getHeapMemorySizeWithoutChildren, DataArrayInt::reserve
6094  */
6095 void DataArrayInt::pack() const
6096 {
6097   _mem.pack();
6098 }
6099
6100 /*!
6101  * Allocates the raw data in memory. If exactly as same memory as needed already
6102  * allocated, it is not re-allocated.
6103  *  \param [in] nbOfTuple - number of tuples of data to allocate.
6104  *  \param [in] nbOfCompo - number of components of data to allocate.
6105  *  \throw If \a nbOfTuple < 0 or \a nbOfCompo < 0.
6106  */
6107 void DataArrayInt::allocIfNecessary(int nbOfTuple, int nbOfCompo)
6108 {
6109   if(isAllocated())
6110     {
6111       if(nbOfTuple!=getNumberOfTuples() || nbOfCompo!=getNumberOfComponents())
6112         alloc(nbOfTuple,nbOfCompo);
6113     }
6114   else
6115     alloc(nbOfTuple,nbOfCompo);
6116 }
6117
6118 /*!
6119  * Allocates the raw data in memory. If the memory was already allocated, then it is
6120  * freed and re-allocated. See an example of this method use
6121  * \ref MEDCouplingArraySteps1WC "here".
6122  *  \param [in] nbOfTuple - number of tuples of data to allocate.
6123  *  \param [in] nbOfCompo - number of components of data to allocate.
6124  *  \throw If \a nbOfTuple < 0 or \a nbOfCompo < 0.
6125  */
6126 void DataArrayInt::alloc(int nbOfTuple, int nbOfCompo)
6127 {
6128   if(nbOfTuple<0 || nbOfCompo<0)
6129     throw INTERP_KERNEL::Exception("DataArrayInt::alloc : request for negative length of data !");
6130   _info_on_compo.resize(nbOfCompo);
6131   _mem.alloc(nbOfCompo*(std::size_t)nbOfTuple);
6132   declareAsNew();
6133 }
6134
6135 /*!
6136  * Assign zero to all values in \a this array. To know more on filling arrays see
6137  * \ref MEDCouplingArrayFill.
6138  * \throw If \a this is not allocated.
6139  */
6140 void DataArrayInt::fillWithZero()
6141 {
6142   checkAllocated();
6143   _mem.fillWithValue(0);
6144   declareAsNew();
6145 }
6146
6147 /*!
6148  * Assign \a val to all values in \a this array. To know more on filling arrays see
6149  * \ref MEDCouplingArrayFill.
6150  *  \param [in] val - the value to fill with.
6151  *  \throw If \a this is not allocated.
6152  */
6153 void DataArrayInt::fillWithValue(int val)
6154 {
6155   checkAllocated();
6156   _mem.fillWithValue(val);
6157   declareAsNew();
6158 }
6159
6160 /*!
6161  * Set all values in \a this array so that the i-th element equals to \a init + i
6162  * (i starts from zero). To know more on filling arrays see \ref MEDCouplingArrayFill.
6163  *  \param [in] init - value to assign to the first element of array.
6164  *  \throw If \a this->getNumberOfComponents() != 1
6165  *  \throw If \a this is not allocated.
6166  */
6167 void DataArrayInt::iota(int init)
6168 {
6169   checkAllocated();
6170   if(getNumberOfComponents()!=1)
6171     throw INTERP_KERNEL::Exception("DataArrayInt::iota : works only for arrays with only one component, you can call 'rearrange' method before !");
6172   int *ptr=getPointer();
6173   int ntuples=getNumberOfTuples();
6174   for(int i=0;i<ntuples;i++)
6175     ptr[i]=init+i;
6176   declareAsNew();
6177 }
6178
6179 /*!
6180  * Returns a textual and human readable representation of \a this instance of
6181  * DataArrayInt. This text is shown when a DataArrayInt is printed in Python.
6182  *  \return std::string - text describing \a this DataArrayInt.
6183  */
6184 std::string DataArrayInt::repr() const
6185 {
6186   std::ostringstream ret;
6187   reprStream(ret);
6188   return ret.str();
6189 }
6190
6191 std::string DataArrayInt::reprZip() const
6192 {
6193   std::ostringstream ret;
6194   reprZipStream(ret);
6195   return ret.str();
6196 }
6197
6198 void DataArrayInt::writeVTK(std::ostream& ofs, int indent, const std::string& type, const std::string& nameInFile, DataArrayByte *byteArr) const
6199 {
6200   static const char SPACE[4]={' ',' ',' ',' '};
6201   checkAllocated();
6202   std::string idt(indent,' ');
6203   ofs << idt << "<DataArray type=\"" << type << "\" Name=\"" << nameInFile << "\" NumberOfComponents=\"" << getNumberOfComponents() << "\"";
6204   if(byteArr)
6205     {
6206       ofs << " format=\"appended\" offset=\"" << byteArr->getNumberOfTuples() << "\">";
6207       if(std::string(type)=="Int32")
6208         {
6209           const char *data(reinterpret_cast<const char *>(begin()));
6210           std::size_t sz(getNbOfElems()*sizeof(int));
6211           byteArr->insertAtTheEnd(data,data+sz);
6212           byteArr->insertAtTheEnd(SPACE,SPACE+4);
6213         }
6214       else if(std::string(type)=="Int8")
6215         {
6216           INTERP_KERNEL::AutoPtr<char> tmp(new char[getNbOfElems()]);
6217           std::copy(begin(),end(),(char *)tmp);
6218           byteArr->insertAtTheEnd((char *)tmp,(char *)tmp+getNbOfElems());
6219           byteArr->insertAtTheEnd(SPACE,SPACE+4);
6220         }
6221       else if(std::string(type)=="UInt8")
6222         {
6223           INTERP_KERNEL::AutoPtr<unsigned char> tmp(new unsigned char[getNbOfElems()]);
6224           std::copy(begin(),end(),(unsigned char *)tmp);
6225           byteArr->insertAtTheEnd((unsigned char *)tmp,(unsigned char *)tmp+getNbOfElems());
6226           byteArr->insertAtTheEnd(SPACE,SPACE+4);
6227         }
6228       else
6229         throw INTERP_KERNEL::Exception("DataArrayInt::writeVTK : Only Int32, Int8 and UInt8 supported !");
6230     }
6231   else
6232     {
6233       ofs << " RangeMin=\"" << getMinValueInArray() << "\" RangeMax=\"" << getMaxValueInArray() << "\" format=\"ascii\">\n" << idt;
6234       std::copy(begin(),end(),std::ostream_iterator<int>(ofs," "));
6235     }
6236   ofs << std::endl << idt << "</DataArray>\n";
6237 }
6238
6239 void DataArrayInt::reprStream(std::ostream& stream) const
6240 {
6241   stream << "Name of int array : \"" << _name << "\"\n";
6242   reprWithoutNameStream(stream);
6243 }
6244
6245 void DataArrayInt::reprZipStream(std::ostream& stream) const
6246 {
6247   stream << "Name of int array : \"" << _name << "\"\n";
6248   reprZipWithoutNameStream(stream);
6249 }
6250
6251 void DataArrayInt::reprWithoutNameStream(std::ostream& stream) const
6252 {
6253   DataArray::reprWithoutNameStream(stream);
6254   _mem.repr(getNumberOfComponents(),stream);
6255 }
6256
6257 void DataArrayInt::reprZipWithoutNameStream(std::ostream& stream) const
6258 {
6259   DataArray::reprWithoutNameStream(stream);
6260   _mem.reprZip(getNumberOfComponents(),stream);
6261 }
6262
6263 void DataArrayInt::reprCppStream(const std::string& varName, std::ostream& stream) const
6264 {
6265   int nbTuples=getNumberOfTuples(),nbComp=getNumberOfComponents();
6266   const int *data=getConstPointer();
6267   stream << "DataArrayInt *" << varName << "=DataArrayInt::New();" << std::endl;
6268   if(nbTuples*nbComp>=1)
6269     {
6270       stream << "const int " << varName << "Data[" << nbTuples*nbComp << "]={";
6271       std::copy(data,data+nbTuples*nbComp-1,std::ostream_iterator<int>(stream,","));
6272       stream << data[nbTuples*nbComp-1] << "};" << std::endl;
6273       stream << varName << "->useArray(" << varName << "Data,false,CPP_DEALLOC," << nbTuples << "," << nbComp << ");" << std::endl;
6274     }
6275   else
6276     stream << varName << "->alloc(" << nbTuples << "," << nbComp << ");" << std::endl;
6277   stream << varName << "->setName(\"" << getName() << "\");" << std::endl;
6278 }
6279
6280 /*!
6281  * Method that gives a quick overvien of \a this for python.
6282  */
6283 void DataArrayInt::reprQuickOverview(std::ostream& stream) const
6284 {
6285   static const std::size_t MAX_NB_OF_BYTE_IN_REPR=300;
6286   stream << "DataArrayInt C++ instance at " << this << ". ";
6287   if(isAllocated())
6288     {
6289       int nbOfCompo=(int)_info_on_compo.size();
6290       if(nbOfCompo>=1)
6291         {
6292           int nbOfTuples=getNumberOfTuples();
6293           stream << "Number of tuples : " << nbOfTuples << ". Number of components : " << nbOfCompo << "." << std::endl;
6294           reprQuickOverviewData(stream,MAX_NB_OF_BYTE_IN_REPR);
6295         }
6296       else
6297         stream << "Number of components : 0.";
6298     }
6299   else
6300     stream << "*** No data allocated ****";
6301 }
6302
6303 void DataArrayInt::reprQuickOverviewData(std::ostream& stream, std::size_t maxNbOfByteInRepr) const
6304 {
6305   const int *data=begin();
6306   int nbOfTuples=getNumberOfTuples();
6307   int nbOfCompo=(int)_info_on_compo.size();
6308   std::ostringstream oss2; oss2 << "[";
6309   std::string oss2Str(oss2.str());
6310   bool isFinished=true;
6311   for(int i=0;i<nbOfTuples && isFinished;i++)
6312     {
6313       if(nbOfCompo>1)
6314         {
6315           oss2 << "(";
6316           for(int j=0;j<nbOfCompo;j++,data++)
6317             {
6318               oss2 << *data;
6319               if(j!=nbOfCompo-1) oss2 << ", ";
6320             }
6321           oss2 << ")";
6322         }
6323       else
6324         oss2 << *data++;
6325       if(i!=nbOfTuples-1) oss2 << ", ";
6326       std::string oss3Str(oss2.str());
6327       if(oss3Str.length()<maxNbOfByteInRepr)
6328         oss2Str=oss3Str;
6329       else
6330         isFinished=false;
6331     }
6332   stream << oss2Str;
6333   if(!isFinished)
6334     stream << "... ";
6335   stream << "]";
6336 }
6337
6338 /*!
6339  * Modifies \a this one-dimensional array so that each value \a v = \a indArrBg[ \a v ],
6340  * i.e. a current value is used as in index to get a new value from \a indArrBg.
6341  *  \param [in] indArrBg - pointer to the first element of array of new values to assign
6342  *         to \a this array.
6343  *  \param [in] indArrEnd - specifies the end of the array \a indArrBg, so that
6344  *              the last value of \a indArrBg is \a indArrEnd[ -1 ].
6345  *  \throw If \a this->getNumberOfComponents() != 1
6346  *  \throw If any value of \a this can't be used as a valid index for 
6347  *         [\a indArrBg, \a indArrEnd).
6348  */
6349 void DataArrayInt::transformWithIndArr(const int *indArrBg, const int *indArrEnd)
6350 {
6351   checkAllocated();
6352   if(getNumberOfComponents()!=1)
6353     throw INTERP_KERNEL::Exception("Call transformWithIndArr method on DataArrayInt with only one component, you can call 'rearrange' method before !");
6354   int nbElemsIn=(int)std::distance(indArrBg,indArrEnd);
6355   int nbOfTuples=getNumberOfTuples();
6356   int *pt=getPointer();
6357   for(int i=0;i<nbOfTuples;i++,pt++)
6358     {
6359       if(*pt>=0 && *pt<nbElemsIn)
6360         *pt=indArrBg[*pt];
6361       else
6362         {
6363           std::ostringstream oss; oss << "DataArrayInt::transformWithIndArr : error on tuple #" << i << " of this value is " << *pt << ", should be in [0," << nbElemsIn << ") !";
6364           throw INTERP_KERNEL::Exception(oss.str().c_str());
6365         }
6366     }
6367   declareAsNew();
6368 }
6369
6370 /*!
6371  * Computes distribution of values of \a this one-dimensional array between given value
6372  * ranges (casts). This method is typically useful for entity number spliting by types,
6373  * for example. 
6374  *  \warning The values contained in \a arrBg should be sorted ascendently. No
6375  *           check of this is be done. If not, the result is not warranted. 
6376  *  \param [in] arrBg - the array of ascending values defining the value ranges. The i-th
6377  *         value of \a arrBg (\a arrBg[ i ]) gives the lowest value of the i-th range,
6378  *         and the greatest value of the i-th range equals to \a arrBg[ i+1 ] - 1. \a
6379  *         arrBg containing \a n values defines \a n-1 ranges. The last value of \a arrBg
6380  *         should be more than every value in \a this array.
6381  *  \param [in] arrEnd - specifies the end of the array \a arrBg, so that
6382  *              the last value of \a arrBg is \a arrEnd[ -1 ].
6383  *  \param [out] castArr - a new instance of DataArrayInt, of same size as \a this array
6384  *         (same number of tuples and components), the caller is to delete 
6385  *         using decrRef() as it is no more needed.
6386  *         This array contains indices of ranges for every value of \a this array. I.e.
6387  *         the i-th value of \a castArr gives the index of range the i-th value of \a this
6388  *         belongs to. Or, in other words, this parameter contains for each tuple in \a
6389  *         this in which cast it holds.
6390  *  \param [out] rankInsideCast - a new instance of DataArrayInt, of same size as \a this
6391  *         array, the caller is to delete using decrRef() as it is no more needed.
6392  *         This array contains ranks of values of \a this array within ranges
6393  *         they belongs to. I.e. the i-th value of \a rankInsideCast gives the rank of
6394  *         the i-th value of \a this array within the \a castArr[ i ]-th range, to which
6395  *         the i-th value of \a this belongs to. Or, in other words, this param contains 
6396  *         for each tuple its rank inside its cast. The rank is computed as difference
6397  *         between the value and the lowest value of range.
6398  *  \param [out] castsPresent - a new instance of DataArrayInt, containing indices of
6399  *         ranges (casts) to which at least one value of \a this array belongs.
6400  *         Or, in other words, this param contains the casts that \a this contains.
6401  *         The caller is to delete this array using decrRef() as it is no more needed.
6402  *
6403  * \b Example: If \a this contains [6,5,0,3,2,7,8,1,4] and \a arrBg contains [0,4,9] then
6404  *            the output of this method will be : 
6405  * - \a castArr       : [1,1,0,0,0,1,1,0,1]
6406  * - \a rankInsideCast: [2,1,0,3,2,3,4,1,0]
6407  * - \a castsPresent  : [0,1]
6408  *
6409  * I.e. values of \a this array belong to 2 ranges: #0 and #1. Value 6 belongs to the
6410  * range #1 and its rank within this range is 2; etc.
6411  *
6412  *  \throw If \a this->getNumberOfComponents() != 1.
6413  *  \throw If \a arrEnd - arrBg < 2.
6414  *  \throw If any value of \a this is not less than \a arrEnd[-1].
6415  */
6416 void DataArrayInt::splitByValueRange(const int *arrBg, const int *arrEnd,
6417                                      DataArrayInt *& castArr, DataArrayInt *& rankInsideCast, DataArrayInt *& castsPresent) const
6418     {
6419   checkAllocated();
6420   if(getNumberOfComponents()!=1)
6421     throw INTERP_KERNEL::Exception("Call splitByValueRange  method on DataArrayInt with only one component, you can call 'rearrange' method before !");
6422   int nbOfTuples=getNumberOfTuples();
6423   std::size_t nbOfCast=std::distance(arrBg,arrEnd);
6424   if(nbOfCast<2)
6425     throw INTERP_KERNEL::Exception("DataArrayInt::splitByValueRange : The input array giving the cast range values should be of size >=2 !");
6426   nbOfCast--;
6427   const int *work=getConstPointer();
6428   typedef std::reverse_iterator<const int *> rintstart;
6429   rintstart bg(arrEnd);//OK no problem because size of 'arr' is greater or equal 2
6430   rintstart end2(arrBg);
6431   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret1=DataArrayInt::New();
6432   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret2=DataArrayInt::New();
6433   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret3=DataArrayInt::New();
6434   ret1->alloc(nbOfTuples,1);
6435   ret2->alloc(nbOfTuples,1);
6436   int *ret1Ptr=ret1->getPointer();
6437   int *ret2Ptr=ret2->getPointer();
6438   std::set<std::size_t> castsDetected;
6439   for(int i=0;i<nbOfTuples;i++)
6440     {
6441       rintstart res=std::find_if(bg,end2,std::bind2nd(std::less_equal<int>(), work[i]));
6442       std::size_t pos=std::distance(bg,res);
6443       std::size_t pos2=nbOfCast-pos;
6444       if(pos2<nbOfCast)
6445         {
6446           ret1Ptr[i]=(int)pos2;
6447           ret2Ptr[i]=work[i]-arrBg[pos2];
6448           castsDetected.insert(pos2);
6449         }
6450       else
6451         {
6452           std::ostringstream oss; oss << "DataArrayInt::splitByValueRange : At rank #" << i << " the value is " << work[i] << " should be in [0," << *bg << ") !";
6453           throw INTERP_KERNEL::Exception(oss.str().c_str());
6454         }
6455     }
6456   ret3->alloc((int)castsDetected.size(),1);
6457   std::copy(castsDetected.begin(),castsDetected.end(),ret3->getPointer());
6458   castArr=ret1.retn();
6459   rankInsideCast=ret2.retn();
6460   castsPresent=ret3.retn();
6461     }
6462
6463 /*!
6464  * Creates a one-dimensional DataArrayInt (\a res) whose contents are computed from 
6465  * values of \a this (\a a) and the given (\a indArr) arrays as follows:
6466  * \a res[ \a indArr[ \a a[ i ]]] = i. I.e. for each value in place i \a v = \a a[ i ],
6467  * new value in place \a indArr[ \a v ] is i.
6468  *  \param [in] indArrBg - the array holding indices within the result array to assign
6469  *         indices of values of \a this array pointing to values of \a indArrBg.
6470  *  \param [in] indArrEnd - specifies the end of the array \a indArrBg, so that
6471  *              the last value of \a indArrBg is \a indArrEnd[ -1 ].
6472  *  \return DataArrayInt * - the new instance of DataArrayInt.
6473  *          The caller is to delete this result array using decrRef() as it is no more
6474  *          needed.
6475  *  \throw If \a this->getNumberOfComponents() != 1.
6476  *  \throw If any value of \a this array is not a valid index for \a indArrBg array.
6477  *  \throw If any value of \a indArrBg is not a valid index for \a this array.
6478  */
6479 DataArrayInt *DataArrayInt::transformWithIndArrR(const int *indArrBg, const int *indArrEnd) const
6480 {
6481   checkAllocated();
6482   if(getNumberOfComponents()!=1)
6483     throw INTERP_KERNEL::Exception("Call transformWithIndArrR method on DataArrayInt with only one component, you can call 'rearrange' method before !");
6484   int nbElemsIn=(int)std::distance(indArrBg,indArrEnd);
6485   int nbOfTuples=getNumberOfTuples();
6486   const int *pt=getConstPointer();
6487   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6488   ret->alloc(nbOfTuples,1);
6489   ret->fillWithValue(-1);
6490   int *tmp=ret->getPointer();
6491   for(int i=0;i<nbOfTuples;i++,pt++)
6492     {
6493       if(*pt>=0 && *pt<nbElemsIn)
6494         {
6495           int pos=indArrBg[*pt];
6496           if(pos>=0 && pos<nbOfTuples)
6497             tmp[pos]=i;
6498           else
6499             {
6500               std::ostringstream oss; oss << "DataArrayInt::transformWithIndArrR : error on tuple #" << i << " value of new pos is " << pos << " ( indArrBg[" << *pt << "]) ! Should be in [0," << nbOfTuples << ") !";
6501               throw INTERP_KERNEL::Exception(oss.str().c_str());
6502             }
6503         }
6504       else
6505         {
6506           std::ostringstream oss; oss << "DataArrayInt::transformWithIndArrR : error on tuple #" << i << " value is " << *pt << " and indirectionnal array as a size equal to " << nbElemsIn << " !";
6507           throw INTERP_KERNEL::Exception(oss.str().c_str());
6508         }
6509     }
6510   return ret.retn();
6511 }
6512
6513 /*!
6514  * Creates a one-dimensional DataArrayInt of given length, whose contents are computed
6515  * from values of \a this array, which is supposed to contain a renumbering map in 
6516  * "Old to New" mode. The result array contains a renumbering map in "New to Old" mode.
6517  * To know how to use the renumbering maps see \ref MEDCouplingArrayRenumbering.
6518  *  \param [in] newNbOfElem - the number of tuples in the result array.
6519  *  \return DataArrayInt * - the new instance of DataArrayInt.
6520  *          The caller is to delete this result array using decrRef() as it is no more
6521  *          needed.
6522  * 
6523  *  \if ENABLE_EXAMPLES
6524  *  \ref cpp_mcdataarrayint_invertarrayo2n2n2o "Here is a C++ example".<br>
6525  *  \ref py_mcdataarrayint_invertarrayo2n2n2o  "Here is a Python example".
6526  *  \endif
6527  */
6528 DataArrayInt *DataArrayInt::invertArrayO2N2N2O(int newNbOfElem) const
6529 {
6530   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6531   ret->alloc(newNbOfElem,1);
6532   int nbOfOldNodes=getNumberOfTuples();
6533   const int *old2New=getConstPointer();
6534   int *pt=ret->getPointer();
6535   for(int i=0;i!=nbOfOldNodes;i++)
6536     {
6537       int newp(old2New[i]);
6538       if(newp!=-1)
6539         {
6540           if(newp>=0 && newp<newNbOfElem)
6541             pt[newp]=i;
6542           else
6543             {
6544               std::ostringstream oss; oss << "DataArrayInt::invertArrayO2N2N2O : At place #" << i << " the newplace is " << newp << " must be in [0," << newNbOfElem << ") !";
6545               throw INTERP_KERNEL::Exception(oss.str().c_str());
6546             }
6547         }
6548     }
6549   return ret.retn();
6550 }
6551
6552 /*!
6553  * This method is similar to DataArrayInt::invertArrayO2N2N2O except that 
6554  * 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]
6555  */
6556 DataArrayInt *DataArrayInt::invertArrayO2N2N2OBis(int newNbOfElem) const
6557 {
6558   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6559   ret->alloc(newNbOfElem,1);
6560   int nbOfOldNodes=getNumberOfTuples();
6561   const int *old2New=getConstPointer();
6562   int *pt=ret->getPointer();
6563   for(int i=nbOfOldNodes-1;i>=0;i--)
6564     {
6565       int newp(old2New[i]);
6566       if(newp!=-1)
6567         {
6568           if(newp>=0 && newp<newNbOfElem)
6569             pt[newp]=i;
6570           else
6571             {
6572               std::ostringstream oss; oss << "DataArrayInt::invertArrayO2N2N2OBis : At place #" << i << " the newplace is " << newp << " must be in [0," << newNbOfElem << ") !";
6573               throw INTERP_KERNEL::Exception(oss.str().c_str());
6574             }
6575         }
6576     }
6577   return ret.retn();
6578 }
6579
6580 /*!
6581  * Creates a one-dimensional DataArrayInt of given length, whose contents are computed
6582  * from values of \a this array, which is supposed to contain a renumbering map in 
6583  * "New to Old" mode. The result array contains a renumbering map in "Old to New" mode.
6584  * To know how to use the renumbering maps see \ref MEDCouplingArrayRenumbering.
6585  *  \param [in] newNbOfElem - the number of tuples in the result array.
6586  *  \return DataArrayInt * - the new instance of DataArrayInt.
6587  *          The caller is to delete this result array using decrRef() as it is no more
6588  *          needed.
6589  * 
6590  *  \if ENABLE_EXAMPLES
6591  *  \ref cpp_mcdataarrayint_invertarrayn2o2o2n "Here is a C++ example".
6592  *
6593  *  \ref py_mcdataarrayint_invertarrayn2o2o2n "Here is a Python example".
6594  *  \endif
6595  */
6596 DataArrayInt *DataArrayInt::invertArrayN2O2O2N(int oldNbOfElem) const
6597 {
6598   checkAllocated();
6599   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6600   ret->alloc(oldNbOfElem,1);
6601   const int *new2Old=getConstPointer();
6602   int *pt=ret->getPointer();
6603   std::fill(pt,pt+oldNbOfElem,-1);
6604   int nbOfNewElems=getNumberOfTuples();
6605   for(int i=0;i<nbOfNewElems;i++)
6606     {
6607       int v(new2Old[i]);
6608       if(v>=0 && v<oldNbOfElem)
6609         pt[v]=i;
6610       else
6611         {
6612           std::ostringstream oss; oss << "DataArrayInt::invertArrayN2O2O2N : in new id #" << i << " old value is " << v << " expected to be in [0," << oldNbOfElem << ") !";
6613           throw INTERP_KERNEL::Exception(oss.str().c_str());
6614         }
6615     }
6616   return ret.retn();
6617 }
6618
6619 /*!
6620  * Equivalent to DataArrayInt::isEqual except that if false the reason of
6621  * mismatch is given.
6622  * 
6623  * \param [in] other the instance to be compared with \a this
6624  * \param [out] reason In case of inequality returns the reason.
6625  * \sa DataArrayInt::isEqual
6626  */
6627 bool DataArrayInt::isEqualIfNotWhy(const DataArrayInt& other, std::string& reason) const
6628 {
6629   if(!areInfoEqualsIfNotWhy(other,reason))
6630     return false;
6631   return _mem.isEqual(other._mem,0,reason);
6632 }
6633
6634 /*!
6635  * Checks if \a this and another DataArrayInt are fully equal. For more info see
6636  * \ref MEDCouplingArrayBasicsCompare.
6637  *  \param [in] other - an instance of DataArrayInt to compare with \a this one.
6638  *  \return bool - \a true if the two arrays are equal, \a false else.
6639  */
6640 bool DataArrayInt::isEqual(const DataArrayInt& other) const
6641 {
6642   std::string tmp;
6643   return isEqualIfNotWhy(other,tmp);
6644 }
6645
6646 /*!
6647  * Checks if values of \a this and another DataArrayInt are equal. For more info see
6648  * \ref MEDCouplingArrayBasicsCompare.
6649  *  \param [in] other - an instance of DataArrayInt to compare with \a this one.
6650  *  \return bool - \a true if the values of two arrays are equal, \a false else.
6651  */
6652 bool DataArrayInt::isEqualWithoutConsideringStr(const DataArrayInt& other) const
6653 {
6654   std::string tmp;
6655   return _mem.isEqual(other._mem,0,tmp);
6656 }
6657
6658 /*!
6659  * Checks if values of \a this and another DataArrayInt are equal. Comparison is
6660  * performed on sorted value sequences.
6661  * For more info see\ref MEDCouplingArrayBasicsCompare.
6662  *  \param [in] other - an instance of DataArrayInt to compare with \a this one.
6663  *  \return bool - \a true if the sorted values of two arrays are equal, \a false else.
6664  */
6665 bool DataArrayInt::isEqualWithoutConsideringStrAndOrder(const DataArrayInt& other) const
6666 {
6667   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> a=deepCpy();
6668   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> b=other.deepCpy();
6669   a->sort();
6670   b->sort();
6671   return a->isEqualWithoutConsideringStr(*b);
6672 }
6673
6674 /*!
6675  * This method compares content of input vector \a v and \a this.
6676  * 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.
6677  * For performance reasons \a this is expected to be sorted ascendingly. If not an exception will be thrown.
6678  *
6679  * \param [in] v - the vector of 'flags' to be compared with \a this.
6680  *
6681  * \throw If \a this is not sorted ascendingly.
6682  * \throw If \a this has not exactly one component.
6683  * \throw If \a this is not allocated.
6684  */
6685 bool DataArrayInt::isFittingWith(const std::vector<bool>& v) const
6686 {
6687   checkAllocated();
6688   if(getNumberOfComponents()!=1)
6689     throw INTERP_KERNEL::Exception("DataArrayInt::isFittingWith : number of components of this should be equal to one !");
6690   const int *w(begin()),*end2(end());
6691   int refVal=-std::numeric_limits<int>::max();
6692   int i=0;
6693   std::vector<bool>::const_iterator it(v.begin());
6694   for(;it!=v.end();it++,i++)
6695     {
6696       if(*it)
6697         {
6698           if(w!=end2)
6699             {
6700               if(*w++==i)
6701                 {
6702                   if(i>refVal)
6703                     refVal=i;
6704                   else
6705                     {
6706                       std::ostringstream oss; oss << "DataArrayInt::isFittingWith : At pos #" << std::distance(begin(),w-1) << " this is not sorted ascendingly !";
6707                       throw INTERP_KERNEL::Exception(oss.str().c_str());
6708                     }
6709                 }
6710               else
6711                 return false;
6712             }
6713           else
6714             return false;
6715         }
6716     }
6717   return w==end2;
6718 }
6719
6720 /*!
6721  * Sorts values of the array.
6722  *  \param [in] asc - \a true means ascending order, \a false, descending.
6723  *  \throw If \a this is not allocated.
6724  *  \throw If \a this->getNumberOfComponents() != 1.
6725  */
6726 void DataArrayInt::sort(bool asc)
6727 {
6728   checkAllocated();
6729   if(getNumberOfComponents()!=1)
6730     throw INTERP_KERNEL::Exception("DataArrayInt::sort : only supported with 'this' array with ONE component !");
6731   _mem.sort(asc);
6732   declareAsNew();
6733 }
6734
6735 /*!
6736  * Computes for each tuple the sum of number of components values in the tuple and return it.
6737  * 
6738  * \return DataArrayInt * - the new instance of DataArrayInt containing the
6739  *          same number of tuples as \a this array and one component.
6740  *          The caller is to delete this result array using decrRef() as it is no more
6741  *          needed.
6742  *  \throw If \a this is not allocated.
6743  */
6744 DataArrayInt *DataArrayInt::sumPerTuple() const
6745 {
6746   checkAllocated();
6747   int nbOfComp(getNumberOfComponents()),nbOfTuple(getNumberOfTuples());
6748   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New());
6749   ret->alloc(nbOfTuple,1);
6750   const int *src(getConstPointer());
6751   int *dest(ret->getPointer());
6752   for(int i=0;i<nbOfTuple;i++,dest++,src+=nbOfComp)
6753     *dest=std::accumulate(src,src+nbOfComp,0);
6754   return ret.retn();
6755 }
6756
6757 /*!
6758  * Reverse the array values.
6759  *  \throw If \a this->getNumberOfComponents() < 1.
6760  *  \throw If \a this is not allocated.
6761  */
6762 void DataArrayInt::reverse()
6763 {
6764   checkAllocated();
6765   _mem.reverse(getNumberOfComponents());
6766   declareAsNew();
6767 }
6768
6769 /*!
6770  * Checks that \a this array is consistently **increasing** or **decreasing** in value.
6771  * If not an exception is thrown.
6772  *  \param [in] increasing - if \a true, the array values should be increasing.
6773  *  \throw If sequence of values is not strictly monotonic in agreement with \a
6774  *         increasing arg.
6775  *  \throw If \a this->getNumberOfComponents() != 1.
6776  *  \throw If \a this is not allocated.
6777  */
6778 void DataArrayInt::checkMonotonic(bool increasing) const
6779 {
6780   if(!isMonotonic(increasing))
6781     {
6782       if (increasing)
6783         throw INTERP_KERNEL::Exception("DataArrayInt::checkMonotonic : 'this' is not INCREASING monotonic !");
6784       else
6785         throw INTERP_KERNEL::Exception("DataArrayInt::checkMonotonic : 'this' is not DECREASING monotonic !");
6786     }
6787 }
6788
6789 /*!
6790  * Checks that \a this array is consistently **increasing** or **decreasing** in value.
6791  *  \param [in] increasing - if \a true, array values should be increasing.
6792  *  \return bool - \a true if values change in accordance with \a increasing arg.
6793  *  \throw If \a this->getNumberOfComponents() != 1.
6794  *  \throw If \a this is not allocated.
6795  */
6796 bool DataArrayInt::isMonotonic(bool increasing) const
6797 {
6798   checkAllocated();
6799   if(getNumberOfComponents()!=1)
6800     throw INTERP_KERNEL::Exception("DataArrayInt::isMonotonic : only supported with 'this' array with ONE component !");
6801   int nbOfElements=getNumberOfTuples();
6802   const int *ptr=getConstPointer();
6803   if(nbOfElements==0)
6804     return true;
6805   int ref=ptr[0];
6806   if(increasing)
6807     {
6808       for(int i=1;i<nbOfElements;i++)
6809         {
6810           if(ptr[i]>=ref)
6811             ref=ptr[i];
6812           else
6813             return false;
6814         }
6815     }
6816   else
6817     {
6818       for(int i=1;i<nbOfElements;i++)
6819         {
6820           if(ptr[i]<=ref)
6821             ref=ptr[i];
6822           else
6823             return false;
6824         }
6825     }
6826   return true;
6827 }
6828
6829 /*!
6830  * This method check that array consistently INCREASING or DECREASING in value.
6831  */
6832 bool DataArrayInt::isStrictlyMonotonic(bool increasing) const
6833 {
6834   checkAllocated();
6835   if(getNumberOfComponents()!=1)
6836     throw INTERP_KERNEL::Exception("DataArrayInt::isStrictlyMonotonic : only supported with 'this' array with ONE component !");
6837   int nbOfElements=getNumberOfTuples();
6838   const int *ptr=getConstPointer();
6839   if(nbOfElements==0)
6840     return true;
6841   int ref=ptr[0];
6842   if(increasing)
6843     {
6844       for(int i=1;i<nbOfElements;i++)
6845         {
6846           if(ptr[i]>ref)
6847             ref=ptr[i];
6848           else
6849             return false;
6850         }
6851     }
6852   else
6853     {
6854       for(int i=1;i<nbOfElements;i++)
6855         {
6856           if(ptr[i]<ref)
6857             ref=ptr[i];
6858           else
6859             return false;
6860         }
6861     }
6862   return true;
6863 }
6864
6865 /*!
6866  * This method check that array consistently INCREASING or DECREASING in value.
6867  */
6868 void DataArrayInt::checkStrictlyMonotonic(bool increasing) const
6869 {
6870   if(!isStrictlyMonotonic(increasing))
6871     {
6872       if (increasing)
6873         throw INTERP_KERNEL::Exception("DataArrayInt::checkStrictlyMonotonic : 'this' is not strictly INCREASING monotonic !");
6874       else
6875         throw INTERP_KERNEL::Exception("DataArrayInt::checkStrictlyMonotonic : 'this' is not strictly DECREASING monotonic !");
6876     }
6877 }
6878
6879 /*!
6880  * Creates a new one-dimensional DataArrayInt of the same size as \a this and a given
6881  * one-dimensional arrays that must be of the same length. The result array describes
6882  * correspondence between \a this and \a other arrays, so that 
6883  * <em> other.getIJ(i,0) == this->getIJ(ret->getIJ(i),0)</em>. If such a permutation is
6884  * not possible because some element in \a other is not in \a this, an exception is thrown.
6885  *  \param [in] other - an array to compute permutation to.
6886  *  \return DataArrayInt * - a new instance of DataArrayInt, which is a permutation array
6887  * from \a this to \a other. The caller is to delete this array using decrRef() as it is
6888  * no more needed.
6889  *  \throw If \a this->getNumberOfComponents() != 1.
6890  *  \throw If \a other->getNumberOfComponents() != 1.
6891  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples().
6892  *  \throw If \a other includes a value which is not in \a this array.
6893  * 
6894  *  \if ENABLE_EXAMPLES
6895  *  \ref cpp_mcdataarrayint_buildpermutationarr "Here is a C++ example".
6896  *
6897  *  \ref py_mcdataarrayint_buildpermutationarr "Here is a Python example".
6898  *  \endif
6899  */
6900 DataArrayInt *DataArrayInt::buildPermutationArr(const DataArrayInt& other) const
6901 {
6902   checkAllocated();
6903   if(getNumberOfComponents()!=1 || other.getNumberOfComponents()!=1)
6904     throw INTERP_KERNEL::Exception("DataArrayInt::buildPermutationArr : 'this' and 'other' have to have exactly ONE component !");
6905   int nbTuple=getNumberOfTuples();
6906   other.checkAllocated();
6907   if(nbTuple!=other.getNumberOfTuples())
6908     throw INTERP_KERNEL::Exception("DataArrayInt::buildPermutationArr : 'this' and 'other' must have the same number of tuple !");
6909   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6910   ret->alloc(nbTuple,1);
6911   ret->fillWithValue(-1);
6912   const int *pt=getConstPointer();
6913   std::map<int,int> mm;
6914   for(int i=0;i<nbTuple;i++)
6915     mm[pt[i]]=i;
6916   pt=other.getConstPointer();
6917   int *retToFill=ret->getPointer();
6918   for(int i=0;i<nbTuple;i++)
6919     {
6920       std::map<int,int>::const_iterator it=mm.find(pt[i]);
6921       if(it==mm.end())
6922         {
6923           std::ostringstream oss; oss << "DataArrayInt::buildPermutationArr : Arrays mismatch : element (" << pt[i] << ") in 'other' not findable in 'this' !";
6924           throw INTERP_KERNEL::Exception(oss.str().c_str());
6925         }
6926       retToFill[i]=(*it).second;
6927     }
6928   return ret.retn();
6929 }
6930
6931 /*!
6932  * Sets a C array to be used as raw data of \a this. The previously set info
6933  *  of components is retained and re-sized. 
6934  * For more info see \ref MEDCouplingArraySteps1.
6935  *  \param [in] array - the C array to be used as raw data of \a this.
6936  *  \param [in] ownership - if \a true, \a array will be deallocated at destruction of \a this.
6937  *  \param [in] type - specifies how to deallocate \a array. If \a type == ParaMEDMEM::CPP_DEALLOC,
6938  *                     \c delete [] \c array; will be called. If \a type == ParaMEDMEM::C_DEALLOC,
6939  *                     \c free(\c array ) will be called.
6940  *  \param [in] nbOfTuple - new number of tuples in \a this.
6941  *  \param [in] nbOfCompo - new number of components in \a this.
6942  */
6943 void DataArrayInt::useArray(const int *array, bool ownership,  DeallocType type, int nbOfTuple, int nbOfCompo)
6944 {
6945   _info_on_compo.resize(nbOfCompo);
6946   _mem.useArray(array,ownership,type,nbOfTuple*nbOfCompo);
6947   declareAsNew();
6948 }
6949
6950 void DataArrayInt::useExternalArrayWithRWAccess(const int *array, int nbOfTuple, int nbOfCompo)
6951 {
6952   _info_on_compo.resize(nbOfCompo);
6953   _mem.useExternalArrayWithRWAccess(array,nbOfTuple*nbOfCompo);
6954   declareAsNew();
6955 }
6956
6957 /*!
6958  * Returns a new DataArrayInt holding the same values as \a this array but differently
6959  * arranged in memory. If \a this array holds 2 components of 3 values:
6960  * \f$ x_0,x_1,x_2,y_0,y_1,y_2 \f$, then the result array holds these values arranged
6961  * as follows: \f$ x_0,y_0,x_1,y_1,x_2,y_2 \f$.
6962  *  \warning Do not confuse this method with transpose()!
6963  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
6964  *          is to delete using decrRef() as it is no more needed.
6965  *  \throw If \a this is not allocated.
6966  */
6967 DataArrayInt *DataArrayInt::fromNoInterlace() const
6968 {
6969   checkAllocated();
6970   if(_mem.isNull())
6971     throw INTERP_KERNEL::Exception("DataArrayInt::fromNoInterlace : Not defined array !");
6972   int *tab=_mem.fromNoInterlace(getNumberOfComponents());
6973   DataArrayInt *ret=DataArrayInt::New();
6974   ret->useArray(tab,true,C_DEALLOC,getNumberOfTuples(),getNumberOfComponents());
6975   return ret;
6976 }
6977
6978 /*!
6979  * Returns a new DataArrayInt holding the same values as \a this array but differently
6980  * arranged in memory. If \a this array holds 2 components of 3 values:
6981  * \f$ x_0,y_0,x_1,y_1,x_2,y_2 \f$, then the result array holds these values arranged
6982  * as follows: \f$ x_0,x_1,x_2,y_0,y_1,y_2 \f$.
6983  *  \warning Do not confuse this method with transpose()!
6984  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
6985  *          is to delete using decrRef() as it is no more needed.
6986  *  \throw If \a this is not allocated.
6987  */
6988 DataArrayInt *DataArrayInt::toNoInterlace() const
6989 {
6990   checkAllocated();
6991   if(_mem.isNull())
6992     throw INTERP_KERNEL::Exception("DataArrayInt::toNoInterlace : Not defined array !");
6993   int *tab=_mem.toNoInterlace(getNumberOfComponents());
6994   DataArrayInt *ret=DataArrayInt::New();
6995   ret->useArray(tab,true,C_DEALLOC,getNumberOfTuples(),getNumberOfComponents());
6996   return ret;
6997 }
6998
6999 /*!
7000  * Permutes values of \a this array as required by \a old2New array. The values are
7001  * permuted so that \c new[ \a old2New[ i ]] = \c old[ i ]. Number of tuples remains
7002  * the same as in \this one.
7003  * If a permutation reduction is needed, substr() or selectByTupleId() should be used.
7004  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
7005  *  \param [in] old2New - C array of length equal to \a this->getNumberOfTuples()
7006  *     giving a new position for i-th old value.
7007  */
7008 void DataArrayInt::renumberInPlace(const int *old2New)
7009 {
7010   checkAllocated();
7011   int nbTuples=getNumberOfTuples();
7012   int nbOfCompo=getNumberOfComponents();
7013   int *tmp=new int[nbTuples*nbOfCompo];
7014   const int *iptr=getConstPointer();
7015   for(int i=0;i<nbTuples;i++)
7016     {
7017       int v=old2New[i];
7018       if(v>=0 && v<nbTuples)
7019         std::copy(iptr+nbOfCompo*i,iptr+nbOfCompo*(i+1),tmp+nbOfCompo*v);
7020       else
7021         {
7022           std::ostringstream oss; oss << "DataArrayInt::renumberInPlace : At place #" << i << " value is " << v << " ! Should be in [0," << nbTuples << ") !";
7023           throw INTERP_KERNEL::Exception(oss.str().c_str());
7024         }
7025     }
7026   std::copy(tmp,tmp+nbTuples*nbOfCompo,getPointer());
7027   delete [] tmp;
7028   declareAsNew();
7029 }
7030
7031 /*!
7032  * Permutes values of \a this array as required by \a new2Old array. The values are
7033  * permuted so that \c new[ i ] = \c old[ \a new2Old[ i ]]. Number of tuples remains
7034  * the same as in \this one.
7035  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
7036  *  \param [in] new2Old - C array of length equal to \a this->getNumberOfTuples()
7037  *     giving a previous position of i-th new value.
7038  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
7039  *          is to delete using decrRef() as it is no more needed.
7040  */
7041 void DataArrayInt::renumberInPlaceR(const int *new2Old)
7042 {
7043   checkAllocated();
7044   int nbTuples=getNumberOfTuples();
7045   int nbOfCompo=getNumberOfComponents();
7046   int *tmp=new int[nbTuples*nbOfCompo];
7047   const int *iptr=getConstPointer();
7048   for(int i=0;i<nbTuples;i++)
7049     {
7050       int v=new2Old[i];
7051       if(v>=0 && v<nbTuples)
7052         std::copy(iptr+nbOfCompo*v,iptr+nbOfCompo*(v+1),tmp+nbOfCompo*i);
7053       else
7054         {
7055           std::ostringstream oss; oss << "DataArrayInt::renumberInPlaceR : At place #" << i << " value is " << v << " ! Should be in [0," << nbTuples << ") !";
7056           throw INTERP_KERNEL::Exception(oss.str().c_str());
7057         }
7058     }
7059   std::copy(tmp,tmp+nbTuples*nbOfCompo,getPointer());
7060   delete [] tmp;
7061   declareAsNew();
7062 }
7063
7064 /*!
7065  * Returns a copy of \a this array with values permuted as required by \a old2New array.
7066  * The values are permuted so that  \c new[ \a old2New[ i ]] = \c old[ i ].
7067  * Number of tuples in the result array remains the same as in \this one.
7068  * If a permutation reduction is needed, renumberAndReduce() should be used.
7069  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
7070  *  \param [in] old2New - C array of length equal to \a this->getNumberOfTuples()
7071  *          giving a new position for i-th old value.
7072  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
7073  *          is to delete using decrRef() as it is no more needed.
7074  *  \throw If \a this is not allocated.
7075  */
7076 DataArrayInt *DataArrayInt::renumber(const int *old2New) const
7077 {
7078   checkAllocated();
7079   int nbTuples=getNumberOfTuples();
7080   int nbOfCompo=getNumberOfComponents();
7081   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
7082   ret->alloc(nbTuples,nbOfCompo);
7083   ret->copyStringInfoFrom(*this);
7084   const int *iptr=getConstPointer();
7085   int *optr=ret->getPointer();
7086   for(int i=0;i<nbTuples;i++)
7087     std::copy(iptr+nbOfCompo*i,iptr+nbOfCompo*(i+1),optr+nbOfCompo*old2New[i]);
7088   ret->copyStringInfoFrom(*this);
7089   return ret.retn();
7090 }
7091
7092 /*!
7093  * Returns a copy of \a this array with values permuted as required by \a new2Old array.
7094  * The values are permuted so that  \c new[ i ] = \c old[ \a new2Old[ i ]]. Number of
7095  * tuples in the result array remains the same as in \this one.
7096  * If a permutation reduction is needed, substr() or selectByTupleId() should be used.
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 DataArrayInt *DataArrayInt::renumberR(const int *new2Old) const
7104 {
7105   checkAllocated();
7106   int nbTuples=getNumberOfTuples();
7107   int nbOfCompo=getNumberOfComponents();
7108   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
7109   ret->alloc(nbTuples,nbOfCompo);
7110   ret->copyStringInfoFrom(*this);
7111   const int *iptr=getConstPointer();
7112   int *optr=ret->getPointer();
7113   for(int i=0;i<nbTuples;i++)
7114     std::copy(iptr+nbOfCompo*new2Old[i],iptr+nbOfCompo*(new2Old[i]+1),optr+nbOfCompo*i);
7115   ret->copyStringInfoFrom(*this);
7116   return ret.retn();
7117 }
7118
7119 /*!
7120  * Returns a shorten and permuted copy of \a this array. The new DataArrayInt is
7121  * of size \a newNbOfTuple and it's values are permuted as required by \a old2New array.
7122  * The values are permuted so that  \c new[ \a old2New[ i ]] = \c old[ i ] for all
7123  * \a old2New[ i ] >= 0. In other words every i-th tuple in \a this array, for which 
7124  * \a old2New[ i ] is negative, is missing from the result array.
7125  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
7126  *  \param [in] old2New - C array of length equal to \a this->getNumberOfTuples()
7127  *     giving a new position for i-th old tuple and giving negative position for
7128  *     for i-th old tuple that should be omitted.
7129  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
7130  *          is to delete using decrRef() as it is no more needed.
7131  */
7132 DataArrayInt *DataArrayInt::renumberAndReduce(const int *old2New, int newNbOfTuple) const
7133 {
7134   checkAllocated();
7135   int nbTuples=getNumberOfTuples();
7136   int nbOfCompo=getNumberOfComponents();
7137   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
7138   ret->alloc(newNbOfTuple,nbOfCompo);
7139   const int *iptr=getConstPointer();
7140   int *optr=ret->getPointer();
7141   for(int i=0;i<nbTuples;i++)
7142     {
7143       int w=old2New[i];
7144       if(w>=0)
7145         std::copy(iptr+i*nbOfCompo,iptr+(i+1)*nbOfCompo,optr+w*nbOfCompo);
7146     }
7147   ret->copyStringInfoFrom(*this);
7148   return ret.retn();
7149 }
7150
7151 /*!
7152  * Returns a shorten and permuted copy of \a this array. The new DataArrayInt is
7153  * of size \a new2OldEnd - \a new2OldBg and it's values are permuted as required by
7154  * \a new2OldBg array.
7155  * The values are permuted so that  \c new[ i ] = \c old[ \a new2OldBg[ i ]].
7156  * This method is equivalent to renumberAndReduce() except that convention in input is
7157  * \c new2old and \b not \c old2new.
7158  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
7159  *  \param [in] new2OldBg - pointer to the beginning of a permutation array that gives a
7160  *              tuple index in \a this array to fill the i-th tuple in the new array.
7161  *  \param [in] new2OldEnd - specifies the end of the permutation array that starts at
7162  *              \a new2OldBg, so that pointer to a tuple index (\a pi) varies as this:
7163  *              \a new2OldBg <= \a pi < \a new2OldEnd.
7164  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
7165  *          is to delete using decrRef() as it is no more needed.
7166  */
7167 DataArrayInt *DataArrayInt::selectByTupleId(const int *new2OldBg, const int *new2OldEnd) const
7168 {
7169   checkAllocated();
7170   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
7171   int nbComp=getNumberOfComponents();
7172   ret->alloc((int)std::distance(new2OldBg,new2OldEnd),nbComp);
7173   ret->copyStringInfoFrom(*this);
7174   int *pt=ret->getPointer();
7175   const int *srcPt=getConstPointer();
7176   int i=0;
7177   for(const int *w=new2OldBg;w!=new2OldEnd;w++,i++)
7178     std::copy(srcPt+(*w)*nbComp,srcPt+((*w)+1)*nbComp,pt+i*nbComp);
7179   ret->copyStringInfoFrom(*this);
7180   return ret.retn();
7181 }
7182
7183 /*!
7184  * Returns a shorten and permuted copy of \a this array. The new DataArrayInt is
7185  * of size \a new2OldEnd - \a new2OldBg and it's values are permuted as required by
7186  * \a new2OldBg array.
7187  * The values are permuted so that  \c new[ i ] = \c old[ \a new2OldBg[ i ]].
7188  * This method is equivalent to renumberAndReduce() except that convention in input is
7189  * \c new2old and \b not \c old2new.
7190  * This method is equivalent to selectByTupleId() except that it prevents coping data
7191  * from behind the end of \a this array.
7192  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
7193  *  \param [in] new2OldBg - pointer to the beginning of a permutation array that gives a
7194  *              tuple index in \a this array to fill the i-th tuple in the new array.
7195  *  \param [in] new2OldEnd - specifies the end of the permutation array that starts at
7196  *              \a new2OldBg, so that pointer to a tuple index (\a pi) varies as this:
7197  *              \a new2OldBg <= \a pi < \a new2OldEnd.
7198  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
7199  *          is to delete using decrRef() as it is no more needed.
7200  *  \throw If \a new2OldEnd - \a new2OldBg > \a this->getNumberOfTuples().
7201  */
7202 DataArrayInt *DataArrayInt::selectByTupleIdSafe(const int *new2OldBg, const int *new2OldEnd) const
7203 {
7204   checkAllocated();
7205   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
7206   int nbComp=getNumberOfComponents();
7207   int oldNbOfTuples=getNumberOfTuples();
7208   ret->alloc((int)std::distance(new2OldBg,new2OldEnd),nbComp);
7209   ret->copyStringInfoFrom(*this);
7210   int *pt=ret->getPointer();
7211   const int *srcPt=getConstPointer();
7212   int i=0;
7213   for(const int *w=new2OldBg;w!=new2OldEnd;w++,i++)
7214     if(*w>=0 && *w<oldNbOfTuples)
7215       std::copy(srcPt+(*w)*nbComp,srcPt+((*w)+1)*nbComp,pt+i*nbComp);
7216     else
7217       throw INTERP_KERNEL::Exception("DataArrayInt::selectByTupleIdSafe : some ids has been detected to be out of [0,this->getNumberOfTuples) !");
7218   ret->copyStringInfoFrom(*this);
7219   return ret.retn();
7220 }
7221
7222 /*!
7223  * Returns a shorten copy of \a this array. The new DataArrayInt contains every
7224  * (\a bg + \c i * \a step)-th tuple of \a this array located before the \a end2-th
7225  * tuple. Indices of the selected tuples are the same as ones returned by the Python
7226  * command \c range( \a bg, \a end2, \a step ).
7227  * This method is equivalent to selectByTupleIdSafe() except that the input array is
7228  * not constructed explicitly.
7229  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
7230  *  \param [in] bg - index of the first tuple to copy from \a this array.
7231  *  \param [in] end2 - index of the tuple before which the tuples to copy are located.
7232  *  \param [in] step - index increment to get index of the next tuple to copy.
7233  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
7234  *          is to delete using decrRef() as it is no more needed.
7235  *  \sa DataArrayInt::substr.
7236  */
7237 DataArrayInt *DataArrayInt::selectByTupleId2(int bg, int end2, int step) const
7238 {
7239   checkAllocated();
7240   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
7241   int nbComp=getNumberOfComponents();
7242   int newNbOfTuples=GetNumberOfItemGivenBESRelative(bg,end2,step,"DataArrayInt::selectByTupleId2 : ");
7243   ret->alloc(newNbOfTuples,nbComp);
7244   int *pt=ret->getPointer();
7245   const int *srcPt=getConstPointer()+bg*nbComp;
7246   for(int i=0;i<newNbOfTuples;i++,srcPt+=step*nbComp)
7247     std::copy(srcPt,srcPt+nbComp,pt+i*nbComp);
7248   ret->copyStringInfoFrom(*this);
7249   return ret.retn();
7250 }
7251
7252 /*!
7253  * Returns a shorten copy of \a this array. The new DataArrayInt contains ranges
7254  * of tuples specified by \a ranges parameter.
7255  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
7256  *  \param [in] ranges - std::vector of std::pair's each of which defines a range
7257  *              of tuples in [\c begin,\c end) format.
7258  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
7259  *          is to delete using decrRef() as it is no more needed.
7260  *  \throw If \a end < \a begin.
7261  *  \throw If \a end > \a this->getNumberOfTuples().
7262  *  \throw If \a this is not allocated.
7263  */
7264 DataArray *DataArrayInt::selectByTupleRanges(const std::vector<std::pair<int,int> >& ranges) const
7265 {
7266   checkAllocated();
7267   int nbOfComp=getNumberOfComponents();
7268   int nbOfTuplesThis=getNumberOfTuples();
7269   if(ranges.empty())
7270     {
7271       MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
7272       ret->alloc(0,nbOfComp);
7273       ret->copyStringInfoFrom(*this);
7274       return ret.retn();
7275     }
7276   int ref=ranges.front().first;
7277   int nbOfTuples=0;
7278   bool isIncreasing=true;
7279   for(std::vector<std::pair<int,int> >::const_iterator it=ranges.begin();it!=ranges.end();it++)
7280     {
7281       if((*it).first<=(*it).second)
7282         {
7283           if((*it).first>=0 && (*it).second<=nbOfTuplesThis)
7284             {
7285               nbOfTuples+=(*it).second-(*it).first;
7286               if(isIncreasing)
7287                 isIncreasing=ref<=(*it).first;
7288               ref=(*it).second;
7289             }
7290           else
7291             {
7292               std::ostringstream oss; oss << "DataArrayInt::selectByTupleRanges : on range #" << std::distance(ranges.begin(),it);
7293               oss << " (" << (*it).first << "," << (*it).second << ") is greater than number of tuples of this :" << nbOfTuples << " !";
7294               throw INTERP_KERNEL::Exception(oss.str().c_str());
7295             }
7296         }
7297       else
7298         {
7299           std::ostringstream oss; oss << "DataArrayInt::selectByTupleRanges : on range #" << std::distance(ranges.begin(),it);
7300           oss << " (" << (*it).first << "," << (*it).second << ") end is before begin !";
7301           throw INTERP_KERNEL::Exception(oss.str().c_str());
7302         }
7303     }
7304   if(isIncreasing && nbOfTuplesThis==nbOfTuples)
7305     return deepCpy();
7306   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
7307   ret->alloc(nbOfTuples,nbOfComp);
7308   ret->copyStringInfoFrom(*this);
7309   const int *src=getConstPointer();
7310   int *work=ret->getPointer();
7311   for(std::vector<std::pair<int,int> >::const_iterator it=ranges.begin();it!=ranges.end();it++)
7312     work=std::copy(src+(*it).first*nbOfComp,src+(*it).second*nbOfComp,work);
7313   return ret.retn();
7314 }
7315
7316 /*!
7317  * Returns a new DataArrayInt containing a renumbering map in "Old to New" mode.
7318  * This map, if applied to \a this array, would make it sorted. For example, if
7319  * \a this array contents are [9,10,0,6,4,11,3,7] then the contents of the result array
7320  * are [5,6,0,3,2,7,1,4]; if this result array (\a res) is used as an argument in call
7321  * \a this->renumber(\a res) then the returned array contains [0,3,4,6,7,9,10,11].
7322  * This method is useful for renumbering (in MED file for example). For more info
7323  * on renumbering see \ref MEDCouplingArrayRenumbering.
7324  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
7325  *          array using decrRef() as it is no more needed.
7326  *  \throw If \a this is not allocated.
7327  *  \throw If \a this->getNumberOfComponents() != 1.
7328  *  \throw If there are equal values in \a this array.
7329  */
7330 DataArrayInt *DataArrayInt::checkAndPreparePermutation() const
7331 {
7332   checkAllocated();
7333   if(getNumberOfComponents()!=1)
7334     throw INTERP_KERNEL::Exception("DataArrayInt::checkAndPreparePermutation : number of components must == 1 !");
7335   int nbTuples=getNumberOfTuples();
7336   const int *pt=getConstPointer();
7337   int *pt2=CheckAndPreparePermutation(pt,pt+nbTuples);
7338   DataArrayInt *ret=DataArrayInt::New();
7339   ret->useArray(pt2,true,C_DEALLOC,nbTuples,1);
7340   return ret;
7341 }
7342
7343 /*!
7344  * 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
7345  * input array \a ids2.
7346  * \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.
7347  * 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
7348  * inversely.
7349  * In case of success (no throw) : \c ids1->renumber(ret)->isEqual(ids2) where \a ret is the return of this method.
7350  *
7351  * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
7352  *          array using decrRef() as it is no more needed.
7353  * \throw If either ids1 or ids2 is null not allocated or not with one components.
7354  * 
7355  */
7356 DataArrayInt *DataArrayInt::FindPermutationFromFirstToSecond(const DataArrayInt *ids1, const DataArrayInt *ids2)
7357 {
7358   if(!ids1 || !ids2)
7359     throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two input arrays must be not null !");
7360   if(!ids1->isAllocated() || !ids2->isAllocated())
7361     throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two input arrays must be allocated !");
7362   if(ids1->getNumberOfComponents()!=1 || ids2->getNumberOfComponents()!=1)
7363     throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two input arrays have exactly one component !");
7364   if(ids1->getNumberOfTuples()!=ids2->getNumberOfTuples())
7365     {
7366       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 !";
7367       throw INTERP_KERNEL::Exception(oss.str().c_str());
7368     }
7369   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> p1(ids1->deepCpy());
7370   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> p2(ids2->deepCpy());
7371   p1->sort(true); p2->sort(true);
7372   if(!p1->isEqualWithoutConsideringStr(*p2))
7373     throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two arrays are not lying on same ids ! Impossible to find a permutation between the 2 arrays !");
7374   p1=ids1->checkAndPreparePermutation();
7375   p2=ids2->checkAndPreparePermutation();
7376   p2=p2->invertArrayO2N2N2O(p2->getNumberOfTuples());
7377   p2=p2->selectByTupleIdSafe(p1->begin(),p1->end());
7378   return p2.retn();
7379 }
7380
7381 /*!
7382  * Returns two arrays describing a surjective mapping from \a this set of values (\a A)
7383  * onto a set of values of size \a targetNb (\a B). The surjective function is 
7384  * \a B[ \a A[ i ]] = i. That is to say that for each \a id in [0,\a targetNb), where \a
7385  * targetNb < \a this->getNumberOfTuples(), there exists at least one tupleId (\a tid) so
7386  * that <em> this->getIJ( tid, 0 ) == id</em>. <br>
7387  * The first of out arrays returns indices of elements of \a this array, grouped by their
7388  * place in the set \a B. The second out array is the index of the first one; it shows how
7389  * many elements of \a A are mapped into each element of \a B. <br>
7390  * For more info on
7391  * mapping and its usage in renumbering see \ref MEDCouplingArrayRenumbering. <br>
7392  * \b Example:
7393  * - \a this: [0,3,2,3,2,2,1,2]
7394  * - \a targetNb: 4
7395  * - \a arr:  [0,  6,  2,4,5,7,  1,3]
7396  * - \a arrI: [0,1,2,6,8]
7397  *
7398  * This result means: <br>
7399  * the element of \a B 0 encounters within \a A once (\a arrI[ 0+1 ] - \a arrI[ 0 ]) and
7400  * its index within \a A is 0 ( \a arr[ 0:1 ] == \a arr[ \a arrI[ 0 ] : \a arrI[ 0+1 ]]);<br>
7401  * the element of \a B 2 encounters within \a A 4 times (\a arrI[ 2+1 ] - \a arrI[ 2 ]) and
7402  * its indices within \a A are [2,4,5,7] ( \a arr[ 2:6 ] == \a arr[ \a arrI[ 2 ] : 
7403  * \a arrI[ 2+1 ]]); <br> etc.
7404  *  \param [in] targetNb - the size of the set \a B. \a targetNb must be equal or more
7405  *         than the maximal value of \a A.
7406  *  \param [out] arr - a new instance of DataArrayInt returning indices of
7407  *         elements of \a this, grouped by their place in the set \a B. The caller is to delete
7408  *         this array using decrRef() as it is no more needed.
7409  *  \param [out] arrI - a new instance of DataArrayInt returning size of groups of equal
7410  *         elements of \a this. The caller is to delete this array using decrRef() as it
7411  *         is no more needed.
7412  *  \throw If \a this is not allocated.
7413  *  \throw If \a this->getNumberOfComponents() != 1.
7414  *  \throw If any value in \a this is more or equal to \a targetNb.
7415  */
7416 void DataArrayInt::changeSurjectiveFormat(int targetNb, DataArrayInt *&arr, DataArrayInt *&arrI) const
7417 {
7418   checkAllocated();
7419   if(getNumberOfComponents()!=1)
7420     throw INTERP_KERNEL::Exception("DataArrayInt::changeSurjectiveFormat : number of components must == 1 !");
7421   int nbOfTuples=getNumberOfTuples();
7422   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New());
7423   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> retI(DataArrayInt::New());
7424   retI->alloc(targetNb+1,1);
7425   const int *input=getConstPointer();
7426   std::vector< std::vector<int> > tmp(targetNb);
7427   for(int i=0;i<nbOfTuples;i++)
7428     {
7429       int tmp2=input[i];
7430       if(tmp2>=0 && tmp2<targetNb)
7431         tmp[tmp2].push_back(i);
7432       else
7433         {
7434           std::ostringstream oss; oss << "DataArrayInt::changeSurjectiveFormat : At pos " << i << " presence of element " << tmp2 << " ! should be in [0," << targetNb << ") !";
7435           throw INTERP_KERNEL::Exception(oss.str().c_str());
7436         }
7437     }
7438   int *retIPtr=retI->getPointer();
7439   *retIPtr=0;
7440   for(std::vector< std::vector<int> >::const_iterator it1=tmp.begin();it1!=tmp.end();it1++,retIPtr++)
7441     retIPtr[1]=retIPtr[0]+(int)((*it1).size());
7442   if(nbOfTuples!=retI->getIJ(targetNb,0))
7443     throw INTERP_KERNEL::Exception("DataArrayInt::changeSurjectiveFormat : big problem should never happen !");
7444   ret->alloc(nbOfTuples,1);
7445   int *retPtr=ret->getPointer();
7446   for(std::vector< std::vector<int> >::const_iterator it1=tmp.begin();it1!=tmp.end();it1++)
7447     retPtr=std::copy((*it1).begin(),(*it1).end(),retPtr);
7448   arr=ret.retn();
7449   arrI=retI.retn();
7450 }
7451
7452
7453 /*!
7454  * Returns a new DataArrayInt containing a renumbering map in "Old to New" mode computed
7455  * from a zip representation of a surjective format (returned e.g. by
7456  * \ref ParaMEDMEM::DataArrayDouble::findCommonTuples() "DataArrayDouble::findCommonTuples()"
7457  * for example). The result array minimizes the permutation. <br>
7458  * For more info on renumbering see \ref MEDCouplingArrayRenumbering. <br>
7459  * \b Example: <br>
7460  * - \a nbOfOldTuples: 10 
7461  * - \a arr          : [0,3, 5,7,9]
7462  * - \a arrIBg       : [0,2,5]
7463  * - \a newNbOfTuples: 7
7464  * - result array    : [0,1,2,0,3,4,5,4,6,4]
7465  *
7466  *  \param [in] nbOfOldTuples - number of tuples in the initial array \a arr.
7467  *  \param [in] arr - the array of tuple indices grouped by \a arrIBg array.
7468  *  \param [in] arrIBg - the array dividing all indices stored in \a arr into groups of
7469  *         (indices of) equal values. Its every element (except the last one) points to
7470  *         the first element of a group of equal values.
7471  *  \param [in] arrIEnd - specifies the end of \a arrIBg, so that the last element of \a
7472  *          arrIBg is \a arrIEnd[ -1 ].
7473  *  \param [out] newNbOfTuples - number of tuples after surjection application.
7474  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
7475  *          array using decrRef() as it is no more needed.
7476  *  \throw If any value of \a arr breaks condition ( 0 <= \a arr[ i ] < \a nbOfOldTuples ).
7477  */
7478 DataArrayInt *DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2(int nbOfOldTuples, const int *arr, const int *arrIBg, const int *arrIEnd, int &newNbOfTuples)
7479 {
7480   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
7481   ret->alloc(nbOfOldTuples,1);
7482   int *pt=ret->getPointer();
7483   std::fill(pt,pt+nbOfOldTuples,-1);
7484   int nbOfGrps=((int)std::distance(arrIBg,arrIEnd))-1;
7485   const int *cIPtr=arrIBg;
7486   for(int i=0;i<nbOfGrps;i++)
7487     pt[arr[cIPtr[i]]]=-(i+2);
7488   int newNb=0;
7489   for(int iNode=0;iNode<nbOfOldTuples;iNode++)
7490     {
7491       if(pt[iNode]<0)
7492         {
7493           if(pt[iNode]==-1)
7494             pt[iNode]=newNb++;
7495           else
7496             {
7497               int grpId=-(pt[iNode]+2);
7498               for(int j=cIPtr[grpId];j<cIPtr[grpId+1];j++)
7499                 {
7500                   if(arr[j]>=0 && arr[j]<nbOfOldTuples)
7501                     pt[arr[j]]=newNb;
7502                   else
7503                     {
7504                       std::ostringstream oss; oss << "DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2 : With element #" << j << " value is " << arr[j] << " should be in [0," << nbOfOldTuples << ") !";
7505                       throw INTERP_KERNEL::Exception(oss.str().c_str());
7506                     }
7507                 }
7508               newNb++;
7509             }
7510         }
7511     }
7512   newNbOfTuples=newNb;
7513   return ret.retn();
7514 }
7515
7516 /*!
7517  * Returns a new DataArrayInt containing a renumbering map in "New to Old" mode,
7518  * which if applied to \a this array would make it sorted ascendingly.
7519  * For more info on renumbering see \ref MEDCouplingArrayRenumbering. <br>
7520  * \b Example: <br>
7521  * - \a this: [2,0,1,1,0,1,2,0,1,1,0,0]
7522  * - result: [10,0,5,6,1,7,11,2,8,9,3,4]
7523  * - after applying result to \a this: [0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2] 
7524  *
7525  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
7526  *          array using decrRef() as it is no more needed.
7527  *  \throw If \a this is not allocated.
7528  *  \throw If \a this->getNumberOfComponents() != 1.
7529  */
7530 DataArrayInt *DataArrayInt::buildPermArrPerLevel() const
7531 {
7532   checkAllocated();
7533   if(getNumberOfComponents()!=1)
7534     throw INTERP_KERNEL::Exception("DataArrayInt::buildPermArrPerLevel : number of components must == 1 !");
7535   int nbOfTuples=getNumberOfTuples();
7536   const int *pt=getConstPointer();
7537   std::map<int,int> m;
7538   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
7539   ret->alloc(nbOfTuples,1);
7540   int *opt=ret->getPointer();
7541   for(int i=0;i<nbOfTuples;i++,pt++,opt++)
7542     {
7543       int val=*pt;
7544       std::map<int,int>::iterator it=m.find(val);
7545       if(it!=m.end())
7546         {
7547           *opt=(*it).second;
7548           (*it).second++;
7549         }
7550       else
7551         {
7552           *opt=0;
7553           m.insert(std::pair<int,int>(val,1));
7554         }
7555     }
7556   int sum=0;
7557   for(std::map<int,int>::iterator it=m.begin();it!=m.end();it++)
7558     {
7559       int vt=(*it).second;
7560       (*it).second=sum;
7561       sum+=vt;
7562     }
7563   pt=getConstPointer();
7564   opt=ret->getPointer();
7565   for(int i=0;i<nbOfTuples;i++,pt++,opt++)
7566     *opt+=m[*pt];
7567   //
7568   return ret.retn();
7569 }
7570
7571 /*!
7572  * Checks if contents of \a this array are equal to that of an array filled with
7573  * iota(). This method is particularly useful for DataArrayInt instances that represent
7574  * a renumbering array to check the real need in renumbering. 
7575  *  \return bool - \a true if \a this array contents == \a range( \a this->getNumberOfTuples())
7576  *  \throw If \a this is not allocated.
7577  *  \throw If \a this->getNumberOfComponents() != 1.
7578  */
7579 bool DataArrayInt::isIdentity() const
7580 {
7581   checkAllocated();
7582   if(getNumberOfComponents()!=1)
7583     return false;
7584   int nbOfTuples=getNumberOfTuples();
7585   const int *pt=getConstPointer();
7586   for(int i=0;i<nbOfTuples;i++,pt++)
7587     if(*pt!=i)
7588       return false;
7589   return true;
7590 }
7591
7592 /*!
7593  * Checks if all values in \a this array are equal to \a val.
7594  *  \param [in] val - value to check equality of array values to.
7595  *  \return bool - \a true if all values are \a val.
7596  *  \throw If \a this is not allocated.
7597  *  \throw If \a this->getNumberOfComponents() != 1
7598  */
7599 bool DataArrayInt::isUniform(int val) const
7600 {
7601   checkAllocated();
7602   if(getNumberOfComponents()!=1)
7603     throw INTERP_KERNEL::Exception("DataArrayInt::isUniform : must be applied on DataArrayInt with only one component, you can call 'rearrange' method before !");
7604   int nbOfTuples=getNumberOfTuples();
7605   const int *w=getConstPointer();
7606   const int *end2=w+nbOfTuples;
7607   for(;w!=end2;w++)
7608     if(*w!=val)
7609       return false;
7610   return true;
7611 }
7612
7613 /*!
7614  * Creates a new DataArrayDouble and assigns all (textual and numerical) data of \a this
7615  * array to the new one.
7616  *  \return DataArrayDouble * - the new instance of DataArrayInt.
7617  */
7618 DataArrayDouble *DataArrayInt::convertToDblArr() const
7619 {
7620   checkAllocated();
7621   DataArrayDouble *ret=DataArrayDouble::New();
7622   ret->alloc(getNumberOfTuples(),getNumberOfComponents());
7623   std::size_t nbOfVals=getNbOfElems();
7624   const int *src=getConstPointer();
7625   double *dest=ret->getPointer();
7626   std::copy(src,src+nbOfVals,dest);
7627   ret->copyStringInfoFrom(*this);
7628   return ret;
7629 }
7630
7631 /*!
7632  * Returns a shorten copy of \a this array. The new DataArrayInt contains all
7633  * tuples starting from the \a tupleIdBg-th tuple and including all tuples located before
7634  * the \a tupleIdEnd-th one. This methods has a similar behavior as std::string::substr().
7635  * This method is a specialization of selectByTupleId2().
7636  *  \param [in] tupleIdBg - index of the first tuple to copy from \a this array.
7637  *  \param [in] tupleIdEnd - index of the tuple before which the tuples to copy are located.
7638  *          If \a tupleIdEnd == -1, all the tuples till the end of \a this array are copied.
7639  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
7640  *          is to delete using decrRef() as it is no more needed.
7641  *  \throw If \a tupleIdBg < 0.
7642  *  \throw If \a tupleIdBg > \a this->getNumberOfTuples().
7643     \throw If \a tupleIdEnd != -1 && \a tupleIdEnd < \a this->getNumberOfTuples().
7644  *  \sa DataArrayInt::selectByTupleId2
7645  */
7646 DataArrayInt *DataArrayInt::substr(int tupleIdBg, int tupleIdEnd) const
7647 {
7648   checkAllocated();
7649   int nbt=getNumberOfTuples();
7650   if(tupleIdBg<0)
7651     throw INTERP_KERNEL::Exception("DataArrayInt::substr : The tupleIdBg parameter must be greater than 0 !");
7652   if(tupleIdBg>nbt)
7653     throw INTERP_KERNEL::Exception("DataArrayInt::substr : The tupleIdBg parameter is greater than number of tuples !");
7654   int trueEnd=tupleIdEnd;
7655   if(tupleIdEnd!=-1)
7656     {
7657       if(tupleIdEnd>nbt)
7658         throw INTERP_KERNEL::Exception("DataArrayInt::substr : The tupleIdBg parameter is greater or equal than number of tuples !");
7659     }
7660   else
7661     trueEnd=nbt;
7662   int nbComp=getNumberOfComponents();
7663   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
7664   ret->alloc(trueEnd-tupleIdBg,nbComp);
7665   ret->copyStringInfoFrom(*this);
7666   std::copy(getConstPointer()+tupleIdBg*nbComp,getConstPointer()+trueEnd*nbComp,ret->getPointer());
7667   return ret.retn();
7668 }
7669
7670 /*!
7671  * Changes the number of components within \a this array so that its raw data **does
7672  * not** change, instead splitting this data into tuples changes.
7673  *  \warning This method erases all (name and unit) component info set before!
7674  *  \param [in] newNbOfComp - number of components for \a this array to have.
7675  *  \throw If \a this is not allocated
7676  *  \throw If getNbOfElems() % \a newNbOfCompo != 0.
7677  *  \throw If \a newNbOfCompo is lower than 1.
7678  *  \throw If the rearrange method would lead to a number of tuples higher than 2147483647 (maximal capacity of int32 !).
7679  *  \warning This method erases all (name and unit) component info set before!
7680  */
7681 void DataArrayInt::rearrange(int newNbOfCompo)
7682 {
7683   checkAllocated();
7684   if(newNbOfCompo<1)
7685     throw INTERP_KERNEL::Exception("DataArrayInt::rearrange : input newNbOfCompo must be > 0 !");
7686   std::size_t nbOfElems=getNbOfElems();
7687   if(nbOfElems%newNbOfCompo!=0)
7688     throw INTERP_KERNEL::Exception("DataArrayInt::rearrange : nbOfElems%newNbOfCompo!=0 !");
7689   if(nbOfElems/newNbOfCompo>(std::size_t)std::numeric_limits<int>::max())
7690     throw INTERP_KERNEL::Exception("DataArrayInt::rearrange : the rearrangement leads to too high number of tuples (> 2147483647) !");
7691   _info_on_compo.clear();
7692   _info_on_compo.resize(newNbOfCompo);
7693   declareAsNew();
7694 }
7695
7696 /*!
7697  * Changes the number of components within \a this array to be equal to its number
7698  * of tuples, and inversely its number of tuples to become equal to its number of 
7699  * components. So that its raw data **does not** change, instead splitting this
7700  * data into tuples changes.
7701  *  \warning This method erases all (name and unit) component info set before!
7702  *  \warning Do not confuse this method with fromNoInterlace() and toNoInterlace()!
7703  *  \throw If \a this is not allocated.
7704  *  \sa rearrange()
7705  */
7706 void DataArrayInt::transpose()
7707 {
7708   checkAllocated();
7709   int nbOfTuples=getNumberOfTuples();
7710   rearrange(nbOfTuples);
7711 }
7712
7713 /*!
7714  * Returns a shorten or extended copy of \a this array. If \a newNbOfComp is less
7715  * than \a this->getNumberOfComponents() then the result array is shorten as each tuple
7716  * is truncated to have \a newNbOfComp components, keeping first components. If \a
7717  * newNbOfComp is more than \a this->getNumberOfComponents() then the result array is
7718  * expanded as each tuple is populated with \a dftValue to have \a newNbOfComp
7719  * components.  
7720  *  \param [in] newNbOfComp - number of components for the new array to have.
7721  *  \param [in] dftValue - value assigned to new values added to the new array.
7722  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
7723  *          is to delete using decrRef() as it is no more needed.
7724  *  \throw If \a this is not allocated.
7725  */
7726 DataArrayInt *DataArrayInt::changeNbOfComponents(int newNbOfComp, int dftValue) const
7727 {
7728   checkAllocated();
7729   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
7730   ret->alloc(getNumberOfTuples(),newNbOfComp);
7731   const int *oldc=getConstPointer();
7732   int *nc=ret->getPointer();
7733   int nbOfTuples=getNumberOfTuples();
7734   int oldNbOfComp=getNumberOfComponents();
7735   int dim=std::min(oldNbOfComp,newNbOfComp);
7736   for(int i=0;i<nbOfTuples;i++)
7737     {
7738       int j=0;
7739       for(;j<dim;j++)
7740         nc[newNbOfComp*i+j]=oldc[i*oldNbOfComp+j];
7741       for(;j<newNbOfComp;j++)
7742         nc[newNbOfComp*i+j]=dftValue;
7743     }
7744   ret->setName(getName());
7745   for(int i=0;i<dim;i++)
7746     ret->setInfoOnComponent(i,getInfoOnComponent(i));
7747   ret->setName(getName());
7748   return ret.retn();
7749 }
7750
7751 /*!
7752  * Changes number of tuples in the array. If the new number of tuples is smaller
7753  * than the current number the array is truncated, otherwise the array is extended.
7754  *  \param [in] nbOfTuples - new number of tuples. 
7755  *  \throw If \a this is not allocated.
7756  *  \throw If \a nbOfTuples is negative.
7757  */
7758 void DataArrayInt::reAlloc(int nbOfTuples)
7759 {
7760   if(nbOfTuples<0)
7761     throw INTERP_KERNEL::Exception("DataArrayInt::reAlloc : input new number of tuples should be >=0 !");
7762   checkAllocated();
7763   _mem.reAlloc(getNumberOfComponents()*(std::size_t)nbOfTuples);
7764   declareAsNew();
7765 }
7766
7767
7768 /*!
7769  * Returns a copy of \a this array composed of selected components.
7770  * The new DataArrayInt has the same number of tuples but includes components
7771  * specified by \a compoIds parameter. So that getNbOfElems() of the result array
7772  * can be either less, same or more than \a this->getNbOfElems().
7773  *  \param [in] compoIds - sequence of zero based indices of components to include
7774  *              into the new array.
7775  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
7776  *          is to delete using decrRef() as it is no more needed.
7777  *  \throw If \a this is not allocated.
7778  *  \throw If a component index (\a i) is not valid: 
7779  *         \a i < 0 || \a i >= \a this->getNumberOfComponents().
7780  *
7781  *  \if ENABLE_EXAMPLES
7782  *  \ref py_mcdataarrayint_keepselectedcomponents "Here is a Python example".
7783  *  \endif
7784  */
7785 DataArrayInt *DataArrayInt::keepSelectedComponents(const std::vector<int>& compoIds) const
7786 {
7787   checkAllocated();
7788   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New());
7789   int newNbOfCompo=(int)compoIds.size();
7790   int oldNbOfCompo=getNumberOfComponents();
7791   for(std::vector<int>::const_iterator it=compoIds.begin();it!=compoIds.end();it++)
7792     DataArray::CheckValueInRange(oldNbOfCompo,(*it),"keepSelectedComponents invalid requested component");
7793   int nbOfTuples=getNumberOfTuples();
7794   ret->alloc(nbOfTuples,newNbOfCompo);
7795   ret->copyPartOfStringInfoFrom(*this,compoIds);
7796   const int *oldc=getConstPointer();
7797   int *nc=ret->getPointer();
7798   for(int i=0;i<nbOfTuples;i++)
7799     for(int j=0;j<newNbOfCompo;j++,nc++)
7800       *nc=oldc[i*oldNbOfCompo+compoIds[j]];
7801   return ret.retn();
7802 }
7803
7804 /*!
7805  * Appends components of another array to components of \a this one, tuple by tuple.
7806  * So that the number of tuples of \a this array remains the same and the number of 
7807  * components increases.
7808  *  \param [in] other - the DataArrayInt to append to \a this one.
7809  *  \throw If \a this is not allocated.
7810  *  \throw If \a this and \a other arrays have different number of tuples.
7811  *
7812  *  \if ENABLE_EXAMPLES
7813  *  \ref cpp_mcdataarrayint_meldwith "Here is a C++ example".
7814  *
7815  *  \ref py_mcdataarrayint_meldwith "Here is a Python example".
7816  *  \endif
7817  */
7818 void DataArrayInt::meldWith(const DataArrayInt *other)
7819 {
7820   if(!other)
7821     throw INTERP_KERNEL::Exception("DataArrayInt::meldWith : DataArrayInt pointer in input is NULL !");
7822   checkAllocated();
7823   other->checkAllocated();
7824   int nbOfTuples=getNumberOfTuples();
7825   if(nbOfTuples!=other->getNumberOfTuples())
7826     throw INTERP_KERNEL::Exception("DataArrayInt::meldWith : mismatch of number of tuples !");
7827   int nbOfComp1=getNumberOfComponents();
7828   int nbOfComp2=other->getNumberOfComponents();
7829   int *newArr=(int *)malloc(nbOfTuples*(nbOfComp1+nbOfComp2)*sizeof(int));
7830   int *w=newArr;
7831   const int *inp1=getConstPointer();
7832   const int *inp2=other->getConstPointer();
7833   for(int i=0;i<nbOfTuples;i++,inp1+=nbOfComp1,inp2+=nbOfComp2)
7834     {
7835       w=std::copy(inp1,inp1+nbOfComp1,w);
7836       w=std::copy(inp2,inp2+nbOfComp2,w);
7837     }
7838   useArray(newArr,true,C_DEALLOC,nbOfTuples,nbOfComp1+nbOfComp2);
7839   std::vector<int> compIds(nbOfComp2);
7840   for(int i=0;i<nbOfComp2;i++)
7841     compIds[i]=nbOfComp1+i;
7842   copyPartOfStringInfoFrom2(compIds,*other);
7843 }
7844
7845 /*!
7846  * Copy all components in a specified order from another DataArrayInt.
7847  * The specified components become the first ones in \a this array.
7848  * Both numerical and textual data is copied. The number of tuples in \a this and
7849  * the other array can be different.
7850  *  \param [in] a - the array to copy data from.
7851  *  \param [in] compoIds - sequence of zero based indices of components, data of which is
7852  *              to be copied.
7853  *  \throw If \a a is NULL.
7854  *  \throw If \a compoIds.size() != \a a->getNumberOfComponents().
7855  *  \throw If \a compoIds[i] < 0 or \a compoIds[i] > \a this->getNumberOfComponents().
7856  *
7857  *  \if ENABLE_EXAMPLES
7858  *  \ref py_mcdataarrayint_setselectedcomponents "Here is a Python example".
7859  *  \endif
7860  */
7861 void DataArrayInt::setSelectedComponents(const DataArrayInt *a, const std::vector<int>& compoIds)
7862 {
7863   if(!a)
7864     throw INTERP_KERNEL::Exception("DataArrayInt::setSelectedComponents : input DataArrayInt is NULL !");
7865   checkAllocated();
7866   a->checkAllocated();
7867   copyPartOfStringInfoFrom2(compoIds,*a);
7868   std::size_t partOfCompoSz=compoIds.size();
7869   int nbOfCompo=getNumberOfComponents();
7870   int nbOfTuples=std::min(getNumberOfTuples(),a->getNumberOfTuples());
7871   const int *ac=a->getConstPointer();
7872   int *nc=getPointer();
7873   for(int i=0;i<nbOfTuples;i++)
7874     for(std::size_t j=0;j<partOfCompoSz;j++,ac++)
7875       nc[nbOfCompo*i+compoIds[j]]=*ac;
7876 }
7877
7878 /*!
7879  * Copy all values from another DataArrayInt into specified tuples and components
7880  * of \a this array. Textual data is not copied.
7881  * The tree parameters defining set of indices of tuples and components are similar to
7882  * the tree parameters of the Python function \c range(\c start,\c stop,\c step).
7883  *  \param [in] a - the array to copy values from.
7884  *  \param [in] bgTuples - index of the first tuple of \a this array to assign values to.
7885  *  \param [in] endTuples - index of the tuple before which the tuples to assign to
7886  *              are located.
7887  *  \param [in] stepTuples - index increment to get index of the next tuple to assign to.
7888  *  \param [in] bgComp - index of the first component of \a this array to assign values to.
7889  *  \param [in] endComp - index of the component before which the components to assign
7890  *              to are located.
7891  *  \param [in] stepComp - index increment to get index of the next component to assign to.
7892  *  \param [in] strictCompoCompare - if \a true (by default), then \a a->getNumberOfComponents() 
7893  *              must be equal to the number of columns to assign to, else an
7894  *              exception is thrown; if \a false, then it is only required that \a
7895  *              a->getNbOfElems() equals to number of values to assign to (this condition
7896  *              must be respected even if \a strictCompoCompare is \a true). The number of 
7897  *              values to assign to is given by following Python expression:
7898  *              \a nbTargetValues = 
7899  *              \c len(\c range(\a bgTuples,\a endTuples,\a stepTuples)) *
7900  *              \c len(\c range(\a bgComp,\a endComp,\a stepComp)).
7901  *  \throw If \a a is NULL.
7902  *  \throw If \a a is not allocated.
7903  *  \throw If \a this is not allocated.
7904  *  \throw If parameters specifying tuples and components to assign to do not give a
7905  *            non-empty range of increasing indices.
7906  *  \throw If \a a->getNbOfElems() != \a nbTargetValues.
7907  *  \throw If \a strictCompoCompare == \a true && \a a->getNumberOfComponents() !=
7908  *            \c len(\c range(\a bgComp,\a endComp,\a stepComp)).
7909  *
7910  *  \if ENABLE_EXAMPLES
7911  *  \ref py_mcdataarrayint_setpartofvalues1 "Here is a Python example".
7912  *  \endif
7913  */
7914 void DataArrayInt::setPartOfValues1(const DataArrayInt *a, int bgTuples, int endTuples, int stepTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare)
7915 {
7916   if(!a)
7917     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValues1 : DataArrayInt pointer in input is NULL !");
7918   const char msg[]="DataArrayInt::setPartOfValues1";
7919   checkAllocated();
7920   a->checkAllocated();
7921   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
7922   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
7923   int nbComp=getNumberOfComponents();
7924   int nbOfTuples=getNumberOfTuples();
7925   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
7926   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
7927   bool assignTech=true;
7928   if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
7929     {
7930       if(strictCompoCompare)
7931         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
7932     }
7933   else
7934     {
7935       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
7936       assignTech=false;
7937     }
7938   int *pt=getPointer()+bgTuples*nbComp+bgComp;
7939   const int *srcPt=a->getConstPointer();
7940   if(assignTech)
7941     {
7942       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
7943         for(int j=0;j<newNbOfComp;j++,srcPt++)
7944           pt[j*stepComp]=*srcPt;
7945     }
7946   else
7947     {
7948       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
7949         {
7950           const int *srcPt2=srcPt;
7951           for(int j=0;j<newNbOfComp;j++,srcPt2++)
7952             pt[j*stepComp]=*srcPt2;
7953         }
7954     }
7955 }
7956
7957 /*!
7958  * Assign a given value to values at specified tuples and components of \a this array.
7959  * The tree parameters defining set of indices of tuples and components are similar to
7960  * the tree parameters of the Python function \c range(\c start,\c stop,\c step)..
7961  *  \param [in] a - the value to assign.
7962  *  \param [in] bgTuples - index of the first tuple of \a this array to assign to.
7963  *  \param [in] endTuples - index of the tuple before which the tuples to assign to
7964  *              are located.
7965  *  \param [in] stepTuples - index increment to get index of the next tuple to assign to.
7966  *  \param [in] bgComp - index of the first component of \a this array to assign to.
7967  *  \param [in] endComp - index of the component before which the components to assign
7968  *              to are located.
7969  *  \param [in] stepComp - index increment to get index of the next component to assign to.
7970  *  \throw If \a this is not allocated.
7971  *  \throw If parameters specifying tuples and components to assign to, do not give a
7972  *            non-empty range of increasing indices or indices are out of a valid range
7973  *            for \this array.
7974  *
7975  *  \if ENABLE_EXAMPLES
7976  *  \ref py_mcdataarrayint_setpartofvaluessimple1 "Here is a Python example".
7977  *  \endif
7978  */
7979 void DataArrayInt::setPartOfValuesSimple1(int a, int bgTuples, int endTuples, int stepTuples, int bgComp, int endComp, int stepComp)
7980 {
7981   const char msg[]="DataArrayInt::setPartOfValuesSimple1";
7982   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   int *pt=getPointer()+bgTuples*nbComp+bgComp;
7990   for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
7991     for(int j=0;j<newNbOfComp;j++)
7992       pt[j*stepComp]=a;
7993 }
7994
7995
7996 /*!
7997  * Copy all values from another DataArrayInt (\a a) into specified tuples and 
7998  * components of \a this array. Textual data is not copied.
7999  * The tuples and components to assign to are defined by C arrays of indices.
8000  * There are two *modes of usage*:
8001  * - If \a a->getNbOfElems() equals to number of values to assign to, then every value
8002  *   of \a a is assigned to its own location within \a this array. 
8003  * - If \a a includes one tuple, then all values of \a a are assigned to the specified
8004  *   components of every specified tuple of \a this array. In this mode it is required
8005  *   that \a a->getNumberOfComponents() equals to the number of specified components.
8006  * 
8007  *  \param [in] a - the array to copy values from.
8008  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
8009  *              assign values of \a a to.
8010  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
8011  *              pointer to a tuple index <em>(pi)</em> varies as this: 
8012  *              \a bgTuples <= \a pi < \a endTuples.
8013  *  \param [in] bgComp - pointer to an array of component indices of \a this array to
8014  *              assign values of \a a to.
8015  *  \param [in] endComp - specifies the end of the array \a bgTuples, so that
8016  *              pointer to a component index <em>(pi)</em> varies as this: 
8017  *              \a bgComp <= \a pi < \a endComp.
8018  *  \param [in] strictCompoCompare - this parameter is checked only if the
8019  *               *mode of usage* is the first; if it is \a true (default), 
8020  *               then \a a->getNumberOfComponents() must be equal 
8021  *               to the number of specified columns, else this is not required.
8022  *  \throw If \a a is NULL.
8023  *  \throw If \a a is not allocated.
8024  *  \throw If \a this is not allocated.
8025  *  \throw If any index of tuple/component given by <em>bgTuples / bgComp</em> is
8026  *         out of a valid range for \a this array.
8027  *  \throw In the first *mode of usage*, if <em>strictCompoCompare == true </em> and
8028  *         if <em> a->getNumberOfComponents() != (endComp - bgComp) </em>.
8029  *  \throw In the second *mode of usage*, if \a a->getNumberOfTuples() != 1 or
8030  *         <em> a->getNumberOfComponents() != (endComp - bgComp)</em>.
8031  *
8032  *  \if ENABLE_EXAMPLES
8033  *  \ref py_mcdataarrayint_setpartofvalues2 "Here is a Python example".
8034  *  \endif
8035  */
8036 void DataArrayInt::setPartOfValues2(const DataArrayInt *a, const int *bgTuples, const int *endTuples, const int *bgComp, const int *endComp, bool strictCompoCompare)
8037 {
8038   if(!a)
8039     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValues2 : DataArrayInt pointer in input is NULL !");
8040   const char msg[]="DataArrayInt::setPartOfValues2";
8041   checkAllocated();
8042   a->checkAllocated();
8043   int nbComp=getNumberOfComponents();
8044   int nbOfTuples=getNumberOfTuples();
8045   for(const int *z=bgComp;z!=endComp;z++)
8046     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
8047   int newNbOfTuples=(int)std::distance(bgTuples,endTuples);
8048   int newNbOfComp=(int)std::distance(bgComp,endComp);
8049   bool assignTech=true;
8050   if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
8051     {
8052       if(strictCompoCompare)
8053         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
8054     }
8055   else
8056     {
8057       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
8058       assignTech=false;
8059     }
8060   int *pt=getPointer();
8061   const int *srcPt=a->getConstPointer();
8062   if(assignTech)
8063     {    
8064       for(const int *w=bgTuples;w!=endTuples;w++)
8065         {
8066           DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
8067           for(const int *z=bgComp;z!=endComp;z++,srcPt++)
8068             {    
8069               pt[(std::size_t)(*w)*nbComp+(*z)]=*srcPt;
8070             }
8071         }
8072     }
8073   else
8074     {
8075       for(const int *w=bgTuples;w!=endTuples;w++)
8076         {
8077           const int *srcPt2=srcPt;
8078           DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
8079           for(const int *z=bgComp;z!=endComp;z++,srcPt2++)
8080             {    
8081               pt[(std::size_t)(*w)*nbComp+(*z)]=*srcPt2;
8082             }
8083         }
8084     }
8085 }
8086
8087 /*!
8088  * Assign a given value to values at specified tuples and components of \a this array.
8089  * The tuples and components to assign to are defined by C arrays of indices.
8090  *  \param [in] a - the value to assign.
8091  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
8092  *              assign \a a to.
8093  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
8094  *              pointer to a tuple index (\a pi) varies as this: 
8095  *              \a bgTuples <= \a pi < \a endTuples.
8096  *  \param [in] bgComp - pointer to an array of component indices of \a this array to
8097  *              assign \a a to.
8098  *  \param [in] endComp - specifies the end of the array \a bgTuples, so that
8099  *              pointer to a component index (\a pi) varies as this: 
8100  *              \a bgComp <= \a pi < \a endComp.
8101  *  \throw If \a this is not allocated.
8102  *  \throw If any index of tuple/component given by <em>bgTuples / bgComp</em> is
8103  *         out of a valid range for \a this array.
8104  *
8105  *  \if ENABLE_EXAMPLES
8106  *  \ref py_mcdataarrayint_setpartofvaluessimple2 "Here is a Python example".
8107  *  \endif
8108  */
8109 void DataArrayInt::setPartOfValuesSimple2(int a, const int *bgTuples, const int *endTuples, const int *bgComp, const int *endComp)
8110 {
8111   checkAllocated();
8112   int nbComp=getNumberOfComponents();
8113   int nbOfTuples=getNumberOfTuples();
8114   for(const int *z=bgComp;z!=endComp;z++)
8115     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
8116   int *pt=getPointer();
8117   for(const int *w=bgTuples;w!=endTuples;w++)
8118     for(const int *z=bgComp;z!=endComp;z++)
8119       {
8120         DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
8121         pt[(std::size_t)(*w)*nbComp+(*z)]=a;
8122       }
8123 }
8124
8125 /*!
8126  * Copy all values from another DataArrayInt (\a a) into specified tuples and 
8127  * components of \a this array. Textual data is not copied.
8128  * The tuples to assign to are defined by a C array of indices.
8129  * The components to assign to are defined by three values similar to parameters of
8130  * the Python function \c range(\c start,\c stop,\c step).
8131  * There are two *modes of usage*:
8132  * - If \a a->getNbOfElems() equals to number of values to assign to, then every value
8133  *   of \a a is assigned to its own location within \a this array. 
8134  * - If \a a includes one tuple, then all values of \a a are assigned to the specified
8135  *   components of every specified tuple of \a this array. In this mode it is required
8136  *   that \a a->getNumberOfComponents() equals to the number of specified components.
8137  *
8138  *  \param [in] a - the array to copy values from.
8139  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
8140  *              assign values of \a a to.
8141  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
8142  *              pointer to a tuple index <em>(pi)</em> varies as this: 
8143  *              \a bgTuples <= \a pi < \a endTuples.
8144  *  \param [in] bgComp - index of the first component of \a this array to assign to.
8145  *  \param [in] endComp - index of the component before which the components to assign
8146  *              to are located.
8147  *  \param [in] stepComp - index increment to get index of the next component to assign to.
8148  *  \param [in] strictCompoCompare - this parameter is checked only in the first
8149  *               *mode of usage*; if \a strictCompoCompare is \a true (default), 
8150  *               then \a a->getNumberOfComponents() must be equal 
8151  *               to the number of specified columns, else this is not required.
8152  *  \throw If \a a is NULL.
8153  *  \throw If \a a is not allocated.
8154  *  \throw If \a this is not allocated.
8155  *  \throw If any index of tuple given by \a bgTuples is out of a valid range for 
8156  *         \a this array.
8157  *  \throw In the first *mode of usage*, if <em>strictCompoCompare == true </em> and
8158  *         if <em> a->getNumberOfComponents()</em> is unequal to the number of components
8159  *         defined by <em>(bgComp,endComp,stepComp)</em>.
8160  *  \throw In the second *mode of usage*, if \a a->getNumberOfTuples() != 1 or
8161  *         <em> a->getNumberOfComponents()</em> is unequal to the number of components
8162  *         defined by <em>(bgComp,endComp,stepComp)</em>.
8163  *  \throw If parameters specifying components to assign to, do not give a
8164  *            non-empty range of increasing indices or indices are out of a valid range
8165  *            for \this array.
8166  *
8167  *  \if ENABLE_EXAMPLES
8168  *  \ref py_mcdataarrayint_setpartofvalues3 "Here is a Python example".
8169  *  \endif
8170  */
8171 void DataArrayInt::setPartOfValues3(const DataArrayInt *a, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare)
8172 {
8173   if(!a)
8174     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValues3 : DataArrayInt pointer in input is NULL !");
8175   const char msg[]="DataArrayInt::setPartOfValues3";
8176   checkAllocated();
8177   a->checkAllocated();
8178   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
8179   int nbComp=getNumberOfComponents();
8180   int nbOfTuples=getNumberOfTuples();
8181   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
8182   int newNbOfTuples=(int)std::distance(bgTuples,endTuples);
8183   bool assignTech=true;
8184   if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
8185     {
8186       if(strictCompoCompare)
8187         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
8188     }
8189   else
8190     {
8191       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
8192       assignTech=false;
8193     }
8194   int *pt=getPointer()+bgComp;
8195   const int *srcPt=a->getConstPointer();
8196   if(assignTech)
8197     {
8198       for(const int *w=bgTuples;w!=endTuples;w++)
8199         for(int j=0;j<newNbOfComp;j++,srcPt++)
8200           {
8201             DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
8202             pt[(std::size_t)(*w)*nbComp+j*stepComp]=*srcPt;
8203           }
8204     }
8205   else
8206     {
8207       for(const int *w=bgTuples;w!=endTuples;w++)
8208         {
8209           const int *srcPt2=srcPt;
8210           for(int j=0;j<newNbOfComp;j++,srcPt2++)
8211             {
8212               DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
8213               pt[(std::size_t)(*w)*nbComp+j*stepComp]=*srcPt2;
8214             }
8215         }
8216     }
8217 }
8218
8219 /*!
8220  * Assign a given value to values at specified tuples and components of \a this array.
8221  * The tuples to assign to are defined by a C array of indices.
8222  * The components to assign to are defined by three values similar to parameters of
8223  * the Python function \c range(\c start,\c stop,\c step).
8224  *  \param [in] a - the value to assign.
8225  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
8226  *              assign \a a to.
8227  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
8228  *              pointer to a tuple index <em>(pi)</em> varies as this: 
8229  *              \a bgTuples <= \a pi < \a endTuples.
8230  *  \param [in] bgComp - index of the first component of \a this array to assign to.
8231  *  \param [in] endComp - index of the component before which the components to assign
8232  *              to are located.
8233  *  \param [in] stepComp - index increment to get index of the next component to assign to.
8234  *  \throw If \a this is not allocated.
8235  *  \throw If any index of tuple given by \a bgTuples is out of a valid range for 
8236  *         \a this array.
8237  *  \throw If parameters specifying components to assign to, do not give a
8238  *            non-empty range of increasing indices or indices are out of a valid range
8239  *            for \this array.
8240  *
8241  *  \if ENABLE_EXAMPLES
8242  *  \ref py_mcdataarrayint_setpartofvaluessimple3 "Here is a Python example".
8243  *  \endif
8244  */
8245 void DataArrayInt::setPartOfValuesSimple3(int a, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp)
8246 {
8247   const char msg[]="DataArrayInt::setPartOfValuesSimple3";
8248   checkAllocated();
8249   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
8250   int nbComp=getNumberOfComponents();
8251   int nbOfTuples=getNumberOfTuples();
8252   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
8253   int *pt=getPointer()+bgComp;
8254   for(const int *w=bgTuples;w!=endTuples;w++)
8255     for(int j=0;j<newNbOfComp;j++)
8256       {
8257         DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
8258         pt[(std::size_t)(*w)*nbComp+j*stepComp]=a;
8259       }
8260 }
8261
8262 void DataArrayInt::setPartOfValues4(const DataArrayInt *a, int bgTuples, int endTuples, int stepTuples, const int *bgComp, const int *endComp, bool strictCompoCompare)
8263 {
8264   if(!a)
8265     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValues4 : input DataArrayInt is NULL !");
8266   const char msg[]="DataArrayInt::setPartOfValues4";
8267   checkAllocated();
8268   a->checkAllocated();
8269   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
8270   int newNbOfComp=(int)std::distance(bgComp,endComp);
8271   int nbComp=getNumberOfComponents();
8272   for(const int *z=bgComp;z!=endComp;z++)
8273     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
8274   int nbOfTuples=getNumberOfTuples();
8275   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
8276   bool assignTech=true;
8277   if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
8278     {
8279       if(strictCompoCompare)
8280         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
8281     }
8282   else
8283     {
8284       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
8285       assignTech=false;
8286     }
8287   const int *srcPt=a->getConstPointer();
8288   int *pt=getPointer()+bgTuples*nbComp;
8289   if(assignTech)
8290     {
8291       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
8292         for(const int *z=bgComp;z!=endComp;z++,srcPt++)
8293           pt[*z]=*srcPt;
8294     }
8295   else
8296     {
8297       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
8298         {
8299           const int *srcPt2=srcPt;
8300           for(const int *z=bgComp;z!=endComp;z++,srcPt2++)
8301             pt[*z]=*srcPt2;
8302         }
8303     }
8304 }
8305
8306 void DataArrayInt::setPartOfValuesSimple4(int a, int bgTuples, int endTuples, int stepTuples, const int *bgComp, const int *endComp)
8307 {
8308   const char msg[]="DataArrayInt::setPartOfValuesSimple4";
8309   checkAllocated();
8310   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
8311   int nbComp=getNumberOfComponents();
8312   for(const int *z=bgComp;z!=endComp;z++)
8313     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
8314   int nbOfTuples=getNumberOfTuples();
8315   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
8316   int *pt=getPointer()+bgTuples*nbComp;
8317   for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
8318     for(const int *z=bgComp;z!=endComp;z++)
8319       pt[*z]=a;
8320 }
8321
8322 /*!
8323  * Copy some tuples from another DataArrayInt into specified tuples
8324  * of \a this array. Textual data is not copied. Both arrays must have equal number of
8325  * components.
8326  * Both the tuples to assign and the tuples to assign to are defined by a DataArrayInt.
8327  * All components of selected tuples are copied.
8328  *  \param [in] a - the array to copy values from.
8329  *  \param [in] tuplesSelec - the array specifying both source tuples of \a a and
8330  *              target tuples of \a this. \a tuplesSelec has two components, and the
8331  *              first component specifies index of the source tuple and the second
8332  *              one specifies index of the target tuple.
8333  *  \throw If \a this is not allocated.
8334  *  \throw If \a a is NULL.
8335  *  \throw If \a a is not allocated.
8336  *  \throw If \a tuplesSelec is NULL.
8337  *  \throw If \a tuplesSelec is not allocated.
8338  *  \throw If <em>this->getNumberOfComponents() != a->getNumberOfComponents()</em>.
8339  *  \throw If \a tuplesSelec->getNumberOfComponents() != 2.
8340  *  \throw If any tuple index given by \a tuplesSelec is out of a valid range for 
8341  *         the corresponding (\a this or \a a) array.
8342  */
8343 void DataArrayInt::setPartOfValuesAdv(const DataArrayInt *a, const DataArrayInt *tuplesSelec)
8344 {
8345   if(!a || !tuplesSelec)
8346     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValuesAdv : DataArrayInt pointer in input is NULL !");
8347   checkAllocated();
8348   a->checkAllocated();
8349   tuplesSelec->checkAllocated();
8350   int nbOfComp=getNumberOfComponents();
8351   if(nbOfComp!=a->getNumberOfComponents())
8352     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValuesAdv : This and a do not have the same number of components !");
8353   if(tuplesSelec->getNumberOfComponents()!=2)
8354     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValuesAdv : Expecting to have a tuple selector DataArrayInt instance with exactly 2 components !");
8355   int thisNt=getNumberOfTuples();
8356   int aNt=a->getNumberOfTuples();
8357   int *valsToSet=getPointer();
8358   const int *valsSrc=a->getConstPointer();
8359   for(const int *tuple=tuplesSelec->begin();tuple!=tuplesSelec->end();tuple+=2)
8360     {
8361       if(tuple[1]>=0 && tuple[1]<aNt)
8362         {
8363           if(tuple[0]>=0 && tuple[0]<thisNt)
8364             std::copy(valsSrc+nbOfComp*tuple[1],valsSrc+nbOfComp*(tuple[1]+1),valsToSet+nbOfComp*tuple[0]);
8365           else
8366             {
8367               std::ostringstream oss; oss << "DataArrayInt::setPartOfValuesAdv : Tuple #" << std::distance(tuplesSelec->begin(),tuple)/2;
8368               oss << " of 'tuplesSelec' request of tuple id #" << tuple[0] << " in 'this' ! It should be in [0," << thisNt << ") !";
8369               throw INTERP_KERNEL::Exception(oss.str().c_str());
8370             }
8371         }
8372       else
8373         {
8374           std::ostringstream oss; oss << "DataArrayInt::setPartOfValuesAdv : Tuple #" << std::distance(tuplesSelec->begin(),tuple)/2;
8375           oss << " of 'tuplesSelec' request of tuple id #" << tuple[1] << " in 'a' ! It should be in [0," << aNt << ") !";
8376           throw INTERP_KERNEL::Exception(oss.str().c_str());
8377         }
8378     }
8379 }
8380
8381 /*!
8382  * Copy some tuples from another DataArrayInt (\a aBase) into contiguous tuples
8383  * of \a this array. Textual data is not copied. Both arrays must have equal number of
8384  * components.
8385  * The tuples to assign to are defined by index of the first tuple, and
8386  * their number is defined by \a tuplesSelec->getNumberOfTuples().
8387  * The tuples to copy are defined by values of a DataArrayInt.
8388  * All components of selected tuples are copied.
8389  *  \param [in] tupleIdStart - index of the first tuple of \a this array to assign
8390  *              values to.
8391  *  \param [in] aBase - the array to copy values from.
8392  *  \param [in] tuplesSelec - the array specifying tuples of \a aBase to copy.
8393  *  \throw If \a this is not allocated.
8394  *  \throw If \a aBase is NULL.
8395  *  \throw If \a aBase is not allocated.
8396  *  \throw If \a tuplesSelec is NULL.
8397  *  \throw If \a tuplesSelec is not allocated.
8398  *  \throw If <em>this->getNumberOfComponents() != a->getNumberOfComponents()</em>.
8399  *  \throw If \a tuplesSelec->getNumberOfComponents() != 1.
8400  *  \throw If <em>tupleIdStart + tuplesSelec->getNumberOfTuples() > this->getNumberOfTuples().</em>
8401  *  \throw If any tuple index given by \a tuplesSelec is out of a valid range for 
8402  *         \a aBase array.
8403  */
8404 void DataArrayInt::setContigPartOfSelectedValues(int tupleIdStart, const DataArray *aBase, const DataArrayInt *tuplesSelec)
8405 {
8406   if(!aBase || !tuplesSelec)
8407     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues : input DataArray is NULL !");
8408   const DataArrayInt *a=dynamic_cast<const DataArrayInt *>(aBase);
8409   if(!a)
8410     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues : input DataArray aBase is not a DataArrayInt !");
8411   checkAllocated();
8412   a->checkAllocated();
8413   tuplesSelec->checkAllocated();
8414   int nbOfComp=getNumberOfComponents();
8415   if(nbOfComp!=a->getNumberOfComponents())
8416     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues : This and a do not have the same number of components !");
8417   if(tuplesSelec->getNumberOfComponents()!=1)
8418     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues : Expecting to have a tuple selector DataArrayInt instance with exactly 1 component !");
8419   int thisNt=getNumberOfTuples();
8420   int aNt=a->getNumberOfTuples();
8421   int nbOfTupleToWrite=tuplesSelec->getNumberOfTuples();
8422   int *valsToSet=getPointer()+tupleIdStart*nbOfComp;
8423   if(tupleIdStart+nbOfTupleToWrite>thisNt)
8424     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues : invalid number range of values to write !");
8425   const int *valsSrc=a->getConstPointer();
8426   for(const int *tuple=tuplesSelec->begin();tuple!=tuplesSelec->end();tuple++,valsToSet+=nbOfComp)
8427     {
8428       if(*tuple>=0 && *tuple<aNt)
8429         {
8430           std::copy(valsSrc+nbOfComp*(*tuple),valsSrc+nbOfComp*(*tuple+1),valsToSet);
8431         }
8432       else
8433         {
8434           std::ostringstream oss; oss << "DataArrayInt::setContigPartOfSelectedValues : Tuple #" << std::distance(tuplesSelec->begin(),tuple);
8435           oss << " of 'tuplesSelec' request of tuple id #" << *tuple << " in 'a' ! It should be in [0," << aNt << ") !";
8436           throw INTERP_KERNEL::Exception(oss.str().c_str());
8437         }
8438     }
8439 }
8440
8441 /*!
8442  * Copy some tuples from another DataArrayInt (\a aBase) into contiguous tuples
8443  * of \a this array. Textual data is not copied. Both arrays must have equal number of
8444  * components.
8445  * The tuples to copy are defined by three values similar to parameters of
8446  * the Python function \c range(\c start,\c stop,\c step).
8447  * The tuples to assign to are defined by index of the first tuple, and
8448  * their number is defined by number of tuples to copy.
8449  * All components of selected tuples are copied.
8450  *  \param [in] tupleIdStart - index of the first tuple of \a this array to assign
8451  *              values to.
8452  *  \param [in] aBase - the array to copy values from.
8453  *  \param [in] bg - index of the first tuple to copy of the array \a aBase.
8454  *  \param [in] end2 - index of the tuple of \a aBase before which the tuples to copy
8455  *              are located.
8456  *  \param [in] step - index increment to get index of the next tuple to copy.
8457  *  \throw If \a this is not allocated.
8458  *  \throw If \a aBase is NULL.
8459  *  \throw If \a aBase is not allocated.
8460  *  \throw If <em>this->getNumberOfComponents() != aBase->getNumberOfComponents()</em>.
8461  *  \throw If <em>tupleIdStart + len(range(bg,end2,step)) > this->getNumberOfTuples().</em>
8462  *  \throw If parameters specifying tuples to copy, do not give a
8463  *            non-empty range of increasing indices or indices are out of a valid range
8464  *            for the array \a aBase.
8465  */
8466 void DataArrayInt::setContigPartOfSelectedValues2(int tupleIdStart, const DataArray *aBase, int bg, int end2, int step)
8467 {
8468   if(!aBase)
8469     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues2 : input DataArray is NULL !");
8470   const DataArrayInt *a=dynamic_cast<const DataArrayInt *>(aBase);
8471   if(!a)
8472     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues2 : input DataArray aBase is not a DataArrayInt !");
8473   checkAllocated();
8474   a->checkAllocated();
8475   int nbOfComp=getNumberOfComponents();
8476   const char msg[]="DataArrayInt::setContigPartOfSelectedValues2";
8477   int nbOfTupleToWrite=DataArray::GetNumberOfItemGivenBES(bg,end2,step,msg);
8478   if(nbOfComp!=a->getNumberOfComponents())
8479     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues2 : This and a do not have the same number of components !");
8480   int thisNt=getNumberOfTuples();
8481   int aNt=a->getNumberOfTuples();
8482   int *valsToSet=getPointer()+tupleIdStart*nbOfComp;
8483   if(tupleIdStart+nbOfTupleToWrite>thisNt)
8484     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues2 : invalid number range of values to write !");
8485   if(end2>aNt)
8486     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues2 : invalid range of values to read !");
8487   const int *valsSrc=a->getConstPointer()+bg*nbOfComp;
8488   for(int i=0;i<nbOfTupleToWrite;i++,valsToSet+=nbOfComp,valsSrc+=step*nbOfComp)
8489     {
8490       std::copy(valsSrc,valsSrc+nbOfComp,valsToSet);
8491     }
8492 }
8493
8494 /*!
8495  * Returns a value located at specified tuple and component.
8496  * This method is equivalent to DataArrayInt::getIJ() except that validity of
8497  * parameters is checked. So this method is safe but expensive if used to go through
8498  * all values of \a this.
8499  *  \param [in] tupleId - index of tuple of interest.
8500  *  \param [in] compoId - index of component of interest.
8501  *  \return double - value located by \a tupleId and \a compoId.
8502  *  \throw If \a this is not allocated.
8503  *  \throw If condition <em>( 0 <= tupleId < this->getNumberOfTuples() )</em> is violated.
8504  *  \throw If condition <em>( 0 <= compoId < this->getNumberOfComponents() )</em> is violated.
8505  */
8506 int DataArrayInt::getIJSafe(int tupleId, int compoId) const
8507 {
8508   checkAllocated();
8509   if(tupleId<0 || tupleId>=getNumberOfTuples())
8510     {
8511       std::ostringstream oss; oss << "DataArrayInt::getIJSafe : request for tupleId " << tupleId << " should be in [0," << getNumberOfTuples() << ") !";
8512       throw INTERP_KERNEL::Exception(oss.str().c_str());
8513     }
8514   if(compoId<0 || compoId>=getNumberOfComponents())
8515     {
8516       std::ostringstream oss; oss << "DataArrayInt::getIJSafe : request for compoId " << compoId << " should be in [0," << getNumberOfComponents() << ") !";
8517       throw INTERP_KERNEL::Exception(oss.str().c_str());
8518     }
8519   return _mem[tupleId*_info_on_compo.size()+compoId];
8520 }
8521
8522 /*!
8523  * Returns the first value of \a this. 
8524  *  \return int - the last value of \a this array.
8525  *  \throw If \a this is not allocated.
8526  *  \throw If \a this->getNumberOfComponents() != 1.
8527  *  \throw If \a this->getNumberOfTuples() < 1.
8528  */
8529 int DataArrayInt::front() const
8530 {
8531   checkAllocated();
8532   if(getNumberOfComponents()!=1)
8533     throw INTERP_KERNEL::Exception("DataArrayInt::front : number of components not equal to one !");
8534   int nbOfTuples=getNumberOfTuples();
8535   if(nbOfTuples<1)
8536     throw INTERP_KERNEL::Exception("DataArrayInt::front : number of tuples must be >= 1 !");
8537   return *(getConstPointer());
8538 }
8539
8540 /*!
8541  * Returns the last value of \a this. 
8542  *  \return int - the last value of \a this array.
8543  *  \throw If \a this is not allocated.
8544  *  \throw If \a this->getNumberOfComponents() != 1.
8545  *  \throw If \a this->getNumberOfTuples() < 1.
8546  */
8547 int DataArrayInt::back() const
8548 {
8549   checkAllocated();
8550   if(getNumberOfComponents()!=1)
8551     throw INTERP_KERNEL::Exception("DataArrayInt::back : number of components not equal to one !");
8552   int nbOfTuples=getNumberOfTuples();
8553   if(nbOfTuples<1)
8554     throw INTERP_KERNEL::Exception("DataArrayInt::back : number of tuples must be >= 1 !");
8555   return *(getConstPointer()+nbOfTuples-1);
8556 }
8557
8558 /*!
8559  * Assign pointer to one array to a pointer to another appay. Reference counter of
8560  * \a arrayToSet is incremented / decremented.
8561  *  \param [in] newArray - the pointer to array to assign to \a arrayToSet.
8562  *  \param [in,out] arrayToSet - the pointer to array to assign to.
8563  */
8564 void DataArrayInt::SetArrayIn(DataArrayInt *newArray, DataArrayInt* &arrayToSet)
8565 {
8566   if(newArray!=arrayToSet)
8567     {
8568       if(arrayToSet)
8569         arrayToSet->decrRef();
8570       arrayToSet=newArray;
8571       if(arrayToSet)
8572         arrayToSet->incrRef();
8573     }
8574 }
8575
8576 DataArrayIntIterator *DataArrayInt::iterator()
8577 {
8578   return new DataArrayIntIterator(this);
8579 }
8580
8581 /*!
8582  * Creates a new DataArrayInt containing IDs (indices) of tuples holding value equal to a
8583  * given one. The ids are sorted in the ascending order.
8584  *  \param [in] val - the value to find within \a this.
8585  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
8586  *          array using decrRef() as it is no more needed.
8587  *  \throw If \a this is not allocated.
8588  *  \throw If \a this->getNumberOfComponents() != 1.
8589  *  \sa DataArrayInt::getIdsEqualTuple
8590  */
8591 DataArrayInt *DataArrayInt::getIdsEqual(int val) const
8592 {
8593   checkAllocated();
8594   if(getNumberOfComponents()!=1)
8595     throw INTERP_KERNEL::Exception("DataArrayInt::getIdsEqual : the array must have only one component, you can call 'rearrange' method before !");
8596   const int *cptr(getConstPointer());
8597   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
8598   int nbOfTuples=getNumberOfTuples();
8599   for(int i=0;i<nbOfTuples;i++,cptr++)
8600     if(*cptr==val)
8601       ret->pushBackSilent(i);
8602   return ret.retn();
8603 }
8604
8605 /*!
8606  * Creates a new DataArrayInt containing IDs (indices) of tuples holding value \b not
8607  * equal to a given one. 
8608  *  \param [in] val - the value to ignore within \a this.
8609  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
8610  *          array using decrRef() as it is no more needed.
8611  *  \throw If \a this is not allocated.
8612  *  \throw If \a this->getNumberOfComponents() != 1.
8613  */
8614 DataArrayInt *DataArrayInt::getIdsNotEqual(int val) const
8615 {
8616   checkAllocated();
8617   if(getNumberOfComponents()!=1)
8618     throw INTERP_KERNEL::Exception("DataArrayInt::getIdsNotEqual : the array must have only one component, you can call 'rearrange' method before !");
8619   const int *cptr(getConstPointer());
8620   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
8621   int nbOfTuples=getNumberOfTuples();
8622   for(int i=0;i<nbOfTuples;i++,cptr++)
8623     if(*cptr!=val)
8624       ret->pushBackSilent(i);
8625   return ret.retn();
8626 }
8627
8628 /*!
8629  * Creates a new DataArrayInt containing IDs (indices) of tuples holding tuple equal to those defined by [ \a tupleBg , \a tupleEnd )
8630  * This method is an extension of  DataArrayInt::getIdsEqual method.
8631  *
8632  *  \param [in] tupleBg - the begin (included) of the input tuple to find within \a this.
8633  *  \param [in] tupleEnd - the end (excluded) of the input tuple to find within \a this.
8634  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
8635  *          array using decrRef() as it is no more needed.
8636  *  \throw If \a this is not allocated.
8637  *  \throw If \a this->getNumberOfComponents() != std::distance(tupleBg,tupleEnd).
8638  * \throw If \a this->getNumberOfComponents() is equal to 0.
8639  * \sa DataArrayInt::getIdsEqual
8640  */
8641 DataArrayInt *DataArrayInt::getIdsEqualTuple(const int *tupleBg, const int *tupleEnd) const
8642 {
8643   std::size_t nbOfCompoExp(std::distance(tupleBg,tupleEnd));
8644   checkAllocated();
8645   if(getNumberOfComponents()!=(int)nbOfCompoExp)
8646     {
8647       std::ostringstream oss; oss << "DataArrayInt::getIdsEqualTuple : mismatch of number of components. Input tuple has " << nbOfCompoExp << " whereas this array has " << getNumberOfComponents() << " components !";
8648       throw INTERP_KERNEL::Exception(oss.str().c_str());
8649     }
8650   if(nbOfCompoExp==0)
8651     throw INTERP_KERNEL::Exception("DataArrayInt::getIdsEqualTuple : number of components should be > 0 !");
8652   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
8653   const int *bg(begin()),*end2(end()),*work(begin());
8654   while(work!=end2)
8655     {
8656       work=std::search(work,end2,tupleBg,tupleEnd);
8657       if(work!=end2)
8658         {
8659           std::size_t pos(std::distance(bg,work));
8660           if(pos%nbOfCompoExp==0)
8661             ret->pushBackSilent(pos/nbOfCompoExp);
8662           work++;
8663         }
8664     }
8665   return ret.retn();
8666 }
8667
8668 /*!
8669  * Assigns \a newValue to all elements holding \a oldValue within \a this
8670  * one-dimensional array.
8671  *  \param [in] oldValue - the value to replace.
8672  *  \param [in] newValue - the value to assign.
8673  *  \return int - number of replacements performed.
8674  *  \throw If \a this is not allocated.
8675  *  \throw If \a this->getNumberOfComponents() != 1.
8676  */
8677 int DataArrayInt::changeValue(int oldValue, int newValue)
8678 {
8679   checkAllocated();
8680   if(getNumberOfComponents()!=1)
8681     throw INTERP_KERNEL::Exception("DataArrayInt::changeValue : the array must have only one component, you can call 'rearrange' method before !");
8682   int *start=getPointer();
8683   int *end2=start+getNbOfElems();
8684   int ret=0;
8685   for(int *val=start;val!=end2;val++)
8686     {
8687       if(*val==oldValue)
8688         {
8689           *val=newValue;
8690           ret++;
8691         }
8692     }
8693   return ret;
8694 }
8695
8696 /*!
8697  * Creates a new DataArrayInt containing IDs (indices) of tuples holding value equal to
8698  * one of given values.
8699  *  \param [in] valsBg - an array of values to find within \a this array.
8700  *  \param [in] valsEnd - specifies the end of the array \a valsBg, so that
8701  *              the last value of \a valsBg is \a valsEnd[ -1 ].
8702  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
8703  *          array using decrRef() as it is no more needed.
8704  *  \throw If \a this->getNumberOfComponents() != 1.
8705  */
8706 DataArrayInt *DataArrayInt::getIdsEqualList(const int *valsBg, const int *valsEnd) const
8707 {
8708   if(getNumberOfComponents()!=1)
8709     throw INTERP_KERNEL::Exception("DataArrayInt::getIdsEqualList : the array must have only one component, you can call 'rearrange' method before !");
8710   std::set<int> vals2(valsBg,valsEnd);
8711   const int *cptr=getConstPointer();
8712   std::vector<int> res;
8713   int nbOfTuples=getNumberOfTuples();
8714   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
8715   for(int i=0;i<nbOfTuples;i++,cptr++)
8716     if(vals2.find(*cptr)!=vals2.end())
8717       ret->pushBackSilent(i);
8718   return ret.retn();
8719 }
8720
8721 /*!
8722  * Creates a new DataArrayInt containing IDs (indices) of tuples holding values \b not
8723  * equal to any of given values.
8724  *  \param [in] valsBg - an array of values to ignore within \a this array.
8725  *  \param [in] valsEnd - specifies the end of the array \a valsBg, so that
8726  *              the last value of \a valsBg is \a valsEnd[ -1 ].
8727  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
8728  *          array using decrRef() as it is no more needed.
8729  *  \throw If \a this->getNumberOfComponents() != 1.
8730  */
8731 DataArrayInt *DataArrayInt::getIdsNotEqualList(const int *valsBg, const int *valsEnd) const
8732 {
8733   if(getNumberOfComponents()!=1)
8734     throw INTERP_KERNEL::Exception("DataArrayInt::getIdsNotEqualList : the array must have only one component, you can call 'rearrange' method before !");
8735   std::set<int> vals2(valsBg,valsEnd);
8736   const int *cptr=getConstPointer();
8737   std::vector<int> res;
8738   int nbOfTuples=getNumberOfTuples();
8739   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
8740   for(int i=0;i<nbOfTuples;i++,cptr++)
8741     if(vals2.find(*cptr)==vals2.end())
8742       ret->pushBackSilent(i);
8743   return ret.retn();
8744 }
8745
8746 /*!
8747  * This method is an extension of DataArrayInt::locateValue method because this method works for DataArrayInt with
8748  * any number of components excepted 0 (an INTERP_KERNEL::Exception is thrown in this case).
8749  * This method searches in \b this is there is a tuple that matched the input parameter \b tupl.
8750  * If any the tuple id is returned. If not -1 is returned.
8751  * 
8752  * This method throws an INTERP_KERNEL::Exception if the number of components in \b this mismatches with the size of
8753  * the input vector. An INTERP_KERNEL::Exception is thrown too if \b this is not allocated.
8754  *
8755  * \return tuple id where \b tupl is. -1 if no such tuple exists in \b this.
8756  * \sa DataArrayInt::search, DataArrayInt::presenceOfTuple.
8757  */
8758 int DataArrayInt::locateTuple(const std::vector<int>& tupl) const
8759 {
8760   checkAllocated();
8761   int nbOfCompo=getNumberOfComponents();
8762   if(nbOfCompo==0)
8763     throw INTERP_KERNEL::Exception("DataArrayInt::locateTuple : 0 components in 'this' !");
8764   if(nbOfCompo!=(int)tupl.size())
8765     {
8766       std::ostringstream oss; oss << "DataArrayInt::locateTuple : 'this' contains " << nbOfCompo << " components and searching for a tuple of length " << tupl.size() << " !";
8767       throw INTERP_KERNEL::Exception(oss.str().c_str());
8768     }
8769   const int *cptr=getConstPointer();
8770   std::size_t nbOfVals=getNbOfElems();
8771   for(const int *work=cptr;work!=cptr+nbOfVals;)
8772     {
8773       work=std::search(work,cptr+nbOfVals,tupl.begin(),tupl.end());
8774       if(work!=cptr+nbOfVals)
8775         {
8776           if(std::distance(cptr,work)%nbOfCompo!=0)
8777             work++;
8778           else
8779             return std::distance(cptr,work)/nbOfCompo;
8780         }
8781     }
8782   return -1;
8783 }
8784
8785 /*!
8786  * This method searches the sequence specified in input parameter \b vals in \b this.
8787  * This works only for DataArrayInt having number of components equal to one (if not an INTERP_KERNEL::Exception will be thrown).
8788  * This method differs from DataArrayInt::locateTuple in that the position is internal raw data is not considered here contrary to DataArrayInt::locateTuple.
8789  * \sa DataArrayInt::locateTuple
8790  */
8791 int DataArrayInt::search(const std::vector<int>& vals) const
8792 {
8793   checkAllocated();
8794   int nbOfCompo=getNumberOfComponents();
8795   if(nbOfCompo!=1)
8796     throw INTERP_KERNEL::Exception("DataArrayInt::search : works only for DataArrayInt instance with one component !");
8797   const int *cptr=getConstPointer();
8798   std::size_t nbOfVals=getNbOfElems();
8799   const int *loc=std::search(cptr,cptr+nbOfVals,vals.begin(),vals.end());
8800   if(loc!=cptr+nbOfVals)
8801     return std::distance(cptr,loc);
8802   return -1;
8803 }
8804
8805 /*!
8806  * This method expects to be called when number of components of this is equal to one.
8807  * This method returns the tuple id, if it exists, of the first tuple equal to \b value.
8808  * If not any tuple contains \b value -1 is returned.
8809  * \sa DataArrayInt::presenceOfValue
8810  */
8811 int DataArrayInt::locateValue(int value) const
8812 {
8813   checkAllocated();
8814   if(getNumberOfComponents()!=1)
8815     throw INTERP_KERNEL::Exception("DataArrayInt::presenceOfValue : the array must have only one component, you can call 'rearrange' method before !");
8816   const int *cptr=getConstPointer();
8817   int nbOfTuples=getNumberOfTuples();
8818   const int *ret=std::find(cptr,cptr+nbOfTuples,value);
8819   if(ret!=cptr+nbOfTuples)
8820     return std::distance(cptr,ret);
8821   return -1;
8822 }
8823
8824 /*!
8825  * This method expects to be called when number of components of this is equal to one.
8826  * This method returns the tuple id, if it exists, of the first tuple so that the value is contained in \b vals.
8827  * If not any tuple contains one of the values contained in 'vals' false is returned.
8828  * \sa DataArrayInt::presenceOfValue
8829  */
8830 int DataArrayInt::locateValue(const std::vector<int>& vals) const
8831 {
8832   checkAllocated();
8833   if(getNumberOfComponents()!=1)
8834     throw INTERP_KERNEL::Exception("DataArrayInt::presenceOfValue : the array must have only one component, you can call 'rearrange' method before !");
8835   std::set<int> vals2(vals.begin(),vals.end());
8836   const int *cptr=getConstPointer();
8837   int nbOfTuples=getNumberOfTuples();
8838   for(const int *w=cptr;w!=cptr+nbOfTuples;w++)
8839     if(vals2.find(*w)!=vals2.end())
8840       return std::distance(cptr,w);
8841   return -1;
8842 }
8843
8844 /*!
8845  * This method returns the number of values in \a this that are equals to input parameter \a value.
8846  * This method only works for single component array.
8847  *
8848  * \return a value in [ 0, \c this->getNumberOfTuples() )
8849  *
8850  * \throw If \a this is not allocated
8851  *
8852  */
8853 int DataArrayInt::count(int value) const
8854 {
8855   int ret=0;
8856   checkAllocated();
8857   if(getNumberOfComponents()!=1)
8858     throw INTERP_KERNEL::Exception("DataArrayInt::count : must be applied on DataArrayInt with only one component, you can call 'rearrange' method before !");
8859   const int *vals=begin();
8860   int nbOfTuples=getNumberOfTuples();
8861   for(int i=0;i<nbOfTuples;i++,vals++)
8862     if(*vals==value)
8863       ret++;
8864   return ret;
8865 }
8866
8867 /*!
8868  * This method is an extension of DataArrayInt::presenceOfValue method because this method works for DataArrayInt with
8869  * any number of components excepted 0 (an INTERP_KERNEL::Exception is thrown in this case).
8870  * This method searches in \b this is there is a tuple that matched the input parameter \b tupl.
8871  * This method throws an INTERP_KERNEL::Exception if the number of components in \b this mismatches with the size of
8872  * the input vector. An INTERP_KERNEL::Exception is thrown too if \b this is not allocated.
8873  * \sa DataArrayInt::locateTuple
8874  */
8875 bool DataArrayInt::presenceOfTuple(const std::vector<int>& tupl) const
8876 {
8877   return locateTuple(tupl)!=-1;
8878 }
8879
8880
8881 /*!
8882  * Returns \a true if a given value is present within \a this one-dimensional array.
8883  *  \param [in] value - the value to find within \a this array.
8884  *  \return bool - \a true in case if \a value is present within \a this array.
8885  *  \throw If \a this is not allocated.
8886  *  \throw If \a this->getNumberOfComponents() != 1.
8887  *  \sa locateValue()
8888  */
8889 bool DataArrayInt::presenceOfValue(int value) const
8890 {
8891   return locateValue(value)!=-1;
8892 }
8893
8894 /*!
8895  * This method expects to be called when number of components of this is equal to one.
8896  * This method returns true if it exists a tuple so that the value is contained in \b vals.
8897  * If not any tuple contains one of the values contained in 'vals' false is returned.
8898  * \sa DataArrayInt::locateValue
8899  */
8900 bool DataArrayInt::presenceOfValue(const std::vector<int>& vals) const
8901 {
8902   return locateValue(vals)!=-1;
8903 }
8904
8905 /*!
8906  * Accumulates values of each component of \a this array.
8907  *  \param [out] res - an array of length \a this->getNumberOfComponents(), allocated 
8908  *         by the caller, that is filled by this method with sum value for each
8909  *         component.
8910  *  \throw If \a this is not allocated.
8911  */
8912 void DataArrayInt::accumulate(int *res) const
8913 {
8914   checkAllocated();
8915   const int *ptr=getConstPointer();
8916   int nbTuple=getNumberOfTuples();
8917   int nbComps=getNumberOfComponents();
8918   std::fill(res,res+nbComps,0);
8919   for(int i=0;i<nbTuple;i++)
8920     std::transform(ptr+i*nbComps,ptr+(i+1)*nbComps,res,res,std::plus<int>());
8921 }
8922
8923 int DataArrayInt::accumulate(int compId) const
8924 {
8925   checkAllocated();
8926   const int *ptr=getConstPointer();
8927   int nbTuple=getNumberOfTuples();
8928   int nbComps=getNumberOfComponents();
8929   if(compId<0 || compId>=nbComps)
8930     throw INTERP_KERNEL::Exception("DataArrayInt::accumulate : Invalid compId specified : No such nb of components !");
8931   int ret=0;
8932   for(int i=0;i<nbTuple;i++)
8933     ret+=ptr[i*nbComps+compId];
8934   return ret;
8935 }
8936
8937 /*!
8938  * This method accumulate using addition tuples in \a this using input index array [ \a bgOfIndex, \a endOfIndex ).
8939  * The returned array will have same number of components than \a this and number of tuples equal to
8940  * \c std::distance(bgOfIndex,endOfIndex) \b minus \b one.
8941  *
8942  * The input index array is expected to be ascendingly sorted in which the all referenced ids should be in [0, \c this->getNumberOfTuples).
8943  *
8944  * \param [in] bgOfIndex - begin (included) of the input index array.
8945  * \param [in] endOfIndex - end (excluded) of the input index array.
8946  * \return DataArrayInt * - the new instance having the same number of components than \a this.
8947  * 
8948  * \throw If bgOfIndex or end is NULL.
8949  * \throw If input index array is not ascendingly sorted.
8950  * \throw If there is an id in [ \a bgOfIndex, \a endOfIndex ) not in [0, \c this->getNumberOfTuples).
8951  * \throw If std::distance(bgOfIndex,endOfIndex)==0.
8952  */
8953 DataArrayInt *DataArrayInt::accumulatePerChunck(const int *bgOfIndex, const int *endOfIndex) const
8954 {
8955   if(!bgOfIndex || !endOfIndex)
8956     throw INTERP_KERNEL::Exception("DataArrayInt::accumulatePerChunck : input pointer NULL !");
8957   checkAllocated();
8958   int nbCompo=getNumberOfComponents();
8959   int nbOfTuples=getNumberOfTuples();
8960   int sz=(int)std::distance(bgOfIndex,endOfIndex);
8961   if(sz<1)
8962     throw INTERP_KERNEL::Exception("DataArrayInt::accumulatePerChunck : invalid size of input index array !");
8963   sz--;
8964   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(sz,nbCompo);
8965   const int *w=bgOfIndex;
8966   if(*w<0 || *w>=nbOfTuples)
8967     throw INTERP_KERNEL::Exception("DataArrayInt::accumulatePerChunck : The first element of the input index not in [0,nbOfTuples) !");
8968   const int *srcPt=begin()+(*w)*nbCompo;
8969   int *tmp=ret->getPointer();
8970   for(int i=0;i<sz;i++,tmp+=nbCompo,w++)
8971     {
8972       std::fill(tmp,tmp+nbCompo,0);
8973       if(w[1]>=w[0])
8974         {
8975           for(int j=w[0];j<w[1];j++,srcPt+=nbCompo)
8976             {
8977               if(j>=0 && j<nbOfTuples)
8978                 std::transform(srcPt,srcPt+nbCompo,tmp,tmp,std::plus<int>());
8979               else
8980                 {
8981                   std::ostringstream oss; oss << "DataArrayInt::accumulatePerChunck : At rank #" << i << " the input index array points to id " << j << " should be in [0," << nbOfTuples << ") !";
8982                   throw INTERP_KERNEL::Exception(oss.str().c_str());
8983                 }
8984             }
8985         }
8986       else
8987         {
8988           std::ostringstream oss; oss << "DataArrayInt::accumulatePerChunck : At rank #" << i << " the input index array is not in ascendingly sorted.";
8989           throw INTERP_KERNEL::Exception(oss.str().c_str());
8990         }
8991     }
8992   ret->copyStringInfoFrom(*this);
8993   return ret.retn();
8994 }
8995
8996 /*!
8997  * Returns a new DataArrayInt by concatenating two given arrays, so that (1) the number
8998  * of tuples in the result array is <em> a1->getNumberOfTuples() + a2->getNumberOfTuples() -
8999  * offsetA2</em> and (2)
9000  * the number of component in the result array is same as that of each of given arrays.
9001  * First \a offsetA2 tuples of \a a2 are skipped and thus are missing from the result array.
9002  * Info on components is copied from the first of the given arrays. Number of components
9003  * in the given arrays must be the same.
9004  *  \param [in] a1 - an array to include in the result array.
9005  *  \param [in] a2 - another array to include in the result array.
9006  *  \param [in] offsetA2 - number of tuples of \a a2 to skip.
9007  *  \return DataArrayInt * - the new instance of DataArrayInt.
9008  *          The caller is to delete this result array using decrRef() as it is no more
9009  *          needed.
9010  *  \throw If either \a a1 or \a a2 is NULL.
9011  *  \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents().
9012  */
9013 DataArrayInt *DataArrayInt::Aggregate(const DataArrayInt *a1, const DataArrayInt *a2, int offsetA2)
9014 {
9015   if(!a1 || !a2)
9016     throw INTERP_KERNEL::Exception("DataArrayInt::Aggregate : input DataArrayInt instance is NULL !");
9017   int nbOfComp=a1->getNumberOfComponents();
9018   if(nbOfComp!=a2->getNumberOfComponents())
9019     throw INTERP_KERNEL::Exception("Nb of components mismatch for array Aggregation !");
9020   int nbOfTuple1=a1->getNumberOfTuples();
9021   int nbOfTuple2=a2->getNumberOfTuples();
9022   DataArrayInt *ret=DataArrayInt::New();
9023   ret->alloc(nbOfTuple1+nbOfTuple2-offsetA2,nbOfComp);
9024   int *pt=std::copy(a1->getConstPointer(),a1->getConstPointer()+nbOfTuple1*nbOfComp,ret->getPointer());
9025   std::copy(a2->getConstPointer()+offsetA2*nbOfComp,a2->getConstPointer()+nbOfTuple2*nbOfComp,pt);
9026   ret->copyStringInfoFrom(*a1);
9027   return ret;
9028 }
9029
9030 /*!
9031  * Returns a new DataArrayInt by concatenating all given arrays, so that (1) the number
9032  * of tuples in the result array is a sum of the number of tuples of given arrays and (2)
9033  * the number of component in the result array is same as that of each of given arrays.
9034  * Info on components is copied from the first of the given arrays. Number of components
9035  * in the given arrays must be  the same.
9036  * If the number of non null of elements in \a arr is equal to one the returned object is a copy of it
9037  * not the object itself.
9038  *  \param [in] arr - a sequence of arrays to include in the result array.
9039  *  \return DataArrayInt * - the new instance of DataArrayInt.
9040  *          The caller is to delete this result array using decrRef() as it is no more
9041  *          needed.
9042  *  \throw If all arrays within \a arr are NULL.
9043  *  \throw If getNumberOfComponents() of arrays within \a arr.
9044  */
9045 DataArrayInt *DataArrayInt::Aggregate(const std::vector<const DataArrayInt *>& arr)
9046 {
9047   std::vector<const DataArrayInt *> a;
9048   for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
9049     if(*it4)
9050       a.push_back(*it4);
9051   if(a.empty())
9052     throw INTERP_KERNEL::Exception("DataArrayInt::Aggregate : input list must be NON EMPTY !");
9053   std::vector<const DataArrayInt *>::const_iterator it=a.begin();
9054   int nbOfComp=(*it)->getNumberOfComponents();
9055   int nbt=(*it++)->getNumberOfTuples();
9056   for(int i=1;it!=a.end();it++,i++)
9057     {
9058       if((*it)->getNumberOfComponents()!=nbOfComp)
9059         throw INTERP_KERNEL::Exception("DataArrayInt::Aggregate : Nb of components mismatch for array aggregation !");
9060       nbt+=(*it)->getNumberOfTuples();
9061     }
9062   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
9063   ret->alloc(nbt,nbOfComp);
9064   int *pt=ret->getPointer();
9065   for(it=a.begin();it!=a.end();it++)
9066     pt=std::copy((*it)->getConstPointer(),(*it)->getConstPointer()+(*it)->getNbOfElems(),pt);
9067   ret->copyStringInfoFrom(*(a[0]));
9068   return ret.retn();
9069 }
9070
9071 /*!
9072  * This method takes as input a list of DataArrayInt instances \a arrs that represent each a packed index arrays.
9073  * A packed index array is an allocated array with one component, and at least one tuple. The first element
9074  * of each array in \a arrs must be 0. Each array in \a arrs is expected to be increasingly monotonic.
9075  * 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.
9076  * 
9077  * \return DataArrayInt * - a new object to be managed by the caller.
9078  */
9079 DataArrayInt *DataArrayInt::AggregateIndexes(const std::vector<const DataArrayInt *>& arrs)
9080 {
9081   int retSz=1;
9082   for(std::vector<const DataArrayInt *>::const_iterator it4=arrs.begin();it4!=arrs.end();it4++)
9083     {
9084       if(*it4)
9085         {
9086           (*it4)->checkAllocated();
9087           if((*it4)->getNumberOfComponents()!=1)
9088             {
9089               std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a DataArrayInt instance with nb of compo != 1 at pos " << std::distance(arrs.begin(),it4) << " !";
9090               throw INTERP_KERNEL::Exception(oss.str().c_str());
9091             }
9092           int nbTupl=(*it4)->getNumberOfTuples();
9093           if(nbTupl<1)
9094             {
9095               std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a DataArrayInt instance with nb of tuples < 1 at pos " << std::distance(arrs.begin(),it4) << " !";
9096               throw INTERP_KERNEL::Exception(oss.str().c_str());
9097             }
9098           if((*it4)->front()!=0)
9099             {
9100               std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a DataArrayInt instance with front value != 0 at pos " << std::distance(arrs.begin(),it4) << " !";
9101               throw INTERP_KERNEL::Exception(oss.str().c_str());
9102             }
9103           retSz+=nbTupl-1;
9104         }
9105       else
9106         {
9107           std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a null instance at pos " << std::distance(arrs.begin(),it4) << " !";
9108           throw INTERP_KERNEL::Exception(oss.str().c_str());
9109         }
9110     }
9111   if(arrs.empty())
9112     throw INTERP_KERNEL::Exception("DataArrayInt::AggregateIndexes : input list must be NON EMPTY !");
9113   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
9114   ret->alloc(retSz,1);
9115   int *pt=ret->getPointer(); *pt++=0;
9116   for(std::vector<const DataArrayInt *>::const_iterator it=arrs.begin();it!=arrs.end();it++)
9117     pt=std::transform((*it)->begin()+1,(*it)->end(),pt,std::bind2nd(std::plus<int>(),pt[-1]));
9118   ret->copyStringInfoFrom(*(arrs[0]));
9119   return ret.retn();
9120 }
9121
9122 /*!
9123  * Returns the maximal value and its location within \a this one-dimensional array.
9124  *  \param [out] tupleId - index of the tuple holding the maximal value.
9125  *  \return int - the maximal value among all values of \a this array.
9126  *  \throw If \a this->getNumberOfComponents() != 1
9127  *  \throw If \a this->getNumberOfTuples() < 1
9128  */
9129 int DataArrayInt::getMaxValue(int& tupleId) const
9130 {
9131   checkAllocated();
9132   if(getNumberOfComponents()!=1)
9133     throw INTERP_KERNEL::Exception("DataArrayInt::getMaxValue : must be applied on DataArrayInt with only one component !");
9134   int nbOfTuples=getNumberOfTuples();
9135   if(nbOfTuples<=0)
9136     throw INTERP_KERNEL::Exception("DataArrayInt::getMaxValue : array exists but number of tuples must be > 0 !");
9137   const int *vals=getConstPointer();
9138   const int *loc=std::max_element(vals,vals+nbOfTuples);
9139   tupleId=(int)std::distance(vals,loc);
9140   return *loc;
9141 }
9142
9143 /*!
9144  * Returns the maximal value within \a this array that is allowed to have more than
9145  *  one component.
9146  *  \return int - the maximal value among all values of \a this array.
9147  *  \throw If \a this is not allocated.
9148  */
9149 int DataArrayInt::getMaxValueInArray() const
9150 {
9151   checkAllocated();
9152   const int *loc=std::max_element(begin(),end());
9153   return *loc;
9154 }
9155
9156 /*!
9157  * Returns the minimal value and its location within \a this one-dimensional array.
9158  *  \param [out] tupleId - index of the tuple holding the minimal value.
9159  *  \return int - the minimal value among all values of \a this array.
9160  *  \throw If \a this->getNumberOfComponents() != 1
9161  *  \throw If \a this->getNumberOfTuples() < 1
9162  */
9163 int DataArrayInt::getMinValue(int& tupleId) const
9164 {
9165   checkAllocated();
9166   if(getNumberOfComponents()!=1)
9167     throw INTERP_KERNEL::Exception("DataArrayInt::getMaxValue : must be applied on DataArrayInt with only one component !");
9168   int nbOfTuples=getNumberOfTuples();
9169   if(nbOfTuples<=0)
9170     throw INTERP_KERNEL::Exception("DataArrayInt::getMaxValue : array exists but number of tuples must be > 0 !");
9171   const int *vals=getConstPointer();
9172   const int *loc=std::min_element(vals,vals+nbOfTuples);
9173   tupleId=(int)std::distance(vals,loc);
9174   return *loc;
9175 }
9176
9177 /*!
9178  * Returns the minimal value within \a this array that is allowed to have more than
9179  *  one component.
9180  *  \return int - the minimal value among all values of \a this array.
9181  *  \throw If \a this is not allocated.
9182  */
9183 int DataArrayInt::getMinValueInArray() const
9184 {
9185   checkAllocated();
9186   const int *loc=std::min_element(begin(),end());
9187   return *loc;
9188 }
9189
9190 /*!
9191  * Converts every value of \a this array to its absolute value.
9192  * \b WARNING this method is non const. If a new DataArrayInt instance should be built containing the result of abs DataArrayInt::computeAbs
9193  * should be called instead.
9194  *
9195  * \throw If \a this is not allocated.
9196  * \sa DataArrayInt::computeAbs
9197  */
9198 void DataArrayInt::abs()
9199 {
9200   checkAllocated();
9201   int *ptr(getPointer());
9202   std::size_t nbOfElems(getNbOfElems());
9203   std::transform(ptr,ptr+nbOfElems,ptr,std::ptr_fun<int,int>(std::abs));
9204   declareAsNew();
9205 }
9206
9207 /*!
9208  * This method builds a new instance of \a this object containing the result of std::abs applied of all elements in \a this.
9209  * This method is a const method (that do not change any values in \a this) contrary to  DataArrayInt::abs method.
9210  *
9211  * \return DataArrayInt * - the new instance of DataArrayInt containing the
9212  *         same number of tuples and component as \a this array.
9213  *         The caller is to delete this result array using decrRef() as it is no more
9214  *         needed.
9215  * \throw If \a this is not allocated.
9216  * \sa DataArrayInt::abs
9217  */
9218 DataArrayInt *DataArrayInt::computeAbs() const
9219 {
9220   checkAllocated();
9221   DataArrayInt *newArr(DataArrayInt::New());
9222   int nbOfTuples(getNumberOfTuples());
9223   int nbOfComp(getNumberOfComponents());
9224   newArr->alloc(nbOfTuples,nbOfComp);
9225   std::transform(begin(),end(),newArr->getPointer(),std::ptr_fun<int,int>(std::abs));
9226   newArr->copyStringInfoFrom(*this);
9227   return newArr;
9228 }
9229
9230 /*!
9231  * Apply a liner function to a given component of \a this array, so that
9232  * an array element <em>(x)</em> becomes \f$ a * x + b \f$.
9233  *  \param [in] a - the first coefficient of the function.
9234  *  \param [in] b - the second coefficient of the function.
9235  *  \param [in] compoId - the index of component to modify.
9236  *  \throw If \a this is not allocated.
9237  */
9238 void DataArrayInt::applyLin(int a, int b, int compoId)
9239 {
9240   checkAllocated();
9241   int *ptr=getPointer()+compoId;
9242   int nbOfComp=getNumberOfComponents();
9243   int nbOfTuple=getNumberOfTuples();
9244   for(int i=0;i<nbOfTuple;i++,ptr+=nbOfComp)
9245     *ptr=a*(*ptr)+b;
9246   declareAsNew();
9247 }
9248
9249 /*!
9250  * Apply a liner function to all elements of \a this array, so that
9251  * an element _x_ becomes \f$ a * x + b \f$.
9252  *  \param [in] a - the first coefficient of the function.
9253  *  \param [in] b - the second coefficient of the function.
9254  *  \throw If \a this is not allocated.
9255  */
9256 void DataArrayInt::applyLin(int a, int b)
9257 {
9258   checkAllocated();
9259   int *ptr=getPointer();
9260   std::size_t nbOfElems=getNbOfElems();
9261   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
9262     *ptr=a*(*ptr)+b;
9263   declareAsNew();
9264 }
9265
9266 /*!
9267  * Returns a full copy of \a this array except that sign of all elements is reversed.
9268  *  \return DataArrayInt * - the new instance of DataArrayInt containing the
9269  *          same number of tuples and component as \a this array.
9270  *          The caller is to delete this result array using decrRef() as it is no more
9271  *          needed.
9272  *  \throw If \a this is not allocated.
9273  */
9274 DataArrayInt *DataArrayInt::negate() const
9275 {
9276   checkAllocated();
9277   DataArrayInt *newArr=DataArrayInt::New();
9278   int nbOfTuples=getNumberOfTuples();
9279   int nbOfComp=getNumberOfComponents();
9280   newArr->alloc(nbOfTuples,nbOfComp);
9281   const int *cptr=getConstPointer();
9282   std::transform(cptr,cptr+nbOfTuples*nbOfComp,newArr->getPointer(),std::negate<int>());
9283   newArr->copyStringInfoFrom(*this);
9284   return newArr;
9285 }
9286
9287 /*!
9288  * Modify all elements of \a this array, so that
9289  * an element _x_ becomes \f$ numerator / x \f$.
9290  *  \warning If an exception is thrown because of presence of 0 element in \a this 
9291  *           array, all elements processed before detection of the zero element remain
9292  *           modified.
9293  *  \param [in] numerator - the numerator used to modify array elements.
9294  *  \throw If \a this is not allocated.
9295  *  \throw If there is an element equal to 0 in \a this array.
9296  */
9297 void DataArrayInt::applyInv(int numerator)
9298 {
9299   checkAllocated();
9300   int *ptr=getPointer();
9301   std::size_t nbOfElems=getNbOfElems();
9302   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
9303     {
9304       if(*ptr!=0)
9305         {
9306           *ptr=numerator/(*ptr);
9307         }
9308       else
9309         {
9310           std::ostringstream oss; oss << "DataArrayInt::applyInv : presence of null value in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
9311           oss << " !";
9312           throw INTERP_KERNEL::Exception(oss.str().c_str());
9313         }
9314     }
9315   declareAsNew();
9316 }
9317
9318 /*!
9319  * Modify all elements of \a this array, so that
9320  * an element _x_ becomes \f$ x / val \f$.
9321  *  \param [in] val - the denominator used to modify array elements.
9322  *  \throw If \a this is not allocated.
9323  *  \throw If \a val == 0.
9324  */
9325 void DataArrayInt::applyDivideBy(int val)
9326 {
9327   if(val==0)
9328     throw INTERP_KERNEL::Exception("DataArrayInt::applyDivideBy : Trying to divide by 0 !");
9329   checkAllocated();
9330   int *ptr=getPointer();
9331   std::size_t nbOfElems=getNbOfElems();
9332   std::transform(ptr,ptr+nbOfElems,ptr,std::bind2nd(std::divides<int>(),val));
9333   declareAsNew();
9334 }
9335
9336 /*!
9337  * Modify all elements of \a this array, so that
9338  * an element _x_ becomes  <em> x % val </em>.
9339  *  \param [in] val - the divisor used to modify array elements.
9340  *  \throw If \a this is not allocated.
9341  *  \throw If \a val <= 0.
9342  */
9343 void DataArrayInt::applyModulus(int val)
9344 {
9345   if(val<=0)
9346     throw INTERP_KERNEL::Exception("DataArrayInt::applyDivideBy : Trying to operate modulus on value <= 0 !");
9347   checkAllocated();
9348   int *ptr=getPointer();
9349   std::size_t nbOfElems=getNbOfElems();
9350   std::transform(ptr,ptr+nbOfElems,ptr,std::bind2nd(std::modulus<int>(),val));
9351   declareAsNew();
9352 }
9353
9354 /*!
9355  * This method works only on data array with one component.
9356  * This method returns a newly allocated array storing stored ascendantly tuple ids in \b this so that
9357  * this[*id] in [\b vmin,\b vmax)
9358  * 
9359  * \param [in] vmin begin of range. This value is included in range (included).
9360  * \param [in] vmax end of range. This value is \b not included in range (excluded).
9361  * \return a newly allocated data array that the caller should deal with.
9362  *
9363  * \sa DataArrayInt::getIdsNotInRange
9364  */
9365 DataArrayInt *DataArrayInt::getIdsInRange(int vmin, int vmax) const
9366 {
9367   checkAllocated();
9368   if(getNumberOfComponents()!=1)
9369     throw INTERP_KERNEL::Exception("DataArrayInt::getIdsInRange : this must have exactly one component !");
9370   const int *cptr(begin());
9371   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
9372   int nbOfTuples(getNumberOfTuples());
9373   for(int i=0;i<nbOfTuples;i++,cptr++)
9374     if(*cptr>=vmin && *cptr<vmax)
9375       ret->pushBackSilent(i);
9376   return ret.retn();
9377 }
9378
9379 /*!
9380  * This method works only on data array with one component.
9381  * This method returns a newly allocated array storing stored ascendantly tuple ids in \b this so that
9382  * this[*id] \b not in [\b vmin,\b vmax)
9383  * 
9384  * \param [in] vmin begin of range. This value is \b not included in range (excluded).
9385  * \param [in] vmax end of range. This value is included in range (included).
9386  * \return a newly allocated data array that the caller should deal with.
9387  * 
9388  * \sa DataArrayInt::getIdsInRange
9389  */
9390 DataArrayInt *DataArrayInt::getIdsNotInRange(int vmin, int vmax) const
9391 {
9392   checkAllocated();
9393   if(getNumberOfComponents()!=1)
9394     throw INTERP_KERNEL::Exception("DataArrayInt::getIdsNotInRange : this must have exactly one component !");
9395   const int *cptr(getConstPointer());
9396   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
9397   int nbOfTuples(getNumberOfTuples());
9398   for(int i=0;i<nbOfTuples;i++,cptr++)
9399     if(*cptr<vmin || *cptr>=vmax)
9400       ret->pushBackSilent(i);
9401   return ret.retn();
9402 }
9403
9404 /*!
9405  * This method works only on data array with one component.
9406  * 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.
9407  * 
9408  * \param [in] vmin begin of range. This value is included in range (included).
9409  * \param [in] vmax end of range. This value is \b not included in range (excluded).
9410  * \return if all ids in \a this are so that (*this)[i]==i for all i in [ 0, \c this->getNumberOfTuples() ). */
9411 bool DataArrayInt::checkAllIdsInRange(int vmin, int vmax) const
9412 {
9413   checkAllocated();
9414   if(getNumberOfComponents()!=1)
9415     throw INTERP_KERNEL::Exception("DataArrayInt::checkAllIdsInRange : this must have exactly one component !");
9416   int nbOfTuples=getNumberOfTuples();
9417   bool ret=true;
9418   const int *cptr=getConstPointer();
9419   for(int i=0;i<nbOfTuples;i++,cptr++)
9420     {
9421       if(*cptr>=vmin && *cptr<vmax)
9422         { ret=ret && *cptr==i; }
9423       else
9424         {
9425           std::ostringstream oss; oss << "DataArrayInt::checkAllIdsInRange : tuple #" << i << " has value " << *cptr << " should be in [" << vmin << "," << vmax << ") !";
9426           throw INTERP_KERNEL::Exception(oss.str().c_str());
9427         }
9428     }
9429   return ret;
9430 }
9431
9432 /*!
9433  * Modify all elements of \a this array, so that
9434  * an element _x_ becomes <em> val % x </em>.
9435  *  \warning If an exception is thrown because of presence of an element <= 0 in \a this 
9436  *           array, all elements processed before detection of the zero element remain
9437  *           modified.
9438  *  \param [in] val - the divident used to modify array elements.
9439  *  \throw If \a this is not allocated.
9440  *  \throw If there is an element equal to or less than 0 in \a this array.
9441  */
9442 void DataArrayInt::applyRModulus(int val)
9443 {
9444   checkAllocated();
9445   int *ptr=getPointer();
9446   std::size_t nbOfElems=getNbOfElems();
9447   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
9448     {
9449       if(*ptr>0)
9450         {
9451           *ptr=val%(*ptr);
9452         }
9453       else
9454         {
9455           std::ostringstream oss; oss << "DataArrayInt::applyRModulus : presence of value <=0 in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
9456           oss << " !";
9457           throw INTERP_KERNEL::Exception(oss.str().c_str());
9458         }
9459     }
9460   declareAsNew();
9461 }
9462
9463 /*!
9464  * Modify all elements of \a this array, so that
9465  * an element _x_ becomes <em> val ^ x </em>.
9466  *  \param [in] val - the value used to apply pow on all array elements.
9467  *  \throw If \a this is not allocated.
9468  *  \throw If \a val < 0.
9469  */
9470 void DataArrayInt::applyPow(int val)
9471 {
9472   checkAllocated();
9473   if(val<0)
9474     throw INTERP_KERNEL::Exception("DataArrayInt::applyPow : input pow in < 0 !");
9475   int *ptr=getPointer();
9476   std::size_t nbOfElems=getNbOfElems();
9477   if(val==0)
9478     {
9479       std::fill(ptr,ptr+nbOfElems,1);
9480       return ;
9481     }
9482   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
9483     {
9484       int tmp=1;
9485       for(int j=0;j<val;j++)
9486         tmp*=*ptr;
9487       *ptr=tmp;
9488     }
9489   declareAsNew();
9490 }
9491
9492 /*!
9493  * Modify all elements of \a this array, so that
9494  * an element _x_ becomes \f$ val ^ x \f$.
9495  *  \param [in] val - the value used to apply pow on all array elements.
9496  *  \throw If \a this is not allocated.
9497  *  \throw If there is an element < 0 in \a this array.
9498  *  \warning If an exception is thrown because of presence of 0 element in \a this 
9499  *           array, all elements processed before detection of the zero element remain
9500  *           modified.
9501  */
9502 void DataArrayInt::applyRPow(int val)
9503 {
9504   checkAllocated();
9505   int *ptr=getPointer();
9506   std::size_t nbOfElems=getNbOfElems();
9507   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
9508     {
9509       if(*ptr>=0)
9510         {
9511           int tmp=1;
9512           for(int j=0;j<*ptr;j++)
9513             tmp*=val;
9514           *ptr=tmp;
9515         }
9516       else
9517         {
9518           std::ostringstream oss; oss << "DataArrayInt::applyRPow : presence of negative value in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
9519           oss << " !";
9520           throw INTERP_KERNEL::Exception(oss.str().c_str());
9521         }
9522     }
9523   declareAsNew();
9524 }
9525
9526 /*!
9527  * Returns a new DataArrayInt by aggregating two given arrays, so that (1) the number
9528  * of components in the result array is a sum of the number of components of given arrays
9529  * and (2) the number of tuples in the result array is same as that of each of given
9530  * arrays. In other words the i-th tuple of result array includes all components of
9531  * i-th tuples of all given arrays.
9532  * Number of tuples in the given arrays must be the same.
9533  *  \param [in] a1 - an array to include in the result array.
9534  *  \param [in] a2 - another array to include in the result array.
9535  *  \return DataArrayInt * - the new instance of DataArrayInt.
9536  *          The caller is to delete this result array using decrRef() as it is no more
9537  *          needed.
9538  *  \throw If both \a a1 and \a a2 are NULL.
9539  *  \throw If any given array is not allocated.
9540  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
9541  */
9542 DataArrayInt *DataArrayInt::Meld(const DataArrayInt *a1, const DataArrayInt *a2)
9543 {
9544   std::vector<const DataArrayInt *> arr(2);
9545   arr[0]=a1; arr[1]=a2;
9546   return Meld(arr);
9547 }
9548
9549 /*!
9550  * Returns a new DataArrayInt by aggregating all given arrays, so that (1) the number
9551  * of components in the result array is a sum of the number of components of given arrays
9552  * and (2) the number of tuples in the result array is same as that of each of given
9553  * arrays. In other words the i-th tuple of result array includes all components of
9554  * i-th tuples of all given arrays.
9555  * Number of tuples in the given arrays must be  the same.
9556  *  \param [in] arr - a sequence of arrays to include in the result array.
9557  *  \return DataArrayInt * - the new instance of DataArrayInt.
9558  *          The caller is to delete this result array using decrRef() as it is no more
9559  *          needed.
9560  *  \throw If all arrays within \a arr are NULL.
9561  *  \throw If any given array is not allocated.
9562  *  \throw If getNumberOfTuples() of arrays within \a arr is different.
9563  */
9564 DataArrayInt *DataArrayInt::Meld(const std::vector<const DataArrayInt *>& arr)
9565 {
9566   std::vector<const DataArrayInt *> a;
9567   for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
9568     if(*it4)
9569       a.push_back(*it4);
9570   if(a.empty())
9571     throw INTERP_KERNEL::Exception("DataArrayInt::Meld : array must be NON empty !");
9572   std::vector<const DataArrayInt *>::const_iterator it;
9573   for(it=a.begin();it!=a.end();it++)
9574     (*it)->checkAllocated();
9575   it=a.begin();
9576   int nbOfTuples=(*it)->getNumberOfTuples();
9577   std::vector<int> nbc(a.size());
9578   std::vector<const int *> pts(a.size());
9579   nbc[0]=(*it)->getNumberOfComponents();
9580   pts[0]=(*it++)->getConstPointer();
9581   for(int i=1;it!=a.end();it++,i++)
9582     {
9583       if(nbOfTuples!=(*it)->getNumberOfTuples())
9584         throw INTERP_KERNEL::Exception("DataArrayInt::meld : mismatch of number of tuples !");
9585       nbc[i]=(*it)->getNumberOfComponents();
9586       pts[i]=(*it)->getConstPointer();
9587     }
9588   int totalNbOfComp=std::accumulate(nbc.begin(),nbc.end(),0);
9589   DataArrayInt *ret=DataArrayInt::New();
9590   ret->alloc(nbOfTuples,totalNbOfComp);
9591   int *retPtr=ret->getPointer();
9592   for(int i=0;i<nbOfTuples;i++)
9593     for(int j=0;j<(int)a.size();j++)
9594       {
9595         retPtr=std::copy(pts[j],pts[j]+nbc[j],retPtr);
9596         pts[j]+=nbc[j];
9597       }
9598   int k=0;
9599   for(int i=0;i<(int)a.size();i++)
9600     for(int j=0;j<nbc[i];j++,k++)
9601       ret->setInfoOnComponent(k,a[i]->getInfoOnComponent(j));
9602   return ret;
9603 }
9604
9605 /*!
9606  * Returns a new DataArrayInt which is a minimal partition of elements of \a groups.
9607  * The i-th item of the result array is an ID of a set of elements belonging to a
9608  * unique set of groups, which the i-th element is a part of. This set of elements
9609  * belonging to a unique set of groups is called \a family, so the result array contains
9610  * IDs of families each element belongs to.
9611  *
9612  * \b Example: if we have two groups of elements: \a group1 [0,4] and \a group2 [ 0,1,2 ],
9613  * then there are 3 families:
9614  * - \a family1 (with ID 1) contains element [0] belonging to ( \a group1 + \a group2 ),
9615  * - \a family2 (with ID 2) contains elements [4] belonging to ( \a group1 ),
9616  * - \a family3 (with ID 3) contains element [1,2] belonging to ( \a group2 ), <br>
9617  * and the result array contains IDs of families [ 1,3,3,0,2 ]. <br> Note a family ID 0 which
9618  * stands for the element #3 which is in none of groups.
9619  *
9620  *  \param [in] groups - sequence of groups of element IDs.
9621  *  \param [in] newNb - total number of elements; it must be more than max ID of element
9622  *         in \a groups.
9623  *  \param [out] fidsOfGroups - IDs of families the elements of each group belong to.
9624  *  \return DataArrayInt * - a new instance of DataArrayInt containing IDs of families
9625  *         each element with ID from range [0, \a newNb ) belongs to. The caller is to
9626  *         delete this array using decrRef() as it is no more needed.
9627  *  \throw If any element ID in \a groups violates condition ( 0 <= ID < \a newNb ).
9628  */
9629 DataArrayInt *DataArrayInt::MakePartition(const std::vector<const DataArrayInt *>& groups, int newNb, std::vector< std::vector<int> >& fidsOfGroups)
9630 {
9631   std::vector<const DataArrayInt *> groups2;
9632   for(std::vector<const DataArrayInt *>::const_iterator it4=groups.begin();it4!=groups.end();it4++)
9633     if(*it4)
9634       groups2.push_back(*it4);
9635   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
9636   ret->alloc(newNb,1);
9637   int *retPtr=ret->getPointer();
9638   std::fill(retPtr,retPtr+newNb,0);
9639   int fid=1;
9640   for(std::vector<const DataArrayInt *>::const_iterator iter=groups2.begin();iter!=groups2.end();iter++)
9641     {
9642       const int *ptr=(*iter)->getConstPointer();
9643       std::size_t nbOfElem=(*iter)->getNbOfElems();
9644       int sfid=fid;
9645       for(int j=0;j<sfid;j++)
9646         {
9647           bool found=false;
9648           for(std::size_t i=0;i<nbOfElem;i++)
9649             {
9650               if(ptr[i]>=0 && ptr[i]<newNb)
9651                 {
9652                   if(retPtr[ptr[i]]==j)
9653                     {
9654                       retPtr[ptr[i]]=fid;
9655                       found=true;
9656                     }
9657                 }
9658               else
9659                 {
9660                   std::ostringstream oss; oss << "DataArrayInt::MakePartition : In group \"" << (*iter)->getName() << "\" in tuple #" << i << " value = " << ptr[i] << " ! Should be in [0," << newNb;
9661                   oss << ") !";
9662                   throw INTERP_KERNEL::Exception(oss.str().c_str());
9663                 }
9664             }
9665           if(found)
9666             fid++;
9667         }
9668     }
9669   fidsOfGroups.clear();
9670   fidsOfGroups.resize(groups2.size());
9671   int grId=0;
9672   for(std::vector<const DataArrayInt *>::const_iterator iter=groups2.begin();iter!=groups2.end();iter++,grId++)
9673     {
9674       std::set<int> tmp;
9675       const int *ptr=(*iter)->getConstPointer();
9676       std::size_t nbOfElem=(*iter)->getNbOfElems();
9677       for(const int *p=ptr;p!=ptr+nbOfElem;p++)
9678         tmp.insert(retPtr[*p]);
9679       fidsOfGroups[grId].insert(fidsOfGroups[grId].end(),tmp.begin(),tmp.end());
9680     }
9681   return ret.retn();
9682 }
9683
9684 /*!
9685  * Returns a new DataArrayInt which contains all elements of given one-dimensional
9686  * arrays. The result array does not contain any duplicates and its values
9687  * are sorted in ascending order.
9688  *  \param [in] arr - sequence of DataArrayInt's to unite.
9689  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
9690  *         array using decrRef() as it is no more needed.
9691  *  \throw If any \a arr[i] is not allocated.
9692  *  \throw If \a arr[i]->getNumberOfComponents() != 1.
9693  */
9694 DataArrayInt *DataArrayInt::BuildUnion(const std::vector<const DataArrayInt *>& arr)
9695 {
9696   std::vector<const DataArrayInt *> a;
9697   for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
9698     if(*it4)
9699       a.push_back(*it4);
9700   for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
9701     {
9702       (*it)->checkAllocated();
9703       if((*it)->getNumberOfComponents()!=1)
9704         throw INTERP_KERNEL::Exception("DataArrayInt::BuildUnion : only single component allowed !");
9705     }
9706   //
9707   std::set<int> r;
9708   for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
9709     {
9710       const int *pt=(*it)->getConstPointer();
9711       int nbOfTuples=(*it)->getNumberOfTuples();
9712       r.insert(pt,pt+nbOfTuples);
9713     }
9714   DataArrayInt *ret=DataArrayInt::New();
9715   ret->alloc((int)r.size(),1);
9716   std::copy(r.begin(),r.end(),ret->getPointer());
9717   return ret;
9718 }
9719
9720 /*!
9721  * Returns a new DataArrayInt which contains elements present in each of given one-dimensional
9722  * arrays. The result array does not contain any duplicates and its values
9723  * are sorted in ascending order.
9724  *  \param [in] arr - sequence of DataArrayInt's to intersect.
9725  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
9726  *         array using decrRef() as it is no more needed.
9727  *  \throw If any \a arr[i] is not allocated.
9728  *  \throw If \a arr[i]->getNumberOfComponents() != 1.
9729  */
9730 DataArrayInt *DataArrayInt::BuildIntersection(const std::vector<const DataArrayInt *>& arr)
9731 {
9732   std::vector<const DataArrayInt *> a;
9733   for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
9734     if(*it4)
9735       a.push_back(*it4);
9736   for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
9737     {
9738       (*it)->checkAllocated();
9739       if((*it)->getNumberOfComponents()!=1)
9740         throw INTERP_KERNEL::Exception("DataArrayInt::BuildIntersection : only single component allowed !");
9741     }
9742   //
9743   std::set<int> r;
9744   for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
9745     {
9746       const int *pt=(*it)->getConstPointer();
9747       int nbOfTuples=(*it)->getNumberOfTuples();
9748       std::set<int> s1(pt,pt+nbOfTuples);
9749       if(it!=a.begin())
9750         {
9751           std::set<int> r2;
9752           std::set_intersection(r.begin(),r.end(),s1.begin(),s1.end(),inserter(r2,r2.end()));
9753           r=r2;
9754         }
9755       else
9756         r=s1;
9757     }
9758   DataArrayInt *ret(DataArrayInt::New());
9759   ret->alloc((int)r.size(),1);
9760   std::copy(r.begin(),r.end(),ret->getPointer());
9761   return ret;
9762 }
9763
9764 /// @cond INTERNAL
9765 namespace ParaMEDMEMImpl
9766 {
9767   class OpSwitchedOn
9768   {
9769   public:
9770     OpSwitchedOn(int *pt):_pt(pt),_cnt(0) { }
9771     void operator()(const bool& b) { if(b) *_pt++=_cnt; _cnt++; }
9772   private:
9773     int *_pt;
9774     int _cnt;
9775   };
9776
9777   class OpSwitchedOff
9778   {
9779   public:
9780     OpSwitchedOff(int *pt):_pt(pt),_cnt(0) { }
9781     void operator()(const bool& b) { if(!b) *_pt++=_cnt; _cnt++; }
9782   private:
9783     int *_pt;
9784     int _cnt;
9785   };
9786 }
9787 /// @endcond
9788
9789 /*!
9790  * This method returns the list of ids in ascending mode so that v[id]==true.
9791  */
9792 DataArrayInt *DataArrayInt::BuildListOfSwitchedOn(const std::vector<bool>& v)
9793 {
9794   int sz((int)std::count(v.begin(),v.end(),true));
9795   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(sz,1);
9796   std::for_each(v.begin(),v.end(),ParaMEDMEMImpl::OpSwitchedOn(ret->getPointer()));
9797   return ret.retn();
9798 }
9799
9800 /*!
9801  * This method returns the list of ids in ascending mode so that v[id]==false.
9802  */
9803 DataArrayInt *DataArrayInt::BuildListOfSwitchedOff(const std::vector<bool>& v)
9804 {
9805   int sz((int)std::count(v.begin(),v.end(),false));
9806   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(sz,1);
9807   std::for_each(v.begin(),v.end(),ParaMEDMEMImpl::OpSwitchedOff(ret->getPointer()));
9808   return ret.retn();
9809 }
9810
9811 /*!
9812  * This method allows to put a vector of vector of integer into a more compact data stucture (skyline). 
9813  * This method is not available into python because no available optimized data structure available to map std::vector< std::vector<int> >.
9814  *
9815  * \param [in] v the input data structure to be translate into skyline format.
9816  * \param [out] data the first element of the skyline format. The user is expected to deal with newly allocated array.
9817  * \param [out] dataIndex the second element of the skyline format.
9818  */
9819 void DataArrayInt::PutIntoToSkylineFrmt(const std::vector< std::vector<int> >& v, DataArrayInt *& data, DataArrayInt *& dataIndex)
9820 {
9821   int sz((int)v.size());
9822   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret0(DataArrayInt::New()),ret1(DataArrayInt::New());
9823   ret1->alloc(sz+1,1);
9824   int *pt(ret1->getPointer()); *pt=0;
9825   for(int i=0;i<sz;i++,pt++)
9826     pt[1]=pt[0]+(int)v[i].size();
9827   ret0->alloc(ret1->back(),1);
9828   pt=ret0->getPointer();
9829   for(int i=0;i<sz;i++)
9830     pt=std::copy(v[i].begin(),v[i].end(),pt);
9831   data=ret0.retn(); dataIndex=ret1.retn();
9832 }
9833
9834 /*!
9835  * Returns a new DataArrayInt which contains a complement of elements of \a this
9836  * one-dimensional array. I.e. the result array contains all elements from the range [0,
9837  * \a nbOfElement) not present in \a this array.
9838  *  \param [in] nbOfElement - maximal size of the result array.
9839  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
9840  *         array using decrRef() as it is no more needed.
9841  *  \throw If \a this is not allocated.
9842  *  \throw If \a this->getNumberOfComponents() != 1.
9843  *  \throw If any element \a x of \a this array violates condition ( 0 <= \a x < \a
9844  *         nbOfElement ).
9845  */
9846 DataArrayInt *DataArrayInt::buildComplement(int nbOfElement) const
9847 {
9848   checkAllocated();
9849   if(getNumberOfComponents()!=1)
9850     throw INTERP_KERNEL::Exception("DataArrayInt::buildComplement : only single component allowed !");
9851   std::vector<bool> tmp(nbOfElement);
9852   const int *pt=getConstPointer();
9853   int nbOfTuples=getNumberOfTuples();
9854   for(const int *w=pt;w!=pt+nbOfTuples;w++)
9855     if(*w>=0 && *w<nbOfElement)
9856       tmp[*w]=true;
9857     else
9858       throw INTERP_KERNEL::Exception("DataArrayInt::buildComplement : an element is not in valid range : [0,nbOfElement) !");
9859   int nbOfRetVal=(int)std::count(tmp.begin(),tmp.end(),false);
9860   DataArrayInt *ret=DataArrayInt::New();
9861   ret->alloc(nbOfRetVal,1);
9862   int j=0;
9863   int *retPtr=ret->getPointer();
9864   for(int i=0;i<nbOfElement;i++)
9865     if(!tmp[i])
9866       retPtr[j++]=i;
9867   return ret;
9868 }
9869
9870 /*!
9871  * Returns a new DataArrayInt containing elements of \a this one-dimensional missing
9872  * from an \a other one-dimensional array.
9873  *  \param [in] other - a DataArrayInt containing elements not to include in the result array.
9874  *  \return DataArrayInt * - a new instance of DataArrayInt with one component. The
9875  *         caller is to delete this array using decrRef() as it is no more needed.
9876  *  \throw If \a other is NULL.
9877  *  \throw If \a other is not allocated.
9878  *  \throw If \a other->getNumberOfComponents() != 1.
9879  *  \throw If \a this is not allocated.
9880  *  \throw If \a this->getNumberOfComponents() != 1.
9881  *  \sa DataArrayInt::buildSubstractionOptimized()
9882  */
9883 DataArrayInt *DataArrayInt::buildSubstraction(const DataArrayInt *other) const
9884 {
9885   if(!other)
9886     throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstraction : DataArrayInt pointer in input is NULL !");
9887   checkAllocated();
9888   other->checkAllocated();
9889   if(getNumberOfComponents()!=1)
9890     throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstraction : only single component allowed !");
9891   if(other->getNumberOfComponents()!=1)
9892     throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstraction : only single component allowed for other type !");
9893   const int *pt=getConstPointer();
9894   int nbOfTuples=getNumberOfTuples();
9895   std::set<int> s1(pt,pt+nbOfTuples);
9896   pt=other->getConstPointer();
9897   nbOfTuples=other->getNumberOfTuples();
9898   std::set<int> s2(pt,pt+nbOfTuples);
9899   std::vector<int> r;
9900   std::set_difference(s1.begin(),s1.end(),s2.begin(),s2.end(),std::back_insert_iterator< std::vector<int> >(r));
9901   DataArrayInt *ret=DataArrayInt::New();
9902   ret->alloc((int)r.size(),1);
9903   std::copy(r.begin(),r.end(),ret->getPointer());
9904   return ret;
9905 }
9906
9907 /*!
9908  * \a this is expected to have one component and to be sorted ascendingly (as for \a other).
9909  * \a other is expected to be a part of \a this. If not DataArrayInt::buildSubstraction should be called instead.
9910  * 
9911  * \param [in] other an array with one component and expected to be sorted ascendingly.
9912  * \ret list of ids in \a this but not in \a other.
9913  * \sa DataArrayInt::buildSubstraction
9914  */
9915 DataArrayInt *DataArrayInt::buildSubstractionOptimized(const DataArrayInt *other) const
9916 {
9917   static const char *MSG="DataArrayInt::buildSubstractionOptimized : only single component allowed !";
9918   if(!other) throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstractionOptimized : NULL input array !");
9919   checkAllocated(); other->checkAllocated();
9920   if(getNumberOfComponents()!=1) throw INTERP_KERNEL::Exception(MSG);
9921   if(other->getNumberOfComponents()!=1) throw INTERP_KERNEL::Exception(MSG);
9922   const int *pt1Bg(begin()),*pt1End(end()),*pt2Bg(other->begin()),*pt2End(other->end());
9923   const int *work1(pt1Bg),*work2(pt2Bg);
9924   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
9925   for(;work1!=pt1End;work1++)
9926     {
9927       if(work2!=pt2End && *work1==*work2)
9928         work2++;
9929       else
9930         ret->pushBackSilent(*work1);
9931     }
9932   return ret.retn();
9933 }
9934
9935
9936 /*!
9937  * Returns a new DataArrayInt which contains all elements of \a this and a given
9938  * one-dimensional arrays. The result array does not contain any duplicates
9939  * and its values are sorted in ascending order.
9940  *  \param [in] other - an array to unite with \a this one.
9941  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
9942  *         array using decrRef() as it is no more needed.
9943  *  \throw If \a this or \a other is not allocated.
9944  *  \throw If \a this->getNumberOfComponents() != 1.
9945  *  \throw If \a other->getNumberOfComponents() != 1.
9946  */
9947 DataArrayInt *DataArrayInt::buildUnion(const DataArrayInt *other) const
9948 {
9949   std::vector<const DataArrayInt *>arrs(2);
9950   arrs[0]=this; arrs[1]=other;
9951   return BuildUnion(arrs);
9952 }
9953
9954
9955 /*!
9956  * Returns a new DataArrayInt which contains elements present in both \a this and a given
9957  * one-dimensional arrays. The result array does not contain any duplicates
9958  * and its values are sorted in ascending order.
9959  *  \param [in] other - an array to intersect with \a this one.
9960  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
9961  *         array using decrRef() as it is no more needed.
9962  *  \throw If \a this or \a other is not allocated.
9963  *  \throw If \a this->getNumberOfComponents() != 1.
9964  *  \throw If \a other->getNumberOfComponents() != 1.
9965  */
9966 DataArrayInt *DataArrayInt::buildIntersection(const DataArrayInt *other) const
9967 {
9968   std::vector<const DataArrayInt *>arrs(2);
9969   arrs[0]=this; arrs[1]=other;
9970   return BuildIntersection(arrs);
9971 }
9972
9973 /*!
9974  * This method can be applied on allocated with one component DataArrayInt instance.
9975  * This method is typically relevant for sorted arrays. All consecutive duplicated items in \a this will appear only once in returned DataArrayInt instance.
9976  * 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]
9977  * 
9978  * \return a newly allocated array that contain the result of the unique operation applied on \a this.
9979  * \throw if \a this is not allocated or if \a this has not exactly one component.
9980  */
9981 DataArrayInt *DataArrayInt::buildUnique() const
9982 {
9983   checkAllocated();
9984   if(getNumberOfComponents()!=1)
9985     throw INTERP_KERNEL::Exception("DataArrayInt::buildUnique : only single component allowed !");
9986   int nbOfTuples=getNumberOfTuples();
9987   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp=deepCpy();
9988   int *data=tmp->getPointer();
9989   int *last=std::unique(data,data+nbOfTuples);
9990   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
9991   ret->alloc(std::distance(data,last),1);
9992   std::copy(data,last,ret->getPointer());
9993   return ret.retn();
9994 }
9995
9996 /*!
9997  * Returns a new DataArrayInt which contains size of every of groups described by \a this
9998  * "index" array. Such "index" array is returned for example by 
9999  * \ref ParaMEDMEM::MEDCouplingUMesh::buildDescendingConnectivity
10000  * "MEDCouplingUMesh::buildDescendingConnectivity" and
10001  * \ref ParaMEDMEM::MEDCouplingUMesh::getNodalConnectivityIndex
10002  * "MEDCouplingUMesh::getNodalConnectivityIndex" etc.
10003  * This method preforms the reverse operation of DataArrayInt::computeOffsets2.
10004  *  \return DataArrayInt * - a new instance of DataArrayInt, whose number of tuples
10005  *          equals to \a this->getNumberOfComponents() - 1, and number of components is 1.
10006  *          The caller is to delete this array using decrRef() as it is no more needed. 
10007  *  \throw If \a this is not allocated.
10008  *  \throw If \a this->getNumberOfComponents() != 1.
10009  *  \throw If \a this->getNumberOfTuples() < 2.
10010  *
10011  *  \b Example: <br> 
10012  *         - this contains [1,3,6,7,7,9,15]
10013  *         - result array contains [2,3,1,0,2,6],
10014  *          where 2 = 3 - 1, 3 = 6 - 3, 1 = 7 - 6 etc.
10015  *
10016  * \sa DataArrayInt::computeOffsets2
10017  */
10018 DataArrayInt *DataArrayInt::deltaShiftIndex() const
10019 {
10020   checkAllocated();
10021   if(getNumberOfComponents()!=1)
10022     throw INTERP_KERNEL::Exception("DataArrayInt::deltaShiftIndex : only single component allowed !");
10023   int nbOfTuples=getNumberOfTuples();
10024   if(nbOfTuples<2)
10025     throw INTERP_KERNEL::Exception("DataArrayInt::deltaShiftIndex : 1 tuple at least must be present in 'this' !");
10026   const int *ptr=getConstPointer();
10027   DataArrayInt *ret=DataArrayInt::New();
10028   ret->alloc(nbOfTuples-1,1);
10029   int *out=ret->getPointer();
10030   std::transform(ptr+1,ptr+nbOfTuples,ptr,out,std::minus<int>());
10031   return ret;
10032 }
10033
10034 /*!
10035  * Modifies \a this one-dimensional array so that value of each element \a x
10036  * of \a this array (\a a) is computed as \f$ x_i = \sum_{j=0}^{i-1} a[ j ] \f$.
10037  * Or: for each i>0 new[i]=new[i-1]+old[i-1] for i==0 new[i]=0. Number of tuples
10038  * and components remains the same.<br>
10039  * This method is useful for allToAllV in MPI with contiguous policy. This method
10040  * differs from computeOffsets2() in that the number of tuples is \b not changed by
10041  * this one.
10042  *  \throw If \a this is not allocated.
10043  *  \throw If \a this->getNumberOfComponents() != 1.
10044  *
10045  *  \b Example: <br>
10046  *          - Before \a this contains [3,5,1,2,0,8]
10047  *          - After \a this contains  [0,3,8,9,11,11]<br>
10048  *          Note that the last element 19 = 11 + 8 is missing because size of \a this
10049  *          array is retained and thus there is no space to store the last element.
10050  */
10051 void DataArrayInt::computeOffsets()
10052 {
10053   checkAllocated();
10054   if(getNumberOfComponents()!=1)
10055     throw INTERP_KERNEL::Exception("DataArrayInt::computeOffsets : only single component allowed !");
10056   int nbOfTuples=getNumberOfTuples();
10057   if(nbOfTuples==0)
10058     return ;
10059   int *work=getPointer();
10060   int tmp=work[0];
10061   work[0]=0;
10062   for(int i=1;i<nbOfTuples;i++)
10063     {
10064       int tmp2=work[i];
10065       work[i]=work[i-1]+tmp;
10066       tmp=tmp2;
10067     }
10068   declareAsNew();
10069 }
10070
10071
10072 /*!
10073  * Modifies \a this one-dimensional array so that value of each element \a x
10074  * of \a this array (\a a) is computed as \f$ x_i = \sum_{j=0}^{i-1} a[ j ] \f$.
10075  * Or: for each i>0 new[i]=new[i-1]+old[i-1] for i==0 new[i]=0. Number
10076  * components remains the same and number of tuples is inceamented by one.<br>
10077  * This method is useful for allToAllV in MPI with contiguous policy. This method
10078  * differs from computeOffsets() in that the number of tuples is changed by this one.
10079  * This method preforms the reverse operation of DataArrayInt::deltaShiftIndex.
10080  *  \throw If \a this is not allocated.
10081  *  \throw If \a this->getNumberOfComponents() != 1.
10082  *
10083  *  \b Example: <br>
10084  *          - Before \a this contains [3,5,1,2,0,8]
10085  *          - After \a this contains  [0,3,8,9,11,11,19]<br>
10086  * \sa DataArrayInt::deltaShiftIndex
10087  */
10088 void DataArrayInt::computeOffsets2()
10089 {
10090   checkAllocated();
10091   if(getNumberOfComponents()!=1)
10092     throw INTERP_KERNEL::Exception("DataArrayInt::computeOffsets2 : only single component allowed !");
10093   int nbOfTuples=getNumberOfTuples();
10094   int *ret=(int *)malloc((nbOfTuples+1)*sizeof(int));
10095   if(nbOfTuples==0)
10096     return ;
10097   const int *work=getConstPointer();
10098   ret[0]=0;
10099   for(int i=0;i<nbOfTuples;i++)
10100     ret[i+1]=work[i]+ret[i];
10101   useArray(ret,true,C_DEALLOC,nbOfTuples+1,1);
10102   declareAsNew();
10103 }
10104
10105 /*!
10106  * Returns two new DataArrayInt instances whose contents is computed from that of \a this and \a listOfIds arrays as follows.
10107  * \a this is expected to be an offset format ( as returned by DataArrayInt::computeOffsets2 ) that is to say with one component
10108  * and ** sorted strictly increasingly **. \a listOfIds is expected to be sorted ascendingly (not strictly needed for \a listOfIds).
10109  * This methods searches in \a this, considered as a set of contiguous \c this->getNumberOfComponents() ranges, all ids in \a listOfIds
10110  * filling completely one of the ranges in \a this.
10111  *
10112  * \param [in] listOfIds a list of ids that has to be sorted ascendingly.
10113  * \param [out] rangeIdsFetched the range ids fetched
10114  * \param [out] idsInInputListThatFetch contains the list of ids in \a listOfIds that are \b fully included in a range in \a this. So
10115  *              \a idsInInputListThatFetch is a part of input \a listOfIds.
10116  *
10117  * \sa DataArrayInt::computeOffsets2
10118  *
10119  *  \b Example: <br>
10120  *          - \a this : [0,3,7,9,15,18]
10121  *          - \a listOfIds contains  [0,1,2,3,7,8,15,16,17]
10122  *          - \a rangeIdsFetched result array: [0,2,4]
10123  *          - \a idsInInputListThatFetch result array: [0,1,2,7,8,15,16,17]
10124  * In this example id 3 in input \a listOfIds is alone so it do not appear in output \a idsInInputListThatFetch.
10125  * <br>
10126  */
10127 void DataArrayInt::searchRangesInListOfIds(const DataArrayInt *listOfIds, DataArrayInt *& rangeIdsFetched, DataArrayInt *& idsInInputListThatFetch) const
10128 {
10129   if(!listOfIds)
10130     throw INTERP_KERNEL::Exception("DataArrayInt::searchRangesInListOfIds : input list of ids is null !");
10131   listOfIds->checkAllocated(); checkAllocated();
10132   if(listOfIds->getNumberOfComponents()!=1)
10133     throw INTERP_KERNEL::Exception("DataArrayInt::searchRangesInListOfIds : input list of ids must have exactly one component !");
10134   if(getNumberOfComponents()!=1)
10135     throw INTERP_KERNEL::Exception("DataArrayInt::searchRangesInListOfIds : this must have exactly one component !");
10136   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret0=DataArrayInt::New(); ret0->alloc(0,1);
10137   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret1=DataArrayInt::New(); ret1->alloc(0,1);
10138   const int *tupEnd(listOfIds->end()),*offBg(begin()),*offEnd(end()-1);
10139   const int *tupPtr(listOfIds->begin()),*offPtr(offBg);
10140   while(tupPtr!=tupEnd && offPtr!=offEnd)
10141     {
10142       if(*tupPtr==*offPtr)
10143         {
10144           int i=offPtr[0];
10145           while(i<offPtr[1] && *tupPtr==i && tupPtr!=tupEnd) { i++; tupPtr++; }
10146           if(i==offPtr[1])
10147             {
10148               ret0->pushBackSilent((int)std::distance(offBg,offPtr));
10149               ret1->pushBackValsSilent(tupPtr-(offPtr[1]-offPtr[0]),tupPtr);
10150               offPtr++;
10151             }
10152         }
10153       else
10154         { if(*tupPtr<*offPtr) tupPtr++; else offPtr++; }
10155     }
10156   rangeIdsFetched=ret0.retn();
10157   idsInInputListThatFetch=ret1.retn();
10158 }
10159
10160 /*!
10161  * Returns a new DataArrayInt whose contents is computed from that of \a this and \a
10162  * offsets arrays as follows. \a offsets is a one-dimensional array considered as an
10163  * "index" array of a "iota" array, thus, whose each element gives an index of a group
10164  * beginning within the "iota" array. And \a this is a one-dimensional array
10165  * considered as a selector of groups described by \a offsets to include into the result array.
10166  *  \throw If \a offsets is NULL.
10167  *  \throw If \a offsets is not allocated.
10168  *  \throw If \a offsets->getNumberOfComponents() != 1.
10169  *  \throw If \a offsets is not monotonically increasing.
10170  *  \throw If \a this is not allocated.
10171  *  \throw If \a this->getNumberOfComponents() != 1.
10172  *  \throw If any element of \a this is not a valid index for \a offsets array.
10173  *
10174  *  \b Example: <br>
10175  *          - \a this: [0,2,3]
10176  *          - \a offsets: [0,3,6,10,14,20]
10177  *          - result array: [0,1,2,6,7,8,9,10,11,12,13] == <br>
10178  *            \c range(0,3) + \c range(6,10) + \c range(10,14) ==<br>
10179  *            \c range( \a offsets[ \a this[0] ], offsets[ \a this[0]+1 ]) + 
10180  *            \c range( \a offsets[ \a this[1] ], offsets[ \a this[1]+1 ]) + 
10181  *            \c range( \a offsets[ \a this[2] ], offsets[ \a this[2]+1 ])
10182  */
10183 DataArrayInt *DataArrayInt::buildExplicitArrByRanges(const DataArrayInt *offsets) const
10184 {
10185   if(!offsets)
10186     throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrByRanges : DataArrayInt pointer in input is NULL !");
10187   checkAllocated();
10188   if(getNumberOfComponents()!=1)
10189     throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrByRanges : only single component allowed !");
10190   offsets->checkAllocated();
10191   if(offsets->getNumberOfComponents()!=1)
10192     throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrByRanges : input array should have only single component !");
10193   int othNbTuples=offsets->getNumberOfTuples()-1;
10194   int nbOfTuples=getNumberOfTuples();
10195   int retNbOftuples=0;
10196   const int *work=getConstPointer();
10197   const int *offPtr=offsets->getConstPointer();
10198   for(int i=0;i<nbOfTuples;i++)
10199     {
10200       int val=work[i];
10201       if(val>=0 && val<othNbTuples)
10202         {
10203           int delta=offPtr[val+1]-offPtr[val];
10204           if(delta>=0)
10205             retNbOftuples+=delta;
10206           else
10207             {
10208               std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrByRanges : Tuple #" << val << " of offset array has a delta < 0 !";
10209               throw INTERP_KERNEL::Exception(oss.str().c_str());
10210             }
10211         }
10212       else
10213         {
10214           std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrByRanges : Tuple #" << i << " in this contains " << val;
10215           oss << " whereas offsets array is of size " << othNbTuples+1 << " !";
10216           throw INTERP_KERNEL::Exception(oss.str().c_str());
10217         }
10218     }
10219   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
10220   ret->alloc(retNbOftuples,1);
10221   int *retPtr=ret->getPointer();
10222   for(int i=0;i<nbOfTuples;i++)
10223     {
10224       int val=work[i];
10225       int start=offPtr[val];
10226       int off=offPtr[val+1]-start;
10227       for(int j=0;j<off;j++,retPtr++)
10228         *retPtr=start+j;
10229     }
10230   return ret.retn();
10231 }
10232
10233 /*!
10234  * Returns a new DataArrayInt whose contents is computed using \a this that must be a 
10235  * scaled array (monotonically increasing).
10236 from that of \a this and \a
10237  * offsets arrays as follows. \a offsets is a one-dimensional array considered as an
10238  * "index" array of a "iota" array, thus, whose each element gives an index of a group
10239  * beginning within the "iota" array. And \a this is a one-dimensional array
10240  * considered as a selector of groups described by \a offsets to include into the result array.
10241  *  \throw If \a  is NULL.
10242  *  \throw If \a this is not allocated.
10243  *  \throw If \a this->getNumberOfComponents() != 1.
10244  *  \throw If \a this->getNumberOfTuples() == 0.
10245  *  \throw If \a this is not monotonically increasing.
10246  *  \throw If any element of ids in ( \a bg \a stop \a step ) points outside the scale in \a this.
10247  *
10248  *  \b Example: <br>
10249  *          - \a bg , \a stop and \a step : (0,5,2)
10250  *          - \a this: [0,3,6,10,14,20]
10251  *          - result array: [0,0,0, 2,2,2,2, 4,4,4,4,4,4] == <br>
10252  */
10253 DataArrayInt *DataArrayInt::buildExplicitArrOfSliceOnScaledArr(int bg, int stop, int step) const
10254 {
10255   if(!isAllocated())
10256     throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrOfSliceOnScaledArr : not allocated array !");
10257   if(getNumberOfComponents()!=1)
10258     throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrOfSliceOnScaledArr : number of components is expected to be equal to one !");
10259   int nbOfTuples(getNumberOfTuples());
10260   if(nbOfTuples==0)
10261     throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrOfSliceOnScaledArr : number of tuples must be != 0 !");
10262   const int *ids(begin());
10263   int nbOfEltsInSlc(GetNumberOfItemGivenBESRelative(bg,stop,step,"DataArrayInt::buildExplicitArrOfSliceOnScaledArr")),sz(0),pos(bg);
10264   for(int i=0;i<nbOfEltsInSlc;i++,pos+=step)
10265     {
10266       if(pos>=0 && pos<nbOfTuples-1)
10267         {
10268           int delta(ids[pos+1]-ids[pos]);
10269           sz+=delta;
10270           if(delta<0)
10271             {
10272               std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrOfSliceOnScaledArr : At pos #" << i << " of input slice, value is " << pos << " and at this pos this is not monotonically increasing !";
10273               throw INTERP_KERNEL::Exception(oss.str().c_str());
10274             }          
10275         }
10276       else
10277         {
10278           std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrOfSliceOnScaledArr : At pos #" << i << " of input slice, value is " << pos << " should be in [0," << nbOfTuples-1 << ") !";  
10279           throw INTERP_KERNEL::Exception(oss.str().c_str());
10280         }
10281     }
10282   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(sz,1);
10283   int *retPtr(ret->getPointer());
10284   pos=bg;
10285   for(int i=0;i<nbOfEltsInSlc;i++,pos+=step)
10286     {
10287       int delta(ids[pos+1]-ids[pos]);
10288       for(int j=0;j<delta;j++,retPtr++)
10289         *retPtr=pos;
10290     }
10291   return ret.retn();
10292 }
10293
10294 /*!
10295  * 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.
10296  * 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
10297  * in tuple **i** of returned DataArrayInt.
10298  * If ranges overlapped (in theory it should not) this method do not detect it and always returns the first range.
10299  *
10300  * 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)]
10301  * The return DataArrayInt will contain : **[0,4,1,2,2,3]**
10302  * 
10303  * \param [in] ranges typically come from output of MEDCouplingUMesh::ComputeRangesFromTypeDistribution. Each range is specified like this : 1st component is
10304  *             for lower value included and 2nd component is the upper value of corresponding range **excluded**.
10305  * \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
10306  *        is thrown if no ranges in \a ranges contains value in \a this.
10307  * 
10308  * \sa DataArrayInt::findIdInRangeForEachTuple
10309  */
10310 DataArrayInt *DataArrayInt::findRangeIdForEachTuple(const DataArrayInt *ranges) const
10311 {
10312   if(!ranges)
10313     throw INTERP_KERNEL::Exception("DataArrayInt::findRangeIdForEachTuple : null input pointer !");
10314   if(ranges->getNumberOfComponents()!=2)
10315     throw INTERP_KERNEL::Exception("DataArrayInt::findRangeIdForEachTuple : input DataArrayInt instance should have 2 components !");
10316   checkAllocated();
10317   if(getNumberOfComponents()!=1)
10318     throw INTERP_KERNEL::Exception("DataArrayInt::findRangeIdForEachTuple : this should have only one component !");
10319   int nbTuples=getNumberOfTuples();
10320   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbTuples,1);
10321   int nbOfRanges=ranges->getNumberOfTuples();
10322   const int *rangesPtr=ranges->getConstPointer();
10323   int *retPtr=ret->getPointer();
10324   const int *inPtr=getConstPointer();
10325   for(int i=0;i<nbTuples;i++,retPtr++)
10326     {
10327       int val=inPtr[i];
10328       bool found=false;
10329       for(int j=0;j<nbOfRanges && !found;j++)
10330         if(val>=rangesPtr[2*j] && val<rangesPtr[2*j+1])
10331           { *retPtr=j; found=true; }
10332       if(found)
10333         continue;
10334       else
10335         {
10336           std::ostringstream oss; oss << "DataArrayInt::findRangeIdForEachTuple : tuple #" << i << " not found by any ranges !";
10337           throw INTERP_KERNEL::Exception(oss.str().c_str());
10338         }
10339     }
10340   return ret.retn();
10341 }
10342
10343 /*!
10344  * 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.
10345  * 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
10346  * in tuple **i** of returned DataArrayInt.
10347  * If ranges overlapped (in theory it should not) this method do not detect it and always returns the sub position of the first range.
10348  *
10349  * 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)]
10350  * The return DataArrayInt will contain : **[1,2,4,0,2,2]**
10351  * This method is often called in pair with DataArrayInt::findRangeIdForEachTuple method.
10352  * 
10353  * \param [in] ranges typically come from output of MEDCouplingUMesh::ComputeRangesFromTypeDistribution. Each range is specified like this : 1st component is
10354  *             for lower value included and 2nd component is the upper value of corresponding range **excluded**.
10355  * \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
10356  *        is thrown if no ranges in \a ranges contains value in \a this.
10357  * \sa DataArrayInt::findRangeIdForEachTuple
10358  */
10359 DataArrayInt *DataArrayInt::findIdInRangeForEachTuple(const DataArrayInt *ranges) const
10360 {
10361   if(!ranges)
10362     throw INTERP_KERNEL::Exception("DataArrayInt::findIdInRangeForEachTuple : null input pointer !");
10363   if(ranges->getNumberOfComponents()!=2)
10364     throw INTERP_KERNEL::Exception("DataArrayInt::findIdInRangeForEachTuple : input DataArrayInt instance should have 2 components !");
10365   checkAllocated();
10366   if(getNumberOfComponents()!=1)
10367     throw INTERP_KERNEL::Exception("DataArrayInt::findIdInRangeForEachTuple : this should have only one component !");
10368   int nbTuples=getNumberOfTuples();
10369   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbTuples,1);
10370   int nbOfRanges=ranges->getNumberOfTuples();
10371   const int *rangesPtr=ranges->getConstPointer();
10372   int *retPtr=ret->getPointer();
10373   const int *inPtr=getConstPointer();
10374   for(int i=0;i<nbTuples;i++,retPtr++)
10375     {
10376       int val=inPtr[i];
10377       bool found=false;
10378       for(int j=0;j<nbOfRanges && !found;j++)
10379         if(val>=rangesPtr[2*j] && val<rangesPtr[2*j+1])
10380           { *retPtr=val-rangesPtr[2*j]; found=true; }
10381       if(found)
10382         continue;
10383       else
10384         {
10385           std::ostringstream oss; oss << "DataArrayInt::findIdInRangeForEachTuple : tuple #" << i << " not found by any ranges !";
10386           throw INTERP_KERNEL::Exception(oss.str().c_str());
10387         }
10388     }
10389   return ret.retn();
10390 }
10391
10392 /*!
10393  * 
10394  * \param [in] nbTimes specifies the nb of times each tuples in \a this will be duplicated contiguouly in returned DataArrayInt instance.
10395  *             \a nbTimes  should be at least equal to 1.
10396  * \return a newly allocated DataArrayInt having one component and number of tuples equal to \a nbTimes * \c this->getNumberOfTuples.
10397  * \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.
10398  */
10399 DataArrayInt *DataArrayInt::duplicateEachTupleNTimes(int nbTimes) const
10400 {
10401   checkAllocated();
10402   if(getNumberOfComponents()!=1)
10403     throw INTERP_KERNEL::Exception("DataArrayInt::duplicateEachTupleNTimes : this should have only one component !");
10404   if(nbTimes<1)
10405     throw INTERP_KERNEL::Exception("DataArrayInt::duplicateEachTupleNTimes : nb times should be >= 1 !");
10406   int nbTuples=getNumberOfTuples();
10407   const int *inPtr=getConstPointer();
10408   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbTimes*nbTuples,1);
10409   int *retPtr=ret->getPointer();
10410   for(int i=0;i<nbTuples;i++,inPtr++)
10411     {
10412       int val=*inPtr;
10413       for(int j=0;j<nbTimes;j++,retPtr++)
10414         *retPtr=val;
10415     }
10416   ret->copyStringInfoFrom(*this);
10417   return ret.retn();
10418 }
10419
10420 /*!
10421  * This method returns all different values found in \a this. This method throws if \a this has not been allocated.
10422  * But the number of components can be different from one.
10423  * \return a newly allocated array (that should be dealt by the caller) containing different values in \a this.
10424  */
10425 DataArrayInt *DataArrayInt::getDifferentValues() const
10426 {
10427   checkAllocated();
10428   std::set<int> ret;
10429   ret.insert(begin(),end());
10430   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret2=DataArrayInt::New(); ret2->alloc((int)ret.size(),1);
10431   std::copy(ret.begin(),ret.end(),ret2->getPointer());
10432   return ret2.retn();
10433 }
10434
10435 /*!
10436  * This method is a refinement of DataArrayInt::getDifferentValues because it returns not only different values in \a this but also, for each of
10437  * them it tells which tuple id have this id.
10438  * This method works only on arrays with one component (if it is not the case call DataArrayInt::rearrange(1) ).
10439  * This method returns two arrays having same size.
10440  * 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.
10441  * 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]]
10442  */
10443 std::vector<DataArrayInt *> DataArrayInt::partitionByDifferentValues(std::vector<int>& differentIds) const
10444 {
10445   checkAllocated();
10446   if(getNumberOfComponents()!=1)
10447     throw INTERP_KERNEL::Exception("DataArrayInt::partitionByDifferentValues : this should have only one component !");
10448   int id=0;
10449   std::map<int,int> m,m2,m3;
10450   for(const int *w=begin();w!=end();w++)
10451     m[*w]++;
10452   differentIds.resize(m.size());
10453   std::vector<DataArrayInt *> ret(m.size());
10454   std::vector<int *> retPtr(m.size());
10455   for(std::map<int,int>::const_iterator it=m.begin();it!=m.end();it++,id++)
10456     {
10457       m2[(*it).first]=id;
10458       ret[id]=DataArrayInt::New();
10459       ret[id]->alloc((*it).second,1);
10460       retPtr[id]=ret[id]->getPointer();
10461       differentIds[id]=(*it).first;
10462     }
10463   id=0;
10464   for(const int *w=begin();w!=end();w++,id++)
10465     {
10466       retPtr[m2[*w]][m3[*w]++]=id;
10467     }
10468   return ret;
10469 }
10470
10471 /*!
10472  * This method split ids in [0, \c this->getNumberOfTuples() ) using \a this array as a field of weight (>=0 each).
10473  * The aim of this method is to return a set of \a nbOfSlices chunk of contiguous ids as balanced as possible.
10474  *
10475  * \param [in] nbOfSlices - number of slices expected.
10476  * \return - a vector having a size equal to \a nbOfSlices giving the start (included) and the stop (excluded) of each chunks.
10477  * 
10478  * \sa DataArray::GetSlice
10479  * \throw If \a this is not allocated or not with exactly one component.
10480  * \throw If an element in \a this if < 0.
10481  */
10482 std::vector< std::pair<int,int> > DataArrayInt::splitInBalancedSlices(int nbOfSlices) const
10483 {
10484   if(!isAllocated() || getNumberOfComponents()!=1)
10485     throw INTERP_KERNEL::Exception("DataArrayInt::splitInBalancedSlices : this array should have number of components equal to one and must be allocated !");
10486   if(nbOfSlices<=0)
10487     throw INTERP_KERNEL::Exception("DataArrayInt::splitInBalancedSlices : number of slices must be >= 1 !");
10488   int sum(accumulate(0)),nbOfTuples(getNumberOfTuples());
10489   int sumPerSlc(sum/nbOfSlices),pos(0);
10490   const int *w(begin());
10491   std::vector< std::pair<int,int> > ret(nbOfSlices);
10492   for(int i=0;i<nbOfSlices;i++)
10493     {
10494       std::pair<int,int> p(pos,-1);
10495       int locSum(0);
10496       while(locSum<sumPerSlc && pos<nbOfTuples) { pos++; locSum+=*w++; }
10497       if(i!=nbOfSlices-1)
10498         p.second=pos;
10499       else
10500         p.second=nbOfTuples;
10501       ret[i]=p;
10502     }
10503   return ret;
10504 }
10505
10506 /*!
10507  * Returns a new DataArrayInt that is a sum of two given arrays. There are 3
10508  * valid cases.
10509  * 1.  The arrays have same number of tuples and components. Then each value of
10510  *   the result array (_a_) is a sum of the corresponding values of \a a1 and \a a2,
10511  *   i.e.: _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ i, j ].
10512  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
10513  *   component. Then
10514  *   _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ i, 0 ].
10515  * 3.  The arrays have same number of components and one array, say _a2_, has one
10516  *   tuple. Then
10517  *   _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ 0, j ].
10518  *
10519  * Info on components is copied either from the first array (in the first case) or from
10520  * the array with maximal number of elements (getNbOfElems()).
10521  *  \param [in] a1 - an array to sum up.
10522  *  \param [in] a2 - another array to sum up.
10523  *  \return DataArrayInt * - the new instance of DataArrayInt.
10524  *          The caller is to delete this result array using decrRef() as it is no more
10525  *          needed.
10526  *  \throw If either \a a1 or \a a2 is NULL.
10527  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
10528  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
10529  *         none of them has number of tuples or components equal to 1.
10530  */
10531 DataArrayInt *DataArrayInt::Add(const DataArrayInt *a1, const DataArrayInt *a2)
10532 {
10533   if(!a1 || !a2)
10534     throw INTERP_KERNEL::Exception("DataArrayInt::Add : input DataArrayInt instance is NULL !");
10535   int nbOfTuple=a1->getNumberOfTuples();
10536   int nbOfTuple2=a2->getNumberOfTuples();
10537   int nbOfComp=a1->getNumberOfComponents();
10538   int nbOfComp2=a2->getNumberOfComponents();
10539   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=0;
10540   if(nbOfTuple==nbOfTuple2)
10541     {
10542       if(nbOfComp==nbOfComp2)
10543         {
10544           ret=DataArrayInt::New();
10545           ret->alloc(nbOfTuple,nbOfComp);
10546           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::plus<int>());
10547           ret->copyStringInfoFrom(*a1);
10548         }
10549       else
10550         {
10551           int nbOfCompMin,nbOfCompMax;
10552           const DataArrayInt *aMin, *aMax;
10553           if(nbOfComp>nbOfComp2)
10554             {
10555               nbOfCompMin=nbOfComp2; nbOfCompMax=nbOfComp;
10556               aMin=a2; aMax=a1;
10557             }
10558           else
10559             {
10560               nbOfCompMin=nbOfComp; nbOfCompMax=nbOfComp2;
10561               aMin=a1; aMax=a2;
10562             }
10563           if(nbOfCompMin==1)
10564             {
10565               ret=DataArrayInt::New();
10566               ret->alloc(nbOfTuple,nbOfCompMax);
10567               const int *aMinPtr=aMin->getConstPointer();
10568               const int *aMaxPtr=aMax->getConstPointer();
10569               int *res=ret->getPointer();
10570               for(int i=0;i<nbOfTuple;i++)
10571                 res=std::transform(aMaxPtr+i*nbOfCompMax,aMaxPtr+(i+1)*nbOfCompMax,res,std::bind2nd(std::plus<int>(),aMinPtr[i]));
10572               ret->copyStringInfoFrom(*aMax);
10573             }
10574           else
10575             throw INTERP_KERNEL::Exception("Nb of components mismatch for array Add !");
10576         }
10577     }
10578   else if((nbOfTuple==1 && nbOfTuple2>1) || (nbOfTuple>1 && nbOfTuple2==1))
10579     {
10580       if(nbOfComp==nbOfComp2)
10581         {
10582           int nbOfTupleMax=std::max(nbOfTuple,nbOfTuple2);
10583           const DataArrayInt *aMin=nbOfTuple>nbOfTuple2?a2:a1;
10584           const DataArrayInt *aMax=nbOfTuple>nbOfTuple2?a1:a2;
10585           const int *aMinPtr=aMin->getConstPointer(),*aMaxPtr=aMax->getConstPointer();
10586           ret=DataArrayInt::New();
10587           ret->alloc(nbOfTupleMax,nbOfComp);
10588           int *res=ret->getPointer();
10589           for(int i=0;i<nbOfTupleMax;i++)
10590             res=std::transform(aMaxPtr+i*nbOfComp,aMaxPtr+(i+1)*nbOfComp,aMinPtr,res,std::plus<int>());
10591           ret->copyStringInfoFrom(*aMax);
10592         }
10593       else
10594         throw INTERP_KERNEL::Exception("Nb of components mismatch for array Add !");
10595     }
10596   else
10597     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Add !");
10598   return ret.retn();
10599 }
10600
10601 /*!
10602  * Adds values of another DataArrayInt to values of \a this one. There are 3
10603  * valid cases.
10604  * 1.  The arrays have same number of tuples and components. Then each value of
10605  *   \a other array is added to the corresponding value of \a this array, i.e.:
10606  *   _a_ [ i, j ] += _other_ [ i, j ].
10607  * 2.  The arrays have same number of tuples and \a other array has one component. Then
10608  *   _a_ [ i, j ] += _other_ [ i, 0 ].
10609  * 3.  The arrays have same number of components and \a other array has one tuple. Then
10610  *   _a_ [ i, j ] += _a2_ [ 0, j ].
10611  *
10612  *  \param [in] other - an array to add to \a this one.
10613  *  \throw If \a other is NULL.
10614  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
10615  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
10616  *         \a other has number of both tuples and components not equal to 1.
10617  */
10618 void DataArrayInt::addEqual(const DataArrayInt *other)
10619 {
10620   if(!other)
10621     throw INTERP_KERNEL::Exception("DataArrayInt::addEqual : input DataArrayInt instance is NULL !");
10622   const char *msg="Nb of tuples mismatch for DataArrayInt::addEqual  !";
10623   checkAllocated(); other->checkAllocated();
10624   int nbOfTuple=getNumberOfTuples();
10625   int nbOfTuple2=other->getNumberOfTuples();
10626   int nbOfComp=getNumberOfComponents();
10627   int nbOfComp2=other->getNumberOfComponents();
10628   if(nbOfTuple==nbOfTuple2)
10629     {
10630       if(nbOfComp==nbOfComp2)
10631         {
10632           std::transform(begin(),end(),other->begin(),getPointer(),std::plus<int>());
10633         }
10634       else if(nbOfComp2==1)
10635         {
10636           int *ptr=getPointer();
10637           const int *ptrc=other->getConstPointer();
10638           for(int i=0;i<nbOfTuple;i++)
10639             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::plus<int>(),*ptrc++));
10640         }
10641       else
10642         throw INTERP_KERNEL::Exception(msg);
10643     }
10644   else if(nbOfTuple2==1)
10645     {
10646       if(nbOfComp2==nbOfComp)
10647         {
10648           int *ptr=getPointer();
10649           const int *ptrc=other->getConstPointer();
10650           for(int i=0;i<nbOfTuple;i++)
10651             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::plus<int>());
10652         }
10653       else
10654         throw INTERP_KERNEL::Exception(msg);
10655     }
10656   else
10657     throw INTERP_KERNEL::Exception(msg);
10658   declareAsNew();
10659 }
10660
10661 /*!
10662  * Returns a new DataArrayInt that is a subtraction of two given arrays. There are 3
10663  * valid cases.
10664  * 1.  The arrays have same number of tuples and components. Then each value of
10665  *   the result array (_a_) is a subtraction of the corresponding values of \a a1 and
10666  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ i, j ].
10667  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
10668  *   component. Then
10669  *   _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ i, 0 ].
10670  * 3.  The arrays have same number of components and one array, say _a2_, has one
10671  *   tuple. Then
10672  *   _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ 0, j ].
10673  *
10674  * Info on components is copied either from the first array (in the first case) or from
10675  * the array with maximal number of elements (getNbOfElems()).
10676  *  \param [in] a1 - an array to subtract from.
10677  *  \param [in] a2 - an array to subtract.
10678  *  \return DataArrayInt * - the new instance of DataArrayInt.
10679  *          The caller is to delete this result array using decrRef() as it is no more
10680  *          needed.
10681  *  \throw If either \a a1 or \a a2 is NULL.
10682  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
10683  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
10684  *         none of them has number of tuples or components equal to 1.
10685  */
10686 DataArrayInt *DataArrayInt::Substract(const DataArrayInt *a1, const DataArrayInt *a2)
10687 {
10688   if(!a1 || !a2)
10689     throw INTERP_KERNEL::Exception("DataArrayInt::Substract : input DataArrayInt instance is NULL !");
10690   int nbOfTuple1=a1->getNumberOfTuples();
10691   int nbOfTuple2=a2->getNumberOfTuples();
10692   int nbOfComp1=a1->getNumberOfComponents();
10693   int nbOfComp2=a2->getNumberOfComponents();
10694   if(nbOfTuple2==nbOfTuple1)
10695     {
10696       if(nbOfComp1==nbOfComp2)
10697         {
10698           MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
10699           ret->alloc(nbOfTuple2,nbOfComp1);
10700           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::minus<int>());
10701           ret->copyStringInfoFrom(*a1);
10702           return ret.retn();
10703         }
10704       else if(nbOfComp2==1)
10705         {
10706           MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
10707           ret->alloc(nbOfTuple1,nbOfComp1);
10708           const int *a2Ptr=a2->getConstPointer();
10709           const int *a1Ptr=a1->getConstPointer();
10710           int *res=ret->getPointer();
10711           for(int i=0;i<nbOfTuple1;i++)
10712             res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::minus<int>(),a2Ptr[i]));
10713           ret->copyStringInfoFrom(*a1);
10714           return ret.retn();
10715         }
10716       else
10717         {
10718           a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Substract !");
10719           return 0;
10720         }
10721     }
10722   else if(nbOfTuple2==1)
10723     {
10724       a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Substract !");
10725       MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
10726       ret->alloc(nbOfTuple1,nbOfComp1);
10727       const int *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
10728       int *pt=ret->getPointer();
10729       for(int i=0;i<nbOfTuple1;i++)
10730         pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::minus<int>());
10731       ret->copyStringInfoFrom(*a1);
10732       return ret.retn();
10733     }
10734   else
10735     {
10736       a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Substract !");//will always throw an exception
10737       return 0;
10738     }
10739 }
10740
10741 /*!
10742  * Subtract values of another DataArrayInt from values of \a this one. There are 3
10743  * valid cases.
10744  * 1.  The arrays have same number of tuples and components. Then each value of
10745  *   \a other array is subtracted from the corresponding value of \a this array, i.e.:
10746  *   _a_ [ i, j ] -= _other_ [ i, j ].
10747  * 2.  The arrays have same number of tuples and \a other array has one component. Then
10748  *   _a_ [ i, j ] -= _other_ [ i, 0 ].
10749  * 3.  The arrays have same number of components and \a other array has one tuple. Then
10750  *   _a_ [ i, j ] -= _a2_ [ 0, j ].
10751  *
10752  *  \param [in] other - an array to subtract from \a this one.
10753  *  \throw If \a other is NULL.
10754  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
10755  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
10756  *         \a other has number of both tuples and components not equal to 1.
10757  */
10758 void DataArrayInt::substractEqual(const DataArrayInt *other)
10759 {
10760   if(!other)
10761     throw INTERP_KERNEL::Exception("DataArrayInt::substractEqual : input DataArrayInt instance is NULL !");
10762   const char *msg="Nb of tuples mismatch for DataArrayInt::substractEqual  !";
10763   checkAllocated(); other->checkAllocated();
10764   int nbOfTuple=getNumberOfTuples();
10765   int nbOfTuple2=other->getNumberOfTuples();
10766   int nbOfComp=getNumberOfComponents();
10767   int nbOfComp2=other->getNumberOfComponents();
10768   if(nbOfTuple==nbOfTuple2)
10769     {
10770       if(nbOfComp==nbOfComp2)
10771         {
10772           std::transform(begin(),end(),other->begin(),getPointer(),std::minus<int>());
10773         }
10774       else if(nbOfComp2==1)
10775         {
10776           int *ptr=getPointer();
10777           const int *ptrc=other->getConstPointer();
10778           for(int i=0;i<nbOfTuple;i++)
10779             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::minus<int>(),*ptrc++));
10780         }
10781       else
10782         throw INTERP_KERNEL::Exception(msg);
10783     }
10784   else if(nbOfTuple2==1)
10785     {
10786       int *ptr=getPointer();
10787       const int *ptrc=other->getConstPointer();
10788       for(int i=0;i<nbOfTuple;i++)
10789         std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::minus<int>());
10790     }
10791   else
10792     throw INTERP_KERNEL::Exception(msg);
10793   declareAsNew();
10794 }
10795
10796 /*!
10797  * Returns a new DataArrayInt that is a product of two given arrays. There are 3
10798  * valid cases.
10799  * 1.  The arrays have same number of tuples and components. Then each value of
10800  *   the result array (_a_) is a product of the corresponding values of \a a1 and
10801  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ i, j ].
10802  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
10803  *   component. Then
10804  *   _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ i, 0 ].
10805  * 3.  The arrays have same number of components and one array, say _a2_, has one
10806  *   tuple. Then
10807  *   _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ 0, j ].
10808  *
10809  * Info on components is copied either from the first array (in the first case) or from
10810  * the array with maximal number of elements (getNbOfElems()).
10811  *  \param [in] a1 - a factor array.
10812  *  \param [in] a2 - another factor array.
10813  *  \return DataArrayInt * - the new instance of DataArrayInt.
10814  *          The caller is to delete this result array using decrRef() as it is no more
10815  *          needed.
10816  *  \throw If either \a a1 or \a a2 is NULL.
10817  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
10818  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
10819  *         none of them has number of tuples or components equal to 1.
10820  */
10821 DataArrayInt *DataArrayInt::Multiply(const DataArrayInt *a1, const DataArrayInt *a2)
10822 {
10823   if(!a1 || !a2)
10824     throw INTERP_KERNEL::Exception("DataArrayInt::Multiply : input DataArrayInt instance is NULL !");
10825   int nbOfTuple=a1->getNumberOfTuples();
10826   int nbOfTuple2=a2->getNumberOfTuples();
10827   int nbOfComp=a1->getNumberOfComponents();
10828   int nbOfComp2=a2->getNumberOfComponents();
10829   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=0;
10830   if(nbOfTuple==nbOfTuple2)
10831     {
10832       if(nbOfComp==nbOfComp2)
10833         {
10834           ret=DataArrayInt::New();
10835           ret->alloc(nbOfTuple,nbOfComp);
10836           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::multiplies<int>());
10837           ret->copyStringInfoFrom(*a1);
10838         }
10839       else
10840         {
10841           int nbOfCompMin,nbOfCompMax;
10842           const DataArrayInt *aMin, *aMax;
10843           if(nbOfComp>nbOfComp2)
10844             {
10845               nbOfCompMin=nbOfComp2; nbOfCompMax=nbOfComp;
10846               aMin=a2; aMax=a1;
10847             }
10848           else
10849             {
10850               nbOfCompMin=nbOfComp; nbOfCompMax=nbOfComp2;
10851               aMin=a1; aMax=a2;
10852             }
10853           if(nbOfCompMin==1)
10854             {
10855               ret=DataArrayInt::New();
10856               ret->alloc(nbOfTuple,nbOfCompMax);
10857               const int *aMinPtr=aMin->getConstPointer();
10858               const int *aMaxPtr=aMax->getConstPointer();
10859               int *res=ret->getPointer();
10860               for(int i=0;i<nbOfTuple;i++)
10861                 res=std::transform(aMaxPtr+i*nbOfCompMax,aMaxPtr+(i+1)*nbOfCompMax,res,std::bind2nd(std::multiplies<int>(),aMinPtr[i]));
10862               ret->copyStringInfoFrom(*aMax);
10863             }
10864           else
10865             throw INTERP_KERNEL::Exception("Nb of components mismatch for array Multiply !");
10866         }
10867     }
10868   else if((nbOfTuple==1 && nbOfTuple2>1) || (nbOfTuple>1 && nbOfTuple2==1))
10869     {
10870       if(nbOfComp==nbOfComp2)
10871         {
10872           int nbOfTupleMax=std::max(nbOfTuple,nbOfTuple2);
10873           const DataArrayInt *aMin=nbOfTuple>nbOfTuple2?a2:a1;
10874           const DataArrayInt *aMax=nbOfTuple>nbOfTuple2?a1:a2;
10875           const int *aMinPtr=aMin->getConstPointer(),*aMaxPtr=aMax->getConstPointer();
10876           ret=DataArrayInt::New();
10877           ret->alloc(nbOfTupleMax,nbOfComp);
10878           int *res=ret->getPointer();
10879           for(int i=0;i<nbOfTupleMax;i++)
10880             res=std::transform(aMaxPtr+i*nbOfComp,aMaxPtr+(i+1)*nbOfComp,aMinPtr,res,std::multiplies<int>());
10881           ret->copyStringInfoFrom(*aMax);
10882         }
10883       else
10884         throw INTERP_KERNEL::Exception("Nb of components mismatch for array Multiply !");
10885     }
10886   else
10887     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Multiply !");
10888   return ret.retn();
10889 }
10890
10891
10892 /*!
10893  * Multiply values of another DataArrayInt to values of \a this one. There are 3
10894  * valid cases.
10895  * 1.  The arrays have same number of tuples and components. Then each value of
10896  *   \a other array is multiplied to the corresponding value of \a this array, i.e.:
10897  *   _a_ [ i, j ] *= _other_ [ i, j ].
10898  * 2.  The arrays have same number of tuples and \a other array has one component. Then
10899  *   _a_ [ i, j ] *= _other_ [ i, 0 ].
10900  * 3.  The arrays have same number of components and \a other array has one tuple. Then
10901  *   _a_ [ i, j ] *= _a2_ [ 0, j ].
10902  *
10903  *  \param [in] other - an array to multiply to \a this one.
10904  *  \throw If \a other is NULL.
10905  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
10906  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
10907  *         \a other has number of both tuples and components not equal to 1.
10908  */
10909 void DataArrayInt::multiplyEqual(const DataArrayInt *other)
10910 {
10911   if(!other)
10912     throw INTERP_KERNEL::Exception("DataArrayInt::multiplyEqual : input DataArrayInt instance is NULL !");
10913   const char *msg="Nb of tuples mismatch for DataArrayInt::multiplyEqual !";
10914   checkAllocated(); other->checkAllocated();
10915   int nbOfTuple=getNumberOfTuples();
10916   int nbOfTuple2=other->getNumberOfTuples();
10917   int nbOfComp=getNumberOfComponents();
10918   int nbOfComp2=other->getNumberOfComponents();
10919   if(nbOfTuple==nbOfTuple2)
10920     {
10921       if(nbOfComp==nbOfComp2)
10922         {
10923           std::transform(begin(),end(),other->begin(),getPointer(),std::multiplies<int>());
10924         }
10925       else if(nbOfComp2==1)
10926         {
10927           int *ptr=getPointer();
10928           const int *ptrc=other->getConstPointer();
10929           for(int i=0;i<nbOfTuple;i++)
10930             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::multiplies<int>(),*ptrc++));    
10931         }
10932       else
10933         throw INTERP_KERNEL::Exception(msg);
10934     }
10935   else if(nbOfTuple2==1)
10936     {
10937       if(nbOfComp2==nbOfComp)
10938         {
10939           int *ptr=getPointer();
10940           const int *ptrc=other->getConstPointer();
10941           for(int i=0;i<nbOfTuple;i++)
10942             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::multiplies<int>());
10943         }
10944       else
10945         throw INTERP_KERNEL::Exception(msg);
10946     }
10947   else
10948     throw INTERP_KERNEL::Exception(msg);
10949   declareAsNew();
10950 }
10951
10952
10953 /*!
10954  * Returns a new DataArrayInt that is a division of two given arrays. There are 3
10955  * valid cases.
10956  * 1.  The arrays have same number of tuples and components. Then each value of
10957  *   the result array (_a_) is a division of the corresponding values of \a a1 and
10958  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ i, j ].
10959  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
10960  *   component. Then
10961  *   _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ i, 0 ].
10962  * 3.  The arrays have same number of components and one array, say _a2_, has one
10963  *   tuple. Then
10964  *   _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ 0, j ].
10965  *
10966  * Info on components is copied either from the first array (in the first case) or from
10967  * the array with maximal number of elements (getNbOfElems()).
10968  *  \warning No check of division by zero is performed!
10969  *  \param [in] a1 - a numerator array.
10970  *  \param [in] a2 - a denominator array.
10971  *  \return DataArrayInt * - the new instance of DataArrayInt.
10972  *          The caller is to delete this result array using decrRef() as it is no more
10973  *          needed.
10974  *  \throw If either \a a1 or \a a2 is NULL.
10975  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
10976  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
10977  *         none of them has number of tuples or components equal to 1.
10978  */
10979 DataArrayInt *DataArrayInt::Divide(const DataArrayInt *a1, const DataArrayInt *a2)
10980 {
10981   if(!a1 || !a2)
10982     throw INTERP_KERNEL::Exception("DataArrayInt::Divide : input DataArrayInt instance is NULL !");
10983   int nbOfTuple1=a1->getNumberOfTuples();
10984   int nbOfTuple2=a2->getNumberOfTuples();
10985   int nbOfComp1=a1->getNumberOfComponents();
10986   int nbOfComp2=a2->getNumberOfComponents();
10987   if(nbOfTuple2==nbOfTuple1)
10988     {
10989       if(nbOfComp1==nbOfComp2)
10990         {
10991           MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
10992           ret->alloc(nbOfTuple2,nbOfComp1);
10993           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::divides<int>());
10994           ret->copyStringInfoFrom(*a1);
10995           return ret.retn();
10996         }
10997       else if(nbOfComp2==1)
10998         {
10999           MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
11000           ret->alloc(nbOfTuple1,nbOfComp1);
11001           const int *a2Ptr=a2->getConstPointer();
11002           const int *a1Ptr=a1->getConstPointer();
11003           int *res=ret->getPointer();
11004           for(int i=0;i<nbOfTuple1;i++)
11005             res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::divides<int>(),a2Ptr[i]));
11006           ret->copyStringInfoFrom(*a1);
11007           return ret.retn();
11008         }
11009       else
11010         {
11011           a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Divide !");
11012           return 0;
11013         }
11014     }
11015   else if(nbOfTuple2==1)
11016     {
11017       a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Divide !");
11018       MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
11019       ret->alloc(nbOfTuple1,nbOfComp1);
11020       const int *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
11021       int *pt=ret->getPointer();
11022       for(int i=0;i<nbOfTuple1;i++)
11023         pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::divides<int>());
11024       ret->copyStringInfoFrom(*a1);
11025       return ret.retn();
11026     }
11027   else
11028     {
11029       a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Divide !");//will always throw an exception
11030       return 0;
11031     }
11032 }
11033
11034 /*!
11035  * Divide values of \a this array by values of another DataArrayInt. There are 3
11036  * valid cases.
11037  * 1.  The arrays have same number of tuples and components. Then each value of
11038  *    \a this array is divided by the corresponding value of \a other one, i.e.:
11039  *   _a_ [ i, j ] /= _other_ [ i, j ].
11040  * 2.  The arrays have same number of tuples and \a other array has one component. Then
11041  *   _a_ [ i, j ] /= _other_ [ i, 0 ].
11042  * 3.  The arrays have same number of components and \a other array has one tuple. Then
11043  *   _a_ [ i, j ] /= _a2_ [ 0, j ].
11044  *
11045  *  \warning No check of division by zero is performed!
11046  *  \param [in] other - an array to divide \a this one by.
11047  *  \throw If \a other is NULL.
11048  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
11049  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
11050  *         \a other has number of both tuples and components not equal to 1.
11051  */
11052 void DataArrayInt::divideEqual(const DataArrayInt *other)
11053 {
11054   if(!other)
11055     throw INTERP_KERNEL::Exception("DataArrayInt::divideEqual : input DataArrayInt instance is NULL !");
11056   const char *msg="Nb of tuples mismatch for DataArrayInt::divideEqual !";
11057   checkAllocated(); other->checkAllocated();
11058   int nbOfTuple=getNumberOfTuples();
11059   int nbOfTuple2=other->getNumberOfTuples();
11060   int nbOfComp=getNumberOfComponents();
11061   int nbOfComp2=other->getNumberOfComponents();
11062   if(nbOfTuple==nbOfTuple2)
11063     {
11064       if(nbOfComp==nbOfComp2)
11065         {
11066           std::transform(begin(),end(),other->begin(),getPointer(),std::divides<int>());
11067         }
11068       else if(nbOfComp2==1)
11069         {
11070           int *ptr=getPointer();
11071           const int *ptrc=other->getConstPointer();
11072           for(int i=0;i<nbOfTuple;i++)
11073             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::divides<int>(),*ptrc++));
11074         }
11075       else
11076         throw INTERP_KERNEL::Exception(msg);
11077     }
11078   else if(nbOfTuple2==1)
11079     {
11080       if(nbOfComp2==nbOfComp)
11081         {
11082           int *ptr=getPointer();
11083           const int *ptrc=other->getConstPointer();
11084           for(int i=0;i<nbOfTuple;i++)
11085             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::divides<int>());
11086         }
11087       else
11088         throw INTERP_KERNEL::Exception(msg);
11089     }
11090   else
11091     throw INTERP_KERNEL::Exception(msg);
11092   declareAsNew();
11093 }
11094
11095
11096 /*!
11097  * Returns a new DataArrayInt that is a modulus of two given arrays. There are 3
11098  * valid cases.
11099  * 1.  The arrays have same number of tuples and components. Then each value of
11100  *   the result array (_a_) is a division of the corresponding values of \a a1 and
11101  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] % _a2_ [ i, j ].
11102  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
11103  *   component. Then
11104  *   _a_ [ i, j ] = _a1_ [ i, j ] % _a2_ [ i, 0 ].
11105  * 3.  The arrays have same number of components and one array, say _a2_, has one
11106  *   tuple. Then
11107  *   _a_ [ i, j ] = _a1_ [ i, j ] % _a2_ [ 0, j ].
11108  *
11109  * Info on components is copied either from the first array (in the first case) or from
11110  * the array with maximal number of elements (getNbOfElems()).
11111  *  \warning No check of division by zero is performed!
11112  *  \param [in] a1 - a dividend array.
11113  *  \param [in] a2 - a divisor array.
11114  *  \return DataArrayInt * - the new instance of DataArrayInt.
11115  *          The caller is to delete this result array using decrRef() as it is no more
11116  *          needed.
11117  *  \throw If either \a a1 or \a a2 is NULL.
11118  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
11119  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
11120  *         none of them has number of tuples or components equal to 1.
11121  */
11122 DataArrayInt *DataArrayInt::Modulus(const DataArrayInt *a1, const DataArrayInt *a2)
11123 {
11124   if(!a1 || !a2)
11125     throw INTERP_KERNEL::Exception("DataArrayInt::Modulus : input DataArrayInt instance is NULL !");
11126   int nbOfTuple1=a1->getNumberOfTuples();
11127   int nbOfTuple2=a2->getNumberOfTuples();
11128   int nbOfComp1=a1->getNumberOfComponents();
11129   int nbOfComp2=a2->getNumberOfComponents();
11130   if(nbOfTuple2==nbOfTuple1)
11131     {
11132       if(nbOfComp1==nbOfComp2)
11133         {
11134           MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
11135           ret->alloc(nbOfTuple2,nbOfComp1);
11136           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::modulus<int>());
11137           ret->copyStringInfoFrom(*a1);
11138           return ret.retn();
11139         }
11140       else if(nbOfComp2==1)
11141         {
11142           MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
11143           ret->alloc(nbOfTuple1,nbOfComp1);
11144           const int *a2Ptr=a2->getConstPointer();
11145           const int *a1Ptr=a1->getConstPointer();
11146           int *res=ret->getPointer();
11147           for(int i=0;i<nbOfTuple1;i++)
11148             res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::modulus<int>(),a2Ptr[i]));
11149           ret->copyStringInfoFrom(*a1);
11150           return ret.retn();
11151         }
11152       else
11153         {
11154           a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Modulus !");
11155           return 0;
11156         }
11157     }
11158   else if(nbOfTuple2==1)
11159     {
11160       a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Modulus !");
11161       MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
11162       ret->alloc(nbOfTuple1,nbOfComp1);
11163       const int *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
11164       int *pt=ret->getPointer();
11165       for(int i=0;i<nbOfTuple1;i++)
11166         pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::modulus<int>());
11167       ret->copyStringInfoFrom(*a1);
11168       return ret.retn();
11169     }
11170   else
11171     {
11172       a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Modulus !");//will always throw an exception
11173       return 0;
11174     }
11175 }
11176
11177 /*!
11178  * Modify \a this array so that each value becomes a modulus of division of this value by
11179  * a value of another DataArrayInt. There are 3 valid cases.
11180  * 1.  The arrays have same number of tuples and components. Then each value of
11181  *    \a this array is divided by the corresponding value of \a other one, i.e.:
11182  *   _a_ [ i, j ] %= _other_ [ i, j ].
11183  * 2.  The arrays have same number of tuples and \a other array has one component. Then
11184  *   _a_ [ i, j ] %= _other_ [ i, 0 ].
11185  * 3.  The arrays have same number of components and \a other array has one tuple. Then
11186  *   _a_ [ i, j ] %= _a2_ [ 0, j ].
11187  *
11188  *  \warning No check of division by zero is performed!
11189  *  \param [in] other - a divisor array.
11190  *  \throw If \a other is NULL.
11191  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
11192  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
11193  *         \a other has number of both tuples and components not equal to 1.
11194  */
11195 void DataArrayInt::modulusEqual(const DataArrayInt *other)
11196 {
11197   if(!other)
11198     throw INTERP_KERNEL::Exception("DataArrayInt::modulusEqual : input DataArrayInt instance is NULL !");
11199   const char *msg="Nb of tuples mismatch for DataArrayInt::modulusEqual !";
11200   checkAllocated(); other->checkAllocated();
11201   int nbOfTuple=getNumberOfTuples();
11202   int nbOfTuple2=other->getNumberOfTuples();
11203   int nbOfComp=getNumberOfComponents();
11204   int nbOfComp2=other->getNumberOfComponents();
11205   if(nbOfTuple==nbOfTuple2)
11206     {
11207       if(nbOfComp==nbOfComp2)
11208         {
11209           std::transform(begin(),end(),other->begin(),getPointer(),std::modulus<int>());
11210         }
11211       else if(nbOfComp2==1)
11212         {
11213           if(nbOfComp2==nbOfComp)
11214             {
11215               int *ptr=getPointer();
11216               const int *ptrc=other->getConstPointer();
11217               for(int i=0;i<nbOfTuple;i++)
11218                 std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::modulus<int>(),*ptrc++));
11219             }
11220           else
11221             throw INTERP_KERNEL::Exception(msg);
11222         }
11223       else
11224         throw INTERP_KERNEL::Exception(msg);
11225     }
11226   else if(nbOfTuple2==1)
11227     {
11228       int *ptr=getPointer();
11229       const int *ptrc=other->getConstPointer();
11230       for(int i=0;i<nbOfTuple;i++)
11231         std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::modulus<int>());
11232     }
11233   else
11234     throw INTERP_KERNEL::Exception(msg);
11235   declareAsNew();
11236 }
11237
11238 /*!
11239  * Returns a new DataArrayInt that is the result of pow of two given arrays. There are 3
11240  * valid cases.
11241  *
11242  *  \param [in] a1 - an array to pow up.
11243  *  \param [in] a2 - another array to sum up.
11244  *  \return DataArrayInt * - the new instance of DataArrayInt.
11245  *          The caller is to delete this result array using decrRef() as it is no more
11246  *          needed.
11247  *  \throw If either \a a1 or \a a2 is NULL.
11248  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
11249  *  \throw If \a a1->getNumberOfComponents() != 1 or \a a2->getNumberOfComponents() != 1.
11250  *  \throw If there is a negative value in \a a2.
11251  */
11252 DataArrayInt *DataArrayInt::Pow(const DataArrayInt *a1, const DataArrayInt *a2)
11253 {
11254   if(!a1 || !a2)
11255     throw INTERP_KERNEL::Exception("DataArrayInt::Pow : at least one of input instances is null !");
11256   int nbOfTuple=a1->getNumberOfTuples();
11257   int nbOfTuple2=a2->getNumberOfTuples();
11258   int nbOfComp=a1->getNumberOfComponents();
11259   int nbOfComp2=a2->getNumberOfComponents();
11260   if(nbOfTuple!=nbOfTuple2)
11261     throw INTERP_KERNEL::Exception("DataArrayInt::Pow : number of tuples mismatches !");
11262   if(nbOfComp!=1 || nbOfComp2!=1)
11263     throw INTERP_KERNEL::Exception("DataArrayInt::Pow : number of components of both arrays must be equal to 1 !");
11264   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbOfTuple,1);
11265   const int *ptr1(a1->begin()),*ptr2(a2->begin());
11266   int *ptr=ret->getPointer();
11267   for(int i=0;i<nbOfTuple;i++,ptr1++,ptr2++,ptr++)
11268     {
11269       if(*ptr2>=0)
11270         {
11271           int tmp=1;
11272           for(int j=0;j<*ptr2;j++)
11273             tmp*=*ptr1;
11274           *ptr=tmp;
11275         }
11276       else
11277         {
11278           std::ostringstream oss; oss << "DataArrayInt::Pow : on tuple #" << i << " of a2 value is < 0 (" << *ptr2 << ") !";
11279           throw INTERP_KERNEL::Exception(oss.str().c_str());
11280         }
11281     }
11282   return ret.retn();
11283 }
11284
11285 /*!
11286  * Apply pow on values of another DataArrayInt to values of \a this one.
11287  *
11288  *  \param [in] other - an array to pow to \a this one.
11289  *  \throw If \a other is NULL.
11290  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples()
11291  *  \throw If \a this->getNumberOfComponents() != 1 or \a other->getNumberOfComponents() != 1
11292  *  \throw If there is a negative value in \a other.
11293  */
11294 void DataArrayInt::powEqual(const DataArrayInt *other)
11295 {
11296   if(!other)
11297     throw INTERP_KERNEL::Exception("DataArrayInt::powEqual : input instance is null !");
11298   int nbOfTuple=getNumberOfTuples();
11299   int nbOfTuple2=other->getNumberOfTuples();
11300   int nbOfComp=getNumberOfComponents();
11301   int nbOfComp2=other->getNumberOfComponents();
11302   if(nbOfTuple!=nbOfTuple2)
11303     throw INTERP_KERNEL::Exception("DataArrayInt::powEqual : number of tuples mismatches !");
11304   if(nbOfComp!=1 || nbOfComp2!=1)
11305     throw INTERP_KERNEL::Exception("DataArrayInt::powEqual : number of components of both arrays must be equal to 1 !");
11306   int *ptr=getPointer();
11307   const int *ptrc=other->begin();
11308   for(int i=0;i<nbOfTuple;i++,ptrc++,ptr++)
11309     {
11310       if(*ptrc>=0)
11311         {
11312           int tmp=1;
11313           for(int j=0;j<*ptrc;j++)
11314             tmp*=*ptr;
11315           *ptr=tmp;
11316         }
11317       else
11318         {
11319           std::ostringstream oss; oss << "DataArrayInt::powEqual : on tuple #" << i << " of other value is < 0 (" << *ptrc << ") !";
11320           throw INTERP_KERNEL::Exception(oss.str().c_str());
11321         }
11322     }
11323   declareAsNew();
11324 }
11325
11326 /*!
11327  * Returns a C array which is a renumbering map in "Old to New" mode for the input array.
11328  * This map, if applied to \a start array, would make it sorted. For example, if
11329  * \a start array contents are [9,10,0,6,4,11,3,7] then the contents of the result array is
11330  * [5,6,0,3,2,7,1,4].
11331  *  \param [in] start - pointer to the first element of the array for which the
11332  *         permutation map is computed.
11333  *  \param [in] end - pointer specifying the end of the array \a start, so that
11334  *         the last value of \a start is \a end[ -1 ].
11335  *  \return int * - the result permutation array that the caller is to delete as it is no
11336  *         more needed.
11337  *  \throw If there are equal values in the input array.
11338  */
11339 int *DataArrayInt::CheckAndPreparePermutation(const int *start, const int *end)
11340 {
11341   std::size_t sz=std::distance(start,end);
11342   int *ret=(int *)malloc(sz*sizeof(int));
11343   int *work=new int[sz];
11344   std::copy(start,end,work);
11345   std::sort(work,work+sz);
11346   if(std::unique(work,work+sz)!=work+sz)
11347     {
11348       delete [] work;
11349       free(ret);
11350       throw INTERP_KERNEL::Exception("Some elements are equals in the specified array !");
11351     }
11352   std::map<int,int> m;
11353   for(int *workPt=work;workPt!=work+sz;workPt++)
11354     m[*workPt]=(int)std::distance(work,workPt);
11355   int *iter2=ret;
11356   for(const int *iter=start;iter!=end;iter++,iter2++)
11357     *iter2=m[*iter];
11358   delete [] work;
11359   return ret;
11360 }
11361
11362 /*!
11363  * Returns a new DataArrayInt containing an arithmetic progression
11364  * that is equal to the sequence returned by Python \c range(\a begin,\a  end,\a  step )
11365  * function.
11366  *  \param [in] begin - the start value of the result sequence.
11367  *  \param [in] end - limiting value, so that every value of the result array is less than
11368  *              \a end.
11369  *  \param [in] step - specifies the increment or decrement.
11370  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
11371  *          array using decrRef() as it is no more needed.
11372  *  \throw If \a step == 0.
11373  *  \throw If \a end < \a begin && \a step > 0.
11374  *  \throw If \a end > \a begin && \a step < 0.
11375  */
11376 DataArrayInt *DataArrayInt::Range(int begin, int end, int step)
11377 {
11378   int nbOfTuples=GetNumberOfItemGivenBESRelative(begin,end,step,"DataArrayInt::Range");
11379   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
11380   ret->alloc(nbOfTuples,1);
11381   int *ptr=ret->getPointer();
11382   if(step>0)
11383     {
11384       for(int i=begin;i<end;i+=step,ptr++)
11385         *ptr=i;
11386     }
11387   else
11388     {
11389       for(int i=begin;i>end;i+=step,ptr++)
11390         *ptr=i;
11391     }
11392   return ret.retn();
11393 }
11394
11395 /*!
11396  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
11397  * Server side.
11398  */
11399 void DataArrayInt::getTinySerializationIntInformation(std::vector<int>& tinyInfo) const
11400 {
11401   tinyInfo.resize(2);
11402   if(isAllocated())
11403     {
11404       tinyInfo[0]=getNumberOfTuples();
11405       tinyInfo[1]=getNumberOfComponents();
11406     }
11407   else
11408     {
11409       tinyInfo[0]=-1;
11410       tinyInfo[1]=-1;
11411     }
11412 }
11413
11414 /*!
11415  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
11416  * Server side.
11417  */
11418 void DataArrayInt::getTinySerializationStrInformation(std::vector<std::string>& tinyInfo) const
11419 {
11420   if(isAllocated())
11421     {
11422       int nbOfCompo=getNumberOfComponents();
11423       tinyInfo.resize(nbOfCompo+1);
11424       tinyInfo[0]=getName();
11425       for(int i=0;i<nbOfCompo;i++)
11426         tinyInfo[i+1]=getInfoOnComponent(i);
11427     }
11428   else
11429     {
11430       tinyInfo.resize(1);
11431       tinyInfo[0]=getName();
11432     }
11433 }
11434
11435 /*!
11436  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
11437  * This method returns if a feeding is needed.
11438  */
11439 bool DataArrayInt::resizeForUnserialization(const std::vector<int>& tinyInfoI)
11440 {
11441   int nbOfTuple=tinyInfoI[0];
11442   int nbOfComp=tinyInfoI[1];
11443   if(nbOfTuple!=-1 || nbOfComp!=-1)
11444     {
11445       alloc(nbOfTuple,nbOfComp);
11446       return true;
11447     }
11448   return false;
11449 }
11450
11451 /*!
11452  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
11453  * This method returns if a feeding is needed.
11454  */
11455 void DataArrayInt::finishUnserialization(const std::vector<int>& tinyInfoI, const std::vector<std::string>& tinyInfoS)
11456 {
11457   setName(tinyInfoS[0]);
11458   if(isAllocated())
11459     {
11460       int nbOfCompo=tinyInfoI[1];
11461       for(int i=0;i<nbOfCompo;i++)
11462         setInfoOnComponent(i,tinyInfoS[i+1]);
11463     }
11464 }
11465
11466 DataArrayIntIterator::DataArrayIntIterator(DataArrayInt *da):_da(da),_pt(0),_tuple_id(0),_nb_comp(0),_nb_tuple(0)
11467 {
11468   if(_da)
11469     {
11470       _da->incrRef();
11471       if(_da->isAllocated())
11472         {
11473           _nb_comp=da->getNumberOfComponents();
11474           _nb_tuple=da->getNumberOfTuples();
11475           _pt=da->getPointer();
11476         }
11477     }
11478 }
11479
11480 DataArrayIntIterator::~DataArrayIntIterator()
11481 {
11482   if(_da)
11483     _da->decrRef();
11484 }
11485
11486 DataArrayIntTuple *DataArrayIntIterator::nextt()
11487 {
11488   if(_tuple_id<_nb_tuple)
11489     {
11490       _tuple_id++;
11491       DataArrayIntTuple *ret=new DataArrayIntTuple(_pt,_nb_comp);
11492       _pt+=_nb_comp;
11493       return ret;
11494     }
11495   else
11496     return 0;
11497 }
11498
11499 DataArrayIntTuple::DataArrayIntTuple(int *pt, int nbOfComp):_pt(pt),_nb_of_compo(nbOfComp)
11500 {
11501 }
11502
11503 std::string DataArrayIntTuple::repr() const
11504 {
11505   std::ostringstream oss; oss << "(";
11506   for(int i=0;i<_nb_of_compo-1;i++)
11507     oss << _pt[i] << ", ";
11508   oss << _pt[_nb_of_compo-1] << ")";
11509   return oss.str();
11510 }
11511
11512 int DataArrayIntTuple::intValue() const
11513 {
11514   if(_nb_of_compo==1)
11515     return *_pt;
11516   throw INTERP_KERNEL::Exception("DataArrayIntTuple::intValue : DataArrayIntTuple instance has not exactly 1 component -> Not possible to convert it into an integer !");
11517 }
11518
11519 /*!
11520  * This method returns a newly allocated instance the caller should dealed with by a ParaMEDMEM::DataArrayInt::decrRef.
11521  * This method performs \b no copy of data. The content is only referenced using ParaMEDMEM::DataArrayInt::useArray with ownership set to \b false.
11522  * 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
11523  * \b nbOfCompo=1 and \bnbOfTuples==this->_nb_of_elem.
11524  */
11525 DataArrayInt *DataArrayIntTuple::buildDAInt(int nbOfTuples, int nbOfCompo) const
11526 {
11527   if((_nb_of_compo==nbOfCompo && nbOfTuples==1) || (_nb_of_compo==nbOfTuples && nbOfCompo==1))
11528     {
11529       DataArrayInt *ret=DataArrayInt::New();
11530       ret->useExternalArrayWithRWAccess(_pt,nbOfTuples,nbOfCompo);
11531       return ret;
11532     }
11533   else
11534     {
11535       std::ostringstream oss; oss << "DataArrayIntTuple::buildDAInt : unable to build a requested DataArrayInt instance with nbofTuple=" << nbOfTuples << " and nbOfCompo=" << nbOfCompo;
11536       oss << ".\nBecause the number of elements in this is " << _nb_of_compo << " !";
11537       throw INTERP_KERNEL::Exception(oss.str().c_str());
11538     }
11539 }