Salome HOME
Warning hunting.
[tools/medcoupling.git] / src / MEDCoupling / MEDCouplingMemArray.cxx
1 // Copyright (C) 2007-2013  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.
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::getDirectChildren() 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 char *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]).c_str());
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).c_str());
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 char *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  * Returns a new DataArray by concatenating all given arrays, so that (1) the number
427  * of tuples in the result array is a sum of the number of tuples of given arrays and (2)
428  * the number of component in the result array is same as that of each of given arrays.
429  * Info on components is copied from the first of the given arrays. Number of components
430  * in the given arrays must be  the same.
431  *  \param [in] arrs - a sequence of arrays to include in the result array. All arrays must have the same type.
432  *  \return DataArray * - the new instance of DataArray (that can be either DataArrayInt, DataArrayDouble, DataArrayChar).
433  *          The caller is to delete this result array using decrRef() as it is no more
434  *          needed.
435  *  \throw If all arrays within \a arrs are NULL.
436  *  \throw If all not null arrays in \a arrs have not the same type.
437  *  \throw If getNumberOfComponents() of arrays within \a arrs.
438  */
439 DataArray *DataArray::Aggregate(const std::vector<const DataArray *>& arrs)
440 {
441   std::vector<const DataArray *> arr2;
442   for(std::vector<const DataArray *>::const_iterator it=arrs.begin();it!=arrs.end();it++)
443     if(*it)
444       arr2.push_back(*it);
445   if(arr2.empty())
446     throw INTERP_KERNEL::Exception("DataArray::Aggregate : only null instance in input vector !");
447   std::vector<const DataArrayDouble *> arrd;
448   std::vector<const DataArrayInt *> arri;
449   std::vector<const DataArrayChar *> arrc;
450   for(std::vector<const DataArray *>::const_iterator it=arr2.begin();it!=arr2.end();it++)
451     {
452       const DataArrayDouble *a=dynamic_cast<const DataArrayDouble *>(*it);
453       if(a)
454         { arrd.push_back(a); continue; }
455       const DataArrayInt *b=dynamic_cast<const DataArrayInt *>(*it);
456       if(b)
457         { arri.push_back(b); continue; }
458       const DataArrayChar *c=dynamic_cast<const DataArrayChar *>(*it);
459       if(c)
460         { arrc.push_back(c); continue; }
461       throw INTERP_KERNEL::Exception("DataArray::Aggregate : presence of not null instance in inuput that is not in [DataArrayDouble, DataArrayInt, DataArrayChar] !");
462     }
463   if(arr2.size()==arrd.size())
464     return DataArrayDouble::Aggregate(arrd);
465   if(arr2.size()==arri.size())
466     return DataArrayInt::Aggregate(arri);
467   if(arr2.size()==arrc.size())
468     return DataArrayChar::Aggregate(arrc);
469   throw INTERP_KERNEL::Exception("DataArray::Aggregate : all input arrays must have the same type !");
470 }
471
472 /*!
473  * Sets information on a component specified by an index.
474  * To know more on format of this information
475  * see \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
476  *  \warning Don't pass NULL as \a info!
477  *  \param [in] i - the index (zero based) of the component of interest.
478  *  \param [in] info - the string containing the information.
479  *  \throw If \a i is not a valid component index.
480  */
481 void DataArray::setInfoOnComponent(int i, const char *info)
482 {
483   if(i<(int)_info_on_compo.size() && i>=0)
484     _info_on_compo[i]=info;
485   else
486     {
487       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();
488       throw INTERP_KERNEL::Exception(oss.str().c_str());
489     }
490 }
491
492 /*!
493  * Sets information on all components. This method can change number of components
494  * at certain conditions; if the conditions are not respected, an exception is thrown.
495  * The number of components can be changed in \a this only if \a this is not allocated.
496  * The condition of number of components must not be changed.
497  *
498  * To know more on format of the component information see
499  * \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
500  *  \param [in] info - a vector of component infos.
501  *  \throw If \a this->getNumberOfComponents() != \a info.size() && \a this->isAllocated()
502  */
503 void DataArray::setInfoAndChangeNbOfCompo(const std::vector<std::string>& info)
504 {
505   if(getNumberOfComponents()!=(int)info.size())
506     {
507       if(!isAllocated())
508         _info_on_compo=info;
509       else
510         {
511           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 !";
512           throw INTERP_KERNEL::Exception(oss.str().c_str());
513         }
514     }
515   else
516     _info_on_compo=info;
517 }
518
519 void DataArray::checkNbOfTuples(int nbOfTuples, const char *msg) const
520 {
521   if(getNumberOfTuples()!=nbOfTuples)
522     {
523       std::ostringstream oss; oss << msg << " : mismatch number of tuples : expected " <<  nbOfTuples << " having " << getNumberOfTuples() << " !";
524       throw INTERP_KERNEL::Exception(oss.str().c_str());
525     }
526 }
527
528 void DataArray::checkNbOfComps(int nbOfCompo, const char *msg) const
529 {
530   if(getNumberOfComponents()!=nbOfCompo)
531     {
532       std::ostringstream oss; oss << msg << " : mismatch number of components : expected " << nbOfCompo << " having " << getNumberOfComponents() << " !";
533       throw INTERP_KERNEL::Exception(oss.str().c_str());
534     }
535 }
536
537 void DataArray::checkNbOfElems(std::size_t nbOfElems, const char *msg) const
538 {
539   if(getNbOfElems()!=nbOfElems)
540     {
541       std::ostringstream oss; oss << msg << " : mismatch number of elems : Expected " << nbOfElems << " having " << getNbOfElems() << " !";
542       throw INTERP_KERNEL::Exception(oss.str().c_str());
543     }
544 }
545
546 void DataArray::checkNbOfTuplesAndComp(const DataArray& other, const char *msg) const
547 {
548    if(getNumberOfTuples()!=other.getNumberOfTuples())
549     {
550       std::ostringstream oss; oss << msg << " : mismatch number of tuples : expected " <<  other.getNumberOfTuples() << " having " << getNumberOfTuples() << " !";
551       throw INTERP_KERNEL::Exception(oss.str().c_str());
552     }
553   if(getNumberOfComponents()!=other.getNumberOfComponents())
554     {
555       std::ostringstream oss; oss << msg << " : mismatch number of components : expected " << other.getNumberOfComponents() << " having " << getNumberOfComponents() << " !";
556       throw INTERP_KERNEL::Exception(oss.str().c_str());
557     }
558 }
559
560 void DataArray::checkNbOfTuplesAndComp(int nbOfTuples, int nbOfCompo, const char *msg) const
561 {
562   checkNbOfTuples(nbOfTuples,msg);
563   checkNbOfComps(nbOfCompo,msg);
564 }
565
566 /*!
567  * Simply this method checks that \b value is in [0,\b ref).
568  */
569 void DataArray::CheckValueInRange(int ref, int value, const char *msg)
570 {
571   if(value<0 || value>=ref)
572     {
573       std::ostringstream oss; oss << "DataArray::CheckValueInRange : " << msg  << " ! Expected in range [0," << ref << "[ having " << value << " !";
574       throw INTERP_KERNEL::Exception(oss.str().c_str());
575     }
576 }
577
578 /*!
579  * This method checks that [\b start, \b end) is compliant with ref length \b value.
580  * typicaly start in [0,\b value) and end in [0,\b value). If value==start and start==end, it is supported.
581  */
582 void DataArray::CheckValueInRangeEx(int value, int start, int end, const char *msg)
583 {
584   if(start<0 || start>=value)
585     {
586       if(value!=start || end!=start)
587         {
588           std::ostringstream oss; oss << "DataArray::CheckValueInRangeEx : " << msg  << " ! Expected start " << start << " of input range, in [0," << value << "[ !";
589           throw INTERP_KERNEL::Exception(oss.str().c_str());
590         }
591     }
592   if(end<0 || end>value)
593     {
594       std::ostringstream oss; oss << "DataArray::CheckValueInRangeEx : " << msg  << " ! Expected end " << end << " of input range, in [0," << value << "] !";
595       throw INTERP_KERNEL::Exception(oss.str().c_str());
596     }
597 }
598
599 void DataArray::CheckClosingParInRange(int ref, int value, const char *msg)
600 {
601   if(value<0 || value>ref)
602     {
603       std::ostringstream oss; oss << "DataArray::CheckClosingParInRange : " << msg  << " ! Expected input range in [0," << ref << "] having closing open parenthesis " << value << " !";
604       throw INTERP_KERNEL::Exception(oss.str().c_str());
605     }
606 }
607
608 /*!
609  * 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, 
610  * typically it is a whole slice of tuples of DataArray or cells, nodes of a mesh...
611  *
612  * The input \a sliceId should be an id in [0, \a nbOfSlices) that specifies the slice of work.
613  *
614  * \param [in] start - the start of the input slice of the whole work to perform splitted into slices.
615  * \param [in] stop - the stop of the input slice of the whole work to perform splitted into slices.
616  * \param [in] step - the step (that can be <0) of the input slice of the whole work to perform splitted into slices.
617  * \param [in] sliceId - the slice id considered
618  * \param [in] nbOfSlices - the number of slices (typically the number of cores on which the work is expected to be sliced)
619  * \param [out] startSlice - the start of the slice considered
620  * \param [out] stopSlice - the stop of the slice consided
621  * 
622  * \throw If \a step == 0
623  * \throw If \a nbOfSlices not > 0
624  * \throw If \a sliceId not in [0,nbOfSlices)
625  */
626 void DataArray::GetSlice(int start, int stop, int step, int sliceId, int nbOfSlices, int& startSlice, int& stopSlice)
627 {
628   if(nbOfSlices<=0)
629     {
630       std::ostringstream oss; oss << "DataArray::GetSlice : nbOfSlices (" << nbOfSlices << ") must be > 0 !";
631       throw INTERP_KERNEL::Exception(oss.str().c_str());
632     }
633   if(sliceId<0 || sliceId>=nbOfSlices)
634     {
635       std::ostringstream oss; oss << "DataArray::GetSlice : sliceId (" << nbOfSlices << ") must be in [0 , nbOfSlices (" << nbOfSlices << ") ) !";
636       throw INTERP_KERNEL::Exception(oss.str().c_str());
637     }
638   int nbElems=GetNumberOfItemGivenBESRelative(start,stop,step,"DataArray::GetSlice");
639   int minNbOfElemsPerSlice=nbElems/nbOfSlices;
640   startSlice=start+minNbOfElemsPerSlice*step*sliceId;
641   if(sliceId<nbOfSlices-1)
642     stopSlice=start+minNbOfElemsPerSlice*step*(sliceId+1);
643   else
644     stopSlice=stop;
645 }
646
647 int DataArray::GetNumberOfItemGivenBES(int begin, int end, int step, const char *msg)
648 {
649   if(end<begin)
650     {
651       std::ostringstream oss; oss << msg << " : end before begin !";
652       throw INTERP_KERNEL::Exception(oss.str().c_str());
653     }
654   if(end==begin)
655     return 0;
656   if(step<=0)
657     {
658       std::ostringstream oss; oss << msg << " : invalid step should be > 0 !";
659       throw INTERP_KERNEL::Exception(oss.str().c_str());
660     }
661   return (end-1-begin)/step+1;
662 }
663
664 int DataArray::GetNumberOfItemGivenBESRelative(int begin, int end, int step, const char *msg)
665 {
666   if(step==0)
667     throw INTERP_KERNEL::Exception("DataArray::GetNumberOfItemGivenBES : step=0 is not allowed !");
668   if(end<begin && step>0)
669     {
670       std::ostringstream oss; oss << msg << " : end before begin whereas step is positive !";
671       throw INTERP_KERNEL::Exception(oss.str().c_str());
672     }
673   if(begin<end && step<0)
674     {
675       std::ostringstream oss; oss << msg << " : invalid step should be > 0 !";
676       throw INTERP_KERNEL::Exception(oss.str().c_str());
677     }
678   if(begin!=end)
679     return (std::max(begin,end)-1-std::min(begin,end))/std::abs(step)+1;
680   else
681     return 0;
682 }
683
684 int DataArray::GetPosOfItemGivenBESRelativeNoThrow(int value, int begin, int end, int step)
685 {
686   if(step!=0)
687     {
688       if(step>0)
689         {
690           if(begin<=value && value<end)
691             {
692               if((value-begin)%step==0)
693                 return (value-begin)/step;
694               else
695                 return -1;
696             }
697           else
698             return -1;
699         }
700       else
701         {
702           if(begin>=value && value>end)
703             {
704               if((begin-value)%(-step)==0)
705                 return (begin-value)/(-step);
706               else
707                 return -1;
708             }
709           else
710             return -1;
711         }
712     }
713   else
714     return -1;
715 }
716
717 /*!
718  * Returns a new instance of DataArrayDouble. The caller is to delete this array
719  * using decrRef() as it is no more needed. 
720  */
721 DataArrayDouble *DataArrayDouble::New()
722 {
723   return new DataArrayDouble;
724 }
725
726 /*!
727  * Checks if raw data is allocated. Read more on the raw data
728  * in \ref MEDCouplingArrayBasicsTuplesAndCompo "DataArrays infos" for more information.
729  *  \return bool - \a true if the raw data is allocated, \a false else.
730  */
731 bool DataArrayDouble::isAllocated() const
732 {
733   return getConstPointer()!=0;
734 }
735
736 /*!
737  * Checks if raw data is allocated and throws an exception if it is not the case.
738  *  \throw If the raw data is not allocated.
739  */
740 void DataArrayDouble::checkAllocated() const
741 {
742   if(!isAllocated())
743     throw INTERP_KERNEL::Exception("DataArrayDouble::checkAllocated : Array is defined but not allocated ! Call alloc or setValues method first !");
744 }
745
746 /*!
747  * This method desallocated \a this without modification of informations relative to the components.
748  * After call of this method, DataArrayDouble::isAllocated will return false.
749  * If \a this is already not allocated, \a this is let unchanged.
750  */
751 void DataArrayDouble::desallocate()
752 {
753   _mem.destroy();
754 }
755
756 std::size_t DataArrayDouble::getHeapMemorySizeWithoutChildren() const
757 {
758   std::size_t sz(_mem.getNbOfElemAllocated());
759   sz*=sizeof(double);
760   return DataArray::getHeapMemorySizeWithoutChildren()+sz;
761 }
762
763 /*!
764  * Returns the only one value in \a this, if and only if number of elements
765  * (nb of tuples * nb of components) is equal to 1, and that \a this is allocated.
766  *  \return double - the sole value stored in \a this array.
767  *  \throw If at least one of conditions stated above is not fulfilled.
768  */
769 double DataArrayDouble::doubleValue() const
770 {
771   if(isAllocated())
772     {
773       if(getNbOfElems()==1)
774         {
775           return *getConstPointer();
776         }
777       else
778         throw INTERP_KERNEL::Exception("DataArrayDouble::doubleValue : DataArrayDouble instance is allocated but number of elements is not equal to 1 !");
779     }
780   else
781     throw INTERP_KERNEL::Exception("DataArrayDouble::doubleValue : DataArrayDouble instance is not allocated !");
782 }
783
784 /*!
785  * Checks the number of tuples.
786  *  \return bool - \a true if getNumberOfTuples() == 0, \a false else.
787  *  \throw If \a this is not allocated.
788  */
789 bool DataArrayDouble::empty() const
790 {
791   checkAllocated();
792   return getNumberOfTuples()==0;
793 }
794
795 /*!
796  * Returns a full copy of \a this. For more info on copying data arrays see
797  * \ref MEDCouplingArrayBasicsCopyDeep.
798  *  \return DataArrayDouble * - a new instance of DataArrayDouble. The caller is to
799  *          delete this array using decrRef() as it is no more needed. 
800  */
801 DataArrayDouble *DataArrayDouble::deepCpy() const
802 {
803   return new DataArrayDouble(*this);
804 }
805
806 /*!
807  * Returns either a \a deep or \a shallow copy of this array. For more info see
808  * \ref MEDCouplingArrayBasicsCopyDeep and \ref MEDCouplingArrayBasicsCopyShallow.
809  *  \param [in] dCpy - if \a true, a deep copy is returned, else, a shallow one.
810  *  \return DataArrayDouble * - either a new instance of DataArrayDouble (if \a dCpy
811  *          == \a true) or \a this instance (if \a dCpy == \a false).
812  */
813 DataArrayDouble *DataArrayDouble::performCpy(bool dCpy) const
814 {
815   if(dCpy)
816     return deepCpy();
817   else
818     {
819       incrRef();
820       return const_cast<DataArrayDouble *>(this);
821     }
822 }
823
824 /*!
825  * Copies all the data from another DataArrayDouble. For more info see
826  * \ref MEDCouplingArrayBasicsCopyDeepAssign.
827  *  \param [in] other - another instance of DataArrayDouble to copy data from.
828  *  \throw If the \a other is not allocated.
829  */
830 void DataArrayDouble::cpyFrom(const DataArrayDouble& other)
831 {
832   other.checkAllocated();
833   int nbOfTuples=other.getNumberOfTuples();
834   int nbOfComp=other.getNumberOfComponents();
835   allocIfNecessary(nbOfTuples,nbOfComp);
836   std::size_t nbOfElems=(std::size_t)nbOfTuples*nbOfComp;
837   double *pt=getPointer();
838   const double *ptI=other.getConstPointer();
839   for(std::size_t i=0;i<nbOfElems;i++)
840     pt[i]=ptI[i];
841   copyStringInfoFrom(other);
842 }
843
844 /*!
845  * This method reserve nbOfElems elements in memory ( nbOfElems*8 bytes ) \b without impacting the number of tuples in \a this.
846  * 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.
847  * If \a this has not already been allocated, number of components is set to one.
848  * This method allows to reduce number of reallocations on invokation of DataArrayDouble::pushBackSilent and DataArrayDouble::pushBackValsSilent on \a this.
849  * 
850  * \sa DataArrayDouble::pack, DataArrayDouble::pushBackSilent, DataArrayDouble::pushBackValsSilent
851  */
852 void DataArrayDouble::reserve(std::size_t nbOfElems)
853 {
854   int nbCompo=getNumberOfComponents();
855   if(nbCompo==1)
856     {
857       _mem.reserve(nbOfElems);
858     }
859   else if(nbCompo==0)
860     {
861       _mem.reserve(nbOfElems);
862       _info_on_compo.resize(1);
863     }
864   else
865     throw INTERP_KERNEL::Exception("DataArrayDouble::reserve : not available for DataArrayDouble with number of components different than 1 !");
866 }
867
868 /*!
869  * 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
870  * of counter. So the caller is expected to call TimeLabel::declareAsNew on \a this at the end of the push session.
871  *
872  * \param [in] val the value to be added in \a this
873  * \throw If \a this has already been allocated with number of components different from one.
874  * \sa DataArrayDouble::pushBackValsSilent
875  */
876 void DataArrayDouble::pushBackSilent(double val)
877 {
878   int nbCompo=getNumberOfComponents();
879   if(nbCompo==1)
880     _mem.pushBack(val);
881   else if(nbCompo==0)
882     {
883       _info_on_compo.resize(1);
884       _mem.pushBack(val);
885     }
886   else
887     throw INTERP_KERNEL::Exception("DataArrayDouble::pushBackSilent : not available for DataArrayDouble with number of components different than 1 !");
888 }
889
890 /*!
891  * 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
892  * of counter. So the caller is expected to call TimeLabel::declareAsNew on \a this at the end of the push session.
893  *
894  *  \param [in] valsBg - an array of values to push at the end of \this.
895  *  \param [in] valsEnd - specifies the end of the array \a valsBg, so that
896  *              the last value of \a valsBg is \a valsEnd[ -1 ].
897  * \throw If \a this has already been allocated with number of components different from one.
898  * \sa DataArrayDouble::pushBackSilent
899  */
900 void DataArrayDouble::pushBackValsSilent(const double *valsBg, const double *valsEnd)
901 {
902   int nbCompo=getNumberOfComponents();
903   if(nbCompo==1)
904     _mem.insertAtTheEnd(valsBg,valsEnd);
905   else if(nbCompo==0)
906     {
907       _info_on_compo.resize(1);
908       _mem.insertAtTheEnd(valsBg,valsEnd);
909     }
910   else
911     throw INTERP_KERNEL::Exception("DataArrayDouble::pushBackValsSilent : not available for DataArrayDouble with number of components different than 1 !");
912 }
913
914 /*!
915  * This method returns silently ( without updating time label in \a this ) the last value, if any and suppress it.
916  * \throw If \a this is already empty.
917  * \throw If \a this has number of components different from one.
918  */
919 double DataArrayDouble::popBackSilent()
920 {
921   if(getNumberOfComponents()==1)
922     return _mem.popBack();
923   else
924     throw INTERP_KERNEL::Exception("DataArrayDouble::popBackSilent : not available for DataArrayDouble with number of components different than 1 !");
925 }
926
927 /*!
928  * 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.
929  *
930  * \sa DataArrayDouble::getHeapMemorySizeWithoutChildren, DataArrayDouble::reserve
931  */
932 void DataArrayDouble::pack() const
933 {
934   _mem.pack();
935 }
936
937 /*!
938  * Allocates the raw data in memory. If exactly same memory as needed already
939  * allocated, it is not re-allocated.
940  *  \param [in] nbOfTuple - number of tuples of data to allocate.
941  *  \param [in] nbOfCompo - number of components of data to allocate.
942  *  \throw If \a nbOfTuple < 0 or \a nbOfCompo < 0.
943  */
944 void DataArrayDouble::allocIfNecessary(int nbOfTuple, int nbOfCompo)
945 {
946   if(isAllocated())
947     {
948       if(nbOfTuple!=getNumberOfTuples() || nbOfCompo!=getNumberOfComponents())
949         alloc(nbOfTuple,nbOfCompo);
950     }
951   else
952     alloc(nbOfTuple,nbOfCompo);
953 }
954
955 /*!
956  * Allocates the raw data in memory. If the memory was already allocated, then it is
957  * freed and re-allocated. See an example of this method use
958  * \ref MEDCouplingArraySteps1WC "here".
959  *  \param [in] nbOfTuple - number of tuples of data to allocate.
960  *  \param [in] nbOfCompo - number of components of data to allocate.
961  *  \throw If \a nbOfTuple < 0 or \a nbOfCompo < 0.
962  */
963 void DataArrayDouble::alloc(int nbOfTuple, int nbOfCompo)
964 {
965   if(nbOfTuple<0 || nbOfCompo<0)
966     throw INTERP_KERNEL::Exception("DataArrayDouble::alloc : request for negative length of data !");
967   _info_on_compo.resize(nbOfCompo);
968   _mem.alloc(nbOfCompo*(std::size_t)nbOfTuple);
969   declareAsNew();
970 }
971
972 /*!
973  * Assign zero to all values in \a this array. To know more on filling arrays see
974  * \ref MEDCouplingArrayFill.
975  * \throw If \a this is not allocated.
976  */
977 void DataArrayDouble::fillWithZero()
978 {
979   checkAllocated();
980   _mem.fillWithValue(0.);
981   declareAsNew();
982 }
983
984 /*!
985  * Assign \a val to all values in \a this array. To know more on filling arrays see
986  * \ref MEDCouplingArrayFill.
987  *  \param [in] val - the value to fill with.
988  *  \throw If \a this is not allocated.
989  */
990 void DataArrayDouble::fillWithValue(double val)
991 {
992   checkAllocated();
993   _mem.fillWithValue(val);
994   declareAsNew();
995 }
996
997 /*!
998  * Set all values in \a this array so that the i-th element equals to \a init + i
999  * (i starts from zero). To know more on filling arrays see \ref MEDCouplingArrayFill.
1000  *  \param [in] init - value to assign to the first element of array.
1001  *  \throw If \a this->getNumberOfComponents() != 1
1002  *  \throw If \a this is not allocated.
1003  */
1004 void DataArrayDouble::iota(double init)
1005 {
1006   checkAllocated();
1007   if(getNumberOfComponents()!=1)
1008     throw INTERP_KERNEL::Exception("DataArrayDouble::iota : works only for arrays with only one component, you can call 'rearrange' method before !");
1009   double *ptr=getPointer();
1010   int ntuples=getNumberOfTuples();
1011   for(int i=0;i<ntuples;i++)
1012     ptr[i]=init+double(i);
1013   declareAsNew();
1014 }
1015
1016 /*!
1017  * Checks if all values in \a this array are equal to \a val at precision \a eps.
1018  *  \param [in] val - value to check equality of array values to.
1019  *  \param [in] eps - precision to check the equality.
1020  *  \return bool - \a true if all values are in range (_val_ - _eps_; _val_ + _eps_),
1021  *                 \a false else.
1022  *  \throw If \a this->getNumberOfComponents() != 1
1023  *  \throw If \a this is not allocated.
1024  */
1025 bool DataArrayDouble::isUniform(double val, double eps) const
1026 {
1027   checkAllocated();
1028   if(getNumberOfComponents()!=1)
1029     throw INTERP_KERNEL::Exception("DataArrayDouble::isUniform : must be applied on DataArrayDouble with only one component, you can call 'rearrange' method before !");
1030   int nbOfTuples=getNumberOfTuples();
1031   const double *w=getConstPointer();
1032   const double *end2=w+nbOfTuples;
1033   const double vmin=val-eps;
1034   const double vmax=val+eps;
1035   for(;w!=end2;w++)
1036     if(*w<vmin || *w>vmax)
1037       return false;
1038   return true;
1039 }
1040
1041 /*!
1042  * Sorts values of the array.
1043  *  \param [in] asc - \a true means ascending order, \a false, descending.
1044  *  \throw If \a this is not allocated.
1045  *  \throw If \a this->getNumberOfComponents() != 1.
1046  */
1047 void DataArrayDouble::sort(bool asc)
1048 {
1049   checkAllocated();
1050   if(getNumberOfComponents()!=1)
1051     throw INTERP_KERNEL::Exception("DataArrayDouble::sort : only supported with 'this' array with ONE component !");
1052   _mem.sort(asc);
1053   declareAsNew();
1054 }
1055
1056 /*!
1057  * Reverse the array values.
1058  *  \throw If \a this->getNumberOfComponents() < 1.
1059  *  \throw If \a this is not allocated.
1060  */
1061 void DataArrayDouble::reverse()
1062 {
1063   checkAllocated();
1064   _mem.reverse(getNumberOfComponents());
1065   declareAsNew();
1066 }
1067
1068 /*!
1069  * Checks that \a this array is consistently **increasing** or **decreasing** in value,
1070  * with at least absolute difference value of |\a eps| at each step.
1071  * If not an exception is thrown.
1072  *  \param [in] increasing - if \a true, the array values should be increasing.
1073  *  \param [in] eps - minimal absolute difference between the neighbor values at which 
1074  *                    the values are considered different.
1075  *  \throw If sequence of values is not strictly monotonic in agreement with \a
1076  *         increasing arg.
1077  *  \throw If \a this->getNumberOfComponents() != 1.
1078  *  \throw If \a this is not allocated.
1079  */
1080 void DataArrayDouble::checkMonotonic(bool increasing, double eps) const
1081 {
1082   if(!isMonotonic(increasing,eps))
1083     {
1084       if (increasing)
1085         throw INTERP_KERNEL::Exception("DataArrayDouble::checkMonotonic : 'this' is not INCREASING monotonic !");
1086       else
1087         throw INTERP_KERNEL::Exception("DataArrayDouble::checkMonotonic : 'this' is not DECREASING monotonic !");
1088     }
1089 }
1090
1091 /*!
1092  * Checks that \a this array is consistently **increasing** or **decreasing** in value,
1093  * with at least absolute difference value of |\a eps| at each step.
1094  *  \param [in] increasing - if \a true, array values should be increasing.
1095  *  \param [in] eps - minimal absolute difference between the neighbor values at which 
1096  *                    the values are considered different.
1097  *  \return bool - \a true if values change in accordance with \a increasing arg.
1098  *  \throw If \a this->getNumberOfComponents() != 1.
1099  *  \throw If \a this is not allocated.
1100  */
1101 bool DataArrayDouble::isMonotonic(bool increasing, double eps) const
1102 {
1103   checkAllocated();
1104   if(getNumberOfComponents()!=1)
1105     throw INTERP_KERNEL::Exception("DataArrayDouble::isMonotonic : only supported with 'this' array with ONE component !");
1106   int nbOfElements=getNumberOfTuples();
1107   const double *ptr=getConstPointer();
1108   if(nbOfElements==0)
1109     return true;
1110   double ref=ptr[0];
1111   double absEps=fabs(eps);
1112   if(increasing)
1113     {
1114       for(int i=1;i<nbOfElements;i++)
1115         {
1116           if(ptr[i]<(ref+absEps))
1117             return false;
1118           ref=ptr[i];
1119         }
1120       return true;
1121     }
1122   else
1123     {
1124       for(int i=1;i<nbOfElements;i++)
1125         {
1126           if(ptr[i]>(ref-absEps))
1127             return false;
1128           ref=ptr[i];
1129         }
1130       return true;
1131     }
1132 }
1133
1134 /*!
1135  * Returns a textual and human readable representation of \a this instance of
1136  * DataArrayDouble. This text is shown when a DataArrayDouble is printed in Python.
1137  *  \return std::string - text describing \a this DataArrayDouble.
1138  */
1139 std::string DataArrayDouble::repr() const
1140 {
1141   std::ostringstream ret;
1142   reprStream(ret);
1143   return ret.str();
1144 }
1145
1146 std::string DataArrayDouble::reprZip() const
1147 {
1148   std::ostringstream ret;
1149   reprZipStream(ret);
1150   return ret.str();
1151 }
1152
1153 void DataArrayDouble::writeVTK(std::ostream& ofs, int indent, const char *nameInFile, DataArrayByte *byteArr) const
1154 {
1155   static const char SPACE[4]={' ',' ',' ',' '};
1156   checkAllocated();
1157   std::string idt(indent,' ');
1158   ofs.precision(17);
1159   ofs << idt << "<DataArray type=\"Float32\" Name=\"" << nameInFile << "\" NumberOfComponents=\"" << getNumberOfComponents() << "\"";
1160   if(byteArr)
1161     {
1162       ofs << " format=\"appended\" offset=\"" << byteArr->getNumberOfTuples() << "\">";
1163       INTERP_KERNEL::AutoPtr<float> tmp(new float[getNbOfElems()]);
1164       float *pt(tmp);
1165       // to make Visual C++ happy : instead of std::copy(begin(),end(),(float *)tmp);
1166       for(const double *src=begin();src!=end();src++,pt++)
1167         *pt=float(*src);
1168       const char *data(reinterpret_cast<const char *>((float *)tmp));
1169       std::size_t sz(getNbOfElems()*sizeof(float));
1170       byteArr->insertAtTheEnd(data,data+sz);
1171       byteArr->insertAtTheEnd(SPACE,SPACE+4);
1172     }
1173   else
1174     {
1175       ofs << " RangeMin=\"" << getMinValueInArray() << "\" RangeMax=\"" << getMaxValueInArray() << "\" format=\"ascii\">\n" << idt;
1176       std::copy(begin(),end(),std::ostream_iterator<double>(ofs," "));
1177     }
1178   ofs << std::endl << idt << "</DataArray>\n";
1179 }
1180
1181 void DataArrayDouble::reprStream(std::ostream& stream) const
1182 {
1183   stream << "Name of double array : \"" << _name << "\"\n";
1184   reprWithoutNameStream(stream);
1185 }
1186
1187 void DataArrayDouble::reprZipStream(std::ostream& stream) const
1188 {
1189   stream << "Name of double array : \"" << _name << "\"\n";
1190   reprZipWithoutNameStream(stream);
1191 }
1192
1193 void DataArrayDouble::reprWithoutNameStream(std::ostream& stream) const
1194 {
1195   DataArray::reprWithoutNameStream(stream);
1196   stream.precision(17);
1197   _mem.repr(getNumberOfComponents(),stream);
1198 }
1199
1200 void DataArrayDouble::reprZipWithoutNameStream(std::ostream& stream) const
1201 {
1202   DataArray::reprWithoutNameStream(stream);
1203   stream.precision(17);
1204   _mem.reprZip(getNumberOfComponents(),stream);
1205 }
1206
1207 void DataArrayDouble::reprCppStream(const char *varName, std::ostream& stream) const
1208 {
1209   int nbTuples=getNumberOfTuples(),nbComp=getNumberOfComponents();
1210   const double *data=getConstPointer();
1211   stream.precision(17);
1212   stream << "DataArrayDouble *" << varName << "=DataArrayDouble::New();" << std::endl;
1213   if(nbTuples*nbComp>=1)
1214     {
1215       stream << "const double " << varName << "Data[" << nbTuples*nbComp << "]={";
1216       std::copy(data,data+nbTuples*nbComp-1,std::ostream_iterator<double>(stream,","));
1217       stream << data[nbTuples*nbComp-1] << "};" << std::endl;
1218       stream << varName << "->useArray(" << varName << "Data,false,CPP_DEALLOC," << nbTuples << "," << nbComp << ");" << std::endl;
1219     }
1220   else
1221     stream << varName << "->alloc(" << nbTuples << "," << nbComp << ");" << std::endl;
1222   stream << varName << "->setName(\"" << getName() << "\");" << std::endl;
1223 }
1224
1225 /*!
1226  * Method that gives a quick overvien of \a this for python.
1227  */
1228 void DataArrayDouble::reprQuickOverview(std::ostream& stream) const
1229 {
1230   static const std::size_t MAX_NB_OF_BYTE_IN_REPR=300;
1231   stream << "DataArrayDouble C++ instance at " << this << ". ";
1232   if(isAllocated())
1233     {
1234       int nbOfCompo=(int)_info_on_compo.size();
1235       if(nbOfCompo>=1)
1236         {
1237           int nbOfTuples=getNumberOfTuples();
1238           stream << "Number of tuples : " << nbOfTuples << ". Number of components : " << nbOfCompo << "." << std::endl;
1239           reprQuickOverviewData(stream,MAX_NB_OF_BYTE_IN_REPR);
1240         }
1241       else
1242         stream << "Number of components : 0.";
1243     }
1244   else
1245     stream << "*** No data allocated ****";
1246 }
1247
1248 void DataArrayDouble::reprQuickOverviewData(std::ostream& stream, std::size_t maxNbOfByteInRepr) const
1249 {
1250   const double *data=begin();
1251   int nbOfTuples=getNumberOfTuples();
1252   int nbOfCompo=(int)_info_on_compo.size();
1253   std::ostringstream oss2; oss2 << "[";
1254   oss2.precision(17);
1255   std::string oss2Str(oss2.str());
1256   bool isFinished=true;
1257   for(int i=0;i<nbOfTuples && isFinished;i++)
1258     {
1259       if(nbOfCompo>1)
1260         {
1261           oss2 << "(";
1262           for(int j=0;j<nbOfCompo;j++,data++)
1263             {
1264               oss2 << *data;
1265               if(j!=nbOfCompo-1) oss2 << ", ";
1266             }
1267           oss2 << ")";
1268         }
1269       else
1270         oss2 << *data++;
1271       if(i!=nbOfTuples-1) oss2 << ", ";
1272       std::string oss3Str(oss2.str());
1273       if(oss3Str.length()<maxNbOfByteInRepr)
1274         oss2Str=oss3Str;
1275       else
1276         isFinished=false;
1277     }
1278   stream << oss2Str;
1279   if(!isFinished)
1280     stream << "... ";
1281   stream << "]";
1282 }
1283
1284 /*!
1285  * Equivalent to DataArrayDouble::isEqual except that if false the reason of
1286  * mismatch is given.
1287  * 
1288  * \param [in] other the instance to be compared with \a this
1289  * \param [in] prec the precision to compare numeric data of the arrays.
1290  * \param [out] reason In case of inequality returns the reason.
1291  * \sa DataArrayDouble::isEqual
1292  */
1293 bool DataArrayDouble::isEqualIfNotWhy(const DataArrayDouble& other, double prec, std::string& reason) const
1294 {
1295   if(!areInfoEqualsIfNotWhy(other,reason))
1296     return false;
1297   return _mem.isEqual(other._mem,prec,reason);
1298 }
1299
1300 /*!
1301  * Checks if \a this and another DataArrayDouble are fully equal. For more info see
1302  * \ref MEDCouplingArrayBasicsCompare.
1303  *  \param [in] other - an instance of DataArrayDouble to compare with \a this one.
1304  *  \param [in] prec - precision value to compare numeric data of the arrays.
1305  *  \return bool - \a true if the two arrays are equal, \a false else.
1306  */
1307 bool DataArrayDouble::isEqual(const DataArrayDouble& other, double prec) const
1308 {
1309   std::string tmp;
1310   return isEqualIfNotWhy(other,prec,tmp);
1311 }
1312
1313 /*!
1314  * Checks if values of \a this and another DataArrayDouble are equal. For more info see
1315  * \ref MEDCouplingArrayBasicsCompare.
1316  *  \param [in] other - an instance of DataArrayDouble to compare with \a this one.
1317  *  \param [in] prec - precision value to compare numeric data of the arrays.
1318  *  \return bool - \a true if the values of two arrays are equal, \a false else.
1319  */
1320 bool DataArrayDouble::isEqualWithoutConsideringStr(const DataArrayDouble& other, double prec) const
1321 {
1322   std::string tmp;
1323   return _mem.isEqual(other._mem,prec,tmp);
1324 }
1325
1326 /*!
1327  * Changes number of tuples in the array. If the new number of tuples is smaller
1328  * than the current number the array is truncated, otherwise the array is extended.
1329  *  \param [in] nbOfTuples - new number of tuples. 
1330  *  \throw If \a this is not allocated.
1331  *  \throw If \a nbOfTuples is negative.
1332  */
1333 void DataArrayDouble::reAlloc(int nbOfTuples)
1334 {
1335   if(nbOfTuples<0)
1336     throw INTERP_KERNEL::Exception("DataArrayDouble::reAlloc : input new number of tuples should be >=0 !");
1337   checkAllocated();
1338   _mem.reAlloc(getNumberOfComponents()*(std::size_t)nbOfTuples);
1339   declareAsNew();
1340 }
1341
1342 /*!
1343  * Creates a new DataArrayInt and assigns all (textual and numerical) data of \a this
1344  * array to the new one.
1345  *  \return DataArrayInt * - the new instance of DataArrayInt.
1346  */
1347 DataArrayInt *DataArrayDouble::convertToIntArr() const
1348 {
1349   DataArrayInt *ret=DataArrayInt::New();
1350   ret->alloc(getNumberOfTuples(),getNumberOfComponents());
1351   int *dest=ret->getPointer();
1352   // to make Visual C++ happy : instead of std::size_t nbOfVals=getNbOfElems(); std::copy(src,src+nbOfVals,dest);
1353   for(const double *src=begin();src!=end();src++,dest++)
1354     *dest=(int)*src;
1355   ret->copyStringInfoFrom(*this);
1356   return ret;
1357 }
1358
1359 /*!
1360  * Returns a new DataArrayDouble holding the same values as \a this array but differently
1361  * arranged in memory. If \a this array holds 2 components of 3 values:
1362  * \f$ x_0,x_1,x_2,y_0,y_1,y_2 \f$, then the result array holds these values arranged
1363  * as follows: \f$ x_0,y_0,x_1,y_1,x_2,y_2 \f$.
1364  *  \warning Do not confuse this method with transpose()!
1365  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1366  *          is to delete using decrRef() as it is no more needed.
1367  *  \throw If \a this is not allocated.
1368  */
1369 DataArrayDouble *DataArrayDouble::fromNoInterlace() const
1370 {
1371   if(_mem.isNull())
1372     throw INTERP_KERNEL::Exception("DataArrayDouble::fromNoInterlace : Not defined array !");
1373   double *tab=_mem.fromNoInterlace(getNumberOfComponents());
1374   DataArrayDouble *ret=DataArrayDouble::New();
1375   ret->useArray(tab,true,C_DEALLOC,getNumberOfTuples(),getNumberOfComponents());
1376   return ret;
1377 }
1378
1379 /*!
1380  * Returns a new DataArrayDouble holding the same values as \a this array but differently
1381  * arranged in memory. If \a this array holds 2 components of 3 values:
1382  * \f$ x_0,y_0,x_1,y_1,x_2,y_2 \f$, then the result array holds these values arranged
1383  * as follows: \f$ x_0,x_1,x_2,y_0,y_1,y_2 \f$.
1384  *  \warning Do not confuse this method with transpose()!
1385  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1386  *          is to delete using decrRef() as it is no more needed.
1387  *  \throw If \a this is not allocated.
1388  */
1389 DataArrayDouble *DataArrayDouble::toNoInterlace() const
1390 {
1391   if(_mem.isNull())
1392     throw INTERP_KERNEL::Exception("DataArrayDouble::toNoInterlace : Not defined array !");
1393   double *tab=_mem.toNoInterlace(getNumberOfComponents());
1394   DataArrayDouble *ret=DataArrayDouble::New();
1395   ret->useArray(tab,true,C_DEALLOC,getNumberOfTuples(),getNumberOfComponents());
1396   return ret;
1397 }
1398
1399 /*!
1400  * Permutes values of \a this array as required by \a old2New array. The values are
1401  * permuted so that \c new[ \a old2New[ i ]] = \c old[ i ]. Number of tuples remains
1402  * the same as in \this one.
1403  * If a permutation reduction is needed, substr() or selectByTupleId() should be used.
1404  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
1405  *  \param [in] old2New - C array of length equal to \a this->getNumberOfTuples()
1406  *     giving a new position for i-th old value.
1407  */
1408 void DataArrayDouble::renumberInPlace(const int *old2New)
1409 {
1410   checkAllocated();
1411   int nbTuples=getNumberOfTuples();
1412   int nbOfCompo=getNumberOfComponents();
1413   double *tmp=new double[nbTuples*nbOfCompo];
1414   const double *iptr=getConstPointer();
1415   for(int i=0;i<nbTuples;i++)
1416     {
1417       int v=old2New[i];
1418       if(v>=0 && v<nbTuples)
1419         std::copy(iptr+nbOfCompo*i,iptr+nbOfCompo*(i+1),tmp+nbOfCompo*v);
1420       else
1421         {
1422           std::ostringstream oss; oss << "DataArrayDouble::renumberInPlace : At place #" << i << " value is " << v << " ! Should be in [0," << nbTuples << ") !";
1423           throw INTERP_KERNEL::Exception(oss.str().c_str());
1424         }
1425     }
1426   std::copy(tmp,tmp+nbTuples*nbOfCompo,getPointer());
1427   delete [] tmp;
1428   declareAsNew();
1429 }
1430
1431 /*!
1432  * Permutes values of \a this array as required by \a new2Old array. The values are
1433  * permuted so that \c new[ i ] = \c old[ \a new2Old[ i ]]. Number of tuples remains
1434  * the same as in \this one.
1435  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
1436  *  \param [in] new2Old - C array of length equal to \a this->getNumberOfTuples()
1437  *     giving a previous position of i-th new value.
1438  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1439  *          is to delete using decrRef() as it is no more needed.
1440  */
1441 void DataArrayDouble::renumberInPlaceR(const int *new2Old)
1442 {
1443   checkAllocated();
1444   int nbTuples=getNumberOfTuples();
1445   int nbOfCompo=getNumberOfComponents();
1446   double *tmp=new double[nbTuples*nbOfCompo];
1447   const double *iptr=getConstPointer();
1448   for(int i=0;i<nbTuples;i++)
1449     {
1450       int v=new2Old[i];
1451       if(v>=0 && v<nbTuples)
1452         std::copy(iptr+nbOfCompo*v,iptr+nbOfCompo*(v+1),tmp+nbOfCompo*i);
1453       else
1454         {
1455           std::ostringstream oss; oss << "DataArrayDouble::renumberInPlaceR : At place #" << i << " value is " << v << " ! Should be in [0," << nbTuples << ") !";
1456           throw INTERP_KERNEL::Exception(oss.str().c_str());
1457         }
1458     }
1459   std::copy(tmp,tmp+nbTuples*nbOfCompo,getPointer());
1460   delete [] tmp;
1461   declareAsNew();
1462 }
1463
1464 /*!
1465  * Returns a copy of \a this array with values permuted as required by \a old2New array.
1466  * The values are permuted so that  \c new[ \a old2New[ i ]] = \c old[ i ].
1467  * Number of tuples in the result array remains the same as in \this one.
1468  * If a permutation reduction is needed, renumberAndReduce() should be used.
1469  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
1470  *  \param [in] old2New - C array of length equal to \a this->getNumberOfTuples()
1471  *          giving a new position for i-th old value.
1472  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1473  *          is to delete using decrRef() as it is no more needed.
1474  *  \throw If \a this is not allocated.
1475  */
1476 DataArrayDouble *DataArrayDouble::renumber(const int *old2New) const
1477 {
1478   checkAllocated();
1479   int nbTuples=getNumberOfTuples();
1480   int nbOfCompo=getNumberOfComponents();
1481   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
1482   ret->alloc(nbTuples,nbOfCompo);
1483   ret->copyStringInfoFrom(*this);
1484   const double *iptr=getConstPointer();
1485   double *optr=ret->getPointer();
1486   for(int i=0;i<nbTuples;i++)
1487     std::copy(iptr+nbOfCompo*i,iptr+nbOfCompo*(i+1),optr+nbOfCompo*old2New[i]);
1488   ret->copyStringInfoFrom(*this);
1489   return ret.retn();
1490 }
1491
1492 /*!
1493  * Returns a copy of \a this array with values permuted as required by \a new2Old array.
1494  * The values are permuted so that  \c new[ i ] = \c old[ \a new2Old[ i ]]. Number of
1495  * tuples in the result array remains the same as in \this one.
1496  * If a permutation reduction is needed, substr() or selectByTupleId() should be used.
1497  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
1498  *  \param [in] new2Old - C array of length equal to \a this->getNumberOfTuples()
1499  *     giving a previous position of i-th new value.
1500  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1501  *          is to delete using decrRef() as it is no more needed.
1502  */
1503 DataArrayDouble *DataArrayDouble::renumberR(const int *new2Old) const
1504 {
1505   checkAllocated();
1506   int nbTuples=getNumberOfTuples();
1507   int nbOfCompo=getNumberOfComponents();
1508   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
1509   ret->alloc(nbTuples,nbOfCompo);
1510   ret->copyStringInfoFrom(*this);
1511   const double *iptr=getConstPointer();
1512   double *optr=ret->getPointer();
1513   for(int i=0;i<nbTuples;i++)
1514     std::copy(iptr+nbOfCompo*new2Old[i],iptr+nbOfCompo*(new2Old[i]+1),optr+i*nbOfCompo);
1515   ret->copyStringInfoFrom(*this);
1516   return ret.retn();
1517 }
1518
1519 /*!
1520  * Returns a shorten and permuted copy of \a this array. The new DataArrayDouble is
1521  * of size \a newNbOfTuple and it's values are permuted as required by \a old2New array.
1522  * The values are permuted so that  \c new[ \a old2New[ i ]] = \c old[ i ] for all
1523  * \a old2New[ i ] >= 0. In other words every i-th tuple in \a this array, for which 
1524  * \a old2New[ i ] is negative, is missing from the result array.
1525  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
1526  *  \param [in] old2New - C array of length equal to \a this->getNumberOfTuples()
1527  *     giving a new position for i-th old tuple and giving negative position for
1528  *     for i-th old tuple that should be omitted.
1529  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1530  *          is to delete using decrRef() as it is no more needed.
1531  */
1532 DataArrayDouble *DataArrayDouble::renumberAndReduce(const int *old2New, int newNbOfTuple) const
1533 {
1534   checkAllocated();
1535   int nbTuples=getNumberOfTuples();
1536   int nbOfCompo=getNumberOfComponents();
1537   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
1538   ret->alloc(newNbOfTuple,nbOfCompo);
1539   const double *iptr=getConstPointer();
1540   double *optr=ret->getPointer();
1541   for(int i=0;i<nbTuples;i++)
1542     {
1543       int w=old2New[i];
1544       if(w>=0)
1545         std::copy(iptr+i*nbOfCompo,iptr+(i+1)*nbOfCompo,optr+w*nbOfCompo);
1546     }
1547   ret->copyStringInfoFrom(*this);
1548   return ret.retn();
1549 }
1550
1551 /*!
1552  * Returns a shorten and permuted copy of \a this array. The new DataArrayDouble is
1553  * of size \a new2OldEnd - \a new2OldBg and it's values are permuted as required by
1554  * \a new2OldBg array.
1555  * The values are permuted so that  \c new[ i ] = \c old[ \a new2OldBg[ i ]].
1556  * This method is equivalent to renumberAndReduce() except that convention in input is
1557  * \c new2old and \b not \c old2new.
1558  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
1559  *  \param [in] new2OldBg - pointer to the beginning of a permutation array that gives a
1560  *              tuple index in \a this array to fill the i-th tuple in the new array.
1561  *  \param [in] new2OldEnd - specifies the end of the permutation array that starts at
1562  *              \a new2OldBg, so that pointer to a tuple index (\a pi) varies as this:
1563  *              \a new2OldBg <= \a pi < \a new2OldEnd.
1564  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1565  *          is to delete using decrRef() as it is no more needed.
1566  */
1567 DataArrayDouble *DataArrayDouble::selectByTupleId(const int *new2OldBg, const int *new2OldEnd) const
1568 {
1569   checkAllocated();
1570   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
1571   int nbComp=getNumberOfComponents();
1572   ret->alloc((int)std::distance(new2OldBg,new2OldEnd),nbComp);
1573   ret->copyStringInfoFrom(*this);
1574   double *pt=ret->getPointer();
1575   const double *srcPt=getConstPointer();
1576   int i=0;
1577   for(const int *w=new2OldBg;w!=new2OldEnd;w++,i++)
1578     std::copy(srcPt+(*w)*nbComp,srcPt+((*w)+1)*nbComp,pt+i*nbComp);
1579   ret->copyStringInfoFrom(*this);
1580   return ret.retn();
1581 }
1582
1583 /*!
1584  * Returns a shorten and permuted copy of \a this array. The new DataArrayDouble is
1585  * of size \a new2OldEnd - \a new2OldBg and it's values are permuted as required by
1586  * \a new2OldBg array.
1587  * The values are permuted so that  \c new[ i ] = \c old[ \a new2OldBg[ i ]].
1588  * This method is equivalent to renumberAndReduce() except that convention in input is
1589  * \c new2old and \b not \c old2new.
1590  * This method is equivalent to selectByTupleId() except that it prevents coping data
1591  * from behind the end of \a this array.
1592  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
1593  *  \param [in] new2OldBg - pointer to the beginning of a permutation array that gives a
1594  *              tuple index in \a this array to fill the i-th tuple in the new array.
1595  *  \param [in] new2OldEnd - specifies the end of the permutation array that starts at
1596  *              \a new2OldBg, so that pointer to a tuple index (\a pi) varies as this:
1597  *              \a new2OldBg <= \a pi < \a new2OldEnd.
1598  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1599  *          is to delete using decrRef() as it is no more needed.
1600  *  \throw If \a new2OldEnd - \a new2OldBg > \a this->getNumberOfTuples().
1601  */
1602 DataArrayDouble *DataArrayDouble::selectByTupleIdSafe(const int *new2OldBg, const int *new2OldEnd) const
1603 {
1604   checkAllocated();
1605   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
1606   int nbComp=getNumberOfComponents();
1607   int oldNbOfTuples=getNumberOfTuples();
1608   ret->alloc((int)std::distance(new2OldBg,new2OldEnd),nbComp);
1609   ret->copyStringInfoFrom(*this);
1610   double *pt=ret->getPointer();
1611   const double *srcPt=getConstPointer();
1612   int i=0;
1613   for(const int *w=new2OldBg;w!=new2OldEnd;w++,i++)
1614     if(*w>=0 && *w<oldNbOfTuples)
1615       std::copy(srcPt+(*w)*nbComp,srcPt+((*w)+1)*nbComp,pt+i*nbComp);
1616     else
1617       throw INTERP_KERNEL::Exception("DataArrayDouble::selectByTupleIdSafe : some ids has been detected to be out of [0,this->getNumberOfTuples) !");
1618   ret->copyStringInfoFrom(*this);
1619   return ret.retn();
1620 }
1621
1622 /*!
1623  * Returns a shorten copy of \a this array. The new DataArrayDouble contains every
1624  * (\a bg + \c i * \a step)-th tuple of \a this array located before the \a end2-th
1625  * tuple. Indices of the selected tuples are the same as ones returned by the Python
1626  * command \c range( \a bg, \a end2, \a step ).
1627  * This method is equivalent to selectByTupleIdSafe() except that the input array is
1628  * not constructed explicitly.
1629  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
1630  *  \param [in] bg - index of the first tuple to copy from \a this array.
1631  *  \param [in] end2 - index of the tuple before which the tuples to copy are located.
1632  *  \param [in] step - index increment to get index of the next tuple to copy.
1633  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1634  *          is to delete using decrRef() as it is no more needed.
1635  *  \sa DataArrayDouble::substr.
1636  */
1637 DataArrayDouble *DataArrayDouble::selectByTupleId2(int bg, int end2, int step) const
1638 {
1639   checkAllocated();
1640   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
1641   int nbComp=getNumberOfComponents();
1642   int newNbOfTuples=GetNumberOfItemGivenBESRelative(bg,end2,step,"DataArrayDouble::selectByTupleId2 : ");
1643   ret->alloc(newNbOfTuples,nbComp);
1644   double *pt=ret->getPointer();
1645   const double *srcPt=getConstPointer()+bg*nbComp;
1646   for(int i=0;i<newNbOfTuples;i++,srcPt+=step*nbComp)
1647     std::copy(srcPt,srcPt+nbComp,pt+i*nbComp);
1648   ret->copyStringInfoFrom(*this);
1649   return ret.retn();
1650 }
1651
1652 /*!
1653  * Returns a shorten copy of \a this array. The new DataArrayDouble contains ranges
1654  * of tuples specified by \a ranges parameter.
1655  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
1656  *  \param [in] ranges - std::vector of std::pair's each of which defines a range
1657  *              of tuples in [\c begin,\c end) format.
1658  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1659  *          is to delete using decrRef() as it is no more needed.
1660  *  \throw If \a end < \a begin.
1661  *  \throw If \a end > \a this->getNumberOfTuples().
1662  *  \throw If \a this is not allocated.
1663  */
1664 DataArray *DataArrayDouble::selectByTupleRanges(const std::vector<std::pair<int,int> >& ranges) const
1665 {
1666   checkAllocated();
1667   int nbOfComp=getNumberOfComponents();
1668   int nbOfTuplesThis=getNumberOfTuples();
1669   if(ranges.empty())
1670     {
1671       DataArrayDouble *ret=DataArrayDouble::New();
1672       ret->alloc(0,nbOfComp);
1673       ret->copyStringInfoFrom(*this);
1674       return ret;
1675     }
1676   int ref=ranges.front().first;
1677   int nbOfTuples=0;
1678   bool isIncreasing=true;
1679   for(std::vector<std::pair<int,int> >::const_iterator it=ranges.begin();it!=ranges.end();it++)
1680     {
1681       if((*it).first<=(*it).second)
1682         {
1683           if((*it).first>=0 && (*it).second<=nbOfTuplesThis)
1684             {
1685               nbOfTuples+=(*it).second-(*it).first;
1686               if(isIncreasing)
1687                 isIncreasing=ref<=(*it).first;
1688               ref=(*it).second;
1689             }
1690           else
1691             {
1692               std::ostringstream oss; oss << "DataArrayDouble::selectByTupleRanges : on range #" << std::distance(ranges.begin(),it);
1693               oss << " (" << (*it).first << "," << (*it).second << ") is greater than number of tuples of this :" << nbOfTuples << " !";
1694               throw INTERP_KERNEL::Exception(oss.str().c_str());
1695             }
1696         }
1697       else
1698         {
1699           std::ostringstream oss; oss << "DataArrayDouble::selectByTupleRanges : on range #" << std::distance(ranges.begin(),it);
1700           oss << " (" << (*it).first << "," << (*it).second << ") end is before begin !";
1701           throw INTERP_KERNEL::Exception(oss.str().c_str());
1702         }
1703     }
1704   if(isIncreasing && nbOfTuplesThis==nbOfTuples)
1705     return deepCpy();
1706   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
1707   ret->alloc(nbOfTuples,nbOfComp);
1708   ret->copyStringInfoFrom(*this);
1709   const double *src=getConstPointer();
1710   double *work=ret->getPointer();
1711   for(std::vector<std::pair<int,int> >::const_iterator it=ranges.begin();it!=ranges.end();it++)
1712     work=std::copy(src+(*it).first*nbOfComp,src+(*it).second*nbOfComp,work);
1713   return ret.retn();
1714 }
1715
1716 /*!
1717  * Returns a shorten copy of \a this array. The new DataArrayDouble contains all
1718  * tuples starting from the \a tupleIdBg-th tuple and including all tuples located before
1719  * the \a tupleIdEnd-th one. This methods has a similar behavior as std::string::substr().
1720  * This method is a specialization of selectByTupleId2().
1721  *  \param [in] tupleIdBg - index of the first tuple to copy from \a this array.
1722  *  \param [in] tupleIdEnd - index of the tuple before which the tuples to copy are located.
1723  *          If \a tupleIdEnd == -1, all the tuples till the end of \a this array are copied.
1724  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1725  *          is to delete using decrRef() as it is no more needed.
1726  *  \throw If \a tupleIdBg < 0.
1727  *  \throw If \a tupleIdBg > \a this->getNumberOfTuples().
1728     \throw If \a tupleIdEnd != -1 && \a tupleIdEnd < \a this->getNumberOfTuples().
1729  *  \sa DataArrayDouble::selectByTupleId2
1730  */
1731 DataArrayDouble *DataArrayDouble::substr(int tupleIdBg, int tupleIdEnd) const
1732 {
1733   checkAllocated();
1734   int nbt=getNumberOfTuples();
1735   if(tupleIdBg<0)
1736     throw INTERP_KERNEL::Exception("DataArrayDouble::substr : The tupleIdBg parameter must be greater than 0 !");
1737   if(tupleIdBg>nbt)
1738     throw INTERP_KERNEL::Exception("DataArrayDouble::substr : The tupleIdBg parameter is greater than number of tuples !");
1739   int trueEnd=tupleIdEnd;
1740   if(tupleIdEnd!=-1)
1741     {
1742       if(tupleIdEnd>nbt)
1743         throw INTERP_KERNEL::Exception("DataArrayDouble::substr : The tupleIdBg parameter is greater or equal than number of tuples !");
1744     }
1745   else
1746     trueEnd=nbt;
1747   int nbComp=getNumberOfComponents();
1748   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
1749   ret->alloc(trueEnd-tupleIdBg,nbComp);
1750   ret->copyStringInfoFrom(*this);
1751   std::copy(getConstPointer()+tupleIdBg*nbComp,getConstPointer()+trueEnd*nbComp,ret->getPointer());
1752   return ret.retn();
1753 }
1754
1755 /*!
1756  * Returns a shorten or extended copy of \a this array. If \a newNbOfComp is less
1757  * than \a this->getNumberOfComponents() then the result array is shorten as each tuple
1758  * is truncated to have \a newNbOfComp components, keeping first components. If \a
1759  * newNbOfComp is more than \a this->getNumberOfComponents() then the result array is
1760  * expanded as each tuple is populated with \a dftValue to have \a newNbOfComp
1761  * components.  
1762  *  \param [in] newNbOfComp - number of components for the new array to have.
1763  *  \param [in] dftValue - value assigned to new values added to the new array.
1764  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1765  *          is to delete using decrRef() as it is no more needed.
1766  *  \throw If \a this is not allocated.
1767  */
1768 DataArrayDouble *DataArrayDouble::changeNbOfComponents(int newNbOfComp, double dftValue) const
1769 {
1770   checkAllocated();
1771   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
1772   ret->alloc(getNumberOfTuples(),newNbOfComp);
1773   const double *oldc=getConstPointer();
1774   double *nc=ret->getPointer();
1775   int nbOfTuples=getNumberOfTuples();
1776   int oldNbOfComp=getNumberOfComponents();
1777   int dim=std::min(oldNbOfComp,newNbOfComp);
1778   for(int i=0;i<nbOfTuples;i++)
1779     {
1780       int j=0;
1781       for(;j<dim;j++)
1782         nc[newNbOfComp*i+j]=oldc[i*oldNbOfComp+j];
1783       for(;j<newNbOfComp;j++)
1784         nc[newNbOfComp*i+j]=dftValue;
1785     }
1786   ret->setName(getName().c_str());
1787   for(int i=0;i<dim;i++)
1788     ret->setInfoOnComponent(i,getInfoOnComponent(i).c_str());
1789   ret->setName(getName().c_str());
1790   return ret.retn();
1791 }
1792
1793 /*!
1794  * Changes the number of components within \a this array so that its raw data **does
1795  * not** change, instead splitting this data into tuples changes.
1796  *  \warning This method erases all (name and unit) component info set before!
1797  *  \param [in] newNbOfComp - number of components for \a this array to have.
1798  *  \throw If \a this is not allocated
1799  *  \throw If getNbOfElems() % \a newNbOfCompo != 0.
1800  *  \throw If \a newNbOfCompo is lower than 1.
1801  *  \throw If the rearrange method would lead to a number of tuples higher than 2147483647 (maximal capacity of int32 !).
1802  *  \warning This method erases all (name and unit) component info set before!
1803  */
1804 void DataArrayDouble::rearrange(int newNbOfCompo)
1805 {
1806   checkAllocated();
1807   if(newNbOfCompo<1)
1808     throw INTERP_KERNEL::Exception("DataArrayDouble::rearrange : input newNbOfCompo must be > 0 !");
1809   std::size_t nbOfElems=getNbOfElems();
1810   if(nbOfElems%newNbOfCompo!=0)
1811     throw INTERP_KERNEL::Exception("DataArrayDouble::rearrange : nbOfElems%newNbOfCompo!=0 !");
1812   if(nbOfElems/newNbOfCompo>(std::size_t)std::numeric_limits<int>::max())
1813     throw INTERP_KERNEL::Exception("DataArrayDouble::rearrange : the rearrangement leads to too high number of tuples (> 2147483647) !");
1814   _info_on_compo.clear();
1815   _info_on_compo.resize(newNbOfCompo);
1816   declareAsNew();
1817 }
1818
1819 /*!
1820  * Changes the number of components within \a this array to be equal to its number
1821  * of tuples, and inversely its number of tuples to become equal to its number of 
1822  * components. So that its raw data **does not** change, instead splitting this
1823  * data into tuples changes.
1824  *  \warning This method erases all (name and unit) component info set before!
1825  *  \warning Do not confuse this method with fromNoInterlace() and toNoInterlace()!
1826  *  \throw If \a this is not allocated.
1827  *  \sa rearrange()
1828  */
1829 void DataArrayDouble::transpose()
1830 {
1831   checkAllocated();
1832   int nbOfTuples=getNumberOfTuples();
1833   rearrange(nbOfTuples);
1834 }
1835
1836 /*!
1837  * Returns a copy of \a this array composed of selected components.
1838  * The new DataArrayDouble has the same number of tuples but includes components
1839  * specified by \a compoIds parameter. So that getNbOfElems() of the result array
1840  * can be either less, same or more than \a this->getNbOfElems().
1841  *  \param [in] compoIds - sequence of zero based indices of components to include
1842  *              into the new array.
1843  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1844  *          is to delete using decrRef() as it is no more needed.
1845  *  \throw If \a this is not allocated.
1846  *  \throw If a component index (\a i) is not valid: 
1847  *         \a i < 0 || \a i >= \a this->getNumberOfComponents().
1848  *
1849  *  \ref py_mcdataarraydouble_KeepSelectedComponents "Here is a Python example".
1850  */
1851 DataArray *DataArrayDouble::keepSelectedComponents(const std::vector<int>& compoIds) const
1852 {
1853   checkAllocated();
1854   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret(DataArrayDouble::New());
1855   std::size_t newNbOfCompo=compoIds.size();
1856   int oldNbOfCompo=getNumberOfComponents();
1857   for(std::vector<int>::const_iterator it=compoIds.begin();it!=compoIds.end();it++)
1858     if((*it)<0 || (*it)>=oldNbOfCompo)
1859       {
1860         std::ostringstream oss; oss << "DataArrayDouble::keepSelectedComponents : invalid requested component : " << *it << " whereas it should be in [0," << oldNbOfCompo << ") !";
1861         throw INTERP_KERNEL::Exception(oss.str().c_str());
1862       }
1863   int nbOfTuples=getNumberOfTuples();
1864   ret->alloc(nbOfTuples,(int)newNbOfCompo);
1865   ret->copyPartOfStringInfoFrom(*this,compoIds);
1866   const double *oldc=getConstPointer();
1867   double *nc=ret->getPointer();
1868   for(int i=0;i<nbOfTuples;i++)
1869     for(std::size_t j=0;j<newNbOfCompo;j++,nc++)
1870       *nc=oldc[i*oldNbOfCompo+compoIds[j]];
1871   return ret.retn();
1872 }
1873
1874 /*!
1875  * Appends components of another array to components of \a this one, tuple by tuple.
1876  * So that the number of tuples of \a this array remains the same and the number of 
1877  * components increases.
1878  *  \param [in] other - the DataArrayDouble to append to \a this one.
1879  *  \throw If \a this is not allocated.
1880  *  \throw If \a this and \a other arrays have different number of tuples.
1881  *
1882  *  \ref cpp_mcdataarraydouble_meldwith "Here is a C++ example".
1883  *
1884  *  \ref py_mcdataarraydouble_meldwith "Here is a Python example".
1885  */
1886 void DataArrayDouble::meldWith(const DataArrayDouble *other)
1887 {
1888   checkAllocated();
1889   other->checkAllocated();
1890   int nbOfTuples=getNumberOfTuples();
1891   if(nbOfTuples!=other->getNumberOfTuples())
1892     throw INTERP_KERNEL::Exception("DataArrayDouble::meldWith : mismatch of number of tuples !");
1893   int nbOfComp1=getNumberOfComponents();
1894   int nbOfComp2=other->getNumberOfComponents();
1895   double *newArr=(double *)malloc((nbOfTuples*(nbOfComp1+nbOfComp2))*sizeof(double));
1896   double *w=newArr;
1897   const double *inp1=getConstPointer();
1898   const double *inp2=other->getConstPointer();
1899   for(int i=0;i<nbOfTuples;i++,inp1+=nbOfComp1,inp2+=nbOfComp2)
1900     {
1901       w=std::copy(inp1,inp1+nbOfComp1,w);
1902       w=std::copy(inp2,inp2+nbOfComp2,w);
1903     }
1904   useArray(newArr,true,C_DEALLOC,nbOfTuples,nbOfComp1+nbOfComp2);
1905   std::vector<int> compIds(nbOfComp2);
1906   for(int i=0;i<nbOfComp2;i++)
1907     compIds[i]=nbOfComp1+i;
1908   copyPartOfStringInfoFrom2(compIds,*other);
1909 }
1910
1911 /*!
1912  * This method checks that all tuples in \a other are in \a this.
1913  * If true, the output param \a tupleIds contains the tuples ids of \a this that correspond to tupes in \a this.
1914  * 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.
1915  *
1916  * \param [in] other - the array having the same number of components than \a this.
1917  * \param [out] tupleIds - the tuple ids containing the same number of tuples than \a other has.
1918  * \sa DataArrayDouble::findCommonTuples
1919  */
1920 bool DataArrayDouble::areIncludedInMe(const DataArrayDouble *other, double prec, DataArrayInt *&tupleIds) const
1921 {
1922   if(!other)
1923     throw INTERP_KERNEL::Exception("DataArrayDouble::areIncludedInMe : input array is NULL !");
1924   checkAllocated(); other->checkAllocated();
1925   if(getNumberOfComponents()!=other->getNumberOfComponents())
1926     throw INTERP_KERNEL::Exception("DataArrayDouble::areIncludedInMe : the number of components does not match !");
1927   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> a=DataArrayDouble::Aggregate(this,other);
1928   DataArrayInt *c=0,*ci=0;
1929   a->findCommonTuples(prec,getNumberOfTuples(),c,ci);
1930   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cSafe(c),ciSafe(ci);
1931   int newNbOfTuples=-1;
1932   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ids=DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2(a->getNumberOfTuples(),c->begin(),ci->begin(),ci->end(),newNbOfTuples);
1933   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret1=ids->selectByTupleId2(getNumberOfTuples(),a->getNumberOfTuples(),1);
1934   tupleIds=ret1.retn();
1935   return newNbOfTuples==getNumberOfTuples();
1936 }
1937
1938 /*!
1939  * Searches for tuples coincident within \a prec tolerance. Each tuple is considered
1940  * as coordinates of a point in getNumberOfComponents()-dimensional space. The
1941  * distance separating two points is computed with the infinite norm.
1942  *
1943  * Indices of coincident tuples are stored in output arrays.
1944  * A pair of arrays (\a comm, \a commIndex) is called "Surjective Format 2".
1945  *
1946  * This method is typically used by MEDCouplingPointSet::findCommonNodes() and
1947  * MEDCouplingUMesh::mergeNodes().
1948  *  \param [in] prec - minimal absolute distance between two tuples (infinite norm) at which they are
1949  *              considered not coincident.
1950  *  \param [in] limitTupleId - limit tuple id. If all tuples within a group of coincident
1951  *              tuples have id strictly lower than \a limitTupleId then they are not returned.
1952  *  \param [out] comm - the array holding ids (== indices) of coincident tuples. 
1953  *               \a comm->getNumberOfComponents() == 1. 
1954  *               \a comm->getNumberOfTuples() == \a commIndex->back().
1955  *  \param [out] commIndex - the array dividing all indices stored in \a comm into
1956  *               groups of (indices of) coincident tuples. Its every value is a tuple
1957  *               index where a next group of tuples begins. For example the second
1958  *               group of tuples in \a comm is described by following range of indices:
1959  *               [ \a commIndex[1], \a commIndex[2] ). \a commIndex->getNumberOfTuples()-1
1960  *               gives the number of groups of coincident tuples.
1961  *  \throw If \a this is not allocated.
1962  *  \throw If the number of components is not in [1,2,3].
1963  *
1964  *  \ref cpp_mcdataarraydouble_findcommontuples "Here is a C++ example".
1965  *
1966  *  \ref py_mcdataarraydouble_findcommontuples  "Here is a Python example".
1967  *  \sa DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2(), DataArrayDouble::areIncludedInMe
1968  */
1969 void DataArrayDouble::findCommonTuples(double prec, int limitTupleId, DataArrayInt *&comm, DataArrayInt *&commIndex) const
1970 {
1971   checkAllocated();
1972   int nbOfCompo=getNumberOfComponents();
1973   if ((nbOfCompo<1) || (nbOfCompo>3)) //test before work
1974     throw INTERP_KERNEL::Exception("DataArrayDouble::findCommonTuples : Unexpected spacedim of coords. Must be 1, 2 or 3.");
1975   
1976   int nbOfTuples=getNumberOfTuples();
1977   //
1978   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> c(DataArrayInt::New()),cI(DataArrayInt::New()); c->alloc(0,1); cI->pushBackSilent(0);
1979   switch(nbOfCompo)
1980     {
1981     case 3:
1982       findCommonTuplesAlg<3>(begin(),nbOfTuples,limitTupleId,prec,c,cI);
1983       break;
1984     case 2:
1985       findCommonTuplesAlg<2>(begin(),nbOfTuples,limitTupleId,prec,c,cI);
1986       break;
1987     case 1:
1988       findCommonTuplesAlg<1>(begin(),nbOfTuples,limitTupleId,prec,c,cI);
1989       break;
1990     default:
1991       throw INTERP_KERNEL::Exception("DataArrayDouble::findCommonTuples : nb of components managed are 1,2 and 3 ! not implemented for other number of components !");
1992     }
1993   comm=c.retn();
1994   commIndex=cI.retn();
1995 }
1996
1997 /*!
1998  * 
1999  * \param [in] nbTimes specifies the nb of times each tuples in \a this will be duplicated contiguouly in returned DataArrayDouble instance.
2000  *             \a nbTimes  should be at least equal to 1.
2001  * \return a newly allocated DataArrayDouble having one component and number of tuples equal to \a nbTimes * \c this->getNumberOfTuples.
2002  * \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.
2003  */
2004 DataArrayDouble *DataArrayDouble::duplicateEachTupleNTimes(int nbTimes) const
2005 {
2006   checkAllocated();
2007   if(getNumberOfComponents()!=1)
2008     throw INTERP_KERNEL::Exception("DataArrayDouble::duplicateEachTupleNTimes : this should have only one component !");
2009   if(nbTimes<1)
2010     throw INTERP_KERNEL::Exception("DataArrayDouble::duplicateEachTupleNTimes : nb times should be >= 1 !");
2011   int nbTuples=getNumberOfTuples();
2012   const double *inPtr=getConstPointer();
2013   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New(); ret->alloc(nbTimes*nbTuples,1);
2014   double *retPtr=ret->getPointer();
2015   for(int i=0;i<nbTuples;i++,inPtr++)
2016     {
2017       double val=*inPtr;
2018       for(int j=0;j<nbTimes;j++,retPtr++)
2019         *retPtr=val;
2020     }
2021   ret->copyStringInfoFrom(*this);
2022   return ret.retn();
2023 }
2024
2025 /*!
2026  * This methods returns the minimal distance between the two set of points \a this and \a other.
2027  * So \a this and \a other have to have the same number of components. If not an INTERP_KERNEL::Exception will be thrown.
2028  * This method works only if number of components of \a this (equal to those of \a other) is in 1, 2 or 3.
2029  *
2030  * \param [out] thisTupleId the tuple id in \a this corresponding to the returned minimal distance
2031  * \param [out] otherTupleId the tuple id in \a other corresponding to the returned minimal distance
2032  * \return the minimal distance between the two set of points \a this and \a other.
2033  * \sa DataArrayDouble::findClosestTupleId
2034  */
2035 double DataArrayDouble::minimalDistanceTo(const DataArrayDouble *other, int& thisTupleId, int& otherTupleId) const
2036 {
2037   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> part1=findClosestTupleId(other);
2038   int nbOfCompo(getNumberOfComponents());
2039   int otherNbTuples(other->getNumberOfTuples());
2040   const double *thisPt(begin()),*otherPt(other->begin());
2041   const int *part1Pt(part1->begin());
2042   double ret=std::numeric_limits<double>::max();
2043   for(int i=0;i<otherNbTuples;i++,part1Pt++,otherPt+=nbOfCompo)
2044     {
2045       double tmp(0.);
2046       for(int j=0;j<nbOfCompo;j++)
2047         tmp+=(otherPt[j]-thisPt[nbOfCompo*(*part1Pt)+j])*(otherPt[j]-thisPt[nbOfCompo*(*part1Pt)+j]);
2048       if(tmp<ret)
2049         { ret=tmp; thisTupleId=*part1Pt; otherTupleId=i; }
2050     }
2051   return sqrt(ret);
2052 }
2053
2054 /*!
2055  * This methods returns for each tuple in \a other which tuple in \a this is the closest.
2056  * So \a this and \a other have to have the same number of components. If not an INTERP_KERNEL::Exception will be thrown.
2057  * This method works only if number of components of \a this (equal to those of \a other) is in 1, 2 or 3.
2058  *
2059  * \return a newly allocated (new object to be dealt by the caller) DataArrayInt having \c other->getNumberOfTuples() tuples and one components.
2060  * \sa DataArrayDouble::minimalDistanceTo
2061  */
2062 DataArrayInt *DataArrayDouble::findClosestTupleId(const DataArrayDouble *other) const
2063 {
2064   if(!other)
2065     throw INTERP_KERNEL::Exception("DataArrayDouble::findClosestTupleId : other instance is NULL !");
2066   checkAllocated(); other->checkAllocated();
2067   int nbOfCompo=getNumberOfComponents();
2068   if(nbOfCompo!=other->getNumberOfComponents())
2069     {
2070       std::ostringstream oss; oss << "DataArrayDouble::findClosestTupleId : number of components in this is " << nbOfCompo;
2071       oss << ", whereas number of components in other is " << other->getNumberOfComponents() << "! Should be equal !";
2072       throw INTERP_KERNEL::Exception(oss.str().c_str());
2073     }
2074   int nbOfTuples=other->getNumberOfTuples();
2075   int thisNbOfTuples=getNumberOfTuples();
2076   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbOfTuples,1);
2077   double bounds[6];
2078   getMinMaxPerComponent(bounds);
2079   switch(nbOfCompo)
2080     {
2081     case 3:
2082       {
2083         double xDelta(fabs(bounds[1]-bounds[0])),yDelta(fabs(bounds[3]-bounds[2])),zDelta(fabs(bounds[5]-bounds[4]));
2084         double delta=std::max(xDelta,yDelta); delta=std::max(delta,zDelta);
2085         double characSize=pow((delta*delta*delta)/((double)thisNbOfTuples),1./3.);
2086         BBTreePts<3,int> myTree(begin(),0,0,getNumberOfTuples(),characSize*1e-12);
2087         FindClosestTupleIdAlg<3>(myTree,3.*characSize*characSize,other->begin(),nbOfTuples,begin(),thisNbOfTuples,ret->getPointer());
2088         break;
2089       }
2090     case 2:
2091       {
2092         double xDelta(fabs(bounds[1]-bounds[0])),yDelta(fabs(bounds[3]-bounds[2]));
2093         double delta=std::max(xDelta,yDelta);
2094         double characSize=sqrt(delta/(double)thisNbOfTuples);
2095         BBTreePts<2,int> myTree(begin(),0,0,getNumberOfTuples(),characSize*1e-12);
2096         FindClosestTupleIdAlg<2>(myTree,2.*characSize*characSize,other->begin(),nbOfTuples,begin(),thisNbOfTuples,ret->getPointer());
2097         break;
2098       }
2099     case 1:
2100       {
2101         double characSize=fabs(bounds[1]-bounds[0])/thisNbOfTuples;
2102         BBTreePts<1,int> myTree(begin(),0,0,getNumberOfTuples(),characSize*1e-12);
2103         FindClosestTupleIdAlg<1>(myTree,1.*characSize*characSize,other->begin(),nbOfTuples,begin(),thisNbOfTuples,ret->getPointer());
2104         break;
2105       }
2106     default:
2107       throw INTERP_KERNEL::Exception("Unexpected spacedim of coords for findClosestTupleId. Must be 1, 2 or 3.");
2108     }
2109   return ret.retn();
2110 }
2111
2112 /*!
2113  * This method expects that \a this and \a otherBBoxFrmt arrays are bounding box arrays ( as the output of MEDCouplingPointSet::getBoundingBoxForBBTree method ).
2114  * 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
2115  * how many bounding boxes in \a otherBBoxFrmt.
2116  * So, this method expects that \a this and \a otherBBoxFrmt have the same number of components.
2117  *
2118  * \param [in] otherBBoxFrmt - It is an array .
2119  * \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.
2120  * \sa MEDCouplingPointSet::getBoundingBoxForBBTree
2121  * \throw If \a this and \a otherBBoxFrmt have not the same number of components.
2122  * \throw If \a this and \a otherBBoxFrmt number of components is not even (BBox format).
2123  */
2124 DataArrayInt *DataArrayDouble::computeNbOfInteractionsWith(const DataArrayDouble *otherBBoxFrmt, double eps) const
2125 {
2126   if(!otherBBoxFrmt)
2127     throw INTERP_KERNEL::Exception("DataArrayDouble::computeNbOfInteractionsWith : input array is NULL !");
2128   if(!isAllocated() || !otherBBoxFrmt->isAllocated())
2129     throw INTERP_KERNEL::Exception("DataArrayDouble::computeNbOfInteractionsWith : this and input array must be allocated !");
2130   int nbOfComp(getNumberOfComponents()),nbOfTuples(getNumberOfTuples());
2131   if(nbOfComp!=otherBBoxFrmt->getNumberOfComponents())
2132     {
2133       std::ostringstream oss; oss << "DataArrayDouble::computeNbOfInteractionsWith : this number of components (" << nbOfComp << ") must be equal to the number of components of input array (" << otherBBoxFrmt->getNumberOfComponents() << ") !";
2134       throw INTERP_KERNEL::Exception(oss.str().c_str());
2135     }
2136   if(nbOfComp%2!=0)
2137     {
2138       std::ostringstream oss; oss << "DataArrayDouble::computeNbOfInteractionsWith : Number of components (" << nbOfComp << ") is not even ! It should be to be compatible with bbox format !";
2139       throw INTERP_KERNEL::Exception(oss.str().c_str());
2140     }
2141   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(nbOfTuples,1);
2142   const double *thisBBPtr(begin());
2143   int *retPtr(ret->getPointer());
2144   switch(nbOfComp/2)
2145     {
2146     case 3:
2147       {
2148         BBTree<3,int> bbt(otherBBoxFrmt->begin(),0,0,otherBBoxFrmt->getNumberOfTuples(),eps);
2149         for(int i=0;i<nbOfTuples;i++,retPtr++,thisBBPtr+=nbOfComp)
2150           *retPtr=bbt.getNbOfIntersectingElems(thisBBPtr);
2151         break;
2152       }
2153     case 2:
2154       {
2155         BBTree<2,int> bbt(otherBBoxFrmt->begin(),0,0,otherBBoxFrmt->getNumberOfTuples(),eps);
2156         for(int i=0;i<nbOfTuples;i++,retPtr++,thisBBPtr+=nbOfComp)
2157           *retPtr=bbt.getNbOfIntersectingElems(thisBBPtr);
2158         break;
2159       }
2160     case 1:
2161       {
2162         BBTree<1,int> bbt(otherBBoxFrmt->begin(),0,0,otherBBoxFrmt->getNumberOfTuples(),eps);
2163         for(int i=0;i<nbOfTuples;i++,retPtr++,thisBBPtr+=nbOfComp)
2164           *retPtr=bbt.getNbOfIntersectingElems(thisBBPtr);
2165         break;
2166       }
2167     default:
2168       throw INTERP_KERNEL::Exception("DataArrayDouble::computeNbOfInteractionsWith : space dimension supported are [1,2,3] !");
2169     }
2170   
2171   return ret.retn();
2172 }
2173
2174 /*!
2175  * Returns a copy of \a this array by excluding coincident tuples. Each tuple is
2176  * considered as coordinates of a point in getNumberOfComponents()-dimensional
2177  * space. The distance between tuples is computed using norm2. If several tuples are
2178  * not far each from other than \a prec, only one of them remains in the result
2179  * array. The order of tuples in the result array is same as in \a this one except
2180  * that coincident tuples are excluded.
2181  *  \param [in] prec - minimal absolute distance between two tuples at which they are
2182  *              considered not coincident.
2183  *  \param [in] limitTupleId - limit tuple id. If all tuples within a group of coincident
2184  *              tuples have id strictly lower than \a limitTupleId then they are not excluded.
2185  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
2186  *          is to delete using decrRef() as it is no more needed.
2187  *  \throw If \a this is not allocated.
2188  *  \throw If the number of components is not in [1,2,3].
2189  *
2190  *  \ref py_mcdataarraydouble_getdifferentvalues "Here is a Python example".
2191  */
2192 DataArrayDouble *DataArrayDouble::getDifferentValues(double prec, int limitTupleId) const
2193 {
2194   checkAllocated();
2195   DataArrayInt *c0=0,*cI0=0;
2196   findCommonTuples(prec,limitTupleId,c0,cI0);
2197   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> c(c0),cI(cI0);
2198   int newNbOfTuples=-1;
2199   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> o2n=DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2(getNumberOfTuples(),c0->begin(),cI0->begin(),cI0->end(),newNbOfTuples);
2200   return renumberAndReduce(o2n->getConstPointer(),newNbOfTuples);
2201 }
2202
2203 /*!
2204  * Copy all components in a specified order from another DataArrayDouble.
2205  * Both numerical and textual data is copied. The number of tuples in \a this and
2206  * the other array can be different.
2207  *  \param [in] a - the array to copy data from.
2208  *  \param [in] compoIds - sequence of zero based indices of components, data of which is
2209  *              to be copied.
2210  *  \throw If \a a is NULL.
2211  *  \throw If \a compoIds.size() != \a a->getNumberOfComponents().
2212  *  \throw If \a compoIds[i] < 0 or \a compoIds[i] > \a this->getNumberOfComponents().
2213  *
2214  *  \ref py_mcdataarraydouble_setselectedcomponents "Here is a Python example".
2215  */
2216 void DataArrayDouble::setSelectedComponents(const DataArrayDouble *a, const std::vector<int>& compoIds)
2217 {
2218   if(!a)
2219     throw INTERP_KERNEL::Exception("DataArrayDouble::setSelectedComponents : input DataArrayDouble is NULL !");
2220   checkAllocated();
2221   copyPartOfStringInfoFrom2(compoIds,*a);
2222   std::size_t partOfCompoSz=compoIds.size();
2223   int nbOfCompo=getNumberOfComponents();
2224   int nbOfTuples=std::min(getNumberOfTuples(),a->getNumberOfTuples());
2225   const double *ac=a->getConstPointer();
2226   double *nc=getPointer();
2227   for(int i=0;i<nbOfTuples;i++)
2228     for(std::size_t j=0;j<partOfCompoSz;j++,ac++)
2229       nc[nbOfCompo*i+compoIds[j]]=*ac;
2230 }
2231
2232 /*!
2233  * Copy all values from another DataArrayDouble into specified tuples and components
2234  * of \a this array. Textual data is not copied.
2235  * The tree parameters defining set of indices of tuples and components are similar to
2236  * the tree parameters of the Python function \c range(\c start,\c stop,\c step).
2237  *  \param [in] a - the array to copy values from.
2238  *  \param [in] bgTuples - index of the first tuple of \a this array to assign values to.
2239  *  \param [in] endTuples - index of the tuple before which the tuples to assign to
2240  *              are located.
2241  *  \param [in] stepTuples - index increment to get index of the next tuple to assign to.
2242  *  \param [in] bgComp - index of the first component of \a this array to assign values to.
2243  *  \param [in] endComp - index of the component before which the components to assign
2244  *              to are located.
2245  *  \param [in] stepComp - index increment to get index of the next component to assign to.
2246  *  \param [in] strictCompoCompare - if \a true (by default), then \a a->getNumberOfComponents() 
2247  *              must be equal to the number of columns to assign to, else an
2248  *              exception is thrown; if \a false, then it is only required that \a
2249  *              a->getNbOfElems() equals to number of values to assign to (this condition
2250  *              must be respected even if \a strictCompoCompare is \a true). The number of 
2251  *              values to assign to is given by following Python expression:
2252  *              \a nbTargetValues = 
2253  *              \c len(\c range(\a bgTuples,\a endTuples,\a stepTuples)) *
2254  *              \c len(\c range(\a bgComp,\a endComp,\a stepComp)).
2255  *  \throw If \a a is NULL.
2256  *  \throw If \a a is not allocated.
2257  *  \throw If \a this is not allocated.
2258  *  \throw If parameters specifying tuples and components to assign to do not give a
2259  *            non-empty range of increasing indices.
2260  *  \throw If \a a->getNbOfElems() != \a nbTargetValues.
2261  *  \throw If \a strictCompoCompare == \a true && \a a->getNumberOfComponents() !=
2262  *            \c len(\c range(\a bgComp,\a endComp,\a stepComp)).
2263  *
2264  *  \ref py_mcdataarraydouble_setpartofvalues1 "Here is a Python example".
2265  */
2266 void DataArrayDouble::setPartOfValues1(const DataArrayDouble *a, int bgTuples, int endTuples, int stepTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare)
2267 {
2268   if(!a)
2269     throw INTERP_KERNEL::Exception("DataArrayDouble::setPartOfValues1 : input DataArrayDouble is NULL !");
2270   const char msg[]="DataArrayDouble::setPartOfValues1";
2271   checkAllocated();
2272   a->checkAllocated();
2273   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
2274   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
2275   int nbComp=getNumberOfComponents();
2276   int nbOfTuples=getNumberOfTuples();
2277   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
2278   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
2279   bool assignTech=true;
2280   if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
2281     {
2282       if(strictCompoCompare)
2283         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
2284     }
2285   else
2286     {
2287       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
2288       assignTech=false;
2289     }
2290   const double *srcPt=a->getConstPointer();
2291   double *pt=getPointer()+bgTuples*nbComp+bgComp;
2292   if(assignTech)
2293     {
2294       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
2295         for(int j=0;j<newNbOfComp;j++,srcPt++)
2296           pt[j*stepComp]=*srcPt;
2297     }
2298   else
2299     {
2300       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
2301         {
2302           const double *srcPt2=srcPt;
2303           for(int j=0;j<newNbOfComp;j++,srcPt2++)
2304             pt[j*stepComp]=*srcPt2;
2305         }
2306     }
2307 }
2308
2309 /*!
2310  * Assign a given value to values at specified tuples and components of \a this array.
2311  * The tree parameters defining set of indices of tuples and components are similar to
2312  * the tree parameters of the Python function \c range(\c start,\c stop,\c step)..
2313  *  \param [in] a - the value to assign.
2314  *  \param [in] bgTuples - index of the first tuple of \a this array to assign to.
2315  *  \param [in] endTuples - index of the tuple before which the tuples to assign to
2316  *              are located.
2317  *  \param [in] stepTuples - index increment to get index of the next tuple to assign to.
2318  *  \param [in] bgComp - index of the first component of \a this array to assign to.
2319  *  \param [in] endComp - index of the component before which the components to assign
2320  *              to are located.
2321  *  \param [in] stepComp - index increment to get index of the next component to assign to.
2322  *  \throw If \a this is not allocated.
2323  *  \throw If parameters specifying tuples and components to assign to, do not give a
2324  *            non-empty range of increasing indices or indices are out of a valid range
2325  *            for \this array.
2326  *
2327  *  \ref py_mcdataarraydouble_setpartofvaluessimple1 "Here is a Python example".
2328  */
2329 void DataArrayDouble::setPartOfValuesSimple1(double a, int bgTuples, int endTuples, int stepTuples, int bgComp, int endComp, int stepComp)
2330 {
2331   const char msg[]="DataArrayDouble::setPartOfValuesSimple1";
2332   checkAllocated();
2333   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
2334   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
2335   int nbComp=getNumberOfComponents();
2336   int nbOfTuples=getNumberOfTuples();
2337   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
2338   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
2339   double *pt=getPointer()+bgTuples*nbComp+bgComp;
2340   for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
2341     for(int j=0;j<newNbOfComp;j++)
2342       pt[j*stepComp]=a;
2343 }
2344
2345 /*!
2346  * Copy all values from another DataArrayDouble (\a a) into specified tuples and 
2347  * components of \a this array. Textual data is not copied.
2348  * The tuples and components to assign to are defined by C arrays of indices.
2349  * There are two *modes of usage*:
2350  * - If \a a->getNbOfElems() equals to number of values to assign to, then every value
2351  *   of \a a is assigned to its own location within \a this array. 
2352  * - If \a a includes one tuple, then all values of \a a are assigned to the specified
2353  *   components of every specified tuple of \a this array. In this mode it is required
2354  *   that \a a->getNumberOfComponents() equals to the number of specified components.
2355  *
2356  *  \param [in] a - the array to copy values from.
2357  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
2358  *              assign values of \a a to.
2359  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
2360  *              pointer to a tuple index <em>(pi)</em> varies as this: 
2361  *              \a bgTuples <= \a pi < \a endTuples.
2362  *  \param [in] bgComp - pointer to an array of component indices of \a this array to
2363  *              assign values of \a a to.
2364  *  \param [in] endComp - specifies the end of the array \a bgTuples, so that
2365  *              pointer to a component index <em>(pi)</em> varies as this: 
2366  *              \a bgComp <= \a pi < \a endComp.
2367  *  \param [in] strictCompoCompare - this parameter is checked only if the
2368  *               *mode of usage* is the first; if it is \a true (default), 
2369  *               then \a a->getNumberOfComponents() must be equal 
2370  *               to the number of specified columns, else this is not required.
2371  *  \throw If \a a is NULL.
2372  *  \throw If \a a is not allocated.
2373  *  \throw If \a this is not allocated.
2374  *  \throw If any index of tuple/component given by <em>bgTuples / bgComp</em> is
2375  *         out of a valid range for \a this array.
2376  *  \throw In the first *mode of usage*, if <em>strictCompoCompare == true </em> and
2377  *         if <em> a->getNumberOfComponents() != (endComp - bgComp) </em>.
2378  *  \throw In the second *mode of usage*, if \a a->getNumberOfTuples() != 1 or
2379  *         <em> a->getNumberOfComponents() != (endComp - bgComp)</em>.
2380  *
2381  *  \ref py_mcdataarraydouble_setpartofvalues2 "Here is a Python example".
2382  */
2383 void DataArrayDouble::setPartOfValues2(const DataArrayDouble *a, const int *bgTuples, const int *endTuples, const int *bgComp, const int *endComp, bool strictCompoCompare)
2384 {
2385   if(!a)
2386     throw INTERP_KERNEL::Exception("DataArrayDouble::setPartOfValues2 : input DataArrayDouble is NULL !");
2387   const char msg[]="DataArrayDouble::setPartOfValues2";
2388   checkAllocated();
2389   a->checkAllocated();
2390   int nbComp=getNumberOfComponents();
2391   int nbOfTuples=getNumberOfTuples();
2392   for(const int *z=bgComp;z!=endComp;z++)
2393     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
2394   int newNbOfTuples=(int)std::distance(bgTuples,endTuples);
2395   int newNbOfComp=(int)std::distance(bgComp,endComp);
2396   bool assignTech=true;
2397   if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
2398     {
2399       if(strictCompoCompare)
2400         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
2401     }
2402   else
2403     {
2404       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
2405       assignTech=false;
2406     }
2407   double *pt=getPointer();
2408   const double *srcPt=a->getConstPointer();
2409   if(assignTech)
2410     {    
2411       for(const int *w=bgTuples;w!=endTuples;w++)
2412         {
2413           DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
2414           for(const int *z=bgComp;z!=endComp;z++,srcPt++)
2415             {    
2416               pt[(std::size_t)(*w)*nbComp+(*z)]=*srcPt;
2417             }
2418         }
2419     }
2420   else
2421     {
2422       for(const int *w=bgTuples;w!=endTuples;w++)
2423         {
2424           const double *srcPt2=srcPt;
2425           DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
2426           for(const int *z=bgComp;z!=endComp;z++,srcPt2++)
2427             {    
2428               pt[(std::size_t)(*w)*nbComp+(*z)]=*srcPt2;
2429             }
2430         }
2431     }
2432 }
2433
2434 /*!
2435  * Assign a given value to values at specified tuples and components of \a this array.
2436  * The tuples and components to assign to are defined by C arrays of indices.
2437  *  \param [in] a - the value to assign.
2438  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
2439  *              assign \a a to.
2440  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
2441  *              pointer to a tuple index (\a pi) varies as this: 
2442  *              \a bgTuples <= \a pi < \a endTuples.
2443  *  \param [in] bgComp - pointer to an array of component indices of \a this array to
2444  *              assign \a a to.
2445  *  \param [in] endComp - specifies the end of the array \a bgTuples, so that
2446  *              pointer to a component index (\a pi) varies as this: 
2447  *              \a bgComp <= \a pi < \a endComp.
2448  *  \throw If \a this is not allocated.
2449  *  \throw If any index of tuple/component given by <em>bgTuples / bgComp</em> is
2450  *         out of a valid range for \a this array.
2451  *
2452  *  \ref py_mcdataarraydouble_setpartofvaluessimple2 "Here is a Python example".
2453  */
2454 void DataArrayDouble::setPartOfValuesSimple2(double a, const int *bgTuples, const int *endTuples, const int *bgComp, const int *endComp)
2455 {
2456   checkAllocated();
2457   int nbComp=getNumberOfComponents();
2458   int nbOfTuples=getNumberOfTuples();
2459   for(const int *z=bgComp;z!=endComp;z++)
2460     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
2461   double *pt=getPointer();
2462   for(const int *w=bgTuples;w!=endTuples;w++)
2463     for(const int *z=bgComp;z!=endComp;z++)
2464       {
2465         DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
2466         pt[(std::size_t)(*w)*nbComp+(*z)]=a;
2467       }
2468 }
2469
2470 /*!
2471  * Copy all values from another DataArrayDouble (\a a) into specified tuples and 
2472  * components of \a this array. Textual data is not copied.
2473  * The tuples to assign to are defined by a C array of indices.
2474  * The components to assign to are defined by three values similar to parameters of
2475  * the Python function \c range(\c start,\c stop,\c step).
2476  * There are two *modes of usage*:
2477  * - If \a a->getNbOfElems() equals to number of values to assign to, then every value
2478  *   of \a a is assigned to its own location within \a this array. 
2479  * - If \a a includes one tuple, then all values of \a a are assigned to the specified
2480  *   components of every specified tuple of \a this array. In this mode it is required
2481  *   that \a a->getNumberOfComponents() equals to the number of specified components.
2482  *
2483  *  \param [in] a - the array to copy values from.
2484  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
2485  *              assign values of \a a to.
2486  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
2487  *              pointer to a tuple index <em>(pi)</em> varies as this: 
2488  *              \a bgTuples <= \a pi < \a endTuples.
2489  *  \param [in] bgComp - index of the first component of \a this array to assign to.
2490  *  \param [in] endComp - index of the component before which the components to assign
2491  *              to are located.
2492  *  \param [in] stepComp - index increment to get index of the next component to assign to.
2493  *  \param [in] strictCompoCompare - this parameter is checked only in the first
2494  *               *mode of usage*; if \a strictCompoCompare is \a true (default), 
2495  *               then \a a->getNumberOfComponents() must be equal 
2496  *               to the number of specified columns, else this is not required.
2497  *  \throw If \a a is NULL.
2498  *  \throw If \a a is not allocated.
2499  *  \throw If \a this is not allocated.
2500  *  \throw If any index of tuple given by \a bgTuples is out of a valid range for 
2501  *         \a this array.
2502  *  \throw In the first *mode of usage*, if <em>strictCompoCompare == true </em> and
2503  *         if <em> a->getNumberOfComponents()</em> is unequal to the number of components
2504  *         defined by <em>(bgComp,endComp,stepComp)</em>.
2505  *  \throw In the second *mode of usage*, if \a a->getNumberOfTuples() != 1 or
2506  *         <em> a->getNumberOfComponents()</em> is unequal to the number of components
2507  *         defined by <em>(bgComp,endComp,stepComp)</em>.
2508  *  \throw If parameters specifying components to assign to, do not give a
2509  *            non-empty range of increasing indices or indices are out of a valid range
2510  *            for \this array.
2511  *
2512  *  \ref py_mcdataarraydouble_setpartofvalues3 "Here is a Python example".
2513  */
2514 void DataArrayDouble::setPartOfValues3(const DataArrayDouble *a, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare)
2515 {
2516   if(!a)
2517     throw INTERP_KERNEL::Exception("DataArrayDouble::setPartOfValues3 : input DataArrayDouble is NULL !");
2518   const char msg[]="DataArrayDouble::setPartOfValues3";
2519   checkAllocated();
2520   a->checkAllocated();
2521   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
2522   int nbComp=getNumberOfComponents();
2523   int nbOfTuples=getNumberOfTuples();
2524   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
2525   int newNbOfTuples=(int)std::distance(bgTuples,endTuples);
2526   bool assignTech=true;
2527   if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
2528     {
2529       if(strictCompoCompare)
2530         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
2531     }
2532   else
2533     {
2534       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
2535       assignTech=false;
2536     }
2537   double *pt=getPointer()+bgComp;
2538   const double *srcPt=a->getConstPointer();
2539   if(assignTech)
2540     {
2541       for(const int *w=bgTuples;w!=endTuples;w++)
2542         for(int j=0;j<newNbOfComp;j++,srcPt++)
2543           {
2544             DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
2545             pt[(std::size_t)(*w)*nbComp+j*stepComp]=*srcPt;
2546           }
2547     }
2548   else
2549     {
2550       for(const int *w=bgTuples;w!=endTuples;w++)
2551         {
2552           const double *srcPt2=srcPt;
2553           for(int j=0;j<newNbOfComp;j++,srcPt2++)
2554             {
2555               DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
2556               pt[(std::size_t)(*w)*nbComp+j*stepComp]=*srcPt2;
2557             }
2558         }
2559     }
2560 }
2561
2562 /*!
2563  * Assign a given value to values at specified tuples and components of \a this array.
2564  * The tuples to assign to are defined by a C array of indices.
2565  * The components to assign to are defined by three values similar to parameters of
2566  * the Python function \c range(\c start,\c stop,\c step).
2567  *  \param [in] a - the value to assign.
2568  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
2569  *              assign \a a to.
2570  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
2571  *              pointer to a tuple index <em>(pi)</em> varies as this: 
2572  *              \a bgTuples <= \a pi < \a endTuples.
2573  *  \param [in] bgComp - index of the first component of \a this array to assign to.
2574  *  \param [in] endComp - index of the component before which the components to assign
2575  *              to are located.
2576  *  \param [in] stepComp - index increment to get index of the next component to assign to.
2577  *  \throw If \a this is not allocated.
2578  *  \throw If any index of tuple given by \a bgTuples is out of a valid range for 
2579  *         \a this array.
2580  *  \throw If parameters specifying components to assign to, do not give a
2581  *            non-empty range of increasing indices or indices are out of a valid range
2582  *            for \this array.
2583  *
2584  *  \ref py_mcdataarraydouble_setpartofvaluessimple3 "Here is a Python example".
2585  */
2586 void DataArrayDouble::setPartOfValuesSimple3(double a, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp)
2587 {
2588   const char msg[]="DataArrayDouble::setPartOfValuesSimple3";
2589   checkAllocated();
2590   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
2591   int nbComp=getNumberOfComponents();
2592   int nbOfTuples=getNumberOfTuples();
2593   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
2594   double *pt=getPointer()+bgComp;
2595   for(const int *w=bgTuples;w!=endTuples;w++)
2596     for(int j=0;j<newNbOfComp;j++)
2597       {
2598         DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
2599         pt[(std::size_t)(*w)*nbComp+j*stepComp]=a;
2600       }
2601 }
2602
2603 /*!
2604  * Copy all values from another DataArrayDouble into specified tuples and components
2605  * of \a this array. Textual data is not copied.
2606  * The tree parameters defining set of indices of tuples and components are similar to
2607  * the tree parameters of the Python function \c range(\c start,\c stop,\c step).
2608  *  \param [in] a - the array to copy values from.
2609  *  \param [in] bgTuples - index of the first tuple of \a this array to assign values to.
2610  *  \param [in] endTuples - index of the tuple before which the tuples to assign to
2611  *              are located.
2612  *  \param [in] stepTuples - index increment to get index of the next tuple to assign to.
2613  *  \param [in] bgComp - pointer to an array of component indices of \a this array to
2614  *              assign \a a to.
2615  *  \param [in] endComp - specifies the end of the array \a bgTuples, so that
2616  *              pointer to a component index (\a pi) varies as this: 
2617  *              \a bgComp <= \a pi < \a endComp.
2618  *  \param [in] strictCompoCompare - if \a true (by default), then \a a->getNumberOfComponents() 
2619  *              must be equal to the number of columns to assign to, else an
2620  *              exception is thrown; if \a false, then it is only required that \a
2621  *              a->getNbOfElems() equals to number of values to assign to (this condition
2622  *              must be respected even if \a strictCompoCompare is \a true). The number of 
2623  *              values to assign to is given by following Python expression:
2624  *              \a nbTargetValues = 
2625  *              \c len(\c range(\a bgTuples,\a endTuples,\a stepTuples)) *
2626  *              \c len(\c range(\a bgComp,\a endComp,\a stepComp)).
2627  *  \throw If \a a is NULL.
2628  *  \throw If \a a is not allocated.
2629  *  \throw If \a this is not allocated.
2630  *  \throw If parameters specifying tuples and components to assign to do not give a
2631  *            non-empty range of increasing indices.
2632  *  \throw If \a a->getNbOfElems() != \a nbTargetValues.
2633  *  \throw If \a strictCompoCompare == \a true && \a a->getNumberOfComponents() !=
2634  *            \c len(\c range(\a bgComp,\a endComp,\a stepComp)).
2635  *
2636  */
2637 void DataArrayDouble::setPartOfValues4(const DataArrayDouble *a, int bgTuples, int endTuples, int stepTuples, const int *bgComp, const int *endComp, bool strictCompoCompare)
2638 {
2639   if(!a)
2640     throw INTERP_KERNEL::Exception("DataArrayDouble::setPartOfValues4 : input DataArrayDouble is NULL !");
2641   const char msg[]="DataArrayDouble::setPartOfValues4";
2642   checkAllocated();
2643   a->checkAllocated();
2644   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
2645   int newNbOfComp=(int)std::distance(bgComp,endComp);
2646   int nbComp=getNumberOfComponents();
2647   for(const int *z=bgComp;z!=endComp;z++)
2648     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
2649   int nbOfTuples=getNumberOfTuples();
2650   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
2651   bool assignTech=true;
2652   if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
2653     {
2654       if(strictCompoCompare)
2655         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
2656     }
2657   else
2658     {
2659       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
2660       assignTech=false;
2661     }
2662   const double *srcPt=a->getConstPointer();
2663   double *pt=getPointer()+bgTuples*nbComp;
2664   if(assignTech)
2665     {
2666       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
2667         for(const int *z=bgComp;z!=endComp;z++,srcPt++)
2668           pt[*z]=*srcPt;
2669     }
2670   else
2671     {
2672       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
2673         {
2674           const double *srcPt2=srcPt;
2675           for(const int *z=bgComp;z!=endComp;z++,srcPt2++)
2676             pt[*z]=*srcPt2;
2677         }
2678     }
2679 }
2680
2681 void DataArrayDouble::setPartOfValuesSimple4(double a, int bgTuples, int endTuples, int stepTuples, const int *bgComp, const int *endComp)
2682 {
2683   const char msg[]="DataArrayDouble::setPartOfValuesSimple4";
2684   checkAllocated();
2685   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
2686   int nbComp=getNumberOfComponents();
2687   for(const int *z=bgComp;z!=endComp;z++)
2688     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
2689   int nbOfTuples=getNumberOfTuples();
2690   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
2691   double *pt=getPointer()+bgTuples*nbComp;
2692   for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
2693     for(const int *z=bgComp;z!=endComp;z++)
2694       pt[*z]=a;
2695 }
2696
2697 /*!
2698  * Copy some tuples from another DataArrayDouble into specified tuples
2699  * of \a this array. Textual data is not copied. Both arrays must have equal number of
2700  * components.
2701  * Both the tuples to assign and the tuples to assign to are defined by a DataArrayInt.
2702  * All components of selected tuples are copied.
2703  *  \param [in] a - the array to copy values from.
2704  *  \param [in] tuplesSelec - the array specifying both source tuples of \a a and
2705  *              target tuples of \a this. \a tuplesSelec has two components, and the
2706  *              first component specifies index of the source tuple and the second
2707  *              one specifies index of the target tuple.
2708  *  \throw If \a this is not allocated.
2709  *  \throw If \a a is NULL.
2710  *  \throw If \a a is not allocated.
2711  *  \throw If \a tuplesSelec is NULL.
2712  *  \throw If \a tuplesSelec is not allocated.
2713  *  \throw If <em>this->getNumberOfComponents() != a->getNumberOfComponents()</em>.
2714  *  \throw If \a tuplesSelec->getNumberOfComponents() != 2.
2715  *  \throw If any tuple index given by \a tuplesSelec is out of a valid range for 
2716  *         the corresponding (\a this or \a a) array.
2717  */
2718 void DataArrayDouble::setPartOfValuesAdv(const DataArrayDouble *a, const DataArrayInt *tuplesSelec)
2719 {
2720   if(!a || !tuplesSelec)
2721     throw INTERP_KERNEL::Exception("DataArrayDouble::setPartOfValuesAdv : input DataArrayDouble is NULL !");
2722   checkAllocated();
2723   a->checkAllocated();
2724   tuplesSelec->checkAllocated();
2725   int nbOfComp=getNumberOfComponents();
2726   if(nbOfComp!=a->getNumberOfComponents())
2727     throw INTERP_KERNEL::Exception("DataArrayDouble::setPartOfValuesAdv : This and a do not have the same number of components !");
2728   if(tuplesSelec->getNumberOfComponents()!=2)
2729     throw INTERP_KERNEL::Exception("DataArrayDouble::setPartOfValuesAdv : Expecting to have a tuple selector DataArrayInt instance with exactly 2 components !");
2730   int thisNt=getNumberOfTuples();
2731   int aNt=a->getNumberOfTuples();
2732   double *valsToSet=getPointer();
2733   const double *valsSrc=a->getConstPointer();
2734   for(const int *tuple=tuplesSelec->begin();tuple!=tuplesSelec->end();tuple+=2)
2735     {
2736       if(tuple[1]>=0 && tuple[1]<aNt)
2737         {
2738           if(tuple[0]>=0 && tuple[0]<thisNt)
2739             std::copy(valsSrc+nbOfComp*tuple[1],valsSrc+nbOfComp*(tuple[1]+1),valsToSet+nbOfComp*tuple[0]);
2740           else
2741             {
2742               std::ostringstream oss; oss << "DataArrayDouble::setPartOfValuesAdv : Tuple #" << std::distance(tuplesSelec->begin(),tuple)/2;
2743               oss << " of 'tuplesSelec' request of tuple id #" << tuple[0] << " in 'this' ! It should be in [0," << thisNt << ") !";
2744               throw INTERP_KERNEL::Exception(oss.str().c_str());
2745             }
2746         }
2747       else
2748         {
2749           std::ostringstream oss; oss << "DataArrayDouble::setPartOfValuesAdv : Tuple #" << std::distance(tuplesSelec->begin(),tuple)/2;
2750           oss << " of 'tuplesSelec' request of tuple id #" << tuple[1] << " in 'a' ! It should be in [0," << aNt << ") !";
2751           throw INTERP_KERNEL::Exception(oss.str().c_str());
2752         }
2753     }
2754 }
2755
2756 /*!
2757  * Copy some tuples from another DataArrayDouble (\a aBase) into contiguous tuples
2758  * of \a this array. Textual data is not copied. Both arrays must have equal number of
2759  * components.
2760  * The tuples to assign to are defined by index of the first tuple, and
2761  * their number is defined by \a tuplesSelec->getNumberOfTuples().
2762  * The tuples to copy are defined by values of a DataArrayInt.
2763  * All components of selected tuples are copied.
2764  *  \param [in] tupleIdStart - index of the first tuple of \a this array to assign
2765  *              values to.
2766  *  \param [in] aBase - the array to copy values from.
2767  *  \param [in] tuplesSelec - the array specifying tuples of \a a to copy.
2768  *  \throw If \a this is not allocated.
2769  *  \throw If \a aBase is NULL.
2770  *  \throw If \a aBase is not allocated.
2771  *  \throw If \a tuplesSelec is NULL.
2772  *  \throw If \a tuplesSelec is not allocated.
2773  *  \throw If <em>this->getNumberOfComponents() != aBase->getNumberOfComponents()</em>.
2774  *  \throw If \a tuplesSelec->getNumberOfComponents() != 1.
2775  *  \throw If <em>tupleIdStart + tuplesSelec->getNumberOfTuples() > this->getNumberOfTuples().</em>
2776  *  \throw If any tuple index given by \a tuplesSelec is out of a valid range for 
2777  *         \a aBase array.
2778  */
2779 void DataArrayDouble::setContigPartOfSelectedValues(int tupleIdStart, const DataArray *aBase, const DataArrayInt *tuplesSelec)
2780 {
2781   if(!aBase || !tuplesSelec)
2782     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues : input DataArray is NULL !");
2783   const DataArrayDouble *a=dynamic_cast<const DataArrayDouble *>(aBase);
2784   if(!a)
2785     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues : input DataArray aBase is not a DataArrayDouble !");
2786   checkAllocated();
2787   a->checkAllocated();
2788   tuplesSelec->checkAllocated();
2789   int nbOfComp=getNumberOfComponents();
2790   if(nbOfComp!=a->getNumberOfComponents())
2791     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues : This and a do not have the same number of components !");
2792   if(tuplesSelec->getNumberOfComponents()!=1)
2793     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues : Expecting to have a tuple selector DataArrayInt instance with exactly 1 component !");
2794   int thisNt=getNumberOfTuples();
2795   int aNt=a->getNumberOfTuples();
2796   int nbOfTupleToWrite=tuplesSelec->getNumberOfTuples();
2797   double *valsToSet=getPointer()+tupleIdStart*nbOfComp;
2798   if(tupleIdStart+nbOfTupleToWrite>thisNt)
2799     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues : invalid number range of values to write !");
2800   const double *valsSrc=a->getConstPointer();
2801   for(const int *tuple=tuplesSelec->begin();tuple!=tuplesSelec->end();tuple++,valsToSet+=nbOfComp)
2802     {
2803       if(*tuple>=0 && *tuple<aNt)
2804         {
2805           std::copy(valsSrc+nbOfComp*(*tuple),valsSrc+nbOfComp*(*tuple+1),valsToSet);
2806         }
2807       else
2808         {
2809           std::ostringstream oss; oss << "DataArrayDouble::setContigPartOfSelectedValues : Tuple #" << std::distance(tuplesSelec->begin(),tuple);
2810           oss << " of 'tuplesSelec' request of tuple id #" << *tuple << " in 'a' ! It should be in [0," << aNt << ") !";
2811           throw INTERP_KERNEL::Exception(oss.str().c_str());
2812         }
2813     }
2814 }
2815
2816 /*!
2817  * Copy some tuples from another DataArrayDouble (\a aBase) into contiguous tuples
2818  * of \a this array. Textual data is not copied. Both arrays must have equal number of
2819  * components.
2820  * The tuples to copy are defined by three values similar to parameters of
2821  * the Python function \c range(\c start,\c stop,\c step).
2822  * The tuples to assign to are defined by index of the first tuple, and
2823  * their number is defined by number of tuples to copy.
2824  * All components of selected tuples are copied.
2825  *  \param [in] tupleIdStart - index of the first tuple of \a this array to assign
2826  *              values to.
2827  *  \param [in] aBase - the array to copy values from.
2828  *  \param [in] bg - index of the first tuple to copy of the array \a aBase.
2829  *  \param [in] end2 - index of the tuple of \a aBase before which the tuples to copy
2830  *              are located.
2831  *  \param [in] step - index increment to get index of the next tuple to copy.
2832  *  \throw If \a this is not allocated.
2833  *  \throw If \a aBase is NULL.
2834  *  \throw If \a aBase is not allocated.
2835  *  \throw If <em>this->getNumberOfComponents() != aBase->getNumberOfComponents()</em>.
2836  *  \throw If <em>tupleIdStart + len(range(bg,end2,step)) > this->getNumberOfTuples().</em>
2837  *  \throw If parameters specifying tuples to copy, do not give a
2838  *            non-empty range of increasing indices or indices are out of a valid range
2839  *            for the array \a aBase.
2840  */
2841 void DataArrayDouble::setContigPartOfSelectedValues2(int tupleIdStart, const DataArray *aBase, int bg, int end2, int step)
2842 {
2843   if(!aBase)
2844     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues2 : input DataArray is NULL !");
2845   const DataArrayDouble *a=dynamic_cast<const DataArrayDouble *>(aBase);
2846   if(!a)
2847     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues2 : input DataArray aBase is not a DataArrayDouble !");
2848   checkAllocated();
2849   a->checkAllocated();
2850   int nbOfComp=getNumberOfComponents();
2851   const char msg[]="DataArrayDouble::setContigPartOfSelectedValues2";
2852   int nbOfTupleToWrite=DataArray::GetNumberOfItemGivenBES(bg,end2,step,msg);
2853   if(nbOfComp!=a->getNumberOfComponents())
2854     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues2 : This and a do not have the same number of components !");
2855   int thisNt=getNumberOfTuples();
2856   int aNt=a->getNumberOfTuples();
2857   double *valsToSet=getPointer()+tupleIdStart*nbOfComp;
2858   if(tupleIdStart+nbOfTupleToWrite>thisNt)
2859     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues2 : invalid number range of values to write !");
2860   if(end2>aNt)
2861     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues2 : invalid range of values to read !");
2862   const double *valsSrc=a->getConstPointer()+bg*nbOfComp;
2863   for(int i=0;i<nbOfTupleToWrite;i++,valsToSet+=nbOfComp,valsSrc+=step*nbOfComp)
2864     {
2865       std::copy(valsSrc,valsSrc+nbOfComp,valsToSet);
2866     }
2867 }
2868
2869 /*!
2870  * Returns a value located at specified tuple and component.
2871  * This method is equivalent to DataArrayDouble::getIJ() except that validity of
2872  * parameters is checked. So this method is safe but expensive if used to go through
2873  * all values of \a this.
2874  *  \param [in] tupleId - index of tuple of interest.
2875  *  \param [in] compoId - index of component of interest.
2876  *  \return double - value located by \a tupleId and \a compoId.
2877  *  \throw If \a this is not allocated.
2878  *  \throw If condition <em>( 0 <= tupleId < this->getNumberOfTuples() )</em> is violated.
2879  *  \throw If condition <em>( 0 <= compoId < this->getNumberOfComponents() )</em> is violated.
2880  */
2881 double DataArrayDouble::getIJSafe(int tupleId, int compoId) const
2882 {
2883   checkAllocated();
2884   if(tupleId<0 || tupleId>=getNumberOfTuples())
2885     {
2886       std::ostringstream oss; oss << "DataArrayDouble::getIJSafe : request for tupleId " << tupleId << " should be in [0," << getNumberOfTuples() << ") !";
2887       throw INTERP_KERNEL::Exception(oss.str().c_str());
2888     }
2889   if(compoId<0 || compoId>=getNumberOfComponents())
2890     {
2891       std::ostringstream oss; oss << "DataArrayDouble::getIJSafe : request for compoId " << compoId << " should be in [0," << getNumberOfComponents() << ") !";
2892       throw INTERP_KERNEL::Exception(oss.str().c_str());
2893     }
2894   return _mem[tupleId*_info_on_compo.size()+compoId];
2895 }
2896
2897 /*!
2898  * Returns the first value of \a this. 
2899  *  \return double - the last value of \a this array.
2900  *  \throw If \a this is not allocated.
2901  *  \throw If \a this->getNumberOfComponents() != 1.
2902  *  \throw If \a this->getNumberOfTuples() < 1.
2903  */
2904 double DataArrayDouble::front() const
2905 {
2906   checkAllocated();
2907   if(getNumberOfComponents()!=1)
2908     throw INTERP_KERNEL::Exception("DataArrayDouble::front : number of components not equal to one !");
2909   int nbOfTuples=getNumberOfTuples();
2910   if(nbOfTuples<1)
2911     throw INTERP_KERNEL::Exception("DataArrayDouble::front : number of tuples must be >= 1 !");
2912   return *(getConstPointer());
2913 }
2914
2915 /*!
2916  * Returns the last value of \a this. 
2917  *  \return double - the last value of \a this array.
2918  *  \throw If \a this is not allocated.
2919  *  \throw If \a this->getNumberOfComponents() != 1.
2920  *  \throw If \a this->getNumberOfTuples() < 1.
2921  */
2922 double DataArrayDouble::back() const
2923 {
2924   checkAllocated();
2925   if(getNumberOfComponents()!=1)
2926     throw INTERP_KERNEL::Exception("DataArrayDouble::back : number of components not equal to one !");
2927   int nbOfTuples=getNumberOfTuples();
2928   if(nbOfTuples<1)
2929     throw INTERP_KERNEL::Exception("DataArrayDouble::back : number of tuples must be >= 1 !");
2930   return *(getConstPointer()+nbOfTuples-1);
2931 }
2932
2933 void DataArrayDouble::SetArrayIn(DataArrayDouble *newArray, DataArrayDouble* &arrayToSet)
2934 {
2935   if(newArray!=arrayToSet)
2936     {
2937       if(arrayToSet)
2938         arrayToSet->decrRef();
2939       arrayToSet=newArray;
2940       if(arrayToSet)
2941         arrayToSet->incrRef();
2942     }
2943 }
2944
2945 /*!
2946  * Sets a C array to be used as raw data of \a this. The previously set info
2947  *  of components is retained and re-sized. 
2948  * For more info see \ref MEDCouplingArraySteps1.
2949  *  \param [in] array - the C array to be used as raw data of \a this.
2950  *  \param [in] ownership - if \a true, \a array will be deallocated at destruction of \a this.
2951  *  \param [in] type - specifies how to deallocate \a array. If \a type == ParaMEDMEM::CPP_DEALLOC,
2952  *                     \c delete [] \c array; will be called. If \a type == ParaMEDMEM::C_DEALLOC,
2953  *                     \c free(\c array ) will be called.
2954  *  \param [in] nbOfTuple - new number of tuples in \a this.
2955  *  \param [in] nbOfCompo - new number of components in \a this.
2956  */
2957 void DataArrayDouble::useArray(const double *array, bool ownership, DeallocType type, int nbOfTuple, int nbOfCompo)
2958 {
2959   _info_on_compo.resize(nbOfCompo);
2960   _mem.useArray(array,ownership,type,(std::size_t)nbOfTuple*nbOfCompo);
2961   declareAsNew();
2962 }
2963
2964 void DataArrayDouble::useExternalArrayWithRWAccess(const double *array, int nbOfTuple, int nbOfCompo)
2965 {
2966   _info_on_compo.resize(nbOfCompo);
2967   _mem.useExternalArrayWithRWAccess(array,(std::size_t)nbOfTuple*nbOfCompo);
2968   declareAsNew();
2969 }
2970
2971 /*!
2972  * Checks if 0.0 value is present in \a this array. If it is the case, an exception
2973  * is thrown.
2974  * \throw If zero is found in \a this array.
2975  */
2976 void DataArrayDouble::checkNoNullValues() const
2977 {
2978   const double *tmp=getConstPointer();
2979   std::size_t nbOfElems=getNbOfElems();
2980   const double *where=std::find(tmp,tmp+nbOfElems,0.);
2981   if(where!=tmp+nbOfElems)
2982     throw INTERP_KERNEL::Exception("A value 0.0 have been detected !");
2983 }
2984
2985 /*!
2986  * Computes minimal and maximal value in each component. An output array is filled
2987  * with \c 2 * \a this->getNumberOfComponents() values, so the caller is to allocate
2988  * enough memory before calling this method.
2989  *  \param [out] bounds - array of size at least 2 *\a this->getNumberOfComponents().
2990  *               It is filled as follows:<br>
2991  *               \a bounds[0] = \c min_of_component_0 <br>
2992  *               \a bounds[1] = \c max_of_component_0 <br>
2993  *               \a bounds[2] = \c min_of_component_1 <br>
2994  *               \a bounds[3] = \c max_of_component_1 <br>
2995  *               ...
2996  */
2997 void DataArrayDouble::getMinMaxPerComponent(double *bounds) const
2998 {
2999   checkAllocated();
3000   int dim=getNumberOfComponents();
3001   for (int idim=0; idim<dim; idim++)
3002     {
3003       bounds[idim*2]=std::numeric_limits<double>::max();
3004       bounds[idim*2+1]=-std::numeric_limits<double>::max();
3005     } 
3006   const double *ptr=getConstPointer();
3007   int nbOfTuples=getNumberOfTuples();
3008   for(int i=0;i<nbOfTuples;i++)
3009     {
3010       for(int idim=0;idim<dim;idim++)
3011         {
3012           if(bounds[idim*2]>ptr[i*dim+idim])
3013             {
3014               bounds[idim*2]=ptr[i*dim+idim];
3015             }
3016           if(bounds[idim*2+1]<ptr[i*dim+idim])
3017             {
3018               bounds[idim*2+1]=ptr[i*dim+idim];
3019             }
3020         }
3021     }
3022 }
3023
3024 /*!
3025  * This method retrieves a newly allocated DataArrayDouble instance having same number of tuples than \a this and twice number of components than \a this
3026  * to store both the min and max per component of each tuples. 
3027  * \param [in] epsilon the width of the bbox (identical in each direction) - 0.0 by default
3028  *
3029  * \return a newly created DataArrayDouble instance having \c this->getNumberOfTuples() tuples and 2 * \c this->getNumberOfComponent() components
3030  *
3031  * \throw If \a this is not allocated yet.
3032  */
3033 DataArrayDouble *DataArrayDouble::computeBBoxPerTuple(double epsilon) const
3034 {
3035   checkAllocated();
3036   const double *dataPtr=getConstPointer();
3037   int nbOfCompo=getNumberOfComponents();
3038   int nbTuples=getNumberOfTuples();
3039   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> bbox=DataArrayDouble::New();
3040   bbox->alloc(nbTuples,2*nbOfCompo);
3041   double *bboxPtr=bbox->getPointer();
3042   for(int i=0;i<nbTuples;i++)
3043     {
3044       for(int j=0;j<nbOfCompo;j++)
3045         {
3046           bboxPtr[2*nbOfCompo*i+2*j]=dataPtr[nbOfCompo*i+j]-epsilon;
3047           bboxPtr[2*nbOfCompo*i+2*j+1]=dataPtr[nbOfCompo*i+j]+epsilon;
3048         }
3049     }
3050   return bbox.retn();
3051 }
3052
3053 /*!
3054  * For each tuples **t** in \a other, this method retrieves tuples in \a this that are equal to **t**.
3055  * Two tuples are considered equal if the euclidian distance between the two tuples is lower than \a eps.
3056  * 
3057  * \param [in] other a DataArrayDouble having same number of components than \a this.
3058  * \param [in] eps absolute precision representing distance (using infinite norm) between 2 tuples behind which 2 tuples are considered equal.
3059  * \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.
3060  *             \a cI allows to extract information in \a c.
3061  * \param [out] cI is an indirection array that allows to extract the data contained in \a c.
3062  *
3063  * \throw In case of:
3064  *  - \a this is not allocated
3065  *  - \a other is not allocated or null
3066  *  - \a this and \a other do not have the same number of components
3067  *  - if number of components of \a this is not in [1,2,3]
3068  *
3069  * \sa MEDCouplingPointSet::getNodeIdsNearPoints, DataArrayDouble::getDifferentValues
3070  */
3071 void DataArrayDouble::computeTupleIdsNearTuples(const DataArrayDouble *other, double eps, DataArrayInt *& c, DataArrayInt *& cI) const
3072 {
3073   if(!other)
3074     throw INTERP_KERNEL::Exception("DataArrayDouble::computeTupleIdsNearTuples : input pointer other is null !");
3075   checkAllocated();
3076   other->checkAllocated();
3077   int nbOfCompo=getNumberOfComponents();
3078   int otherNbOfCompo=other->getNumberOfComponents();
3079   if(nbOfCompo!=otherNbOfCompo)
3080     throw INTERP_KERNEL::Exception("DataArrayDouble::computeTupleIdsNearTuples : number of components should be equal between this and other !");
3081   int nbOfTuplesOther=other->getNumberOfTuples();
3082   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cArr(DataArrayInt::New()),cIArr(DataArrayInt::New()); cArr->alloc(0,1); cIArr->pushBackSilent(0);
3083   switch(nbOfCompo)
3084     {
3085     case 3:
3086       {
3087         BBTreePts<3,int> myTree(begin(),0,0,getNumberOfTuples(),eps);
3088         FindTupleIdsNearTuplesAlg<3>(myTree,other->getConstPointer(),nbOfTuplesOther,eps,cArr,cIArr);
3089         break;
3090       }
3091     case 2:
3092       {
3093         BBTreePts<2,int> myTree(begin(),0,0,getNumberOfTuples(),eps);
3094         FindTupleIdsNearTuplesAlg<2>(myTree,other->getConstPointer(),nbOfTuplesOther,eps,cArr,cIArr);
3095         break;
3096       }
3097     case 1:
3098       {
3099         BBTreePts<1,int> myTree(begin(),0,0,getNumberOfTuples(),eps);
3100         FindTupleIdsNearTuplesAlg<1>(myTree,other->getConstPointer(),nbOfTuplesOther,eps,cArr,cIArr);
3101         break;
3102       }
3103     default:
3104       throw INTERP_KERNEL::Exception("Unexpected spacedim of coords for computeTupleIdsNearTuples. Must be 1, 2 or 3.");
3105     }
3106   c=cArr.retn(); cI=cIArr.retn();
3107 }
3108
3109 /*!
3110  * 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
3111  * around origin of 'radius' 1.
3112  * 
3113  * \param [in] eps absolute epsilon. under that value of delta between max and min no scale is performed.
3114  */
3115 void DataArrayDouble::recenterForMaxPrecision(double eps)
3116 {
3117   checkAllocated();
3118   int dim=getNumberOfComponents();
3119   std::vector<double> bounds(2*dim);
3120   getMinMaxPerComponent(&bounds[0]);
3121   for(int i=0;i<dim;i++)
3122     {
3123       double delta=bounds[2*i+1]-bounds[2*i];
3124       double offset=(bounds[2*i]+bounds[2*i+1])/2.;
3125       if(delta>eps)
3126         applyLin(1./delta,-offset/delta,i);
3127       else
3128         applyLin(1.,-offset,i);
3129     }
3130 }
3131
3132 /*!
3133  * Returns the maximal value and its location within \a this one-dimensional array.
3134  *  \param [out] tupleId - index of the tuple holding the maximal value.
3135  *  \return double - the maximal value among all values of \a this array.
3136  *  \throw If \a this->getNumberOfComponents() != 1
3137  *  \throw If \a this->getNumberOfTuples() < 1
3138  */
3139 double DataArrayDouble::getMaxValue(int& tupleId) const
3140 {
3141   checkAllocated();
3142   if(getNumberOfComponents()!=1)
3143     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 !");
3144   int nbOfTuples=getNumberOfTuples();
3145   if(nbOfTuples<=0)
3146     throw INTERP_KERNEL::Exception("DataArrayDouble::getMaxValue : array exists but number of tuples must be > 0 !");
3147   const double *vals=getConstPointer();
3148   const double *loc=std::max_element(vals,vals+nbOfTuples);
3149   tupleId=(int)std::distance(vals,loc);
3150   return *loc;
3151 }
3152
3153 /*!
3154  * Returns the maximal value within \a this array that is allowed to have more than
3155  *  one component.
3156  *  \return double - the maximal value among all values of \a this array.
3157  *  \throw If \a this is not allocated.
3158  */
3159 double DataArrayDouble::getMaxValueInArray() const
3160 {
3161   checkAllocated();
3162   const double *loc=std::max_element(begin(),end());
3163   return *loc;
3164 }
3165
3166 /*!
3167  * Returns the maximal value and all its locations within \a this one-dimensional array.
3168  *  \param [out] tupleIds - a new instance of DataArrayInt containg indices of
3169  *               tuples holding the maximal value. The caller is to delete it using
3170  *               decrRef() as it is no more needed.
3171  *  \return double - the maximal value among all values of \a this array.
3172  *  \throw If \a this->getNumberOfComponents() != 1
3173  *  \throw If \a this->getNumberOfTuples() < 1
3174  */
3175 double DataArrayDouble::getMaxValue2(DataArrayInt*& tupleIds) const
3176 {
3177   int tmp;
3178   tupleIds=0;
3179   double ret=getMaxValue(tmp);
3180   tupleIds=getIdsInRange(ret,ret);
3181   return ret;
3182 }
3183
3184 /*!
3185  * Returns the minimal value and its location within \a this one-dimensional array.
3186  *  \param [out] tupleId - index of the tuple holding the minimal value.
3187  *  \return double - the minimal value among all values of \a this array.
3188  *  \throw If \a this->getNumberOfComponents() != 1
3189  *  \throw If \a this->getNumberOfTuples() < 1
3190  */
3191 double DataArrayDouble::getMinValue(int& tupleId) const
3192 {
3193   checkAllocated();
3194   if(getNumberOfComponents()!=1)
3195     throw INTERP_KERNEL::Exception("DataArrayDouble::getMinValue : must be applied on DataArrayDouble with only one component, you can call 'rearrange' method before call 'getMinValueInArray' method !");
3196   int nbOfTuples=getNumberOfTuples();
3197   if(nbOfTuples<=0)
3198     throw INTERP_KERNEL::Exception("DataArrayDouble::getMinValue : array exists but number of tuples must be > 0 !");
3199   const double *vals=getConstPointer();
3200   const double *loc=std::min_element(vals,vals+nbOfTuples);
3201   tupleId=(int)std::distance(vals,loc);
3202   return *loc;
3203 }
3204
3205 /*!
3206  * Returns the minimal value within \a this array that is allowed to have more than
3207  *  one component.
3208  *  \return double - the minimal value among all values of \a this array.
3209  *  \throw If \a this is not allocated.
3210  */
3211 double DataArrayDouble::getMinValueInArray() const
3212 {
3213   checkAllocated();
3214   const double *loc=std::min_element(begin(),end());
3215   return *loc;
3216 }
3217
3218 /*!
3219  * Returns the minimal value and all its locations within \a this one-dimensional array.
3220  *  \param [out] tupleIds - a new instance of DataArrayInt containg indices of
3221  *               tuples holding the minimal value. The caller is to delete it using
3222  *               decrRef() as it is no more needed.
3223  *  \return double - the minimal value among all values of \a this array.
3224  *  \throw If \a this->getNumberOfComponents() != 1
3225  *  \throw If \a this->getNumberOfTuples() < 1
3226  */
3227 double DataArrayDouble::getMinValue2(DataArrayInt*& tupleIds) const
3228 {
3229   int tmp;
3230   tupleIds=0;
3231   double ret=getMinValue(tmp);
3232   tupleIds=getIdsInRange(ret,ret);
3233   return ret;
3234 }
3235
3236 /*!
3237  * 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.
3238  * This method only works for single component array.
3239  *
3240  * \return a value in [ 0, \c this->getNumberOfTuples() )
3241  *
3242  * \throw If \a this is not allocated
3243  *
3244  */
3245 int DataArrayDouble::count(double value, double eps) const
3246 {
3247   int ret=0;
3248   checkAllocated();
3249   if(getNumberOfComponents()!=1)
3250     throw INTERP_KERNEL::Exception("DataArrayDouble::count : must be applied on DataArrayDouble with only one component, you can call 'rearrange' method before !");
3251   const double *vals=begin();
3252   int nbOfTuples=getNumberOfTuples();
3253   for(int i=0;i<nbOfTuples;i++,vals++)
3254     if(fabs(*vals-value)<=eps)
3255       ret++;
3256   return ret;
3257 }
3258
3259 /*!
3260  * Returns the average value of \a this one-dimensional array.
3261  *  \return double - the average value over all values of \a this array.
3262  *  \throw If \a this->getNumberOfComponents() != 1
3263  *  \throw If \a this->getNumberOfTuples() < 1
3264  */
3265 double DataArrayDouble::getAverageValue() const
3266 {
3267   if(getNumberOfComponents()!=1)
3268     throw INTERP_KERNEL::Exception("DataArrayDouble::getAverageValue : must be applied on DataArrayDouble with only one component, you can call 'rearrange' method before !");
3269   int nbOfTuples=getNumberOfTuples();
3270   if(nbOfTuples<=0)
3271     throw INTERP_KERNEL::Exception("DataArrayDouble::getAverageValue : array exists but number of tuples must be > 0 !");
3272   const double *vals=getConstPointer();
3273   double ret=std::accumulate(vals,vals+nbOfTuples,0.);
3274   return ret/nbOfTuples;
3275 }
3276
3277 /*!
3278  * Returns the Euclidean norm of the vector defined by \a this array.
3279  *  \return double - the value of the Euclidean norm, i.e.
3280  *          the square root of the inner product of vector.
3281  *  \throw If \a this is not allocated.
3282  */
3283 double DataArrayDouble::norm2() const
3284 {
3285   checkAllocated();
3286   double ret=0.;
3287   std::size_t nbOfElems=getNbOfElems();
3288   const double *pt=getConstPointer();
3289   for(std::size_t i=0;i<nbOfElems;i++,pt++)
3290     ret+=(*pt)*(*pt);
3291   return sqrt(ret);
3292 }
3293
3294 /*!
3295  * Returns the maximum norm of the vector defined by \a this array.
3296  *  \return double - the value of the maximum norm, i.e.
3297  *          the maximal absolute value among values of \a this array.
3298  *  \throw If \a this is not allocated.
3299  */
3300 double DataArrayDouble::normMax() const
3301 {
3302   checkAllocated();
3303   double ret=-1.;
3304   std::size_t nbOfElems=getNbOfElems();
3305   const double *pt=getConstPointer();
3306   for(std::size_t i=0;i<nbOfElems;i++,pt++)
3307     {
3308       double val=std::abs(*pt);
3309       if(val>ret)
3310         ret=val;
3311     }
3312   return ret;
3313 }
3314
3315 /*!
3316  * Accumulates values of each component of \a this array.
3317  *  \param [out] res - an array of length \a this->getNumberOfComponents(), allocated 
3318  *         by the caller, that is filled by this method with sum value for each
3319  *         component.
3320  *  \throw If \a this is not allocated.
3321  */
3322 void DataArrayDouble::accumulate(double *res) const
3323 {
3324   checkAllocated();
3325   const double *ptr=getConstPointer();
3326   int nbTuple=getNumberOfTuples();
3327   int nbComps=getNumberOfComponents();
3328   std::fill(res,res+nbComps,0.);
3329   for(int i=0;i<nbTuple;i++)
3330     std::transform(ptr+i*nbComps,ptr+(i+1)*nbComps,res,res,std::plus<double>());
3331 }
3332
3333 /*!
3334  * This method returns the min distance from an external tuple defined by [ \a tupleBg , \a tupleEnd ) to \a this and
3335  * the first tuple in \a this that matches the returned distance. If there is no tuples in \a this an exception will be thrown.
3336  *
3337  *
3338  * \a this is expected to be allocated and expected to have a number of components equal to the distance from \a tupleBg to
3339  * \a tupleEnd. If not an exception will be thrown.
3340  *
3341  * \param [in] tupleBg start pointer (included) of input external tuple
3342  * \param [in] tupleEnd end pointer (not included) of input external tuple
3343  * \param [out] tupleId the tuple id in \a this that matches the min of distance between \a this and input external tuple
3344  * \return the min distance.
3345  * \sa MEDCouplingUMesh::distanceToPoint
3346  */
3347 double DataArrayDouble::distanceToTuple(const double *tupleBg, const double *tupleEnd, int& tupleId) const
3348 {
3349   checkAllocated();
3350   int nbTuple=getNumberOfTuples();
3351   int nbComps=getNumberOfComponents();
3352   if(nbComps!=(int)std::distance(tupleBg,tupleEnd))
3353     { 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()); }
3354   if(nbTuple==0)
3355     throw INTERP_KERNEL::Exception("DataArrayDouble::distanceToTuple : no tuple in this ! No distance to compute !");
3356   double ret0=std::numeric_limits<double>::max();
3357   tupleId=-1;
3358   const double *work=getConstPointer();
3359   for(int i=0;i<nbTuple;i++)
3360     {
3361       double val=0.;
3362       for(int j=0;j<nbComps;j++,work++) 
3363         val+=(*work-tupleBg[j])*((*work-tupleBg[j]));
3364       if(val>=ret0)
3365         continue;
3366       else
3367         { ret0=val; tupleId=i; }
3368     }
3369   return sqrt(ret0);
3370 }
3371
3372 /*!
3373  * Accumulate values of the given component of \a this array.
3374  *  \param [in] compId - the index of the component of interest.
3375  *  \return double - a sum value of \a compId-th component.
3376  *  \throw If \a this is not allocated.
3377  *  \throw If \a the condition ( 0 <= \a compId < \a this->getNumberOfComponents() ) is
3378  *         not respected.
3379  */
3380 double DataArrayDouble::accumulate(int compId) const
3381 {
3382   checkAllocated();
3383   const double *ptr=getConstPointer();
3384   int nbTuple=getNumberOfTuples();
3385   int nbComps=getNumberOfComponents();
3386   if(compId<0 || compId>=nbComps)
3387     throw INTERP_KERNEL::Exception("DataArrayDouble::accumulate : Invalid compId specified : No such nb of components !");
3388   double ret=0.;
3389   for(int i=0;i<nbTuple;i++)
3390     ret+=ptr[i*nbComps+compId];
3391   return ret;
3392 }
3393
3394 /*!
3395  * This method accumulate using addition tuples in \a this using input index array [ \a bgOfIndex, \a endOfIndex ).
3396  * The returned array will have same number of components than \a this and number of tuples equal to
3397  * \c std::distance(bgOfIndex,endOfIndex) \b minus \b one.
3398  *
3399  * The input index array is expected to be ascendingly sorted in which the all referenced ids should be in [0, \c this->getNumberOfTuples).
3400  * 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.
3401  *
3402  * \param [in] bgOfIndex - begin (included) of the input index array.
3403  * \param [in] endOfIndex - end (excluded) of the input index array.
3404  * \return DataArrayDouble * - the new instance having the same number of components than \a this.
3405  * 
3406  * \throw If bgOfIndex or end is NULL.
3407  * \throw If input index array is not ascendingly sorted.
3408  * \throw If there is an id in [ \a bgOfIndex, \a endOfIndex ) not in [0, \c this->getNumberOfTuples).
3409  * \throw If std::distance(bgOfIndex,endOfIndex)==0.
3410  */
3411 DataArrayDouble *DataArrayDouble::accumulatePerChunck(const int *bgOfIndex, const int *endOfIndex) const
3412 {
3413   if(!bgOfIndex || !endOfIndex)
3414     throw INTERP_KERNEL::Exception("DataArrayDouble::accumulatePerChunck : input pointer NULL !");
3415   checkAllocated();
3416   int nbCompo=getNumberOfComponents();
3417   int nbOfTuples=getNumberOfTuples();
3418   int sz=(int)std::distance(bgOfIndex,endOfIndex);
3419   if(sz<1)
3420     throw INTERP_KERNEL::Exception("DataArrayDouble::accumulatePerChunck : invalid size of input index array !");
3421   sz--;
3422   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New(); ret->alloc(sz,nbCompo);
3423   const int *w=bgOfIndex;
3424   if(*w<0 || *w>=nbOfTuples)
3425     throw INTERP_KERNEL::Exception("DataArrayDouble::accumulatePerChunck : The first element of the input index not in [0,nbOfTuples) !");
3426   const double *srcPt=begin()+(*w)*nbCompo;
3427   double *tmp=ret->getPointer();
3428   for(int i=0;i<sz;i++,tmp+=nbCompo,w++)
3429     {
3430       std::fill(tmp,tmp+nbCompo,0.);
3431       if(w[1]>=w[0])
3432         {
3433           for(int j=w[0];j<w[1];j++,srcPt+=nbCompo)
3434             {
3435               if(j>=0 && j<nbOfTuples)
3436                 std::transform(srcPt,srcPt+nbCompo,tmp,tmp,std::plus<double>());
3437               else
3438                 {
3439                   std::ostringstream oss; oss << "DataArrayDouble::accumulatePerChunck : At rank #" << i << " the input index array points to id " << j << " should be in [0," << nbOfTuples << ") !";
3440                   throw INTERP_KERNEL::Exception(oss.str().c_str());
3441                 }
3442             }
3443         }
3444       else
3445         {
3446           std::ostringstream oss; oss << "DataArrayDouble::accumulatePerChunck : At rank #" << i << " the input index array is not in ascendingly sorted.";
3447           throw INTERP_KERNEL::Exception(oss.str().c_str());
3448         }
3449     }
3450   ret->copyStringInfoFrom(*this);
3451   return ret.retn();
3452 }
3453
3454 /*!
3455  * Converts each 2D point defined by the tuple of \a this array from the Polar to the
3456  * Cartesian coordinate system. The two components of the tuple of \a this array are 
3457  * considered to contain (1) radius and (2) angle of the point in the Polar CS.
3458  *  \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
3459  *          contains X and Y coordinates of the point in the Cartesian CS. The caller
3460  *          is to delete this array using decrRef() as it is no more needed. The array
3461  *          does not contain any textual info on components.
3462  *  \throw If \a this->getNumberOfComponents() != 2.
3463  */
3464 DataArrayDouble *DataArrayDouble::fromPolarToCart() const
3465 {
3466   checkAllocated();
3467   int nbOfComp=getNumberOfComponents();
3468   if(nbOfComp!=2)
3469     throw INTERP_KERNEL::Exception("DataArrayDouble::fromPolarToCart : must be an array with exactly 2 components !");
3470   int nbOfTuple=getNumberOfTuples();
3471   DataArrayDouble *ret=DataArrayDouble::New();
3472   ret->alloc(nbOfTuple,2);
3473   double *w=ret->getPointer();
3474   const double *wIn=getConstPointer();
3475   for(int i=0;i<nbOfTuple;i++,w+=2,wIn+=2)
3476     {
3477       w[0]=wIn[0]*cos(wIn[1]);
3478       w[1]=wIn[0]*sin(wIn[1]);
3479     }
3480   return ret;
3481 }
3482
3483 /*!
3484  * Converts each 3D point defined by the tuple of \a this array from the Cylindrical to
3485  * the Cartesian coordinate system. The three components of the tuple of \a this array 
3486  * are considered to contain (1) radius, (2) azimuth and (3) altitude of the point in
3487  * the Cylindrical CS.
3488  *  \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
3489  *          contains X, Y and Z coordinates of the point in the Cartesian CS. The info
3490  *          on the third component is copied from \a this array. The caller
3491  *          is to delete this array using decrRef() as it is no more needed. 
3492  *  \throw If \a this->getNumberOfComponents() != 3.
3493  */
3494 DataArrayDouble *DataArrayDouble::fromCylToCart() const
3495 {
3496   checkAllocated();
3497   int nbOfComp=getNumberOfComponents();
3498   if(nbOfComp!=3)
3499     throw INTERP_KERNEL::Exception("DataArrayDouble::fromCylToCart : must be an array with exactly 3 components !");
3500   int nbOfTuple=getNumberOfTuples();
3501   DataArrayDouble *ret=DataArrayDouble::New();
3502   ret->alloc(getNumberOfTuples(),3);
3503   double *w=ret->getPointer();
3504   const double *wIn=getConstPointer();
3505   for(int i=0;i<nbOfTuple;i++,w+=3,wIn+=3)
3506     {
3507       w[0]=wIn[0]*cos(wIn[1]);
3508       w[1]=wIn[0]*sin(wIn[1]);
3509       w[2]=wIn[2];
3510     }
3511   ret->setInfoOnComponent(2,getInfoOnComponent(2).c_str());
3512   return ret;
3513 }
3514
3515 /*!
3516  * Converts each 3D point defined by the tuple of \a this array from the Spherical to
3517  * the Cartesian coordinate system. The three components of the tuple of \a this array 
3518  * are considered to contain (1) radius, (2) polar angle and (3) azimuthal angle of the
3519  * point in the Cylindrical CS.
3520  *  \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
3521  *          contains X, Y and Z coordinates of the point in the Cartesian CS. The info
3522  *          on the third component is copied from \a this array. The caller
3523  *          is to delete this array using decrRef() as it is no more needed.
3524  *  \throw If \a this->getNumberOfComponents() != 3.
3525  */
3526 DataArrayDouble *DataArrayDouble::fromSpherToCart() const
3527 {
3528   checkAllocated();
3529   int nbOfComp=getNumberOfComponents();
3530   if(nbOfComp!=3)
3531     throw INTERP_KERNEL::Exception("DataArrayDouble::fromSpherToCart : must be an array with exactly 3 components !");
3532   int nbOfTuple=getNumberOfTuples();
3533   DataArrayDouble *ret=DataArrayDouble::New();
3534   ret->alloc(getNumberOfTuples(),3);
3535   double *w=ret->getPointer();
3536   const double *wIn=getConstPointer();
3537   for(int i=0;i<nbOfTuple;i++,w+=3,wIn+=3)
3538     {
3539       w[0]=wIn[0]*cos(wIn[2])*sin(wIn[1]);
3540       w[1]=wIn[0]*sin(wIn[2])*sin(wIn[1]);
3541       w[2]=wIn[0]*cos(wIn[1]);
3542     }
3543   return ret;
3544 }
3545
3546 /*!
3547  * Computes the doubly contracted product of every tensor defined by the tuple of \a this
3548  * array contating 6 components.
3549  *  \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
3550  *          is calculated from the tuple <em>(t)</em> of \a this array as follows:
3551  *          \f$ t[0]^2+t[1]^2+t[2]^2+2*t[3]^2+2*t[4]^2+2*t[5]^2\f$.
3552  *         The caller is to delete this result array using decrRef() as it is no more needed. 
3553  *  \throw If \a this->getNumberOfComponents() != 6.
3554  */
3555 DataArrayDouble *DataArrayDouble::doublyContractedProduct() const
3556 {
3557   checkAllocated();
3558   int nbOfComp=getNumberOfComponents();
3559   if(nbOfComp!=6)
3560     throw INTERP_KERNEL::Exception("DataArrayDouble::doublyContractedProduct : must be an array with exactly 6 components !");
3561   DataArrayDouble *ret=DataArrayDouble::New();
3562   int nbOfTuple=getNumberOfTuples();
3563   ret->alloc(nbOfTuple,1);
3564   const double *src=getConstPointer();
3565   double *dest=ret->getPointer();
3566   for(int i=0;i<nbOfTuple;i++,dest++,src+=6)
3567     *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];
3568   return ret;
3569 }
3570
3571 /*!
3572  * Computes the determinant of every square matrix defined by the tuple of \a this
3573  * array, which contains either 4, 6 or 9 components. The case of 6 components
3574  * corresponds to that of the upper triangular matrix.
3575  *  \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
3576  *          is the determinant of matrix of the corresponding tuple of \a this array.
3577  *          The caller is to delete this result array using decrRef() as it is no more
3578  *          needed. 
3579  *  \throw If \a this->getNumberOfComponents() is not in [4,6,9].
3580  */
3581 DataArrayDouble *DataArrayDouble::determinant() const
3582 {
3583   checkAllocated();
3584   DataArrayDouble *ret=DataArrayDouble::New();
3585   int nbOfTuple=getNumberOfTuples();
3586   ret->alloc(nbOfTuple,1);
3587   const double *src=getConstPointer();
3588   double *dest=ret->getPointer();
3589   switch(getNumberOfComponents())
3590     {
3591     case 6:
3592       for(int i=0;i<nbOfTuple;i++,dest++,src+=6)
3593         *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];
3594       return ret;
3595     case 4:
3596       for(int i=0;i<nbOfTuple;i++,dest++,src+=4)
3597         *dest=src[0]*src[3]-src[1]*src[2];
3598       return ret;
3599     case 9:
3600       for(int i=0;i<nbOfTuple;i++,dest++,src+=9)
3601         *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];
3602       return ret;
3603     default:
3604       ret->decrRef();
3605       throw INTERP_KERNEL::Exception("DataArrayDouble::determinant : Invalid number of components ! must be in 4,6,9 !");
3606     }
3607 }
3608
3609 /*!
3610  * Computes 3 eigenvalues of every upper triangular matrix defined by the tuple of
3611  * \a this array, which contains 6 components.
3612  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing 3
3613  *          components, whose each tuple contains the eigenvalues of the matrix of
3614  *          corresponding tuple of \a this array. 
3615  *          The caller is to delete this result array using decrRef() as it is no more
3616  *          needed. 
3617  *  \throw If \a this->getNumberOfComponents() != 6.
3618  */
3619 DataArrayDouble *DataArrayDouble::eigenValues() const
3620 {
3621   checkAllocated();
3622   int nbOfComp=getNumberOfComponents();
3623   if(nbOfComp!=6)
3624     throw INTERP_KERNEL::Exception("DataArrayDouble::eigenValues : must be an array with exactly 6 components !");
3625   DataArrayDouble *ret=DataArrayDouble::New();
3626   int nbOfTuple=getNumberOfTuples();
3627   ret->alloc(nbOfTuple,3);
3628   const double *src=getConstPointer();
3629   double *dest=ret->getPointer();
3630   for(int i=0;i<nbOfTuple;i++,dest+=3,src+=6)
3631     INTERP_KERNEL::computeEigenValues6(src,dest);
3632   return ret;
3633 }
3634
3635 /*!
3636  * Computes 3 eigenvectors of every upper triangular matrix defined by the tuple of
3637  * \a this array, which contains 6 components.
3638  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing 9
3639  *          components, whose each tuple contains 3 eigenvectors of the matrix of
3640  *          corresponding tuple of \a this array.
3641  *          The caller is to delete this result array using decrRef() as it is no more
3642  *          needed.
3643  *  \throw If \a this->getNumberOfComponents() != 6.
3644  */
3645 DataArrayDouble *DataArrayDouble::eigenVectors() const
3646 {
3647   checkAllocated();
3648   int nbOfComp=getNumberOfComponents();
3649   if(nbOfComp!=6)
3650     throw INTERP_KERNEL::Exception("DataArrayDouble::eigenVectors : must be an array with exactly 6 components !");
3651   DataArrayDouble *ret=DataArrayDouble::New();
3652   int nbOfTuple=getNumberOfTuples();
3653   ret->alloc(nbOfTuple,9);
3654   const double *src=getConstPointer();
3655   double *dest=ret->getPointer();
3656   for(int i=0;i<nbOfTuple;i++,src+=6)
3657     {
3658       double tmp[3];
3659       INTERP_KERNEL::computeEigenValues6(src,tmp);
3660       for(int j=0;j<3;j++,dest+=3)
3661         INTERP_KERNEL::computeEigenVectorForEigenValue6(src,tmp[j],1e-12,dest);
3662     }
3663   return ret;
3664 }
3665
3666 /*!
3667  * Computes the inverse matrix of every matrix defined by the tuple of \a this
3668  * array, which contains either 4, 6 or 9 components. The case of 6 components
3669  * corresponds to that of the upper triangular matrix.
3670  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
3671  *          same number of components as \a this one, whose each tuple is the inverse
3672  *          matrix of the matrix of corresponding tuple of \a this array. 
3673  *          The caller is to delete this result array using decrRef() as it is no more
3674  *          needed. 
3675  *  \throw If \a this->getNumberOfComponents() is not in [4,6,9].
3676  */
3677 DataArrayDouble *DataArrayDouble::inverse() const
3678 {
3679   checkAllocated();
3680   int nbOfComp=getNumberOfComponents();
3681   if(nbOfComp!=6 && nbOfComp!=9 && nbOfComp!=4)
3682     throw INTERP_KERNEL::Exception("DataArrayDouble::inversion : must be an array with 4,6 or 9 components !");
3683   DataArrayDouble *ret=DataArrayDouble::New();
3684   int nbOfTuple=getNumberOfTuples();
3685   ret->alloc(nbOfTuple,nbOfComp);
3686   const double *src=getConstPointer();
3687   double *dest=ret->getPointer();
3688 if(nbOfComp==6)
3689     for(int i=0;i<nbOfTuple;i++,dest+=6,src+=6)
3690       {
3691         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];
3692         dest[0]=(src[1]*src[2]-src[4]*src[4])/det;
3693         dest[1]=(src[0]*src[2]-src[5]*src[5])/det;
3694         dest[2]=(src[0]*src[1]-src[3]*src[3])/det;
3695         dest[3]=(src[5]*src[4]-src[3]*src[2])/det;
3696         dest[4]=(src[5]*src[3]-src[0]*src[4])/det;
3697         dest[5]=(src[3]*src[4]-src[1]*src[5])/det;
3698       }
3699   else if(nbOfComp==4)
3700     for(int i=0;i<nbOfTuple;i++,dest+=4,src+=4)
3701       {
3702         double det=src[0]*src[3]-src[1]*src[2];
3703         dest[0]=src[3]/det;
3704         dest[1]=-src[1]/det;
3705         dest[2]=-src[2]/det;
3706         dest[3]=src[0]/det;
3707       }
3708   else
3709     for(int i=0;i<nbOfTuple;i++,dest+=9,src+=9)
3710       {
3711         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];
3712         dest[0]=(src[4]*src[8]-src[7]*src[5])/det;
3713         dest[1]=(src[7]*src[2]-src[1]*src[8])/det;
3714         dest[2]=(src[1]*src[5]-src[4]*src[2])/det;
3715         dest[3]=(src[6]*src[5]-src[3]*src[8])/det;
3716         dest[4]=(src[0]*src[8]-src[6]*src[2])/det;
3717         dest[5]=(src[2]*src[3]-src[0]*src[5])/det;
3718         dest[6]=(src[3]*src[7]-src[6]*src[4])/det;
3719         dest[7]=(src[6]*src[1]-src[0]*src[7])/det;
3720         dest[8]=(src[0]*src[4]-src[1]*src[3])/det;
3721       }
3722   return ret;
3723 }
3724
3725 /*!
3726  * Computes the trace of every matrix defined by the tuple of \a this
3727  * array, which contains either 4, 6 or 9 components. The case of 6 components
3728  * corresponds to that of the upper triangular matrix.
3729  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing 
3730  *          1 component, whose each tuple is the trace of
3731  *          the matrix of corresponding tuple of \a this array. 
3732  *          The caller is to delete this result array using decrRef() as it is no more
3733  *          needed. 
3734  *  \throw If \a this->getNumberOfComponents() is not in [4,6,9].
3735  */
3736 DataArrayDouble *DataArrayDouble::trace() const
3737 {
3738   checkAllocated();
3739   int nbOfComp=getNumberOfComponents();
3740   if(nbOfComp!=6 && nbOfComp!=9 && nbOfComp!=4)
3741     throw INTERP_KERNEL::Exception("DataArrayDouble::trace : must be an array with 4,6 or 9 components !");
3742   DataArrayDouble *ret=DataArrayDouble::New();
3743   int nbOfTuple=getNumberOfTuples();
3744   ret->alloc(nbOfTuple,1);
3745   const double *src=getConstPointer();
3746   double *dest=ret->getPointer();
3747   if(nbOfComp==6)
3748     for(int i=0;i<nbOfTuple;i++,dest++,src+=6)
3749       *dest=src[0]+src[1]+src[2];
3750   else if(nbOfComp==4)
3751     for(int i=0;i<nbOfTuple;i++,dest++,src+=4)
3752       *dest=src[0]+src[3];
3753   else
3754     for(int i=0;i<nbOfTuple;i++,dest++,src+=9)
3755       *dest=src[0]+src[4]+src[8];
3756   return ret;
3757 }
3758
3759 /*!
3760  * Computes the stress deviator tensor of every stress tensor defined by the tuple of
3761  * \a this array, which contains 6 components.
3762  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
3763  *          same number of components and tuples as \a this array.
3764  *          The caller is to delete this result array using decrRef() as it is no more
3765  *          needed.
3766  *  \throw If \a this->getNumberOfComponents() != 6.
3767  */
3768 DataArrayDouble *DataArrayDouble::deviator() const
3769 {
3770   checkAllocated();
3771   int nbOfComp=getNumberOfComponents();
3772   if(nbOfComp!=6)
3773     throw INTERP_KERNEL::Exception("DataArrayDouble::deviator : must be an array with exactly 6 components !");
3774   DataArrayDouble *ret=DataArrayDouble::New();
3775   int nbOfTuple=getNumberOfTuples();
3776   ret->alloc(nbOfTuple,6);
3777   const double *src=getConstPointer();
3778   double *dest=ret->getPointer();
3779   for(int i=0;i<nbOfTuple;i++,dest+=6,src+=6)
3780     {
3781       double tr=(src[0]+src[1]+src[2])/3.;
3782       dest[0]=src[0]-tr;
3783       dest[1]=src[1]-tr;
3784       dest[2]=src[2]-tr;
3785       dest[3]=src[3];
3786       dest[4]=src[4];
3787       dest[5]=src[5];
3788     }
3789   return ret;
3790 }
3791
3792 /*!
3793  * Computes the magnitude of every vector defined by the tuple of
3794  * \a this array.
3795  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
3796  *          same number of tuples as \a this array and one component.
3797  *          The caller is to delete this result array using decrRef() as it is no more
3798  *          needed.
3799  *  \throw If \a this is not allocated.
3800  */
3801 DataArrayDouble *DataArrayDouble::magnitude() const
3802 {
3803   checkAllocated();
3804   int nbOfComp=getNumberOfComponents();
3805   DataArrayDouble *ret=DataArrayDouble::New();
3806   int nbOfTuple=getNumberOfTuples();
3807   ret->alloc(nbOfTuple,1);
3808   const double *src=getConstPointer();
3809   double *dest=ret->getPointer();
3810   for(int i=0;i<nbOfTuple;i++,dest++)
3811     {
3812       double sum=0.;
3813       for(int j=0;j<nbOfComp;j++,src++)
3814         sum+=(*src)*(*src);
3815       *dest=sqrt(sum);
3816     }
3817   return ret;
3818 }
3819
3820 /*!
3821  * Computes for each tuple the sum of number of components values in the tuple and return it.
3822  * 
3823  * \return DataArrayDouble * - the new instance of DataArrayDouble containing the
3824  *          same number of tuples as \a this array and one component.
3825  *          The caller is to delete this result array using decrRef() as it is no more
3826  *          needed.
3827  *  \throw If \a this is not allocated.
3828  */
3829 DataArrayDouble *DataArrayDouble::sumPerTuple() const
3830 {
3831   checkAllocated();
3832   int nbOfComp(getNumberOfComponents()),nbOfTuple(getNumberOfTuples());
3833   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret(DataArrayDouble::New());
3834   ret->alloc(nbOfTuple,1);
3835   const double *src(getConstPointer());
3836   double *dest(ret->getPointer());
3837   for(int i=0;i<nbOfTuple;i++,dest++,src+=nbOfComp)
3838     *dest=std::accumulate(src,src+nbOfComp,0.);
3839   return ret.retn();
3840 }
3841
3842 /*!
3843  * Computes the maximal value within every tuple of \a this array.
3844  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
3845  *          same number of tuples as \a this array and one component.
3846  *          The caller is to delete this result array using decrRef() as it is no more
3847  *          needed.
3848  *  \throw If \a this is not allocated.
3849  *  \sa DataArrayDouble::maxPerTupleWithCompoId
3850  */
3851 DataArrayDouble *DataArrayDouble::maxPerTuple() const
3852 {
3853   checkAllocated();
3854   int nbOfComp=getNumberOfComponents();
3855   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
3856   int nbOfTuple=getNumberOfTuples();
3857   ret->alloc(nbOfTuple,1);
3858   const double *src=getConstPointer();
3859   double *dest=ret->getPointer();
3860   for(int i=0;i<nbOfTuple;i++,dest++,src+=nbOfComp)
3861     *dest=*std::max_element(src,src+nbOfComp);
3862   return ret.retn();
3863 }
3864
3865 /*!
3866  * Computes the maximal value within every tuple of \a this array and it returns the first component
3867  * id for each tuple that corresponds to the maximal value within the tuple.
3868  * 
3869  *  \param [out] compoIdOfMaxPerTuple - the new new instance of DataArrayInt containing the
3870  *          same number of tuples and only one component.
3871  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
3872  *          same number of tuples as \a this array and one component.
3873  *          The caller is to delete this result array using decrRef() as it is no more
3874  *          needed.
3875  *  \throw If \a this is not allocated.
3876  *  \sa DataArrayDouble::maxPerTuple
3877  */
3878 DataArrayDouble *DataArrayDouble::maxPerTupleWithCompoId(DataArrayInt* &compoIdOfMaxPerTuple) const
3879 {
3880   checkAllocated();
3881   int nbOfComp=getNumberOfComponents();
3882   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret0=DataArrayDouble::New();
3883   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret1=DataArrayInt::New();
3884   int nbOfTuple=getNumberOfTuples();
3885   ret0->alloc(nbOfTuple,1); ret1->alloc(nbOfTuple,1);
3886   const double *src=getConstPointer();
3887   double *dest=ret0->getPointer(); int *dest1=ret1->getPointer();
3888   for(int i=0;i<nbOfTuple;i++,dest++,dest1++,src+=nbOfComp)
3889     {
3890       const double *loc=std::max_element(src,src+nbOfComp);
3891       *dest=*loc;
3892       *dest1=(int)std::distance(src,loc);
3893     }
3894   compoIdOfMaxPerTuple=ret1.retn();
3895   return ret0.retn();
3896 }
3897
3898 /*!
3899  * This method returns a newly allocated DataArrayDouble instance having one component and \c this->getNumberOfTuples() * \c this->getNumberOfTuples() tuples.
3900  * \n This returned array contains the euclidian distance for each tuple in \a this. 
3901  * \n So the returned array can be seen as a dense symmetrical matrix whose diagonal elements are equal to 0.
3902  * \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)
3903  *
3904  * \warning use this method with care because it can leads to big amount of consumed memory !
3905  * 
3906  * \return A newly allocated (huge) ParaMEDMEM::DataArrayDouble instance that the caller should deal with.
3907  *
3908  * \throw If \a this is not allocated.
3909  *
3910  * \sa DataArrayDouble::buildEuclidianDistanceDenseMatrixWith
3911  */
3912 DataArrayDouble *DataArrayDouble::buildEuclidianDistanceDenseMatrix() const
3913 {
3914   checkAllocated();
3915   int nbOfComp=getNumberOfComponents();
3916   int nbOfTuples=getNumberOfTuples();
3917   const double *inData=getConstPointer();
3918   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
3919   ret->alloc(nbOfTuples*nbOfTuples,1);
3920   double *outData=ret->getPointer();
3921   for(int i=0;i<nbOfTuples;i++)
3922     {
3923       outData[i*nbOfTuples+i]=0.;
3924       for(int j=i+1;j<nbOfTuples;j++)
3925         {
3926           double dist=0.;
3927           for(int k=0;k<nbOfComp;k++)
3928             { double delta=inData[i*nbOfComp+k]-inData[j*nbOfComp+k]; dist+=delta*delta; }
3929           dist=sqrt(dist);
3930           outData[i*nbOfTuples+j]=dist;
3931           outData[j*nbOfTuples+i]=dist;
3932         }
3933     }
3934   return ret.retn();
3935 }
3936
3937 /*!
3938  * This method returns a newly allocated DataArrayDouble instance having one component and \c this->getNumberOfTuples() * \c other->getNumberOfTuples() tuples.
3939  * \n This returned array contains the euclidian distance for each tuple in \a other with each tuple in \a this. 
3940  * \n So the returned array can be seen as a dense rectangular matrix with \c other->getNumberOfTuples() rows and \c this->getNumberOfTuples() columns.
3941  * \n Output rectangular matrix is sorted along rows.
3942  * \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)
3943  *
3944  * \warning use this method with care because it can leads to big amount of consumed memory !
3945  * 
3946  * \param [in] other DataArrayDouble instance having same number of components than \a this.
3947  * \return A newly allocated (huge) ParaMEDMEM::DataArrayDouble instance that the caller should deal with.
3948  *
3949  * \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.
3950  *
3951  * \sa DataArrayDouble::buildEuclidianDistanceDenseMatrix
3952  */
3953 DataArrayDouble *DataArrayDouble::buildEuclidianDistanceDenseMatrixWith(const DataArrayDouble *other) const
3954 {
3955   if(!other)
3956     throw INTERP_KERNEL::Exception("DataArrayDouble::buildEuclidianDistanceDenseMatrixWith : input parameter is null !");
3957   checkAllocated();
3958   other->checkAllocated();
3959   int nbOfComp=getNumberOfComponents();
3960   int otherNbOfComp=other->getNumberOfComponents();
3961   if(nbOfComp!=otherNbOfComp)
3962     {
3963       std::ostringstream oss; oss << "DataArrayDouble::buildEuclidianDistanceDenseMatrixWith : this nb of compo=" << nbOfComp << " and other nb of compo=" << otherNbOfComp << ". It should match !";
3964       throw INTERP_KERNEL::Exception(oss.str().c_str());
3965     }
3966   int nbOfTuples=getNumberOfTuples();
3967   int otherNbOfTuples=other->getNumberOfTuples();
3968   const double *inData=getConstPointer();
3969   const double *inDataOther=other->getConstPointer();
3970   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
3971   ret->alloc(otherNbOfTuples*nbOfTuples,1);
3972   double *outData=ret->getPointer();
3973   for(int i=0;i<otherNbOfTuples;i++,inDataOther+=nbOfComp)
3974     {
3975       for(int j=0;j<nbOfTuples;j++)
3976         {
3977           double dist=0.;
3978           for(int k=0;k<nbOfComp;k++)
3979             { double delta=inDataOther[k]-inData[j*nbOfComp+k]; dist+=delta*delta; }
3980           dist=sqrt(dist);
3981           outData[i*nbOfTuples+j]=dist;
3982         }
3983     }
3984   return ret.retn();
3985 }
3986
3987 /*!
3988  * Sorts value within every tuple of \a this array.
3989  *  \param [in] asc - if \a true, the values are sorted in ascending order, else,
3990  *              in descending order.
3991  *  \throw If \a this is not allocated.
3992  */
3993 void DataArrayDouble::sortPerTuple(bool asc)
3994 {
3995   checkAllocated();
3996   double *pt=getPointer();
3997   int nbOfTuple=getNumberOfTuples();
3998   int nbOfComp=getNumberOfComponents();
3999   if(asc)
4000     for(int i=0;i<nbOfTuple;i++,pt+=nbOfComp)
4001       std::sort(pt,pt+nbOfComp);
4002   else
4003     for(int i=0;i<nbOfTuple;i++,pt+=nbOfComp)
4004       std::sort(pt,pt+nbOfComp,std::greater<double>());
4005   declareAsNew();
4006 }
4007
4008 /*!
4009  * Converts every value of \a this array to its absolute value.
4010  *  \throw If \a this is not allocated.
4011  */
4012 void DataArrayDouble::abs()
4013 {
4014   checkAllocated();
4015   double *ptr=getPointer();
4016   std::size_t nbOfElems=getNbOfElems();
4017   std::transform(ptr,ptr+nbOfElems,ptr,std::ptr_fun<double,double>(fabs));
4018   declareAsNew();
4019 }
4020
4021 /*!
4022  * Apply a liner function to a given component of \a this array, so that
4023  * an array element <em>(x)</em> becomes \f$ a * x + b \f$.
4024  *  \param [in] a - the first coefficient of the function.
4025  *  \param [in] b - the second coefficient of the function.
4026  *  \param [in] compoId - the index of component to modify.
4027  *  \throw If \a this is not allocated.
4028  */
4029 void DataArrayDouble::applyLin(double a, double b, int compoId)
4030 {
4031   checkAllocated();
4032   double *ptr=getPointer()+compoId;
4033   int nbOfComp=getNumberOfComponents();
4034   int nbOfTuple=getNumberOfTuples();
4035   for(int i=0;i<nbOfTuple;i++,ptr+=nbOfComp)
4036     *ptr=a*(*ptr)+b;
4037   declareAsNew();
4038 }
4039
4040 /*!
4041  * Apply a liner function to all elements of \a this array, so that
4042  * an element _x_ becomes \f$ a * x + b \f$.
4043  *  \param [in] a - the first coefficient of the function.
4044  *  \param [in] b - the second coefficient of the function.
4045  *  \throw If \a this is not allocated.
4046  */
4047 void DataArrayDouble::applyLin(double a, double b)
4048 {
4049   checkAllocated();
4050   double *ptr=getPointer();
4051   std::size_t nbOfElems=getNbOfElems();
4052   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
4053     *ptr=a*(*ptr)+b;
4054   declareAsNew();
4055 }
4056
4057 /*!
4058  * Modify all elements of \a this array, so that
4059  * an element _x_ becomes \f$ numerator / x \f$.
4060  *  \warning If an exception is thrown because of presence of 0.0 element in \a this 
4061  *           array, all elements processed before detection of the zero element remain
4062  *           modified.
4063  *  \param [in] numerator - the numerator used to modify array elements.
4064  *  \throw If \a this is not allocated.
4065  *  \throw If there is an element equal to 0.0 in \a this array.
4066  */
4067 void DataArrayDouble::applyInv(double numerator)
4068 {
4069   checkAllocated();
4070   double *ptr=getPointer();
4071   std::size_t nbOfElems=getNbOfElems();
4072   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
4073     {
4074       if(std::abs(*ptr)>std::numeric_limits<double>::min())
4075         {
4076           *ptr=numerator/(*ptr);
4077         }
4078       else
4079         {
4080           std::ostringstream oss; oss << "DataArrayDouble::applyInv : presence of null value in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
4081           oss << " !";
4082           throw INTERP_KERNEL::Exception(oss.str().c_str());
4083         }
4084     }
4085   declareAsNew();
4086 }
4087
4088 /*!
4089  * Returns a full copy of \a this array except that sign of all elements is reversed.
4090  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
4091  *          same number of tuples and component as \a this array.
4092  *          The caller is to delete this result array using decrRef() as it is no more
4093  *          needed.
4094  *  \throw If \a this is not allocated.
4095  */
4096 DataArrayDouble *DataArrayDouble::negate() const
4097 {
4098   checkAllocated();
4099   DataArrayDouble *newArr=DataArrayDouble::New();
4100   int nbOfTuples=getNumberOfTuples();
4101   int nbOfComp=getNumberOfComponents();
4102   newArr->alloc(nbOfTuples,nbOfComp);
4103   const double *cptr=getConstPointer();
4104   std::transform(cptr,cptr+nbOfTuples*nbOfComp,newArr->getPointer(),std::negate<double>());
4105   newArr->copyStringInfoFrom(*this);
4106   return newArr;
4107 }
4108
4109 /*!
4110  * Modify all elements of \a this array, so that
4111  * an element _x_ becomes <em> val ^ x </em>. Contrary to DataArrayInt::applyPow
4112  * all values in \a this have to be >= 0 if val is \b not integer.
4113  *  \param [in] val - the value used to apply pow on all array elements.
4114  *  \throw If \a this is not allocated.
4115  *  \warning If an exception is thrown because of presence of 0 element in \a this 
4116  *           array and \a val is \b not integer, all elements processed before detection of the zero element remain
4117  *           modified.
4118  */
4119 void DataArrayDouble::applyPow(double val)
4120 {
4121   checkAllocated();
4122   double *ptr=getPointer();
4123   std::size_t nbOfElems=getNbOfElems();
4124   int val2=(int)val;
4125   bool isInt=((double)val2)==val;
4126   if(!isInt)
4127     {
4128       for(std::size_t i=0;i<nbOfElems;i++,ptr++)
4129         {
4130           if(*ptr>=0)
4131             *ptr=pow(*ptr,val);
4132           else
4133             {
4134               std::ostringstream oss; oss << "DataArrayDouble::applyPow (double) : At elem # " << i << " value is " << *ptr << " ! must be >=0. !";
4135               throw INTERP_KERNEL::Exception(oss.str().c_str());
4136             }
4137         }
4138     }
4139   else
4140     {
4141       for(std::size_t i=0;i<nbOfElems;i++,ptr++)
4142         *ptr=pow(*ptr,val2);
4143     }
4144   declareAsNew();
4145 }
4146
4147 /*!
4148  * Modify all elements of \a this array, so that
4149  * an element _x_ becomes \f$ val ^ x \f$.
4150  *  \param [in] val - the value used to apply pow on all array elements.
4151  *  \throw If \a this is not allocated.
4152  *  \throw If \a val < 0.
4153  *  \warning If an exception is thrown because of presence of 0 element in \a this 
4154  *           array, all elements processed before detection of the zero element remain
4155  *           modified.
4156  */
4157 void DataArrayDouble::applyRPow(double val)
4158 {
4159   checkAllocated();
4160   if(val<0.)
4161     throw INTERP_KERNEL::Exception("DataArrayDouble::applyRPow : the input value has to be >= 0 !");
4162   double *ptr=getPointer();
4163   std::size_t nbOfElems=getNbOfElems();
4164   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
4165     *ptr=pow(val,*ptr);
4166   declareAsNew();
4167 }
4168
4169 /*!
4170  * Returns a new DataArrayDouble created from \a this one by applying \a
4171  * FunctionToEvaluate to every tuple of \a this array. Textual data is not copied.
4172  * For more info see \ref MEDCouplingArrayApplyFunc
4173  *  \param [in] nbOfComp - number of components in the result array.
4174  *  \param [in] func - the \a FunctionToEvaluate declared as 
4175  *              \c bool (*\a func)(\c const \c double *\a pos, \c double *\a res), 
4176  *              where \a pos points to the first component of a tuple of \a this array
4177  *              and \a res points to the first component of a tuple of the result array.
4178  *              Note that length (number of components) of \a pos can differ from
4179  *              that of \a res.
4180  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
4181  *          same number of tuples as \a this array.
4182  *          The caller is to delete this result array using decrRef() as it is no more
4183  *          needed.
4184  *  \throw If \a this is not allocated.
4185  *  \throw If \a func returns \a false.
4186  */
4187 DataArrayDouble *DataArrayDouble::applyFunc(int nbOfComp, FunctionToEvaluate func) const
4188 {
4189   checkAllocated();
4190   DataArrayDouble *newArr=DataArrayDouble::New();
4191   int nbOfTuples=getNumberOfTuples();
4192   int oldNbOfComp=getNumberOfComponents();
4193   newArr->alloc(nbOfTuples,nbOfComp);
4194   const double *ptr=getConstPointer();
4195   double *ptrToFill=newArr->getPointer();
4196   for(int i=0;i<nbOfTuples;i++)
4197     {
4198       if(!func(ptr+i*oldNbOfComp,ptrToFill+i*nbOfComp))
4199         {
4200           std::ostringstream oss; oss << "For tuple # " << i << " with value (";
4201           std::copy(ptr+oldNbOfComp*i,ptr+oldNbOfComp*(i+1),std::ostream_iterator<double>(oss,", "));
4202           oss << ") : Evaluation of function failed !";
4203           newArr->decrRef();
4204           throw INTERP_KERNEL::Exception(oss.str().c_str());
4205         }
4206     }
4207   return newArr;
4208 }
4209
4210 /*!
4211  * Returns a new DataArrayDouble created from \a this one by applying a function to every
4212  * tuple of \a this array. Textual data is not copied.
4213  * For more info see \ref MEDCouplingArrayApplyFunc1.
4214  *  \param [in] nbOfComp - number of components in the result array.
4215  *  \param [in] func - the expression defining how to transform a tuple of \a this array.
4216  *              Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
4217  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
4218  *          same number of tuples as \a this array and \a nbOfComp components.
4219  *          The caller is to delete this result array using decrRef() as it is no more
4220  *          needed.
4221  *  \throw If \a this is not allocated.
4222  *  \throw If computing \a func fails.
4223  */
4224 DataArrayDouble *DataArrayDouble::applyFunc(int nbOfComp, const char *func) const
4225 {
4226   checkAllocated();
4227   INTERP_KERNEL::ExprParser expr(func);
4228   expr.parse();
4229   std::set<std::string> vars;
4230   expr.getTrueSetOfVars(vars);
4231   int oldNbOfComp=getNumberOfComponents();
4232   if((int)vars.size()>oldNbOfComp)
4233     {
4234       std::ostringstream oss; oss << "The field has " << oldNbOfComp << " components and there are ";
4235       oss << vars.size() << " variables : ";
4236       std::copy(vars.begin(),vars.end(),std::ostream_iterator<std::string>(oss," "));
4237       throw INTERP_KERNEL::Exception(oss.str().c_str());
4238     }
4239   std::vector<std::string> varsV(vars.begin(),vars.end());
4240   expr.prepareExprEvaluation(varsV,oldNbOfComp,nbOfComp);
4241   //
4242   DataArrayDouble *newArr=DataArrayDouble::New();
4243   int nbOfTuples=getNumberOfTuples();
4244   newArr->alloc(nbOfTuples,nbOfComp);
4245   const double *ptr=getConstPointer();
4246   double *ptrToFill=newArr->getPointer();
4247   for(int i=0;i<nbOfTuples;i++)
4248     {
4249       try
4250         {
4251           expr.evaluateExpr(nbOfComp,ptr+i*oldNbOfComp,ptrToFill+i*nbOfComp);
4252         }
4253       catch(INTERP_KERNEL::Exception& e)
4254         {
4255           std::ostringstream oss; oss << "For tuple # " << i << " with value (";
4256           std::copy(ptr+oldNbOfComp*i,ptr+oldNbOfComp*(i+1),std::ostream_iterator<double>(oss,", "));
4257           oss << ") : Evaluation of function failed !" << e.what();
4258           newArr->decrRef();
4259           throw INTERP_KERNEL::Exception(oss.str().c_str());
4260         }
4261     }
4262   return newArr;
4263 }
4264
4265 /*!
4266  * Returns a new DataArrayDouble created from \a this one by applying a function to every
4267  * tuple of \a this array. Textual data is not copied.
4268  * For more info see \ref MEDCouplingArrayApplyFunc0.
4269  *  \param [in] func - the expression defining how to transform a tuple of \a this array.
4270  *              Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
4271  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
4272  *          same number of tuples and components as \a this array.
4273  *          The caller is to delete this result array using decrRef() as it is no more
4274  *          needed.
4275  *  \throw If \a this is not allocated.
4276  *  \throw If computing \a func fails.
4277  */
4278 DataArrayDouble *DataArrayDouble::applyFunc(const char *func) const
4279 {
4280   checkAllocated();
4281   INTERP_KERNEL::ExprParser expr(func);
4282   expr.parse();
4283   expr.prepareExprEvaluationVec();
4284   //
4285   DataArrayDouble *newArr=DataArrayDouble::New();
4286   int nbOfTuples=getNumberOfTuples();
4287   int nbOfComp=getNumberOfComponents();
4288   newArr->alloc(nbOfTuples,nbOfComp);
4289   const double *ptr=getConstPointer();
4290   double *ptrToFill=newArr->getPointer();
4291   for(int i=0;i<nbOfTuples;i++)
4292     {
4293       try
4294         {
4295           expr.evaluateExpr(nbOfComp,ptr+i*nbOfComp,ptrToFill+i*nbOfComp);
4296         }
4297       catch(INTERP_KERNEL::Exception& e)
4298         {
4299           std::ostringstream oss; oss << "For tuple # " << i << " with value (";
4300           std::copy(ptr+nbOfComp*i,ptr+nbOfComp*(i+1),std::ostream_iterator<double>(oss,", "));
4301           oss << ") : Evaluation of function failed ! " << e.what();
4302           newArr->decrRef();
4303           throw INTERP_KERNEL::Exception(oss.str().c_str());
4304         }
4305     }
4306   return newArr;
4307 }
4308
4309 /*!
4310  * Returns a new DataArrayDouble created from \a this one by applying a function to every
4311  * tuple of \a this array. Textual data is not copied.
4312  * For more info see \ref MEDCouplingArrayApplyFunc2.
4313  *  \param [in] nbOfComp - number of components in the result array.
4314  *  \param [in] func - the expression defining how to transform a tuple of \a this array.
4315  *              Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
4316  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
4317  *          same number of tuples as \a this array.
4318  *          The caller is to delete this result array using decrRef() as it is no more
4319  *          needed.
4320  *  \throw If \a this is not allocated.
4321  *  \throw If \a func contains vars that are not in \a this->getInfoOnComponent().
4322  *  \throw If computing \a func fails.
4323  */
4324 DataArrayDouble *DataArrayDouble::applyFunc2(int nbOfComp, const char *func) const
4325 {
4326   checkAllocated();
4327   INTERP_KERNEL::ExprParser expr(func);
4328   expr.parse();
4329   std::set<std::string> vars;
4330   expr.getTrueSetOfVars(vars);
4331   int oldNbOfComp=getNumberOfComponents();
4332   if((int)vars.size()>oldNbOfComp)
4333     {
4334       std::ostringstream oss; oss << "The field has " << oldNbOfComp << " components and there are ";
4335       oss << vars.size() << " variables : ";
4336       std::copy(vars.begin(),vars.end(),std::ostream_iterator<std::string>(oss," "));
4337       throw INTERP_KERNEL::Exception(oss.str().c_str());
4338     }
4339   expr.prepareExprEvaluation(getVarsOnComponent(),oldNbOfComp,nbOfComp);
4340   //
4341   DataArrayDouble *newArr=DataArrayDouble::New();
4342   int nbOfTuples=getNumberOfTuples();
4343   newArr->alloc(nbOfTuples,nbOfComp);
4344   const double *ptr=getConstPointer();
4345   double *ptrToFill=newArr->getPointer();
4346   for(int i=0;i<nbOfTuples;i++)
4347     {
4348       try
4349         {
4350           expr.evaluateExpr(nbOfComp,ptr+i*oldNbOfComp,ptrToFill+i*nbOfComp);
4351         }
4352       catch(INTERP_KERNEL::Exception& e)
4353         {
4354           std::ostringstream oss; oss << "For tuple # " << i << " with value (";
4355           std::copy(ptr+oldNbOfComp*i,ptr+oldNbOfComp*(i+1),std::ostream_iterator<double>(oss,", "));
4356           oss << ") : Evaluation of function failed !" << e.what();
4357           newArr->decrRef();
4358           throw INTERP_KERNEL::Exception(oss.str().c_str());
4359         }
4360     }
4361   return newArr;
4362 }
4363
4364 /*!
4365  * Returns a new DataArrayDouble created from \a this one by applying a function to every
4366  * tuple of \a this array. Textual data is not copied.
4367  * For more info see \ref MEDCouplingArrayApplyFunc3.
4368  *  \param [in] nbOfComp - number of components in the result array.
4369  *  \param [in] varsOrder - sequence of vars defining their order.
4370  *  \param [in] func - the expression defining how to transform a tuple of \a this array.
4371  *              Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
4372  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
4373  *          same number of tuples as \a this array.
4374  *          The caller is to delete this result array using decrRef() as it is no more
4375  *          needed.
4376  *  \throw If \a this is not allocated.
4377  *  \throw If \a func contains vars not in \a varsOrder.
4378  *  \throw If computing \a func fails.
4379  */
4380 DataArrayDouble *DataArrayDouble::applyFunc3(int nbOfComp, const std::vector<std::string>& varsOrder, const char *func) const
4381 {
4382   checkAllocated();
4383   INTERP_KERNEL::ExprParser expr(func);
4384   expr.parse();
4385   std::set<std::string> vars;
4386   expr.getTrueSetOfVars(vars);
4387   int oldNbOfComp=getNumberOfComponents();
4388   if((int)vars.size()>oldNbOfComp)
4389     {
4390       std::ostringstream oss; oss << "The field has " << oldNbOfComp << " components and there are ";
4391       oss << vars.size() << " variables : ";
4392       std::copy(vars.begin(),vars.end(),std::ostream_iterator<std::string>(oss," "));
4393       throw INTERP_KERNEL::Exception(oss.str().c_str());
4394     }
4395   expr.prepareExprEvaluation(varsOrder,oldNbOfComp,nbOfComp);
4396   //
4397   DataArrayDouble *newArr=DataArrayDouble::New();
4398   int nbOfTuples=getNumberOfTuples();
4399   newArr->alloc(nbOfTuples,nbOfComp);
4400   const double *ptr=getConstPointer();
4401   double *ptrToFill=newArr->getPointer();
4402   for(int i=0;i<nbOfTuples;i++)
4403     {
4404       try
4405         {
4406           expr.evaluateExpr(nbOfComp,ptr+i*oldNbOfComp,ptrToFill+i*nbOfComp);
4407         }
4408       catch(INTERP_KERNEL::Exception& e)
4409         {
4410           std::ostringstream oss; oss << "For tuple # " << i << " with value (";
4411           std::copy(ptr+oldNbOfComp*i,ptr+oldNbOfComp*(i+1),std::ostream_iterator<double>(oss,", "));
4412           oss << ") : Evaluation of function failed !" << e.what();
4413           newArr->decrRef();
4414           throw INTERP_KERNEL::Exception(oss.str().c_str());
4415         }
4416     }
4417   return newArr;
4418 }
4419
4420 void DataArrayDouble::applyFuncFast32(const char *func)
4421 {
4422   checkAllocated();
4423   INTERP_KERNEL::ExprParser expr(func);
4424   expr.parse();
4425   char *funcStr=expr.compileX86();
4426   MYFUNCPTR funcPtr;
4427   *((void **)&funcPtr)=funcStr;//he he...
4428   //
4429   double *ptr=getPointer();
4430   int nbOfComp=getNumberOfComponents();
4431   int nbOfTuples=getNumberOfTuples();
4432   int nbOfElems=nbOfTuples*nbOfComp;
4433   for(int i=0;i<nbOfElems;i++,ptr++)
4434     *ptr=funcPtr(*ptr);
4435   declareAsNew();
4436 }
4437
4438 void DataArrayDouble::applyFuncFast64(const char *func)
4439 {
4440   checkAllocated();
4441   INTERP_KERNEL::ExprParser expr(func);
4442   expr.parse();
4443   char *funcStr=expr.compileX86_64();
4444   MYFUNCPTR funcPtr;
4445   *((void **)&funcPtr)=funcStr;//he he...
4446   //
4447   double *ptr=getPointer();
4448   int nbOfComp=getNumberOfComponents();
4449   int nbOfTuples=getNumberOfTuples();
4450   int nbOfElems=nbOfTuples*nbOfComp;
4451   for(int i=0;i<nbOfElems;i++,ptr++)
4452     *ptr=funcPtr(*ptr);
4453   declareAsNew();
4454 }
4455
4456 DataArrayDoubleIterator *DataArrayDouble::iterator()
4457 {
4458   return new DataArrayDoubleIterator(this);
4459 }
4460
4461 /*!
4462  * Returns a new DataArrayInt contating indices of tuples of \a this one-dimensional
4463  * array whose values are within a given range. Textual data is not copied.
4464  *  \param [in] vmin - a lowest acceptable value (included).
4465  *  \param [in] vmax - a greatest acceptable value (included).
4466  *  \return DataArrayInt * - the new instance of DataArrayInt.
4467  *          The caller is to delete this result array using decrRef() as it is no more
4468  *          needed.
4469  *  \throw If \a this->getNumberOfComponents() != 1.
4470  *
4471  *  \sa DataArrayDouble::getIdsNotInRange
4472  *
4473  *  \ref cpp_mcdataarraydouble_getidsinrange "Here is a C++ example".<br>
4474  *  \ref py_mcdataarraydouble_getidsinrange "Here is a Python example".
4475  */
4476 DataArrayInt *DataArrayDouble::getIdsInRange(double vmin, double vmax) const
4477 {
4478   checkAllocated();
4479   if(getNumberOfComponents()!=1)
4480     throw INTERP_KERNEL::Exception("DataArrayDouble::getIdsInRange : this must have exactly one component !");
4481   const double *cptr(begin());
4482   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
4483   int nbOfTuples(getNumberOfTuples());
4484   for(int i=0;i<nbOfTuples;i++,cptr++)
4485     if(*cptr>=vmin && *cptr<=vmax)
4486       ret->pushBackSilent(i);
4487   return ret.retn();
4488 }
4489
4490 /*!
4491  * Returns a new DataArrayInt contating indices of tuples of \a this one-dimensional
4492  * array whose values are not within a given range. Textual data is not copied.
4493  *  \param [in] vmin - a lowest not acceptable value (excluded).
4494  *  \param [in] vmax - a greatest not acceptable value (excluded).
4495  *  \return DataArrayInt * - the new instance of DataArrayInt.
4496  *          The caller is to delete this result array using decrRef() as it is no more
4497  *          needed.
4498  *  \throw If \a this->getNumberOfComponents() != 1.
4499  *
4500  *  \sa DataArrayDouble::getIdsInRange
4501  */
4502 DataArrayInt *DataArrayDouble::getIdsNotInRange(double vmin, double vmax) const
4503 {
4504   checkAllocated();
4505   if(getNumberOfComponents()!=1)
4506     throw INTERP_KERNEL::Exception("DataArrayDouble::getIdsNotInRange : this must have exactly one component !");
4507   const double *cptr(begin());
4508   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
4509   int nbOfTuples(getNumberOfTuples());
4510   for(int i=0;i<nbOfTuples;i++,cptr++)
4511     if(*cptr<vmin || *cptr>vmax)
4512       ret->pushBackSilent(i);
4513   return ret.retn();
4514 }
4515
4516 /*!
4517  * Returns a new DataArrayDouble by concatenating two given arrays, so that (1) the number
4518  * of tuples in the result array is a sum of the number of tuples of given arrays and (2)
4519  * the number of component in the result array is same as that of each of given arrays.
4520  * Info on components is copied from the first of the given arrays. Number of components
4521  * in the given arrays must be  the same.
4522  *  \param [in] a1 - an array to include in the result array.
4523  *  \param [in] a2 - another array to include in the result array.
4524  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4525  *          The caller is to delete this result array using decrRef() as it is no more
4526  *          needed.
4527  *  \throw If both \a a1 and \a a2 are NULL.
4528  *  \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents().
4529  */
4530 DataArrayDouble *DataArrayDouble::Aggregate(const DataArrayDouble *a1, const DataArrayDouble *a2)
4531 {
4532   std::vector<const DataArrayDouble *> tmp(2);
4533   tmp[0]=a1; tmp[1]=a2;
4534   return Aggregate(tmp);
4535 }
4536
4537 /*!
4538  * Returns a new DataArrayDouble by concatenating all given arrays, so that (1) the number
4539  * of tuples in the result array is a sum of the number of tuples of given arrays and (2)
4540  * the number of component in the result array is same as that of each of given arrays.
4541  * Info on components is copied from the first of the given arrays. Number of components
4542  * in the given arrays must be  the same.
4543  *  \param [in] arr - a sequence of arrays to include in the result array.
4544  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4545  *          The caller is to delete this result array using decrRef() as it is no more
4546  *          needed.
4547  *  \throw If all arrays within \a arr are NULL.
4548  *  \throw If getNumberOfComponents() of arrays within \a arr.
4549  */
4550 DataArrayDouble *DataArrayDouble::Aggregate(const std::vector<const DataArrayDouble *>& arr)
4551 {
4552   std::vector<const DataArrayDouble *> a;
4553   for(std::vector<const DataArrayDouble *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
4554     if(*it4)
4555       a.push_back(*it4);
4556   if(a.empty())
4557     throw INTERP_KERNEL::Exception("DataArrayDouble::Aggregate : input list must contain at least one NON EMPTY DataArrayDouble !");
4558   std::vector<const DataArrayDouble *>::const_iterator it=a.begin();
4559   int nbOfComp=(*it)->getNumberOfComponents();
4560   int nbt=(*it++)->getNumberOfTuples();
4561   for(int i=1;it!=a.end();it++,i++)
4562     {
4563       if((*it)->getNumberOfComponents()!=nbOfComp)
4564         throw INTERP_KERNEL::Exception("DataArrayDouble::Aggregate : Nb of components mismatch for array aggregation !");
4565       nbt+=(*it)->getNumberOfTuples();
4566     }
4567   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
4568   ret->alloc(nbt,nbOfComp);
4569   double *pt=ret->getPointer();
4570   for(it=a.begin();it!=a.end();it++)
4571     pt=std::copy((*it)->getConstPointer(),(*it)->getConstPointer()+(*it)->getNbOfElems(),pt);
4572   ret->copyStringInfoFrom(*(a[0]));
4573   return ret.retn();
4574 }
4575
4576 /*!
4577  * Returns a new DataArrayDouble by aggregating two given arrays, so that (1) the number
4578  * of components in the result array is a sum of the number of components of given arrays
4579  * and (2) the number of tuples in the result array is same as that of each of given
4580  * arrays. In other words the i-th tuple of result array includes all components of
4581  * i-th tuples of all given arrays.
4582  * Number of tuples in the given arrays must be  the same.
4583  *  \param [in] a1 - an array to include in the result array.
4584  *  \param [in] a2 - another array to include in the result array.
4585  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4586  *          The caller is to delete this result array using decrRef() as it is no more
4587  *          needed.
4588  *  \throw If both \a a1 and \a a2 are NULL.
4589  *  \throw If any given array is not allocated.
4590  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
4591  */
4592 DataArrayDouble *DataArrayDouble::Meld(const DataArrayDouble *a1, const DataArrayDouble *a2)
4593 {
4594   std::vector<const DataArrayDouble *> arr(2);
4595   arr[0]=a1; arr[1]=a2;
4596   return Meld(arr);
4597 }
4598
4599 /*!
4600  * Returns a new DataArrayDouble by aggregating all given arrays, so that (1) the number
4601  * of components in the result array is a sum of the number of components of given arrays
4602  * and (2) the number of tuples in the result array is same as that of each of given
4603  * arrays. In other words the i-th tuple of result array includes all components of
4604  * i-th tuples of all given arrays.
4605  * Number of tuples in the given arrays must be  the same.
4606  *  \param [in] arr - a sequence of arrays to include in the result array.
4607  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4608  *          The caller is to delete this result array using decrRef() as it is no more
4609  *          needed.
4610  *  \throw If all arrays within \a arr are NULL.
4611  *  \throw If any given array is not allocated.
4612  *  \throw If getNumberOfTuples() of arrays within \a arr is different.
4613  */
4614 DataArrayDouble *DataArrayDouble::Meld(const std::vector<const DataArrayDouble *>& arr)
4615 {
4616   std::vector<const DataArrayDouble *> a;
4617   for(std::vector<const DataArrayDouble *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
4618     if(*it4)
4619       a.push_back(*it4);
4620   if(a.empty())
4621     throw INTERP_KERNEL::Exception("DataArrayDouble::Meld : input list must contain at least one NON EMPTY DataArrayDouble !");
4622   std::vector<const DataArrayDouble *>::const_iterator it;
4623   for(it=a.begin();it!=a.end();it++)
4624     (*it)->checkAllocated();
4625   it=a.begin();
4626   int nbOfTuples=(*it)->getNumberOfTuples();
4627   std::vector<int> nbc(a.size());
4628   std::vector<const double *> pts(a.size());
4629   nbc[0]=(*it)->getNumberOfComponents();
4630   pts[0]=(*it++)->getConstPointer();
4631   for(int i=1;it!=a.end();it++,i++)
4632     {
4633       if(nbOfTuples!=(*it)->getNumberOfTuples())
4634         throw INTERP_KERNEL::Exception("DataArrayDouble::Meld : mismatch of number of tuples !");
4635       nbc[i]=(*it)->getNumberOfComponents();
4636       pts[i]=(*it)->getConstPointer();
4637     }
4638   int totalNbOfComp=std::accumulate(nbc.begin(),nbc.end(),0);
4639   DataArrayDouble *ret=DataArrayDouble::New();
4640   ret->alloc(nbOfTuples,totalNbOfComp);
4641   double *retPtr=ret->getPointer();
4642   for(int i=0;i<nbOfTuples;i++)
4643     for(int j=0;j<(int)a.size();j++)
4644       {
4645         retPtr=std::copy(pts[j],pts[j]+nbc[j],retPtr);
4646         pts[j]+=nbc[j];
4647       }
4648   int k=0;
4649   for(int i=0;i<(int)a.size();i++)
4650     for(int j=0;j<nbc[i];j++,k++)
4651       ret->setInfoOnComponent(k,a[i]->getInfoOnComponent(j).c_str());
4652   return ret;
4653 }
4654
4655 /*!
4656  * Returns a new DataArrayDouble containing a dot product of two given arrays, so that
4657  * the i-th tuple of the result array is a sum of products of j-th components of i-th
4658  * tuples of given arrays (\f$ a_i = \sum_{j=1}^n a1_j * a2_j \f$).
4659  * Info on components and name is copied from the first of the given arrays.
4660  * Number of tuples and components in the given arrays must be the same.
4661  *  \param [in] a1 - a given array.
4662  *  \param [in] a2 - another given array.
4663  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4664  *          The caller is to delete this result array using decrRef() as it is no more
4665  *          needed.
4666  *  \throw If either \a a1 or \a a2 is NULL.
4667  *  \throw If any given array is not allocated.
4668  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
4669  *  \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents()
4670  */
4671 DataArrayDouble *DataArrayDouble::Dot(const DataArrayDouble *a1, const DataArrayDouble *a2)
4672 {
4673   if(!a1 || !a2)
4674     throw INTERP_KERNEL::Exception("DataArrayDouble::Dot : input DataArrayDouble instance is NULL !");
4675   a1->checkAllocated();
4676   a2->checkAllocated();
4677   int nbOfComp=a1->getNumberOfComponents();
4678   if(nbOfComp!=a2->getNumberOfComponents())
4679     throw INTERP_KERNEL::Exception("Nb of components mismatch for array Dot !");
4680   int nbOfTuple=a1->getNumberOfTuples();
4681   if(nbOfTuple!=a2->getNumberOfTuples())
4682     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Dot !");
4683   DataArrayDouble *ret=DataArrayDouble::New();
4684   ret->alloc(nbOfTuple,1);
4685   double *retPtr=ret->getPointer();
4686   const double *a1Ptr=a1->getConstPointer();
4687   const double *a2Ptr=a2->getConstPointer();
4688   for(int i=0;i<nbOfTuple;i++)
4689     {
4690       double sum=0.;
4691       for(int j=0;j<nbOfComp;j++)
4692         sum+=a1Ptr[i*nbOfComp+j]*a2Ptr[i*nbOfComp+j];
4693       retPtr[i]=sum;
4694     }
4695   ret->setInfoOnComponent(0,a1->getInfoOnComponent(0).c_str());
4696   ret->setName(a1->getName().c_str());
4697   return ret;
4698 }
4699
4700 /*!
4701  * Returns a new DataArrayDouble containing a cross product of two given arrays, so that
4702  * the i-th tuple of the result array contains 3 components of a vector which is a cross
4703  * product of two vectors defined by the i-th tuples of given arrays.
4704  * Info on components is copied from the first of the given arrays.
4705  * Number of tuples in the given arrays must be the same.
4706  * Number of components in the given arrays must be 3.
4707  *  \param [in] a1 - a given array.
4708  *  \param [in] a2 - another given array.
4709  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4710  *          The caller is to delete this result array using decrRef() as it is no more
4711  *          needed.
4712  *  \throw If either \a a1 or \a a2 is NULL.
4713  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
4714  *  \throw If \a a1->getNumberOfComponents() != 3
4715  *  \throw If \a a2->getNumberOfComponents() != 3
4716  */
4717 DataArrayDouble *DataArrayDouble::CrossProduct(const DataArrayDouble *a1, const DataArrayDouble *a2)
4718 {
4719   if(!a1 || !a2)
4720     throw INTERP_KERNEL::Exception("DataArrayDouble::CrossProduct : input DataArrayDouble instance is NULL !");
4721   int nbOfComp=a1->getNumberOfComponents();
4722   if(nbOfComp!=a2->getNumberOfComponents())
4723     throw INTERP_KERNEL::Exception("Nb of components mismatch for array crossProduct !");
4724   if(nbOfComp!=3)
4725     throw INTERP_KERNEL::Exception("Nb of components must be equal to 3 for array crossProduct !");
4726   int nbOfTuple=a1->getNumberOfTuples();
4727   if(nbOfTuple!=a2->getNumberOfTuples())
4728     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array crossProduct !");
4729   DataArrayDouble *ret=DataArrayDouble::New();
4730   ret->alloc(nbOfTuple,3);
4731   double *retPtr=ret->getPointer();
4732   const double *a1Ptr=a1->getConstPointer();
4733   const double *a2Ptr=a2->getConstPointer();
4734   for(int i=0;i<nbOfTuple;i++)
4735     {
4736       retPtr[3*i]=a1Ptr[3*i+1]*a2Ptr[3*i+2]-a1Ptr[3*i+2]*a2Ptr[3*i+1];
4737       retPtr[3*i+1]=a1Ptr[3*i+2]*a2Ptr[3*i]-a1Ptr[3*i]*a2Ptr[3*i+2];
4738       retPtr[3*i+2]=a1Ptr[3*i]*a2Ptr[3*i+1]-a1Ptr[3*i+1]*a2Ptr[3*i];
4739     }
4740   ret->copyStringInfoFrom(*a1);
4741   return ret;
4742 }
4743
4744 /*!
4745  * Returns a new DataArrayDouble containing maximal values of two given arrays.
4746  * Info on components is copied from the first of the given arrays.
4747  * Number of tuples and components in the given arrays must be the same.
4748  *  \param [in] a1 - an array to compare values with another one.
4749  *  \param [in] a2 - another array to compare values with the first one.
4750  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4751  *          The caller is to delete this result array using decrRef() as it is no more
4752  *          needed.
4753  *  \throw If either \a a1 or \a a2 is NULL.
4754  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
4755  *  \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents()
4756  */
4757 DataArrayDouble *DataArrayDouble::Max(const DataArrayDouble *a1, const DataArrayDouble *a2)
4758 {
4759   if(!a1 || !a2)
4760     throw INTERP_KERNEL::Exception("DataArrayDouble::Max : input DataArrayDouble instance is NULL !");
4761   int nbOfComp=a1->getNumberOfComponents();
4762   if(nbOfComp!=a2->getNumberOfComponents())
4763     throw INTERP_KERNEL::Exception("Nb of components mismatch for array Max !");
4764   int nbOfTuple=a1->getNumberOfTuples();
4765   if(nbOfTuple!=a2->getNumberOfTuples())
4766     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Max !");
4767   DataArrayDouble *ret=DataArrayDouble::New();
4768   ret->alloc(nbOfTuple,nbOfComp);
4769   double *retPtr=ret->getPointer();
4770   const double *a1Ptr=a1->getConstPointer();
4771   const double *a2Ptr=a2->getConstPointer();
4772   int nbElem=nbOfTuple*nbOfComp;
4773   for(int i=0;i<nbElem;i++)
4774     retPtr[i]=std::max(a1Ptr[i],a2Ptr[i]);
4775   ret->copyStringInfoFrom(*a1);
4776   return ret;
4777 }
4778
4779 /*!
4780  * Returns a new DataArrayDouble containing minimal values of two given arrays.
4781  * Info on components is copied from the first of the given arrays.
4782  * Number of tuples and components in the given arrays must be the same.
4783  *  \param [in] a1 - an array to compare values with another one.
4784  *  \param [in] a2 - another array to compare values with the first one.
4785  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4786  *          The caller is to delete this result array using decrRef() as it is no more
4787  *          needed.
4788  *  \throw If either \a a1 or \a a2 is NULL.
4789  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
4790  *  \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents()
4791  */
4792 DataArrayDouble *DataArrayDouble::Min(const DataArrayDouble *a1, const DataArrayDouble *a2)
4793 {
4794   if(!a1 || !a2)
4795     throw INTERP_KERNEL::Exception("DataArrayDouble::Min : input DataArrayDouble instance is NULL !");
4796   int nbOfComp=a1->getNumberOfComponents();
4797   if(nbOfComp!=a2->getNumberOfComponents())
4798     throw INTERP_KERNEL::Exception("Nb of components mismatch for array min !");
4799   int nbOfTuple=a1->getNumberOfTuples();
4800   if(nbOfTuple!=a2->getNumberOfTuples())
4801     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array min !");
4802   DataArrayDouble *ret=DataArrayDouble::New();
4803   ret->alloc(nbOfTuple,nbOfComp);
4804   double *retPtr=ret->getPointer();
4805   const double *a1Ptr=a1->getConstPointer();
4806   const double *a2Ptr=a2->getConstPointer();
4807   int nbElem=nbOfTuple*nbOfComp;
4808   for(int i=0;i<nbElem;i++)
4809     retPtr[i]=std::min(a1Ptr[i],a2Ptr[i]);
4810   ret->copyStringInfoFrom(*a1);
4811   return ret;
4812 }
4813
4814 /*!
4815  * Returns a new DataArrayDouble that is a sum of two given arrays. There are 3
4816  * valid cases.
4817  * 1.  The arrays have same number of tuples and components. Then each value of
4818  *   the result array (_a_) is a sum of the corresponding values of \a a1 and \a a2,
4819  *   i.e.: _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ i, j ].
4820  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
4821  *   component. Then
4822  *   _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ i, 0 ].
4823  * 3.  The arrays have same number of components and one array, say _a2_, has one
4824  *   tuple. Then
4825  *   _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ 0, j ].
4826  *
4827  * Info on components is copied either from the first array (in the first case) or from
4828  * the array with maximal number of elements (getNbOfElems()).
4829  *  \param [in] a1 - an array to sum up.
4830  *  \param [in] a2 - another array to sum up.
4831  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4832  *          The caller is to delete this result array using decrRef() as it is no more
4833  *          needed.
4834  *  \throw If either \a a1 or \a a2 is NULL.
4835  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
4836  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
4837  *         none of them has number of tuples or components equal to 1.
4838  */
4839 DataArrayDouble *DataArrayDouble::Add(const DataArrayDouble *a1, const DataArrayDouble *a2)
4840 {
4841   if(!a1 || !a2)
4842     throw INTERP_KERNEL::Exception("DataArrayDouble::Add : input DataArrayDouble instance is NULL !");
4843   int nbOfTuple=a1->getNumberOfTuples();
4844   int nbOfTuple2=a2->getNumberOfTuples();
4845   int nbOfComp=a1->getNumberOfComponents();
4846   int nbOfComp2=a2->getNumberOfComponents();
4847   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=0;
4848   if(nbOfTuple==nbOfTuple2)
4849     {
4850       if(nbOfComp==nbOfComp2)
4851         {
4852           ret=DataArrayDouble::New();
4853           ret->alloc(nbOfTuple,nbOfComp);
4854           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::plus<double>());
4855           ret->copyStringInfoFrom(*a1);
4856         }
4857       else
4858         {
4859           int nbOfCompMin,nbOfCompMax;
4860           const DataArrayDouble *aMin, *aMax;
4861           if(nbOfComp>nbOfComp2)
4862             {
4863               nbOfCompMin=nbOfComp2; nbOfCompMax=nbOfComp;
4864               aMin=a2; aMax=a1;
4865             }
4866           else
4867             {
4868               nbOfCompMin=nbOfComp; nbOfCompMax=nbOfComp2;
4869               aMin=a1; aMax=a2;
4870             }
4871           if(nbOfCompMin==1)
4872             {
4873               ret=DataArrayDouble::New();
4874               ret->alloc(nbOfTuple,nbOfCompMax);
4875               const double *aMinPtr=aMin->getConstPointer();
4876               const double *aMaxPtr=aMax->getConstPointer();
4877               double *res=ret->getPointer();
4878               for(int i=0;i<nbOfTuple;i++)
4879                 res=std::transform(aMaxPtr+i*nbOfCompMax,aMaxPtr+(i+1)*nbOfCompMax,res,std::bind2nd(std::plus<double>(),aMinPtr[i]));
4880               ret->copyStringInfoFrom(*aMax);
4881             }
4882           else
4883             throw INTERP_KERNEL::Exception("Nb of components mismatch for array Add !");
4884         }
4885     }
4886   else if((nbOfTuple==1 && nbOfTuple2>1) || (nbOfTuple>1 && nbOfTuple2==1))
4887     {
4888       if(nbOfComp==nbOfComp2)
4889         {
4890           int nbOfTupleMax=std::max(nbOfTuple,nbOfTuple2);
4891           const DataArrayDouble *aMin=nbOfTuple>nbOfTuple2?a2:a1;
4892           const DataArrayDouble *aMax=nbOfTuple>nbOfTuple2?a1:a2;
4893           const double *aMinPtr=aMin->getConstPointer(),*aMaxPtr=aMax->getConstPointer();
4894           ret=DataArrayDouble::New();
4895           ret->alloc(nbOfTupleMax,nbOfComp);
4896           double *res=ret->getPointer();
4897           for(int i=0;i<nbOfTupleMax;i++)
4898             res=std::transform(aMaxPtr+i*nbOfComp,aMaxPtr+(i+1)*nbOfComp,aMinPtr,res,std::plus<double>());
4899           ret->copyStringInfoFrom(*aMax);
4900         }
4901       else
4902         throw INTERP_KERNEL::Exception("Nb of components mismatch for array Add !");
4903     }
4904   else
4905     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Add !");
4906   return ret.retn();
4907 }
4908
4909 /*!
4910  * Adds values of another DataArrayDouble to values of \a this one. There are 3
4911  * valid cases.
4912  * 1.  The arrays have same number of tuples and components. Then each value of
4913  *   \a other array is added to the corresponding value of \a this array, i.e.:
4914  *   _a_ [ i, j ] += _other_ [ i, j ].
4915  * 2.  The arrays have same number of tuples and \a other array has one component. Then
4916  *   _a_ [ i, j ] += _other_ [ i, 0 ].
4917  * 3.  The arrays have same number of components and \a other array has one tuple. Then
4918  *   _a_ [ i, j ] += _a2_ [ 0, j ].
4919  *
4920  *  \param [in] other - an array to add to \a this one.
4921  *  \throw If \a other is NULL.
4922  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
4923  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
4924  *         \a other has number of both tuples and components not equal to 1.
4925  */
4926 void DataArrayDouble::addEqual(const DataArrayDouble *other)
4927 {
4928   if(!other)
4929     throw INTERP_KERNEL::Exception("DataArrayDouble::addEqual : input DataArrayDouble instance is NULL !");
4930   const char *msg="Nb of tuples mismatch for DataArrayDouble::addEqual  !";
4931   checkAllocated();
4932   other->checkAllocated();
4933   int nbOfTuple=getNumberOfTuples();
4934   int nbOfTuple2=other->getNumberOfTuples();
4935   int nbOfComp=getNumberOfComponents();
4936   int nbOfComp2=other->getNumberOfComponents();
4937   if(nbOfTuple==nbOfTuple2)
4938     {
4939       if(nbOfComp==nbOfComp2)
4940         {
4941           std::transform(begin(),end(),other->begin(),getPointer(),std::plus<double>());
4942         }
4943       else if(nbOfComp2==1)
4944         {
4945           double *ptr=getPointer();
4946           const double *ptrc=other->getConstPointer();
4947           for(int i=0;i<nbOfTuple;i++)
4948             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::plus<double>(),*ptrc++));
4949         }
4950       else
4951         throw INTERP_KERNEL::Exception(msg);
4952     }
4953   else if(nbOfTuple2==1)
4954     {
4955       if(nbOfComp2==nbOfComp)
4956         {
4957           double *ptr=getPointer();
4958           const double *ptrc=other->getConstPointer();
4959           for(int i=0;i<nbOfTuple;i++)
4960             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::plus<double>());
4961         }
4962       else
4963         throw INTERP_KERNEL::Exception(msg);
4964     }
4965   else
4966     throw INTERP_KERNEL::Exception(msg);
4967   declareAsNew();
4968 }
4969
4970 /*!
4971  * Returns a new DataArrayDouble that is a subtraction of two given arrays. There are 3
4972  * valid cases.
4973  * 1.  The arrays have same number of tuples and components. Then each value of
4974  *   the result array (_a_) is a subtraction of the corresponding values of \a a1 and
4975  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ i, j ].
4976  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
4977  *   component. Then
4978  *   _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ i, 0 ].
4979  * 3.  The arrays have same number of components and one array, say _a2_, has one
4980  *   tuple. Then
4981  *   _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ 0, j ].
4982  *
4983  * Info on components is copied either from the first array (in the first case) or from
4984  * the array with maximal number of elements (getNbOfElems()).
4985  *  \param [in] a1 - an array to subtract from.
4986  *  \param [in] a2 - an array to subtract.
4987  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4988  *          The caller is to delete this result array using decrRef() as it is no more
4989  *          needed.
4990  *  \throw If either \a a1 or \a a2 is NULL.
4991  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
4992  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
4993  *         none of them has number of tuples or components equal to 1.
4994  */
4995 DataArrayDouble *DataArrayDouble::Substract(const DataArrayDouble *a1, const DataArrayDouble *a2)
4996 {
4997   if(!a1 || !a2)
4998     throw INTERP_KERNEL::Exception("DataArrayDouble::Substract : input DataArrayDouble instance is NULL !");
4999   int nbOfTuple1=a1->getNumberOfTuples();
5000   int nbOfTuple2=a2->getNumberOfTuples();
5001   int nbOfComp1=a1->getNumberOfComponents();
5002   int nbOfComp2=a2->getNumberOfComponents();
5003   if(nbOfTuple2==nbOfTuple1)
5004     {
5005       if(nbOfComp1==nbOfComp2)
5006         {
5007           MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
5008           ret->alloc(nbOfTuple2,nbOfComp1);
5009           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::minus<double>());
5010           ret->copyStringInfoFrom(*a1);
5011           return ret.retn();
5012         }
5013       else if(nbOfComp2==1)
5014         {
5015           MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
5016           ret->alloc(nbOfTuple1,nbOfComp1);
5017           const double *a2Ptr=a2->getConstPointer();
5018           const double *a1Ptr=a1->getConstPointer();
5019           double *res=ret->getPointer();
5020           for(int i=0;i<nbOfTuple1;i++)
5021             res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::minus<double>(),a2Ptr[i]));
5022           ret->copyStringInfoFrom(*a1);
5023           return ret.retn();
5024         }
5025       else
5026         {
5027           a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Substract !");
5028           return 0;
5029         }
5030     }
5031   else if(nbOfTuple2==1)
5032     {
5033       a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Substract !");
5034       MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
5035       ret->alloc(nbOfTuple1,nbOfComp1);
5036       const double *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
5037       double *pt=ret->getPointer();
5038       for(int i=0;i<nbOfTuple1;i++)
5039         pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::minus<double>());
5040       ret->copyStringInfoFrom(*a1);
5041       return ret.retn();
5042     }
5043   else
5044     {
5045       a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Substract !");//will always throw an exception
5046       return 0;
5047     }
5048 }
5049
5050 /*!
5051  * Subtract values of another DataArrayDouble from values of \a this one. There are 3
5052  * valid cases.
5053  * 1.  The arrays have same number of tuples and components. Then each value of
5054  *   \a other array is subtracted from the corresponding value of \a this array, i.e.:
5055  *   _a_ [ i, j ] -= _other_ [ i, j ].
5056  * 2.  The arrays have same number of tuples and \a other array has one component. Then
5057  *   _a_ [ i, j ] -= _other_ [ i, 0 ].
5058  * 3.  The arrays have same number of components and \a other array has one tuple. Then
5059  *   _a_ [ i, j ] -= _a2_ [ 0, j ].
5060  *
5061  *  \param [in] other - an array to subtract from \a this one.
5062  *  \throw If \a other is NULL.
5063  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
5064  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
5065  *         \a other has number of both tuples and components not equal to 1.
5066  */
5067 void DataArrayDouble::substractEqual(const DataArrayDouble *other)
5068 {
5069   if(!other)
5070     throw INTERP_KERNEL::Exception("DataArrayDouble::substractEqual : input DataArrayDouble instance is NULL !");
5071   const char *msg="Nb of tuples mismatch for DataArrayDouble::substractEqual  !";
5072   checkAllocated();
5073   other->checkAllocated();
5074   int nbOfTuple=getNumberOfTuples();
5075   int nbOfTuple2=other->getNumberOfTuples();
5076   int nbOfComp=getNumberOfComponents();
5077   int nbOfComp2=other->getNumberOfComponents();
5078   if(nbOfTuple==nbOfTuple2)
5079     {
5080       if(nbOfComp==nbOfComp2)
5081         {
5082           std::transform(begin(),end(),other->begin(),getPointer(),std::minus<double>());
5083         }
5084       else if(nbOfComp2==1)
5085         {
5086           double *ptr=getPointer();
5087           const double *ptrc=other->getConstPointer();
5088           for(int i=0;i<nbOfTuple;i++)
5089             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::minus<double>(),*ptrc++)); 
5090         }
5091       else
5092         throw INTERP_KERNEL::Exception(msg);
5093     }
5094   else if(nbOfTuple2==1)
5095     {
5096       if(nbOfComp2==nbOfComp)
5097         {
5098           double *ptr=getPointer();
5099           const double *ptrc=other->getConstPointer();
5100           for(int i=0;i<nbOfTuple;i++)
5101             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::minus<double>());
5102         }
5103       else
5104         throw INTERP_KERNEL::Exception(msg);
5105     }
5106   else
5107     throw INTERP_KERNEL::Exception(msg);
5108   declareAsNew();
5109 }
5110
5111 /*!
5112  * Returns a new DataArrayDouble that is a product of two given arrays. There are 3
5113  * valid cases.
5114  * 1.  The arrays have same number of tuples and components. Then each value of
5115  *   the result array (_a_) is a product of the corresponding values of \a a1 and
5116  *   \a a2, i.e. _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ i, j ].
5117  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
5118  *   component. Then
5119  *   _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ i, 0 ].
5120  * 3.  The arrays have same number of components and one array, say _a2_, has one
5121  *   tuple. Then
5122  *   _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ 0, j ].
5123  *
5124  * Info on components is copied either from the first array (in the first case) or from
5125  * the array with maximal number of elements (getNbOfElems()).
5126  *  \param [in] a1 - a factor array.
5127  *  \param [in] a2 - another factor array.
5128  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
5129  *          The caller is to delete this result array using decrRef() as it is no more
5130  *          needed.
5131  *  \throw If either \a a1 or \a a2 is NULL.
5132  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
5133  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
5134  *         none of them has number of tuples or components equal to 1.
5135  */
5136 DataArrayDouble *DataArrayDouble::Multiply(const DataArrayDouble *a1, const DataArrayDouble *a2)
5137 {
5138   if(!a1 || !a2)
5139     throw INTERP_KERNEL::Exception("DataArrayDouble::Multiply : input DataArrayDouble instance is NULL !");
5140   int nbOfTuple=a1->getNumberOfTuples();
5141   int nbOfTuple2=a2->getNumberOfTuples();
5142   int nbOfComp=a1->getNumberOfComponents();
5143   int nbOfComp2=a2->getNumberOfComponents();
5144   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=0;
5145   if(nbOfTuple==nbOfTuple2)
5146     {
5147       if(nbOfComp==nbOfComp2)
5148         {
5149           ret=DataArrayDouble::New();
5150           ret->alloc(nbOfTuple,nbOfComp);
5151           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::multiplies<double>());
5152           ret->copyStringInfoFrom(*a1);
5153         }
5154       else
5155         {
5156           int nbOfCompMin,nbOfCompMax;
5157           const DataArrayDouble *aMin, *aMax;
5158           if(nbOfComp>nbOfComp2)
5159             {
5160               nbOfCompMin=nbOfComp2; nbOfCompMax=nbOfComp;
5161               aMin=a2; aMax=a1;
5162             }
5163           else
5164             {
5165               nbOfCompMin=nbOfComp; nbOfCompMax=nbOfComp2;
5166               aMin=a1; aMax=a2;
5167             }
5168           if(nbOfCompMin==1)
5169             {
5170               ret=DataArrayDouble::New();
5171               ret->alloc(nbOfTuple,nbOfCompMax);
5172               const double *aMinPtr=aMin->getConstPointer();
5173               const double *aMaxPtr=aMax->getConstPointer();
5174               double *res=ret->getPointer();
5175               for(int i=0;i<nbOfTuple;i++)
5176                 res=std::transform(aMaxPtr+i*nbOfCompMax,aMaxPtr+(i+1)*nbOfCompMax,res,std::bind2nd(std::multiplies<double>(),aMinPtr[i]));
5177               ret->copyStringInfoFrom(*aMax);
5178             }
5179           else
5180             throw INTERP_KERNEL::Exception("Nb of components mismatch for array Multiply !");
5181         }
5182     }
5183   else if((nbOfTuple==1 && nbOfTuple2>1) || (nbOfTuple>1 && nbOfTuple2==1))
5184     {
5185       if(nbOfComp==nbOfComp2)
5186         {
5187           int nbOfTupleMax=std::max(nbOfTuple,nbOfTuple2);
5188           const DataArrayDouble *aMin=nbOfTuple>nbOfTuple2?a2:a1;
5189           const DataArrayDouble *aMax=nbOfTuple>nbOfTuple2?a1:a2;
5190           const double *aMinPtr=aMin->getConstPointer(),*aMaxPtr=aMax->getConstPointer();
5191           ret=DataArrayDouble::New();
5192           ret->alloc(nbOfTupleMax,nbOfComp);
5193           double *res=ret->getPointer();
5194           for(int i=0;i<nbOfTupleMax;i++)
5195             res=std::transform(aMaxPtr+i*nbOfComp,aMaxPtr+(i+1)*nbOfComp,aMinPtr,res,std::multiplies<double>());
5196           ret->copyStringInfoFrom(*aMax);
5197         }
5198       else
5199         throw INTERP_KERNEL::Exception("Nb of components mismatch for array Multiply !");
5200     }
5201   else
5202     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Multiply !");
5203   return ret.retn();
5204 }
5205
5206 /*!
5207  * Multiply values of another DataArrayDouble to values of \a this one. There are 3
5208  * valid cases.
5209  * 1.  The arrays have same number of tuples and components. Then each value of
5210  *   \a other array is multiplied to the corresponding value of \a this array, i.e.
5211  *   _this_ [ i, j ] *= _other_ [ i, j ].
5212  * 2.  The arrays have same number of tuples and \a other array has one component. Then
5213  *   _this_ [ i, j ] *= _other_ [ i, 0 ].
5214  * 3.  The arrays have same number of components and \a other array has one tuple. Then
5215  *   _this_ [ i, j ] *= _a2_ [ 0, j ].
5216  *
5217  *  \param [in] other - an array to multiply to \a this one.
5218  *  \throw If \a other is NULL.
5219  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
5220  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
5221  *         \a other has number of both tuples and components not equal to 1.
5222  */
5223 void DataArrayDouble::multiplyEqual(const DataArrayDouble *other)
5224 {
5225   if(!other)
5226     throw INTERP_KERNEL::Exception("DataArrayDouble::multiplyEqual : input DataArrayDouble instance is NULL !");
5227   const char *msg="Nb of tuples mismatch for DataArrayDouble::multiplyEqual !";
5228   checkAllocated();
5229   other->checkAllocated();
5230   int nbOfTuple=getNumberOfTuples();
5231   int nbOfTuple2=other->getNumberOfTuples();
5232   int nbOfComp=getNumberOfComponents();
5233   int nbOfComp2=other->getNumberOfComponents();
5234   if(nbOfTuple==nbOfTuple2)
5235     {
5236       if(nbOfComp==nbOfComp2)
5237         {
5238           std::transform(begin(),end(),other->begin(),getPointer(),std::multiplies<double>());
5239         }
5240       else if(nbOfComp2==1)
5241         {
5242           double *ptr=getPointer();
5243           const double *ptrc=other->getConstPointer();
5244           for(int i=0;i<nbOfTuple;i++)
5245             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::multiplies<double>(),*ptrc++));
5246         }
5247       else
5248         throw INTERP_KERNEL::Exception(msg);
5249     }
5250   else if(nbOfTuple2==1)
5251     {
5252       if(nbOfComp2==nbOfComp)
5253         {
5254           double *ptr=getPointer();
5255           const double *ptrc=other->getConstPointer();
5256           for(int i=0;i<nbOfTuple;i++)
5257             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::multiplies<double>());
5258         }
5259       else
5260         throw INTERP_KERNEL::Exception(msg);
5261     }
5262   else
5263     throw INTERP_KERNEL::Exception(msg);
5264   declareAsNew();
5265 }
5266
5267 /*!
5268  * Returns a new DataArrayDouble that is a division of two given arrays. There are 3
5269  * valid cases.
5270  * 1.  The arrays have same number of tuples and components. Then each value of
5271  *   the result array (_a_) is a division of the corresponding values of \a a1 and
5272  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ i, j ].
5273  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
5274  *   component. Then
5275  *   _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ i, 0 ].
5276  * 3.  The arrays have same number of components and one array, say _a2_, has one
5277  *   tuple. Then
5278  *   _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ 0, j ].
5279  *
5280  * Info on components is copied either from the first array (in the first case) or from
5281  * the array with maximal number of elements (getNbOfElems()).
5282  *  \warning No check of division by zero is performed!
5283  *  \param [in] a1 - a numerator array.
5284  *  \param [in] a2 - a denominator array.
5285  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
5286  *          The caller is to delete this result array using decrRef() as it is no more
5287  *          needed.
5288  *  \throw If either \a a1 or \a a2 is NULL.
5289  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
5290  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
5291  *         none of them has number of tuples or components equal to 1.
5292  */
5293 DataArrayDouble *DataArrayDouble::Divide(const DataArrayDouble *a1, const DataArrayDouble *a2)
5294 {
5295   if(!a1 || !a2)
5296     throw INTERP_KERNEL::Exception("DataArrayDouble::Divide : input DataArrayDouble instance is NULL !");
5297   int nbOfTuple1=a1->getNumberOfTuples();
5298   int nbOfTuple2=a2->getNumberOfTuples();
5299   int nbOfComp1=a1->getNumberOfComponents();
5300   int nbOfComp2=a2->getNumberOfComponents();
5301   if(nbOfTuple2==nbOfTuple1)
5302     {
5303       if(nbOfComp1==nbOfComp2)
5304         {
5305           MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
5306           ret->alloc(nbOfTuple2,nbOfComp1);
5307           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::divides<double>());
5308           ret->copyStringInfoFrom(*a1);
5309           return ret.retn();
5310         }
5311       else if(nbOfComp2==1)
5312         {
5313           MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
5314           ret->alloc(nbOfTuple1,nbOfComp1);
5315           const double *a2Ptr=a2->getConstPointer();
5316           const double *a1Ptr=a1->getConstPointer();
5317           double *res=ret->getPointer();
5318           for(int i=0;i<nbOfTuple1;i++)
5319             res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::divides<double>(),a2Ptr[i]));
5320           ret->copyStringInfoFrom(*a1);
5321           return ret.retn();
5322         }
5323       else
5324         {
5325           a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Divide !");
5326           return 0;
5327         }
5328     }
5329   else if(nbOfTuple2==1)
5330     {
5331       a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Divide !");
5332       MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
5333       ret->alloc(nbOfTuple1,nbOfComp1);
5334       const double *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
5335       double *pt=ret->getPointer();
5336       for(int i=0;i<nbOfTuple1;i++)
5337         pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::divides<double>());
5338       ret->copyStringInfoFrom(*a1);
5339       return ret.retn();
5340     }
5341   else
5342     {
5343       a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Divide !");//will always throw an exception
5344       return 0;
5345     }
5346 }
5347
5348 /*!
5349  * Divide values of \a this array by values of another DataArrayDouble. There are 3
5350  * valid cases.
5351  * 1.  The arrays have same number of tuples and components. Then each value of
5352  *    \a this array is divided by the corresponding value of \a other one, i.e.:
5353  *   _a_ [ i, j ] /= _other_ [ i, j ].
5354  * 2.  The arrays have same number of tuples and \a other array has one component. Then
5355  *   _a_ [ i, j ] /= _other_ [ i, 0 ].
5356  * 3.  The arrays have same number of components and \a other array has one tuple. Then
5357  *   _a_ [ i, j ] /= _a2_ [ 0, j ].
5358  *
5359  *  \warning No check of division by zero is performed!
5360  *  \param [in] other - an array to divide \a this one by.
5361  *  \throw If \a other is NULL.
5362  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
5363  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
5364  *         \a other has number of both tuples and components not equal to 1.
5365  */
5366 void DataArrayDouble::divideEqual(const DataArrayDouble *other)
5367 {
5368   if(!other)
5369     throw INTERP_KERNEL::Exception("DataArrayDouble::divideEqual : input DataArrayDouble instance is NULL !");
5370   const char *msg="Nb of tuples mismatch for DataArrayDouble::divideEqual !";
5371   checkAllocated();
5372   other->checkAllocated();
5373   int nbOfTuple=getNumberOfTuples();
5374   int nbOfTuple2=other->getNumberOfTuples();
5375   int nbOfComp=getNumberOfComponents();
5376   int nbOfComp2=other->getNumberOfComponents();
5377   if(nbOfTuple==nbOfTuple2)
5378     {
5379       if(nbOfComp==nbOfComp2)
5380         {
5381           std::transform(begin(),end(),other->begin(),getPointer(),std::divides<double>());
5382         }
5383       else if(nbOfComp2==1)
5384         {
5385           double *ptr=getPointer();
5386           const double *ptrc=other->getConstPointer();
5387           for(int i=0;i<nbOfTuple;i++)
5388             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::divides<double>(),*ptrc++));
5389         }
5390       else
5391         throw INTERP_KERNEL::Exception(msg);
5392     }
5393   else if(nbOfTuple2==1)
5394     {
5395       if(nbOfComp2==nbOfComp)
5396         {
5397           double *ptr=getPointer();
5398           const double *ptrc=other->getConstPointer();
5399           for(int i=0;i<nbOfTuple;i++)
5400             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::divides<double>());
5401         }
5402       else
5403         throw INTERP_KERNEL::Exception(msg);
5404     }
5405   else
5406     throw INTERP_KERNEL::Exception(msg);
5407   declareAsNew();
5408 }
5409
5410 /*!
5411  * Returns a new DataArrayDouble that is the result of pow of two given arrays. There are 3
5412  * valid cases.
5413  *
5414  *  \param [in] a1 - an array to pow up.
5415  *  \param [in] a2 - another array to sum up.
5416  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
5417  *          The caller is to delete this result array using decrRef() as it is no more
5418  *          needed.
5419  *  \throw If either \a a1 or \a a2 is NULL.
5420  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
5421  *  \throw If \a a1->getNumberOfComponents() != 1 or \a a2->getNumberOfComponents() != 1.
5422  *  \throw If there is a negative value in \a a1.
5423  */
5424 DataArrayDouble *DataArrayDouble::Pow(const DataArrayDouble *a1, const DataArrayDouble *a2)
5425 {
5426   if(!a1 || !a2)
5427     throw INTERP_KERNEL::Exception("DataArrayDouble::Pow : at least one of input instances is null !");
5428   int nbOfTuple=a1->getNumberOfTuples();
5429   int nbOfTuple2=a2->getNumberOfTuples();
5430   int nbOfComp=a1->getNumberOfComponents();
5431   int nbOfComp2=a2->getNumberOfComponents();
5432   if(nbOfTuple!=nbOfTuple2)
5433     throw INTERP_KERNEL::Exception("DataArrayDouble::Pow : number of tuples mismatches !");
5434   if(nbOfComp!=1 || nbOfComp2!=1)
5435     throw INTERP_KERNEL::Exception("DataArrayDouble::Pow : number of components of both arrays must be equal to 1 !");
5436   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New(); ret->alloc(nbOfTuple,1);
5437   const double *ptr1(a1->begin()),*ptr2(a2->begin());
5438   double *ptr=ret->getPointer();
5439   for(int i=0;i<nbOfTuple;i++,ptr1++,ptr2++,ptr++)
5440     {
5441       if(*ptr1>=0)
5442         {
5443           *ptr=pow(*ptr1,*ptr2);
5444         }
5445       else
5446         {
5447           std::ostringstream oss; oss << "DataArrayDouble::Pow : on tuple #" << i << " of a1 value is < 0 (" << *ptr1 << ") !";
5448           throw INTERP_KERNEL::Exception(oss.str().c_str());
5449         }
5450     }
5451   return ret.retn();
5452 }
5453
5454 /*!
5455  * Apply pow on values of another DataArrayDouble to values of \a this one.
5456  *
5457  *  \param [in] other - an array to pow to \a this one.
5458  *  \throw If \a other is NULL.
5459  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples()
5460  *  \throw If \a this->getNumberOfComponents() != 1 or \a other->getNumberOfComponents() != 1
5461  *  \throw If there is a negative value in \a this.
5462  */
5463 void DataArrayDouble::powEqual(const DataArrayDouble *other)
5464 {
5465   if(!other)
5466     throw INTERP_KERNEL::Exception("DataArrayDouble::powEqual : input instance is null !");
5467   int nbOfTuple=getNumberOfTuples();
5468   int nbOfTuple2=other->getNumberOfTuples();
5469   int nbOfComp=getNumberOfComponents();
5470   int nbOfComp2=other->getNumberOfComponents();
5471   if(nbOfTuple!=nbOfTuple2)
5472     throw INTERP_KERNEL::Exception("DataArrayDouble::powEqual : number of tuples mismatches !");
5473   if(nbOfComp!=1 || nbOfComp2!=1)
5474     throw INTERP_KERNEL::Exception("DataArrayDouble::powEqual : number of components of both arrays must be equal to 1 !");
5475   double *ptr=getPointer();
5476   const double *ptrc=other->begin();
5477   for(int i=0;i<nbOfTuple;i++,ptrc++,ptr++)
5478     {
5479       if(*ptr>=0)
5480         *ptr=pow(*ptr,*ptrc);
5481       else
5482         {
5483           std::ostringstream oss; oss << "DataArrayDouble::powEqual : on tuple #" << i << " of this value is < 0 (" << *ptr << ") !";
5484           throw INTERP_KERNEL::Exception(oss.str().c_str());
5485         }
5486     }
5487   declareAsNew();
5488 }
5489
5490 /*!
5491  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
5492  * Server side.
5493  */
5494 void DataArrayDouble::getTinySerializationIntInformation(std::vector<int>& tinyInfo) const
5495 {
5496   tinyInfo.resize(2);
5497   if(isAllocated())
5498     {
5499       tinyInfo[0]=getNumberOfTuples();
5500       tinyInfo[1]=getNumberOfComponents();
5501     }
5502   else
5503     {
5504       tinyInfo[0]=-1;
5505       tinyInfo[1]=-1;
5506     }
5507 }
5508
5509 /*!
5510  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
5511  * Server side.
5512  */
5513 void DataArrayDouble::getTinySerializationStrInformation(std::vector<std::string>& tinyInfo) const
5514 {
5515   if(isAllocated())
5516     {
5517       int nbOfCompo=getNumberOfComponents();
5518       tinyInfo.resize(nbOfCompo+1);
5519       tinyInfo[0]=getName();
5520       for(int i=0;i<nbOfCompo;i++)
5521         tinyInfo[i+1]=getInfoOnComponent(i);
5522     }
5523   else
5524     {
5525       tinyInfo.resize(1);
5526       tinyInfo[0]=getName();
5527     }
5528 }
5529
5530 /*!
5531  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
5532  * This method returns if a feeding is needed.
5533  */
5534 bool DataArrayDouble::resizeForUnserialization(const std::vector<int>& tinyInfoI)
5535 {
5536   int nbOfTuple=tinyInfoI[0];
5537   int nbOfComp=tinyInfoI[1];
5538   if(nbOfTuple!=-1 || nbOfComp!=-1)
5539     {
5540       alloc(nbOfTuple,nbOfComp);
5541       return true;
5542     }
5543   return false;
5544 }
5545
5546 /*!
5547  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
5548  */
5549 void DataArrayDouble::finishUnserialization(const std::vector<int>& tinyInfoI, const std::vector<std::string>& tinyInfoS)
5550 {
5551   setName(tinyInfoS[0].c_str());
5552   if(isAllocated())
5553     {
5554       int nbOfCompo=getNumberOfComponents();
5555       for(int i=0;i<nbOfCompo;i++)
5556         setInfoOnComponent(i,tinyInfoS[i+1].c_str());
5557     }
5558 }
5559
5560 DataArrayDoubleIterator::DataArrayDoubleIterator(DataArrayDouble *da):_da(da),_tuple_id(0),_nb_comp(0),_nb_tuple(0)
5561 {
5562   if(_da)
5563     {
5564       _da->incrRef();
5565       if(_da->isAllocated())
5566         {
5567           _nb_comp=da->getNumberOfComponents();
5568           _nb_tuple=da->getNumberOfTuples();
5569           _pt=da->getPointer();
5570         }
5571     }
5572 }
5573
5574 DataArrayDoubleIterator::~DataArrayDoubleIterator()
5575 {
5576   if(_da)
5577     _da->decrRef();
5578 }
5579
5580 DataArrayDoubleTuple *DataArrayDoubleIterator::nextt()
5581 {
5582   if(_tuple_id<_nb_tuple)
5583     {
5584       _tuple_id++;
5585       DataArrayDoubleTuple *ret=new DataArrayDoubleTuple(_pt,_nb_comp);
5586       _pt+=_nb_comp;
5587       return ret;
5588     }
5589   else
5590     return 0;
5591 }
5592
5593 DataArrayDoubleTuple::DataArrayDoubleTuple(double *pt, int nbOfComp):_pt(pt),_nb_of_compo(nbOfComp)
5594 {
5595 }
5596
5597
5598 std::string DataArrayDoubleTuple::repr() const
5599 {
5600   std::ostringstream oss; oss.precision(17); oss << "(";
5601   for(int i=0;i<_nb_of_compo-1;i++)
5602     oss << _pt[i] << ", ";
5603   oss << _pt[_nb_of_compo-1] << ")";
5604   return oss.str();
5605 }
5606
5607 double DataArrayDoubleTuple::doubleValue() const
5608 {
5609   if(_nb_of_compo==1)
5610     return *_pt;
5611   throw INTERP_KERNEL::Exception("DataArrayDoubleTuple::doubleValue : DataArrayDoubleTuple instance has not exactly 1 component -> Not possible to convert it into a double precision float !");
5612 }
5613
5614 /*!
5615  * This method returns a newly allocated instance the caller should dealed with by a ParaMEDMEM::DataArrayDouble::decrRef.
5616  * This method performs \b no copy of data. The content is only referenced using ParaMEDMEM::DataArrayDouble::useArray with ownership set to \b false.
5617  * 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
5618  * \b nbOfCompo=1 and \bnbOfTuples==this->_nb_of_elem.
5619  */
5620 DataArrayDouble *DataArrayDoubleTuple::buildDADouble(int nbOfTuples, int nbOfCompo) const
5621 {
5622   if((_nb_of_compo==nbOfCompo && nbOfTuples==1) || (_nb_of_compo==nbOfTuples && nbOfCompo==1))
5623     {
5624       DataArrayDouble *ret=DataArrayDouble::New();
5625       ret->useExternalArrayWithRWAccess(_pt,nbOfTuples,nbOfCompo);
5626       return ret;
5627     }
5628   else
5629     {
5630       std::ostringstream oss; oss << "DataArrayDoubleTuple::buildDADouble : unable to build a requested DataArrayDouble instance with nbofTuple=" << nbOfTuples << " and nbOfCompo=" << nbOfCompo;
5631       oss << ".\nBecause the number of elements in this is " << _nb_of_compo << " !";
5632       throw INTERP_KERNEL::Exception(oss.str().c_str());
5633     }
5634 }
5635
5636 /*!
5637  * Returns a new instance of DataArrayInt. The caller is to delete this array
5638  * using decrRef() as it is no more needed. 
5639  */
5640 DataArrayInt *DataArrayInt::New()
5641 {
5642   return new DataArrayInt;
5643 }
5644
5645 /*!
5646  * Checks if raw data is allocated. Read more on the raw data
5647  * in \ref MEDCouplingArrayBasicsTuplesAndCompo "DataArrays infos" for more information.
5648  *  \return bool - \a true if the raw data is allocated, \a false else.
5649  */
5650 bool DataArrayInt::isAllocated() const
5651 {
5652   return getConstPointer()!=0;
5653 }
5654
5655 /*!
5656  * Checks if raw data is allocated and throws an exception if it is not the case.
5657  *  \throw If the raw data is not allocated.
5658  */
5659 void DataArrayInt::checkAllocated() const
5660 {
5661   if(!isAllocated())
5662     throw INTERP_KERNEL::Exception("DataArrayInt::checkAllocated : Array is defined but not allocated ! Call alloc or setValues method first !");
5663 }
5664
5665 /*!
5666  * This method desallocated \a this without modification of informations relative to the components.
5667  * After call of this method, DataArrayInt::isAllocated will return false.
5668  * If \a this is already not allocated, \a this is let unchanged.
5669  */
5670 void DataArrayInt::desallocate()
5671 {
5672   _mem.destroy();
5673 }
5674
5675 std::size_t DataArrayInt::getHeapMemorySizeWithoutChildren() const
5676 {
5677   std::size_t sz(_mem.getNbOfElemAllocated());
5678   sz*=sizeof(int);
5679   return DataArray::getHeapMemorySizeWithoutChildren()+sz;
5680 }
5681
5682 /*!
5683  * Returns the only one value in \a this, if and only if number of elements
5684  * (nb of tuples * nb of components) is equal to 1, and that \a this is allocated.
5685  *  \return double - the sole value stored in \a this array.
5686  *  \throw If at least one of conditions stated above is not fulfilled.
5687  */
5688 int DataArrayInt::intValue() const
5689 {
5690   if(isAllocated())
5691     {
5692       if(getNbOfElems()==1)
5693         {
5694           return *getConstPointer();
5695         }
5696       else
5697         throw INTERP_KERNEL::Exception("DataArrayInt::intValue : DataArrayInt instance is allocated but number of elements is not equal to 1 !");
5698     }
5699   else
5700     throw INTERP_KERNEL::Exception("DataArrayInt::intValue : DataArrayInt instance is not allocated !");
5701 }
5702
5703 /*!
5704  * Returns an integer value characterizing \a this array, which is useful for a quick
5705  * comparison of many instances of DataArrayInt.
5706  *  \return int - the hash value.
5707  *  \throw If \a this is not allocated.
5708  */
5709 int DataArrayInt::getHashCode() const
5710 {
5711   checkAllocated();
5712   std::size_t nbOfElems=getNbOfElems();
5713   int ret=nbOfElems*65536;
5714   int delta=3;
5715   if(nbOfElems>48)
5716     delta=nbOfElems/8;
5717   int ret0=0;
5718   const int *pt=begin();
5719   for(std::size_t i=0;i<nbOfElems;i+=delta)
5720     ret0+=pt[i] & 0x1FFF;
5721   return ret+ret0;
5722 }
5723
5724 /*!
5725  * Checks the number of tuples.
5726  *  \return bool - \a true if getNumberOfTuples() == 0, \a false else.
5727  *  \throw If \a this is not allocated.
5728  */
5729 bool DataArrayInt::empty() const
5730 {
5731   checkAllocated();
5732   return getNumberOfTuples()==0;
5733 }
5734
5735 /*!
5736  * Returns a full copy of \a this. For more info on copying data arrays see
5737  * \ref MEDCouplingArrayBasicsCopyDeep.
5738  *  \return DataArrayInt * - a new instance of DataArrayInt.
5739  */
5740 DataArrayInt *DataArrayInt::deepCpy() const
5741 {
5742   return new DataArrayInt(*this);
5743 }
5744
5745 /*!
5746  * Returns either a \a deep or \a shallow copy of this array. For more info see
5747  * \ref MEDCouplingArrayBasicsCopyDeep and \ref MEDCouplingArrayBasicsCopyShallow.
5748  *  \param [in] dCpy - if \a true, a deep copy is returned, else, a shallow one.
5749  *  \return DataArrayInt * - either a new instance of DataArrayInt (if \a dCpy
5750  *          == \a true) or \a this instance (if \a dCpy == \a false).
5751  */
5752 DataArrayInt *DataArrayInt::performCpy(bool dCpy) const
5753 {
5754   if(dCpy)
5755     return deepCpy();
5756   else
5757     {
5758       incrRef();
5759       return const_cast<DataArrayInt *>(this);
5760     }
5761 }
5762
5763 /*!
5764  * Copies all the data from another DataArrayInt. For more info see
5765  * \ref MEDCouplingArrayBasicsCopyDeepAssign.
5766  *  \param [in] other - another instance of DataArrayInt to copy data from.
5767  *  \throw If the \a other is not allocated.
5768  */
5769 void DataArrayInt::cpyFrom(const DataArrayInt& other)
5770 {
5771   other.checkAllocated();
5772   int nbOfTuples=other.getNumberOfTuples();
5773   int nbOfComp=other.getNumberOfComponents();
5774   allocIfNecessary(nbOfTuples,nbOfComp);
5775   std::size_t nbOfElems=(std::size_t)nbOfTuples*nbOfComp;
5776   int *pt=getPointer();
5777   const int *ptI=other.getConstPointer();
5778   for(std::size_t i=0;i<nbOfElems;i++)
5779     pt[i]=ptI[i];
5780   copyStringInfoFrom(other);
5781 }
5782
5783 /*!
5784  * This method reserve nbOfElems elements in memory ( nbOfElems*4 bytes ) \b without impacting the number of tuples in \a this.
5785  * 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.
5786  * If \a this has not already been allocated, number of components is set to one.
5787  * This method allows to reduce number of reallocations on invokation of DataArrayInt::pushBackSilent and DataArrayInt::pushBackValsSilent on \a this.
5788  * 
5789  * \sa DataArrayInt::pack, DataArrayInt::pushBackSilent, DataArrayInt::pushBackValsSilent
5790  */
5791 void DataArrayInt::reserve(std::size_t nbOfElems)
5792 {
5793   int nbCompo=getNumberOfComponents();
5794   if(nbCompo==1)
5795     {
5796       _mem.reserve(nbOfElems);
5797     }
5798   else if(nbCompo==0)
5799     {
5800       _mem.reserve(nbOfElems);
5801       _info_on_compo.resize(1);
5802     }
5803   else
5804     throw INTERP_KERNEL::Exception("DataArrayInt::reserve : not available for DataArrayInt with number of components different than 1 !");
5805 }
5806
5807 /*!
5808  * 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
5809  * of counter. So the caller is expected to call TimeLabel::declareAsNew on \a this at the end of the push session.
5810  *
5811  * \param [in] val the value to be added in \a this
5812  * \throw If \a this has already been allocated with number of components different from one.
5813  * \sa DataArrayInt::pushBackValsSilent
5814  */
5815 void DataArrayInt::pushBackSilent(int val)
5816 {
5817   int nbCompo=getNumberOfComponents();
5818   if(nbCompo==1)
5819     _mem.pushBack(val);
5820   else if(nbCompo==0)
5821     {
5822       _info_on_compo.resize(1);
5823       _mem.pushBack(val);
5824     }
5825   else
5826     throw INTERP_KERNEL::Exception("DataArrayInt::pushBackSilent : not available for DataArrayInt with number of components different than 1 !");
5827 }
5828
5829 /*!
5830  * 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
5831  * of counter. So the caller is expected to call TimeLabel::declareAsNew on \a this at the end of the push session.
5832  *
5833  *  \param [in] valsBg - an array of values to push at the end of \this.
5834  *  \param [in] valsEnd - specifies the end of the array \a valsBg, so that
5835  *              the last value of \a valsBg is \a valsEnd[ -1 ].
5836  * \throw If \a this has already been allocated with number of components different from one.
5837  * \sa DataArrayInt::pushBackSilent
5838  */
5839 void DataArrayInt::pushBackValsSilent(const int *valsBg, const int *valsEnd)
5840 {
5841   int nbCompo=getNumberOfComponents();
5842   if(nbCompo==1)
5843     _mem.insertAtTheEnd(valsBg,valsEnd);
5844   else if(nbCompo==0)
5845     {
5846       _info_on_compo.resize(1);
5847       _mem.insertAtTheEnd(valsBg,valsEnd);
5848     }
5849   else
5850     throw INTERP_KERNEL::Exception("DataArrayInt::pushBackValsSilent : not available for DataArrayInt with number of components different than 1 !");
5851 }
5852
5853 /*!
5854  * This method returns silently ( without updating time label in \a this ) the last value, if any and suppress it.
5855  * \throw If \a this is already empty.
5856  * \throw If \a this has number of components different from one.
5857  */
5858 int DataArrayInt::popBackSilent()
5859 {
5860   if(getNumberOfComponents()==1)
5861     return _mem.popBack();
5862   else
5863     throw INTERP_KERNEL::Exception("DataArrayInt::popBackSilent : not available for DataArrayInt with number of components different than 1 !");
5864 }
5865
5866 /*!
5867  * 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.
5868  *
5869  * \sa DataArrayInt::getHeapMemorySizeWithoutChildren, DataArrayInt::reserve
5870  */
5871 void DataArrayInt::pack() const
5872 {
5873   _mem.pack();
5874 }
5875
5876 /*!
5877  * Allocates the raw data in memory. If exactly as same memory as needed already
5878  * allocated, it is not re-allocated.
5879  *  \param [in] nbOfTuple - number of tuples of data to allocate.
5880  *  \param [in] nbOfCompo - number of components of data to allocate.
5881  *  \throw If \a nbOfTuple < 0 or \a nbOfCompo < 0.
5882  */
5883 void DataArrayInt::allocIfNecessary(int nbOfTuple, int nbOfCompo)
5884 {
5885   if(isAllocated())
5886     {
5887       if(nbOfTuple!=getNumberOfTuples() || nbOfCompo!=getNumberOfComponents())
5888         alloc(nbOfTuple,nbOfCompo);
5889     }
5890   else
5891     alloc(nbOfTuple,nbOfCompo);
5892 }
5893
5894 /*!
5895  * Allocates the raw data in memory. If the memory was already allocated, then it is
5896  * freed and re-allocated. See an example of this method use
5897  * \ref MEDCouplingArraySteps1WC "here".
5898  *  \param [in] nbOfTuple - number of tuples of data to allocate.
5899  *  \param [in] nbOfCompo - number of components of data to allocate.
5900  *  \throw If \a nbOfTuple < 0 or \a nbOfCompo < 0.
5901  */
5902 void DataArrayInt::alloc(int nbOfTuple, int nbOfCompo)
5903 {
5904   if(nbOfTuple<0 || nbOfCompo<0)
5905     throw INTERP_KERNEL::Exception("DataArrayInt::alloc : request for negative length of data !");
5906   _info_on_compo.resize(nbOfCompo);
5907   _mem.alloc(nbOfCompo*(std::size_t)nbOfTuple);
5908   declareAsNew();
5909 }
5910
5911 /*!
5912  * Assign zero to all values in \a this array. To know more on filling arrays see
5913  * \ref MEDCouplingArrayFill.
5914  * \throw If \a this is not allocated.
5915  */
5916 void DataArrayInt::fillWithZero()
5917 {
5918   checkAllocated();
5919   _mem.fillWithValue(0);
5920   declareAsNew();
5921 }
5922
5923 /*!
5924  * Assign \a val to all values in \a this array. To know more on filling arrays see
5925  * \ref MEDCouplingArrayFill.
5926  *  \param [in] val - the value to fill with.
5927  *  \throw If \a this is not allocated.
5928  */
5929 void DataArrayInt::fillWithValue(int val)
5930 {
5931   checkAllocated();
5932   _mem.fillWithValue(val);
5933   declareAsNew();
5934 }
5935
5936 /*!
5937  * Set all values in \a this array so that the i-th element equals to \a init + i
5938  * (i starts from zero). To know more on filling arrays see \ref MEDCouplingArrayFill.
5939  *  \param [in] init - value to assign to the first element of array.
5940  *  \throw If \a this->getNumberOfComponents() != 1
5941  *  \throw If \a this is not allocated.
5942  */
5943 void DataArrayInt::iota(int init)
5944 {
5945   checkAllocated();
5946   if(getNumberOfComponents()!=1)
5947     throw INTERP_KERNEL::Exception("DataArrayInt::iota : works only for arrays with only one component, you can call 'rearrange' method before !");
5948   int *ptr=getPointer();
5949   int ntuples=getNumberOfTuples();
5950   for(int i=0;i<ntuples;i++)
5951     ptr[i]=init+i;
5952   declareAsNew();
5953 }
5954
5955 /*!
5956  * Returns a textual and human readable representation of \a this instance of
5957  * DataArrayInt. This text is shown when a DataArrayInt is printed in Python.
5958  *  \return std::string - text describing \a this DataArrayInt.
5959  */
5960 std::string DataArrayInt::repr() const
5961 {
5962   std::ostringstream ret;
5963   reprStream(ret);
5964   return ret.str();
5965 }
5966
5967 std::string DataArrayInt::reprZip() const
5968 {
5969   std::ostringstream ret;
5970   reprZipStream(ret);
5971   return ret.str();
5972 }
5973
5974 void DataArrayInt::writeVTK(std::ostream& ofs, int indent, const char *type, const char *nameInFile, DataArrayByte *byteArr) const
5975 {
5976   static const char SPACE[4]={' ',' ',' ',' '};
5977   checkAllocated();
5978   std::string idt(indent,' ');
5979   ofs << idt << "<DataArray type=\"" << type << "\" Name=\"" << nameInFile << "\" NumberOfComponents=\"" << getNumberOfComponents() << "\"";
5980   if(byteArr)
5981     {
5982       ofs << " format=\"appended\" offset=\"" << byteArr->getNumberOfTuples() << "\">";
5983       if(std::string(type)=="Int32")
5984         {
5985           const char *data(reinterpret_cast<const char *>(begin()));
5986           std::size_t sz(getNbOfElems()*sizeof(int));
5987           byteArr->insertAtTheEnd(data,data+sz);
5988           byteArr->insertAtTheEnd(SPACE,SPACE+4);
5989         }
5990       else if(std::string(type)=="Int8")
5991         {
5992           INTERP_KERNEL::AutoPtr<char> tmp(new char[getNbOfElems()]);
5993           std::copy(begin(),end(),(char *)tmp);
5994           byteArr->insertAtTheEnd((char *)tmp,(char *)tmp+getNbOfElems());
5995           byteArr->insertAtTheEnd(SPACE,SPACE+4);
5996         }
5997       else if(std::string(type)=="UInt8")
5998         {
5999           INTERP_KERNEL::AutoPtr<unsigned char> tmp(new unsigned char[getNbOfElems()]);
6000           std::copy(begin(),end(),(unsigned char *)tmp);
6001           byteArr->insertAtTheEnd((unsigned char *)tmp,(unsigned char *)tmp+getNbOfElems());
6002           byteArr->insertAtTheEnd(SPACE,SPACE+4);
6003         }
6004       else
6005         throw INTERP_KERNEL::Exception("DataArrayInt::writeVTK : Only Int32, Int8 and UInt8 supported !");
6006     }
6007   else
6008     {
6009       ofs << " RangeMin=\"" << getMinValueInArray() << "\" RangeMax=\"" << getMaxValueInArray() << "\" format=\"ascii\">\n" << idt;
6010       std::copy(begin(),end(),std::ostream_iterator<int>(ofs," "));
6011     }
6012   ofs << std::endl << idt << "</DataArray>\n";
6013 }
6014
6015 void DataArrayInt::reprStream(std::ostream& stream) const
6016 {
6017   stream << "Name of int array : \"" << _name << "\"\n";
6018   reprWithoutNameStream(stream);
6019 }
6020
6021 void DataArrayInt::reprZipStream(std::ostream& stream) const
6022 {
6023   stream << "Name of int array : \"" << _name << "\"\n";
6024   reprZipWithoutNameStream(stream);
6025 }
6026
6027 void DataArrayInt::reprWithoutNameStream(std::ostream& stream) const
6028 {
6029   DataArray::reprWithoutNameStream(stream);
6030   _mem.repr(getNumberOfComponents(),stream);
6031 }
6032
6033 void DataArrayInt::reprZipWithoutNameStream(std::ostream& stream) const
6034 {
6035   DataArray::reprWithoutNameStream(stream);
6036   _mem.reprZip(getNumberOfComponents(),stream);
6037 }
6038
6039 void DataArrayInt::reprCppStream(const char *varName, std::ostream& stream) const
6040 {
6041   int nbTuples=getNumberOfTuples(),nbComp=getNumberOfComponents();
6042   const int *data=getConstPointer();
6043   stream << "DataArrayInt *" << varName << "=DataArrayInt::New();" << std::endl;
6044   if(nbTuples*nbComp>=1)
6045     {
6046       stream << "const int " << varName << "Data[" << nbTuples*nbComp << "]={";
6047       std::copy(data,data+nbTuples*nbComp-1,std::ostream_iterator<int>(stream,","));
6048       stream << data[nbTuples*nbComp-1] << "};" << std::endl;
6049       stream << varName << "->useArray(" << varName << "Data,false,CPP_DEALLOC," << nbTuples << "," << nbComp << ");" << std::endl;
6050     }
6051   else
6052     stream << varName << "->alloc(" << nbTuples << "," << nbComp << ");" << std::endl;
6053   stream << varName << "->setName(\"" << getName() << "\");" << std::endl;
6054 }
6055
6056 /*!
6057  * Method that gives a quick overvien of \a this for python.
6058  */
6059 void DataArrayInt::reprQuickOverview(std::ostream& stream) const
6060 {
6061   static const std::size_t MAX_NB_OF_BYTE_IN_REPR=300;
6062   stream << "DataArrayInt C++ instance at " << this << ". ";
6063   if(isAllocated())
6064     {
6065       int nbOfCompo=(int)_info_on_compo.size();
6066       if(nbOfCompo>=1)
6067         {
6068           int nbOfTuples=getNumberOfTuples();
6069           stream << "Number of tuples : " << nbOfTuples << ". Number of components : " << nbOfCompo << "." << std::endl;
6070           reprQuickOverviewData(stream,MAX_NB_OF_BYTE_IN_REPR);
6071         }
6072       else
6073         stream << "Number of components : 0.";
6074     }
6075   else
6076     stream << "*** No data allocated ****";
6077 }
6078
6079 void DataArrayInt::reprQuickOverviewData(std::ostream& stream, std::size_t maxNbOfByteInRepr) const
6080 {
6081   const int *data=begin();
6082   int nbOfTuples=getNumberOfTuples();
6083   int nbOfCompo=(int)_info_on_compo.size();
6084   std::ostringstream oss2; oss2 << "[";
6085   std::string oss2Str(oss2.str());
6086   bool isFinished=true;
6087   for(int i=0;i<nbOfTuples && isFinished;i++)
6088     {
6089       if(nbOfCompo>1)
6090         {
6091           oss2 << "(";
6092           for(int j=0;j<nbOfCompo;j++,data++)
6093             {
6094               oss2 << *data;
6095               if(j!=nbOfCompo-1) oss2 << ", ";
6096             }
6097           oss2 << ")";
6098         }
6099       else
6100         oss2 << *data++;
6101       if(i!=nbOfTuples-1) oss2 << ", ";
6102       std::string oss3Str(oss2.str());
6103       if(oss3Str.length()<maxNbOfByteInRepr)
6104         oss2Str=oss3Str;
6105       else
6106         isFinished=false;
6107     }
6108   stream << oss2Str;
6109   if(!isFinished)
6110     stream << "... ";
6111   stream << "]";
6112 }
6113
6114 /*!
6115  * Modifies \a this one-dimensional array so that each value \a v = \a indArrBg[ \a v ],
6116  * i.e. a current value is used as in index to get a new value from \a indArrBg.
6117  *  \param [in] indArrBg - pointer to the first element of array of new values to assign
6118  *         to \a this array.
6119  *  \param [in] indArrEnd - specifies the end of the array \a indArrBg, so that
6120  *              the last value of \a indArrBg is \a indArrEnd[ -1 ].
6121  *  \throw If \a this->getNumberOfComponents() != 1
6122  *  \throw If any value of \a this can't be used as a valid index for 
6123  *         [\a indArrBg, \a indArrEnd).
6124  */
6125 void DataArrayInt::transformWithIndArr(const int *indArrBg, const int *indArrEnd)
6126 {
6127   checkAllocated();
6128   if(getNumberOfComponents()!=1)
6129     throw INTERP_KERNEL::Exception("Call transformWithIndArr method on DataArrayInt with only one component, you can call 'rearrange' method before !");
6130   int nbElemsIn=(int)std::distance(indArrBg,indArrEnd);
6131   int nbOfTuples=getNumberOfTuples();
6132   int *pt=getPointer();
6133   for(int i=0;i<nbOfTuples;i++,pt++)
6134     {
6135       if(*pt>=0 && *pt<nbElemsIn)
6136         *pt=indArrBg[*pt];
6137       else
6138         {
6139           std::ostringstream oss; oss << "DataArrayInt::transformWithIndArr : error on tuple #" << i << " of this value is " << *pt << ", should be in [0," << nbElemsIn << ") !";
6140           throw INTERP_KERNEL::Exception(oss.str().c_str());
6141         }
6142     }
6143   declareAsNew();
6144 }
6145
6146 /*!
6147  * Computes distribution of values of \a this one-dimensional array between given value
6148  * ranges (casts). This method is typically useful for entity number spliting by types,
6149  * for example. 
6150  *  \warning The values contained in \a arrBg should be sorted ascendently. No
6151  *           check of this is be done. If not, the result is not warranted. 
6152  *  \param [in] arrBg - the array of ascending values defining the value ranges. The i-th
6153  *         value of \a arrBg (\a arrBg[ i ]) gives the lowest value of the i-th range,
6154  *         and the greatest value of the i-th range equals to \a arrBg[ i+1 ] - 1. \a
6155  *         arrBg containing \a n values defines \a n-1 ranges. The last value of \a arrBg
6156  *         should be more than every value in \a this array.
6157  *  \param [in] arrEnd - specifies the end of the array \a arrBg, so that
6158  *              the last value of \a arrBg is \a arrEnd[ -1 ].
6159  *  \param [out] castArr - a new instance of DataArrayInt, of same size as \a this array
6160  *         (same number of tuples and components), the caller is to delete 
6161  *         using decrRef() as it is no more needed.
6162  *         This array contains indices of ranges for every value of \a this array. I.e.
6163  *         the i-th value of \a castArr gives the index of range the i-th value of \a this
6164  *         belongs to. Or, in other words, this parameter contains for each tuple in \a
6165  *         this in which cast it holds.
6166  *  \param [out] rankInsideCast - a new instance of DataArrayInt, of same size as \a this
6167  *         array, the caller is to delete using decrRef() as it is no more needed.
6168  *         This array contains ranks of values of \a this array within ranges
6169  *         they belongs to. I.e. the i-th value of \a rankInsideCast gives the rank of
6170  *         the i-th value of \a this array within the \a castArr[ i ]-th range, to which
6171  *         the i-th value of \a this belongs to. Or, in other words, this param contains 
6172  *         for each tuple its rank inside its cast. The rank is computed as difference
6173  *         between the value and the lowest value of range.
6174  *  \param [out] castsPresent - a new instance of DataArrayInt, containing indices of
6175  *         ranges (casts) to which at least one value of \a this array belongs.
6176  *         Or, in other words, this param contains the casts that \a this contains.
6177  *         The caller is to delete this array using decrRef() as it is no more needed.
6178  *
6179  * \b Example: If \a this contains [6,5,0,3,2,7,8,1,4] and \a arrBg contains [0,4,9] then
6180  *            the output of this method will be : 
6181  * - \a castArr       : [1,1,0,0,0,1,1,0,1]
6182  * - \a rankInsideCast: [2,1,0,3,2,3,4,1,0]
6183  * - \a castsPresent  : [0,1]
6184  *
6185  * I.e. values of \a this array belong to 2 ranges: #0 and #1. Value 6 belongs to the
6186  * range #1 and its rank within this range is 2; etc.
6187  *
6188  *  \throw If \a this->getNumberOfComponents() != 1.
6189  *  \throw If \a arrEnd - arrBg < 2.
6190  *  \throw If any value of \a this is not less than \a arrEnd[-1].
6191  */
6192 void DataArrayInt::splitByValueRange(const int *arrBg, const int *arrEnd,
6193                                      DataArrayInt *& castArr, DataArrayInt *& rankInsideCast, DataArrayInt *& castsPresent) const throw(INTERP_KERNEL::Exception)
6194 {
6195   checkAllocated();
6196   if(getNumberOfComponents()!=1)
6197     throw INTERP_KERNEL::Exception("Call splitByValueRange  method on DataArrayInt with only one component, you can call 'rearrange' method before !");
6198   int nbOfTuples=getNumberOfTuples();
6199   std::size_t nbOfCast=std::distance(arrBg,arrEnd);
6200   if(nbOfCast<2)
6201     throw INTERP_KERNEL::Exception("DataArrayInt::splitByValueRange : The input array giving the cast range values should be of size >=2 !");
6202   nbOfCast--;
6203   const int *work=getConstPointer();
6204   typedef std::reverse_iterator<const int *> rintstart;
6205   rintstart bg(arrEnd);//OK no problem because size of 'arr' is greater or equal 2
6206   rintstart end2(arrBg);
6207   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret1=DataArrayInt::New();
6208   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret2=DataArrayInt::New();
6209   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret3=DataArrayInt::New();
6210   ret1->alloc(nbOfTuples,1);
6211   ret2->alloc(nbOfTuples,1);
6212   int *ret1Ptr=ret1->getPointer();
6213   int *ret2Ptr=ret2->getPointer();
6214   std::set<std::size_t> castsDetected;
6215   for(int i=0;i<nbOfTuples;i++)
6216     {
6217       rintstart res=std::find_if(bg,end2,std::bind2nd(std::less_equal<int>(), work[i]));
6218       std::size_t pos=std::distance(bg,res);
6219       std::size_t pos2=nbOfCast-pos;
6220       if(pos2<nbOfCast)
6221         {
6222           ret1Ptr[i]=(int)pos2;
6223           ret2Ptr[i]=work[i]-arrBg[pos2];
6224           castsDetected.insert(pos2);
6225         }
6226       else
6227         {
6228           std::ostringstream oss; oss << "DataArrayInt::splitByValueRange : At rank #" << i << " the value is " << work[i] << " should be in [0," << *bg << ") !";
6229           throw INTERP_KERNEL::Exception(oss.str().c_str());
6230         }
6231     }
6232   ret3->alloc((int)castsDetected.size(),1);
6233   std::copy(castsDetected.begin(),castsDetected.end(),ret3->getPointer());
6234   castArr=ret1.retn();
6235   rankInsideCast=ret2.retn();
6236   castsPresent=ret3.retn();
6237 }
6238
6239 /*!
6240  * Creates a one-dimensional DataArrayInt (\a res) whose contents are computed from 
6241  * values of \a this (\a a) and the given (\a indArr) arrays as follows:
6242  * \a res[ \a indArr[ \a a[ i ]]] = i. I.e. for each value in place i \a v = \a a[ i ],
6243  * new value in place \a indArr[ \a v ] is i.
6244  *  \param [in] indArrBg - the array holding indices within the result array to assign
6245  *         indices of values of \a this array pointing to values of \a indArrBg.
6246  *  \param [in] indArrEnd - specifies the end of the array \a indArrBg, so that
6247  *              the last value of \a indArrBg is \a indArrEnd[ -1 ].
6248  *  \return DataArrayInt * - the new instance of DataArrayInt.
6249  *          The caller is to delete this result array using decrRef() as it is no more
6250  *          needed.
6251  *  \throw If \a this->getNumberOfComponents() != 1.
6252  *  \throw If any value of \a this array is not a valid index for \a indArrBg array.
6253  *  \throw If any value of \a indArrBg is not a valid index for \a this array.
6254  */
6255 DataArrayInt *DataArrayInt::transformWithIndArrR(const int *indArrBg, const int *indArrEnd) const
6256 {
6257   checkAllocated();
6258   if(getNumberOfComponents()!=1)
6259     throw INTERP_KERNEL::Exception("Call transformWithIndArrR method on DataArrayInt with only one component, you can call 'rearrange' method before !");
6260   int nbElemsIn=(int)std::distance(indArrBg,indArrEnd);
6261   int nbOfTuples=getNumberOfTuples();
6262   const int *pt=getConstPointer();
6263   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6264   ret->alloc(nbOfTuples,1);
6265   ret->fillWithValue(-1);
6266   int *tmp=ret->getPointer();
6267   for(int i=0;i<nbOfTuples;i++,pt++)
6268     {
6269       if(*pt>=0 && *pt<nbElemsIn)
6270         {
6271           int pos=indArrBg[*pt];
6272           if(pos>=0 && pos<nbOfTuples)
6273             tmp[pos]=i;
6274           else
6275             {
6276               std::ostringstream oss; oss << "DataArrayInt::transformWithIndArrR : error on tuple #" << i << " value of new pos is " << pos << " ( indArrBg[" << *pt << "]) ! Should be in [0," << nbOfTuples << ") !";
6277               throw INTERP_KERNEL::Exception(oss.str().c_str());
6278             }
6279         }
6280       else
6281         {
6282           std::ostringstream oss; oss << "DataArrayInt::transformWithIndArrR : error on tuple #" << i << " value is " << *pt << " and indirectionnal array as a size equal to " << nbElemsIn << " !";
6283           throw INTERP_KERNEL::Exception(oss.str().c_str());
6284         }
6285     }
6286   return ret.retn();
6287 }
6288
6289 /*!
6290  * Creates a one-dimensional DataArrayInt of given length, whose contents are computed
6291  * from values of \a this array, which is supposed to contain a renumbering map in 
6292  * "Old to New" mode. The result array contains a renumbering map in "New to Old" mode.
6293  * To know how to use the renumbering maps see \ref MEDCouplingArrayRenumbering.
6294  *  \param [in] newNbOfElem - the number of tuples in the result array.
6295  *  \return DataArrayInt * - the new instance of DataArrayInt.
6296  *          The caller is to delete this result array using decrRef() as it is no more
6297  *          needed.
6298  * 
6299  *  \ref cpp_mcdataarrayint_invertarrayo2n2n2o "Here is a C++ example".<br>
6300  *  \ref py_mcdataarrayint_invertarrayo2n2n2o  "Here is a Python example".
6301  */
6302 DataArrayInt *DataArrayInt::invertArrayO2N2N2O(int newNbOfElem) const
6303 {
6304   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6305   ret->alloc(newNbOfElem,1);
6306   int nbOfOldNodes=getNumberOfTuples();
6307   const int *old2New=getConstPointer();
6308   int *pt=ret->getPointer();
6309   for(int i=0;i!=nbOfOldNodes;i++)
6310     {
6311       int newp(old2New[i]);
6312       if(newp!=-1)
6313         {
6314           if(newp>=0 && newp<newNbOfElem)
6315             pt[newp]=i;
6316           else
6317             {
6318               std::ostringstream oss; oss << "DataArrayInt::invertArrayO2N2N2O : At place #" << i << " the newplace is " << newp << " must be in [0," << newNbOfElem << ") !";
6319               throw INTERP_KERNEL::Exception(oss.str().c_str());
6320             }
6321         }
6322     }
6323   return ret.retn();
6324 }
6325
6326 /*!
6327  * This method is similar to DataArrayInt::invertArrayO2N2N2O except that 
6328  * 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]
6329  */
6330 DataArrayInt *DataArrayInt::invertArrayO2N2N2OBis(int newNbOfElem) const
6331 {
6332   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6333   ret->alloc(newNbOfElem,1);
6334   int nbOfOldNodes=getNumberOfTuples();
6335   const int *old2New=getConstPointer();
6336   int *pt=ret->getPointer();
6337   for(int i=nbOfOldNodes-1;i>=0;i--)
6338     {
6339       int newp(old2New[i]);
6340       if(newp!=-1)
6341         {
6342           if(newp>=0 && newp<newNbOfElem)
6343             pt[newp]=i;
6344           else
6345             {
6346               std::ostringstream oss; oss << "DataArrayInt::invertArrayO2N2N2OBis : At place #" << i << " the newplace is " << newp << " must be in [0," << newNbOfElem << ") !";
6347               throw INTERP_KERNEL::Exception(oss.str().c_str());
6348             }
6349         }
6350     }
6351   return ret.retn();
6352 }
6353
6354 /*!
6355  * Creates a one-dimensional DataArrayInt of given length, whose contents are computed
6356  * from values of \a this array, which is supposed to contain a renumbering map in 
6357  * "New to Old" mode. The result array contains a renumbering map in "Old to New" mode.
6358  * To know how to use the renumbering maps see \ref MEDCouplingArrayRenumbering.
6359  *  \param [in] newNbOfElem - the number of tuples in the result array.
6360  *  \return DataArrayInt * - the new instance of DataArrayInt.
6361  *          The caller is to delete this result array using decrRef() as it is no more
6362  *          needed.
6363  * 
6364  *  \ref cpp_mcdataarrayint_invertarrayn2o2o2n "Here is a C++ example".
6365  *
6366  *  \ref py_mcdataarrayint_invertarrayn2o2o2n "Here is a Python example".
6367  */
6368 DataArrayInt *DataArrayInt::invertArrayN2O2O2N(int oldNbOfElem) const
6369 {
6370   checkAllocated();
6371   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6372   ret->alloc(oldNbOfElem,1);
6373   const int *new2Old=getConstPointer();
6374   int *pt=ret->getPointer();
6375   std::fill(pt,pt+oldNbOfElem,-1);
6376   int nbOfNewElems=getNumberOfTuples();
6377   for(int i=0;i<nbOfNewElems;i++)
6378     {
6379       int v(new2Old[i]);
6380       if(v>=0 && v<oldNbOfElem)
6381          pt[v]=i;
6382       else
6383         {
6384           std::ostringstream oss; oss << "DataArrayInt::invertArrayN2O2O2N : in new id #" << i << " old value is " << v << " expected to be in [0," << oldNbOfElem << ") !";
6385           throw INTERP_KERNEL::Exception(oss.str().c_str());
6386         }
6387     }
6388   return ret.retn();
6389 }
6390
6391 /*!
6392  * Equivalent to DataArrayInt::isEqual except that if false the reason of
6393  * mismatch is given.
6394  * 
6395  * \param [in] other the instance to be compared with \a this
6396  * \param [out] reason In case of inequality returns the reason.
6397  * \sa DataArrayInt::isEqual
6398  */
6399 bool DataArrayInt::isEqualIfNotWhy(const DataArrayInt& other, std::string& reason) const
6400 {
6401   if(!areInfoEqualsIfNotWhy(other,reason))
6402     return false;
6403   return _mem.isEqual(other._mem,0,reason);
6404 }
6405
6406 /*!
6407  * Checks if \a this and another DataArrayInt are fully equal. For more info see
6408  * \ref MEDCouplingArrayBasicsCompare.
6409  *  \param [in] other - an instance of DataArrayInt to compare with \a this one.
6410  *  \return bool - \a true if the two arrays are equal, \a false else.
6411  */
6412 bool DataArrayInt::isEqual(const DataArrayInt& other) const
6413 {
6414   std::string tmp;
6415   return isEqualIfNotWhy(other,tmp);
6416 }
6417
6418 /*!
6419  * Checks if values of \a this and another DataArrayInt are equal. For more info see
6420  * \ref MEDCouplingArrayBasicsCompare.
6421  *  \param [in] other - an instance of DataArrayInt to compare with \a this one.
6422  *  \return bool - \a true if the values of two arrays are equal, \a false else.
6423  */
6424 bool DataArrayInt::isEqualWithoutConsideringStr(const DataArrayInt& other) const
6425 {
6426   std::string tmp;
6427   return _mem.isEqual(other._mem,0,tmp);
6428 }
6429
6430 /*!
6431  * Checks if values of \a this and another DataArrayInt are equal. Comparison is
6432  * performed on sorted value sequences.
6433  * For more info see\ref MEDCouplingArrayBasicsCompare.
6434  *  \param [in] other - an instance of DataArrayInt to compare with \a this one.
6435  *  \return bool - \a true if the sorted values of two arrays are equal, \a false else.
6436  */
6437 bool DataArrayInt::isEqualWithoutConsideringStrAndOrder(const DataArrayInt& other) const
6438 {
6439   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> a=deepCpy();
6440   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> b=other.deepCpy();
6441   a->sort();
6442   b->sort();
6443   return a->isEqualWithoutConsideringStr(*b);
6444 }
6445
6446 /*!
6447  * This method compares content of input vector \a v and \a this.
6448  * 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.
6449  * For performance reasons \a this is expected to be sorted ascendingly. If not an exception will be thrown.
6450  *
6451  * \param [in] v - the vector of 'flags' to be compared with \a this.
6452  *
6453  * \throw If \a this is not sorted ascendingly.
6454  * \throw If \a this has not exactly one component.
6455  * \throw If \a this is not allocated.
6456  */
6457 bool DataArrayInt::isFittingWith(const std::vector<bool>& v) const
6458 {
6459   checkAllocated();
6460   if(getNumberOfComponents()!=1)
6461     throw INTERP_KERNEL::Exception("DataArrayInt::isFittingWith : number of components of this should be equal to one !");
6462   const int *w(begin()),*end2(end());
6463   int refVal=-std::numeric_limits<int>::max();
6464   int i=0;
6465   std::vector<bool>::const_iterator it(v.begin());
6466   for(;it!=v.end();it++,i++)
6467     {
6468       if(*it)
6469         {
6470           if(w!=end2)
6471             {
6472               if(*w++==i)
6473                 {
6474                   if(i>refVal)
6475                     refVal=i;
6476                   else
6477                     {
6478                       std::ostringstream oss; oss << "DataArrayInt::isFittingWith : At pos #" << std::distance(begin(),w-1) << " this is not sorted ascendingly !";
6479                       throw INTERP_KERNEL::Exception(oss.str().c_str());
6480                     }
6481                 }
6482               else
6483                 return false;
6484             }
6485           else
6486             return false;
6487         }
6488     }
6489   return w==end2;
6490 }
6491
6492 /*!
6493  * Sorts values of the array.
6494  *  \param [in] asc - \a true means ascending order, \a false, descending.
6495  *  \throw If \a this is not allocated.
6496  *  \throw If \a this->getNumberOfComponents() != 1.
6497  */
6498 void DataArrayInt::sort(bool asc)
6499 {
6500   checkAllocated();
6501   if(getNumberOfComponents()!=1)
6502     throw INTERP_KERNEL::Exception("DataArrayInt::sort : only supported with 'this' array with ONE component !");
6503   _mem.sort(asc);
6504   declareAsNew();
6505 }
6506
6507 /*!
6508  * Computes for each tuple the sum of number of components values in the tuple and return it.
6509  * 
6510  * \return DataArrayInt * - the new instance of DataArrayInt containing the
6511  *          same number of tuples as \a this array and one component.
6512  *          The caller is to delete this result array using decrRef() as it is no more
6513  *          needed.
6514  *  \throw If \a this is not allocated.
6515  */
6516 DataArrayInt *DataArrayInt::sumPerTuple() const
6517 {
6518   checkAllocated();
6519   int nbOfComp(getNumberOfComponents()),nbOfTuple(getNumberOfTuples());
6520   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New());
6521   ret->alloc(nbOfTuple,1);
6522   const int *src(getConstPointer());
6523   int *dest(ret->getPointer());
6524   for(int i=0;i<nbOfTuple;i++,dest++,src+=nbOfComp)
6525     *dest=std::accumulate(src,src+nbOfComp,0);
6526   return ret.retn();
6527 }
6528
6529 /*!
6530  * Reverse the array values.
6531  *  \throw If \a this->getNumberOfComponents() < 1.
6532  *  \throw If \a this is not allocated.
6533  */
6534 void DataArrayInt::reverse()
6535 {
6536   checkAllocated();
6537   _mem.reverse(getNumberOfComponents());
6538   declareAsNew();
6539 }
6540
6541 /*!
6542  * Checks that \a this array is consistently **increasing** or **decreasing** in value.
6543  * If not an exception is thrown.
6544  *  \param [in] increasing - if \a true, the array values should be increasing.
6545  *  \throw If sequence of values is not strictly monotonic in agreement with \a
6546  *         increasing arg.
6547  *  \throw If \a this->getNumberOfComponents() != 1.
6548  *  \throw If \a this is not allocated.
6549  */
6550 void DataArrayInt::checkMonotonic(bool increasing) const
6551 {
6552   if(!isMonotonic(increasing))
6553     {
6554       if (increasing)
6555         throw INTERP_KERNEL::Exception("DataArrayInt::checkMonotonic : 'this' is not INCREASING monotonic !");
6556       else
6557         throw INTERP_KERNEL::Exception("DataArrayInt::checkMonotonic : 'this' is not DECREASING monotonic !");
6558     }
6559 }
6560
6561 /*!
6562  * Checks that \a this array is consistently **increasing** or **decreasing** in value.
6563  *  \param [in] increasing - if \a true, array values should be increasing.
6564  *  \return bool - \a true if values change in accordance with \a increasing arg.
6565  *  \throw If \a this->getNumberOfComponents() != 1.
6566  *  \throw If \a this is not allocated.
6567  */
6568 bool DataArrayInt::isMonotonic(bool increasing) const
6569 {
6570   checkAllocated();
6571   if(getNumberOfComponents()!=1)
6572     throw INTERP_KERNEL::Exception("DataArrayInt::isMonotonic : only supported with 'this' array with ONE component !");
6573   int nbOfElements=getNumberOfTuples();
6574   const int *ptr=getConstPointer();
6575   if(nbOfElements==0)
6576     return true;
6577   int ref=ptr[0];
6578   if(increasing)
6579     {
6580       for(int i=1;i<nbOfElements;i++)
6581         {
6582           if(ptr[i]>=ref)
6583             ref=ptr[i];
6584           else
6585             return false;
6586         }
6587     }
6588   else
6589     {
6590       for(int i=1;i<nbOfElements;i++)
6591         {
6592           if(ptr[i]<=ref)
6593             ref=ptr[i];
6594           else
6595             return false;
6596         }
6597     }
6598   return true;
6599 }
6600
6601 /*!
6602  * This method check that array consistently INCREASING or DECREASING in value.
6603  */
6604 bool DataArrayInt::isStrictlyMonotonic(bool increasing) const
6605 {
6606   checkAllocated();
6607   if(getNumberOfComponents()!=1)
6608     throw INTERP_KERNEL::Exception("DataArrayInt::isStrictlyMonotonic : only supported with 'this' array with ONE component !");
6609   int nbOfElements=getNumberOfTuples();
6610   const int *ptr=getConstPointer();
6611   if(nbOfElements==0)
6612     return true;
6613   int ref=ptr[0];
6614   if(increasing)
6615     {
6616       for(int i=1;i<nbOfElements;i++)
6617         {
6618           if(ptr[i]>ref)
6619             ref=ptr[i];
6620           else
6621             return false;
6622         }
6623     }
6624   else
6625     {
6626       for(int i=1;i<nbOfElements;i++)
6627         {
6628           if(ptr[i]<ref)
6629             ref=ptr[i];
6630           else
6631             return false;
6632         }
6633     }
6634   return true;
6635 }
6636
6637 /*!
6638  * This method check that array consistently INCREASING or DECREASING in value.
6639  */
6640 void DataArrayInt::checkStrictlyMonotonic(bool increasing) const
6641 {
6642   if(!isStrictlyMonotonic(increasing))
6643     {
6644       if (increasing)
6645         throw INTERP_KERNEL::Exception("DataArrayInt::checkStrictlyMonotonic : 'this' is not strictly INCREASING monotonic !");
6646       else
6647         throw INTERP_KERNEL::Exception("DataArrayInt::checkStrictlyMonotonic : 'this' is not strictly DECREASING monotonic !");
6648     }
6649 }
6650
6651 /*!
6652  * Creates a new one-dimensional DataArrayInt of the same size as \a this and a given
6653  * one-dimensional arrays that must be of the same length. The result array describes
6654  * correspondence between \a this and \a other arrays, so that 
6655  * <em> other.getIJ(i,0) == this->getIJ(ret->getIJ(i),0)</em>. If such a permutation is
6656  * not possible because some element in \a other is not in \a this, an exception is thrown.
6657  *  \param [in] other - an array to compute permutation to.
6658  *  \return DataArrayInt * - a new instance of DataArrayInt, which is a permutation array
6659  * from \a this to \a other. The caller is to delete this array using decrRef() as it is
6660  * no more needed.
6661  *  \throw If \a this->getNumberOfComponents() != 1.
6662  *  \throw If \a other->getNumberOfComponents() != 1.
6663  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples().
6664  *  \throw If \a other includes a value which is not in \a this array.
6665  * 
6666  *  \ref cpp_mcdataarrayint_buildpermutationarr "Here is a C++ example".
6667  *
6668  *  \ref py_mcdataarrayint_buildpermutationarr "Here is a Python example".
6669  */
6670 DataArrayInt *DataArrayInt::buildPermutationArr(const DataArrayInt& other) const
6671 {
6672   checkAllocated();
6673   if(getNumberOfComponents()!=1 || other.getNumberOfComponents()!=1)
6674     throw INTERP_KERNEL::Exception("DataArrayInt::buildPermutationArr : 'this' and 'other' have to have exactly ONE component !");
6675   int nbTuple=getNumberOfTuples();
6676   other.checkAllocated();
6677   if(nbTuple!=other.getNumberOfTuples())
6678     throw INTERP_KERNEL::Exception("DataArrayInt::buildPermutationArr : 'this' and 'other' must have the same number of tuple !");
6679   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6680   ret->alloc(nbTuple,1);
6681   ret->fillWithValue(-1);
6682   const int *pt=getConstPointer();
6683   std::map<int,int> mm;
6684   for(int i=0;i<nbTuple;i++)
6685     mm[pt[i]]=i;
6686   pt=other.getConstPointer();
6687   int *retToFill=ret->getPointer();
6688   for(int i=0;i<nbTuple;i++)
6689     {
6690       std::map<int,int>::const_iterator it=mm.find(pt[i]);
6691       if(it==mm.end())
6692         {
6693           std::ostringstream oss; oss << "DataArrayInt::buildPermutationArr : Arrays mismatch : element (" << pt[i] << ") in 'other' not findable in 'this' !";
6694           throw INTERP_KERNEL::Exception(oss.str().c_str());
6695         }
6696       retToFill[i]=(*it).second;
6697     }
6698   return ret.retn();
6699 }
6700
6701 /*!
6702  * Sets a C array to be used as raw data of \a this. The previously set info
6703  *  of components is retained and re-sized. 
6704  * For more info see \ref MEDCouplingArraySteps1.
6705  *  \param [in] array - the C array to be used as raw data of \a this.
6706  *  \param [in] ownership - if \a true, \a array will be deallocated at destruction of \a this.
6707  *  \param [in] type - specifies how to deallocate \a array. If \a type == ParaMEDMEM::CPP_DEALLOC,
6708  *                     \c delete [] \c array; will be called. If \a type == ParaMEDMEM::C_DEALLOC,
6709  *                     \c free(\c array ) will be called.
6710  *  \param [in] nbOfTuple - new number of tuples in \a this.
6711  *  \param [in] nbOfCompo - new number of components in \a this.
6712  */
6713 void DataArrayInt::useArray(const int *array, bool ownership,  DeallocType type, int nbOfTuple, int nbOfCompo)
6714 {
6715   _info_on_compo.resize(nbOfCompo);
6716   _mem.useArray(array,ownership,type,nbOfTuple*nbOfCompo);
6717   declareAsNew();
6718 }
6719
6720 void DataArrayInt::useExternalArrayWithRWAccess(const int *array, int nbOfTuple, int nbOfCompo)
6721 {
6722   _info_on_compo.resize(nbOfCompo);
6723   _mem.useExternalArrayWithRWAccess(array,nbOfTuple*nbOfCompo);
6724   declareAsNew();
6725 }
6726
6727 /*!
6728  * Returns a new DataArrayInt holding the same values as \a this array but differently
6729  * arranged in memory. If \a this array holds 2 components of 3 values:
6730  * \f$ x_0,x_1,x_2,y_0,y_1,y_2 \f$, then the result array holds these values arranged
6731  * as follows: \f$ x_0,y_0,x_1,y_1,x_2,y_2 \f$.
6732  *  \warning Do not confuse this method with transpose()!
6733  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
6734  *          is to delete using decrRef() as it is no more needed.
6735  *  \throw If \a this is not allocated.
6736  */
6737 DataArrayInt *DataArrayInt::fromNoInterlace() const
6738 {
6739   checkAllocated();
6740   if(_mem.isNull())
6741     throw INTERP_KERNEL::Exception("DataArrayInt::fromNoInterlace : Not defined array !");
6742   int *tab=_mem.fromNoInterlace(getNumberOfComponents());
6743   DataArrayInt *ret=DataArrayInt::New();
6744   ret->useArray(tab,true,C_DEALLOC,getNumberOfTuples(),getNumberOfComponents());
6745   return ret;
6746 }
6747
6748 /*!
6749  * Returns a new DataArrayInt holding the same values as \a this array but differently
6750  * arranged in memory. If \a this array holds 2 components of 3 values:
6751  * \f$ x_0,y_0,x_1,y_1,x_2,y_2 \f$, then the result array holds these values arranged
6752  * as follows: \f$ x_0,x_1,x_2,y_0,y_1,y_2 \f$.
6753  *  \warning Do not confuse this method with transpose()!
6754  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
6755  *          is to delete using decrRef() as it is no more needed.
6756  *  \throw If \a this is not allocated.
6757  */
6758 DataArrayInt *DataArrayInt::toNoInterlace() const
6759 {
6760   checkAllocated();
6761   if(_mem.isNull())
6762     throw INTERP_KERNEL::Exception("DataArrayInt::toNoInterlace : Not defined array !");
6763   int *tab=_mem.toNoInterlace(getNumberOfComponents());
6764   DataArrayInt *ret=DataArrayInt::New();
6765   ret->useArray(tab,true,C_DEALLOC,getNumberOfTuples(),getNumberOfComponents());
6766   return ret;
6767 }
6768
6769 /*!
6770  * Permutes values of \a this array as required by \a old2New array. The values are
6771  * permuted so that \c new[ \a old2New[ i ]] = \c old[ i ]. Number of tuples remains
6772  * the same as in \this one.
6773  * If a permutation reduction is needed, substr() or selectByTupleId() should be used.
6774  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
6775  *  \param [in] old2New - C array of length equal to \a this->getNumberOfTuples()
6776  *     giving a new position for i-th old value.
6777  */
6778 void DataArrayInt::renumberInPlace(const int *old2New)
6779 {
6780   checkAllocated();
6781   int nbTuples=getNumberOfTuples();
6782   int nbOfCompo=getNumberOfComponents();
6783   int *tmp=new int[nbTuples*nbOfCompo];
6784   const int *iptr=getConstPointer();
6785   for(int i=0;i<nbTuples;i++)
6786     {
6787       int v=old2New[i];
6788       if(v>=0 && v<nbTuples)
6789         std::copy(iptr+nbOfCompo*i,iptr+nbOfCompo*(i+1),tmp+nbOfCompo*v);
6790       else
6791         {
6792           std::ostringstream oss; oss << "DataArrayInt::renumberInPlace : At place #" << i << " value is " << v << " ! Should be in [0," << nbTuples << ") !";
6793           throw INTERP_KERNEL::Exception(oss.str().c_str());
6794         }
6795     }
6796   std::copy(tmp,tmp+nbTuples*nbOfCompo,getPointer());
6797   delete [] tmp;
6798   declareAsNew();
6799 }
6800
6801 /*!
6802  * Permutes values of \a this array as required by \a new2Old array. The values are
6803  * permuted so that \c new[ i ] = \c old[ \a new2Old[ i ]]. Number of tuples remains
6804  * the same as in \this one.
6805  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
6806  *  \param [in] new2Old - C array of length equal to \a this->getNumberOfTuples()
6807  *     giving a previous position of i-th new value.
6808  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
6809  *          is to delete using decrRef() as it is no more needed.
6810  */
6811 void DataArrayInt::renumberInPlaceR(const int *new2Old)
6812 {
6813   checkAllocated();
6814   int nbTuples=getNumberOfTuples();
6815   int nbOfCompo=getNumberOfComponents();
6816   int *tmp=new int[nbTuples*nbOfCompo];
6817   const int *iptr=getConstPointer();
6818   for(int i=0;i<nbTuples;i++)
6819     {
6820       int v=new2Old[i];
6821       if(v>=0 && v<nbTuples)
6822         std::copy(iptr+nbOfCompo*v,iptr+nbOfCompo*(v+1),tmp+nbOfCompo*i);
6823       else
6824         {
6825           std::ostringstream oss; oss << "DataArrayInt::renumberInPlaceR : At place #" << i << " value is " << v << " ! Should be in [0," << nbTuples << ") !";
6826           throw INTERP_KERNEL::Exception(oss.str().c_str());
6827         }
6828     }
6829   std::copy(tmp,tmp+nbTuples*nbOfCompo,getPointer());
6830   delete [] tmp;
6831   declareAsNew();
6832 }
6833
6834 /*!
6835  * Returns a copy of \a this array with values permuted as required by \a old2New array.
6836  * The values are permuted so that  \c new[ \a old2New[ i ]] = \c old[ i ].
6837  * Number of tuples in the result array remains the same as in \this one.
6838  * If a permutation reduction is needed, renumberAndReduce() should be used.
6839  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
6840  *  \param [in] old2New - C array of length equal to \a this->getNumberOfTuples()
6841  *          giving a new position for i-th old value.
6842  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
6843  *          is to delete using decrRef() as it is no more needed.
6844  *  \throw If \a this is not allocated.
6845  */
6846 DataArrayInt *DataArrayInt::renumber(const int *old2New) const
6847 {
6848   checkAllocated();
6849   int nbTuples=getNumberOfTuples();
6850   int nbOfCompo=getNumberOfComponents();
6851   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6852   ret->alloc(nbTuples,nbOfCompo);
6853   ret->copyStringInfoFrom(*this);
6854   const int *iptr=getConstPointer();
6855   int *optr=ret->getPointer();
6856   for(int i=0;i<nbTuples;i++)
6857     std::copy(iptr+nbOfCompo*i,iptr+nbOfCompo*(i+1),optr+nbOfCompo*old2New[i]);
6858   ret->copyStringInfoFrom(*this);
6859   return ret.retn();
6860 }
6861
6862 /*!
6863  * Returns a copy of \a this array with values permuted as required by \a new2Old array.
6864  * The values are permuted so that  \c new[ i ] = \c old[ \a new2Old[ i ]]. Number of
6865  * tuples in the result array remains the same as in \this one.
6866  * If a permutation reduction is needed, substr() or selectByTupleId() should be used.
6867  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
6868  *  \param [in] new2Old - C array of length equal to \a this->getNumberOfTuples()
6869  *     giving a previous position of i-th new value.
6870  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
6871  *          is to delete using decrRef() as it is no more needed.
6872  */
6873 DataArrayInt *DataArrayInt::renumberR(const int *new2Old) const
6874 {
6875   checkAllocated();
6876   int nbTuples=getNumberOfTuples();
6877   int nbOfCompo=getNumberOfComponents();
6878   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6879   ret->alloc(nbTuples,nbOfCompo);
6880   ret->copyStringInfoFrom(*this);
6881   const int *iptr=getConstPointer();
6882   int *optr=ret->getPointer();
6883   for(int i=0;i<nbTuples;i++)
6884     std::copy(iptr+nbOfCompo*new2Old[i],iptr+nbOfCompo*(new2Old[i]+1),optr+nbOfCompo*i);
6885   ret->copyStringInfoFrom(*this);
6886   return ret.retn();
6887 }
6888
6889 /*!
6890  * Returns a shorten and permuted copy of \a this array. The new DataArrayInt is
6891  * of size \a newNbOfTuple and it's values are permuted as required by \a old2New array.
6892  * The values are permuted so that  \c new[ \a old2New[ i ]] = \c old[ i ] for all
6893  * \a old2New[ i ] >= 0. In other words every i-th tuple in \a this array, for which 
6894  * \a old2New[ i ] is negative, is missing from the result array.
6895  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
6896  *  \param [in] old2New - C array of length equal to \a this->getNumberOfTuples()
6897  *     giving a new position for i-th old tuple and giving negative position for
6898  *     for i-th old tuple that should be omitted.
6899  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
6900  *          is to delete using decrRef() as it is no more needed.
6901  */
6902 DataArrayInt *DataArrayInt::renumberAndReduce(const int *old2New, int newNbOfTuple) const
6903 {
6904   checkAllocated();
6905   int nbTuples=getNumberOfTuples();
6906   int nbOfCompo=getNumberOfComponents();
6907   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6908   ret->alloc(newNbOfTuple,nbOfCompo);
6909   const int *iptr=getConstPointer();
6910   int *optr=ret->getPointer();
6911   for(int i=0;i<nbTuples;i++)
6912     {
6913       int w=old2New[i];
6914       if(w>=0)
6915         std::copy(iptr+i*nbOfCompo,iptr+(i+1)*nbOfCompo,optr+w*nbOfCompo);
6916     }
6917   ret->copyStringInfoFrom(*this);
6918   return ret.retn();
6919 }
6920
6921 /*!
6922  * Returns a shorten and permuted copy of \a this array. The new DataArrayInt is
6923  * of size \a new2OldEnd - \a new2OldBg and it's values are permuted as required by
6924  * \a new2OldBg array.
6925  * The values are permuted so that  \c new[ i ] = \c old[ \a new2OldBg[ i ]].
6926  * This method is equivalent to renumberAndReduce() except that convention in input is
6927  * \c new2old and \b not \c old2new.
6928  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
6929  *  \param [in] new2OldBg - pointer to the beginning of a permutation array that gives a
6930  *              tuple index in \a this array to fill the i-th tuple in the new array.
6931  *  \param [in] new2OldEnd - specifies the end of the permutation array that starts at
6932  *              \a new2OldBg, so that pointer to a tuple index (\a pi) varies as this:
6933  *              \a new2OldBg <= \a pi < \a new2OldEnd.
6934  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
6935  *          is to delete using decrRef() as it is no more needed.
6936  */
6937 DataArrayInt *DataArrayInt::selectByTupleId(const int *new2OldBg, const int *new2OldEnd) const
6938 {
6939   checkAllocated();
6940   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6941   int nbComp=getNumberOfComponents();
6942   ret->alloc((int)std::distance(new2OldBg,new2OldEnd),nbComp);
6943   ret->copyStringInfoFrom(*this);
6944   int *pt=ret->getPointer();
6945   const int *srcPt=getConstPointer();
6946   int i=0;
6947   for(const int *w=new2OldBg;w!=new2OldEnd;w++,i++)
6948     std::copy(srcPt+(*w)*nbComp,srcPt+((*w)+1)*nbComp,pt+i*nbComp);
6949   ret->copyStringInfoFrom(*this);
6950   return ret.retn();
6951 }
6952
6953 /*!
6954  * Returns a shorten and permuted copy of \a this array. The new DataArrayInt is
6955  * of size \a new2OldEnd - \a new2OldBg and it's values are permuted as required by
6956  * \a new2OldBg array.
6957  * The values are permuted so that  \c new[ i ] = \c old[ \a new2OldBg[ i ]].
6958  * This method is equivalent to renumberAndReduce() except that convention in input is
6959  * \c new2old and \b not \c old2new.
6960  * This method is equivalent to selectByTupleId() except that it prevents coping data
6961  * from behind the end of \a this array.
6962  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
6963  *  \param [in] new2OldBg - pointer to the beginning of a permutation array that gives a
6964  *              tuple index in \a this array to fill the i-th tuple in the new array.
6965  *  \param [in] new2OldEnd - specifies the end of the permutation array that starts at
6966  *              \a new2OldBg, so that pointer to a tuple index (\a pi) varies as this:
6967  *              \a new2OldBg <= \a pi < \a new2OldEnd.
6968  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
6969  *          is to delete using decrRef() as it is no more needed.
6970  *  \throw If \a new2OldEnd - \a new2OldBg > \a this->getNumberOfTuples().
6971  */
6972 DataArrayInt *DataArrayInt::selectByTupleIdSafe(const int *new2OldBg, const int *new2OldEnd) const
6973 {
6974   checkAllocated();
6975   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6976   int nbComp=getNumberOfComponents();
6977   int oldNbOfTuples=getNumberOfTuples();
6978   ret->alloc((int)std::distance(new2OldBg,new2OldEnd),nbComp);
6979   ret->copyStringInfoFrom(*this);
6980   int *pt=ret->getPointer();
6981   const int *srcPt=getConstPointer();
6982   int i=0;
6983   for(const int *w=new2OldBg;w!=new2OldEnd;w++,i++)
6984     if(*w>=0 && *w<oldNbOfTuples)
6985       std::copy(srcPt+(*w)*nbComp,srcPt+((*w)+1)*nbComp,pt+i*nbComp);
6986     else
6987       throw INTERP_KERNEL::Exception("DataArrayInt::selectByTupleIdSafe : some ids has been detected to be out of [0,this->getNumberOfTuples) !");
6988   ret->copyStringInfoFrom(*this);
6989   return ret.retn();
6990 }
6991
6992 /*!
6993  * Returns a shorten copy of \a this array. The new DataArrayInt contains every
6994  * (\a bg + \c i * \a step)-th tuple of \a this array located before the \a end2-th
6995  * tuple. Indices of the selected tuples are the same as ones returned by the Python
6996  * command \c range( \a bg, \a end2, \a step ).
6997  * This method is equivalent to selectByTupleIdSafe() except that the input array is
6998  * not constructed explicitly.
6999  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
7000  *  \param [in] bg - index of the first tuple to copy from \a this array.
7001  *  \param [in] end2 - index of the tuple before which the tuples to copy are located.
7002  *  \param [in] step - index increment to get index of the next tuple to copy.
7003  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
7004  *          is to delete using decrRef() as it is no more needed.
7005  *  \sa DataArrayInt::substr.
7006  */
7007 DataArrayInt *DataArrayInt::selectByTupleId2(int bg, int end2, int step) const
7008 {
7009   checkAllocated();
7010   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
7011   int nbComp=getNumberOfComponents();
7012   int newNbOfTuples=GetNumberOfItemGivenBESRelative(bg,end2,step,"DataArrayInt::selectByTupleId2 : ");
7013   ret->alloc(newNbOfTuples,nbComp);
7014   int *pt=ret->getPointer();
7015   const int *srcPt=getConstPointer()+bg*nbComp;
7016   for(int i=0;i<newNbOfTuples;i++,srcPt+=step*nbComp)
7017     std::copy(srcPt,srcPt+nbComp,pt+i*nbComp);
7018   ret->copyStringInfoFrom(*this);
7019   return ret.retn();
7020 }
7021
7022 /*!
7023  * Returns a shorten copy of \a this array. The new DataArrayInt contains ranges
7024  * of tuples specified by \a ranges parameter.
7025  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
7026  *  \param [in] ranges - std::vector of std::pair's each of which defines a range
7027  *              of tuples in [\c begin,\c end) format.
7028  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
7029  *          is to delete using decrRef() as it is no more needed.
7030  *  \throw If \a end < \a begin.
7031  *  \throw If \a end > \a this->getNumberOfTuples().
7032  *  \throw If \a this is not allocated.
7033  */
7034 DataArray *DataArrayInt::selectByTupleRanges(const std::vector<std::pair<int,int> >& ranges) const
7035 {
7036   checkAllocated();
7037   int nbOfComp=getNumberOfComponents();
7038   int nbOfTuplesThis=getNumberOfTuples();
7039   if(ranges.empty())
7040     {
7041       MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
7042       ret->alloc(0,nbOfComp);
7043       ret->copyStringInfoFrom(*this);
7044       return ret.retn();
7045     }
7046   int ref=ranges.front().first;
7047   int nbOfTuples=0;
7048   bool isIncreasing=true;
7049   for(std::vector<std::pair<int,int> >::const_iterator it=ranges.begin();it!=ranges.end();it++)
7050     {
7051       if((*it).first<=(*it).second)
7052         {
7053           if((*it).first>=0 && (*it).second<=nbOfTuplesThis)
7054             {
7055               nbOfTuples+=(*it).second-(*it).first;
7056               if(isIncreasing)
7057                 isIncreasing=ref<=(*it).first;
7058               ref=(*it).second;
7059             }
7060           else
7061             {
7062               std::ostringstream oss; oss << "DataArrayInt::selectByTupleRanges : on range #" << std::distance(ranges.begin(),it);
7063               oss << " (" << (*it).first << "," << (*it).second << ") is greater than number of tuples of this :" << nbOfTuples << " !";
7064               throw INTERP_KERNEL::Exception(oss.str().c_str());
7065             }
7066         }
7067       else
7068         {
7069           std::ostringstream oss; oss << "DataArrayInt::selectByTupleRanges : on range #" << std::distance(ranges.begin(),it);
7070           oss << " (" << (*it).first << "," << (*it).second << ") end is before begin !";
7071           throw INTERP_KERNEL::Exception(oss.str().c_str());
7072         }
7073     }
7074   if(isIncreasing && nbOfTuplesThis==nbOfTuples)
7075     return deepCpy();
7076   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
7077   ret->alloc(nbOfTuples,nbOfComp);
7078   ret->copyStringInfoFrom(*this);
7079   const int *src=getConstPointer();
7080   int *work=ret->getPointer();
7081   for(std::vector<std::pair<int,int> >::const_iterator it=ranges.begin();it!=ranges.end();it++)
7082     work=std::copy(src+(*it).first*nbOfComp,src+(*it).second*nbOfComp,work);
7083   return ret.retn();
7084 }
7085
7086 /*!
7087  * Returns a new DataArrayInt containing a renumbering map in "Old to New" mode.
7088  * This map, if applied to \a this array, would make it sorted. For example, if
7089  * \a this array contents are [9,10,0,6,4,11,3,7] then the contents of the result array
7090  * are [5,6,0,3,2,7,1,4]; if this result array (\a res) is used as an argument in call
7091  * \a this->renumber(\a res) then the returned array contains [0,3,4,6,7,9,10,11].
7092  * This method is useful for renumbering (in MED file for example). For more info
7093  * on renumbering see \ref MEDCouplingArrayRenumbering.
7094  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
7095  *          array using decrRef() as it is no more needed.
7096  *  \throw If \a this is not allocated.
7097  *  \throw If \a this->getNumberOfComponents() != 1.
7098  *  \throw If there are equal values in \a this array.
7099  */
7100 DataArrayInt *DataArrayInt::checkAndPreparePermutation() const
7101 {
7102   checkAllocated();
7103   if(getNumberOfComponents()!=1)
7104     throw INTERP_KERNEL::Exception("DataArrayInt::checkAndPreparePermutation : number of components must == 1 !");
7105   int nbTuples=getNumberOfTuples();
7106   const int *pt=getConstPointer();
7107   int *pt2=CheckAndPreparePermutation(pt,pt+nbTuples);
7108   DataArrayInt *ret=DataArrayInt::New();
7109   ret->useArray(pt2,true,C_DEALLOC,nbTuples,1);
7110   return ret;
7111 }
7112
7113 /*!
7114  * 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
7115  * input array \a ids2.
7116  * \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.
7117  * 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
7118  * inversely.
7119  * In case of success (no throw) : \c ids1->renumber(ret)->isEqual(ids2) where \a ret is the return of this method.
7120  *
7121  * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
7122  *          array using decrRef() as it is no more needed.
7123  * \throw If either ids1 or ids2 is null not allocated or not with one components.
7124  * 
7125  */
7126 DataArrayInt *DataArrayInt::FindPermutationFromFirstToSecond(const DataArrayInt *ids1, const DataArrayInt *ids2)
7127 {
7128   if(!ids1 || !ids2)
7129     throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two input arrays must be not null !");
7130   if(!ids1->isAllocated() || !ids2->isAllocated())
7131     throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two input arrays must be allocated !");
7132   if(ids1->getNumberOfComponents()!=1 || ids2->getNumberOfComponents()!=1)
7133     throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two input arrays have exactly one component !");
7134   if(ids1->getNumberOfTuples()!=ids2->getNumberOfTuples())
7135     {
7136       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 !";
7137       throw INTERP_KERNEL::Exception(oss.str().c_str());
7138     }
7139   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> p1(ids1->deepCpy());
7140   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> p2(ids2->deepCpy());
7141   p1->sort(true); p2->sort(true);
7142   if(!p1->isEqualWithoutConsideringStr(*p2))
7143     throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two arrays are not lying on same ids ! Impossible to find a permutation between the 2 arrays !");
7144   p1=ids1->checkAndPreparePermutation();
7145   p2=ids2->checkAndPreparePermutation();
7146   p2=p2->invertArrayO2N2N2O(p2->getNumberOfTuples());
7147   p2=p2->selectByTupleIdSafe(p1->begin(),p1->end());
7148   return p2.retn();
7149 }
7150
7151 /*!
7152  * Returns two arrays describing a surjective mapping from \a this set of values (\a A)
7153  * onto a set of values of size \a targetNb (\a B). The surjective function is 
7154  * \a B[ \a A[ i ]] = i. That is to say that for each \a id in [0,\a targetNb), where \a
7155  * targetNb < \a this->getNumberOfTuples(), there exists at least one tupleId (\a tid) so
7156  * that <em> this->getIJ( tid, 0 ) == id</em>. <br>
7157  * The first of out arrays returns indices of elements of \a this array, grouped by their
7158  * place in the set \a B. The second out array is the index of the first one; it shows how
7159  * many elements of \a A are mapped into each element of \a B. <br>
7160  * For more info on
7161  * mapping and its usage in renumbering see \ref MEDCouplingArrayRenumbering. <br>
7162  * \b Example:
7163  * - \a this: [0,3,2,3,2,2,1,2]
7164  * - \a targetNb: 4
7165  * - \a arr:  [0,  6,  2,4,5,7,  1,3]
7166  * - \a arrI: [0,1,2,6,8]
7167  *
7168  * This result means: <br>
7169  * the element of \a B 0 encounters within \a A once (\a arrI[ 0+1 ] - \a arrI[ 0 ]) and
7170  * its index within \a A is 0 ( \a arr[ 0:1 ] == \a arr[ \a arrI[ 0 ] : \a arrI[ 0+1 ]]);<br>
7171  * the element of \a B 2 encounters within \a A 4 times (\a arrI[ 2+1 ] - \a arrI[ 2 ]) and
7172  * its indices within \a A are [2,4,5,7] ( \a arr[ 2:6 ] == \a arr[ \a arrI[ 2 ] : 
7173  * \a arrI[ 2+1 ]]); <br> etc.
7174  *  \param [in] targetNb - the size of the set \a B. \a targetNb must be equal or more
7175  *         than the maximal value of \a A.
7176  *  \param [out] arr - a new instance of DataArrayInt returning indices of
7177  *         elements of \a this, grouped by their place in the set \a B. The caller is to delete
7178  *         this array using decrRef() as it is no more needed.
7179  *  \param [out] arrI - a new instance of DataArrayInt returning size of groups of equal
7180  *         elements of \a this. The caller is to delete this array using decrRef() as it
7181  *         is no more needed.
7182  *  \throw If \a this is not allocated.
7183  *  \throw If \a this->getNumberOfComponents() != 1.
7184  *  \throw If any value in \a this is more or equal to \a targetNb.
7185  */
7186 void DataArrayInt::changeSurjectiveFormat(int targetNb, DataArrayInt *&arr, DataArrayInt *&arrI) const
7187 {
7188   checkAllocated();
7189   if(getNumberOfComponents()!=1)
7190     throw INTERP_KERNEL::Exception("DataArrayInt::changeSurjectiveFormat : number of components must == 1 !");
7191   int nbOfTuples=getNumberOfTuples();
7192   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New());
7193   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> retI(DataArrayInt::New());
7194   retI->alloc(targetNb+1,1);
7195   const int *input=getConstPointer();
7196   std::vector< std::vector<int> > tmp(targetNb);
7197   for(int i=0;i<nbOfTuples;i++)
7198     {
7199       int tmp2=input[i];
7200       if(tmp2>=0 && tmp2<targetNb)
7201         tmp[tmp2].push_back(i);
7202       else
7203         {
7204           std::ostringstream oss; oss << "DataArrayInt::changeSurjectiveFormat : At pos " << i << " presence of element " << tmp2 << " ! should be in [0," << targetNb << ") !";
7205           throw INTERP_KERNEL::Exception(oss.str().c_str());
7206         }
7207     }
7208   int *retIPtr=retI->getPointer();
7209   *retIPtr=0;
7210   for(std::vector< std::vector<int> >::const_iterator it1=tmp.begin();it1!=tmp.end();it1++,retIPtr++)
7211     retIPtr[1]=retIPtr[0]+(int)((*it1).size());
7212   if(nbOfTuples!=retI->getIJ(targetNb,0))
7213     throw INTERP_KERNEL::Exception("DataArrayInt::changeSurjectiveFormat : big problem should never happen !");
7214   ret->alloc(nbOfTuples,1);
7215   int *retPtr=ret->getPointer();
7216   for(std::vector< std::vector<int> >::const_iterator it1=tmp.begin();it1!=tmp.end();it1++)
7217     retPtr=std::copy((*it1).begin(),(*it1).end(),retPtr);
7218   arr=ret.retn();
7219   arrI=retI.retn();
7220 }
7221
7222
7223 /*!
7224  * Returns a new DataArrayInt containing a renumbering map in "Old to New" mode computed
7225  * from a zip representation of a surjective format (returned e.g. by
7226  * \ref ParaMEDMEM::DataArrayDouble::findCommonTuples() "DataArrayDouble::findCommonTuples()"
7227  * for example). The result array minimizes the permutation. <br>
7228  * For more info on renumbering see \ref MEDCouplingArrayRenumbering. <br>
7229  * \b Example: <br>
7230  * - \a nbOfOldTuples: 10 
7231  * - \a arr          : [0,3, 5,7,9]
7232  * - \a arrIBg       : [0,2,5]
7233  * - \a newNbOfTuples: 7
7234  * - result array    : [0,1,2,0,3,4,5,4,6,4]
7235  *
7236  *  \param [in] nbOfOldTuples - number of tuples in the initial array \a arr.
7237  *  \param [in] arr - the array of tuple indices grouped by \a arrIBg array.
7238  *  \param [in] arrIBg - the array dividing all indices stored in \a arr into groups of
7239  *         (indices of) equal values. Its every element (except the last one) points to
7240  *         the first element of a group of equal values.
7241  *  \param [in] arrIEnd - specifies the end of \a arrIBg, so that the last element of \a
7242  *          arrIBg is \a arrIEnd[ -1 ].
7243  *  \param [out] newNbOfTuples - number of tuples after surjection application.
7244  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
7245  *          array using decrRef() as it is no more needed.
7246  *  \throw If any value of \a arr breaks condition ( 0 <= \a arr[ i ] < \a nbOfOldTuples ).
7247  */
7248 DataArrayInt *DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2(int nbOfOldTuples, const int *arr, const int *arrIBg, const int *arrIEnd, int &newNbOfTuples)
7249 {
7250   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
7251   ret->alloc(nbOfOldTuples,1);
7252   int *pt=ret->getPointer();
7253   std::fill(pt,pt+nbOfOldTuples,-1);
7254   int nbOfGrps=((int)std::distance(arrIBg,arrIEnd))-1;
7255   const int *cIPtr=arrIBg;
7256   for(int i=0;i<nbOfGrps;i++)
7257     pt[arr[cIPtr[i]]]=-(i+2);
7258   int newNb=0;
7259   for(int iNode=0;iNode<nbOfOldTuples;iNode++)
7260     {
7261       if(pt[iNode]<0)
7262         {
7263           if(pt[iNode]==-1)
7264             pt[iNode]=newNb++;
7265           else
7266             {
7267               int grpId=-(pt[iNode]+2);
7268               for(int j=cIPtr[grpId];j<cIPtr[grpId+1];j++)
7269                 {
7270                   if(arr[j]>=0 && arr[j]<nbOfOldTuples)
7271                     pt[arr[j]]=newNb;
7272                   else
7273                     {
7274                       std::ostringstream oss; oss << "DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2 : With element #" << j << " value is " << arr[j] << " should be in [0," << nbOfOldTuples << ") !";
7275                       throw INTERP_KERNEL::Exception(oss.str().c_str());
7276                     }
7277                 }
7278               newNb++;
7279             }
7280         }
7281     }
7282   newNbOfTuples=newNb;
7283   return ret.retn();
7284 }
7285
7286 /*!
7287  * Returns a new DataArrayInt containing a renumbering map in "New to Old" mode,
7288  * which if applied to \a this array would make it sorted ascendingly.
7289  * For more info on renumbering see \ref MEDCouplingArrayRenumbering. <br>
7290  * \b Example: <br>
7291  * - \a this: [2,0,1,1,0,1,2,0,1,1,0,0]
7292  * - result: [10,0,5,6,1,7,11,2,8,9,3,4]
7293  * - after applying result to \a this: [0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2] 
7294  *
7295  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
7296  *          array using decrRef() as it is no more needed.
7297  *  \throw If \a this is not allocated.
7298  *  \throw If \a this->getNumberOfComponents() != 1.
7299  */
7300 DataArrayInt *DataArrayInt::buildPermArrPerLevel() const
7301 {
7302   checkAllocated();
7303   if(getNumberOfComponents()!=1)
7304     throw INTERP_KERNEL::Exception("DataArrayInt::buildPermArrPerLevel : number of components must == 1 !");
7305   int nbOfTuples=getNumberOfTuples();
7306   const int *pt=getConstPointer();
7307   std::map<int,int> m;
7308   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
7309   ret->alloc(nbOfTuples,1);
7310   int *opt=ret->getPointer();
7311   for(int i=0;i<nbOfTuples;i++,pt++,opt++)
7312     {
7313       int val=*pt;
7314       std::map<int,int>::iterator it=m.find(val);
7315       if(it!=m.end())
7316         {
7317           *opt=(*it).second;
7318           (*it).second++;
7319         }
7320       else
7321         {
7322           *opt=0;
7323           m.insert(std::pair<int,int>(val,1));
7324         }
7325     }
7326   int sum=0;
7327   for(std::map<int,int>::iterator it=m.begin();it!=m.end();it++)
7328     {
7329       int vt=(*it).second;
7330       (*it).second=sum;
7331       sum+=vt;
7332     }
7333   pt=getConstPointer();
7334   opt=ret->getPointer();
7335   for(int i=0;i<nbOfTuples;i++,pt++,opt++)
7336     *opt+=m[*pt];
7337   //
7338   return ret.retn();
7339 }
7340
7341 /*!
7342  * Checks if contents of \a this array are equal to that of an array filled with
7343  * iota(). This method is particularly useful for DataArrayInt instances that represent
7344  * a renumbering array to check the real need in renumbering. 
7345  *  \return bool - \a true if \a this array contents == \a range( \a this->getNumberOfTuples())
7346  *  \throw If \a this is not allocated.
7347  *  \throw If \a this->getNumberOfComponents() != 1.
7348  */
7349 bool DataArrayInt::isIdentity() const
7350 {
7351   checkAllocated();
7352   if(getNumberOfComponents()!=1)
7353     return false;
7354   int nbOfTuples=getNumberOfTuples();
7355   const int *pt=getConstPointer();
7356   for(int i=0;i<nbOfTuples;i++,pt++)
7357     if(*pt!=i)
7358       return false;
7359   return true;
7360 }
7361
7362 /*!
7363  * Checks if all values in \a this array are equal to \a val.
7364  *  \param [in] val - value to check equality of array values to.
7365  *  \return bool - \a true if all values are \a val.
7366  *  \throw If \a this is not allocated.
7367  *  \throw If \a this->getNumberOfComponents() != 1
7368  */
7369 bool DataArrayInt::isUniform(int val) const
7370 {
7371   checkAllocated();
7372   if(getNumberOfComponents()!=1)
7373     throw INTERP_KERNEL::Exception("DataArrayInt::isUniform : must be applied on DataArrayInt with only one component, you can call 'rearrange' method before !");
7374   int nbOfTuples=getNumberOfTuples();
7375   const int *w=getConstPointer();
7376   const int *end2=w+nbOfTuples;
7377   for(;w!=end2;w++)
7378     if(*w!=val)
7379       return false;
7380   return true;
7381 }
7382
7383 /*!
7384  * Creates a new DataArrayDouble and assigns all (textual and numerical) data of \a this
7385  * array to the new one.
7386  *  \return DataArrayDouble * - the new instance of DataArrayInt.
7387  */
7388 DataArrayDouble *DataArrayInt::convertToDblArr() const
7389 {
7390   checkAllocated();
7391   DataArrayDouble *ret=DataArrayDouble::New();
7392   ret->alloc(getNumberOfTuples(),getNumberOfComponents());
7393   std::size_t nbOfVals=getNbOfElems();
7394   const int *src=getConstPointer();
7395   double *dest=ret->getPointer();
7396   std::copy(src,src+nbOfVals,dest);
7397   ret->copyStringInfoFrom(*this);
7398   return ret;
7399 }
7400
7401 /*!
7402  * Returns a shorten copy of \a this array. The new DataArrayInt contains all
7403  * tuples starting from the \a tupleIdBg-th tuple and including all tuples located before
7404  * the \a tupleIdEnd-th one. This methods has a similar behavior as std::string::substr().
7405  * This method is a specialization of selectByTupleId2().
7406  *  \param [in] tupleIdBg - index of the first tuple to copy from \a this array.
7407  *  \param [in] tupleIdEnd - index of the tuple before which the tuples to copy are located.
7408  *          If \a tupleIdEnd == -1, all the tuples till the end of \a this array are copied.
7409  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
7410  *          is to delete using decrRef() as it is no more needed.
7411  *  \throw If \a tupleIdBg < 0.
7412  *  \throw If \a tupleIdBg > \a this->getNumberOfTuples().
7413     \throw If \a tupleIdEnd != -1 && \a tupleIdEnd < \a this->getNumberOfTuples().
7414  *  \sa DataArrayInt::selectByTupleId2
7415  */
7416 DataArrayInt *DataArrayInt::substr(int tupleIdBg, int tupleIdEnd) const
7417 {
7418   checkAllocated();
7419   int nbt=getNumberOfTuples();
7420   if(tupleIdBg<0)
7421     throw INTERP_KERNEL::Exception("DataArrayInt::substr : The tupleIdBg parameter must be greater than 0 !");
7422   if(tupleIdBg>nbt)
7423     throw INTERP_KERNEL::Exception("DataArrayInt::substr : The tupleIdBg parameter is greater than number of tuples !");
7424   int trueEnd=tupleIdEnd;
7425   if(tupleIdEnd!=-1)
7426     {
7427       if(tupleIdEnd>nbt)
7428         throw INTERP_KERNEL::Exception("DataArrayInt::substr : The tupleIdBg parameter is greater or equal than number of tuples !");
7429     }
7430   else
7431     trueEnd=nbt;
7432   int nbComp=getNumberOfComponents();
7433   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
7434   ret->alloc(trueEnd-tupleIdBg,nbComp);
7435   ret->copyStringInfoFrom(*this);
7436   std::copy(getConstPointer()+tupleIdBg*nbComp,getConstPointer()+trueEnd*nbComp,ret->getPointer());
7437   return ret.retn();
7438 }
7439
7440 /*!
7441  * Changes the number of components within \a this array so that its raw data **does
7442  * not** change, instead splitting this data into tuples changes.
7443  *  \warning This method erases all (name and unit) component info set before!
7444  *  \param [in] newNbOfComp - number of components for \a this array to have.
7445  *  \throw If \a this is not allocated
7446  *  \throw If getNbOfElems() % \a newNbOfCompo != 0.
7447  *  \throw If \a newNbOfCompo is lower than 1.
7448  *  \throw If the rearrange method would lead to a number of tuples higher than 2147483647 (maximal capacity of int32 !).
7449  *  \warning This method erases all (name and unit) component info set before!
7450  */
7451 void DataArrayInt::rearrange(int newNbOfCompo)
7452 {
7453   checkAllocated();
7454   if(newNbOfCompo<1)
7455     throw INTERP_KERNEL::Exception("DataArrayInt::rearrange : input newNbOfCompo must be > 0 !");
7456   std::size_t nbOfElems=getNbOfElems();
7457   if(nbOfElems%newNbOfCompo!=0)
7458     throw INTERP_KERNEL::Exception("DataArrayInt::rearrange : nbOfElems%newNbOfCompo!=0 !");
7459   if(nbOfElems/newNbOfCompo>(std::size_t)std::numeric_limits<int>::max())
7460     throw INTERP_KERNEL::Exception("DataArrayInt::rearrange : the rearrangement leads to too high number of tuples (> 2147483647) !");
7461   _info_on_compo.clear();
7462   _info_on_compo.resize(newNbOfCompo);
7463   declareAsNew();
7464 }
7465
7466 /*!
7467  * Changes the number of components within \a this array to be equal to its number
7468  * of tuples, and inversely its number of tuples to become equal to its number of 
7469  * components. So that its raw data **does not** change, instead splitting this
7470  * data into tuples changes.
7471  *  \warning This method erases all (name and unit) component info set before!
7472  *  \warning Do not confuse this method with fromNoInterlace() and toNoInterlace()!
7473  *  \throw If \a this is not allocated.
7474  *  \sa rearrange()
7475  */
7476 void DataArrayInt::transpose()
7477 {
7478   checkAllocated();
7479   int nbOfTuples=getNumberOfTuples();
7480   rearrange(nbOfTuples);
7481 }
7482
7483 /*!
7484  * Returns a shorten or extended copy of \a this array. If \a newNbOfComp is less
7485  * than \a this->getNumberOfComponents() then the result array is shorten as each tuple
7486  * is truncated to have \a newNbOfComp components, keeping first components. If \a
7487  * newNbOfComp is more than \a this->getNumberOfComponents() then the result array is
7488  * expanded as each tuple is populated with \a dftValue to have \a newNbOfComp
7489  * components.  
7490  *  \param [in] newNbOfComp - number of components for the new array to have.
7491  *  \param [in] dftValue - value assigned to new values added to the new array.
7492  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
7493  *          is to delete using decrRef() as it is no more needed.
7494  *  \throw If \a this is not allocated.
7495  */
7496 DataArrayInt *DataArrayInt::changeNbOfComponents(int newNbOfComp, int dftValue) const
7497 {
7498   checkAllocated();
7499   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
7500   ret->alloc(getNumberOfTuples(),newNbOfComp);
7501   const int *oldc=getConstPointer();
7502   int *nc=ret->getPointer();
7503   int nbOfTuples=getNumberOfTuples();
7504   int oldNbOfComp=getNumberOfComponents();
7505   int dim=std::min(oldNbOfComp,newNbOfComp);
7506   for(int i=0;i<nbOfTuples;i++)
7507     {
7508       int j=0;
7509       for(;j<dim;j++)
7510         nc[newNbOfComp*i+j]=oldc[i*oldNbOfComp+j];
7511       for(;j<newNbOfComp;j++)
7512         nc[newNbOfComp*i+j]=dftValue;
7513     }
7514   ret->setName(getName().c_str());
7515   for(int i=0;i<dim;i++)
7516     ret->setInfoOnComponent(i,getInfoOnComponent(i).c_str());
7517   ret->setName(getName().c_str());
7518   return ret.retn();
7519 }
7520
7521 /*!
7522  * Changes number of tuples in the array. If the new number of tuples is smaller
7523  * than the current number the array is truncated, otherwise the array is extended.
7524  *  \param [in] nbOfTuples - new number of tuples. 
7525  *  \throw If \a this is not allocated.
7526  *  \throw If \a nbOfTuples is negative.
7527  */
7528 void DataArrayInt::reAlloc(int nbOfTuples)
7529 {
7530   if(nbOfTuples<0)
7531     throw INTERP_KERNEL::Exception("DataArrayInt::reAlloc : input new number of tuples should be >=0 !");
7532   checkAllocated();
7533   _mem.reAlloc(getNumberOfComponents()*(std::size_t)nbOfTuples);
7534   declareAsNew();
7535 }
7536
7537
7538 /*!
7539  * Returns a copy of \a this array composed of selected components.
7540  * The new DataArrayInt has the same number of tuples but includes components
7541  * specified by \a compoIds parameter. So that getNbOfElems() of the result array
7542  * can be either less, same or more than \a this->getNbOfElems().
7543  *  \param [in] compoIds - sequence of zero based indices of components to include
7544  *              into the new array.
7545  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
7546  *          is to delete using decrRef() as it is no more needed.
7547  *  \throw If \a this is not allocated.
7548  *  \throw If a component index (\a i) is not valid: 
7549  *         \a i < 0 || \a i >= \a this->getNumberOfComponents().
7550  *
7551  *  \ref py_mcdataarrayint_keepselectedcomponents "Here is a Python example".
7552  */
7553 DataArray *DataArrayInt::keepSelectedComponents(const std::vector<int>& compoIds) const
7554 {
7555   checkAllocated();
7556   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New());
7557   int newNbOfCompo=(int)compoIds.size();
7558   int oldNbOfCompo=getNumberOfComponents();
7559   for(std::vector<int>::const_iterator it=compoIds.begin();it!=compoIds.end();it++)
7560     DataArray::CheckValueInRange(oldNbOfCompo,(*it),"keepSelectedComponents invalid requested component");
7561   int nbOfTuples=getNumberOfTuples();
7562   ret->alloc(nbOfTuples,newNbOfCompo);
7563   ret->copyPartOfStringInfoFrom(*this,compoIds);
7564   const int *oldc=getConstPointer();
7565   int *nc=ret->getPointer();
7566   for(int i=0;i<nbOfTuples;i++)
7567     for(int j=0;j<newNbOfCompo;j++,nc++)
7568       *nc=oldc[i*oldNbOfCompo+compoIds[j]];
7569   return ret.retn();
7570 }
7571
7572 /*!
7573  * Appends components of another array to components of \a this one, tuple by tuple.
7574  * So that the number of tuples of \a this array remains the same and the number of 
7575  * components increases.
7576  *  \param [in] other - the DataArrayInt to append to \a this one.
7577  *  \throw If \a this is not allocated.
7578  *  \throw If \a this and \a other arrays have different number of tuples.
7579  *
7580  *  \ref cpp_mcdataarrayint_meldwith "Here is a C++ example".
7581  *
7582  *  \ref py_mcdataarrayint_meldwith "Here is a Python example".
7583  */
7584 void DataArrayInt::meldWith(const DataArrayInt *other)
7585 {
7586   if(!other)
7587     throw INTERP_KERNEL::Exception("DataArrayInt::meldWith : DataArrayInt pointer in input is NULL !");
7588   checkAllocated();
7589   other->checkAllocated();
7590   int nbOfTuples=getNumberOfTuples();
7591   if(nbOfTuples!=other->getNumberOfTuples())
7592     throw INTERP_KERNEL::Exception("DataArrayInt::meldWith : mismatch of number of tuples !");
7593   int nbOfComp1=getNumberOfComponents();
7594   int nbOfComp2=other->getNumberOfComponents();
7595   int *newArr=(int *)malloc(nbOfTuples*(nbOfComp1+nbOfComp2)*sizeof(int));
7596   int *w=newArr;
7597   const int *inp1=getConstPointer();
7598   const int *inp2=other->getConstPointer();
7599   for(int i=0;i<nbOfTuples;i++,inp1+=nbOfComp1,inp2+=nbOfComp2)
7600     {
7601       w=std::copy(inp1,inp1+nbOfComp1,w);
7602       w=std::copy(inp2,inp2+nbOfComp2,w);
7603     }
7604   useArray(newArr,true,C_DEALLOC,nbOfTuples,nbOfComp1+nbOfComp2);
7605   std::vector<int> compIds(nbOfComp2);
7606   for(int i=0;i<nbOfComp2;i++)
7607     compIds[i]=nbOfComp1+i;
7608   copyPartOfStringInfoFrom2(compIds,*other);
7609 }
7610
7611 /*!
7612  * Copy all components in a specified order from another DataArrayInt.
7613  * The specified components become the first ones in \a this array.
7614  * Both numerical and textual data is copied. The number of tuples in \a this and
7615  * the other array can be different.
7616  *  \param [in] a - the array to copy data from.
7617  *  \param [in] compoIds - sequence of zero based indices of components, data of which is
7618  *              to be copied.
7619  *  \throw If \a a is NULL.
7620  *  \throw If \a compoIds.size() != \a a->getNumberOfComponents().
7621  *  \throw If \a compoIds[i] < 0 or \a compoIds[i] > \a this->getNumberOfComponents().
7622  *
7623  *  \ref py_mcdataarrayint_setselectedcomponents "Here is a Python example".
7624  */
7625 void DataArrayInt::setSelectedComponents(const DataArrayInt *a, const std::vector<int>& compoIds)
7626 {
7627   if(!a)
7628     throw INTERP_KERNEL::Exception("DataArrayInt::setSelectedComponents : input DataArrayInt is NULL !");
7629   checkAllocated();
7630   a->checkAllocated();
7631   copyPartOfStringInfoFrom2(compoIds,*a);
7632   std::size_t partOfCompoSz=compoIds.size();
7633   int nbOfCompo=getNumberOfComponents();
7634   int nbOfTuples=std::min(getNumberOfTuples(),a->getNumberOfTuples());
7635   const int *ac=a->getConstPointer();
7636   int *nc=getPointer();
7637   for(int i=0;i<nbOfTuples;i++)
7638     for(std::size_t j=0;j<partOfCompoSz;j++,ac++)
7639       nc[nbOfCompo*i+compoIds[j]]=*ac;
7640 }
7641
7642 /*!
7643  * Copy all values from another DataArrayInt into specified tuples and components
7644  * of \a this array. Textual data is not copied.
7645  * The tree parameters defining set of indices of tuples and components are similar to
7646  * the tree parameters of the Python function \c range(\c start,\c stop,\c step).
7647  *  \param [in] a - the array to copy values from.
7648  *  \param [in] bgTuples - index of the first tuple of \a this array to assign values to.
7649  *  \param [in] endTuples - index of the tuple before which the tuples to assign to
7650  *              are located.
7651  *  \param [in] stepTuples - index increment to get index of the next tuple to assign to.
7652  *  \param [in] bgComp - index of the first component of \a this array to assign values to.
7653  *  \param [in] endComp - index of the component before which the components to assign
7654  *              to are located.
7655  *  \param [in] stepComp - index increment to get index of the next component to assign to.
7656  *  \param [in] strictCompoCompare - if \a true (by default), then \a a->getNumberOfComponents() 
7657  *              must be equal to the number of columns to assign to, else an
7658  *              exception is thrown; if \a false, then it is only required that \a
7659  *              a->getNbOfElems() equals to number of values to assign to (this condition
7660  *              must be respected even if \a strictCompoCompare is \a true). The number of 
7661  *              values to assign to is given by following Python expression:
7662  *              \a nbTargetValues = 
7663  *              \c len(\c range(\a bgTuples,\a endTuples,\a stepTuples)) *
7664  *              \c len(\c range(\a bgComp,\a endComp,\a stepComp)).
7665  *  \throw If \a a is NULL.
7666  *  \throw If \a a is not allocated.
7667  *  \throw If \a this is not allocated.
7668  *  \throw If parameters specifying tuples and components to assign to do not give a
7669  *            non-empty range of increasing indices.
7670  *  \throw If \a a->getNbOfElems() != \a nbTargetValues.
7671  *  \throw If \a strictCompoCompare == \a true && \a a->getNumberOfComponents() !=
7672  *            \c len(\c range(\a bgComp,\a endComp,\a stepComp)).
7673  *
7674  *  \ref py_mcdataarrayint_setpartofvalues1 "Here is a Python example".
7675  */
7676 void DataArrayInt::setPartOfValues1(const DataArrayInt *a, int bgTuples, int endTuples, int stepTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare)
7677 {
7678   if(!a)
7679     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValues1 : DataArrayInt pointer in input is NULL !");
7680   const char msg[]="DataArrayInt::setPartOfValues1";
7681   checkAllocated();
7682   a->checkAllocated();
7683   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
7684   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
7685   int nbComp=getNumberOfComponents();
7686   int nbOfTuples=getNumberOfTuples();
7687   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
7688   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
7689   bool assignTech=true;
7690   if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
7691     {
7692       if(strictCompoCompare)
7693         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
7694     }
7695   else
7696     {
7697       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
7698       assignTech=false;
7699     }
7700   int *pt=getPointer()+bgTuples*nbComp+bgComp;
7701   const int *srcPt=a->getConstPointer();
7702   if(assignTech)
7703     {
7704       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
7705         for(int j=0;j<newNbOfComp;j++,srcPt++)
7706           pt[j*stepComp]=*srcPt;
7707     }
7708   else
7709     {
7710       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
7711         {
7712           const int *srcPt2=srcPt;
7713           for(int j=0;j<newNbOfComp;j++,srcPt2++)
7714             pt[j*stepComp]=*srcPt2;
7715         }
7716     }
7717 }
7718
7719 /*!
7720  * Assign a given value to values at specified tuples and components of \a this array.
7721  * The tree parameters defining set of indices of tuples and components are similar to
7722  * the tree parameters of the Python function \c range(\c start,\c stop,\c step)..
7723  *  \param [in] a - the value to assign.
7724  *  \param [in] bgTuples - index of the first tuple of \a this array to assign to.
7725  *  \param [in] endTuples - index of the tuple before which the tuples to assign to
7726  *              are located.
7727  *  \param [in] stepTuples - index increment to get index of the next tuple to assign to.
7728  *  \param [in] bgComp - index of the first component of \a this array to assign to.
7729  *  \param [in] endComp - index of the component before which the components to assign
7730  *              to are located.
7731  *  \param [in] stepComp - index increment to get index of the next component to assign to.
7732  *  \throw If \a this is not allocated.
7733  *  \throw If parameters specifying tuples and components to assign to, do not give a
7734  *            non-empty range of increasing indices or indices are out of a valid range
7735  *            for \this array.
7736  *
7737  *  \ref py_mcdataarrayint_setpartofvaluessimple1 "Here is a Python example".
7738  */
7739 void DataArrayInt::setPartOfValuesSimple1(int a, int bgTuples, int endTuples, int stepTuples, int bgComp, int endComp, int stepComp)
7740 {
7741   const char msg[]="DataArrayInt::setPartOfValuesSimple1";
7742   checkAllocated();
7743   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
7744   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
7745   int nbComp=getNumberOfComponents();
7746   int nbOfTuples=getNumberOfTuples();
7747   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
7748   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
7749   int *pt=getPointer()+bgTuples*nbComp+bgComp;
7750   for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
7751     for(int j=0;j<newNbOfComp;j++)
7752       pt[j*stepComp]=a;
7753 }
7754
7755
7756 /*!
7757  * Copy all values from another DataArrayInt (\a a) into specified tuples and 
7758  * components of \a this array. Textual data is not copied.
7759  * The tuples and components to assign to are defined by C arrays of indices.
7760  * There are two *modes of usage*:
7761  * - If \a a->getNbOfElems() equals to number of values to assign to, then every value
7762  *   of \a a is assigned to its own location within \a this array. 
7763  * - If \a a includes one tuple, then all values of \a a are assigned to the specified
7764  *   components of every specified tuple of \a this array. In this mode it is required
7765  *   that \a a->getNumberOfComponents() equals to the number of specified components.
7766  * 
7767  *  \param [in] a - the array to copy values from.
7768  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
7769  *              assign values of \a a to.
7770  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
7771  *              pointer to a tuple index <em>(pi)</em> varies as this: 
7772  *              \a bgTuples <= \a pi < \a endTuples.
7773  *  \param [in] bgComp - pointer to an array of component indices of \a this array to
7774  *              assign values of \a a to.
7775  *  \param [in] endComp - specifies the end of the array \a bgTuples, so that
7776  *              pointer to a component index <em>(pi)</em> varies as this: 
7777  *              \a bgComp <= \a pi < \a endComp.
7778  *  \param [in] strictCompoCompare - this parameter is checked only if the
7779  *               *mode of usage* is the first; if it is \a true (default), 
7780  *               then \a a->getNumberOfComponents() must be equal 
7781  *               to the number of specified columns, else this is not required.
7782  *  \throw If \a a is NULL.
7783  *  \throw If \a a is not allocated.
7784  *  \throw If \a this is not allocated.
7785  *  \throw If any index of tuple/component given by <em>bgTuples / bgComp</em> is
7786  *         out of a valid range for \a this array.
7787  *  \throw In the first *mode of usage*, if <em>strictCompoCompare == true </em> and
7788  *         if <em> a->getNumberOfComponents() != (endComp - bgComp) </em>.
7789  *  \throw In the second *mode of usage*, if \a a->getNumberOfTuples() != 1 or
7790  *         <em> a->getNumberOfComponents() != (endComp - bgComp)</em>.
7791  *
7792  *  \ref py_mcdataarrayint_setpartofvalues2 "Here is a Python example".
7793  */
7794 void DataArrayInt::setPartOfValues2(const DataArrayInt *a, const int *bgTuples, const int *endTuples, const int *bgComp, const int *endComp, bool strictCompoCompare)
7795 {
7796   if(!a)
7797     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValues2 : DataArrayInt pointer in input is NULL !");
7798   const char msg[]="DataArrayInt::setPartOfValues2";
7799   checkAllocated();
7800   a->checkAllocated();
7801   int nbComp=getNumberOfComponents();
7802   int nbOfTuples=getNumberOfTuples();
7803   for(const int *z=bgComp;z!=endComp;z++)
7804     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
7805   int newNbOfTuples=(int)std::distance(bgTuples,endTuples);
7806   int newNbOfComp=(int)std::distance(bgComp,endComp);
7807   bool assignTech=true;
7808   if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
7809     {
7810       if(strictCompoCompare)
7811         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
7812     }
7813   else
7814     {
7815       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
7816       assignTech=false;
7817     }
7818   int *pt=getPointer();
7819   const int *srcPt=a->getConstPointer();
7820   if(assignTech)
7821     {    
7822       for(const int *w=bgTuples;w!=endTuples;w++)
7823         {
7824           DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
7825           for(const int *z=bgComp;z!=endComp;z++,srcPt++)
7826             {    
7827               pt[(std::size_t)(*w)*nbComp+(*z)]=*srcPt;
7828             }
7829         }
7830     }
7831   else
7832     {
7833       for(const int *w=bgTuples;w!=endTuples;w++)
7834         {
7835           const int *srcPt2=srcPt;
7836           DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
7837           for(const int *z=bgComp;z!=endComp;z++,srcPt2++)
7838             {    
7839               pt[(std::size_t)(*w)*nbComp+(*z)]=*srcPt2;
7840             }
7841         }
7842     }
7843 }
7844
7845 /*!
7846  * Assign a given value to values at specified tuples and components of \a this array.
7847  * The tuples and components to assign to are defined by C arrays of indices.
7848  *  \param [in] a - the value to assign.
7849  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
7850  *              assign \a a to.
7851  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
7852  *              pointer to a tuple index (\a pi) varies as this: 
7853  *              \a bgTuples <= \a pi < \a endTuples.
7854  *  \param [in] bgComp - pointer to an array of component indices of \a this array to
7855  *              assign \a a to.
7856  *  \param [in] endComp - specifies the end of the array \a bgTuples, so that
7857  *              pointer to a component index (\a pi) varies as this: 
7858  *              \a bgComp <= \a pi < \a endComp.
7859  *  \throw If \a this is not allocated.
7860  *  \throw If any index of tuple/component given by <em>bgTuples / bgComp</em> is
7861  *         out of a valid range for \a this array.
7862  *
7863  *  \ref py_mcdataarrayint_setpartofvaluessimple2 "Here is a Python example".
7864  */
7865 void DataArrayInt::setPartOfValuesSimple2(int a, const int *bgTuples, const int *endTuples, const int *bgComp, const int *endComp)
7866 {
7867   checkAllocated();
7868   int nbComp=getNumberOfComponents();
7869   int nbOfTuples=getNumberOfTuples();
7870   for(const int *z=bgComp;z!=endComp;z++)
7871     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
7872   int *pt=getPointer();
7873   for(const int *w=bgTuples;w!=endTuples;w++)
7874     for(const int *z=bgComp;z!=endComp;z++)
7875       {
7876         DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
7877         pt[(std::size_t)(*w)*nbComp+(*z)]=a;
7878       }
7879 }
7880
7881 /*!
7882  * Copy all values from another DataArrayInt (\a a) into specified tuples and 
7883  * components of \a this array. Textual data is not copied.
7884  * The tuples to assign to are defined by a C array of indices.
7885  * The components to assign to are defined by three values similar to parameters of
7886  * the Python function \c range(\c start,\c stop,\c step).
7887  * There are two *modes of usage*:
7888  * - If \a a->getNbOfElems() equals to number of values to assign to, then every value
7889  *   of \a a is assigned to its own location within \a this array. 
7890  * - If \a a includes one tuple, then all values of \a a are assigned to the specified
7891  *   components of every specified tuple of \a this array. In this mode it is required
7892  *   that \a a->getNumberOfComponents() equals to the number of specified components.
7893  *
7894  *  \param [in] a - the array to copy values from.
7895  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
7896  *              assign values of \a a to.
7897  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
7898  *              pointer to a tuple index <em>(pi)</em> varies as this: 
7899  *              \a bgTuples <= \a pi < \a endTuples.
7900  *  \param [in] bgComp - index of the first component of \a this array to assign to.
7901  *  \param [in] endComp - index of the component before which the components to assign
7902  *              to are located.
7903  *  \param [in] stepComp - index increment to get index of the next component to assign to.
7904  *  \param [in] strictCompoCompare - this parameter is checked only in the first
7905  *               *mode of usage*; if \a strictCompoCompare is \a true (default), 
7906  *               then \a a->getNumberOfComponents() must be equal 
7907  *               to the number of specified columns, else this is not required.
7908  *  \throw If \a a is NULL.
7909  *  \throw If \a a is not allocated.
7910  *  \throw If \a this is not allocated.
7911  *  \throw If any index of tuple given by \a bgTuples is out of a valid range for 
7912  *         \a this array.
7913  *  \throw In the first *mode of usage*, if <em>strictCompoCompare == true </em> and
7914  *         if <em> a->getNumberOfComponents()</em> is unequal to the number of components
7915  *         defined by <em>(bgComp,endComp,stepComp)</em>.
7916  *  \throw In the second *mode of usage*, if \a a->getNumberOfTuples() != 1 or
7917  *         <em> a->getNumberOfComponents()</em> is unequal to the number of components
7918  *         defined by <em>(bgComp,endComp,stepComp)</em>.
7919  *  \throw If parameters specifying components to assign to, do not give a
7920  *            non-empty range of increasing indices or indices are out of a valid range
7921  *            for \this array.
7922  *
7923  *  \ref py_mcdataarrayint_setpartofvalues3 "Here is a Python example".
7924  */
7925 void DataArrayInt::setPartOfValues3(const DataArrayInt *a, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare)
7926 {
7927   if(!a)
7928     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValues3 : DataArrayInt pointer in input is NULL !");
7929   const char msg[]="DataArrayInt::setPartOfValues3";
7930   checkAllocated();
7931   a->checkAllocated();
7932   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
7933   int nbComp=getNumberOfComponents();
7934   int nbOfTuples=getNumberOfTuples();
7935   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
7936   int newNbOfTuples=(int)std::distance(bgTuples,endTuples);
7937   bool assignTech=true;
7938   if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
7939     {
7940       if(strictCompoCompare)
7941         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
7942     }
7943   else
7944     {
7945       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
7946       assignTech=false;
7947     }
7948   int *pt=getPointer()+bgComp;
7949   const int *srcPt=a->getConstPointer();
7950   if(assignTech)
7951     {
7952       for(const int *w=bgTuples;w!=endTuples;w++)
7953         for(int j=0;j<newNbOfComp;j++,srcPt++)
7954           {
7955             DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
7956             pt[(std::size_t)(*w)*nbComp+j*stepComp]=*srcPt;
7957           }
7958     }
7959   else
7960     {
7961       for(const int *w=bgTuples;w!=endTuples;w++)
7962         {
7963           const int *srcPt2=srcPt;
7964           for(int j=0;j<newNbOfComp;j++,srcPt2++)
7965             {
7966               DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
7967               pt[(std::size_t)(*w)*nbComp+j*stepComp]=*srcPt2;
7968             }
7969         }
7970     }
7971 }
7972
7973 /*!
7974  * Assign a given value to values at specified tuples and components of \a this array.
7975  * The tuples to assign to are defined by a C array of indices.
7976  * The components to assign to are defined by three values similar to parameters of
7977  * the Python function \c range(\c start,\c stop,\c step).
7978  *  \param [in] a - the value to assign.
7979  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
7980  *              assign \a a to.
7981  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
7982  *              pointer to a tuple index <em>(pi)</em> varies as this: 
7983  *              \a bgTuples <= \a pi < \a endTuples.
7984  *  \param [in] bgComp - index of the first component of \a this array to assign to.
7985  *  \param [in] endComp - index of the component before which the components to assign
7986  *              to are located.
7987  *  \param [in] stepComp - index increment to get index of the next component to assign to.
7988  *  \throw If \a this is not allocated.
7989  *  \throw If any index of tuple given by \a bgTuples is out of a valid range for 
7990  *         \a this array.
7991  *  \throw If parameters specifying components to assign to, do not give a
7992  *            non-empty range of increasing indices or indices are out of a valid range
7993  *            for \this array.
7994  *
7995  *  \ref py_mcdataarrayint_setpartofvaluessimple3 "Here is a Python example".
7996  */
7997 void DataArrayInt::setPartOfValuesSimple3(int a, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp)
7998 {
7999   const char msg[]="DataArrayInt::setPartOfValuesSimple3";
8000   checkAllocated();
8001   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
8002   int nbComp=getNumberOfComponents();
8003   int nbOfTuples=getNumberOfTuples();
8004   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
8005   int *pt=getPointer()+bgComp;
8006   for(const int *w=bgTuples;w!=endTuples;w++)
8007     for(int j=0;j<newNbOfComp;j++)
8008       {
8009         DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
8010         pt[(std::size_t)(*w)*nbComp+j*stepComp]=a;
8011       }
8012 }
8013
8014 void DataArrayInt::setPartOfValues4(const DataArrayInt *a, int bgTuples, int endTuples, int stepTuples, const int *bgComp, const int *endComp, bool strictCompoCompare)
8015 {
8016   if(!a)
8017     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValues4 : input DataArrayInt is NULL !");
8018   const char msg[]="DataArrayInt::setPartOfValues4";
8019   checkAllocated();
8020   a->checkAllocated();
8021   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
8022   int newNbOfComp=(int)std::distance(bgComp,endComp);
8023   int nbComp=getNumberOfComponents();
8024   for(const int *z=bgComp;z!=endComp;z++)
8025     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
8026   int nbOfTuples=getNumberOfTuples();
8027   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
8028   bool assignTech=true;
8029   if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
8030     {
8031       if(strictCompoCompare)
8032         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
8033     }
8034   else
8035     {
8036       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
8037       assignTech=false;
8038     }
8039   const int *srcPt=a->getConstPointer();
8040   int *pt=getPointer()+bgTuples*nbComp;
8041   if(assignTech)
8042     {
8043       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
8044         for(const int *z=bgComp;z!=endComp;z++,srcPt++)
8045           pt[*z]=*srcPt;
8046     }
8047   else
8048     {
8049       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
8050         {
8051           const int *srcPt2=srcPt;
8052           for(const int *z=bgComp;z!=endComp;z++,srcPt2++)
8053             pt[*z]=*srcPt2;
8054         }
8055     }
8056 }
8057
8058 void DataArrayInt::setPartOfValuesSimple4(int a, int bgTuples, int endTuples, int stepTuples, const int *bgComp, const int *endComp)
8059 {
8060   const char msg[]="DataArrayInt::setPartOfValuesSimple4";
8061   checkAllocated();
8062   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
8063   int nbComp=getNumberOfComponents();
8064   for(const int *z=bgComp;z!=endComp;z++)
8065     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
8066   int nbOfTuples=getNumberOfTuples();
8067   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
8068   int *pt=getPointer()+bgTuples*nbComp;
8069   for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
8070     for(const int *z=bgComp;z!=endComp;z++)
8071       pt[*z]=a;
8072 }
8073
8074 /*!
8075  * Copy some tuples from another DataArrayInt into specified tuples
8076  * of \a this array. Textual data is not copied. Both arrays must have equal number of
8077  * components.
8078  * Both the tuples to assign and the tuples to assign to are defined by a DataArrayInt.
8079  * All components of selected tuples are copied.
8080  *  \param [in] a - the array to copy values from.
8081  *  \param [in] tuplesSelec - the array specifying both source tuples of \a a and
8082  *              target tuples of \a this. \a tuplesSelec has two components, and the
8083  *              first component specifies index of the source tuple and the second
8084  *              one specifies index of the target tuple.
8085  *  \throw If \a this is not allocated.
8086  *  \throw If \a a is NULL.
8087  *  \throw If \a a is not allocated.
8088  *  \throw If \a tuplesSelec is NULL.
8089  *  \throw If \a tuplesSelec is not allocated.
8090  *  \throw If <em>this->getNumberOfComponents() != a->getNumberOfComponents()</em>.
8091  *  \throw If \a tuplesSelec->getNumberOfComponents() != 2.
8092  *  \throw If any tuple index given by \a tuplesSelec is out of a valid range for 
8093  *         the corresponding (\a this or \a a) array.
8094  */
8095 void DataArrayInt::setPartOfValuesAdv(const DataArrayInt *a, const DataArrayInt *tuplesSelec)
8096 {
8097   if(!a || !tuplesSelec)
8098     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValuesAdv : DataArrayInt pointer in input is NULL !");
8099   checkAllocated();
8100   a->checkAllocated();
8101   tuplesSelec->checkAllocated();
8102   int nbOfComp=getNumberOfComponents();
8103   if(nbOfComp!=a->getNumberOfComponents())
8104     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValuesAdv : This and a do not have the same number of components !");
8105   if(tuplesSelec->getNumberOfComponents()!=2)
8106     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValuesAdv : Expecting to have a tuple selector DataArrayInt instance with exactly 2 components !");
8107   int thisNt=getNumberOfTuples();
8108   int aNt=a->getNumberOfTuples();
8109   int *valsToSet=getPointer();
8110   const int *valsSrc=a->getConstPointer();
8111   for(const int *tuple=tuplesSelec->begin();tuple!=tuplesSelec->end();tuple+=2)
8112     {
8113       if(tuple[1]>=0 && tuple[1]<aNt)
8114         {
8115           if(tuple[0]>=0 && tuple[0]<thisNt)
8116             std::copy(valsSrc+nbOfComp*tuple[1],valsSrc+nbOfComp*(tuple[1]+1),valsToSet+nbOfComp*tuple[0]);
8117           else
8118             {
8119               std::ostringstream oss; oss << "DataArrayInt::setPartOfValuesAdv : Tuple #" << std::distance(tuplesSelec->begin(),tuple)/2;
8120               oss << " of 'tuplesSelec' request of tuple id #" << tuple[0] << " in 'this' ! It should be in [0," << thisNt << ") !";
8121               throw INTERP_KERNEL::Exception(oss.str().c_str());
8122             }
8123         }
8124       else
8125         {
8126           std::ostringstream oss; oss << "DataArrayInt::setPartOfValuesAdv : Tuple #" << std::distance(tuplesSelec->begin(),tuple)/2;
8127           oss << " of 'tuplesSelec' request of tuple id #" << tuple[1] << " in 'a' ! It should be in [0," << aNt << ") !";
8128           throw INTERP_KERNEL::Exception(oss.str().c_str());
8129         }
8130     }
8131 }
8132
8133 /*!
8134  * Copy some tuples from another DataArrayInt (\a aBase) into contiguous tuples
8135  * of \a this array. Textual data is not copied. Both arrays must have equal number of
8136  * components.
8137  * The tuples to assign to are defined by index of the first tuple, and
8138  * their number is defined by \a tuplesSelec->getNumberOfTuples().
8139  * The tuples to copy are defined by values of a DataArrayInt.
8140  * All components of selected tuples are copied.
8141  *  \param [in] tupleIdStart - index of the first tuple of \a this array to assign
8142  *              values to.
8143  *  \param [in] aBase - the array to copy values from.
8144  *  \param [in] tuplesSelec - the array specifying tuples of \a aBase to copy.
8145  *  \throw If \a this is not allocated.
8146  *  \throw If \a aBase is NULL.
8147  *  \throw If \a aBase is not allocated.
8148  *  \throw If \a tuplesSelec is NULL.
8149  *  \throw If \a tuplesSelec is not allocated.
8150  *  \throw If <em>this->getNumberOfComponents() != a->getNumberOfComponents()</em>.
8151  *  \throw If \a tuplesSelec->getNumberOfComponents() != 1.
8152  *  \throw If <em>tupleIdStart + tuplesSelec->getNumberOfTuples() > this->getNumberOfTuples().</em>
8153  *  \throw If any tuple index given by \a tuplesSelec is out of a valid range for 
8154  *         \a aBase array.
8155  */
8156 void DataArrayInt::setContigPartOfSelectedValues(int tupleIdStart, const DataArray *aBase, const DataArrayInt *tuplesSelec)
8157 {
8158   if(!aBase || !tuplesSelec)
8159     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues : input DataArray is NULL !");
8160   const DataArrayInt *a=dynamic_cast<const DataArrayInt *>(aBase);
8161   if(!a)
8162     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues : input DataArray aBase is not a DataArrayInt !");
8163   checkAllocated();
8164   a->checkAllocated();
8165   tuplesSelec->checkAllocated();
8166   int nbOfComp=getNumberOfComponents();
8167   if(nbOfComp!=a->getNumberOfComponents())
8168     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues : This and a do not have the same number of components !");
8169   if(tuplesSelec->getNumberOfComponents()!=1)
8170     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues : Expecting to have a tuple selector DataArrayInt instance with exactly 1 component !");
8171   int thisNt=getNumberOfTuples();
8172   int aNt=a->getNumberOfTuples();
8173   int nbOfTupleToWrite=tuplesSelec->getNumberOfTuples();
8174   int *valsToSet=getPointer()+tupleIdStart*nbOfComp;
8175   if(tupleIdStart+nbOfTupleToWrite>thisNt)
8176     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues : invalid number range of values to write !");
8177   const int *valsSrc=a->getConstPointer();
8178   for(const int *tuple=tuplesSelec->begin();tuple!=tuplesSelec->end();tuple++,valsToSet+=nbOfComp)
8179     {
8180       if(*tuple>=0 && *tuple<aNt)
8181         {
8182           std::copy(valsSrc+nbOfComp*(*tuple),valsSrc+nbOfComp*(*tuple+1),valsToSet);
8183         }
8184       else
8185         {
8186           std::ostringstream oss; oss << "DataArrayInt::setContigPartOfSelectedValues : Tuple #" << std::distance(tuplesSelec->begin(),tuple);
8187           oss << " of 'tuplesSelec' request of tuple id #" << *tuple << " in 'a' ! It should be in [0," << aNt << ") !";
8188           throw INTERP_KERNEL::Exception(oss.str().c_str());
8189         }
8190     }
8191 }
8192
8193 /*!
8194  * Copy some tuples from another DataArrayInt (\a aBase) into contiguous tuples
8195  * of \a this array. Textual data is not copied. Both arrays must have equal number of
8196  * components.
8197  * The tuples to copy are defined by three values similar to parameters of
8198  * the Python function \c range(\c start,\c stop,\c step).
8199  * The tuples to assign to are defined by index of the first tuple, and
8200  * their number is defined by number of tuples to copy.
8201  * All components of selected tuples are copied.
8202  *  \param [in] tupleIdStart - index of the first tuple of \a this array to assign
8203  *              values to.
8204  *  \param [in] aBase - the array to copy values from.
8205  *  \param [in] bg - index of the first tuple to copy of the array \a aBase.
8206  *  \param [in] end2 - index of the tuple of \a aBase before which the tuples to copy
8207  *              are located.
8208  *  \param [in] step - index increment to get index of the next tuple to copy.
8209  *  \throw If \a this is not allocated.
8210  *  \throw If \a aBase is NULL.
8211  *  \throw If \a aBase is not allocated.
8212  *  \throw If <em>this->getNumberOfComponents() != aBase->getNumberOfComponents()</em>.
8213  *  \throw If <em>tupleIdStart + len(range(bg,end2,step)) > this->getNumberOfTuples().</em>
8214  *  \throw If parameters specifying tuples to copy, do not give a
8215  *            non-empty range of increasing indices or indices are out of a valid range
8216  *            for the array \a aBase.
8217  */
8218 void DataArrayInt::setContigPartOfSelectedValues2(int tupleIdStart, const DataArray *aBase, int bg, int end2, int step)
8219 {
8220   if(!aBase)
8221     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues2 : input DataArray is NULL !");
8222   const DataArrayInt *a=dynamic_cast<const DataArrayInt *>(aBase);
8223   if(!a)
8224     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues2 : input DataArray aBase is not a DataArrayInt !");
8225   checkAllocated();
8226   a->checkAllocated();
8227   int nbOfComp=getNumberOfComponents();
8228   const char msg[]="DataArrayInt::setContigPartOfSelectedValues2";
8229   int nbOfTupleToWrite=DataArray::GetNumberOfItemGivenBES(bg,end2,step,msg);
8230   if(nbOfComp!=a->getNumberOfComponents())
8231     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues2 : This and a do not have the same number of components !");
8232   int thisNt=getNumberOfTuples();
8233   int aNt=a->getNumberOfTuples();
8234   int *valsToSet=getPointer()+tupleIdStart*nbOfComp;
8235   if(tupleIdStart+nbOfTupleToWrite>thisNt)
8236     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues2 : invalid number range of values to write !");
8237   if(end2>aNt)
8238     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues2 : invalid range of values to read !");
8239   const int *valsSrc=a->getConstPointer()+bg*nbOfComp;
8240   for(int i=0;i<nbOfTupleToWrite;i++,valsToSet+=nbOfComp,valsSrc+=step*nbOfComp)
8241     {
8242       std::copy(valsSrc,valsSrc+nbOfComp,valsToSet);
8243     }
8244 }
8245
8246 /*!
8247  * Returns a value located at specified tuple and component.
8248  * This method is equivalent to DataArrayInt::getIJ() except that validity of
8249  * parameters is checked. So this method is safe but expensive if used to go through
8250  * all values of \a this.
8251  *  \param [in] tupleId - index of tuple of interest.
8252  *  \param [in] compoId - index of component of interest.
8253  *  \return double - value located by \a tupleId and \a compoId.
8254  *  \throw If \a this is not allocated.
8255  *  \throw If condition <em>( 0 <= tupleId < this->getNumberOfTuples() )</em> is violated.
8256  *  \throw If condition <em>( 0 <= compoId < this->getNumberOfComponents() )</em> is violated.
8257  */
8258 int DataArrayInt::getIJSafe(int tupleId, int compoId) const
8259 {
8260   checkAllocated();
8261   if(tupleId<0 || tupleId>=getNumberOfTuples())
8262     {
8263       std::ostringstream oss; oss << "DataArrayInt::getIJSafe : request for tupleId " << tupleId << " should be in [0," << getNumberOfTuples() << ") !";
8264       throw INTERP_KERNEL::Exception(oss.str().c_str());
8265     }
8266   if(compoId<0 || compoId>=getNumberOfComponents())
8267     {
8268       std::ostringstream oss; oss << "DataArrayInt::getIJSafe : request for compoId " << compoId << " should be in [0," << getNumberOfComponents() << ") !";
8269       throw INTERP_KERNEL::Exception(oss.str().c_str());
8270     }
8271   return _mem[tupleId*_info_on_compo.size()+compoId];
8272 }
8273
8274 /*!
8275  * Returns the first value of \a this. 
8276  *  \return int - the last value of \a this array.
8277  *  \throw If \a this is not allocated.
8278  *  \throw If \a this->getNumberOfComponents() != 1.
8279  *  \throw If \a this->getNumberOfTuples() < 1.
8280  */
8281 int DataArrayInt::front() const
8282 {
8283   checkAllocated();
8284   if(getNumberOfComponents()!=1)
8285     throw INTERP_KERNEL::Exception("DataArrayInt::front : number of components not equal to one !");
8286   int nbOfTuples=getNumberOfTuples();
8287   if(nbOfTuples<1)
8288     throw INTERP_KERNEL::Exception("DataArrayInt::front : number of tuples must be >= 1 !");
8289   return *(getConstPointer());
8290 }
8291
8292 /*!
8293  * Returns the last value of \a this. 
8294  *  \return int - the last value of \a this array.
8295  *  \throw If \a this is not allocated.
8296  *  \throw If \a this->getNumberOfComponents() != 1.
8297  *  \throw If \a this->getNumberOfTuples() < 1.
8298  */
8299 int DataArrayInt::back() const
8300 {
8301   checkAllocated();
8302   if(getNumberOfComponents()!=1)
8303     throw INTERP_KERNEL::Exception("DataArrayInt::back : number of components not equal to one !");
8304   int nbOfTuples=getNumberOfTuples();
8305   if(nbOfTuples<1)
8306     throw INTERP_KERNEL::Exception("DataArrayInt::back : number of tuples must be >= 1 !");
8307   return *(getConstPointer()+nbOfTuples-1);
8308 }
8309
8310 /*!
8311  * Assign pointer to one array to a pointer to another appay. Reference counter of
8312  * \a arrayToSet is incremented / decremented.
8313  *  \param [in] newArray - the pointer to array to assign to \a arrayToSet.
8314  *  \param [in,out] arrayToSet - the pointer to array to assign to.
8315  */
8316 void DataArrayInt::SetArrayIn(DataArrayInt *newArray, DataArrayInt* &arrayToSet)
8317 {
8318   if(newArray!=arrayToSet)
8319     {
8320       if(arrayToSet)
8321         arrayToSet->decrRef();
8322       arrayToSet=newArray;
8323       if(arrayToSet)
8324         arrayToSet->incrRef();
8325     }
8326 }
8327
8328 DataArrayIntIterator *DataArrayInt::iterator()
8329 {
8330   return new DataArrayIntIterator(this);
8331 }
8332
8333 /*!
8334  * Creates a new DataArrayInt containing IDs (indices) of tuples holding value equal to a
8335  * given one.
8336  *  \param [in] val - the value to find within \a this.
8337  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
8338  *          array using decrRef() as it is no more needed.
8339  *  \throw If \a this is not allocated.
8340  *  \throw If \a this->getNumberOfComponents() != 1.
8341  */
8342 DataArrayInt *DataArrayInt::getIdsEqual(int val) const
8343 {
8344   checkAllocated();
8345   if(getNumberOfComponents()!=1)
8346     throw INTERP_KERNEL::Exception("DataArrayInt::getIdsEqual : the array must have only one component, you can call 'rearrange' method before !");
8347   const int *cptr=getConstPointer();
8348   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
8349   int nbOfTuples=getNumberOfTuples();
8350   for(int i=0;i<nbOfTuples;i++,cptr++)
8351     if(*cptr==val)
8352       ret->pushBackSilent(i);
8353   return ret.retn();
8354 }
8355
8356 /*!
8357  * Creates a new DataArrayInt containing IDs (indices) of tuples holding value \b not
8358  * equal to a given one. 
8359  *  \param [in] val - the value to ignore within \a this.
8360  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
8361  *          array using decrRef() as it is no more needed.
8362  *  \throw If \a this is not allocated.
8363  *  \throw If \a this->getNumberOfComponents() != 1.
8364  */
8365 DataArrayInt *DataArrayInt::getIdsNotEqual(int val) const
8366 {
8367   checkAllocated();
8368   if(getNumberOfComponents()!=1)
8369     throw INTERP_KERNEL::Exception("DataArrayInt::getIdsNotEqual : the array must have only one component, you can call 'rearrange' method before !");
8370   const int *cptr=getConstPointer();
8371   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
8372   int nbOfTuples=getNumberOfTuples();
8373   for(int i=0;i<nbOfTuples;i++,cptr++)
8374     if(*cptr!=val)
8375       ret->pushBackSilent(i);
8376   return ret.retn();
8377 }
8378
8379
8380 /*!
8381  * Assigns \a newValue to all elements holding \a oldValue within \a this
8382  * one-dimensional array.
8383  *  \param [in] oldValue - the value to replace.
8384  *  \param [in] newValue - the value to assign.
8385  *  \return int - number of replacements performed.
8386  *  \throw If \a this is not allocated.
8387  *  \throw If \a this->getNumberOfComponents() != 1.
8388  */
8389 int DataArrayInt::changeValue(int oldValue, int newValue)
8390 {
8391   checkAllocated();
8392   if(getNumberOfComponents()!=1)
8393     throw INTERP_KERNEL::Exception("DataArrayInt::changeValue : the array must have only one component, you can call 'rearrange' method before !");
8394   int *start=getPointer();
8395   int *end2=start+getNbOfElems();
8396   int ret=0;
8397   for(int *val=start;val!=end2;val++)
8398     {
8399       if(*val==oldValue)
8400         {
8401           *val=newValue;
8402           ret++;
8403         }
8404     }
8405   return ret;
8406 }
8407
8408 /*!
8409  * Creates a new DataArrayInt containing IDs (indices) of tuples holding value equal to
8410  * one of given values.
8411  *  \param [in] valsBg - an array of values to find within \a this array.
8412  *  \param [in] valsEnd - specifies the end of the array \a valsBg, so that
8413  *              the last value of \a valsBg is \a valsEnd[ -1 ].
8414  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
8415  *          array using decrRef() as it is no more needed.
8416  *  \throw If \a this->getNumberOfComponents() != 1.
8417  */
8418 DataArrayInt *DataArrayInt::getIdsEqualList(const int *valsBg, const int *valsEnd) const
8419 {
8420   if(getNumberOfComponents()!=1)
8421     throw INTERP_KERNEL::Exception("DataArrayInt::getIdsEqualList : the array must have only one component, you can call 'rearrange' method before !");
8422   std::set<int> vals2(valsBg,valsEnd);
8423   const int *cptr=getConstPointer();
8424   std::vector<int> res;
8425   int nbOfTuples=getNumberOfTuples();
8426   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
8427   for(int i=0;i<nbOfTuples;i++,cptr++)
8428     if(vals2.find(*cptr)!=vals2.end())
8429       ret->pushBackSilent(i);
8430   return ret.retn();
8431 }
8432
8433 /*!
8434  * Creates a new DataArrayInt containing IDs (indices) of tuples holding values \b not
8435  * equal to any of given values.
8436  *  \param [in] valsBg - an array of values to ignore within \a this array.
8437  *  \param [in] valsEnd - specifies the end of the array \a valsBg, so that
8438  *              the last value of \a valsBg is \a valsEnd[ -1 ].
8439  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
8440  *          array using decrRef() as it is no more needed.
8441  *  \throw If \a this->getNumberOfComponents() != 1.
8442  */
8443 DataArrayInt *DataArrayInt::getIdsNotEqualList(const int *valsBg, const int *valsEnd) const
8444 {
8445   if(getNumberOfComponents()!=1)
8446     throw INTERP_KERNEL::Exception("DataArrayInt::getIdsNotEqualList : the array must have only one component, you can call 'rearrange' method before !");
8447   std::set<int> vals2(valsBg,valsEnd);
8448   const int *cptr=getConstPointer();
8449   std::vector<int> res;
8450   int nbOfTuples=getNumberOfTuples();
8451   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
8452   for(int i=0;i<nbOfTuples;i++,cptr++)
8453     if(vals2.find(*cptr)==vals2.end())
8454       ret->pushBackSilent(i);
8455   return ret.retn();
8456 }
8457
8458 /*!
8459  * This method is an extension of DataArrayInt::locateValue method because this method works for DataArrayInt with
8460  * any number of components excepted 0 (an INTERP_KERNEL::Exception is thrown in this case).
8461  * This method searches in \b this is there is a tuple that matched the input parameter \b tupl.
8462  * If any the tuple id is returned. If not -1 is returned.
8463  * 
8464  * This method throws an INTERP_KERNEL::Exception if the number of components in \b this mismatches with the size of
8465  * the input vector. An INTERP_KERNEL::Exception is thrown too if \b this is not allocated.
8466  *
8467  * \return tuple id where \b tupl is. -1 if no such tuple exists in \b this.
8468  * \sa DataArrayInt::search, DataArrayInt::presenceOfTuple.
8469  */
8470 int DataArrayInt::locateTuple(const std::vector<int>& tupl) const
8471 {
8472   checkAllocated();
8473   int nbOfCompo=getNumberOfComponents();
8474   if(nbOfCompo==0)
8475     throw INTERP_KERNEL::Exception("DataArrayInt::locateTuple : 0 components in 'this' !");
8476   if(nbOfCompo!=(int)tupl.size())
8477     {
8478       std::ostringstream oss; oss << "DataArrayInt::locateTuple : 'this' contains " << nbOfCompo << " components and searching for a tuple of length " << tupl.size() << " !";
8479       throw INTERP_KERNEL::Exception(oss.str().c_str());
8480     }
8481   const int *cptr=getConstPointer();
8482   std::size_t nbOfVals=getNbOfElems();
8483   for(const int *work=cptr;work!=cptr+nbOfVals;)
8484     {
8485       work=std::search(work,cptr+nbOfVals,tupl.begin(),tupl.end());
8486       if(work!=cptr+nbOfVals)
8487         {
8488           if(std::distance(cptr,work)%nbOfCompo!=0)
8489             work++;
8490           else
8491             return std::distance(cptr,work)/nbOfCompo;
8492         }
8493     }
8494   return -1;
8495 }
8496
8497 /*!
8498  * This method searches the sequence specified in input parameter \b vals in \b this.
8499  * This works only for DataArrayInt having number of components equal to one (if not an INTERP_KERNEL::Exception will be thrown).
8500  * This method differs from DataArrayInt::locateTuple in that the position is internal raw data is not considered here contrary to DataArrayInt::locateTuple.
8501  * \sa DataArrayInt::locateTuple
8502  */
8503 int DataArrayInt::search(const std::vector<int>& vals) const
8504 {
8505   checkAllocated();
8506   int nbOfCompo=getNumberOfComponents();
8507   if(nbOfCompo!=1)
8508     throw INTERP_KERNEL::Exception("DataArrayInt::search : works only for DataArrayInt instance with one component !");
8509   const int *cptr=getConstPointer();
8510   std::size_t nbOfVals=getNbOfElems();
8511   const int *loc=std::search(cptr,cptr+nbOfVals,vals.begin(),vals.end());
8512   if(loc!=cptr+nbOfVals)
8513     return std::distance(cptr,loc);
8514   return -1;
8515 }
8516
8517 /*!
8518  * This method expects to be called when number of components of this is equal to one.
8519  * This method returns the tuple id, if it exists, of the first tuple equal to \b value.
8520  * If not any tuple contains \b value -1 is returned.
8521  * \sa DataArrayInt::presenceOfValue
8522  */
8523 int DataArrayInt::locateValue(int value) const
8524 {
8525   checkAllocated();
8526   if(getNumberOfComponents()!=1)
8527     throw INTERP_KERNEL::Exception("DataArrayInt::presenceOfValue : the array must have only one component, you can call 'rearrange' method before !");
8528   const int *cptr=getConstPointer();
8529   int nbOfTuples=getNumberOfTuples();
8530   const int *ret=std::find(cptr,cptr+nbOfTuples,value);
8531   if(ret!=cptr+nbOfTuples)
8532     return std::distance(cptr,ret);
8533   return -1;
8534 }
8535
8536 /*!
8537  * This method expects to be called when number of components of this is equal to one.
8538  * This method returns the tuple id, if it exists, of the first tuple so that the value is contained in \b vals.
8539  * If not any tuple contains one of the values contained in 'vals' false is returned.
8540  * \sa DataArrayInt::presenceOfValue
8541  */
8542 int DataArrayInt::locateValue(const std::vector<int>& vals) const
8543 {
8544   checkAllocated();
8545   if(getNumberOfComponents()!=1)
8546     throw INTERP_KERNEL::Exception("DataArrayInt::presenceOfValue : the array must have only one component, you can call 'rearrange' method before !");
8547   std::set<int> vals2(vals.begin(),vals.end());
8548   const int *cptr=getConstPointer();
8549   int nbOfTuples=getNumberOfTuples();
8550   for(const int *w=cptr;w!=cptr+nbOfTuples;w++)
8551     if(vals2.find(*w)!=vals2.end())
8552       return std::distance(cptr,w);
8553   return -1;
8554 }
8555
8556 /*!
8557  * This method returns the number of values in \a this that are equals to input parameter \a value.
8558  * This method only works for single component array.
8559  *
8560  * \return a value in [ 0, \c this->getNumberOfTuples() )
8561  *
8562  * \throw If \a this is not allocated
8563  *
8564  */
8565 int DataArrayInt::count(int value) const
8566 {
8567   int ret=0;
8568   checkAllocated();
8569   if(getNumberOfComponents()!=1)
8570     throw INTERP_KERNEL::Exception("DataArrayInt::count : must be applied on DataArrayInt with only one component, you can call 'rearrange' method before !");
8571   const int *vals=begin();
8572   int nbOfTuples=getNumberOfTuples();
8573   for(int i=0;i<nbOfTuples;i++,vals++)
8574     if(*vals==value)
8575       ret++;
8576   return ret;
8577 }
8578
8579 /*!
8580  * This method is an extension of DataArrayInt::presenceOfValue method because this method works for DataArrayInt with
8581  * any number of components excepted 0 (an INTERP_KERNEL::Exception is thrown in this case).
8582  * This method searches in \b this is there is a tuple that matched the input parameter \b tupl.
8583  * This method throws an INTERP_KERNEL::Exception if the number of components in \b this mismatches with the size of
8584  * the input vector. An INTERP_KERNEL::Exception is thrown too if \b this is not allocated.
8585  * \sa DataArrayInt::locateTuple
8586  */
8587 bool DataArrayInt::presenceOfTuple(const std::vector<int>& tupl) const
8588 {
8589   return locateTuple(tupl)!=-1;
8590 }
8591
8592
8593 /*!
8594  * Returns \a true if a given value is present within \a this one-dimensional array.
8595  *  \param [in] value - the value to find within \a this array.
8596  *  \return bool - \a true in case if \a value is present within \a this array.
8597  *  \throw If \a this is not allocated.
8598  *  \throw If \a this->getNumberOfComponents() != 1.
8599  *  \sa locateValue()
8600  */
8601 bool DataArrayInt::presenceOfValue(int value) const
8602 {
8603   return locateValue(value)!=-1;
8604 }
8605
8606 /*!
8607  * This method expects to be called when number of components of this is equal to one.
8608  * This method returns true if it exists a tuple so that the value is contained in \b vals.
8609  * If not any tuple contains one of the values contained in 'vals' false is returned.
8610  * \sa DataArrayInt::locateValue
8611  */
8612 bool DataArrayInt::presenceOfValue(const std::vector<int>& vals) const
8613 {
8614   return locateValue(vals)!=-1;
8615 }
8616
8617 /*!
8618  * Accumulates values of each component of \a this array.
8619  *  \param [out] res - an array of length \a this->getNumberOfComponents(), allocated 
8620  *         by the caller, that is filled by this method with sum value for each
8621  *         component.
8622  *  \throw If \a this is not allocated.
8623  */
8624 void DataArrayInt::accumulate(int *res) const
8625 {
8626   checkAllocated();
8627   const int *ptr=getConstPointer();
8628   int nbTuple=getNumberOfTuples();
8629   int nbComps=getNumberOfComponents();
8630   std::fill(res,res+nbComps,0);
8631   for(int i=0;i<nbTuple;i++)
8632     std::transform(ptr+i*nbComps,ptr+(i+1)*nbComps,res,res,std::plus<int>());
8633 }
8634
8635 int DataArrayInt::accumulate(int compId) const
8636 {
8637   checkAllocated();
8638   const int *ptr=getConstPointer();
8639   int nbTuple=getNumberOfTuples();
8640   int nbComps=getNumberOfComponents();
8641   if(compId<0 || compId>=nbComps)
8642     throw INTERP_KERNEL::Exception("DataArrayInt::accumulate : Invalid compId specified : No such nb of components !");
8643   int ret=0;
8644   for(int i=0;i<nbTuple;i++)
8645     ret+=ptr[i*nbComps+compId];
8646   return ret;
8647 }
8648
8649 /*!
8650  * This method accumulate using addition tuples in \a this using input index array [ \a bgOfIndex, \a endOfIndex ).
8651  * The returned array will have same number of components than \a this and number of tuples equal to
8652  * \c std::distance(bgOfIndex,endOfIndex) \b minus \b one.
8653  *
8654  * The input index array is expected to be ascendingly sorted in which the all referenced ids should be in [0, \c this->getNumberOfTuples).
8655  *
8656  * \param [in] bgOfIndex - begin (included) of the input index array.
8657  * \param [in] endOfIndex - end (excluded) of the input index array.
8658  * \return DataArrayInt * - the new instance having the same number of components than \a this.
8659  * 
8660  * \throw If bgOfIndex or end is NULL.
8661  * \throw If input index array is not ascendingly sorted.
8662  * \throw If there is an id in [ \a bgOfIndex, \a endOfIndex ) not in [0, \c this->getNumberOfTuples).
8663  * \throw If std::distance(bgOfIndex,endOfIndex)==0.
8664  */
8665 DataArrayInt *DataArrayInt::accumulatePerChunck(const int *bgOfIndex, const int *endOfIndex) const
8666 {
8667   if(!bgOfIndex || !endOfIndex)
8668     throw INTERP_KERNEL::Exception("DataArrayInt::accumulatePerChunck : input pointer NULL !");
8669   checkAllocated();
8670   int nbCompo=getNumberOfComponents();
8671   int nbOfTuples=getNumberOfTuples();
8672   int sz=(int)std::distance(bgOfIndex,endOfIndex);
8673   if(sz<1)
8674     throw INTERP_KERNEL::Exception("DataArrayInt::accumulatePerChunck : invalid size of input index array !");
8675   sz--;
8676   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(sz,nbCompo);
8677   const int *w=bgOfIndex;
8678   if(*w<0 || *w>=nbOfTuples)
8679     throw INTERP_KERNEL::Exception("DataArrayInt::accumulatePerChunck : The first element of the input index not in [0,nbOfTuples) !");
8680   const int *srcPt=begin()+(*w)*nbCompo;
8681   int *tmp=ret->getPointer();
8682   for(int i=0;i<sz;i++,tmp+=nbCompo,w++)
8683     {
8684       std::fill(tmp,tmp+nbCompo,0);
8685       if(w[1]>=w[0])
8686         {
8687           for(int j=w[0];j<w[1];j++,srcPt+=nbCompo)
8688             {
8689               if(j>=0 && j<nbOfTuples)
8690                 std::transform(srcPt,srcPt+nbCompo,tmp,tmp,std::plus<int>());
8691               else
8692                 {
8693                   std::ostringstream oss; oss << "DataArrayInt::accumulatePerChunck : At rank #" << i << " the input index array points to id " << j << " should be in [0," << nbOfTuples << ") !";
8694                   throw INTERP_KERNEL::Exception(oss.str().c_str());
8695                 }
8696             }
8697         }
8698       else
8699         {
8700           std::ostringstream oss; oss << "DataArrayInt::accumulatePerChunck : At rank #" << i << " the input index array is not in ascendingly sorted.";
8701           throw INTERP_KERNEL::Exception(oss.str().c_str());
8702         }
8703     }
8704   ret->copyStringInfoFrom(*this);
8705   return ret.retn();
8706 }
8707
8708 /*!
8709  * Returns a new DataArrayInt by concatenating two given arrays, so that (1) the number
8710  * of tuples in the result array is <em> a1->getNumberOfTuples() + a2->getNumberOfTuples() -
8711  * offsetA2</em> and (2)
8712  * the number of component in the result array is same as that of each of given arrays.
8713  * First \a offsetA2 tuples of \a a2 are skipped and thus are missing from the result array.
8714  * Info on components is copied from the first of the given arrays. Number of components
8715  * in the given arrays must be the same.
8716  *  \param [in] a1 - an array to include in the result array.
8717  *  \param [in] a2 - another array to include in the result array.
8718  *  \param [in] offsetA2 - number of tuples of \a a2 to skip.
8719  *  \return DataArrayInt * - the new instance of DataArrayInt.
8720  *          The caller is to delete this result array using decrRef() as it is no more
8721  *          needed.
8722  *  \throw If either \a a1 or \a a2 is NULL.
8723  *  \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents().
8724  */
8725 DataArrayInt *DataArrayInt::Aggregate(const DataArrayInt *a1, const DataArrayInt *a2, int offsetA2)
8726 {
8727   if(!a1 || !a2)
8728     throw INTERP_KERNEL::Exception("DataArrayInt::Aggregate : input DataArrayInt instance is NULL !");
8729   int nbOfComp=a1->getNumberOfComponents();
8730   if(nbOfComp!=a2->getNumberOfComponents())
8731     throw INTERP_KERNEL::Exception("Nb of components mismatch for array Aggregation !");
8732   int nbOfTuple1=a1->getNumberOfTuples();
8733   int nbOfTuple2=a2->getNumberOfTuples();
8734   DataArrayInt *ret=DataArrayInt::New();
8735   ret->alloc(nbOfTuple1+nbOfTuple2-offsetA2,nbOfComp);
8736   int *pt=std::copy(a1->getConstPointer(),a1->getConstPointer()+nbOfTuple1*nbOfComp,ret->getPointer());
8737   std::copy(a2->getConstPointer()+offsetA2*nbOfComp,a2->getConstPointer()+nbOfTuple2*nbOfComp,pt);
8738   ret->copyStringInfoFrom(*a1);
8739   return ret;
8740 }
8741
8742 /*!
8743  * Returns a new DataArrayInt by concatenating all given arrays, so that (1) the number
8744  * of tuples in the result array is a sum of the number of tuples of given arrays and (2)
8745  * the number of component in the result array is same as that of each of given arrays.
8746  * Info on components is copied from the first of the given arrays. Number of components
8747  * in the given arrays must be  the same.
8748  *  \param [in] arr - a sequence of arrays to include in the result array.
8749  *  \return DataArrayInt * - the new instance of DataArrayInt.
8750  *          The caller is to delete this result array using decrRef() as it is no more
8751  *          needed.
8752  *  \throw If all arrays within \a arr are NULL.
8753  *  \throw If getNumberOfComponents() of arrays within \a arr.
8754  */
8755 DataArrayInt *DataArrayInt::Aggregate(const std::vector<const DataArrayInt *>& arr)
8756 {
8757   std::vector<const DataArrayInt *> a;
8758   for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
8759     if(*it4)
8760       a.push_back(*it4);
8761   if(a.empty())
8762     throw INTERP_KERNEL::Exception("DataArrayInt::Aggregate : input list must be NON EMPTY !");
8763   std::vector<const DataArrayInt *>::const_iterator it=a.begin();
8764   int nbOfComp=(*it)->getNumberOfComponents();
8765   int nbt=(*it++)->getNumberOfTuples();
8766   for(int i=1;it!=a.end();it++,i++)
8767     {
8768       if((*it)->getNumberOfComponents()!=nbOfComp)
8769         throw INTERP_KERNEL::Exception("DataArrayInt::Aggregate : Nb of components mismatch for array aggregation !");
8770       nbt+=(*it)->getNumberOfTuples();
8771     }
8772   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
8773   ret->alloc(nbt,nbOfComp);
8774   int *pt=ret->getPointer();
8775   for(it=a.begin();it!=a.end();it++)
8776     pt=std::copy((*it)->getConstPointer(),(*it)->getConstPointer()+(*it)->getNbOfElems(),pt);
8777   ret->copyStringInfoFrom(*(a[0]));
8778   return ret.retn();
8779 }
8780
8781 /*!
8782  * This method takes as input a list of DataArrayInt instances \a arrs that represent each a packed index arrays.
8783  * A packed index array is an allocated array with one component, and at least one tuple. The first element
8784  * of each array in \a arrs must be 0. Each array in \a arrs is expected to be increasingly monotonic.
8785  * 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.
8786  * 
8787  * \return DataArrayInt * - a new object to be managed by the caller.
8788  */
8789 DataArrayInt *DataArrayInt::AggregateIndexes(const std::vector<const DataArrayInt *>& arrs)
8790 {
8791   int retSz=1;
8792   for(std::vector<const DataArrayInt *>::const_iterator it4=arrs.begin();it4!=arrs.end();it4++)
8793     {
8794       if(*it4)
8795         {
8796           (*it4)->checkAllocated();
8797           if((*it4)->getNumberOfComponents()!=1)
8798             {
8799               std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a DataArrayInt instance with nb of compo != 1 at pos " << std::distance(arrs.begin(),it4) << " !";
8800               throw INTERP_KERNEL::Exception(oss.str().c_str());
8801             }
8802           int nbTupl=(*it4)->getNumberOfTuples();
8803           if(nbTupl<1)
8804             {
8805               std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a DataArrayInt instance with nb of tuples < 1 at pos " << std::distance(arrs.begin(),it4) << " !";
8806               throw INTERP_KERNEL::Exception(oss.str().c_str());
8807             }
8808           if((*it4)->front()!=0)
8809             {
8810               std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a DataArrayInt instance with front value != 0 at pos " << std::distance(arrs.begin(),it4) << " !";
8811               throw INTERP_KERNEL::Exception(oss.str().c_str());
8812             }
8813           retSz+=nbTupl-1;
8814         }
8815       else
8816         {
8817           std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a null instance at pos " << std::distance(arrs.begin(),it4) << " !";
8818           throw INTERP_KERNEL::Exception(oss.str().c_str());
8819         }
8820     }
8821   if(arrs.empty())
8822     throw INTERP_KERNEL::Exception("DataArrayInt::AggregateIndexes : input list must be NON EMPTY !");
8823   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
8824   ret->alloc(retSz,1);
8825   int *pt=ret->getPointer(); *pt++=0;
8826   for(std::vector<const DataArrayInt *>::const_iterator it=arrs.begin();it!=arrs.end();it++)
8827     pt=std::transform((*it)->begin()+1,(*it)->end(),pt,std::bind2nd(std::plus<int>(),pt[-1]));
8828   ret->copyStringInfoFrom(*(arrs[0]));
8829   return ret.retn();
8830 }
8831
8832 /*!
8833  * Returns the maximal value and its location within \a this one-dimensional array.
8834  *  \param [out] tupleId - index of the tuple holding the maximal value.
8835  *  \return int - the maximal value among all values of \a this array.
8836  *  \throw If \a this->getNumberOfComponents() != 1
8837  *  \throw If \a this->getNumberOfTuples() < 1
8838  */
8839 int DataArrayInt::getMaxValue(int& tupleId) const
8840 {
8841   checkAllocated();
8842   if(getNumberOfComponents()!=1)
8843     throw INTERP_KERNEL::Exception("DataArrayInt::getMaxValue : must be applied on DataArrayInt with only one component !");
8844   int nbOfTuples=getNumberOfTuples();
8845   if(nbOfTuples<=0)
8846     throw INTERP_KERNEL::Exception("DataArrayInt::getMaxValue : array exists but number of tuples must be > 0 !");
8847   const int *vals=getConstPointer();
8848   const int *loc=std::max_element(vals,vals+nbOfTuples);
8849   tupleId=(int)std::distance(vals,loc);
8850   return *loc;
8851 }
8852
8853 /*!
8854  * Returns the maximal value within \a this array that is allowed to have more than
8855  *  one component.
8856  *  \return int - the maximal value among all values of \a this array.
8857  *  \throw If \a this is not allocated.
8858  */
8859 int DataArrayInt::getMaxValueInArray() const
8860 {
8861   checkAllocated();
8862   const int *loc=std::max_element(begin(),end());
8863   return *loc;
8864 }
8865
8866 /*!
8867  * Returns the minimal value and its location within \a this one-dimensional array.
8868  *  \param [out] tupleId - index of the tuple holding the minimal value.
8869  *  \return int - the minimal value among all values of \a this array.
8870  *  \throw If \a this->getNumberOfComponents() != 1
8871  *  \throw If \a this->getNumberOfTuples() < 1
8872  */
8873 int DataArrayInt::getMinValue(int& tupleId) const
8874 {
8875   checkAllocated();
8876   if(getNumberOfComponents()!=1)
8877     throw INTERP_KERNEL::Exception("DataArrayInt::getMaxValue : must be applied on DataArrayInt with only one component !");
8878   int nbOfTuples=getNumberOfTuples();
8879   if(nbOfTuples<=0)
8880     throw INTERP_KERNEL::Exception("DataArrayInt::getMaxValue : array exists but number of tuples must be > 0 !");
8881   const int *vals=getConstPointer();
8882   const int *loc=std::min_element(vals,vals+nbOfTuples);
8883   tupleId=(int)std::distance(vals,loc);
8884   return *loc;
8885 }
8886
8887 /*!
8888  * Returns the minimal value within \a this array that is allowed to have more than
8889  *  one component.
8890  *  \return int - the minimal value among all values of \a this array.
8891  *  \throw If \a this is not allocated.
8892  */
8893 int DataArrayInt::getMinValueInArray() const
8894 {
8895   checkAllocated();
8896   const int *loc=std::min_element(begin(),end());
8897   return *loc;
8898 }
8899
8900 /*!
8901  * Converts every value of \a this array to its absolute value.
8902  *  \throw If \a this is not allocated.
8903  */
8904 void DataArrayInt::abs()
8905 {
8906   checkAllocated();
8907   int *ptr=getPointer();
8908   std::size_t nbOfElems=getNbOfElems();
8909   std::transform(ptr,ptr+nbOfElems,ptr,std::ptr_fun<int,int>(std::abs));
8910   declareAsNew();
8911 }
8912
8913 /*!
8914  * Apply a liner function to a given component of \a this array, so that
8915  * an array element <em>(x)</em> becomes \f$ a * x + b \f$.
8916  *  \param [in] a - the first coefficient of the function.
8917  *  \param [in] b - the second coefficient of the function.
8918  *  \param [in] compoId - the index of component to modify.
8919  *  \throw If \a this is not allocated.
8920  */
8921 void DataArrayInt::applyLin(int a, int b, int compoId)
8922 {
8923   checkAllocated();
8924   int *ptr=getPointer()+compoId;
8925   int nbOfComp=getNumberOfComponents();
8926   int nbOfTuple=getNumberOfTuples();
8927   for(int i=0;i<nbOfTuple;i++,ptr+=nbOfComp)
8928     *ptr=a*(*ptr)+b;
8929   declareAsNew();
8930 }
8931
8932 /*!
8933  * Apply a liner function to all elements of \a this array, so that
8934  * an element _x_ becomes \f$ a * x + b \f$.
8935  *  \param [in] a - the first coefficient of the function.
8936  *  \param [in] b - the second coefficient of the function.
8937  *  \throw If \a this is not allocated.
8938  */
8939 void DataArrayInt::applyLin(int a, int b)
8940 {
8941   checkAllocated();
8942   int *ptr=getPointer();
8943   std::size_t nbOfElems=getNbOfElems();
8944   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
8945     *ptr=a*(*ptr)+b;
8946   declareAsNew();
8947 }
8948
8949 /*!
8950  * Returns a full copy of \a this array except that sign of all elements is reversed.
8951  *  \return DataArrayInt * - the new instance of DataArrayInt containing the
8952  *          same number of tuples and component as \a this array.
8953  *          The caller is to delete this result array using decrRef() as it is no more
8954  *          needed.
8955  *  \throw If \a this is not allocated.
8956  */
8957 DataArrayInt *DataArrayInt::negate() const
8958 {
8959   checkAllocated();
8960   DataArrayInt *newArr=DataArrayInt::New();
8961   int nbOfTuples=getNumberOfTuples();
8962   int nbOfComp=getNumberOfComponents();
8963   newArr->alloc(nbOfTuples,nbOfComp);
8964   const int *cptr=getConstPointer();
8965   std::transform(cptr,cptr+nbOfTuples*nbOfComp,newArr->getPointer(),std::negate<int>());
8966   newArr->copyStringInfoFrom(*this);
8967   return newArr;
8968 }
8969
8970 /*!
8971  * Modify all elements of \a this array, so that
8972  * an element _x_ becomes \f$ numerator / x \f$.
8973  *  \warning If an exception is thrown because of presence of 0 element in \a this 
8974  *           array, all elements processed before detection of the zero element remain
8975  *           modified.
8976  *  \param [in] numerator - the numerator used to modify array elements.
8977  *  \throw If \a this is not allocated.
8978  *  \throw If there is an element equal to 0 in \a this array.
8979  */
8980 void DataArrayInt::applyInv(int numerator)
8981 {
8982   checkAllocated();
8983   int *ptr=getPointer();
8984   std::size_t nbOfElems=getNbOfElems();
8985   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
8986     {
8987       if(*ptr!=0)
8988         {
8989           *ptr=numerator/(*ptr);
8990         }
8991       else
8992         {
8993           std::ostringstream oss; oss << "DataArrayInt::applyInv : presence of null value in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
8994           oss << " !";
8995           throw INTERP_KERNEL::Exception(oss.str().c_str());
8996         }
8997     }
8998   declareAsNew();
8999 }
9000
9001 /*!
9002  * Modify all elements of \a this array, so that
9003  * an element _x_ becomes \f$ x / val \f$.
9004  *  \param [in] val - the denominator used to modify array elements.
9005  *  \throw If \a this is not allocated.
9006  *  \throw If \a val == 0.
9007  */
9008 void DataArrayInt::applyDivideBy(int val)
9009 {
9010   if(val==0)
9011     throw INTERP_KERNEL::Exception("DataArrayInt::applyDivideBy : Trying to divide by 0 !");
9012   checkAllocated();
9013   int *ptr=getPointer();
9014   std::size_t nbOfElems=getNbOfElems();
9015   std::transform(ptr,ptr+nbOfElems,ptr,std::bind2nd(std::divides<int>(),val));
9016   declareAsNew();
9017 }
9018
9019 /*!
9020  * Modify all elements of \a this array, so that
9021  * an element _x_ becomes  <em> x % val </em>.
9022  *  \param [in] val - the divisor used to modify array elements.
9023  *  \throw If \a this is not allocated.
9024  *  \throw If \a val <= 0.
9025  */
9026 void DataArrayInt::applyModulus(int val)
9027 {
9028   if(val<=0)
9029     throw INTERP_KERNEL::Exception("DataArrayInt::applyDivideBy : Trying to operate modulus on value <= 0 !");
9030   checkAllocated();
9031   int *ptr=getPointer();
9032   std::size_t nbOfElems=getNbOfElems();
9033   std::transform(ptr,ptr+nbOfElems,ptr,std::bind2nd(std::modulus<int>(),val));
9034   declareAsNew();
9035 }
9036
9037 /*!
9038  * This method works only on data array with one component.
9039  * This method returns a newly allocated array storing stored ascendantly tuple ids in \b this so that
9040  * this[*id] in [\b vmin,\b vmax)
9041  * 
9042  * \param [in] vmin begin of range. This value is included in range (included).
9043  * \param [in] vmax end of range. This value is \b not included in range (excluded).
9044  * \return a newly allocated data array that the caller should deal with.
9045  *
9046  * \sa DataArrayInt::getIdsNotInRange
9047  */
9048 DataArrayInt *DataArrayInt::getIdsInRange(int vmin, int vmax) const
9049 {
9050   checkAllocated();
9051   if(getNumberOfComponents()!=1)
9052     throw INTERP_KERNEL::Exception("DataArrayInt::getIdsInRange : this must have exactly one component !");
9053   const int *cptr(begin());
9054   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
9055   int nbOfTuples(getNumberOfTuples());
9056   for(int i=0;i<nbOfTuples;i++,cptr++)
9057     if(*cptr>=vmin && *cptr<vmax)
9058       ret->pushBackSilent(i);
9059   return ret.retn();
9060 }
9061
9062 /*!
9063  * This method works only on data array with one component.
9064  * This method returns a newly allocated array storing stored ascendantly tuple ids in \b this so that
9065  * this[*id] \b not in [\b vmin,\b vmax)
9066  * 
9067  * \param [in] vmin begin of range. This value is \b not included in range (excluded).
9068  * \param [in] vmax end of range. This value is included in range (included).
9069  * \return a newly allocated data array that the caller should deal with.
9070  * 
9071  * \sa DataArrayInt::getIdsInRange
9072  */
9073 DataArrayInt *DataArrayInt::getIdsNotInRange(int vmin, int vmax) const
9074 {
9075   checkAllocated();
9076   if(getNumberOfComponents()!=1)
9077     throw INTERP_KERNEL::Exception("DataArrayInt::getIdsNotInRange : this must have exactly one component !");
9078   const int *cptr(getConstPointer());
9079   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
9080   int nbOfTuples(getNumberOfTuples());
9081   for(int i=0;i<nbOfTuples;i++,cptr++)
9082     if(*cptr<vmin || *cptr>=vmax)
9083       ret->pushBackSilent(i);
9084   return ret.retn();
9085 }
9086
9087 /*!
9088  * This method works only on data array with one component.
9089  * 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.
9090  * 
9091  * \param [in] vmin begin of range. This value is included in range (included).
9092  * \param [in] vmax end of range. This value is \b not included in range (excluded).
9093  * \return if all ids in \a this are so that (*this)[i]==i for all i in [ 0, \c this->getNumberOfTuples() ). */
9094 bool DataArrayInt::checkAllIdsInRange(int vmin, int vmax) const
9095 {
9096   checkAllocated();
9097   if(getNumberOfComponents()!=1)
9098     throw INTERP_KERNEL::Exception("DataArrayInt::checkAllIdsInRange : this must have exactly one component !");
9099   int nbOfTuples=getNumberOfTuples();
9100   bool ret=true;
9101   const int *cptr=getConstPointer();
9102   for(int i=0;i<nbOfTuples;i++,cptr++)
9103     {
9104       if(*cptr>=vmin && *cptr<vmax)
9105         { ret=ret && *cptr==i; }
9106       else
9107         {
9108           std::ostringstream oss; oss << "DataArrayInt::checkAllIdsInRange : tuple #" << i << " has value " << *cptr << " should be in [" << vmin << "," << vmax << ") !";
9109           throw INTERP_KERNEL::Exception(oss.str().c_str());
9110         }
9111     }
9112   return ret;
9113 }
9114
9115 /*!
9116  * Modify all elements of \a this array, so that
9117  * an element _x_ becomes <em> val % x </em>.
9118  *  \warning If an exception is thrown because of presence of an element <= 0 in \a this 
9119  *           array, all elements processed before detection of the zero element remain
9120  *           modified.
9121  *  \param [in] val - the divident used to modify array elements.
9122  *  \throw If \a this is not allocated.
9123  *  \throw If there is an element equal to or less than 0 in \a this array.
9124  */
9125 void DataArrayInt::applyRModulus(int val)
9126 {
9127   checkAllocated();
9128   int *ptr=getPointer();
9129   std::size_t nbOfElems=getNbOfElems();
9130   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
9131     {
9132       if(*ptr>0)
9133         {
9134           *ptr=val%(*ptr);
9135         }
9136       else
9137         {
9138           std::ostringstream oss; oss << "DataArrayInt::applyRModulus : presence of value <=0 in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
9139           oss << " !";
9140           throw INTERP_KERNEL::Exception(oss.str().c_str());
9141         }
9142     }
9143   declareAsNew();
9144 }
9145
9146 /*!
9147  * Modify all elements of \a this array, so that
9148  * an element _x_ becomes <em> val ^ x </em>.
9149  *  \param [in] val - the value used to apply pow on all array elements.
9150  *  \throw If \a this is not allocated.
9151  *  \throw If \a val < 0.
9152  */
9153 void DataArrayInt::applyPow(int val)
9154 {
9155   checkAllocated();
9156   if(val<0)
9157     throw INTERP_KERNEL::Exception("DataArrayInt::applyPow : input pow in < 0 !");
9158   int *ptr=getPointer();
9159   std::size_t nbOfElems=getNbOfElems();
9160   if(val==0)
9161     {
9162       std::fill(ptr,ptr+nbOfElems,1);
9163       return ;
9164     }
9165   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
9166     {
9167       int tmp=1;
9168       for(int j=0;j<val;j++)
9169         tmp*=*ptr;
9170       *ptr=tmp;
9171     }
9172   declareAsNew();
9173 }
9174
9175 /*!
9176  * Modify all elements of \a this array, so that
9177  * an element _x_ becomes \f$ val ^ x \f$.
9178  *  \param [in] val - the value used to apply pow on all array elements.
9179  *  \throw If \a this is not allocated.
9180  *  \throw If there is an element < 0 in \a this array.
9181  *  \warning If an exception is thrown because of presence of 0 element in \a this 
9182  *           array, all elements processed before detection of the zero element remain
9183  *           modified.
9184  */
9185 void DataArrayInt::applyRPow(int val)
9186 {
9187   checkAllocated();
9188   int *ptr=getPointer();
9189   std::size_t nbOfElems=getNbOfElems();
9190   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
9191     {
9192       if(*ptr>=0)
9193         {
9194           int tmp=1;
9195           for(int j=0;j<*ptr;j++)
9196             tmp*=val;
9197           *ptr=tmp;
9198         }
9199       else
9200         {
9201           std::ostringstream oss; oss << "DataArrayInt::applyRPow : presence of negative value in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
9202           oss << " !";
9203           throw INTERP_KERNEL::Exception(oss.str().c_str());
9204         }
9205     }
9206   declareAsNew();
9207 }
9208
9209 /*!
9210  * Returns a new DataArrayInt by aggregating two given arrays, so that (1) the number
9211  * of components in the result array is a sum of the number of components of given arrays
9212  * and (2) the number of tuples in the result array is same as that of each of given
9213  * arrays. In other words the i-th tuple of result array includes all components of
9214  * i-th tuples of all given arrays.
9215  * Number of tuples in the given arrays must be the same.
9216  *  \param [in] a1 - an array to include in the result array.
9217  *  \param [in] a2 - another array to include in the result array.
9218  *  \return DataArrayInt * - the new instance of DataArrayInt.
9219  *          The caller is to delete this result array using decrRef() as it is no more
9220  *          needed.
9221  *  \throw If both \a a1 and \a a2 are NULL.
9222  *  \throw If any given array is not allocated.
9223  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
9224  */
9225 DataArrayInt *DataArrayInt::Meld(const DataArrayInt *a1, const DataArrayInt *a2)
9226 {
9227   std::vector<const DataArrayInt *> arr(2);
9228   arr[0]=a1; arr[1]=a2;
9229   return Meld(arr);
9230 }
9231
9232 /*!
9233  * Returns a new DataArrayInt by aggregating all given arrays, so that (1) the number
9234  * of components in the result array is a sum of the number of components of given arrays
9235  * and (2) the number of tuples in the result array is same as that of each of given
9236  * arrays. In other words the i-th tuple of result array includes all components of
9237  * i-th tuples of all given arrays.
9238  * Number of tuples in the given arrays must be  the same.
9239  *  \param [in] arr - a sequence of arrays to include in the result array.
9240  *  \return DataArrayInt * - the new instance of DataArrayInt.
9241  *          The caller is to delete this result array using decrRef() as it is no more
9242  *          needed.
9243  *  \throw If all arrays within \a arr are NULL.
9244  *  \throw If any given array is not allocated.
9245  *  \throw If getNumberOfTuples() of arrays within \a arr is different.
9246  */
9247 DataArrayInt *DataArrayInt::Meld(const std::vector<const DataArrayInt *>& arr)
9248 {
9249   std::vector<const DataArrayInt *> a;
9250   for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
9251     if(*it4)
9252       a.push_back(*it4);
9253   if(a.empty())
9254     throw INTERP_KERNEL::Exception("DataArrayInt::Meld : array must be NON empty !");
9255   std::vector<const DataArrayInt *>::const_iterator it;
9256   for(it=a.begin();it!=a.end();it++)
9257     (*it)->checkAllocated();
9258   it=a.begin();
9259   int nbOfTuples=(*it)->getNumberOfTuples();
9260   std::vector<int> nbc(a.size());
9261   std::vector<const int *> pts(a.size());
9262   nbc[0]=(*it)->getNumberOfComponents();
9263   pts[0]=(*it++)->getConstPointer();
9264   for(int i=1;it!=a.end();it++,i++)
9265     {
9266       if(nbOfTuples!=(*it)->getNumberOfTuples())
9267         throw INTERP_KERNEL::Exception("DataArrayInt::meld : mismatch of number of tuples !");
9268       nbc[i]=(*it)->getNumberOfComponents();
9269       pts[i]=(*it)->getConstPointer();
9270     }
9271   int totalNbOfComp=std::accumulate(nbc.begin(),nbc.end(),0);
9272   DataArrayInt *ret=DataArrayInt::New();
9273   ret->alloc(nbOfTuples,totalNbOfComp);
9274   int *retPtr=ret->getPointer();
9275   for(int i=0;i<nbOfTuples;i++)
9276     for(int j=0;j<(int)a.size();j++)
9277       {
9278         retPtr=std::copy(pts[j],pts[j]+nbc[j],retPtr);
9279         pts[j]+=nbc[j];
9280       }
9281   int k=0;
9282   for(int i=0;i<(int)a.size();i++)
9283     for(int j=0;j<nbc[i];j++,k++)
9284       ret->setInfoOnComponent(k,a[i]->getInfoOnComponent(j).c_str());
9285   return ret;
9286 }
9287
9288 /*!
9289  * Returns a new DataArrayInt which is a minimal partition of elements of \a groups.
9290  * The i-th item of the result array is an ID of a set of elements belonging to a
9291  * unique set of groups, which the i-th element is a part of. This set of elements
9292  * belonging to a unique set of groups is called \a family, so the result array contains
9293  * IDs of families each element belongs to.
9294  *
9295  * \b Example: if we have two groups of elements: \a group1 [0,4] and \a group2 [ 0,1,2 ],
9296  * then there are 3 families:
9297  * - \a family1 (with ID 1) contains element [0] belonging to ( \a group1 + \a group2 ),
9298  * - \a family2 (with ID 2) contains elements [4] belonging to ( \a group1 ),
9299  * - \a family3 (with ID 3) contains element [1,2] belonging to ( \a group2 ), <br>
9300  * and the result array contains IDs of families [ 1,3,3,0,2 ]. <br> Note a family ID 0 which
9301  * stands for the element #3 which is in none of groups.
9302  *
9303  *  \param [in] groups - sequence of groups of element IDs.
9304  *  \param [in] newNb - total number of elements; it must be more than max ID of element
9305  *         in \a groups.
9306  *  \param [out] fidsOfGroups - IDs of families the elements of each group belong to.
9307  *  \return DataArrayInt * - a new instance of DataArrayInt containing IDs of families
9308  *         each element with ID from range [0, \a newNb ) belongs to. The caller is to
9309  *         delete this array using decrRef() as it is no more needed.
9310  *  \throw If any element ID in \a groups violates condition ( 0 <= ID < \a newNb ).
9311  */
9312 DataArrayInt *DataArrayInt::MakePartition(const std::vector<const DataArrayInt *>& groups, int newNb, std::vector< std::vector<int> >& fidsOfGroups)
9313 {
9314   std::vector<const DataArrayInt *> groups2;
9315   for(std::vector<const DataArrayInt *>::const_iterator it4=groups.begin();it4!=groups.end();it4++)
9316     if(*it4)
9317       groups2.push_back(*it4);
9318   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
9319   ret->alloc(newNb,1);
9320   int *retPtr=ret->getPointer();
9321   std::fill(retPtr,retPtr+newNb,0);
9322   int fid=1;
9323   for(std::vector<const DataArrayInt *>::const_iterator iter=groups2.begin();iter!=groups2.end();iter++)
9324     {
9325       const int *ptr=(*iter)->getConstPointer();
9326       std::size_t nbOfElem=(*iter)->getNbOfElems();
9327       int sfid=fid;
9328       for(int j=0;j<sfid;j++)
9329         {
9330           bool found=false;
9331           for(std::size_t i=0;i<nbOfElem;i++)
9332             {
9333               if(ptr[i]>=0 && ptr[i]<newNb)
9334                 {
9335                   if(retPtr[ptr[i]]==j)
9336                     {
9337                       retPtr[ptr[i]]=fid;
9338                       found=true;
9339                     }
9340                 }
9341               else
9342                 {
9343                   std::ostringstream oss; oss << "DataArrayInt::MakePartition : In group \"" << (*iter)->getName() << "\" in tuple #" << i << " value = " << ptr[i] << " ! Should be in [0," << newNb;
9344                   oss << ") !";
9345                   throw INTERP_KERNEL::Exception(oss.str().c_str());
9346                 }
9347             }
9348           if(found)
9349             fid++;
9350         }
9351     }
9352   fidsOfGroups.clear();
9353   fidsOfGroups.resize(groups2.size());
9354   int grId=0;
9355   for(std::vector<const DataArrayInt *>::const_iterator iter=groups2.begin();iter!=groups2.end();iter++,grId++)
9356     {
9357       std::set<int> tmp;
9358       const int *ptr=(*iter)->getConstPointer();
9359       std::size_t nbOfElem=(*iter)->getNbOfElems();
9360       for(const int *p=ptr;p!=ptr+nbOfElem;p++)
9361         tmp.insert(retPtr[*p]);
9362       fidsOfGroups[grId].insert(fidsOfGroups[grId].end(),tmp.begin(),tmp.end());
9363     }
9364   return ret.retn();
9365 }
9366
9367 /*!
9368  * Returns a new DataArrayInt which contains all elements of given one-dimensional
9369  * arrays. The result array does not contain any duplicates and its values
9370  * are sorted in ascending order.
9371  *  \param [in] arr - sequence of DataArrayInt's to unite.
9372  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
9373  *         array using decrRef() as it is no more needed.
9374  *  \throw If any \a arr[i] is not allocated.
9375  *  \throw If \a arr[i]->getNumberOfComponents() != 1.
9376  */
9377 DataArrayInt *DataArrayInt::BuildUnion(const std::vector<const DataArrayInt *>& arr)
9378 {
9379   std::vector<const DataArrayInt *> a;
9380   for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
9381     if(*it4)
9382       a.push_back(*it4);
9383   for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
9384     {
9385       (*it)->checkAllocated();
9386       if((*it)->getNumberOfComponents()!=1)
9387         throw INTERP_KERNEL::Exception("DataArrayInt::BuildUnion : only single component allowed !");
9388     }
9389   //
9390   std::set<int> r;
9391   for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
9392     {
9393       const int *pt=(*it)->getConstPointer();
9394       int nbOfTuples=(*it)->getNumberOfTuples();
9395       r.insert(pt,pt+nbOfTuples);
9396     }
9397   DataArrayInt *ret=DataArrayInt::New();
9398   ret->alloc((int)r.size(),1);
9399   std::copy(r.begin(),r.end(),ret->getPointer());
9400   return ret;
9401 }
9402
9403 /*!
9404  * Returns a new DataArrayInt which contains elements present in each of given one-dimensional
9405  * arrays. The result array does not contain any duplicates and its values
9406  * are sorted in ascending order.
9407  *  \param [in] arr - sequence of DataArrayInt's to intersect.
9408  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
9409  *         array using decrRef() as it is no more needed.
9410  *  \throw If any \a arr[i] is not allocated.
9411  *  \throw If \a arr[i]->getNumberOfComponents() != 1.
9412  */
9413 DataArrayInt *DataArrayInt::BuildIntersection(const std::vector<const DataArrayInt *>& arr)
9414 {
9415   std::vector<const DataArrayInt *> a;
9416   for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
9417     if(*it4)
9418       a.push_back(*it4);
9419   for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
9420     {
9421       (*it)->checkAllocated();
9422       if((*it)->getNumberOfComponents()!=1)
9423         throw INTERP_KERNEL::Exception("DataArrayInt::BuildIntersection : only single component allowed !");
9424     }
9425   //
9426   std::set<int> r;
9427   for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
9428     {
9429       const int *pt=(*it)->getConstPointer();
9430       int nbOfTuples=(*it)->getNumberOfTuples();
9431       std::set<int> s1(pt,pt+nbOfTuples);
9432       if(it!=a.begin())
9433         {
9434           std::set<int> r2;
9435           std::set_intersection(r.begin(),r.end(),s1.begin(),s1.end(),inserter(r2,r2.end()));
9436           r=r2;
9437         }
9438       else
9439         r=s1;
9440     }
9441   DataArrayInt *ret=DataArrayInt::New();
9442   ret->alloc((int)r.size(),1);
9443   std::copy(r.begin(),r.end(),ret->getPointer());
9444   return ret;
9445 }
9446
9447 /*!
9448  * Returns a new DataArrayInt which contains a complement of elements of \a this
9449  * one-dimensional array. I.e. the result array contains all elements from the range [0,
9450  * \a nbOfElement) not present in \a this array.
9451  *  \param [in] nbOfElement - maximal size of the result array.
9452  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
9453  *         array using decrRef() as it is no more needed.
9454  *  \throw If \a this is not allocated.
9455  *  \throw If \a this->getNumberOfComponents() != 1.
9456  *  \throw If any element \a x of \a this array violates condition ( 0 <= \a x < \a
9457  *         nbOfElement ).
9458  */
9459 DataArrayInt *DataArrayInt::buildComplement(int nbOfElement) const
9460 {
9461    checkAllocated();
9462    if(getNumberOfComponents()!=1)
9463      throw INTERP_KERNEL::Exception("DataArrayInt::buildComplement : only single component allowed !");
9464    std::vector<bool> tmp(nbOfElement);
9465    const int *pt=getConstPointer();
9466    int nbOfTuples=getNumberOfTuples();
9467    for(const int *w=pt;w!=pt+nbOfTuples;w++)
9468      if(*w>=0 && *w<nbOfElement)
9469        tmp[*w]=true;
9470      else
9471        throw INTERP_KERNEL::Exception("DataArrayInt::buildComplement : an element is not in valid range : [0,nbOfElement) !");
9472    int nbOfRetVal=(int)std::count(tmp.begin(),tmp.end(),false);
9473    DataArrayInt *ret=DataArrayInt::New();
9474    ret->alloc(nbOfRetVal,1);
9475    int j=0;
9476    int *retPtr=ret->getPointer();
9477    for(int i=0;i<nbOfElement;i++)
9478      if(!tmp[i])
9479        retPtr[j++]=i;
9480    return ret;
9481 }
9482
9483 /*!
9484  * Returns a new DataArrayInt containing elements of \a this one-dimensional missing
9485  * from an \a other one-dimensional array.
9486  *  \param [in] other - a DataArrayInt containing elements not to include in the result array.
9487  *  \return DataArrayInt * - a new instance of DataArrayInt with one component. The
9488  *         caller is to delete this array using decrRef() as it is no more needed.
9489  *  \throw If \a other is NULL.
9490  *  \throw If \a other is not allocated.
9491  *  \throw If \a other->getNumberOfComponents() != 1.
9492  *  \throw If \a this is not allocated.
9493  *  \throw If \a this->getNumberOfComponents() != 1.
9494  *  \sa DataArrayInt::buildSubstractionOptimized()
9495  */
9496 DataArrayInt *DataArrayInt::buildSubstraction(const DataArrayInt *other) const
9497 {
9498   if(!other)
9499     throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstraction : DataArrayInt pointer in input is NULL !");
9500   checkAllocated();
9501   other->checkAllocated();
9502   if(getNumberOfComponents()!=1)
9503      throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstraction : only single component allowed !");
9504   if(other->getNumberOfComponents()!=1)
9505      throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstraction : only single component allowed for other type !");
9506   const int *pt=getConstPointer();
9507   int nbOfTuples=getNumberOfTuples();
9508   std::set<int> s1(pt,pt+nbOfTuples);
9509   pt=other->getConstPointer();
9510   nbOfTuples=other->getNumberOfTuples();
9511   std::set<int> s2(pt,pt+nbOfTuples);
9512   std::vector<int> r;
9513   std::set_difference(s1.begin(),s1.end(),s2.begin(),s2.end(),std::back_insert_iterator< std::vector<int> >(r));
9514   DataArrayInt *ret=DataArrayInt::New();
9515   ret->alloc((int)r.size(),1);
9516   std::copy(r.begin(),r.end(),ret->getPointer());
9517   return ret;
9518 }
9519
9520 /*!
9521  * \a this is expected to have one component and to be sorted ascendingly (as for \a other).
9522  * \a other is expected to be a part of \a this. If not DataArrayInt::buildSubstraction should be called instead.
9523  * 
9524  * \param [in] other an array with one component and expected to be sorted ascendingly.
9525  * \ret list of ids in \a this but not in \a other.
9526  * \sa DataArrayInt::buildSubstraction
9527  */
9528 DataArrayInt *DataArrayInt::buildSubstractionOptimized(const DataArrayInt *other) const
9529 {
9530   static const char *MSG="DataArrayInt::buildSubstractionOptimized : only single component allowed !";
9531   if(!other) throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstractionOptimized : NULL input array !");
9532   checkAllocated(); other->checkAllocated();
9533   if(getNumberOfComponents()!=1) throw INTERP_KERNEL::Exception(MSG);
9534   if(other->getNumberOfComponents()!=1) throw INTERP_KERNEL::Exception(MSG);
9535   const int *pt1Bg(begin()),*pt1End(end()),*pt2Bg(other->begin()),*pt2End(other->end()),*work1(pt1Bg),*work2(pt2Bg);
9536   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
9537   for(;work1!=pt1End;work1++)
9538     {
9539       if(work2!=pt2End && *work1==*work2)
9540         work2++;
9541       else
9542         ret->pushBackSilent(*work1);
9543     }
9544   return ret.retn();
9545 }
9546
9547
9548 /*!
9549  * Returns a new DataArrayInt which contains all elements of \a this and a given
9550  * one-dimensional arrays. The result array does not contain any duplicates
9551  * and its values are sorted in ascending order.
9552  *  \param [in] other - an array to unite with \a this one.
9553  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
9554  *         array using decrRef() as it is no more needed.
9555  *  \throw If \a this or \a other is not allocated.
9556  *  \throw If \a this->getNumberOfComponents() != 1.
9557  *  \throw If \a other->getNumberOfComponents() != 1.
9558  */
9559 DataArrayInt *DataArrayInt::buildUnion(const DataArrayInt *other) const
9560 {
9561   std::vector<const DataArrayInt *>arrs(2);
9562   arrs[0]=this; arrs[1]=other;
9563   return BuildUnion(arrs);
9564 }
9565
9566
9567 /*!
9568  * Returns a new DataArrayInt which contains elements present in both \a this and a given
9569  * one-dimensional arrays. The result array does not contain any duplicates
9570  * and its values are sorted in ascending order.
9571  *  \param [in] other - an array to intersect with \a this one.
9572  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
9573  *         array using decrRef() as it is no more needed.
9574  *  \throw If \a this or \a other is not allocated.
9575  *  \throw If \a this->getNumberOfComponents() != 1.
9576  *  \throw If \a other->getNumberOfComponents() != 1.
9577  */
9578 DataArrayInt *DataArrayInt::buildIntersection(const DataArrayInt *other) const
9579 {
9580   std::vector<const DataArrayInt *>arrs(2);
9581   arrs[0]=this; arrs[1]=other;
9582   return BuildIntersection(arrs);
9583 }
9584
9585 /*!
9586  * This method can be applied on allocated with one component DataArrayInt instance.
9587  * This method is typically relevant for sorted arrays. All consecutive duplicated items in \a this will appear only once in returned DataArrayInt instance.
9588  * 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]
9589  * 
9590  * \return a newly allocated array that contain the result of the unique operation applied on \a this.
9591  * \throw if \a this is not allocated or if \a this has not exactly one component.
9592  */
9593 DataArrayInt *DataArrayInt::buildUnique() const
9594 {
9595   checkAllocated();
9596   if(getNumberOfComponents()!=1)
9597      throw INTERP_KERNEL::Exception("DataArrayInt::buildUnique : only single component allowed !");
9598   int nbOfTuples=getNumberOfTuples();
9599   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp=deepCpy();
9600   int *data=tmp->getPointer();
9601   int *last=std::unique(data,data+nbOfTuples);
9602   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
9603   ret->alloc(std::distance(data,last),1);
9604   std::copy(data,last,ret->getPointer());
9605   return ret.retn();
9606 }
9607
9608 /*!
9609  * Returns a new DataArrayInt which contains size of every of groups described by \a this
9610  * "index" array. Such "index" array is returned for example by 
9611  * \ref ParaMEDMEM::MEDCouplingUMesh::buildDescendingConnectivity
9612  * "MEDCouplingUMesh::buildDescendingConnectivity" and
9613  * \ref ParaMEDMEM::MEDCouplingUMesh::getNodalConnectivityIndex
9614  * "MEDCouplingUMesh::getNodalConnectivityIndex" etc.
9615  * This method preforms the reverse operation of DataArrayInt::computeOffsets2.
9616  *  \return DataArrayInt * - a new instance of DataArrayInt, whose number of tuples
9617  *          equals to \a this->getNumberOfComponents() - 1, and number of components is 1.
9618  *          The caller is to delete this array using decrRef() as it is no more needed. 
9619  *  \throw If \a this is not allocated.
9620  *  \throw If \a this->getNumberOfComponents() != 1.
9621  *  \throw If \a this->getNumberOfTuples() < 2.
9622  *
9623  *  \b Example: <br> 
9624  *         - this contains [1,3,6,7,7,9,15]
9625  *         - result array contains [2,3,1,0,2,6],
9626  *          where 2 = 3 - 1, 3 = 6 - 3, 1 = 7 - 6 etc.
9627  *
9628  * \sa DataArrayInt::computeOffsets2
9629  */
9630 DataArrayInt *DataArrayInt::deltaShiftIndex() const
9631 {
9632   checkAllocated();
9633   if(getNumberOfComponents()!=1)
9634      throw INTERP_KERNEL::Exception("DataArrayInt::deltaShiftIndex : only single component allowed !");
9635   int nbOfTuples=getNumberOfTuples();
9636   if(nbOfTuples<2)
9637     throw INTERP_KERNEL::Exception("DataArrayInt::deltaShiftIndex : 1 tuple at least must be present in 'this' !");
9638   const int *ptr=getConstPointer();
9639   DataArrayInt *ret=DataArrayInt::New();
9640   ret->alloc(nbOfTuples-1,1);
9641   int *out=ret->getPointer();
9642   std::transform(ptr+1,ptr+nbOfTuples,ptr,out,std::minus<int>());
9643   return ret;
9644 }
9645
9646 /*!
9647  * Modifies \a this one-dimensional array so that value of each element \a x
9648  * of \a this array (\a a) is computed as \f$ x_i = \sum_{j=0}^{i-1} a[ j ] \f$.
9649  * Or: for each i>0 new[i]=new[i-1]+old[i-1] for i==0 new[i]=0. Number of tuples
9650  * and components remains the same.<br>
9651  * This method is useful for allToAllV in MPI with contiguous policy. This method
9652  * differs from computeOffsets2() in that the number of tuples is \b not changed by
9653  * this one.
9654  *  \throw If \a this is not allocated.
9655  *  \throw If \a this->getNumberOfComponents() != 1.
9656  *
9657  *  \b Example: <br>
9658  *          - Before \a this contains [3,5,1,2,0,8]
9659  *          - After \a this contains  [0,3,8,9,11,11]<br>
9660  *          Note that the last element 19 = 11 + 8 is missing because size of \a this
9661  *          array is retained and thus there is no space to store the last element.
9662  */
9663 void DataArrayInt::computeOffsets()
9664 {
9665   checkAllocated();
9666   if(getNumberOfComponents()!=1)
9667      throw INTERP_KERNEL::Exception("DataArrayInt::computeOffsets : only single component allowed !");
9668   int nbOfTuples=getNumberOfTuples();
9669   if(nbOfTuples==0)
9670     return ;
9671   int *work=getPointer();
9672   int tmp=work[0];
9673   work[0]=0;
9674   for(int i=1;i<nbOfTuples;i++)
9675     {
9676       int tmp2=work[i];
9677       work[i]=work[i-1]+tmp;
9678       tmp=tmp2;
9679     }
9680   declareAsNew();
9681 }
9682
9683
9684 /*!
9685  * Modifies \a this one-dimensional array so that value of each element \a x
9686  * of \a this array (\a a) is computed as \f$ x_i = \sum_{j=0}^{i-1} a[ j ] \f$.
9687  * Or: for each i>0 new[i]=new[i-1]+old[i-1] for i==0 new[i]=0. Number
9688  * components remains the same and number of tuples is inceamented by one.<br>
9689  * This method is useful for allToAllV in MPI with contiguous policy. This method
9690  * differs from computeOffsets() in that the number of tuples is changed by this one.
9691  * This method preforms the reverse operation of DataArrayInt::deltaShiftIndex.
9692  *  \throw If \a this is not allocated.
9693  *  \throw If \a this->getNumberOfComponents() != 1.
9694  *
9695  *  \b Example: <br>
9696  *          - Before \a this contains [3,5,1,2,0,8]
9697  *          - After \a this contains  [0,3,8,9,11,11,19]<br>
9698  * \sa DataArrayInt::deltaShiftIndex
9699  */
9700 void DataArrayInt::computeOffsets2()
9701 {
9702   checkAllocated();
9703   if(getNumberOfComponents()!=1)
9704     throw INTERP_KERNEL::Exception("DataArrayInt::computeOffsets2 : only single component allowed !");
9705   int nbOfTuples=getNumberOfTuples();
9706   int *ret=(int *)malloc((nbOfTuples+1)*sizeof(int));
9707   if(nbOfTuples==0)
9708     return ;
9709   const int *work=getConstPointer();
9710   ret[0]=0;
9711   for(int i=0;i<nbOfTuples;i++)
9712     ret[i+1]=work[i]+ret[i];
9713   useArray(ret,true,C_DEALLOC,nbOfTuples+1,1);
9714   declareAsNew();
9715 }
9716
9717 /*!
9718  * Returns two new DataArrayInt instances whose contents is computed from that of \a this and \a listOfIds arrays as follows.
9719  * \a this is expected to be an offset format ( as returned by DataArrayInt::computeOffsets2 ) that is to say with one component
9720  * and ** sorted strictly increasingly **. \a listOfIds is expected to be sorted ascendingly (not strictly needed for \a listOfIds).
9721  * This methods searches in \a this, considered as a set of contiguous \c this->getNumberOfComponents() ranges, all ids in \a listOfIds
9722  * filling completely one of the ranges in \a this.
9723  *
9724  * \param [in] listOfIds a list of ids that has to be sorted ascendingly.
9725  * \param [out] rangeIdsFetched the range ids fetched
9726  * \param [out] idsInInputListThatFetch contains the list of ids in \a listOfIds that are \b fully included in a range in \a this. So
9727  *              \a idsInInputListThatFetch is a part of input \a listOfIds.
9728  *
9729  * \sa DataArrayInt::computeOffsets2
9730  *
9731  *  \b Example: <br>
9732  *          - \a this : [0,3,7,9,15,18]
9733  *          - \a listOfIds contains  [0,1,2,3,7,8,15,16,17]
9734  *          - \a rangeIdsFetched result array: [0,2,4]
9735  *          - \a idsInInputListThatFetch result array: [0,1,2,7,8,15,16,17]
9736  * In this example id 3 in input \a listOfIds is alone so it do not appear in output \a idsInInputListThatFetch.
9737  * <br>
9738  */
9739 void DataArrayInt::searchRangesInListOfIds(const DataArrayInt *listOfIds, DataArrayInt *& rangeIdsFetched, DataArrayInt *& idsInInputListThatFetch) const
9740 {
9741   if(!listOfIds)
9742     throw INTERP_KERNEL::Exception("DataArrayInt::searchRangesInListOfIds : input list of ids is null !");
9743   listOfIds->checkAllocated(); checkAllocated();
9744   if(listOfIds->getNumberOfComponents()!=1)
9745     throw INTERP_KERNEL::Exception("DataArrayInt::searchRangesInListOfIds : input list of ids must have exactly one component !");
9746   if(getNumberOfComponents()!=1)
9747     throw INTERP_KERNEL::Exception("DataArrayInt::searchRangesInListOfIds : this must have exactly one component !");
9748   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret0=DataArrayInt::New(); ret0->alloc(0,1);
9749   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret1=DataArrayInt::New(); ret1->alloc(0,1);
9750   const int *tupEnd(listOfIds->end()),*offBg(begin()),*offEnd(end()-1);
9751   const int *tupPtr(listOfIds->begin()),*offPtr(offBg);
9752   while(tupPtr!=tupEnd && offPtr!=offEnd)
9753     {
9754       if(*tupPtr==*offPtr)
9755         {
9756           int i=offPtr[0];
9757           while(i<offPtr[1] && *tupPtr==i && tupPtr!=tupEnd) { i++; tupPtr++; }
9758           if(i==offPtr[1])
9759             {
9760               ret0->pushBackSilent((int)std::distance(offBg,offPtr));
9761               ret1->pushBackValsSilent(tupPtr-(offPtr[1]-offPtr[0]),tupPtr);
9762               offPtr++;
9763             }
9764         }
9765       else
9766         { if(*tupPtr<*offPtr) tupPtr++; else offPtr++; }
9767     }
9768   rangeIdsFetched=ret0.retn();
9769   idsInInputListThatFetch=ret1.retn();
9770 }
9771
9772 /*!
9773  * Returns a new DataArrayInt whose contents is computed from that of \a this and \a
9774  * offsets arrays as follows. \a offsets is a one-dimensional array considered as an
9775  * "index" array of a "iota" array, thus, whose each element gives an index of a group
9776  * beginning within the "iota" array. And \a this is a one-dimensional array
9777  * considered as a selector of groups described by \a offsets to include into the result array.
9778  *  \throw If \a offsets is NULL.
9779  *  \throw If \a offsets is not allocated.
9780  *  \throw If \a offsets->getNumberOfComponents() != 1.
9781  *  \throw If \a offsets is not monotonically increasing.
9782  *  \throw If \a this is not allocated.
9783  *  \throw If \a this->getNumberOfComponents() != 1.
9784  *  \throw If any element of \a this is not a valid index for \a offsets array.
9785  *
9786  *  \b Example: <br>
9787  *          - \a this: [0,2,3]
9788  *          - \a offsets: [0,3,6,10,14,20]
9789  *          - result array: [0,1,2,6,7,8,9,10,11,12,13] == <br>
9790  *            \c range(0,3) + \c range(6,10) + \c range(10,14) ==<br>
9791  *            \c range( \a offsets[ \a this[0] ], offsets[ \a this[0]+1 ]) + 
9792  *            \c range( \a offsets[ \a this[1] ], offsets[ \a this[1]+1 ]) + 
9793  *            \c range( \a offsets[ \a this[2] ], offsets[ \a this[2]+1 ])
9794  */
9795 DataArrayInt *DataArrayInt::buildExplicitArrByRanges(const DataArrayInt *offsets) const
9796 {
9797   if(!offsets)
9798     throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrByRanges : DataArrayInt pointer in input is NULL !");
9799   checkAllocated();
9800   if(getNumberOfComponents()!=1)
9801      throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrByRanges : only single component allowed !");
9802   offsets->checkAllocated();
9803   if(offsets->getNumberOfComponents()!=1)
9804      throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrByRanges : input array should have only single component !");
9805   int othNbTuples=offsets->getNumberOfTuples()-1;
9806   int nbOfTuples=getNumberOfTuples();
9807   int retNbOftuples=0;
9808   const int *work=getConstPointer();
9809   const int *offPtr=offsets->getConstPointer();
9810   for(int i=0;i<nbOfTuples;i++)
9811     {
9812       int val=work[i];
9813       if(val>=0 && val<othNbTuples)
9814         {
9815           int delta=offPtr[val+1]-offPtr[val];
9816           if(delta>=0)
9817             retNbOftuples+=delta;
9818           else
9819             {
9820               std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrByRanges : Tuple #" << val << " of offset array has a delta < 0 !";
9821               throw INTERP_KERNEL::Exception(oss.str().c_str());
9822             }
9823         }
9824       else
9825         {
9826           std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrByRanges : Tuple #" << i << " in this contains " << val;
9827           oss << " whereas offsets array is of size " << othNbTuples+1 << " !";
9828           throw INTERP_KERNEL::Exception(oss.str().c_str());
9829         }
9830     }
9831   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
9832   ret->alloc(retNbOftuples,1);
9833   int *retPtr=ret->getPointer();
9834   for(int i=0;i<nbOfTuples;i++)
9835     {
9836       int val=work[i];
9837       int start=offPtr[val];
9838       int off=offPtr[val+1]-start;
9839       for(int j=0;j<off;j++,retPtr++)
9840         *retPtr=start+j;
9841     }
9842   return ret.retn();
9843 }
9844
9845 /*!
9846  * Returns a new DataArrayInt whose contents is computed using \a this that must be a 
9847  * scaled array (monotonically increasing).
9848 from that of \a this and \a
9849  * offsets arrays as follows. \a offsets is a one-dimensional array considered as an
9850  * "index" array of a "iota" array, thus, whose each element gives an index of a group
9851  * beginning within the "iota" array. And \a this is a one-dimensional array
9852  * considered as a selector of groups described by \a offsets to include into the result array.
9853  *  \throw If \a  is NULL.
9854  *  \throw If \a this is not allocated.
9855  *  \throw If \a this->getNumberOfComponents() != 1.
9856  *  \throw If \a this->getNumberOfTuples() == 0.
9857  *  \throw If \a this is not monotonically increasing.
9858  *  \throw If any element of ids in ( \a bg \a stop \a step ) points outside the scale in \a this.
9859  *
9860  *  \b Example: <br>
9861  *          - \a bg , \a stop and \a step : (0,5,2)
9862  *          - \a this: [0,3,6,10,14,20]
9863  *          - result array: [0,0,0, 2,2,2,2, 4,4,4,4,4,4] == <br>
9864  */
9865 DataArrayInt *DataArrayInt::buildExplicitArrOfSliceOnScaledArr(int bg, int stop, int step) const
9866 {
9867   if(!isAllocated())
9868     throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrOfSliceOnScaledArr : not allocated array !");
9869   if(getNumberOfComponents()!=1)
9870     throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrOfSliceOnScaledArr : number of components is expected to be equal to one !");
9871   int nbOfTuples(getNumberOfTuples());
9872   if(nbOfTuples==0)
9873     throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrOfSliceOnScaledArr : number of tuples must be != 0 !");
9874   const int *ids(begin());
9875   int nbOfEltsInSlc(GetNumberOfItemGivenBESRelative(bg,stop,step,"DataArrayInt::buildExplicitArrOfSliceOnScaledArr")),sz(0),pos(bg);
9876   for(int i=0;i<nbOfEltsInSlc;i++,pos+=step)
9877     {
9878       if(pos>=0 && pos<nbOfTuples-1)
9879         {
9880           int delta(ids[pos+1]-ids[pos]);
9881           sz+=delta;
9882           if(delta<0)
9883             {
9884               std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrOfSliceOnScaledArr : At pos #" << i << " of input slice, value is " << pos << " and at this pos this is not monotonically increasing !";
9885               throw INTERP_KERNEL::Exception(oss.str().c_str());
9886             }          
9887         }
9888       else
9889         {
9890           std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrOfSliceOnScaledArr : At pos #" << i << " of input slice, value is " << pos << " should be in [0," << nbOfTuples-1 << ") !";  
9891           throw INTERP_KERNEL::Exception(oss.str().c_str());
9892         }
9893     }
9894   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(sz,1);
9895   int *retPtr(ret->getPointer());
9896   pos=bg;
9897   for(int i=0;i<nbOfEltsInSlc;i++,pos+=step)
9898     {
9899       int delta(ids[pos+1]-ids[pos]);
9900       for(int j=0;j<delta;j++,retPtr++)
9901         *retPtr=pos;
9902     }
9903   return ret.retn();
9904 }
9905
9906 /*!
9907  * 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.
9908  * 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
9909  * in tuple **i** of returned DataArrayInt.
9910  * If ranges overlapped (in theory it should not) this method do not detect it and always returns the first range.
9911  *
9912  * 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)]
9913  * The return DataArrayInt will contain : **[0,4,1,2,2,3]**
9914  * 
9915  * \param [in] ranges typically come from output of MEDCouplingUMesh::ComputeRangesFromTypeDistribution. Each range is specified like this : 1st component is
9916  *             for lower value included and 2nd component is the upper value of corresponding range **excluded**.
9917  * \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
9918  *        is thrown if no ranges in \a ranges contains value in \a this.
9919  * 
9920  * \sa DataArrayInt::findIdInRangeForEachTuple
9921  */
9922 DataArrayInt *DataArrayInt::findRangeIdForEachTuple(const DataArrayInt *ranges) const
9923 {
9924   if(!ranges)
9925     throw INTERP_KERNEL::Exception("DataArrayInt::findRangeIdForEachTuple : null input pointer !");
9926   if(ranges->getNumberOfComponents()!=2)
9927     throw INTERP_KERNEL::Exception("DataArrayInt::findRangeIdForEachTuple : input DataArrayInt instance should have 2 components !");
9928   checkAllocated();
9929   if(getNumberOfComponents()!=1)
9930     throw INTERP_KERNEL::Exception("DataArrayInt::findRangeIdForEachTuple : this should have only one component !");
9931   int nbTuples=getNumberOfTuples();
9932   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbTuples,1);
9933   int nbOfRanges=ranges->getNumberOfTuples();
9934   const int *rangesPtr=ranges->getConstPointer();
9935   int *retPtr=ret->getPointer();
9936   const int *inPtr=getConstPointer();
9937   for(int i=0;i<nbTuples;i++,retPtr++)
9938     {
9939       int val=inPtr[i];
9940       bool found=false;
9941       for(int j=0;j<nbOfRanges && !found;j++)
9942         if(val>=rangesPtr[2*j] && val<rangesPtr[2*j+1])
9943           { *retPtr=j; found=true; }
9944       if(found)
9945         continue;
9946       else
9947         {
9948           std::ostringstream oss; oss << "DataArrayInt::findRangeIdForEachTuple : tuple #" << i << " not found by any ranges !";
9949           throw INTERP_KERNEL::Exception(oss.str().c_str());
9950         }
9951     }
9952   return ret.retn();
9953 }
9954
9955 /*!
9956  * 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.
9957  * 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
9958  * in tuple **i** of returned DataArrayInt.
9959  * If ranges overlapped (in theory it should not) this method do not detect it and always returns the sub position of the first range.
9960  *
9961  * 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)]
9962  * The return DataArrayInt will contain : **[1,2,4,0,2,2]**
9963  * This method is often called in pair with DataArrayInt::findRangeIdForEachTuple method.
9964  * 
9965  * \param [in] ranges typically come from output of MEDCouplingUMesh::ComputeRangesFromTypeDistribution. Each range is specified like this : 1st component is
9966  *             for lower value included and 2nd component is the upper value of corresponding range **excluded**.
9967  * \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
9968  *        is thrown if no ranges in \a ranges contains value in \a this.
9969  * \sa DataArrayInt::findRangeIdForEachTuple
9970  */
9971 DataArrayInt *DataArrayInt::findIdInRangeForEachTuple(const DataArrayInt *ranges) const
9972 {
9973   if(!ranges)
9974     throw INTERP_KERNEL::Exception("DataArrayInt::findIdInRangeForEachTuple : null input pointer !");
9975   if(ranges->getNumberOfComponents()!=2)
9976     throw INTERP_KERNEL::Exception("DataArrayInt::findIdInRangeForEachTuple : input DataArrayInt instance should have 2 components !");
9977   checkAllocated();
9978   if(getNumberOfComponents()!=1)
9979     throw INTERP_KERNEL::Exception("DataArrayInt::findIdInRangeForEachTuple : this should have only one component !");
9980   int nbTuples=getNumberOfTuples();
9981   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbTuples,1);
9982   int nbOfRanges=ranges->getNumberOfTuples();
9983   const int *rangesPtr=ranges->getConstPointer();
9984   int *retPtr=ret->getPointer();
9985   const int *inPtr=getConstPointer();
9986   for(int i=0;i<nbTuples;i++,retPtr++)
9987     {
9988       int val=inPtr[i];
9989       bool found=false;
9990       for(int j=0;j<nbOfRanges && !found;j++)
9991         if(val>=rangesPtr[2*j] && val<rangesPtr[2*j+1])
9992           { *retPtr=val-rangesPtr[2*j]; found=true; }
9993       if(found)
9994         continue;
9995       else
9996         {
9997           std::ostringstream oss; oss << "DataArrayInt::findIdInRangeForEachTuple : tuple #" << i << " not found by any ranges !";
9998           throw INTERP_KERNEL::Exception(oss.str().c_str());
9999         }
10000     }
10001   return ret.retn();
10002 }
10003
10004 /*!
10005  * 
10006  * \param [in] nbTimes specifies the nb of times each tuples in \a this will be duplicated contiguouly in returned DataArrayInt instance.
10007  *             \a nbTimes  should be at least equal to 1.
10008  * \return a newly allocated DataArrayInt having one component and number of tuples equal to \a nbTimes * \c this->getNumberOfTuples.
10009  * \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.
10010  */
10011 DataArrayInt *DataArrayInt::duplicateEachTupleNTimes(int nbTimes) const
10012 {
10013   checkAllocated();
10014   if(getNumberOfComponents()!=1)
10015     throw INTERP_KERNEL::Exception("DataArrayInt::duplicateEachTupleNTimes : this should have only one component !");
10016   if(nbTimes<1)
10017     throw INTERP_KERNEL::Exception("DataArrayInt::duplicateEachTupleNTimes : nb times should be >= 1 !");
10018   int nbTuples=getNumberOfTuples();
10019   const int *inPtr=getConstPointer();
10020   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbTimes*nbTuples,1);
10021   int *retPtr=ret->getPointer();
10022   for(int i=0;i<nbTuples;i++,inPtr++)
10023     {
10024       int val=*inPtr;
10025       for(int j=0;j<nbTimes;j++,retPtr++)
10026         *retPtr=val;
10027     }
10028   ret->copyStringInfoFrom(*this);
10029   return ret.retn();
10030 }
10031
10032 /*!
10033  * This method returns all different values found in \a this. This method throws if \a this has not been allocated.
10034  * But the number of components can be different from one.
10035  * \return a newly allocated array (that should be dealt by the caller) containing different values in \a this.
10036  */
10037 DataArrayInt *DataArrayInt::getDifferentValues() const
10038 {
10039   checkAllocated();
10040   std::set<int> ret;
10041   ret.insert(begin(),end());
10042   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret2=DataArrayInt::New(); ret2->alloc((int)ret.size(),1);
10043   std::copy(ret.begin(),ret.end(),ret2->getPointer());
10044   return ret2.retn();
10045 }
10046
10047 /*!
10048  * This method is a refinement of DataArrayInt::getDifferentValues because it returns not only different values in \a this but also, for each of
10049  * them it tells which tuple id have this id.
10050  * This method works only on arrays with one component (if it is not the case call DataArrayInt::rearrange(1) ).
10051  * This method returns two arrays having same size.
10052  * 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.
10053  * 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]]
10054  */
10055 std::vector<DataArrayInt *> DataArrayInt::partitionByDifferentValues(std::vector<int>& differentIds) const
10056 {
10057   checkAllocated();
10058   if(getNumberOfComponents()!=1)
10059     throw INTERP_KERNEL::Exception("DataArrayInt::partitionByDifferentValues : this should have only one component !");
10060   int id=0;
10061   std::map<int,int> m,m2,m3;
10062   for(const int *w=begin();w!=end();w++)
10063     m[*w]++;
10064   differentIds.resize(m.size());
10065   std::vector<DataArrayInt *> ret(m.size());
10066   std::vector<int *> retPtr(m.size());
10067   for(std::map<int,int>::const_iterator it=m.begin();it!=m.end();it++,id++)
10068     {
10069       m2[(*it).first]=id;
10070       ret[id]=DataArrayInt::New();
10071       ret[id]->alloc((*it).second,1);
10072       retPtr[id]=ret[id]->getPointer();
10073       differentIds[id]=(*it).first;
10074     }
10075   id=0;
10076   for(const int *w=begin();w!=end();w++,id++)
10077     {
10078       retPtr[m2[*w]][m3[*w]++]=id;
10079     }
10080   return ret;
10081 }
10082
10083 /*!
10084  * This method split ids in [0, \c this->getNumberOfTuples() ) using \a this array as a field of weight (>=0 each).
10085  * The aim of this method is to return a set of \a nbOfSlices chunk of contiguous ids as balanced as possible.
10086  *
10087  * \param [in] nbOfSlices - number of slices expected.
10088  * \return - a vector having a size equal to \a nbOfSlices giving the start (included) and the stop (excluded) of each chunks.
10089  * 
10090  * \sa DataArray::GetSlice
10091  * \throw If \a this is not allocated or not with exactly one component.
10092  * \throw If an element in \a this if < 0.
10093  */
10094 std::vector< std::pair<int,int> > DataArrayInt::splitInBalancedSlices(int nbOfSlices) const
10095 {
10096   if(!isAllocated() || getNumberOfComponents()!=1)
10097     throw INTERP_KERNEL::Exception("DataArrayInt::splitInBalancedSlices : this array should have number of components equal to one and must be allocated !");
10098   if(nbOfSlices<=0)
10099     throw INTERP_KERNEL::Exception("DataArrayInt::splitInBalancedSlices : number of slices must be >= 1 !");
10100   int sum(accumulate(0)),nbOfTuples(getNumberOfTuples());
10101   int sumPerSlc(sum/nbOfSlices),pos(0);
10102   const int *w(begin());
10103   std::vector< std::pair<int,int> > ret(nbOfSlices);
10104   for(int i=0;i<nbOfSlices;i++)
10105     {
10106       std::pair<int,int> p(pos,-1);
10107       int locSum(0);
10108       while(locSum<sumPerSlc && pos<nbOfTuples) { pos++; locSum+=*w++; }
10109       if(i!=nbOfSlices-1)
10110         p.second=pos;
10111       else
10112         p.second=nbOfTuples;
10113       ret[i]=p;
10114     }
10115   return ret;
10116 }
10117
10118 /*!
10119  * Returns a new DataArrayInt that is a sum of two given arrays. There are 3
10120  * valid cases.
10121  * 1.  The arrays have same number of tuples and components. Then each value of
10122  *   the result array (_a_) is a sum of the corresponding values of \a a1 and \a a2,
10123  *   i.e.: _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ i, j ].
10124  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
10125  *   component. Then
10126  *   _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ i, 0 ].
10127  * 3.  The arrays have same number of components and one array, say _a2_, has one
10128  *   tuple. Then
10129  *   _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ 0, j ].
10130  *
10131  * Info on components is copied either from the first array (in the first case) or from
10132  * the array with maximal number of elements (getNbOfElems()).
10133  *  \param [in] a1 - an array to sum up.
10134  *  \param [in] a2 - another array to sum up.
10135  *  \return DataArrayInt * - the new instance of DataArrayInt.
10136  *          The caller is to delete this result array using decrRef() as it is no more
10137  *          needed.
10138  *  \throw If either \a a1 or \a a2 is NULL.
10139  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
10140  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
10141  *         none of them has number of tuples or components equal to 1.
10142  */
10143 DataArrayInt *DataArrayInt::Add(const DataArrayInt *a1, const DataArrayInt *a2)
10144 {
10145   if(!a1 || !a2)
10146     throw INTERP_KERNEL::Exception("DataArrayInt::Add : input DataArrayInt instance is NULL !");
10147   int nbOfTuple=a1->getNumberOfTuples();
10148   int nbOfTuple2=a2->getNumberOfTuples();
10149   int nbOfComp=a1->getNumberOfComponents();
10150   int nbOfComp2=a2->getNumberOfComponents();
10151   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=0;
10152   if(nbOfTuple==nbOfTuple2)
10153     {
10154       if(nbOfComp==nbOfComp2)
10155         {
10156           ret=DataArrayInt::New();
10157           ret->alloc(nbOfTuple,nbOfComp);
10158           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::plus<int>());
10159           ret->copyStringInfoFrom(*a1);
10160         }
10161       else
10162         {
10163           int nbOfCompMin,nbOfCompMax;
10164           const DataArrayInt *aMin, *aMax;
10165           if(nbOfComp>nbOfComp2)
10166             {
10167               nbOfCompMin=nbOfComp2; nbOfCompMax=nbOfComp;
10168               aMin=a2; aMax=a1;
10169             }
10170           else
10171             {
10172               nbOfCompMin=nbOfComp; nbOfCompMax=nbOfComp2;
10173               aMin=a1; aMax=a2;
10174             }
10175           if(nbOfCompMin==1)
10176             {
10177               ret=DataArrayInt::New();
10178               ret->alloc(nbOfTuple,nbOfCompMax);
10179               const int *aMinPtr=aMin->getConstPointer();
10180               const int *aMaxPtr=aMax->getConstPointer();
10181               int *res=ret->getPointer();
10182               for(int i=0;i<nbOfTuple;i++)
10183                 res=std::transform(aMaxPtr+i*nbOfCompMax,aMaxPtr+(i+1)*nbOfCompMax,res,std::bind2nd(std::plus<int>(),aMinPtr[i]));
10184               ret->copyStringInfoFrom(*aMax);
10185             }
10186           else
10187             throw INTERP_KERNEL::Exception("Nb of components mismatch for array Add !");
10188         }
10189     }
10190   else if((nbOfTuple==1 && nbOfTuple2>1) || (nbOfTuple>1 && nbOfTuple2==1))
10191     {
10192       if(nbOfComp==nbOfComp2)
10193         {
10194           int nbOfTupleMax=std::max(nbOfTuple,nbOfTuple2);
10195           const DataArrayInt *aMin=nbOfTuple>nbOfTuple2?a2:a1;
10196           const DataArrayInt *aMax=nbOfTuple>nbOfTuple2?a1:a2;
10197           const int *aMinPtr=aMin->getConstPointer(),*aMaxPtr=aMax->getConstPointer();
10198           ret=DataArrayInt::New();
10199           ret->alloc(nbOfTupleMax,nbOfComp);
10200           int *res=ret->getPointer();
10201           for(int i=0;i<nbOfTupleMax;i++)
10202             res=std::transform(aMaxPtr+i*nbOfComp,aMaxPtr+(i+1)*nbOfComp,aMinPtr,res,std::plus<int>());
10203           ret->copyStringInfoFrom(*aMax);
10204         }
10205       else
10206         throw INTERP_KERNEL::Exception("Nb of components mismatch for array Add !");
10207     }
10208   else
10209     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Add !");
10210   return ret.retn();
10211 }
10212
10213 /*!
10214  * Adds values of another DataArrayInt to values of \a this one. There are 3
10215  * valid cases.
10216  * 1.  The arrays have same number of tuples and components. Then each value of
10217  *   \a other array is added to the corresponding value of \a this array, i.e.:
10218  *   _a_ [ i, j ] += _other_ [ i, j ].
10219  * 2.  The arrays have same number of tuples and \a other array has one component. Then
10220  *   _a_ [ i, j ] += _other_ [ i, 0 ].
10221  * 3.  The arrays have same number of components and \a other array has one tuple. Then
10222  *   _a_ [ i, j ] += _a2_ [ 0, j ].
10223  *
10224  *  \param [in] other - an array to add to \a this one.
10225  *  \throw If \a other is NULL.
10226  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
10227  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
10228  *         \a other has number of both tuples and components not equal to 1.
10229  */
10230 void DataArrayInt::addEqual(const DataArrayInt *other)
10231 {
10232   if(!other)
10233     throw INTERP_KERNEL::Exception("DataArrayInt::addEqual : input DataArrayInt instance is NULL !");
10234   const char *msg="Nb of tuples mismatch for DataArrayInt::addEqual  !";
10235   checkAllocated(); other->checkAllocated();
10236   int nbOfTuple=getNumberOfTuples();
10237   int nbOfTuple2=other->getNumberOfTuples();
10238   int nbOfComp=getNumberOfComponents();
10239   int nbOfComp2=other->getNumberOfComponents();
10240   if(nbOfTuple==nbOfTuple2)
10241     {
10242       if(nbOfComp==nbOfComp2)
10243         {
10244           std::transform(begin(),end(),other->begin(),getPointer(),std::plus<int>());
10245         }
10246       else if(nbOfComp2==1)
10247         {
10248           int *ptr=getPointer();
10249           const int *ptrc=other->getConstPointer();
10250           for(int i=0;i<nbOfTuple;i++)
10251             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::plus<int>(),*ptrc++));
10252         }
10253       else
10254         throw INTERP_KERNEL::Exception(msg);
10255     }
10256   else if(nbOfTuple2==1)
10257     {
10258       if(nbOfComp2==nbOfComp)
10259         {
10260           int *ptr=getPointer();
10261           const int *ptrc=other->getConstPointer();
10262           for(int i=0;i<nbOfTuple;i++)
10263             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::plus<int>());
10264         }
10265       else
10266         throw INTERP_KERNEL::Exception(msg);
10267     }
10268   else
10269     throw INTERP_KERNEL::Exception(msg);
10270   declareAsNew();
10271 }
10272
10273 /*!
10274  * Returns a new DataArrayInt that is a subtraction of two given arrays. There are 3
10275  * valid cases.
10276  * 1.  The arrays have same number of tuples and components. Then each value of
10277  *   the result array (_a_) is a subtraction of the corresponding values of \a a1 and
10278  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ i, j ].
10279  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
10280  *   component. Then
10281  *   _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ i, 0 ].
10282  * 3.  The arrays have same number of components and one array, say _a2_, has one
10283  *   tuple. Then
10284  *   _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ 0, j ].
10285  *
10286  * Info on components is copied either from the first array (in the first case) or from
10287  * the array with maximal number of elements (getNbOfElems()).
10288  *  \param [in] a1 - an array to subtract from.
10289  *  \param [in] a2 - an array to subtract.
10290  *  \return DataArrayInt * - the new instance of DataArrayInt.
10291  *          The caller is to delete this result array using decrRef() as it is no more
10292  *          needed.
10293  *  \throw If either \a a1 or \a a2 is NULL.
10294  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
10295  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
10296  *         none of them has number of tuples or components equal to 1.
10297  */
10298 DataArrayInt *DataArrayInt::Substract(const DataArrayInt *a1, const DataArrayInt *a2)
10299 {
10300   if(!a1 || !a2)
10301     throw INTERP_KERNEL::Exception("DataArrayInt::Substract : input DataArrayInt instance is NULL !");
10302   int nbOfTuple1=a1->getNumberOfTuples();
10303   int nbOfTuple2=a2->getNumberOfTuples();
10304   int nbOfComp1=a1->getNumberOfComponents();
10305   int nbOfComp2=a2->getNumberOfComponents();
10306   if(nbOfTuple2==nbOfTuple1)
10307     {
10308       if(nbOfComp1==nbOfComp2)
10309         {
10310           MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
10311           ret->alloc(nbOfTuple2,nbOfComp1);
10312           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::minus<int>());
10313           ret->copyStringInfoFrom(*a1);
10314           return ret.retn();
10315         }
10316       else if(nbOfComp2==1)
10317         {
10318           MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
10319           ret->alloc(nbOfTuple1,nbOfComp1);
10320           const int *a2Ptr=a2->getConstPointer();
10321           const int *a1Ptr=a1->getConstPointer();
10322           int *res=ret->getPointer();
10323           for(int i=0;i<nbOfTuple1;i++)
10324             res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::minus<int>(),a2Ptr[i]));
10325           ret->copyStringInfoFrom(*a1);
10326           return ret.retn();
10327         }
10328       else
10329         {
10330           a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Substract !");
10331           return 0;
10332         }
10333     }
10334   else if(nbOfTuple2==1)
10335     {
10336       a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Substract !");
10337       MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
10338       ret->alloc(nbOfTuple1,nbOfComp1);
10339       const int *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
10340       int *pt=ret->getPointer();
10341       for(int i=0;i<nbOfTuple1;i++)
10342         pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::minus<int>());
10343       ret->copyStringInfoFrom(*a1);
10344       return ret.retn();
10345     }
10346   else
10347     {
10348       a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Substract !");//will always throw an exception
10349       return 0;
10350     }
10351 }
10352
10353 /*!
10354  * Subtract values of another DataArrayInt from values of \a this one. There are 3
10355  * valid cases.
10356  * 1.  The arrays have same number of tuples and components. Then each value of
10357  *   \a other array is subtracted from the corresponding value of \a this array, i.e.:
10358  *   _a_ [ i, j ] -= _other_ [ i, j ].
10359  * 2.  The arrays have same number of tuples and \a other array has one component. Then
10360  *   _a_ [ i, j ] -= _other_ [ i, 0 ].
10361  * 3.  The arrays have same number of components and \a other array has one tuple. Then
10362  *   _a_ [ i, j ] -= _a2_ [ 0, j ].
10363  *
10364  *  \param [in] other - an array to subtract from \a this one.
10365  *  \throw If \a other is NULL.
10366  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
10367  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
10368  *         \a other has number of both tuples and components not equal to 1.
10369  */
10370 void DataArrayInt::substractEqual(const DataArrayInt *other)
10371 {
10372   if(!other)
10373     throw INTERP_KERNEL::Exception("DataArrayInt::substractEqual : input DataArrayInt instance is NULL !");
10374   const char *msg="Nb of tuples mismatch for DataArrayInt::substractEqual  !";
10375   checkAllocated(); other->checkAllocated();
10376   int nbOfTuple=getNumberOfTuples();
10377   int nbOfTuple2=other->getNumberOfTuples();
10378   int nbOfComp=getNumberOfComponents();
10379   int nbOfComp2=other->getNumberOfComponents();
10380   if(nbOfTuple==nbOfTuple2)
10381     {
10382       if(nbOfComp==nbOfComp2)
10383         {
10384           std::transform(begin(),end(),other->begin(),getPointer(),std::minus<int>());
10385         }
10386       else if(nbOfComp2==1)
10387         {
10388           int *ptr=getPointer();
10389           const int *ptrc=other->getConstPointer();
10390           for(int i=0;i<nbOfTuple;i++)
10391             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::minus<int>(),*ptrc++));
10392         }
10393       else
10394         throw INTERP_KERNEL::Exception(msg);
10395     }
10396   else if(nbOfTuple2==1)
10397     {
10398       int *ptr=getPointer();
10399       const int *ptrc=other->getConstPointer();
10400       for(int i=0;i<nbOfTuple;i++)
10401         std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::minus<int>());
10402     }
10403   else
10404     throw INTERP_KERNEL::Exception(msg);
10405   declareAsNew();
10406 }
10407
10408 /*!
10409  * Returns a new DataArrayInt that is a product of two given arrays. There are 3
10410  * valid cases.
10411  * 1.  The arrays have same number of tuples and components. Then each value of
10412  *   the result array (_a_) is a product of the corresponding values of \a a1 and
10413  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ i, j ].
10414  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
10415  *   component. Then
10416  *   _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ i, 0 ].
10417  * 3.  The arrays have same number of components and one array, say _a2_, has one
10418  *   tuple. Then
10419  *   _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ 0, j ].
10420  *
10421  * Info on components is copied either from the first array (in the first case) or from
10422  * the array with maximal number of elements (getNbOfElems()).
10423  *  \param [in] a1 - a factor array.
10424  *  \param [in] a2 - another factor array.
10425  *  \return DataArrayInt * - the new instance of DataArrayInt.
10426  *          The caller is to delete this result array using decrRef() as it is no more
10427  *          needed.
10428  *  \throw If either \a a1 or \a a2 is NULL.
10429  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
10430  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
10431  *         none of them has number of tuples or components equal to 1.
10432  */
10433 DataArrayInt *DataArrayInt::Multiply(const DataArrayInt *a1, const DataArrayInt *a2)
10434 {
10435   if(!a1 || !a2)
10436     throw INTERP_KERNEL::Exception("DataArrayInt::Multiply : input DataArrayInt instance is NULL !");
10437   int nbOfTuple=a1->getNumberOfTuples();
10438   int nbOfTuple2=a2->getNumberOfTuples();
10439   int nbOfComp=a1->getNumberOfComponents();
10440   int nbOfComp2=a2->getNumberOfComponents();
10441   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=0;
10442   if(nbOfTuple==nbOfTuple2)
10443     {
10444       if(nbOfComp==nbOfComp2)
10445         {
10446           ret=DataArrayInt::New();
10447           ret->alloc(nbOfTuple,nbOfComp);
10448           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::multiplies<int>());
10449           ret->copyStringInfoFrom(*a1);
10450         }
10451       else
10452         {
10453           int nbOfCompMin,nbOfCompMax;
10454           const DataArrayInt *aMin, *aMax;
10455           if(nbOfComp>nbOfComp2)
10456             {
10457               nbOfCompMin=nbOfComp2; nbOfCompMax=nbOfComp;
10458               aMin=a2; aMax=a1;
10459             }
10460           else
10461             {
10462               nbOfCompMin=nbOfComp; nbOfCompMax=nbOfComp2;
10463               aMin=a1; aMax=a2;
10464             }
10465           if(nbOfCompMin==1)
10466             {
10467               ret=DataArrayInt::New();
10468               ret->alloc(nbOfTuple,nbOfCompMax);
10469               const int *aMinPtr=aMin->getConstPointer();
10470               const int *aMaxPtr=aMax->getConstPointer();
10471               int *res=ret->getPointer();
10472               for(int i=0;i<nbOfTuple;i++)
10473                 res=std::transform(aMaxPtr+i*nbOfCompMax,aMaxPtr+(i+1)*nbOfCompMax,res,std::bind2nd(std::multiplies<int>(),aMinPtr[i]));
10474               ret->copyStringInfoFrom(*aMax);
10475             }
10476           else
10477             throw INTERP_KERNEL::Exception("Nb of components mismatch for array Multiply !");
10478         }
10479     }
10480   else if((nbOfTuple==1 && nbOfTuple2>1) || (nbOfTuple>1 && nbOfTuple2==1))
10481     {
10482       if(nbOfComp==nbOfComp2)
10483         {
10484           int nbOfTupleMax=std::max(nbOfTuple,nbOfTuple2);
10485           const DataArrayInt *aMin=nbOfTuple>nbOfTuple2?a2:a1;
10486           const DataArrayInt *aMax=nbOfTuple>nbOfTuple2?a1:a2;
10487           const int *aMinPtr=aMin->getConstPointer(),*aMaxPtr=aMax->getConstPointer();
10488           ret=DataArrayInt::New();
10489           ret->alloc(nbOfTupleMax,nbOfComp);
10490           int *res=ret->getPointer();
10491           for(int i=0;i<nbOfTupleMax;i++)
10492             res=std::transform(aMaxPtr+i*nbOfComp,aMaxPtr+(i+1)*nbOfComp,aMinPtr,res,std::multiplies<int>());
10493           ret->copyStringInfoFrom(*aMax);
10494         }
10495       else
10496         throw INTERP_KERNEL::Exception("Nb of components mismatch for array Multiply !");
10497     }
10498   else
10499     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Multiply !");
10500   return ret.retn();
10501 }
10502
10503
10504 /*!
10505  * Multiply values of another DataArrayInt to values of \a this one. There are 3
10506  * valid cases.
10507  * 1.  The arrays have same number of tuples and components. Then each value of
10508  *   \a other array is multiplied to the corresponding value of \a this array, i.e.:
10509  *   _a_ [ i, j ] *= _other_ [ i, j ].
10510  * 2.  The arrays have same number of tuples and \a other array has one component. Then
10511  *   _a_ [ i, j ] *= _other_ [ i, 0 ].
10512  * 3.  The arrays have same number of components and \a other array has one tuple. Then
10513  *   _a_ [ i, j ] *= _a2_ [ 0, j ].
10514  *
10515  *  \param [in] other - an array to multiply to \a this one.
10516  *  \throw If \a other is NULL.
10517  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
10518  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
10519  *         \a other has number of both tuples and components not equal to 1.
10520  */
10521 void DataArrayInt::multiplyEqual(const DataArrayInt *other)
10522 {
10523   if(!other)
10524     throw INTERP_KERNEL::Exception("DataArrayInt::multiplyEqual : input DataArrayInt instance is NULL !");
10525   const char *msg="Nb of tuples mismatch for DataArrayInt::multiplyEqual !";
10526   checkAllocated(); other->checkAllocated();
10527   int nbOfTuple=getNumberOfTuples();
10528   int nbOfTuple2=other->getNumberOfTuples();
10529   int nbOfComp=getNumberOfComponents();
10530   int nbOfComp2=other->getNumberOfComponents();
10531   if(nbOfTuple==nbOfTuple2)
10532     {
10533       if(nbOfComp==nbOfComp2)
10534         {
10535           std::transform(begin(),end(),other->begin(),getPointer(),std::multiplies<int>());
10536         }
10537       else if(nbOfComp2==1)
10538         {
10539           int *ptr=getPointer();
10540           const int *ptrc=other->getConstPointer();
10541           for(int i=0;i<nbOfTuple;i++)
10542             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::multiplies<int>(),*ptrc++));    
10543         }
10544       else
10545         throw INTERP_KERNEL::Exception(msg);
10546     }
10547   else if(nbOfTuple2==1)
10548     {
10549       if(nbOfComp2==nbOfComp)
10550         {
10551           int *ptr=getPointer();
10552           const int *ptrc=other->getConstPointer();
10553           for(int i=0;i<nbOfTuple;i++)
10554             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::multiplies<int>());
10555         }
10556       else
10557         throw INTERP_KERNEL::Exception(msg);
10558     }
10559   else
10560     throw INTERP_KERNEL::Exception(msg);
10561   declareAsNew();
10562 }
10563
10564
10565 /*!
10566  * Returns a new DataArrayInt that is a division of two given arrays. There are 3
10567  * valid cases.
10568  * 1.  The arrays have same number of tuples and components. Then each value of
10569  *   the result array (_a_) is a division of the corresponding values of \a a1 and
10570  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ i, j ].
10571  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
10572  *   component. Then
10573  *   _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ i, 0 ].
10574  * 3.  The arrays have same number of components and one array, say _a2_, has one
10575  *   tuple. Then
10576  *   _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ 0, j ].
10577  *
10578  * Info on components is copied either from the first array (in the first case) or from
10579  * the array with maximal number of elements (getNbOfElems()).
10580  *  \warning No check of division by zero is performed!
10581  *  \param [in] a1 - a numerator array.
10582  *  \param [in] a2 - a denominator array.
10583  *  \return DataArrayInt * - the new instance of DataArrayInt.
10584  *          The caller is to delete this result array using decrRef() as it is no more
10585  *          needed.
10586  *  \throw If either \a a1 or \a a2 is NULL.
10587  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
10588  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
10589  *         none of them has number of tuples or components equal to 1.
10590  */
10591 DataArrayInt *DataArrayInt::Divide(const DataArrayInt *a1, const DataArrayInt *a2)
10592 {
10593   if(!a1 || !a2)
10594     throw INTERP_KERNEL::Exception("DataArrayInt::Divide : input DataArrayInt instance is NULL !");
10595   int nbOfTuple1=a1->getNumberOfTuples();
10596   int nbOfTuple2=a2->getNumberOfTuples();
10597   int nbOfComp1=a1->getNumberOfComponents();
10598   int nbOfComp2=a2->getNumberOfComponents();
10599   if(nbOfTuple2==nbOfTuple1)
10600     {
10601       if(nbOfComp1==nbOfComp2)
10602         {
10603           MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
10604           ret->alloc(nbOfTuple2,nbOfComp1);
10605           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::divides<int>());
10606           ret->copyStringInfoFrom(*a1);
10607           return ret.retn();
10608         }
10609       else if(nbOfComp2==1)
10610         {
10611           MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
10612           ret->alloc(nbOfTuple1,nbOfComp1);
10613           const int *a2Ptr=a2->getConstPointer();
10614           const int *a1Ptr=a1->getConstPointer();
10615           int *res=ret->getPointer();
10616           for(int i=0;i<nbOfTuple1;i++)
10617             res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::divides<int>(),a2Ptr[i]));
10618           ret->copyStringInfoFrom(*a1);
10619           return ret.retn();
10620         }
10621       else
10622         {
10623           a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Divide !");
10624           return 0;
10625         }
10626     }
10627   else if(nbOfTuple2==1)
10628     {
10629       a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Divide !");
10630       MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
10631       ret->alloc(nbOfTuple1,nbOfComp1);
10632       const int *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
10633       int *pt=ret->getPointer();
10634       for(int i=0;i<nbOfTuple1;i++)
10635         pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::divides<int>());
10636       ret->copyStringInfoFrom(*a1);
10637       return ret.retn();
10638     }
10639   else
10640     {
10641       a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Divide !");//will always throw an exception
10642       return 0;
10643     }
10644 }
10645
10646 /*!
10647  * Divide values of \a this array by values of another DataArrayInt. There are 3
10648  * valid cases.
10649  * 1.  The arrays have same number of tuples and components. Then each value of
10650  *    \a this array is divided by the corresponding value of \a other one, i.e.:
10651  *   _a_ [ i, j ] /= _other_ [ i, j ].
10652  * 2.  The arrays have same number of tuples and \a other array has one component. Then
10653  *   _a_ [ i, j ] /= _other_ [ i, 0 ].
10654  * 3.  The arrays have same number of components and \a other array has one tuple. Then
10655  *   _a_ [ i, j ] /= _a2_ [ 0, j ].
10656  *
10657  *  \warning No check of division by zero is performed!
10658  *  \param [in] other - an array to divide \a this one by.
10659  *  \throw If \a other is NULL.
10660  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
10661  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
10662  *         \a other has number of both tuples and components not equal to 1.
10663  */
10664 void DataArrayInt::divideEqual(const DataArrayInt *other)
10665 {
10666   if(!other)
10667     throw INTERP_KERNEL::Exception("DataArrayInt::divideEqual : input DataArrayInt instance is NULL !");
10668   const char *msg="Nb of tuples mismatch for DataArrayInt::divideEqual !";
10669   checkAllocated(); other->checkAllocated();
10670   int nbOfTuple=getNumberOfTuples();
10671   int nbOfTuple2=other->getNumberOfTuples();
10672   int nbOfComp=getNumberOfComponents();
10673   int nbOfComp2=other->getNumberOfComponents();
10674   if(nbOfTuple==nbOfTuple2)
10675     {
10676       if(nbOfComp==nbOfComp2)
10677         {
10678           std::transform(begin(),end(),other->begin(),getPointer(),std::divides<int>());
10679         }
10680       else if(nbOfComp2==1)
10681         {
10682           int *ptr=getPointer();
10683           const int *ptrc=other->getConstPointer();
10684           for(int i=0;i<nbOfTuple;i++)
10685             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::divides<int>(),*ptrc++));
10686         }
10687       else
10688         throw INTERP_KERNEL::Exception(msg);
10689     }
10690   else if(nbOfTuple2==1)
10691     {
10692       if(nbOfComp2==nbOfComp)
10693         {
10694           int *ptr=getPointer();
10695           const int *ptrc=other->getConstPointer();
10696           for(int i=0;i<nbOfTuple;i++)
10697             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::divides<int>());
10698         }
10699       else
10700         throw INTERP_KERNEL::Exception(msg);
10701     }
10702   else
10703     throw INTERP_KERNEL::Exception(msg);
10704   declareAsNew();
10705 }
10706
10707
10708 /*!
10709  * Returns a new DataArrayInt that is a modulus of two given arrays. There are 3
10710  * valid cases.
10711  * 1.  The arrays have same number of tuples and components. Then each value of
10712  *   the result array (_a_) is a division of the corresponding values of \a a1 and
10713  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] % _a2_ [ i, j ].
10714  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
10715  *   component. Then
10716  *   _a_ [ i, j ] = _a1_ [ i, j ] % _a2_ [ i, 0 ].
10717  * 3.  The arrays have same number of components and one array, say _a2_, has one
10718  *   tuple. Then
10719  *   _a_ [ i, j ] = _a1_ [ i, j ] % _a2_ [ 0, j ].
10720  *
10721  * Info on components is copied either from the first array (in the first case) or from
10722  * the array with maximal number of elements (getNbOfElems()).
10723  *  \warning No check of division by zero is performed!
10724  *  \param [in] a1 - a dividend array.
10725  *  \param [in] a2 - a divisor array.
10726  *  \return DataArrayInt * - the new instance of DataArrayInt.
10727  *          The caller is to delete this result array using decrRef() as it is no more
10728  *          needed.
10729  *  \throw If either \a a1 or \a a2 is NULL.
10730  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
10731  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
10732  *         none of them has number of tuples or components equal to 1.
10733  */
10734 DataArrayInt *DataArrayInt::Modulus(const DataArrayInt *a1, const DataArrayInt *a2)
10735 {
10736     if(!a1 || !a2)
10737     throw INTERP_KERNEL::Exception("DataArrayInt::Modulus : input DataArrayInt instance is NULL !");
10738   int nbOfTuple1=a1->getNumberOfTuples();
10739   int nbOfTuple2=a2->getNumberOfTuples();
10740   int nbOfComp1=a1->getNumberOfComponents();
10741   int nbOfComp2=a2->getNumberOfComponents();
10742   if(nbOfTuple2==nbOfTuple1)
10743     {
10744       if(nbOfComp1==nbOfComp2)
10745         {
10746           MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
10747           ret->alloc(nbOfTuple2,nbOfComp1);
10748           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::modulus<int>());
10749           ret->copyStringInfoFrom(*a1);
10750           return ret.retn();
10751         }
10752       else if(nbOfComp2==1)
10753         {
10754           MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
10755           ret->alloc(nbOfTuple1,nbOfComp1);
10756           const int *a2Ptr=a2->getConstPointer();
10757           const int *a1Ptr=a1->getConstPointer();
10758           int *res=ret->getPointer();
10759           for(int i=0;i<nbOfTuple1;i++)
10760             res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::modulus<int>(),a2Ptr[i]));
10761           ret->copyStringInfoFrom(*a1);
10762           return ret.retn();
10763         }
10764       else
10765         {
10766           a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Modulus !");
10767           return 0;
10768         }
10769     }
10770   else if(nbOfTuple2==1)
10771     {
10772       a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Modulus !");
10773       MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
10774       ret->alloc(nbOfTuple1,nbOfComp1);
10775       const int *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
10776       int *pt=ret->getPointer();
10777       for(int i=0;i<nbOfTuple1;i++)
10778         pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::modulus<int>());
10779       ret->copyStringInfoFrom(*a1);
10780       return ret.retn();
10781     }
10782   else
10783     {
10784       a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Modulus !");//will always throw an exception
10785       return 0;
10786     }
10787 }
10788
10789 /*!
10790  * Modify \a this array so that each value becomes a modulus of division of this value by
10791  * a value of another DataArrayInt. There are 3 valid cases.
10792  * 1.  The arrays have same number of tuples and components. Then each value of
10793  *    \a this array is divided by the corresponding value of \a other one, i.e.:
10794  *   _a_ [ i, j ] %= _other_ [ i, j ].
10795  * 2.  The arrays have same number of tuples and \a other array has one component. Then
10796  *   _a_ [ i, j ] %= _other_ [ i, 0 ].
10797  * 3.  The arrays have same number of components and \a other array has one tuple. Then
10798  *   _a_ [ i, j ] %= _a2_ [ 0, j ].
10799  *
10800  *  \warning No check of division by zero is performed!
10801  *  \param [in] other - a divisor array.
10802  *  \throw If \a other is NULL.
10803  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
10804  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
10805  *         \a other has number of both tuples and components not equal to 1.
10806  */
10807 void DataArrayInt::modulusEqual(const DataArrayInt *other)
10808 {
10809   if(!other)
10810     throw INTERP_KERNEL::Exception("DataArrayInt::modulusEqual : input DataArrayInt instance is NULL !");
10811   const char *msg="Nb of tuples mismatch for DataArrayInt::modulusEqual !";
10812   checkAllocated(); other->checkAllocated();
10813   int nbOfTuple=getNumberOfTuples();
10814   int nbOfTuple2=other->getNumberOfTuples();
10815   int nbOfComp=getNumberOfComponents();
10816   int nbOfComp2=other->getNumberOfComponents();
10817   if(nbOfTuple==nbOfTuple2)
10818     {
10819       if(nbOfComp==nbOfComp2)
10820         {
10821           std::transform(begin(),end(),other->begin(),getPointer(),std::modulus<int>());
10822         }
10823       else if(nbOfComp2==1)
10824         {
10825           if(nbOfComp2==nbOfComp)
10826             {
10827               int *ptr=getPointer();
10828               const int *ptrc=other->getConstPointer();
10829               for(int i=0;i<nbOfTuple;i++)
10830                 std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::modulus<int>(),*ptrc++));
10831             }
10832           else
10833             throw INTERP_KERNEL::Exception(msg);
10834         }
10835       else
10836         throw INTERP_KERNEL::Exception(msg);
10837     }
10838   else if(nbOfTuple2==1)
10839     {
10840       int *ptr=getPointer();
10841       const int *ptrc=other->getConstPointer();
10842       for(int i=0;i<nbOfTuple;i++)
10843         std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::modulus<int>());
10844     }
10845   else
10846     throw INTERP_KERNEL::Exception(msg);
10847   declareAsNew();
10848 }
10849
10850 /*!
10851  * Returns a new DataArrayInt that is the result of pow of two given arrays. There are 3
10852  * valid cases.
10853  *
10854  *  \param [in] a1 - an array to pow up.
10855  *  \param [in] a2 - another array to sum up.
10856  *  \return DataArrayInt * - the new instance of DataArrayInt.
10857  *          The caller is to delete this result array using decrRef() as it is no more
10858  *          needed.
10859  *  \throw If either \a a1 or \a a2 is NULL.
10860  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
10861  *  \throw If \a a1->getNumberOfComponents() != 1 or \a a2->getNumberOfComponents() != 1.
10862  *  \throw If there is a negative value in \a a2.
10863  */
10864 DataArrayInt *DataArrayInt::Pow(const DataArrayInt *a1, const DataArrayInt *a2)
10865 {
10866   if(!a1 || !a2)
10867     throw INTERP_KERNEL::Exception("DataArrayInt::Pow : at least one of input instances is null !");
10868   int nbOfTuple=a1->getNumberOfTuples();
10869   int nbOfTuple2=a2->getNumberOfTuples();
10870   int nbOfComp=a1->getNumberOfComponents();
10871   int nbOfComp2=a2->getNumberOfComponents();
10872   if(nbOfTuple!=nbOfTuple2)
10873     throw INTERP_KERNEL::Exception("DataArrayInt::Pow : number of tuples mismatches !");
10874   if(nbOfComp!=1 || nbOfComp2!=1)
10875     throw INTERP_KERNEL::Exception("DataArrayInt::Pow : number of components of both arrays must be equal to 1 !");
10876   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbOfTuple,1);
10877   const int *ptr1(a1->begin()),*ptr2(a2->begin());
10878   int *ptr=ret->getPointer();
10879   for(int i=0;i<nbOfTuple;i++,ptr1++,ptr2++,ptr++)
10880     {
10881       if(*ptr2>=0)
10882         {
10883           int tmp=1;
10884           for(int j=0;j<*ptr2;j++)
10885             tmp*=*ptr1;
10886           *ptr=tmp;
10887         }
10888       else
10889         {
10890           std::ostringstream oss; oss << "DataArrayInt::Pow : on tuple #" << i << " of a2 value is < 0 (" << *ptr2 << ") !";
10891           throw INTERP_KERNEL::Exception(oss.str().c_str());
10892         }
10893     }
10894   return ret.retn();
10895 }
10896
10897 /*!
10898  * Apply pow on values of another DataArrayInt to values of \a this one.
10899  *
10900  *  \param [in] other - an array to pow to \a this one.
10901  *  \throw If \a other is NULL.
10902  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples()
10903  *  \throw If \a this->getNumberOfComponents() != 1 or \a other->getNumberOfComponents() != 1
10904  *  \throw If there is a negative value in \a other.
10905  */
10906 void DataArrayInt::powEqual(const DataArrayInt *other)
10907 {
10908   if(!other)
10909     throw INTERP_KERNEL::Exception("DataArrayInt::powEqual : input instance is null !");
10910   int nbOfTuple=getNumberOfTuples();
10911   int nbOfTuple2=other->getNumberOfTuples();
10912   int nbOfComp=getNumberOfComponents();
10913   int nbOfComp2=other->getNumberOfComponents();
10914   if(nbOfTuple!=nbOfTuple2)
10915     throw INTERP_KERNEL::Exception("DataArrayInt::powEqual : number of tuples mismatches !");
10916   if(nbOfComp!=1 || nbOfComp2!=1)
10917     throw INTERP_KERNEL::Exception("DataArrayInt::powEqual : number of components of both arrays must be equal to 1 !");
10918   int *ptr=getPointer();
10919   const int *ptrc=other->begin();
10920   for(int i=0;i<nbOfTuple;i++,ptrc++,ptr++)
10921     {
10922       if(*ptrc>=0)
10923         {
10924           int tmp=1;
10925           for(int j=0;j<*ptrc;j++)
10926             tmp*=*ptr;
10927           *ptr=tmp;
10928         }
10929       else
10930         {
10931           std::ostringstream oss; oss << "DataArrayInt::powEqual : on tuple #" << i << " of other value is < 0 (" << *ptrc << ") !";
10932           throw INTERP_KERNEL::Exception(oss.str().c_str());
10933         }
10934     }
10935   declareAsNew();
10936 }
10937
10938 /*!
10939  * Returns a C array which is a renumbering map in "Old to New" mode for the input array.
10940  * This map, if applied to \a start array, would make it sorted. For example, if
10941  * \a start array contents are [9,10,0,6,4,11,3,7] then the contents of the result array is
10942  * [5,6,0,3,2,7,1,4].
10943  *  \param [in] start - pointer to the first element of the array for which the
10944  *         permutation map is computed.
10945  *  \param [in] end - pointer specifying the end of the array \a start, so that
10946  *         the last value of \a start is \a end[ -1 ].
10947  *  \return int * - the result permutation array that the caller is to delete as it is no
10948  *         more needed.
10949  *  \throw If there are equal values in the input array.
10950  */
10951 int *DataArrayInt::CheckAndPreparePermutation(const int *start, const int *end)
10952 {
10953   std::size_t sz=std::distance(start,end);
10954   int *ret=(int *)malloc(sz*sizeof(int));
10955   int *work=new int[sz];
10956   std::copy(start,end,work);
10957   std::sort(work,work+sz);
10958   if(std::unique(work,work+sz)!=work+sz)
10959     {
10960       delete [] work;
10961       free(ret);
10962       throw INTERP_KERNEL::Exception("Some elements are equals in the specified array !");
10963     }
10964   std::map<int,int> m;
10965   for(int *workPt=work;workPt!=work+sz;workPt++)
10966     m[*workPt]=(int)std::distance(work,workPt);
10967   int *iter2=ret;
10968   for(const int *iter=start;iter!=end;iter++,iter2++)
10969     *iter2=m[*iter];
10970   delete [] work;
10971   return ret;
10972 }
10973
10974 /*!
10975  * Returns a new DataArrayInt containing an arithmetic progression
10976  * that is equal to the sequence returned by Python \c range(\a begin,\a  end,\a  step )
10977  * function.
10978  *  \param [in] begin - the start value of the result sequence.
10979  *  \param [in] end - limiting value, so that every value of the result array is less than
10980  *              \a end.
10981  *  \param [in] step - specifies the increment or decrement.
10982  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
10983  *          array using decrRef() as it is no more needed.
10984  *  \throw If \a step == 0.
10985  *  \throw If \a end < \a begin && \a step > 0.
10986  *  \throw If \a end > \a begin && \a step < 0.
10987  */
10988 DataArrayInt *DataArrayInt::Range(int begin, int end, int step)
10989 {
10990   int nbOfTuples=GetNumberOfItemGivenBESRelative(begin,end,step,"DataArrayInt::Range");
10991   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
10992   ret->alloc(nbOfTuples,1);
10993   int *ptr=ret->getPointer();
10994   if(step>0)
10995     {
10996       for(int i=begin;i<end;i+=step,ptr++)
10997         *ptr=i;
10998     }
10999   else
11000     {
11001       for(int i=begin;i>end;i+=step,ptr++)
11002         *ptr=i;
11003     }
11004   return ret.retn();
11005 }
11006
11007 /*!
11008  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
11009  * Server side.
11010  */
11011 void DataArrayInt::getTinySerializationIntInformation(std::vector<int>& tinyInfo) const
11012 {
11013   tinyInfo.resize(2);
11014   if(isAllocated())
11015     {
11016       tinyInfo[0]=getNumberOfTuples();
11017       tinyInfo[1]=getNumberOfComponents();
11018     }
11019   else
11020     {
11021       tinyInfo[0]=-1;
11022       tinyInfo[1]=-1;
11023     }
11024 }
11025
11026 /*!
11027  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
11028  * Server side.
11029  */
11030 void DataArrayInt::getTinySerializationStrInformation(std::vector<std::string>& tinyInfo) const
11031 {
11032   if(isAllocated())
11033     {
11034       int nbOfCompo=getNumberOfComponents();
11035       tinyInfo.resize(nbOfCompo+1);
11036       tinyInfo[0]=getName();
11037       for(int i=0;i<nbOfCompo;i++)
11038         tinyInfo[i+1]=getInfoOnComponent(i);
11039     }
11040   else
11041     {
11042       tinyInfo.resize(1);
11043       tinyInfo[0]=getName();
11044     }
11045 }
11046
11047 /*!
11048  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
11049  * This method returns if a feeding is needed.
11050  */
11051 bool DataArrayInt::resizeForUnserialization(const std::vector<int>& tinyInfoI)
11052 {
11053   int nbOfTuple=tinyInfoI[0];
11054   int nbOfComp=tinyInfoI[1];
11055   if(nbOfTuple!=-1 || nbOfComp!=-1)
11056     {
11057       alloc(nbOfTuple,nbOfComp);
11058       return true;
11059     }
11060   return false;
11061 }
11062
11063 /*!
11064  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
11065  * This method returns if a feeding is needed.
11066  */
11067 void DataArrayInt::finishUnserialization(const std::vector<int>& tinyInfoI, const std::vector<std::string>& tinyInfoS)
11068 {
11069   setName(tinyInfoS[0].c_str());
11070   if(isAllocated())
11071     {
11072       int nbOfCompo=tinyInfoI[1];
11073       for(int i=0;i<nbOfCompo;i++)
11074         setInfoOnComponent(i,tinyInfoS[i+1].c_str());
11075     }
11076 }
11077
11078 DataArrayIntIterator::DataArrayIntIterator(DataArrayInt *da):_da(da),_pt(0),_tuple_id(0),_nb_comp(0),_nb_tuple(0)
11079 {
11080   if(_da)
11081     {
11082       _da->incrRef();
11083       if(_da->isAllocated())
11084         {
11085           _nb_comp=da->getNumberOfComponents();
11086           _nb_tuple=da->getNumberOfTuples();
11087           _pt=da->getPointer();
11088         }
11089     }
11090 }
11091
11092 DataArrayIntIterator::~DataArrayIntIterator()
11093 {
11094   if(_da)
11095     _da->decrRef();
11096 }
11097
11098 DataArrayIntTuple *DataArrayIntIterator::nextt()
11099 {
11100   if(_tuple_id<_nb_tuple)
11101     {
11102       _tuple_id++;
11103       DataArrayIntTuple *ret=new DataArrayIntTuple(_pt,_nb_comp);
11104       _pt+=_nb_comp;
11105       return ret;
11106     }
11107   else
11108     return 0;
11109 }
11110
11111 DataArrayIntTuple::DataArrayIntTuple(int *pt, int nbOfComp):_pt(pt),_nb_of_compo(nbOfComp)
11112 {
11113 }
11114
11115 std::string DataArrayIntTuple::repr() const
11116 {
11117   std::ostringstream oss; oss << "(";
11118   for(int i=0;i<_nb_of_compo-1;i++)
11119     oss << _pt[i] << ", ";
11120   oss << _pt[_nb_of_compo-1] << ")";
11121   return oss.str();
11122 }
11123
11124 int DataArrayIntTuple::intValue() const
11125 {
11126   if(_nb_of_compo==1)
11127     return *_pt;
11128   throw INTERP_KERNEL::Exception("DataArrayIntTuple::intValue : DataArrayIntTuple instance has not exactly 1 component -> Not possible to convert it into an integer !");
11129 }
11130
11131 /*!
11132  * This method returns a newly allocated instance the caller should dealed with by a ParaMEDMEM::DataArrayInt::decrRef.
11133  * This method performs \b no copy of data. The content is only referenced using ParaMEDMEM::DataArrayInt::useArray with ownership set to \b false.
11134  * 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
11135  * \b nbOfCompo=1 and \bnbOfTuples==this->_nb_of_elem.
11136  */
11137 DataArrayInt *DataArrayIntTuple::buildDAInt(int nbOfTuples, int nbOfCompo) const
11138 {
11139   if((_nb_of_compo==nbOfCompo && nbOfTuples==1) || (_nb_of_compo==nbOfTuples && nbOfCompo==1))
11140     {
11141       DataArrayInt *ret=DataArrayInt::New();
11142       ret->useExternalArrayWithRWAccess(_pt,nbOfTuples,nbOfCompo);
11143       return ret;
11144     }
11145   else
11146     {
11147       std::ostringstream oss; oss << "DataArrayIntTuple::buildDAInt : unable to build a requested DataArrayInt instance with nbofTuple=" << nbOfTuples << " and nbOfCompo=" << nbOfCompo;
11148       oss << ".\nBecause the number of elements in this is " << _nb_of_compo << " !";
11149       throw INTERP_KERNEL::Exception(oss.str().c_str());
11150     }
11151 }