Salome HOME
ca8343508e47afbb028b5ee5e479200e2b84917b
[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   std::size_t nbOfVals=getNbOfElems();
1352   int *dest=ret->getPointer();
1353   // to make Visual C++ happy : instead of std::copy(src,src+nbOfVals,dest);
1354   for(const double *src=begin();src!=end();src++,dest++)
1355     *dest=(int)*src;
1356   ret->copyStringInfoFrom(*this);
1357   return ret;
1358 }
1359
1360 /*!
1361  * Returns a new DataArrayDouble holding the same values as \a this array but differently
1362  * arranged in memory. If \a this array holds 2 components of 3 values:
1363  * \f$ x_0,x_1,x_2,y_0,y_1,y_2 \f$, then the result array holds these values arranged
1364  * as follows: \f$ x_0,y_0,x_1,y_1,x_2,y_2 \f$.
1365  *  \warning Do not confuse this method with transpose()!
1366  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1367  *          is to delete using decrRef() as it is no more needed.
1368  *  \throw If \a this is not allocated.
1369  */
1370 DataArrayDouble *DataArrayDouble::fromNoInterlace() const
1371 {
1372   if(_mem.isNull())
1373     throw INTERP_KERNEL::Exception("DataArrayDouble::fromNoInterlace : Not defined array !");
1374   double *tab=_mem.fromNoInterlace(getNumberOfComponents());
1375   DataArrayDouble *ret=DataArrayDouble::New();
1376   ret->useArray(tab,true,C_DEALLOC,getNumberOfTuples(),getNumberOfComponents());
1377   return ret;
1378 }
1379
1380 /*!
1381  * Returns a new DataArrayDouble holding the same values as \a this array but differently
1382  * arranged in memory. If \a this array holds 2 components of 3 values:
1383  * \f$ x_0,y_0,x_1,y_1,x_2,y_2 \f$, then the result array holds these values arranged
1384  * as follows: \f$ x_0,x_1,x_2,y_0,y_1,y_2 \f$.
1385  *  \warning Do not confuse this method with transpose()!
1386  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1387  *          is to delete using decrRef() as it is no more needed.
1388  *  \throw If \a this is not allocated.
1389  */
1390 DataArrayDouble *DataArrayDouble::toNoInterlace() const
1391 {
1392   if(_mem.isNull())
1393     throw INTERP_KERNEL::Exception("DataArrayDouble::toNoInterlace : Not defined array !");
1394   double *tab=_mem.toNoInterlace(getNumberOfComponents());
1395   DataArrayDouble *ret=DataArrayDouble::New();
1396   ret->useArray(tab,true,C_DEALLOC,getNumberOfTuples(),getNumberOfComponents());
1397   return ret;
1398 }
1399
1400 /*!
1401  * Permutes values of \a this array as required by \a old2New array. The values are
1402  * permuted so that \c new[ \a old2New[ i ]] = \c old[ i ]. Number of tuples remains
1403  * the same as in \this one.
1404  * If a permutation reduction is needed, substr() or selectByTupleId() should be used.
1405  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
1406  *  \param [in] old2New - C array of length equal to \a this->getNumberOfTuples()
1407  *     giving a new position for i-th old value.
1408  */
1409 void DataArrayDouble::renumberInPlace(const int *old2New)
1410 {
1411   checkAllocated();
1412   int nbTuples=getNumberOfTuples();
1413   int nbOfCompo=getNumberOfComponents();
1414   double *tmp=new double[nbTuples*nbOfCompo];
1415   const double *iptr=getConstPointer();
1416   for(int i=0;i<nbTuples;i++)
1417     {
1418       int v=old2New[i];
1419       if(v>=0 && v<nbTuples)
1420         std::copy(iptr+nbOfCompo*i,iptr+nbOfCompo*(i+1),tmp+nbOfCompo*v);
1421       else
1422         {
1423           std::ostringstream oss; oss << "DataArrayDouble::renumberInPlace : At place #" << i << " value is " << v << " ! Should be in [0," << nbTuples << ") !";
1424           throw INTERP_KERNEL::Exception(oss.str().c_str());
1425         }
1426     }
1427   std::copy(tmp,tmp+nbTuples*nbOfCompo,getPointer());
1428   delete [] tmp;
1429   declareAsNew();
1430 }
1431
1432 /*!
1433  * Permutes values of \a this array as required by \a new2Old array. The values are
1434  * permuted so that \c new[ i ] = \c old[ \a new2Old[ i ]]. Number of tuples remains
1435  * the same as in \this one.
1436  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
1437  *  \param [in] new2Old - C array of length equal to \a this->getNumberOfTuples()
1438  *     giving a previous position of i-th new value.
1439  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1440  *          is to delete using decrRef() as it is no more needed.
1441  */
1442 void DataArrayDouble::renumberInPlaceR(const int *new2Old)
1443 {
1444   checkAllocated();
1445   int nbTuples=getNumberOfTuples();
1446   int nbOfCompo=getNumberOfComponents();
1447   double *tmp=new double[nbTuples*nbOfCompo];
1448   const double *iptr=getConstPointer();
1449   for(int i=0;i<nbTuples;i++)
1450     {
1451       int v=new2Old[i];
1452       if(v>=0 && v<nbTuples)
1453         std::copy(iptr+nbOfCompo*v,iptr+nbOfCompo*(v+1),tmp+nbOfCompo*i);
1454       else
1455         {
1456           std::ostringstream oss; oss << "DataArrayDouble::renumberInPlaceR : At place #" << i << " value is " << v << " ! Should be in [0," << nbTuples << ") !";
1457           throw INTERP_KERNEL::Exception(oss.str().c_str());
1458         }
1459     }
1460   std::copy(tmp,tmp+nbTuples*nbOfCompo,getPointer());
1461   delete [] tmp;
1462   declareAsNew();
1463 }
1464
1465 /*!
1466  * Returns a copy of \a this array with values permuted as required by \a old2New array.
1467  * The values are permuted so that  \c new[ \a old2New[ i ]] = \c old[ i ].
1468  * Number of tuples in the result array remains the same as in \this one.
1469  * If a permutation reduction is needed, renumberAndReduce() should be used.
1470  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
1471  *  \param [in] old2New - C array of length equal to \a this->getNumberOfTuples()
1472  *          giving a new position for i-th old value.
1473  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1474  *          is to delete using decrRef() as it is no more needed.
1475  *  \throw If \a this is not allocated.
1476  */
1477 DataArrayDouble *DataArrayDouble::renumber(const int *old2New) const
1478 {
1479   checkAllocated();
1480   int nbTuples=getNumberOfTuples();
1481   int nbOfCompo=getNumberOfComponents();
1482   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
1483   ret->alloc(nbTuples,nbOfCompo);
1484   ret->copyStringInfoFrom(*this);
1485   const double *iptr=getConstPointer();
1486   double *optr=ret->getPointer();
1487   for(int i=0;i<nbTuples;i++)
1488     std::copy(iptr+nbOfCompo*i,iptr+nbOfCompo*(i+1),optr+nbOfCompo*old2New[i]);
1489   ret->copyStringInfoFrom(*this);
1490   return ret.retn();
1491 }
1492
1493 /*!
1494  * Returns a copy of \a this array with values permuted as required by \a new2Old array.
1495  * The values are permuted so that  \c new[ i ] = \c old[ \a new2Old[ i ]]. Number of
1496  * tuples in the result array remains the same as in \this one.
1497  * If a permutation reduction is needed, substr() or selectByTupleId() should be used.
1498  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
1499  *  \param [in] new2Old - C array of length equal to \a this->getNumberOfTuples()
1500  *     giving a previous position of i-th new value.
1501  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1502  *          is to delete using decrRef() as it is no more needed.
1503  */
1504 DataArrayDouble *DataArrayDouble::renumberR(const int *new2Old) const
1505 {
1506   checkAllocated();
1507   int nbTuples=getNumberOfTuples();
1508   int nbOfCompo=getNumberOfComponents();
1509   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
1510   ret->alloc(nbTuples,nbOfCompo);
1511   ret->copyStringInfoFrom(*this);
1512   const double *iptr=getConstPointer();
1513   double *optr=ret->getPointer();
1514   for(int i=0;i<nbTuples;i++)
1515     std::copy(iptr+nbOfCompo*new2Old[i],iptr+nbOfCompo*(new2Old[i]+1),optr+i*nbOfCompo);
1516   ret->copyStringInfoFrom(*this);
1517   return ret.retn();
1518 }
1519
1520 /*!
1521  * Returns a shorten and permuted copy of \a this array. The new DataArrayDouble is
1522  * of size \a newNbOfTuple and it's values are permuted as required by \a old2New array.
1523  * The values are permuted so that  \c new[ \a old2New[ i ]] = \c old[ i ] for all
1524  * \a old2New[ i ] >= 0. In other words every i-th tuple in \a this array, for which 
1525  * \a old2New[ i ] is negative, is missing from the result array.
1526  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
1527  *  \param [in] old2New - C array of length equal to \a this->getNumberOfTuples()
1528  *     giving a new position for i-th old tuple and giving negative position for
1529  *     for i-th old tuple that should be omitted.
1530  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1531  *          is to delete using decrRef() as it is no more needed.
1532  */
1533 DataArrayDouble *DataArrayDouble::renumberAndReduce(const int *old2New, int newNbOfTuple) const
1534 {
1535   checkAllocated();
1536   int nbTuples=getNumberOfTuples();
1537   int nbOfCompo=getNumberOfComponents();
1538   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
1539   ret->alloc(newNbOfTuple,nbOfCompo);
1540   const double *iptr=getConstPointer();
1541   double *optr=ret->getPointer();
1542   for(int i=0;i<nbTuples;i++)
1543     {
1544       int w=old2New[i];
1545       if(w>=0)
1546         std::copy(iptr+i*nbOfCompo,iptr+(i+1)*nbOfCompo,optr+w*nbOfCompo);
1547     }
1548   ret->copyStringInfoFrom(*this);
1549   return ret.retn();
1550 }
1551
1552 /*!
1553  * Returns a shorten and permuted copy of \a this array. The new DataArrayDouble is
1554  * of size \a new2OldEnd - \a new2OldBg and it's values are permuted as required by
1555  * \a new2OldBg array.
1556  * The values are permuted so that  \c new[ i ] = \c old[ \a new2OldBg[ i ]].
1557  * This method is equivalent to renumberAndReduce() except that convention in input is
1558  * \c new2old and \b not \c old2new.
1559  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
1560  *  \param [in] new2OldBg - pointer to the beginning of a permutation array that gives a
1561  *              tuple index in \a this array to fill the i-th tuple in the new array.
1562  *  \param [in] new2OldEnd - specifies the end of the permutation array that starts at
1563  *              \a new2OldBg, so that pointer to a tuple index (\a pi) varies as this:
1564  *              \a new2OldBg <= \a pi < \a new2OldEnd.
1565  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1566  *          is to delete using decrRef() as it is no more needed.
1567  */
1568 DataArrayDouble *DataArrayDouble::selectByTupleId(const int *new2OldBg, const int *new2OldEnd) const
1569 {
1570   checkAllocated();
1571   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
1572   int nbComp=getNumberOfComponents();
1573   ret->alloc((int)std::distance(new2OldBg,new2OldEnd),nbComp);
1574   ret->copyStringInfoFrom(*this);
1575   double *pt=ret->getPointer();
1576   const double *srcPt=getConstPointer();
1577   int i=0;
1578   for(const int *w=new2OldBg;w!=new2OldEnd;w++,i++)
1579     std::copy(srcPt+(*w)*nbComp,srcPt+((*w)+1)*nbComp,pt+i*nbComp);
1580   ret->copyStringInfoFrom(*this);
1581   return ret.retn();
1582 }
1583
1584 /*!
1585  * Returns a shorten and permuted copy of \a this array. The new DataArrayDouble is
1586  * of size \a new2OldEnd - \a new2OldBg and it's values are permuted as required by
1587  * \a new2OldBg array.
1588  * The values are permuted so that  \c new[ i ] = \c old[ \a new2OldBg[ i ]].
1589  * This method is equivalent to renumberAndReduce() except that convention in input is
1590  * \c new2old and \b not \c old2new.
1591  * This method is equivalent to selectByTupleId() except that it prevents coping data
1592  * from behind the end of \a this array.
1593  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
1594  *  \param [in] new2OldBg - pointer to the beginning of a permutation array that gives a
1595  *              tuple index in \a this array to fill the i-th tuple in the new array.
1596  *  \param [in] new2OldEnd - specifies the end of the permutation array that starts at
1597  *              \a new2OldBg, so that pointer to a tuple index (\a pi) varies as this:
1598  *              \a new2OldBg <= \a pi < \a new2OldEnd.
1599  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1600  *          is to delete using decrRef() as it is no more needed.
1601  *  \throw If \a new2OldEnd - \a new2OldBg > \a this->getNumberOfTuples().
1602  */
1603 DataArrayDouble *DataArrayDouble::selectByTupleIdSafe(const int *new2OldBg, const int *new2OldEnd) const
1604 {
1605   checkAllocated();
1606   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
1607   int nbComp=getNumberOfComponents();
1608   int oldNbOfTuples=getNumberOfTuples();
1609   ret->alloc((int)std::distance(new2OldBg,new2OldEnd),nbComp);
1610   ret->copyStringInfoFrom(*this);
1611   double *pt=ret->getPointer();
1612   const double *srcPt=getConstPointer();
1613   int i=0;
1614   for(const int *w=new2OldBg;w!=new2OldEnd;w++,i++)
1615     if(*w>=0 && *w<oldNbOfTuples)
1616       std::copy(srcPt+(*w)*nbComp,srcPt+((*w)+1)*nbComp,pt+i*nbComp);
1617     else
1618       throw INTERP_KERNEL::Exception("DataArrayDouble::selectByTupleIdSafe : some ids has been detected to be out of [0,this->getNumberOfTuples) !");
1619   ret->copyStringInfoFrom(*this);
1620   return ret.retn();
1621 }
1622
1623 /*!
1624  * Returns a shorten copy of \a this array. The new DataArrayDouble contains every
1625  * (\a bg + \c i * \a step)-th tuple of \a this array located before the \a end2-th
1626  * tuple. Indices of the selected tuples are the same as ones returned by the Python
1627  * command \c range( \a bg, \a end2, \a step ).
1628  * This method is equivalent to selectByTupleIdSafe() except that the input array is
1629  * not constructed explicitly.
1630  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
1631  *  \param [in] bg - index of the first tuple to copy from \a this array.
1632  *  \param [in] end2 - index of the tuple before which the tuples to copy are located.
1633  *  \param [in] step - index increment to get index of the next tuple to copy.
1634  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1635  *          is to delete using decrRef() as it is no more needed.
1636  *  \sa DataArrayDouble::substr.
1637  */
1638 DataArrayDouble *DataArrayDouble::selectByTupleId2(int bg, int end2, int step) const
1639 {
1640   checkAllocated();
1641   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
1642   int nbComp=getNumberOfComponents();
1643   int newNbOfTuples=GetNumberOfItemGivenBESRelative(bg,end2,step,"DataArrayDouble::selectByTupleId2 : ");
1644   ret->alloc(newNbOfTuples,nbComp);
1645   double *pt=ret->getPointer();
1646   const double *srcPt=getConstPointer()+bg*nbComp;
1647   for(int i=0;i<newNbOfTuples;i++,srcPt+=step*nbComp)
1648     std::copy(srcPt,srcPt+nbComp,pt+i*nbComp);
1649   ret->copyStringInfoFrom(*this);
1650   return ret.retn();
1651 }
1652
1653 /*!
1654  * Returns a shorten copy of \a this array. The new DataArrayDouble contains ranges
1655  * of tuples specified by \a ranges parameter.
1656  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
1657  *  \param [in] ranges - std::vector of std::pair's each of which defines a range
1658  *              of tuples in [\c begin,\c end) format.
1659  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1660  *          is to delete using decrRef() as it is no more needed.
1661  *  \throw If \a end < \a begin.
1662  *  \throw If \a end > \a this->getNumberOfTuples().
1663  *  \throw If \a this is not allocated.
1664  */
1665 DataArray *DataArrayDouble::selectByTupleRanges(const std::vector<std::pair<int,int> >& ranges) const
1666 {
1667   checkAllocated();
1668   int nbOfComp=getNumberOfComponents();
1669   int nbOfTuplesThis=getNumberOfTuples();
1670   if(ranges.empty())
1671     {
1672       DataArrayDouble *ret=DataArrayDouble::New();
1673       ret->alloc(0,nbOfComp);
1674       ret->copyStringInfoFrom(*this);
1675       return ret;
1676     }
1677   int ref=ranges.front().first;
1678   int nbOfTuples=0;
1679   bool isIncreasing=true;
1680   for(std::vector<std::pair<int,int> >::const_iterator it=ranges.begin();it!=ranges.end();it++)
1681     {
1682       if((*it).first<=(*it).second)
1683         {
1684           if((*it).first>=0 && (*it).second<=nbOfTuplesThis)
1685             {
1686               nbOfTuples+=(*it).second-(*it).first;
1687               if(isIncreasing)
1688                 isIncreasing=ref<=(*it).first;
1689               ref=(*it).second;
1690             }
1691           else
1692             {
1693               std::ostringstream oss; oss << "DataArrayDouble::selectByTupleRanges : on range #" << std::distance(ranges.begin(),it);
1694               oss << " (" << (*it).first << "," << (*it).second << ") is greater than number of tuples of this :" << nbOfTuples << " !";
1695               throw INTERP_KERNEL::Exception(oss.str().c_str());
1696             }
1697         }
1698       else
1699         {
1700           std::ostringstream oss; oss << "DataArrayDouble::selectByTupleRanges : on range #" << std::distance(ranges.begin(),it);
1701           oss << " (" << (*it).first << "," << (*it).second << ") end is before begin !";
1702           throw INTERP_KERNEL::Exception(oss.str().c_str());
1703         }
1704     }
1705   if(isIncreasing && nbOfTuplesThis==nbOfTuples)
1706     return deepCpy();
1707   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
1708   ret->alloc(nbOfTuples,nbOfComp);
1709   ret->copyStringInfoFrom(*this);
1710   const double *src=getConstPointer();
1711   double *work=ret->getPointer();
1712   for(std::vector<std::pair<int,int> >::const_iterator it=ranges.begin();it!=ranges.end();it++)
1713     work=std::copy(src+(*it).first*nbOfComp,src+(*it).second*nbOfComp,work);
1714   return ret.retn();
1715 }
1716
1717 /*!
1718  * Returns a shorten copy of \a this array. The new DataArrayDouble contains all
1719  * tuples starting from the \a tupleIdBg-th tuple and including all tuples located before
1720  * the \a tupleIdEnd-th one. This methods has a similar behavior as std::string::substr().
1721  * This method is a specialization of selectByTupleId2().
1722  *  \param [in] tupleIdBg - index of the first tuple to copy from \a this array.
1723  *  \param [in] tupleIdEnd - index of the tuple before which the tuples to copy are located.
1724  *          If \a tupleIdEnd == -1, all the tuples till the end of \a this array are copied.
1725  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1726  *          is to delete using decrRef() as it is no more needed.
1727  *  \throw If \a tupleIdBg < 0.
1728  *  \throw If \a tupleIdBg > \a this->getNumberOfTuples().
1729     \throw If \a tupleIdEnd != -1 && \a tupleIdEnd < \a this->getNumberOfTuples().
1730  *  \sa DataArrayDouble::selectByTupleId2
1731  */
1732 DataArrayDouble *DataArrayDouble::substr(int tupleIdBg, int tupleIdEnd) const
1733 {
1734   checkAllocated();
1735   int nbt=getNumberOfTuples();
1736   if(tupleIdBg<0)
1737     throw INTERP_KERNEL::Exception("DataArrayDouble::substr : The tupleIdBg parameter must be greater than 0 !");
1738   if(tupleIdBg>nbt)
1739     throw INTERP_KERNEL::Exception("DataArrayDouble::substr : The tupleIdBg parameter is greater than number of tuples !");
1740   int trueEnd=tupleIdEnd;
1741   if(tupleIdEnd!=-1)
1742     {
1743       if(tupleIdEnd>nbt)
1744         throw INTERP_KERNEL::Exception("DataArrayDouble::substr : The tupleIdBg parameter is greater or equal than number of tuples !");
1745     }
1746   else
1747     trueEnd=nbt;
1748   int nbComp=getNumberOfComponents();
1749   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
1750   ret->alloc(trueEnd-tupleIdBg,nbComp);
1751   ret->copyStringInfoFrom(*this);
1752   std::copy(getConstPointer()+tupleIdBg*nbComp,getConstPointer()+trueEnd*nbComp,ret->getPointer());
1753   return ret.retn();
1754 }
1755
1756 /*!
1757  * Returns a shorten or extended copy of \a this array. If \a newNbOfComp is less
1758  * than \a this->getNumberOfComponents() then the result array is shorten as each tuple
1759  * is truncated to have \a newNbOfComp components, keeping first components. If \a
1760  * newNbOfComp is more than \a this->getNumberOfComponents() then the result array is
1761  * expanded as each tuple is populated with \a dftValue to have \a newNbOfComp
1762  * components.  
1763  *  \param [in] newNbOfComp - number of components for the new array to have.
1764  *  \param [in] dftValue - value assigned to new values added to the new array.
1765  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1766  *          is to delete using decrRef() as it is no more needed.
1767  *  \throw If \a this is not allocated.
1768  */
1769 DataArrayDouble *DataArrayDouble::changeNbOfComponents(int newNbOfComp, double dftValue) const
1770 {
1771   checkAllocated();
1772   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
1773   ret->alloc(getNumberOfTuples(),newNbOfComp);
1774   const double *oldc=getConstPointer();
1775   double *nc=ret->getPointer();
1776   int nbOfTuples=getNumberOfTuples();
1777   int oldNbOfComp=getNumberOfComponents();
1778   int dim=std::min(oldNbOfComp,newNbOfComp);
1779   for(int i=0;i<nbOfTuples;i++)
1780     {
1781       int j=0;
1782       for(;j<dim;j++)
1783         nc[newNbOfComp*i+j]=oldc[i*oldNbOfComp+j];
1784       for(;j<newNbOfComp;j++)
1785         nc[newNbOfComp*i+j]=dftValue;
1786     }
1787   ret->setName(getName().c_str());
1788   for(int i=0;i<dim;i++)
1789     ret->setInfoOnComponent(i,getInfoOnComponent(i).c_str());
1790   ret->setName(getName().c_str());
1791   return ret.retn();
1792 }
1793
1794 /*!
1795  * Changes the number of components within \a this array so that its raw data **does
1796  * not** change, instead splitting this data into tuples changes.
1797  *  \warning This method erases all (name and unit) component info set before!
1798  *  \param [in] newNbOfComp - number of components for \a this array to have.
1799  *  \throw If \a this is not allocated
1800  *  \throw If getNbOfElems() % \a newNbOfCompo != 0.
1801  *  \throw If \a newNbOfCompo is lower than 1.
1802  *  \throw If the rearrange method would lead to a number of tuples higher than 2147483647 (maximal capacity of int32 !).
1803  *  \warning This method erases all (name and unit) component info set before!
1804  */
1805 void DataArrayDouble::rearrange(int newNbOfCompo)
1806 {
1807   checkAllocated();
1808   if(newNbOfCompo<1)
1809     throw INTERP_KERNEL::Exception("DataArrayDouble::rearrange : input newNbOfCompo must be > 0 !");
1810   std::size_t nbOfElems=getNbOfElems();
1811   if(nbOfElems%newNbOfCompo!=0)
1812     throw INTERP_KERNEL::Exception("DataArrayDouble::rearrange : nbOfElems%newNbOfCompo!=0 !");
1813   if(nbOfElems/newNbOfCompo>(std::size_t)std::numeric_limits<int>::max())
1814     throw INTERP_KERNEL::Exception("DataArrayDouble::rearrange : the rearrangement leads to too high number of tuples (> 2147483647) !");
1815   _info_on_compo.clear();
1816   _info_on_compo.resize(newNbOfCompo);
1817   declareAsNew();
1818 }
1819
1820 /*!
1821  * Changes the number of components within \a this array to be equal to its number
1822  * of tuples, and inversely its number of tuples to become equal to its number of 
1823  * components. So that its raw data **does not** change, instead splitting this
1824  * data into tuples changes.
1825  *  \warning This method erases all (name and unit) component info set before!
1826  *  \warning Do not confuse this method with fromNoInterlace() and toNoInterlace()!
1827  *  \throw If \a this is not allocated.
1828  *  \sa rearrange()
1829  */
1830 void DataArrayDouble::transpose()
1831 {
1832   checkAllocated();
1833   int nbOfTuples=getNumberOfTuples();
1834   rearrange(nbOfTuples);
1835 }
1836
1837 /*!
1838  * Returns a copy of \a this array composed of selected components.
1839  * The new DataArrayDouble has the same number of tuples but includes components
1840  * specified by \a compoIds parameter. So that getNbOfElems() of the result array
1841  * can be either less, same or more than \a this->getNbOfElems().
1842  *  \param [in] compoIds - sequence of zero based indices of components to include
1843  *              into the new array.
1844  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1845  *          is to delete using decrRef() as it is no more needed.
1846  *  \throw If \a this is not allocated.
1847  *  \throw If a component index (\a i) is not valid: 
1848  *         \a i < 0 || \a i >= \a this->getNumberOfComponents().
1849  *
1850  *  \ref py_mcdataarraydouble_KeepSelectedComponents "Here is a Python example".
1851  */
1852 DataArray *DataArrayDouble::keepSelectedComponents(const std::vector<int>& compoIds) const
1853 {
1854   checkAllocated();
1855   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret(DataArrayDouble::New());
1856   std::size_t newNbOfCompo=compoIds.size();
1857   int oldNbOfCompo=getNumberOfComponents();
1858   for(std::vector<int>::const_iterator it=compoIds.begin();it!=compoIds.end();it++)
1859     if((*it)<0 || (*it)>=oldNbOfCompo)
1860       {
1861         std::ostringstream oss; oss << "DataArrayDouble::keepSelectedComponents : invalid requested component : " << *it << " whereas it should be in [0," << oldNbOfCompo << ") !";
1862         throw INTERP_KERNEL::Exception(oss.str().c_str());
1863       }
1864   int nbOfTuples=getNumberOfTuples();
1865   ret->alloc(nbOfTuples,(int)newNbOfCompo);
1866   ret->copyPartOfStringInfoFrom(*this,compoIds);
1867   const double *oldc=getConstPointer();
1868   double *nc=ret->getPointer();
1869   for(int i=0;i<nbOfTuples;i++)
1870     for(std::size_t j=0;j<newNbOfCompo;j++,nc++)
1871       *nc=oldc[i*oldNbOfCompo+compoIds[j]];
1872   return ret.retn();
1873 }
1874
1875 /*!
1876  * Appends components of another array to components of \a this one, tuple by tuple.
1877  * So that the number of tuples of \a this array remains the same and the number of 
1878  * components increases.
1879  *  \param [in] other - the DataArrayDouble to append to \a this one.
1880  *  \throw If \a this is not allocated.
1881  *  \throw If \a this and \a other arrays have different number of tuples.
1882  *
1883  *  \ref cpp_mcdataarraydouble_meldwith "Here is a C++ example".
1884  *
1885  *  \ref py_mcdataarraydouble_meldwith "Here is a Python example".
1886  */
1887 void DataArrayDouble::meldWith(const DataArrayDouble *other)
1888 {
1889   checkAllocated();
1890   other->checkAllocated();
1891   int nbOfTuples=getNumberOfTuples();
1892   if(nbOfTuples!=other->getNumberOfTuples())
1893     throw INTERP_KERNEL::Exception("DataArrayDouble::meldWith : mismatch of number of tuples !");
1894   int nbOfComp1=getNumberOfComponents();
1895   int nbOfComp2=other->getNumberOfComponents();
1896   double *newArr=(double *)malloc((nbOfTuples*(nbOfComp1+nbOfComp2))*sizeof(double));
1897   double *w=newArr;
1898   const double *inp1=getConstPointer();
1899   const double *inp2=other->getConstPointer();
1900   for(int i=0;i<nbOfTuples;i++,inp1+=nbOfComp1,inp2+=nbOfComp2)
1901     {
1902       w=std::copy(inp1,inp1+nbOfComp1,w);
1903       w=std::copy(inp2,inp2+nbOfComp2,w);
1904     }
1905   useArray(newArr,true,C_DEALLOC,nbOfTuples,nbOfComp1+nbOfComp2);
1906   std::vector<int> compIds(nbOfComp2);
1907   for(int i=0;i<nbOfComp2;i++)
1908     compIds[i]=nbOfComp1+i;
1909   copyPartOfStringInfoFrom2(compIds,*other);
1910 }
1911
1912 /*!
1913  * This method checks that all tuples in \a other are in \a this.
1914  * If true, the output param \a tupleIds contains the tuples ids of \a this that correspond to tupes in \a this.
1915  * 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.
1916  *
1917  * \param [in] other - the array having the same number of components than \a this.
1918  * \param [out] tupleIds - the tuple ids containing the same number of tuples than \a other has.
1919  * \sa DataArrayDouble::findCommonTuples
1920  */
1921 bool DataArrayDouble::areIncludedInMe(const DataArrayDouble *other, double prec, DataArrayInt *&tupleIds) const
1922 {
1923   if(!other)
1924     throw INTERP_KERNEL::Exception("DataArrayDouble::areIncludedInMe : input array is NULL !");
1925   checkAllocated(); other->checkAllocated();
1926   if(getNumberOfComponents()!=other->getNumberOfComponents())
1927     throw INTERP_KERNEL::Exception("DataArrayDouble::areIncludedInMe : the number of components does not match !");
1928   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> a=DataArrayDouble::Aggregate(this,other);
1929   DataArrayInt *c=0,*ci=0;
1930   a->findCommonTuples(prec,getNumberOfTuples(),c,ci);
1931   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cSafe(c),ciSafe(ci);
1932   int newNbOfTuples=-1;
1933   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ids=DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2(a->getNumberOfTuples(),c->begin(),ci->begin(),ci->end(),newNbOfTuples);
1934   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret1=ids->selectByTupleId2(getNumberOfTuples(),a->getNumberOfTuples(),1);
1935   tupleIds=ret1.retn();
1936   return newNbOfTuples==getNumberOfTuples();
1937 }
1938
1939 /*!
1940  * Searches for tuples coincident within \a prec tolerance. Each tuple is considered
1941  * as coordinates of a point in getNumberOfComponents()-dimensional space. The
1942  * distance separating two points is computed with the infinite norm.
1943  *
1944  * Indices of coincident tuples are stored in output arrays.
1945  * A pair of arrays (\a comm, \a commIndex) is called "Surjective Format 2".
1946  *
1947  * This method is typically used by MEDCouplingPointSet::findCommonNodes() and
1948  * MEDCouplingUMesh::mergeNodes().
1949  *  \param [in] prec - minimal absolute distance between two tuples (infinite norm) at which they are
1950  *              considered not coincident.
1951  *  \param [in] limitTupleId - limit tuple id. If all tuples within a group of coincident
1952  *              tuples have id strictly lower than \a limitTupleId then they are not returned.
1953  *  \param [out] comm - the array holding ids (== indices) of coincident tuples. 
1954  *               \a comm->getNumberOfComponents() == 1. 
1955  *               \a comm->getNumberOfTuples() == \a commIndex->back().
1956  *  \param [out] commIndex - the array dividing all indices stored in \a comm into
1957  *               groups of (indices of) coincident tuples. Its every value is a tuple
1958  *               index where a next group of tuples begins. For example the second
1959  *               group of tuples in \a comm is described by following range of indices:
1960  *               [ \a commIndex[1], \a commIndex[2] ). \a commIndex->getNumberOfTuples()-1
1961  *               gives the number of groups of coincident tuples.
1962  *  \throw If \a this is not allocated.
1963  *  \throw If the number of components is not in [1,2,3].
1964  *
1965  *  \ref cpp_mcdataarraydouble_findcommontuples "Here is a C++ example".
1966  *
1967  *  \ref py_mcdataarraydouble_findcommontuples  "Here is a Python example".
1968  *  \sa DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2(), DataArrayDouble::areIncludedInMe
1969  */
1970 void DataArrayDouble::findCommonTuples(double prec, int limitTupleId, DataArrayInt *&comm, DataArrayInt *&commIndex) const
1971 {
1972   checkAllocated();
1973   int nbOfCompo=getNumberOfComponents();
1974   if ((nbOfCompo<1) || (nbOfCompo>3)) //test before work
1975     throw INTERP_KERNEL::Exception("DataArrayDouble::findCommonTuples : Unexpected spacedim of coords. Must be 1, 2 or 3.");
1976   
1977   int nbOfTuples=getNumberOfTuples();
1978   //
1979   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> c(DataArrayInt::New()),cI(DataArrayInt::New()); c->alloc(0,1); cI->pushBackSilent(0);
1980   switch(nbOfCompo)
1981     {
1982     case 3:
1983       findCommonTuplesAlg<3>(begin(),nbOfTuples,limitTupleId,prec,c,cI);
1984       break;
1985     case 2:
1986       findCommonTuplesAlg<2>(begin(),nbOfTuples,limitTupleId,prec,c,cI);
1987       break;
1988     case 1:
1989       findCommonTuplesAlg<1>(begin(),nbOfTuples,limitTupleId,prec,c,cI);
1990       break;
1991     default:
1992       throw INTERP_KERNEL::Exception("DataArrayDouble::findCommonTuples : nb of components managed are 1,2 and 3 ! not implemented for other number of components !");
1993     }
1994   comm=c.retn();
1995   commIndex=cI.retn();
1996 }
1997
1998 /*!
1999  * 
2000  * \param [in] nbTimes specifies the nb of times each tuples in \a this will be duplicated contiguouly in returned DataArrayDouble instance.
2001  *             \a nbTimes  should be at least equal to 1.
2002  * \return a newly allocated DataArrayDouble having one component and number of tuples equal to \a nbTimes * \c this->getNumberOfTuples.
2003  * \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.
2004  */
2005 DataArrayDouble *DataArrayDouble::duplicateEachTupleNTimes(int nbTimes) const
2006 {
2007   checkAllocated();
2008   if(getNumberOfComponents()!=1)
2009     throw INTERP_KERNEL::Exception("DataArrayDouble::duplicateEachTupleNTimes : this should have only one component !");
2010   if(nbTimes<1)
2011     throw INTERP_KERNEL::Exception("DataArrayDouble::duplicateEachTupleNTimes : nb times should be >= 1 !");
2012   int nbTuples=getNumberOfTuples();
2013   const double *inPtr=getConstPointer();
2014   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New(); ret->alloc(nbTimes*nbTuples,1);
2015   double *retPtr=ret->getPointer();
2016   for(int i=0;i<nbTuples;i++,inPtr++)
2017     {
2018       double val=*inPtr;
2019       for(int j=0;j<nbTimes;j++,retPtr++)
2020         *retPtr=val;
2021     }
2022   ret->copyStringInfoFrom(*this);
2023   return ret.retn();
2024 }
2025
2026 /*!
2027  * This methods returns the minimal distance between the two set of points \a this and \a other.
2028  * So \a this and \a other have to have the same number of components. If not an INTERP_KERNEL::Exception will be thrown.
2029  * This method works only if number of components of \a this (equal to those of \a other) is in 1, 2 or 3.
2030  *
2031  * \param [out] thisTupleId the tuple id in \a this corresponding to the returned minimal distance
2032  * \param [out] otherTupleId the tuple id in \a other corresponding to the returned minimal distance
2033  * \return the minimal distance between the two set of points \a this and \a other.
2034  * \sa DataArrayDouble::findClosestTupleId
2035  */
2036 double DataArrayDouble::minimalDistanceTo(const DataArrayDouble *other, int& thisTupleId, int& otherTupleId) const
2037 {
2038   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> part1=findClosestTupleId(other);
2039   int nbOfCompo(getNumberOfComponents());
2040   int otherNbTuples(other->getNumberOfTuples());
2041   const double *thisPt(begin()),*otherPt(other->begin());
2042   const int *part1Pt(part1->begin());
2043   double ret=std::numeric_limits<double>::max();
2044   for(int i=0;i<otherNbTuples;i++,part1Pt++,otherPt+=nbOfCompo)
2045     {
2046       double tmp(0.);
2047       for(int j=0;j<nbOfCompo;j++)
2048         tmp+=(otherPt[j]-thisPt[nbOfCompo*(*part1Pt)+j])*(otherPt[j]-thisPt[nbOfCompo*(*part1Pt)+j]);
2049       if(tmp<ret)
2050         { ret=tmp; thisTupleId=*part1Pt; otherTupleId=i; }
2051     }
2052   return sqrt(ret);
2053 }
2054
2055 /*!
2056  * This methods returns for each tuple in \a other which tuple in \a this is the closest.
2057  * So \a this and \a other have to have the same number of components. If not an INTERP_KERNEL::Exception will be thrown.
2058  * This method works only if number of components of \a this (equal to those of \a other) is in 1, 2 or 3.
2059  *
2060  * \return a newly allocated (new object to be dealt by the caller) DataArrayInt having \c other->getNumberOfTuples() tuples and one components.
2061  * \sa DataArrayDouble::minimalDistanceTo
2062  */
2063 DataArrayInt *DataArrayDouble::findClosestTupleId(const DataArrayDouble *other) const
2064 {
2065   if(!other)
2066     throw INTERP_KERNEL::Exception("DataArrayDouble::findClosestTupleId : other instance is NULL !");
2067   checkAllocated(); other->checkAllocated();
2068   int nbOfCompo=getNumberOfComponents();
2069   if(nbOfCompo!=other->getNumberOfComponents())
2070     {
2071       std::ostringstream oss; oss << "DataArrayDouble::findClosestTupleId : number of components in this is " << nbOfCompo;
2072       oss << ", whereas number of components in other is " << other->getNumberOfComponents() << "! Should be equal !";
2073       throw INTERP_KERNEL::Exception(oss.str().c_str());
2074     }
2075   int nbOfTuples=other->getNumberOfTuples();
2076   int thisNbOfTuples=getNumberOfTuples();
2077   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbOfTuples,1);
2078   double bounds[6];
2079   getMinMaxPerComponent(bounds);
2080   switch(nbOfCompo)
2081     {
2082     case 3:
2083       {
2084         double xDelta(fabs(bounds[1]-bounds[0])),yDelta(fabs(bounds[3]-bounds[2])),zDelta(fabs(bounds[5]-bounds[4]));
2085         double delta=std::max(xDelta,yDelta); delta=std::max(delta,zDelta);
2086         double characSize=pow((delta*delta*delta)/((double)thisNbOfTuples),1./3.);
2087         BBTreePts<3,int> myTree(begin(),0,0,getNumberOfTuples(),characSize*1e-12);
2088         FindClosestTupleIdAlg<3>(myTree,3.*characSize*characSize,other->begin(),nbOfTuples,begin(),thisNbOfTuples,ret->getPointer());
2089         break;
2090       }
2091     case 2:
2092       {
2093         double xDelta(fabs(bounds[1]-bounds[0])),yDelta(fabs(bounds[3]-bounds[2]));
2094         double delta=std::max(xDelta,yDelta);
2095         double characSize=sqrt(delta/(double)thisNbOfTuples);
2096         BBTreePts<2,int> myTree(begin(),0,0,getNumberOfTuples(),characSize*1e-12);
2097         FindClosestTupleIdAlg<2>(myTree,2.*characSize*characSize,other->begin(),nbOfTuples,begin(),thisNbOfTuples,ret->getPointer());
2098         break;
2099       }
2100     case 1:
2101       {
2102         double characSize=fabs(bounds[1]-bounds[0])/thisNbOfTuples;
2103         BBTreePts<1,int> myTree(begin(),0,0,getNumberOfTuples(),characSize*1e-12);
2104         FindClosestTupleIdAlg<1>(myTree,1.*characSize*characSize,other->begin(),nbOfTuples,begin(),thisNbOfTuples,ret->getPointer());
2105         break;
2106       }
2107     default:
2108       throw INTERP_KERNEL::Exception("Unexpected spacedim of coords for findClosestTupleId. Must be 1, 2 or 3.");
2109     }
2110   return ret.retn();
2111 }
2112
2113 /*!
2114  * This method expects that \a this and \a otherBBoxFrmt arrays are bounding box arrays ( as the output of MEDCouplingPointSet::getBoundingBoxForBBTree method ).
2115  * 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
2116  * how many bounding boxes in \a otherBBoxFrmt.
2117  * So, this method expects that \a this and \a otherBBoxFrmt have the same number of components.
2118  *
2119  * \param [in] otherBBoxFrmt - It is an array .
2120  * \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.
2121  * \sa MEDCouplingPointSet::getBoundingBoxForBBTree
2122  * \throw If \a this and \a otherBBoxFrmt have not the same number of components.
2123  * \throw If \a this and \a otherBBoxFrmt number of components is not even (BBox format).
2124  */
2125 DataArrayInt *DataArrayDouble::computeNbOfInteractionsWith(const DataArrayDouble *otherBBoxFrmt, double eps) const
2126 {
2127   if(!otherBBoxFrmt)
2128     throw INTERP_KERNEL::Exception("DataArrayDouble::computeNbOfInteractionsWith : input array is NULL !");
2129   if(!isAllocated() || !otherBBoxFrmt->isAllocated())
2130     throw INTERP_KERNEL::Exception("DataArrayDouble::computeNbOfInteractionsWith : this and input array must be allocated !");
2131   int nbOfComp(getNumberOfComponents()),nbOfTuples(getNumberOfTuples());
2132   if(nbOfComp!=otherBBoxFrmt->getNumberOfComponents())
2133     {
2134       std::ostringstream oss; oss << "DataArrayDouble::computeNbOfInteractionsWith : this number of components (" << nbOfComp << ") must be equal to the number of components of input array (" << otherBBoxFrmt->getNumberOfComponents() << ") !";
2135       throw INTERP_KERNEL::Exception(oss.str().c_str());
2136     }
2137   if(nbOfComp%2!=0)
2138     {
2139       std::ostringstream oss; oss << "DataArrayDouble::computeNbOfInteractionsWith : Number of components (" << nbOfComp << ") is not even ! It should be to be compatible with bbox format !";
2140       throw INTERP_KERNEL::Exception(oss.str().c_str());
2141     }
2142   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(nbOfTuples,1);
2143   const double *thisBBPtr(begin());
2144   int *retPtr(ret->getPointer());
2145   switch(nbOfComp/2)
2146     {
2147     case 3:
2148       {
2149         BBTree<3,int> bbt(otherBBoxFrmt->begin(),0,0,otherBBoxFrmt->getNumberOfTuples(),eps);
2150         for(int i=0;i<nbOfTuples;i++,retPtr++,thisBBPtr+=nbOfComp)
2151           *retPtr=bbt.getNbOfIntersectingElems(thisBBPtr);
2152         break;
2153       }
2154     case 2:
2155       {
2156         BBTree<2,int> bbt(otherBBoxFrmt->begin(),0,0,otherBBoxFrmt->getNumberOfTuples(),eps);
2157         for(int i=0;i<nbOfTuples;i++,retPtr++,thisBBPtr+=nbOfComp)
2158           *retPtr=bbt.getNbOfIntersectingElems(thisBBPtr);
2159         break;
2160       }
2161     case 1:
2162       {
2163         BBTree<1,int> bbt(otherBBoxFrmt->begin(),0,0,otherBBoxFrmt->getNumberOfTuples(),eps);
2164         for(int i=0;i<nbOfTuples;i++,retPtr++,thisBBPtr+=nbOfComp)
2165           *retPtr=bbt.getNbOfIntersectingElems(thisBBPtr);
2166         break;
2167       }
2168     default:
2169       throw INTERP_KERNEL::Exception("DataArrayDouble::computeNbOfInteractionsWith : space dimension supported are [1,2,3] !");
2170     }
2171   
2172   return ret.retn();
2173 }
2174
2175 /*!
2176  * Returns a copy of \a this array by excluding coincident tuples. Each tuple is
2177  * considered as coordinates of a point in getNumberOfComponents()-dimensional
2178  * space. The distance between tuples is computed using norm2. If several tuples are
2179  * not far each from other than \a prec, only one of them remains in the result
2180  * array. The order of tuples in the result array is same as in \a this one except
2181  * that coincident tuples are excluded.
2182  *  \param [in] prec - minimal absolute distance between two tuples at which they are
2183  *              considered not coincident.
2184  *  \param [in] limitTupleId - limit tuple id. If all tuples within a group of coincident
2185  *              tuples have id strictly lower than \a limitTupleId then they are not excluded.
2186  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
2187  *          is to delete using decrRef() as it is no more needed.
2188  *  \throw If \a this is not allocated.
2189  *  \throw If the number of components is not in [1,2,3].
2190  *
2191  *  \ref py_mcdataarraydouble_getdifferentvalues "Here is a Python example".
2192  */
2193 DataArrayDouble *DataArrayDouble::getDifferentValues(double prec, int limitTupleId) const
2194 {
2195   checkAllocated();
2196   DataArrayInt *c0=0,*cI0=0;
2197   findCommonTuples(prec,limitTupleId,c0,cI0);
2198   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> c(c0),cI(cI0);
2199   int newNbOfTuples=-1;
2200   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> o2n=DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2(getNumberOfTuples(),c0->begin(),cI0->begin(),cI0->end(),newNbOfTuples);
2201   return renumberAndReduce(o2n->getConstPointer(),newNbOfTuples);
2202 }
2203
2204 /*!
2205  * Copy all components in a specified order from another DataArrayDouble.
2206  * Both numerical and textual data is copied. The number of tuples in \a this and
2207  * the other array can be different.
2208  *  \param [in] a - the array to copy data from.
2209  *  \param [in] compoIds - sequence of zero based indices of components, data of which is
2210  *              to be copied.
2211  *  \throw If \a a is NULL.
2212  *  \throw If \a compoIds.size() != \a a->getNumberOfComponents().
2213  *  \throw If \a compoIds[i] < 0 or \a compoIds[i] > \a this->getNumberOfComponents().
2214  *
2215  *  \ref py_mcdataarraydouble_setselectedcomponents "Here is a Python example".
2216  */
2217 void DataArrayDouble::setSelectedComponents(const DataArrayDouble *a, const std::vector<int>& compoIds)
2218 {
2219   if(!a)
2220     throw INTERP_KERNEL::Exception("DataArrayDouble::setSelectedComponents : input DataArrayDouble is NULL !");
2221   checkAllocated();
2222   copyPartOfStringInfoFrom2(compoIds,*a);
2223   std::size_t partOfCompoSz=compoIds.size();
2224   int nbOfCompo=getNumberOfComponents();
2225   int nbOfTuples=std::min(getNumberOfTuples(),a->getNumberOfTuples());
2226   const double *ac=a->getConstPointer();
2227   double *nc=getPointer();
2228   for(int i=0;i<nbOfTuples;i++)
2229     for(std::size_t j=0;j<partOfCompoSz;j++,ac++)
2230       nc[nbOfCompo*i+compoIds[j]]=*ac;
2231 }
2232
2233 /*!
2234  * Copy all values from another DataArrayDouble into specified tuples and components
2235  * of \a this array. Textual data is not copied.
2236  * The tree parameters defining set of indices of tuples and components are similar to
2237  * the tree parameters of the Python function \c range(\c start,\c stop,\c step).
2238  *  \param [in] a - the array to copy values from.
2239  *  \param [in] bgTuples - index of the first tuple of \a this array to assign values to.
2240  *  \param [in] endTuples - index of the tuple before which the tuples to assign to
2241  *              are located.
2242  *  \param [in] stepTuples - index increment to get index of the next tuple to assign to.
2243  *  \param [in] bgComp - index of the first component of \a this array to assign values to.
2244  *  \param [in] endComp - index of the component before which the components to assign
2245  *              to are located.
2246  *  \param [in] stepComp - index increment to get index of the next component to assign to.
2247  *  \param [in] strictCompoCompare - if \a true (by default), then \a a->getNumberOfComponents() 
2248  *              must be equal to the number of columns to assign to, else an
2249  *              exception is thrown; if \a false, then it is only required that \a
2250  *              a->getNbOfElems() equals to number of values to assign to (this condition
2251  *              must be respected even if \a strictCompoCompare is \a true). The number of 
2252  *              values to assign to is given by following Python expression:
2253  *              \a nbTargetValues = 
2254  *              \c len(\c range(\a bgTuples,\a endTuples,\a stepTuples)) *
2255  *              \c len(\c range(\a bgComp,\a endComp,\a stepComp)).
2256  *  \throw If \a a is NULL.
2257  *  \throw If \a a is not allocated.
2258  *  \throw If \a this is not allocated.
2259  *  \throw If parameters specifying tuples and components to assign to do not give a
2260  *            non-empty range of increasing indices.
2261  *  \throw If \a a->getNbOfElems() != \a nbTargetValues.
2262  *  \throw If \a strictCompoCompare == \a true && \a a->getNumberOfComponents() !=
2263  *            \c len(\c range(\a bgComp,\a endComp,\a stepComp)).
2264  *
2265  *  \ref py_mcdataarraydouble_setpartofvalues1 "Here is a Python example".
2266  */
2267 void DataArrayDouble::setPartOfValues1(const DataArrayDouble *a, int bgTuples, int endTuples, int stepTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare)
2268 {
2269   if(!a)
2270     throw INTERP_KERNEL::Exception("DataArrayDouble::setPartOfValues1 : input DataArrayDouble is NULL !");
2271   const char msg[]="DataArrayDouble::setPartOfValues1";
2272   checkAllocated();
2273   a->checkAllocated();
2274   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
2275   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
2276   int nbComp=getNumberOfComponents();
2277   int nbOfTuples=getNumberOfTuples();
2278   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
2279   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
2280   bool assignTech=true;
2281   if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
2282     {
2283       if(strictCompoCompare)
2284         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
2285     }
2286   else
2287     {
2288       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
2289       assignTech=false;
2290     }
2291   const double *srcPt=a->getConstPointer();
2292   double *pt=getPointer()+bgTuples*nbComp+bgComp;
2293   if(assignTech)
2294     {
2295       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
2296         for(int j=0;j<newNbOfComp;j++,srcPt++)
2297           pt[j*stepComp]=*srcPt;
2298     }
2299   else
2300     {
2301       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
2302         {
2303           const double *srcPt2=srcPt;
2304           for(int j=0;j<newNbOfComp;j++,srcPt2++)
2305             pt[j*stepComp]=*srcPt2;
2306         }
2307     }
2308 }
2309
2310 /*!
2311  * Assign a given value to values at specified tuples and components of \a this array.
2312  * The tree parameters defining set of indices of tuples and components are similar to
2313  * the tree parameters of the Python function \c range(\c start,\c stop,\c step)..
2314  *  \param [in] a - the value to assign.
2315  *  \param [in] bgTuples - index of the first tuple of \a this array to assign to.
2316  *  \param [in] endTuples - index of the tuple before which the tuples to assign to
2317  *              are located.
2318  *  \param [in] stepTuples - index increment to get index of the next tuple to assign to.
2319  *  \param [in] bgComp - index of the first component of \a this array to assign to.
2320  *  \param [in] endComp - index of the component before which the components to assign
2321  *              to are located.
2322  *  \param [in] stepComp - index increment to get index of the next component to assign to.
2323  *  \throw If \a this is not allocated.
2324  *  \throw If parameters specifying tuples and components to assign to, do not give a
2325  *            non-empty range of increasing indices or indices are out of a valid range
2326  *            for \this array.
2327  *
2328  *  \ref py_mcdataarraydouble_setpartofvaluessimple1 "Here is a Python example".
2329  */
2330 void DataArrayDouble::setPartOfValuesSimple1(double a, int bgTuples, int endTuples, int stepTuples, int bgComp, int endComp, int stepComp)
2331 {
2332   const char msg[]="DataArrayDouble::setPartOfValuesSimple1";
2333   checkAllocated();
2334   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
2335   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
2336   int nbComp=getNumberOfComponents();
2337   int nbOfTuples=getNumberOfTuples();
2338   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
2339   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
2340   double *pt=getPointer()+bgTuples*nbComp+bgComp;
2341   for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
2342     for(int j=0;j<newNbOfComp;j++)
2343       pt[j*stepComp]=a;
2344 }
2345
2346 /*!
2347  * Copy all values from another DataArrayDouble (\a a) into specified tuples and 
2348  * components of \a this array. Textual data is not copied.
2349  * The tuples and components to assign to are defined by C arrays of indices.
2350  * There are two *modes of usage*:
2351  * - If \a a->getNbOfElems() equals to number of values to assign to, then every value
2352  *   of \a a is assigned to its own location within \a this array. 
2353  * - If \a a includes one tuple, then all values of \a a are assigned to the specified
2354  *   components of every specified tuple of \a this array. In this mode it is required
2355  *   that \a a->getNumberOfComponents() equals to the number of specified components.
2356  *
2357  *  \param [in] a - the array to copy values from.
2358  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
2359  *              assign values of \a a to.
2360  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
2361  *              pointer to a tuple index <em>(pi)</em> varies as this: 
2362  *              \a bgTuples <= \a pi < \a endTuples.
2363  *  \param [in] bgComp - pointer to an array of component indices of \a this array to
2364  *              assign values of \a a to.
2365  *  \param [in] endComp - specifies the end of the array \a bgTuples, so that
2366  *              pointer to a component index <em>(pi)</em> varies as this: 
2367  *              \a bgComp <= \a pi < \a endComp.
2368  *  \param [in] strictCompoCompare - this parameter is checked only if the
2369  *               *mode of usage* is the first; if it is \a true (default), 
2370  *               then \a a->getNumberOfComponents() must be equal 
2371  *               to the number of specified columns, else this is not required.
2372  *  \throw If \a a is NULL.
2373  *  \throw If \a a is not allocated.
2374  *  \throw If \a this is not allocated.
2375  *  \throw If any index of tuple/component given by <em>bgTuples / bgComp</em> is
2376  *         out of a valid range for \a this array.
2377  *  \throw In the first *mode of usage*, if <em>strictCompoCompare == true </em> and
2378  *         if <em> a->getNumberOfComponents() != (endComp - bgComp) </em>.
2379  *  \throw In the second *mode of usage*, if \a a->getNumberOfTuples() != 1 or
2380  *         <em> a->getNumberOfComponents() != (endComp - bgComp)</em>.
2381  *
2382  *  \ref py_mcdataarraydouble_setpartofvalues2 "Here is a Python example".
2383  */
2384 void DataArrayDouble::setPartOfValues2(const DataArrayDouble *a, const int *bgTuples, const int *endTuples, const int *bgComp, const int *endComp, bool strictCompoCompare)
2385 {
2386   if(!a)
2387     throw INTERP_KERNEL::Exception("DataArrayDouble::setPartOfValues2 : input DataArrayDouble is NULL !");
2388   const char msg[]="DataArrayDouble::setPartOfValues2";
2389   checkAllocated();
2390   a->checkAllocated();
2391   int nbComp=getNumberOfComponents();
2392   int nbOfTuples=getNumberOfTuples();
2393   for(const int *z=bgComp;z!=endComp;z++)
2394     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
2395   int newNbOfTuples=(int)std::distance(bgTuples,endTuples);
2396   int newNbOfComp=(int)std::distance(bgComp,endComp);
2397   bool assignTech=true;
2398   if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
2399     {
2400       if(strictCompoCompare)
2401         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
2402     }
2403   else
2404     {
2405       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
2406       assignTech=false;
2407     }
2408   double *pt=getPointer();
2409   const double *srcPt=a->getConstPointer();
2410   if(assignTech)
2411     {    
2412       for(const int *w=bgTuples;w!=endTuples;w++)
2413         {
2414           DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
2415           for(const int *z=bgComp;z!=endComp;z++,srcPt++)
2416             {    
2417               pt[(std::size_t)(*w)*nbComp+(*z)]=*srcPt;
2418             }
2419         }
2420     }
2421   else
2422     {
2423       for(const int *w=bgTuples;w!=endTuples;w++)
2424         {
2425           const double *srcPt2=srcPt;
2426           DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
2427           for(const int *z=bgComp;z!=endComp;z++,srcPt2++)
2428             {    
2429               pt[(std::size_t)(*w)*nbComp+(*z)]=*srcPt2;
2430             }
2431         }
2432     }
2433 }
2434
2435 /*!
2436  * Assign a given value to values at specified tuples and components of \a this array.
2437  * The tuples and components to assign to are defined by C arrays of indices.
2438  *  \param [in] a - the value to assign.
2439  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
2440  *              assign \a a to.
2441  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
2442  *              pointer to a tuple index (\a pi) varies as this: 
2443  *              \a bgTuples <= \a pi < \a endTuples.
2444  *  \param [in] bgComp - pointer to an array of component indices of \a this array to
2445  *              assign \a a to.
2446  *  \param [in] endComp - specifies the end of the array \a bgTuples, so that
2447  *              pointer to a component index (\a pi) varies as this: 
2448  *              \a bgComp <= \a pi < \a endComp.
2449  *  \throw If \a this is not allocated.
2450  *  \throw If any index of tuple/component given by <em>bgTuples / bgComp</em> is
2451  *         out of a valid range for \a this array.
2452  *
2453  *  \ref py_mcdataarraydouble_setpartofvaluessimple2 "Here is a Python example".
2454  */
2455 void DataArrayDouble::setPartOfValuesSimple2(double a, const int *bgTuples, const int *endTuples, const int *bgComp, const int *endComp)
2456 {
2457   checkAllocated();
2458   int nbComp=getNumberOfComponents();
2459   int nbOfTuples=getNumberOfTuples();
2460   for(const int *z=bgComp;z!=endComp;z++)
2461     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
2462   double *pt=getPointer();
2463   for(const int *w=bgTuples;w!=endTuples;w++)
2464     for(const int *z=bgComp;z!=endComp;z++)
2465       {
2466         DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
2467         pt[(std::size_t)(*w)*nbComp+(*z)]=a;
2468       }
2469 }
2470
2471 /*!
2472  * Copy all values from another DataArrayDouble (\a a) into specified tuples and 
2473  * components of \a this array. Textual data is not copied.
2474  * The tuples to assign to are defined by a C array of indices.
2475  * The components to assign to are defined by three values similar to parameters of
2476  * the Python function \c range(\c start,\c stop,\c step).
2477  * There are two *modes of usage*:
2478  * - If \a a->getNbOfElems() equals to number of values to assign to, then every value
2479  *   of \a a is assigned to its own location within \a this array. 
2480  * - If \a a includes one tuple, then all values of \a a are assigned to the specified
2481  *   components of every specified tuple of \a this array. In this mode it is required
2482  *   that \a a->getNumberOfComponents() equals to the number of specified components.
2483  *
2484  *  \param [in] a - the array to copy values from.
2485  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
2486  *              assign values of \a a to.
2487  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
2488  *              pointer to a tuple index <em>(pi)</em> varies as this: 
2489  *              \a bgTuples <= \a pi < \a endTuples.
2490  *  \param [in] bgComp - index of the first component of \a this array to assign to.
2491  *  \param [in] endComp - index of the component before which the components to assign
2492  *              to are located.
2493  *  \param [in] stepComp - index increment to get index of the next component to assign to.
2494  *  \param [in] strictCompoCompare - this parameter is checked only in the first
2495  *               *mode of usage*; if \a strictCompoCompare is \a true (default), 
2496  *               then \a a->getNumberOfComponents() must be equal 
2497  *               to the number of specified columns, else this is not required.
2498  *  \throw If \a a is NULL.
2499  *  \throw If \a a is not allocated.
2500  *  \throw If \a this is not allocated.
2501  *  \throw If any index of tuple given by \a bgTuples is out of a valid range for 
2502  *         \a this array.
2503  *  \throw In the first *mode of usage*, if <em>strictCompoCompare == true </em> and
2504  *         if <em> a->getNumberOfComponents()</em> is unequal to the number of components
2505  *         defined by <em>(bgComp,endComp,stepComp)</em>.
2506  *  \throw In the second *mode of usage*, if \a a->getNumberOfTuples() != 1 or
2507  *         <em> a->getNumberOfComponents()</em> is unequal to the number of components
2508  *         defined by <em>(bgComp,endComp,stepComp)</em>.
2509  *  \throw If parameters specifying components to assign to, do not give a
2510  *            non-empty range of increasing indices or indices are out of a valid range
2511  *            for \this array.
2512  *
2513  *  \ref py_mcdataarraydouble_setpartofvalues3 "Here is a Python example".
2514  */
2515 void DataArrayDouble::setPartOfValues3(const DataArrayDouble *a, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare)
2516 {
2517   if(!a)
2518     throw INTERP_KERNEL::Exception("DataArrayDouble::setPartOfValues3 : input DataArrayDouble is NULL !");
2519   const char msg[]="DataArrayDouble::setPartOfValues3";
2520   checkAllocated();
2521   a->checkAllocated();
2522   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
2523   int nbComp=getNumberOfComponents();
2524   int nbOfTuples=getNumberOfTuples();
2525   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
2526   int newNbOfTuples=(int)std::distance(bgTuples,endTuples);
2527   bool assignTech=true;
2528   if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
2529     {
2530       if(strictCompoCompare)
2531         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
2532     }
2533   else
2534     {
2535       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
2536       assignTech=false;
2537     }
2538   double *pt=getPointer()+bgComp;
2539   const double *srcPt=a->getConstPointer();
2540   if(assignTech)
2541     {
2542       for(const int *w=bgTuples;w!=endTuples;w++)
2543         for(int j=0;j<newNbOfComp;j++,srcPt++)
2544           {
2545             DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
2546             pt[(std::size_t)(*w)*nbComp+j*stepComp]=*srcPt;
2547           }
2548     }
2549   else
2550     {
2551       for(const int *w=bgTuples;w!=endTuples;w++)
2552         {
2553           const double *srcPt2=srcPt;
2554           for(int j=0;j<newNbOfComp;j++,srcPt2++)
2555             {
2556               DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
2557               pt[(std::size_t)(*w)*nbComp+j*stepComp]=*srcPt2;
2558             }
2559         }
2560     }
2561 }
2562
2563 /*!
2564  * Assign a given value to values at specified tuples and components of \a this array.
2565  * The tuples to assign to are defined by a C array of indices.
2566  * The components to assign to are defined by three values similar to parameters of
2567  * the Python function \c range(\c start,\c stop,\c step).
2568  *  \param [in] a - the value to assign.
2569  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
2570  *              assign \a a to.
2571  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
2572  *              pointer to a tuple index <em>(pi)</em> varies as this: 
2573  *              \a bgTuples <= \a pi < \a endTuples.
2574  *  \param [in] bgComp - index of the first component of \a this array to assign to.
2575  *  \param [in] endComp - index of the component before which the components to assign
2576  *              to are located.
2577  *  \param [in] stepComp - index increment to get index of the next component to assign to.
2578  *  \throw If \a this is not allocated.
2579  *  \throw If any index of tuple given by \a bgTuples is out of a valid range for 
2580  *         \a this array.
2581  *  \throw If parameters specifying components to assign to, do not give a
2582  *            non-empty range of increasing indices or indices are out of a valid range
2583  *            for \this array.
2584  *
2585  *  \ref py_mcdataarraydouble_setpartofvaluessimple3 "Here is a Python example".
2586  */
2587 void DataArrayDouble::setPartOfValuesSimple3(double a, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp)
2588 {
2589   const char msg[]="DataArrayDouble::setPartOfValuesSimple3";
2590   checkAllocated();
2591   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
2592   int nbComp=getNumberOfComponents();
2593   int nbOfTuples=getNumberOfTuples();
2594   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
2595   double *pt=getPointer()+bgComp;
2596   for(const int *w=bgTuples;w!=endTuples;w++)
2597     for(int j=0;j<newNbOfComp;j++)
2598       {
2599         DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
2600         pt[(std::size_t)(*w)*nbComp+j*stepComp]=a;
2601       }
2602 }
2603
2604 /*!
2605  * Copy all values from another DataArrayDouble into specified tuples and components
2606  * of \a this array. Textual data is not copied.
2607  * The tree parameters defining set of indices of tuples and components are similar to
2608  * the tree parameters of the Python function \c range(\c start,\c stop,\c step).
2609  *  \param [in] a - the array to copy values from.
2610  *  \param [in] bgTuples - index of the first tuple of \a this array to assign values to.
2611  *  \param [in] endTuples - index of the tuple before which the tuples to assign to
2612  *              are located.
2613  *  \param [in] stepTuples - index increment to get index of the next tuple to assign to.
2614  *  \param [in] bgComp - pointer to an array of component indices of \a this array to
2615  *              assign \a a to.
2616  *  \param [in] endComp - specifies the end of the array \a bgTuples, so that
2617  *              pointer to a component index (\a pi) varies as this: 
2618  *              \a bgComp <= \a pi < \a endComp.
2619  *  \param [in] strictCompoCompare - if \a true (by default), then \a a->getNumberOfComponents() 
2620  *              must be equal to the number of columns to assign to, else an
2621  *              exception is thrown; if \a false, then it is only required that \a
2622  *              a->getNbOfElems() equals to number of values to assign to (this condition
2623  *              must be respected even if \a strictCompoCompare is \a true). The number of 
2624  *              values to assign to is given by following Python expression:
2625  *              \a nbTargetValues = 
2626  *              \c len(\c range(\a bgTuples,\a endTuples,\a stepTuples)) *
2627  *              \c len(\c range(\a bgComp,\a endComp,\a stepComp)).
2628  *  \throw If \a a is NULL.
2629  *  \throw If \a a is not allocated.
2630  *  \throw If \a this is not allocated.
2631  *  \throw If parameters specifying tuples and components to assign to do not give a
2632  *            non-empty range of increasing indices.
2633  *  \throw If \a a->getNbOfElems() != \a nbTargetValues.
2634  *  \throw If \a strictCompoCompare == \a true && \a a->getNumberOfComponents() !=
2635  *            \c len(\c range(\a bgComp,\a endComp,\a stepComp)).
2636  *
2637  */
2638 void DataArrayDouble::setPartOfValues4(const DataArrayDouble *a, int bgTuples, int endTuples, int stepTuples, const int *bgComp, const int *endComp, bool strictCompoCompare)
2639 {
2640   if(!a)
2641     throw INTERP_KERNEL::Exception("DataArrayDouble::setPartOfValues4 : input DataArrayDouble is NULL !");
2642   const char msg[]="DataArrayDouble::setPartOfValues4";
2643   checkAllocated();
2644   a->checkAllocated();
2645   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
2646   int newNbOfComp=(int)std::distance(bgComp,endComp);
2647   int nbComp=getNumberOfComponents();
2648   for(const int *z=bgComp;z!=endComp;z++)
2649     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
2650   int nbOfTuples=getNumberOfTuples();
2651   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
2652   bool assignTech=true;
2653   if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
2654     {
2655       if(strictCompoCompare)
2656         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
2657     }
2658   else
2659     {
2660       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
2661       assignTech=false;
2662     }
2663   const double *srcPt=a->getConstPointer();
2664   double *pt=getPointer()+bgTuples*nbComp;
2665   if(assignTech)
2666     {
2667       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
2668         for(const int *z=bgComp;z!=endComp;z++,srcPt++)
2669           pt[*z]=*srcPt;
2670     }
2671   else
2672     {
2673       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
2674         {
2675           const double *srcPt2=srcPt;
2676           for(const int *z=bgComp;z!=endComp;z++,srcPt2++)
2677             pt[*z]=*srcPt2;
2678         }
2679     }
2680 }
2681
2682 void DataArrayDouble::setPartOfValuesSimple4(double a, int bgTuples, int endTuples, int stepTuples, const int *bgComp, const int *endComp)
2683 {
2684   const char msg[]="DataArrayDouble::setPartOfValuesSimple4";
2685   checkAllocated();
2686   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
2687   int nbComp=getNumberOfComponents();
2688   for(const int *z=bgComp;z!=endComp;z++)
2689     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
2690   int nbOfTuples=getNumberOfTuples();
2691   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
2692   double *pt=getPointer()+bgTuples*nbComp;
2693   for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
2694     for(const int *z=bgComp;z!=endComp;z++)
2695       pt[*z]=a;
2696 }
2697
2698 /*!
2699  * Copy some tuples from another DataArrayDouble into specified tuples
2700  * of \a this array. Textual data is not copied. Both arrays must have equal number of
2701  * components.
2702  * Both the tuples to assign and the tuples to assign to are defined by a DataArrayInt.
2703  * All components of selected tuples are copied.
2704  *  \param [in] a - the array to copy values from.
2705  *  \param [in] tuplesSelec - the array specifying both source tuples of \a a and
2706  *              target tuples of \a this. \a tuplesSelec has two components, and the
2707  *              first component specifies index of the source tuple and the second
2708  *              one specifies index of the target tuple.
2709  *  \throw If \a this is not allocated.
2710  *  \throw If \a a is NULL.
2711  *  \throw If \a a is not allocated.
2712  *  \throw If \a tuplesSelec is NULL.
2713  *  \throw If \a tuplesSelec is not allocated.
2714  *  \throw If <em>this->getNumberOfComponents() != a->getNumberOfComponents()</em>.
2715  *  \throw If \a tuplesSelec->getNumberOfComponents() != 2.
2716  *  \throw If any tuple index given by \a tuplesSelec is out of a valid range for 
2717  *         the corresponding (\a this or \a a) array.
2718  */
2719 void DataArrayDouble::setPartOfValuesAdv(const DataArrayDouble *a, const DataArrayInt *tuplesSelec)
2720 {
2721   if(!a || !tuplesSelec)
2722     throw INTERP_KERNEL::Exception("DataArrayDouble::setPartOfValuesAdv : input DataArrayDouble is NULL !");
2723   checkAllocated();
2724   a->checkAllocated();
2725   tuplesSelec->checkAllocated();
2726   int nbOfComp=getNumberOfComponents();
2727   if(nbOfComp!=a->getNumberOfComponents())
2728     throw INTERP_KERNEL::Exception("DataArrayDouble::setPartOfValuesAdv : This and a do not have the same number of components !");
2729   if(tuplesSelec->getNumberOfComponents()!=2)
2730     throw INTERP_KERNEL::Exception("DataArrayDouble::setPartOfValuesAdv : Expecting to have a tuple selector DataArrayInt instance with exactly 2 components !");
2731   int thisNt=getNumberOfTuples();
2732   int aNt=a->getNumberOfTuples();
2733   double *valsToSet=getPointer();
2734   const double *valsSrc=a->getConstPointer();
2735   for(const int *tuple=tuplesSelec->begin();tuple!=tuplesSelec->end();tuple+=2)
2736     {
2737       if(tuple[1]>=0 && tuple[1]<aNt)
2738         {
2739           if(tuple[0]>=0 && tuple[0]<thisNt)
2740             std::copy(valsSrc+nbOfComp*tuple[1],valsSrc+nbOfComp*(tuple[1]+1),valsToSet+nbOfComp*tuple[0]);
2741           else
2742             {
2743               std::ostringstream oss; oss << "DataArrayDouble::setPartOfValuesAdv : Tuple #" << std::distance(tuplesSelec->begin(),tuple)/2;
2744               oss << " of 'tuplesSelec' request of tuple id #" << tuple[0] << " in 'this' ! It should be in [0," << thisNt << ") !";
2745               throw INTERP_KERNEL::Exception(oss.str().c_str());
2746             }
2747         }
2748       else
2749         {
2750           std::ostringstream oss; oss << "DataArrayDouble::setPartOfValuesAdv : Tuple #" << std::distance(tuplesSelec->begin(),tuple)/2;
2751           oss << " of 'tuplesSelec' request of tuple id #" << tuple[1] << " in 'a' ! It should be in [0," << aNt << ") !";
2752           throw INTERP_KERNEL::Exception(oss.str().c_str());
2753         }
2754     }
2755 }
2756
2757 /*!
2758  * Copy some tuples from another DataArrayDouble (\a aBase) into contiguous tuples
2759  * of \a this array. Textual data is not copied. Both arrays must have equal number of
2760  * components.
2761  * The tuples to assign to are defined by index of the first tuple, and
2762  * their number is defined by \a tuplesSelec->getNumberOfTuples().
2763  * The tuples to copy are defined by values of a DataArrayInt.
2764  * All components of selected tuples are copied.
2765  *  \param [in] tupleIdStart - index of the first tuple of \a this array to assign
2766  *              values to.
2767  *  \param [in] aBase - the array to copy values from.
2768  *  \param [in] tuplesSelec - the array specifying tuples of \a a to copy.
2769  *  \throw If \a this is not allocated.
2770  *  \throw If \a aBase is NULL.
2771  *  \throw If \a aBase is not allocated.
2772  *  \throw If \a tuplesSelec is NULL.
2773  *  \throw If \a tuplesSelec is not allocated.
2774  *  \throw If <em>this->getNumberOfComponents() != aBase->getNumberOfComponents()</em>.
2775  *  \throw If \a tuplesSelec->getNumberOfComponents() != 1.
2776  *  \throw If <em>tupleIdStart + tuplesSelec->getNumberOfTuples() > this->getNumberOfTuples().</em>
2777  *  \throw If any tuple index given by \a tuplesSelec is out of a valid range for 
2778  *         \a aBase array.
2779  */
2780 void DataArrayDouble::setContigPartOfSelectedValues(int tupleIdStart, const DataArray *aBase, const DataArrayInt *tuplesSelec)
2781 {
2782   if(!aBase || !tuplesSelec)
2783     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues : input DataArray is NULL !");
2784   const DataArrayDouble *a=dynamic_cast<const DataArrayDouble *>(aBase);
2785   if(!a)
2786     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues : input DataArray aBase is not a DataArrayDouble !");
2787   checkAllocated();
2788   a->checkAllocated();
2789   tuplesSelec->checkAllocated();
2790   int nbOfComp=getNumberOfComponents();
2791   if(nbOfComp!=a->getNumberOfComponents())
2792     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues : This and a do not have the same number of components !");
2793   if(tuplesSelec->getNumberOfComponents()!=1)
2794     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues : Expecting to have a tuple selector DataArrayInt instance with exactly 1 component !");
2795   int thisNt=getNumberOfTuples();
2796   int aNt=a->getNumberOfTuples();
2797   int nbOfTupleToWrite=tuplesSelec->getNumberOfTuples();
2798   double *valsToSet=getPointer()+tupleIdStart*nbOfComp;
2799   if(tupleIdStart+nbOfTupleToWrite>thisNt)
2800     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues : invalid number range of values to write !");
2801   const double *valsSrc=a->getConstPointer();
2802   for(const int *tuple=tuplesSelec->begin();tuple!=tuplesSelec->end();tuple++,valsToSet+=nbOfComp)
2803     {
2804       if(*tuple>=0 && *tuple<aNt)
2805         {
2806           std::copy(valsSrc+nbOfComp*(*tuple),valsSrc+nbOfComp*(*tuple+1),valsToSet);
2807         }
2808       else
2809         {
2810           std::ostringstream oss; oss << "DataArrayDouble::setContigPartOfSelectedValues : Tuple #" << std::distance(tuplesSelec->begin(),tuple);
2811           oss << " of 'tuplesSelec' request of tuple id #" << *tuple << " in 'a' ! It should be in [0," << aNt << ") !";
2812           throw INTERP_KERNEL::Exception(oss.str().c_str());
2813         }
2814     }
2815 }
2816
2817 /*!
2818  * Copy some tuples from another DataArrayDouble (\a aBase) into contiguous tuples
2819  * of \a this array. Textual data is not copied. Both arrays must have equal number of
2820  * components.
2821  * The tuples to copy are defined by three values similar to parameters of
2822  * the Python function \c range(\c start,\c stop,\c step).
2823  * The tuples to assign to are defined by index of the first tuple, and
2824  * their number is defined by number of tuples to copy.
2825  * All components of selected tuples are copied.
2826  *  \param [in] tupleIdStart - index of the first tuple of \a this array to assign
2827  *              values to.
2828  *  \param [in] aBase - the array to copy values from.
2829  *  \param [in] bg - index of the first tuple to copy of the array \a aBase.
2830  *  \param [in] end2 - index of the tuple of \a aBase before which the tuples to copy
2831  *              are located.
2832  *  \param [in] step - index increment to get index of the next tuple to copy.
2833  *  \throw If \a this is not allocated.
2834  *  \throw If \a aBase is NULL.
2835  *  \throw If \a aBase is not allocated.
2836  *  \throw If <em>this->getNumberOfComponents() != aBase->getNumberOfComponents()</em>.
2837  *  \throw If <em>tupleIdStart + len(range(bg,end2,step)) > this->getNumberOfTuples().</em>
2838  *  \throw If parameters specifying tuples to copy, do not give a
2839  *            non-empty range of increasing indices or indices are out of a valid range
2840  *            for the array \a aBase.
2841  */
2842 void DataArrayDouble::setContigPartOfSelectedValues2(int tupleIdStart, const DataArray *aBase, int bg, int end2, int step)
2843 {
2844   if(!aBase)
2845     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues2 : input DataArray is NULL !");
2846   const DataArrayDouble *a=dynamic_cast<const DataArrayDouble *>(aBase);
2847   if(!a)
2848     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues2 : input DataArray aBase is not a DataArrayDouble !");
2849   checkAllocated();
2850   a->checkAllocated();
2851   int nbOfComp=getNumberOfComponents();
2852   const char msg[]="DataArrayDouble::setContigPartOfSelectedValues2";
2853   int nbOfTupleToWrite=DataArray::GetNumberOfItemGivenBES(bg,end2,step,msg);
2854   if(nbOfComp!=a->getNumberOfComponents())
2855     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues2 : This and a do not have the same number of components !");
2856   int thisNt=getNumberOfTuples();
2857   int aNt=a->getNumberOfTuples();
2858   double *valsToSet=getPointer()+tupleIdStart*nbOfComp;
2859   if(tupleIdStart+nbOfTupleToWrite>thisNt)
2860     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues2 : invalid number range of values to write !");
2861   if(end2>aNt)
2862     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues2 : invalid range of values to read !");
2863   const double *valsSrc=a->getConstPointer()+bg*nbOfComp;
2864   for(int i=0;i<nbOfTupleToWrite;i++,valsToSet+=nbOfComp,valsSrc+=step*nbOfComp)
2865     {
2866       std::copy(valsSrc,valsSrc+nbOfComp,valsToSet);
2867     }
2868 }
2869
2870 /*!
2871  * Returns a value located at specified tuple and component.
2872  * This method is equivalent to DataArrayDouble::getIJ() except that validity of
2873  * parameters is checked. So this method is safe but expensive if used to go through
2874  * all values of \a this.
2875  *  \param [in] tupleId - index of tuple of interest.
2876  *  \param [in] compoId - index of component of interest.
2877  *  \return double - value located by \a tupleId and \a compoId.
2878  *  \throw If \a this is not allocated.
2879  *  \throw If condition <em>( 0 <= tupleId < this->getNumberOfTuples() )</em> is violated.
2880  *  \throw If condition <em>( 0 <= compoId < this->getNumberOfComponents() )</em> is violated.
2881  */
2882 double DataArrayDouble::getIJSafe(int tupleId, int compoId) const
2883 {
2884   checkAllocated();
2885   if(tupleId<0 || tupleId>=getNumberOfTuples())
2886     {
2887       std::ostringstream oss; oss << "DataArrayDouble::getIJSafe : request for tupleId " << tupleId << " should be in [0," << getNumberOfTuples() << ") !";
2888       throw INTERP_KERNEL::Exception(oss.str().c_str());
2889     }
2890   if(compoId<0 || compoId>=getNumberOfComponents())
2891     {
2892       std::ostringstream oss; oss << "DataArrayDouble::getIJSafe : request for compoId " << compoId << " should be in [0," << getNumberOfComponents() << ") !";
2893       throw INTERP_KERNEL::Exception(oss.str().c_str());
2894     }
2895   return _mem[tupleId*_info_on_compo.size()+compoId];
2896 }
2897
2898 /*!
2899  * Returns the first value of \a this. 
2900  *  \return double - the last value of \a this array.
2901  *  \throw If \a this is not allocated.
2902  *  \throw If \a this->getNumberOfComponents() != 1.
2903  *  \throw If \a this->getNumberOfTuples() < 1.
2904  */
2905 double DataArrayDouble::front() const
2906 {
2907   checkAllocated();
2908   if(getNumberOfComponents()!=1)
2909     throw INTERP_KERNEL::Exception("DataArrayDouble::front : number of components not equal to one !");
2910   int nbOfTuples=getNumberOfTuples();
2911   if(nbOfTuples<1)
2912     throw INTERP_KERNEL::Exception("DataArrayDouble::front : number of tuples must be >= 1 !");
2913   return *(getConstPointer());
2914 }
2915
2916 /*!
2917  * Returns the last value of \a this. 
2918  *  \return double - the last value of \a this array.
2919  *  \throw If \a this is not allocated.
2920  *  \throw If \a this->getNumberOfComponents() != 1.
2921  *  \throw If \a this->getNumberOfTuples() < 1.
2922  */
2923 double DataArrayDouble::back() const
2924 {
2925   checkAllocated();
2926   if(getNumberOfComponents()!=1)
2927     throw INTERP_KERNEL::Exception("DataArrayDouble::back : number of components not equal to one !");
2928   int nbOfTuples=getNumberOfTuples();
2929   if(nbOfTuples<1)
2930     throw INTERP_KERNEL::Exception("DataArrayDouble::back : number of tuples must be >= 1 !");
2931   return *(getConstPointer()+nbOfTuples-1);
2932 }
2933
2934 void DataArrayDouble::SetArrayIn(DataArrayDouble *newArray, DataArrayDouble* &arrayToSet)
2935 {
2936   if(newArray!=arrayToSet)
2937     {
2938       if(arrayToSet)
2939         arrayToSet->decrRef();
2940       arrayToSet=newArray;
2941       if(arrayToSet)
2942         arrayToSet->incrRef();
2943     }
2944 }
2945
2946 /*!
2947  * Sets a C array to be used as raw data of \a this. The previously set info
2948  *  of components is retained and re-sized. 
2949  * For more info see \ref MEDCouplingArraySteps1.
2950  *  \param [in] array - the C array to be used as raw data of \a this.
2951  *  \param [in] ownership - if \a true, \a array will be deallocated at destruction of \a this.
2952  *  \param [in] type - specifies how to deallocate \a array. If \a type == ParaMEDMEM::CPP_DEALLOC,
2953  *                     \c delete [] \c array; will be called. If \a type == ParaMEDMEM::C_DEALLOC,
2954  *                     \c free(\c array ) will be called.
2955  *  \param [in] nbOfTuple - new number of tuples in \a this.
2956  *  \param [in] nbOfCompo - new number of components in \a this.
2957  */
2958 void DataArrayDouble::useArray(const double *array, bool ownership, DeallocType type, int nbOfTuple, int nbOfCompo)
2959 {
2960   _info_on_compo.resize(nbOfCompo);
2961   _mem.useArray(array,ownership,type,(std::size_t)nbOfTuple*nbOfCompo);
2962   declareAsNew();
2963 }
2964
2965 void DataArrayDouble::useExternalArrayWithRWAccess(const double *array, int nbOfTuple, int nbOfCompo)
2966 {
2967   _info_on_compo.resize(nbOfCompo);
2968   _mem.useExternalArrayWithRWAccess(array,(std::size_t)nbOfTuple*nbOfCompo);
2969   declareAsNew();
2970 }
2971
2972 /*!
2973  * Checks if 0.0 value is present in \a this array. If it is the case, an exception
2974  * is thrown.
2975  * \throw If zero is found in \a this array.
2976  */
2977 void DataArrayDouble::checkNoNullValues() const
2978 {
2979   const double *tmp=getConstPointer();
2980   std::size_t nbOfElems=getNbOfElems();
2981   const double *where=std::find(tmp,tmp+nbOfElems,0.);
2982   if(where!=tmp+nbOfElems)
2983     throw INTERP_KERNEL::Exception("A value 0.0 have been detected !");
2984 }
2985
2986 /*!
2987  * Computes minimal and maximal value in each component. An output array is filled
2988  * with \c 2 * \a this->getNumberOfComponents() values, so the caller is to allocate
2989  * enough memory before calling this method.
2990  *  \param [out] bounds - array of size at least 2 *\a this->getNumberOfComponents().
2991  *               It is filled as follows:<br>
2992  *               \a bounds[0] = \c min_of_component_0 <br>
2993  *               \a bounds[1] = \c max_of_component_0 <br>
2994  *               \a bounds[2] = \c min_of_component_1 <br>
2995  *               \a bounds[3] = \c max_of_component_1 <br>
2996  *               ...
2997  */
2998 void DataArrayDouble::getMinMaxPerComponent(double *bounds) const
2999 {
3000   checkAllocated();
3001   int dim=getNumberOfComponents();
3002   for (int idim=0; idim<dim; idim++)
3003     {
3004       bounds[idim*2]=std::numeric_limits<double>::max();
3005       bounds[idim*2+1]=-std::numeric_limits<double>::max();
3006     } 
3007   const double *ptr=getConstPointer();
3008   int nbOfTuples=getNumberOfTuples();
3009   for(int i=0;i<nbOfTuples;i++)
3010     {
3011       for(int idim=0;idim<dim;idim++)
3012         {
3013           if(bounds[idim*2]>ptr[i*dim+idim])
3014             {
3015               bounds[idim*2]=ptr[i*dim+idim];
3016             }
3017           if(bounds[idim*2+1]<ptr[i*dim+idim])
3018             {
3019               bounds[idim*2+1]=ptr[i*dim+idim];
3020             }
3021         }
3022     }
3023 }
3024
3025 /*!
3026  * This method retrieves a newly allocated DataArrayDouble instance having same number of tuples than \a this and twice number of components than \a this
3027  * to store both the min and max per component of each tuples. 
3028  * \param [in] epsilon the width of the bbox (identical in each direction) - 0.0 by default
3029  *
3030  * \return a newly created DataArrayDouble instance having \c this->getNumberOfTuples() tuples and 2 * \c this->getNumberOfComponent() components
3031  *
3032  * \throw If \a this is not allocated yet.
3033  */
3034 DataArrayDouble *DataArrayDouble::computeBBoxPerTuple(double epsilon) const
3035 {
3036   checkAllocated();
3037   const double *dataPtr=getConstPointer();
3038   int nbOfCompo=getNumberOfComponents();
3039   int nbTuples=getNumberOfTuples();
3040   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> bbox=DataArrayDouble::New();
3041   bbox->alloc(nbTuples,2*nbOfCompo);
3042   double *bboxPtr=bbox->getPointer();
3043   for(int i=0;i<nbTuples;i++)
3044     {
3045       for(int j=0;j<nbOfCompo;j++)
3046         {
3047           bboxPtr[2*nbOfCompo*i+2*j]=dataPtr[nbOfCompo*i+j]-epsilon;
3048           bboxPtr[2*nbOfCompo*i+2*j+1]=dataPtr[nbOfCompo*i+j]+epsilon;
3049         }
3050     }
3051   return bbox.retn();
3052 }
3053
3054 /*!
3055  * For each tuples **t** in \a other, this method retrieves tuples in \a this that are equal to **t**.
3056  * Two tuples are considered equal if the euclidian distance between the two tuples is lower than \a eps.
3057  * 
3058  * \param [in] other a DataArrayDouble having same number of components than \a this.
3059  * \param [in] eps absolute precision representing distance (using infinite norm) between 2 tuples behind which 2 tuples are considered equal.
3060  * \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.
3061  *             \a cI allows to extract information in \a c.
3062  * \param [out] cI is an indirection array that allows to extract the data contained in \a c.
3063  *
3064  * \throw In case of:
3065  *  - \a this is not allocated
3066  *  - \a other is not allocated or null
3067  *  - \a this and \a other do not have the same number of components
3068  *  - if number of components of \a this is not in [1,2,3]
3069  *
3070  * \sa MEDCouplingPointSet::getNodeIdsNearPoints, DataArrayDouble::getDifferentValues
3071  */
3072 void DataArrayDouble::computeTupleIdsNearTuples(const DataArrayDouble *other, double eps, DataArrayInt *& c, DataArrayInt *& cI) const
3073 {
3074   if(!other)
3075     throw INTERP_KERNEL::Exception("DataArrayDouble::computeTupleIdsNearTuples : input pointer other is null !");
3076   checkAllocated();
3077   other->checkAllocated();
3078   int nbOfCompo=getNumberOfComponents();
3079   int otherNbOfCompo=other->getNumberOfComponents();
3080   if(nbOfCompo!=otherNbOfCompo)
3081     throw INTERP_KERNEL::Exception("DataArrayDouble::computeTupleIdsNearTuples : number of components should be equal between this and other !");
3082   int nbOfTuplesOther=other->getNumberOfTuples();
3083   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cArr(DataArrayInt::New()),cIArr(DataArrayInt::New()); cArr->alloc(0,1); cIArr->pushBackSilent(0);
3084   switch(nbOfCompo)
3085     {
3086     case 3:
3087       {
3088         BBTreePts<3,int> myTree(begin(),0,0,getNumberOfTuples(),eps);
3089         FindTupleIdsNearTuplesAlg<3>(myTree,other->getConstPointer(),nbOfTuplesOther,eps,cArr,cIArr);
3090         break;
3091       }
3092     case 2:
3093       {
3094         BBTreePts<2,int> myTree(begin(),0,0,getNumberOfTuples(),eps);
3095         FindTupleIdsNearTuplesAlg<2>(myTree,other->getConstPointer(),nbOfTuplesOther,eps,cArr,cIArr);
3096         break;
3097       }
3098     case 1:
3099       {
3100         BBTreePts<1,int> myTree(begin(),0,0,getNumberOfTuples(),eps);
3101         FindTupleIdsNearTuplesAlg<1>(myTree,other->getConstPointer(),nbOfTuplesOther,eps,cArr,cIArr);
3102         break;
3103       }
3104     default:
3105       throw INTERP_KERNEL::Exception("Unexpected spacedim of coords for computeTupleIdsNearTuples. Must be 1, 2 or 3.");
3106     }
3107   c=cArr.retn(); cI=cIArr.retn();
3108 }
3109
3110 /*!
3111  * 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
3112  * around origin of 'radius' 1.
3113  * 
3114  * \param [in] eps absolute epsilon. under that value of delta between max and min no scale is performed.
3115  */
3116 void DataArrayDouble::recenterForMaxPrecision(double eps)
3117 {
3118   checkAllocated();
3119   int dim=getNumberOfComponents();
3120   std::vector<double> bounds(2*dim);
3121   getMinMaxPerComponent(&bounds[0]);
3122   for(int i=0;i<dim;i++)
3123     {
3124       double delta=bounds[2*i+1]-bounds[2*i];
3125       double offset=(bounds[2*i]+bounds[2*i+1])/2.;
3126       if(delta>eps)
3127         applyLin(1./delta,-offset/delta,i);
3128       else
3129         applyLin(1.,-offset,i);
3130     }
3131 }
3132
3133 /*!
3134  * Returns the maximal value and its location within \a this one-dimensional array.
3135  *  \param [out] tupleId - index of the tuple holding the maximal value.
3136  *  \return double - the maximal value among all values of \a this array.
3137  *  \throw If \a this->getNumberOfComponents() != 1
3138  *  \throw If \a this->getNumberOfTuples() < 1
3139  */
3140 double DataArrayDouble::getMaxValue(int& tupleId) const
3141 {
3142   checkAllocated();
3143   if(getNumberOfComponents()!=1)
3144     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 !");
3145   int nbOfTuples=getNumberOfTuples();
3146   if(nbOfTuples<=0)
3147     throw INTERP_KERNEL::Exception("DataArrayDouble::getMaxValue : array exists but number of tuples must be > 0 !");
3148   const double *vals=getConstPointer();
3149   const double *loc=std::max_element(vals,vals+nbOfTuples);
3150   tupleId=(int)std::distance(vals,loc);
3151   return *loc;
3152 }
3153
3154 /*!
3155  * Returns the maximal value within \a this array that is allowed to have more than
3156  *  one component.
3157  *  \return double - the maximal value among all values of \a this array.
3158  *  \throw If \a this is not allocated.
3159  */
3160 double DataArrayDouble::getMaxValueInArray() const
3161 {
3162   checkAllocated();
3163   const double *loc=std::max_element(begin(),end());
3164   return *loc;
3165 }
3166
3167 /*!
3168  * Returns the maximal value and all its locations within \a this one-dimensional array.
3169  *  \param [out] tupleIds - a new instance of DataArrayInt containg indices of
3170  *               tuples holding the maximal value. The caller is to delete it using
3171  *               decrRef() as it is no more needed.
3172  *  \return double - the maximal value among all values of \a this array.
3173  *  \throw If \a this->getNumberOfComponents() != 1
3174  *  \throw If \a this->getNumberOfTuples() < 1
3175  */
3176 double DataArrayDouble::getMaxValue2(DataArrayInt*& tupleIds) const
3177 {
3178   int tmp;
3179   tupleIds=0;
3180   double ret=getMaxValue(tmp);
3181   tupleIds=getIdsInRange(ret,ret);
3182   return ret;
3183 }
3184
3185 /*!
3186  * Returns the minimal value and its location within \a this one-dimensional array.
3187  *  \param [out] tupleId - index of the tuple holding the minimal value.
3188  *  \return double - the minimal value among all values of \a this array.
3189  *  \throw If \a this->getNumberOfComponents() != 1
3190  *  \throw If \a this->getNumberOfTuples() < 1
3191  */
3192 double DataArrayDouble::getMinValue(int& tupleId) const
3193 {
3194   checkAllocated();
3195   if(getNumberOfComponents()!=1)
3196     throw INTERP_KERNEL::Exception("DataArrayDouble::getMinValue : must be applied on DataArrayDouble with only one component, you can call 'rearrange' method before call 'getMinValueInArray' method !");
3197   int nbOfTuples=getNumberOfTuples();
3198   if(nbOfTuples<=0)
3199     throw INTERP_KERNEL::Exception("DataArrayDouble::getMinValue : array exists but number of tuples must be > 0 !");
3200   const double *vals=getConstPointer();
3201   const double *loc=std::min_element(vals,vals+nbOfTuples);
3202   tupleId=(int)std::distance(vals,loc);
3203   return *loc;
3204 }
3205
3206 /*!
3207  * Returns the minimal value within \a this array that is allowed to have more than
3208  *  one component.
3209  *  \return double - the minimal value among all values of \a this array.
3210  *  \throw If \a this is not allocated.
3211  */
3212 double DataArrayDouble::getMinValueInArray() const
3213 {
3214   checkAllocated();
3215   const double *loc=std::min_element(begin(),end());
3216   return *loc;
3217 }
3218
3219 /*!
3220  * Returns the minimal value and all its locations within \a this one-dimensional array.
3221  *  \param [out] tupleIds - a new instance of DataArrayInt containg indices of
3222  *               tuples holding the minimal value. The caller is to delete it using
3223  *               decrRef() as it is no more needed.
3224  *  \return double - the minimal value among all values of \a this array.
3225  *  \throw If \a this->getNumberOfComponents() != 1
3226  *  \throw If \a this->getNumberOfTuples() < 1
3227  */
3228 double DataArrayDouble::getMinValue2(DataArrayInt*& tupleIds) const
3229 {
3230   int tmp;
3231   tupleIds=0;
3232   double ret=getMinValue(tmp);
3233   tupleIds=getIdsInRange(ret,ret);
3234   return ret;
3235 }
3236
3237 /*!
3238  * 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.
3239  * This method only works for single component array.
3240  *
3241  * \return a value in [ 0, \c this->getNumberOfTuples() )
3242  *
3243  * \throw If \a this is not allocated
3244  *
3245  */
3246 int DataArrayDouble::count(double value, double eps) const
3247 {
3248   int ret=0;
3249   checkAllocated();
3250   if(getNumberOfComponents()!=1)
3251     throw INTERP_KERNEL::Exception("DataArrayDouble::count : must be applied on DataArrayDouble with only one component, you can call 'rearrange' method before !");
3252   const double *vals=begin();
3253   int nbOfTuples=getNumberOfTuples();
3254   for(int i=0;i<nbOfTuples;i++,vals++)
3255     if(fabs(*vals-value)<=eps)
3256       ret++;
3257   return ret;
3258 }
3259
3260 /*!
3261  * Returns the average value of \a this one-dimensional array.
3262  *  \return double - the average value over all values of \a this array.
3263  *  \throw If \a this->getNumberOfComponents() != 1
3264  *  \throw If \a this->getNumberOfTuples() < 1
3265  */
3266 double DataArrayDouble::getAverageValue() const
3267 {
3268   if(getNumberOfComponents()!=1)
3269     throw INTERP_KERNEL::Exception("DataArrayDouble::getAverageValue : must be applied on DataArrayDouble with only one component, you can call 'rearrange' method before !");
3270   int nbOfTuples=getNumberOfTuples();
3271   if(nbOfTuples<=0)
3272     throw INTERP_KERNEL::Exception("DataArrayDouble::getAverageValue : array exists but number of tuples must be > 0 !");
3273   const double *vals=getConstPointer();
3274   double ret=std::accumulate(vals,vals+nbOfTuples,0.);
3275   return ret/nbOfTuples;
3276 }
3277
3278 /*!
3279  * Returns the Euclidean norm of the vector defined by \a this array.
3280  *  \return double - the value of the Euclidean norm, i.e.
3281  *          the square root of the inner product of vector.
3282  *  \throw If \a this is not allocated.
3283  */
3284 double DataArrayDouble::norm2() const
3285 {
3286   checkAllocated();
3287   double ret=0.;
3288   std::size_t nbOfElems=getNbOfElems();
3289   const double *pt=getConstPointer();
3290   for(std::size_t i=0;i<nbOfElems;i++,pt++)
3291     ret+=(*pt)*(*pt);
3292   return sqrt(ret);
3293 }
3294
3295 /*!
3296  * Returns the maximum norm of the vector defined by \a this array.
3297  *  \return double - the value of the maximum norm, i.e.
3298  *          the maximal absolute value among values of \a this array.
3299  *  \throw If \a this is not allocated.
3300  */
3301 double DataArrayDouble::normMax() const
3302 {
3303   checkAllocated();
3304   double ret=-1.;
3305   std::size_t nbOfElems=getNbOfElems();
3306   const double *pt=getConstPointer();
3307   for(std::size_t i=0;i<nbOfElems;i++,pt++)
3308     {
3309       double val=std::abs(*pt);
3310       if(val>ret)
3311         ret=val;
3312     }
3313   return ret;
3314 }
3315
3316 /*!
3317  * Accumulates values of each component of \a this array.
3318  *  \param [out] res - an array of length \a this->getNumberOfComponents(), allocated 
3319  *         by the caller, that is filled by this method with sum value for each
3320  *         component.
3321  *  \throw If \a this is not allocated.
3322  */
3323 void DataArrayDouble::accumulate(double *res) const
3324 {
3325   checkAllocated();
3326   const double *ptr=getConstPointer();
3327   int nbTuple=getNumberOfTuples();
3328   int nbComps=getNumberOfComponents();
3329   std::fill(res,res+nbComps,0.);
3330   for(int i=0;i<nbTuple;i++)
3331     std::transform(ptr+i*nbComps,ptr+(i+1)*nbComps,res,res,std::plus<double>());
3332 }
3333
3334 /*!
3335  * This method returns the min distance from an external tuple defined by [ \a tupleBg , \a tupleEnd ) to \a this and
3336  * the first tuple in \a this that matches the returned distance. If there is no tuples in \a this an exception will be thrown.
3337  *
3338  *
3339  * \a this is expected to be allocated and expected to have a number of components equal to the distance from \a tupleBg to
3340  * \a tupleEnd. If not an exception will be thrown.
3341  *
3342  * \param [in] tupleBg start pointer (included) of input external tuple
3343  * \param [in] tupleEnd end pointer (not included) of input external tuple
3344  * \param [out] tupleId the tuple id in \a this that matches the min of distance between \a this and input external tuple
3345  * \return the min distance.
3346  * \sa MEDCouplingUMesh::distanceToPoint
3347  */
3348 double DataArrayDouble::distanceToTuple(const double *tupleBg, const double *tupleEnd, int& tupleId) const
3349 {
3350   checkAllocated();
3351   int nbTuple=getNumberOfTuples();
3352   int nbComps=getNumberOfComponents();
3353   if(nbComps!=(int)std::distance(tupleBg,tupleEnd))
3354     { 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()); }
3355   if(nbTuple==0)
3356     throw INTERP_KERNEL::Exception("DataArrayDouble::distanceToTuple : no tuple in this ! No distance to compute !");
3357   double ret0=std::numeric_limits<double>::max();
3358   tupleId=-1;
3359   const double *work=getConstPointer();
3360   for(int i=0;i<nbTuple;i++)
3361     {
3362       double val=0.;
3363       for(int j=0;j<nbComps;j++,work++) 
3364         val+=(*work-tupleBg[j])*((*work-tupleBg[j]));
3365       if(val>=ret0)
3366         continue;
3367       else
3368         { ret0=val; tupleId=i; }
3369     }
3370   return sqrt(ret0);
3371 }
3372
3373 /*!
3374  * Accumulate values of the given component of \a this array.
3375  *  \param [in] compId - the index of the component of interest.
3376  *  \return double - a sum value of \a compId-th component.
3377  *  \throw If \a this is not allocated.
3378  *  \throw If \a the condition ( 0 <= \a compId < \a this->getNumberOfComponents() ) is
3379  *         not respected.
3380  */
3381 double DataArrayDouble::accumulate(int compId) const
3382 {
3383   checkAllocated();
3384   const double *ptr=getConstPointer();
3385   int nbTuple=getNumberOfTuples();
3386   int nbComps=getNumberOfComponents();
3387   if(compId<0 || compId>=nbComps)
3388     throw INTERP_KERNEL::Exception("DataArrayDouble::accumulate : Invalid compId specified : No such nb of components !");
3389   double ret=0.;
3390   for(int i=0;i<nbTuple;i++)
3391     ret+=ptr[i*nbComps+compId];
3392   return ret;
3393 }
3394
3395 /*!
3396  * This method accumulate using addition tuples in \a this using input index array [ \a bgOfIndex, \a endOfIndex ).
3397  * The returned array will have same number of components than \a this and number of tuples equal to
3398  * \c std::distance(bgOfIndex,endOfIndex) \b minus \b one.
3399  *
3400  * The input index array is expected to be ascendingly sorted in which the all referenced ids should be in [0, \c this->getNumberOfTuples).
3401  * 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.
3402  *
3403  * \param [in] bgOfIndex - begin (included) of the input index array.
3404  * \param [in] endOfIndex - end (excluded) of the input index array.
3405  * \return DataArrayDouble * - the new instance having the same number of components than \a this.
3406  * 
3407  * \throw If bgOfIndex or end is NULL.
3408  * \throw If input index array is not ascendingly sorted.
3409  * \throw If there is an id in [ \a bgOfIndex, \a endOfIndex ) not in [0, \c this->getNumberOfTuples).
3410  * \throw If std::distance(bgOfIndex,endOfIndex)==0.
3411  */
3412 DataArrayDouble *DataArrayDouble::accumulatePerChunck(const int *bgOfIndex, const int *endOfIndex) const
3413 {
3414   if(!bgOfIndex || !endOfIndex)
3415     throw INTERP_KERNEL::Exception("DataArrayDouble::accumulatePerChunck : input pointer NULL !");
3416   checkAllocated();
3417   int nbCompo=getNumberOfComponents();
3418   int nbOfTuples=getNumberOfTuples();
3419   int sz=(int)std::distance(bgOfIndex,endOfIndex);
3420   if(sz<1)
3421     throw INTERP_KERNEL::Exception("DataArrayDouble::accumulatePerChunck : invalid size of input index array !");
3422   sz--;
3423   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New(); ret->alloc(sz,nbCompo);
3424   const int *w=bgOfIndex;
3425   if(*w<0 || *w>=nbOfTuples)
3426     throw INTERP_KERNEL::Exception("DataArrayDouble::accumulatePerChunck : The first element of the input index not in [0,nbOfTuples) !");
3427   const double *srcPt=begin()+(*w)*nbCompo;
3428   double *tmp=ret->getPointer();
3429   for(int i=0;i<sz;i++,tmp+=nbCompo,w++)
3430     {
3431       std::fill(tmp,tmp+nbCompo,0.);
3432       if(w[1]>=w[0])
3433         {
3434           for(int j=w[0];j<w[1];j++,srcPt+=nbCompo)
3435             {
3436               if(j>=0 && j<nbOfTuples)
3437                 std::transform(srcPt,srcPt+nbCompo,tmp,tmp,std::plus<double>());
3438               else
3439                 {
3440                   std::ostringstream oss; oss << "DataArrayDouble::accumulatePerChunck : At rank #" << i << " the input index array points to id " << j << " should be in [0," << nbOfTuples << ") !";
3441                   throw INTERP_KERNEL::Exception(oss.str().c_str());
3442                 }
3443             }
3444         }
3445       else
3446         {
3447           std::ostringstream oss; oss << "DataArrayDouble::accumulatePerChunck : At rank #" << i << " the input index array is not in ascendingly sorted.";
3448           throw INTERP_KERNEL::Exception(oss.str().c_str());
3449         }
3450     }
3451   ret->copyStringInfoFrom(*this);
3452   return ret.retn();
3453 }
3454
3455 /*!
3456  * Converts each 2D point defined by the tuple of \a this array from the Polar to the
3457  * Cartesian coordinate system. The two components of the tuple of \a this array are 
3458  * considered to contain (1) radius and (2) angle of the point in the Polar CS.
3459  *  \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
3460  *          contains X and Y coordinates of the point in the Cartesian CS. The caller
3461  *          is to delete this array using decrRef() as it is no more needed. The array
3462  *          does not contain any textual info on components.
3463  *  \throw If \a this->getNumberOfComponents() != 2.
3464  */
3465 DataArrayDouble *DataArrayDouble::fromPolarToCart() const
3466 {
3467   checkAllocated();
3468   int nbOfComp=getNumberOfComponents();
3469   if(nbOfComp!=2)
3470     throw INTERP_KERNEL::Exception("DataArrayDouble::fromPolarToCart : must be an array with exactly 2 components !");
3471   int nbOfTuple=getNumberOfTuples();
3472   DataArrayDouble *ret=DataArrayDouble::New();
3473   ret->alloc(nbOfTuple,2);
3474   double *w=ret->getPointer();
3475   const double *wIn=getConstPointer();
3476   for(int i=0;i<nbOfTuple;i++,w+=2,wIn+=2)
3477     {
3478       w[0]=wIn[0]*cos(wIn[1]);
3479       w[1]=wIn[0]*sin(wIn[1]);
3480     }
3481   return ret;
3482 }
3483
3484 /*!
3485  * Converts each 3D point defined by the tuple of \a this array from the Cylindrical to
3486  * the Cartesian coordinate system. The three components of the tuple of \a this array 
3487  * are considered to contain (1) radius, (2) azimuth and (3) altitude of the point in
3488  * the Cylindrical CS.
3489  *  \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
3490  *          contains X, Y and Z coordinates of the point in the Cartesian CS. The info
3491  *          on the third component is copied from \a this array. The caller
3492  *          is to delete this array using decrRef() as it is no more needed. 
3493  *  \throw If \a this->getNumberOfComponents() != 3.
3494  */
3495 DataArrayDouble *DataArrayDouble::fromCylToCart() const
3496 {
3497   checkAllocated();
3498   int nbOfComp=getNumberOfComponents();
3499   if(nbOfComp!=3)
3500     throw INTERP_KERNEL::Exception("DataArrayDouble::fromCylToCart : must be an array with exactly 3 components !");
3501   int nbOfTuple=getNumberOfTuples();
3502   DataArrayDouble *ret=DataArrayDouble::New();
3503   ret->alloc(getNumberOfTuples(),3);
3504   double *w=ret->getPointer();
3505   const double *wIn=getConstPointer();
3506   for(int i=0;i<nbOfTuple;i++,w+=3,wIn+=3)
3507     {
3508       w[0]=wIn[0]*cos(wIn[1]);
3509       w[1]=wIn[0]*sin(wIn[1]);
3510       w[2]=wIn[2];
3511     }
3512   ret->setInfoOnComponent(2,getInfoOnComponent(2).c_str());
3513   return ret;
3514 }
3515
3516 /*!
3517  * Converts each 3D point defined by the tuple of \a this array from the Spherical to
3518  * the Cartesian coordinate system. The three components of the tuple of \a this array 
3519  * are considered to contain (1) radius, (2) polar angle and (3) azimuthal angle of the
3520  * point in the Cylindrical CS.
3521  *  \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
3522  *          contains X, Y and Z coordinates of the point in the Cartesian CS. The info
3523  *          on the third component is copied from \a this array. The caller
3524  *          is to delete this array using decrRef() as it is no more needed.
3525  *  \throw If \a this->getNumberOfComponents() != 3.
3526  */
3527 DataArrayDouble *DataArrayDouble::fromSpherToCart() const
3528 {
3529   checkAllocated();
3530   int nbOfComp=getNumberOfComponents();
3531   if(nbOfComp!=3)
3532     throw INTERP_KERNEL::Exception("DataArrayDouble::fromSpherToCart : must be an array with exactly 3 components !");
3533   int nbOfTuple=getNumberOfTuples();
3534   DataArrayDouble *ret=DataArrayDouble::New();
3535   ret->alloc(getNumberOfTuples(),3);
3536   double *w=ret->getPointer();
3537   const double *wIn=getConstPointer();
3538   for(int i=0;i<nbOfTuple;i++,w+=3,wIn+=3)
3539     {
3540       w[0]=wIn[0]*cos(wIn[2])*sin(wIn[1]);
3541       w[1]=wIn[0]*sin(wIn[2])*sin(wIn[1]);
3542       w[2]=wIn[0]*cos(wIn[1]);
3543     }
3544   return ret;
3545 }
3546
3547 /*!
3548  * Computes the doubly contracted product of every tensor defined by the tuple of \a this
3549  * array contating 6 components.
3550  *  \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
3551  *          is calculated from the tuple <em>(t)</em> of \a this array as follows:
3552  *          \f$ t[0]^2+t[1]^2+t[2]^2+2*t[3]^2+2*t[4]^2+2*t[5]^2\f$.
3553  *         The caller is to delete this result array using decrRef() as it is no more needed. 
3554  *  \throw If \a this->getNumberOfComponents() != 6.
3555  */
3556 DataArrayDouble *DataArrayDouble::doublyContractedProduct() const
3557 {
3558   checkAllocated();
3559   int nbOfComp=getNumberOfComponents();
3560   if(nbOfComp!=6)
3561     throw INTERP_KERNEL::Exception("DataArrayDouble::doublyContractedProduct : must be an array with exactly 6 components !");
3562   DataArrayDouble *ret=DataArrayDouble::New();
3563   int nbOfTuple=getNumberOfTuples();
3564   ret->alloc(nbOfTuple,1);
3565   const double *src=getConstPointer();
3566   double *dest=ret->getPointer();
3567   for(int i=0;i<nbOfTuple;i++,dest++,src+=6)
3568     *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];
3569   return ret;
3570 }
3571
3572 /*!
3573  * Computes the determinant of every square matrix defined by the tuple of \a this
3574  * array, which contains either 4, 6 or 9 components. The case of 6 components
3575  * corresponds to that of the upper triangular matrix.
3576  *  \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
3577  *          is the determinant of matrix of the corresponding tuple of \a this array.
3578  *          The caller is to delete this result array using decrRef() as it is no more
3579  *          needed. 
3580  *  \throw If \a this->getNumberOfComponents() is not in [4,6,9].
3581  */
3582 DataArrayDouble *DataArrayDouble::determinant() const
3583 {
3584   checkAllocated();
3585   DataArrayDouble *ret=DataArrayDouble::New();
3586   int nbOfTuple=getNumberOfTuples();
3587   ret->alloc(nbOfTuple,1);
3588   const double *src=getConstPointer();
3589   double *dest=ret->getPointer();
3590   switch(getNumberOfComponents())
3591     {
3592     case 6:
3593       for(int i=0;i<nbOfTuple;i++,dest++,src+=6)
3594         *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];
3595       return ret;
3596     case 4:
3597       for(int i=0;i<nbOfTuple;i++,dest++,src+=4)
3598         *dest=src[0]*src[3]-src[1]*src[2];
3599       return ret;
3600     case 9:
3601       for(int i=0;i<nbOfTuple;i++,dest++,src+=9)
3602         *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];
3603       return ret;
3604     default:
3605       ret->decrRef();
3606       throw INTERP_KERNEL::Exception("DataArrayDouble::determinant : Invalid number of components ! must be in 4,6,9 !");
3607     }
3608 }
3609
3610 /*!
3611  * Computes 3 eigenvalues of every upper triangular matrix defined by the tuple of
3612  * \a this array, which contains 6 components.
3613  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing 3
3614  *          components, whose each tuple contains the eigenvalues of the matrix of
3615  *          corresponding tuple of \a this array. 
3616  *          The caller is to delete this result array using decrRef() as it is no more
3617  *          needed. 
3618  *  \throw If \a this->getNumberOfComponents() != 6.
3619  */
3620 DataArrayDouble *DataArrayDouble::eigenValues() const
3621 {
3622   checkAllocated();
3623   int nbOfComp=getNumberOfComponents();
3624   if(nbOfComp!=6)
3625     throw INTERP_KERNEL::Exception("DataArrayDouble::eigenValues : must be an array with exactly 6 components !");
3626   DataArrayDouble *ret=DataArrayDouble::New();
3627   int nbOfTuple=getNumberOfTuples();
3628   ret->alloc(nbOfTuple,3);
3629   const double *src=getConstPointer();
3630   double *dest=ret->getPointer();
3631   for(int i=0;i<nbOfTuple;i++,dest+=3,src+=6)
3632     INTERP_KERNEL::computeEigenValues6(src,dest);
3633   return ret;
3634 }
3635
3636 /*!
3637  * Computes 3 eigenvectors of every upper triangular matrix defined by the tuple of
3638  * \a this array, which contains 6 components.
3639  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing 9
3640  *          components, whose each tuple contains 3 eigenvectors of the matrix of
3641  *          corresponding tuple of \a this array.
3642  *          The caller is to delete this result array using decrRef() as it is no more
3643  *          needed.
3644  *  \throw If \a this->getNumberOfComponents() != 6.
3645  */
3646 DataArrayDouble *DataArrayDouble::eigenVectors() const
3647 {
3648   checkAllocated();
3649   int nbOfComp=getNumberOfComponents();
3650   if(nbOfComp!=6)
3651     throw INTERP_KERNEL::Exception("DataArrayDouble::eigenVectors : must be an array with exactly 6 components !");
3652   DataArrayDouble *ret=DataArrayDouble::New();
3653   int nbOfTuple=getNumberOfTuples();
3654   ret->alloc(nbOfTuple,9);
3655   const double *src=getConstPointer();
3656   double *dest=ret->getPointer();
3657   for(int i=0;i<nbOfTuple;i++,src+=6)
3658     {
3659       double tmp[3];
3660       INTERP_KERNEL::computeEigenValues6(src,tmp);
3661       for(int j=0;j<3;j++,dest+=3)
3662         INTERP_KERNEL::computeEigenVectorForEigenValue6(src,tmp[j],1e-12,dest);
3663     }
3664   return ret;
3665 }
3666
3667 /*!
3668  * Computes the inverse matrix of every matrix defined by the tuple of \a this
3669  * array, which contains either 4, 6 or 9 components. The case of 6 components
3670  * corresponds to that of the upper triangular matrix.
3671  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
3672  *          same number of components as \a this one, whose each tuple is the inverse
3673  *          matrix of the matrix of corresponding tuple of \a this array. 
3674  *          The caller is to delete this result array using decrRef() as it is no more
3675  *          needed. 
3676  *  \throw If \a this->getNumberOfComponents() is not in [4,6,9].
3677  */
3678 DataArrayDouble *DataArrayDouble::inverse() const
3679 {
3680   checkAllocated();
3681   int nbOfComp=getNumberOfComponents();
3682   if(nbOfComp!=6 && nbOfComp!=9 && nbOfComp!=4)
3683     throw INTERP_KERNEL::Exception("DataArrayDouble::inversion : must be an array with 4,6 or 9 components !");
3684   DataArrayDouble *ret=DataArrayDouble::New();
3685   int nbOfTuple=getNumberOfTuples();
3686   ret->alloc(nbOfTuple,nbOfComp);
3687   const double *src=getConstPointer();
3688   double *dest=ret->getPointer();
3689 if(nbOfComp==6)
3690     for(int i=0;i<nbOfTuple;i++,dest+=6,src+=6)
3691       {
3692         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];
3693         dest[0]=(src[1]*src[2]-src[4]*src[4])/det;
3694         dest[1]=(src[0]*src[2]-src[5]*src[5])/det;
3695         dest[2]=(src[0]*src[1]-src[3]*src[3])/det;
3696         dest[3]=(src[5]*src[4]-src[3]*src[2])/det;
3697         dest[4]=(src[5]*src[3]-src[0]*src[4])/det;
3698         dest[5]=(src[3]*src[4]-src[1]*src[5])/det;
3699       }
3700   else if(nbOfComp==4)
3701     for(int i=0;i<nbOfTuple;i++,dest+=4,src+=4)
3702       {
3703         double det=src[0]*src[3]-src[1]*src[2];
3704         dest[0]=src[3]/det;
3705         dest[1]=-src[1]/det;
3706         dest[2]=-src[2]/det;
3707         dest[3]=src[0]/det;
3708       }
3709   else
3710     for(int i=0;i<nbOfTuple;i++,dest+=9,src+=9)
3711       {
3712         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];
3713         dest[0]=(src[4]*src[8]-src[7]*src[5])/det;
3714         dest[1]=(src[7]*src[2]-src[1]*src[8])/det;
3715         dest[2]=(src[1]*src[5]-src[4]*src[2])/det;
3716         dest[3]=(src[6]*src[5]-src[3]*src[8])/det;
3717         dest[4]=(src[0]*src[8]-src[6]*src[2])/det;
3718         dest[5]=(src[2]*src[3]-src[0]*src[5])/det;
3719         dest[6]=(src[3]*src[7]-src[6]*src[4])/det;
3720         dest[7]=(src[6]*src[1]-src[0]*src[7])/det;
3721         dest[8]=(src[0]*src[4]-src[1]*src[3])/det;
3722       }
3723   return ret;
3724 }
3725
3726 /*!
3727  * Computes the trace of every matrix defined by the tuple of \a this
3728  * array, which contains either 4, 6 or 9 components. The case of 6 components
3729  * corresponds to that of the upper triangular matrix.
3730  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing 
3731  *          1 component, whose each tuple is the trace of
3732  *          the matrix of corresponding tuple of \a this array. 
3733  *          The caller is to delete this result array using decrRef() as it is no more
3734  *          needed. 
3735  *  \throw If \a this->getNumberOfComponents() is not in [4,6,9].
3736  */
3737 DataArrayDouble *DataArrayDouble::trace() const
3738 {
3739   checkAllocated();
3740   int nbOfComp=getNumberOfComponents();
3741   if(nbOfComp!=6 && nbOfComp!=9 && nbOfComp!=4)
3742     throw INTERP_KERNEL::Exception("DataArrayDouble::trace : must be an array with 4,6 or 9 components !");
3743   DataArrayDouble *ret=DataArrayDouble::New();
3744   int nbOfTuple=getNumberOfTuples();
3745   ret->alloc(nbOfTuple,1);
3746   const double *src=getConstPointer();
3747   double *dest=ret->getPointer();
3748   if(nbOfComp==6)
3749     for(int i=0;i<nbOfTuple;i++,dest++,src+=6)
3750       *dest=src[0]+src[1]+src[2];
3751   else if(nbOfComp==4)
3752     for(int i=0;i<nbOfTuple;i++,dest++,src+=4)
3753       *dest=src[0]+src[3];
3754   else
3755     for(int i=0;i<nbOfTuple;i++,dest++,src+=9)
3756       *dest=src[0]+src[4]+src[8];
3757   return ret;
3758 }
3759
3760 /*!
3761  * Computes the stress deviator tensor of every stress tensor defined by the tuple of
3762  * \a this array, which contains 6 components.
3763  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
3764  *          same number of components and tuples as \a this array.
3765  *          The caller is to delete this result array using decrRef() as it is no more
3766  *          needed.
3767  *  \throw If \a this->getNumberOfComponents() != 6.
3768  */
3769 DataArrayDouble *DataArrayDouble::deviator() const
3770 {
3771   checkAllocated();
3772   int nbOfComp=getNumberOfComponents();
3773   if(nbOfComp!=6)
3774     throw INTERP_KERNEL::Exception("DataArrayDouble::deviator : must be an array with exactly 6 components !");
3775   DataArrayDouble *ret=DataArrayDouble::New();
3776   int nbOfTuple=getNumberOfTuples();
3777   ret->alloc(nbOfTuple,6);
3778   const double *src=getConstPointer();
3779   double *dest=ret->getPointer();
3780   for(int i=0;i<nbOfTuple;i++,dest+=6,src+=6)
3781     {
3782       double tr=(src[0]+src[1]+src[2])/3.;
3783       dest[0]=src[0]-tr;
3784       dest[1]=src[1]-tr;
3785       dest[2]=src[2]-tr;
3786       dest[3]=src[3];
3787       dest[4]=src[4];
3788       dest[5]=src[5];
3789     }
3790   return ret;
3791 }
3792
3793 /*!
3794  * Computes the magnitude of every vector defined by the tuple of
3795  * \a this array.
3796  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
3797  *          same number of tuples as \a this array and one component.
3798  *          The caller is to delete this result array using decrRef() as it is no more
3799  *          needed.
3800  *  \throw If \a this is not allocated.
3801  */
3802 DataArrayDouble *DataArrayDouble::magnitude() const
3803 {
3804   checkAllocated();
3805   int nbOfComp=getNumberOfComponents();
3806   DataArrayDouble *ret=DataArrayDouble::New();
3807   int nbOfTuple=getNumberOfTuples();
3808   ret->alloc(nbOfTuple,1);
3809   const double *src=getConstPointer();
3810   double *dest=ret->getPointer();
3811   for(int i=0;i<nbOfTuple;i++,dest++)
3812     {
3813       double sum=0.;
3814       for(int j=0;j<nbOfComp;j++,src++)
3815         sum+=(*src)*(*src);
3816       *dest=sqrt(sum);
3817     }
3818   return ret;
3819 }
3820
3821 /*!
3822  * Computes the maximal value within every tuple of \a this array.
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  *  \sa DataArrayDouble::maxPerTupleWithCompoId
3829  */
3830 DataArrayDouble *DataArrayDouble::maxPerTuple() const
3831 {
3832   checkAllocated();
3833   int nbOfComp=getNumberOfComponents();
3834   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
3835   int nbOfTuple=getNumberOfTuples();
3836   ret->alloc(nbOfTuple,1);
3837   const double *src=getConstPointer();
3838   double *dest=ret->getPointer();
3839   for(int i=0;i<nbOfTuple;i++,dest++,src+=nbOfComp)
3840     *dest=*std::max_element(src,src+nbOfComp);
3841   return ret.retn();
3842 }
3843
3844 /*!
3845  * Computes the maximal value within every tuple of \a this array and it returns the first component
3846  * id for each tuple that corresponds to the maximal value within the tuple.
3847  * 
3848  *  \param [out] compoIdOfMaxPerTuple - the new new instance of DataArrayInt containing the
3849  *          same number of tuples and only one component.
3850  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
3851  *          same number of tuples as \a this array and one component.
3852  *          The caller is to delete this result array using decrRef() as it is no more
3853  *          needed.
3854  *  \throw If \a this is not allocated.
3855  *  \sa DataArrayDouble::maxPerTuple
3856  */
3857 DataArrayDouble *DataArrayDouble::maxPerTupleWithCompoId(DataArrayInt* &compoIdOfMaxPerTuple) const
3858 {
3859   checkAllocated();
3860   int nbOfComp=getNumberOfComponents();
3861   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret0=DataArrayDouble::New();
3862   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret1=DataArrayInt::New();
3863   int nbOfTuple=getNumberOfTuples();
3864   ret0->alloc(nbOfTuple,1); ret1->alloc(nbOfTuple,1);
3865   const double *src=getConstPointer();
3866   double *dest=ret0->getPointer(); int *dest1=ret1->getPointer();
3867   for(int i=0;i<nbOfTuple;i++,dest++,dest1++,src+=nbOfComp)
3868     {
3869       const double *loc=std::max_element(src,src+nbOfComp);
3870       *dest=*loc;
3871       *dest1=(int)std::distance(src,loc);
3872     }
3873   compoIdOfMaxPerTuple=ret1.retn();
3874   return ret0.retn();
3875 }
3876
3877 /*!
3878  * This method returns a newly allocated DataArrayDouble instance having one component and \c this->getNumberOfTuples() * \c this->getNumberOfTuples() tuples.
3879  * \n This returned array contains the euclidian distance for each tuple in \a this. 
3880  * \n So the returned array can be seen as a dense symmetrical matrix whose diagonal elements are equal to 0.
3881  * \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)
3882  *
3883  * \warning use this method with care because it can leads to big amount of consumed memory !
3884  * 
3885  * \return A newly allocated (huge) ParaMEDMEM::DataArrayDouble instance that the caller should deal with.
3886  *
3887  * \throw If \a this is not allocated.
3888  *
3889  * \sa DataArrayDouble::buildEuclidianDistanceDenseMatrixWith
3890  */
3891 DataArrayDouble *DataArrayDouble::buildEuclidianDistanceDenseMatrix() const
3892 {
3893   checkAllocated();
3894   int nbOfComp=getNumberOfComponents();
3895   int nbOfTuples=getNumberOfTuples();
3896   const double *inData=getConstPointer();
3897   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
3898   ret->alloc(nbOfTuples*nbOfTuples,1);
3899   double *outData=ret->getPointer();
3900   for(int i=0;i<nbOfTuples;i++)
3901     {
3902       outData[i*nbOfTuples+i]=0.;
3903       for(int j=i+1;j<nbOfTuples;j++)
3904         {
3905           double dist=0.;
3906           for(int k=0;k<nbOfComp;k++)
3907             { double delta=inData[i*nbOfComp+k]-inData[j*nbOfComp+k]; dist+=delta*delta; }
3908           dist=sqrt(dist);
3909           outData[i*nbOfTuples+j]=dist;
3910           outData[j*nbOfTuples+i]=dist;
3911         }
3912     }
3913   return ret.retn();
3914 }
3915
3916 /*!
3917  * This method returns a newly allocated DataArrayDouble instance having one component and \c this->getNumberOfTuples() * \c other->getNumberOfTuples() tuples.
3918  * \n This returned array contains the euclidian distance for each tuple in \a other with each tuple in \a this. 
3919  * \n So the returned array can be seen as a dense rectangular matrix with \c other->getNumberOfTuples() rows and \c this->getNumberOfTuples() columns.
3920  * \n Output rectangular matrix is sorted along rows.
3921  * \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)
3922  *
3923  * \warning use this method with care because it can leads to big amount of consumed memory !
3924  * 
3925  * \param [in] other DataArrayDouble instance having same number of components than \a this.
3926  * \return A newly allocated (huge) ParaMEDMEM::DataArrayDouble instance that the caller should deal with.
3927  *
3928  * \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.
3929  *
3930  * \sa DataArrayDouble::buildEuclidianDistanceDenseMatrix
3931  */
3932 DataArrayDouble *DataArrayDouble::buildEuclidianDistanceDenseMatrixWith(const DataArrayDouble *other) const
3933 {
3934   if(!other)
3935     throw INTERP_KERNEL::Exception("DataArrayDouble::buildEuclidianDistanceDenseMatrixWith : input parameter is null !");
3936   checkAllocated();
3937   other->checkAllocated();
3938   int nbOfComp=getNumberOfComponents();
3939   int otherNbOfComp=other->getNumberOfComponents();
3940   if(nbOfComp!=otherNbOfComp)
3941     {
3942       std::ostringstream oss; oss << "DataArrayDouble::buildEuclidianDistanceDenseMatrixWith : this nb of compo=" << nbOfComp << " and other nb of compo=" << otherNbOfComp << ". It should match !";
3943       throw INTERP_KERNEL::Exception(oss.str().c_str());
3944     }
3945   int nbOfTuples=getNumberOfTuples();
3946   int otherNbOfTuples=other->getNumberOfTuples();
3947   const double *inData=getConstPointer();
3948   const double *inDataOther=other->getConstPointer();
3949   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
3950   ret->alloc(otherNbOfTuples*nbOfTuples,1);
3951   double *outData=ret->getPointer();
3952   for(int i=0;i<otherNbOfTuples;i++,inDataOther+=nbOfComp)
3953     {
3954       for(int j=0;j<nbOfTuples;j++)
3955         {
3956           double dist=0.;
3957           for(int k=0;k<nbOfComp;k++)
3958             { double delta=inDataOther[k]-inData[j*nbOfComp+k]; dist+=delta*delta; }
3959           dist=sqrt(dist);
3960           outData[i*nbOfTuples+j]=dist;
3961         }
3962     }
3963   return ret.retn();
3964 }
3965
3966 /*!
3967  * Sorts value within every tuple of \a this array.
3968  *  \param [in] asc - if \a true, the values are sorted in ascending order, else,
3969  *              in descending order.
3970  *  \throw If \a this is not allocated.
3971  */
3972 void DataArrayDouble::sortPerTuple(bool asc)
3973 {
3974   checkAllocated();
3975   double *pt=getPointer();
3976   int nbOfTuple=getNumberOfTuples();
3977   int nbOfComp=getNumberOfComponents();
3978   if(asc)
3979     for(int i=0;i<nbOfTuple;i++,pt+=nbOfComp)
3980       std::sort(pt,pt+nbOfComp);
3981   else
3982     for(int i=0;i<nbOfTuple;i++,pt+=nbOfComp)
3983       std::sort(pt,pt+nbOfComp,std::greater<double>());
3984   declareAsNew();
3985 }
3986
3987 /*!
3988  * Converts every value of \a this array to its absolute value.
3989  *  \throw If \a this is not allocated.
3990  */
3991 void DataArrayDouble::abs()
3992 {
3993   checkAllocated();
3994   double *ptr=getPointer();
3995   std::size_t nbOfElems=getNbOfElems();
3996   std::transform(ptr,ptr+nbOfElems,ptr,std::ptr_fun<double,double>(fabs));
3997   declareAsNew();
3998 }
3999
4000 /*!
4001  * Apply a liner function to a given component of \a this array, so that
4002  * an array element <em>(x)</em> becomes \f$ a * x + b \f$.
4003  *  \param [in] a - the first coefficient of the function.
4004  *  \param [in] b - the second coefficient of the function.
4005  *  \param [in] compoId - the index of component to modify.
4006  *  \throw If \a this is not allocated.
4007  */
4008 void DataArrayDouble::applyLin(double a, double b, int compoId)
4009 {
4010   checkAllocated();
4011   double *ptr=getPointer()+compoId;
4012   int nbOfComp=getNumberOfComponents();
4013   int nbOfTuple=getNumberOfTuples();
4014   for(int i=0;i<nbOfTuple;i++,ptr+=nbOfComp)
4015     *ptr=a*(*ptr)+b;
4016   declareAsNew();
4017 }
4018
4019 /*!
4020  * Apply a liner function to all elements of \a this array, so that
4021  * an element _x_ becomes \f$ a * x + b \f$.
4022  *  \param [in] a - the first coefficient of the function.
4023  *  \param [in] b - the second coefficient of the function.
4024  *  \throw If \a this is not allocated.
4025  */
4026 void DataArrayDouble::applyLin(double a, double b)
4027 {
4028   checkAllocated();
4029   double *ptr=getPointer();
4030   std::size_t nbOfElems=getNbOfElems();
4031   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
4032     *ptr=a*(*ptr)+b;
4033   declareAsNew();
4034 }
4035
4036 /*!
4037  * Modify all elements of \a this array, so that
4038  * an element _x_ becomes \f$ numerator / x \f$.
4039  *  \warning If an exception is thrown because of presence of 0.0 element in \a this 
4040  *           array, all elements processed before detection of the zero element remain
4041  *           modified.
4042  *  \param [in] numerator - the numerator used to modify array elements.
4043  *  \throw If \a this is not allocated.
4044  *  \throw If there is an element equal to 0.0 in \a this array.
4045  */
4046 void DataArrayDouble::applyInv(double numerator)
4047 {
4048   checkAllocated();
4049   double *ptr=getPointer();
4050   std::size_t nbOfElems=getNbOfElems();
4051   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
4052     {
4053       if(std::abs(*ptr)>std::numeric_limits<double>::min())
4054         {
4055           *ptr=numerator/(*ptr);
4056         }
4057       else
4058         {
4059           std::ostringstream oss; oss << "DataArrayDouble::applyInv : presence of null value in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
4060           oss << " !";
4061           throw INTERP_KERNEL::Exception(oss.str().c_str());
4062         }
4063     }
4064   declareAsNew();
4065 }
4066
4067 /*!
4068  * Returns a full copy of \a this array except that sign of all elements is reversed.
4069  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
4070  *          same number of tuples and component as \a this array.
4071  *          The caller is to delete this result array using decrRef() as it is no more
4072  *          needed.
4073  *  \throw If \a this is not allocated.
4074  */
4075 DataArrayDouble *DataArrayDouble::negate() const
4076 {
4077   checkAllocated();
4078   DataArrayDouble *newArr=DataArrayDouble::New();
4079   int nbOfTuples=getNumberOfTuples();
4080   int nbOfComp=getNumberOfComponents();
4081   newArr->alloc(nbOfTuples,nbOfComp);
4082   const double *cptr=getConstPointer();
4083   std::transform(cptr,cptr+nbOfTuples*nbOfComp,newArr->getPointer(),std::negate<double>());
4084   newArr->copyStringInfoFrom(*this);
4085   return newArr;
4086 }
4087
4088 /*!
4089  * Modify all elements of \a this array, so that
4090  * an element _x_ becomes <em> val ^ x </em>. Contrary to DataArrayInt::applyPow
4091  * all values in \a this have to be >= 0 if val is \b not integer.
4092  *  \param [in] val - the value used to apply pow on all array elements.
4093  *  \throw If \a this is not allocated.
4094  *  \warning If an exception is thrown because of presence of 0 element in \a this 
4095  *           array and \a val is \b not integer, all elements processed before detection of the zero element remain
4096  *           modified.
4097  */
4098 void DataArrayDouble::applyPow(double val)
4099 {
4100   checkAllocated();
4101   double *ptr=getPointer();
4102   std::size_t nbOfElems=getNbOfElems();
4103   int val2=(int)val;
4104   bool isInt=((double)val2)==val;
4105   if(!isInt)
4106     {
4107       for(std::size_t i=0;i<nbOfElems;i++,ptr++)
4108         {
4109           if(*ptr>=0)
4110             *ptr=pow(*ptr,val);
4111           else
4112             {
4113               std::ostringstream oss; oss << "DataArrayDouble::applyPow (double) : At elem # " << i << " value is " << *ptr << " ! must be >=0. !";
4114               throw INTERP_KERNEL::Exception(oss.str().c_str());
4115             }
4116         }
4117     }
4118   else
4119     {
4120       for(std::size_t i=0;i<nbOfElems;i++,ptr++)
4121         *ptr=pow(*ptr,val2);
4122     }
4123   declareAsNew();
4124 }
4125
4126 /*!
4127  * Modify all elements of \a this array, so that
4128  * an element _x_ becomes \f$ val ^ x \f$.
4129  *  \param [in] val - the value used to apply pow on all array elements.
4130  *  \throw If \a this is not allocated.
4131  *  \throw If \a val < 0.
4132  *  \warning If an exception is thrown because of presence of 0 element in \a this 
4133  *           array, all elements processed before detection of the zero element remain
4134  *           modified.
4135  */
4136 void DataArrayDouble::applyRPow(double val)
4137 {
4138   checkAllocated();
4139   if(val<0.)
4140     throw INTERP_KERNEL::Exception("DataArrayDouble::applyRPow : the input value has to be >= 0 !");
4141   double *ptr=getPointer();
4142   std::size_t nbOfElems=getNbOfElems();
4143   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
4144     *ptr=pow(val,*ptr);
4145   declareAsNew();
4146 }
4147
4148 /*!
4149  * Returns a new DataArrayDouble created from \a this one by applying \a
4150  * FunctionToEvaluate to every tuple of \a this array. Textual data is not copied.
4151  * For more info see \ref MEDCouplingArrayApplyFunc
4152  *  \param [in] nbOfComp - number of components in the result array.
4153  *  \param [in] func - the \a FunctionToEvaluate declared as 
4154  *              \c bool (*\a func)(\c const \c double *\a pos, \c double *\a res), 
4155  *              where \a pos points to the first component of a tuple of \a this array
4156  *              and \a res points to the first component of a tuple of the result array.
4157  *              Note that length (number of components) of \a pos can differ from
4158  *              that of \a res.
4159  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
4160  *          same number of tuples as \a this array.
4161  *          The caller is to delete this result array using decrRef() as it is no more
4162  *          needed.
4163  *  \throw If \a this is not allocated.
4164  *  \throw If \a func returns \a false.
4165  */
4166 DataArrayDouble *DataArrayDouble::applyFunc(int nbOfComp, FunctionToEvaluate func) const
4167 {
4168   checkAllocated();
4169   DataArrayDouble *newArr=DataArrayDouble::New();
4170   int nbOfTuples=getNumberOfTuples();
4171   int oldNbOfComp=getNumberOfComponents();
4172   newArr->alloc(nbOfTuples,nbOfComp);
4173   const double *ptr=getConstPointer();
4174   double *ptrToFill=newArr->getPointer();
4175   for(int i=0;i<nbOfTuples;i++)
4176     {
4177       if(!func(ptr+i*oldNbOfComp,ptrToFill+i*nbOfComp))
4178         {
4179           std::ostringstream oss; oss << "For tuple # " << i << " with value (";
4180           std::copy(ptr+oldNbOfComp*i,ptr+oldNbOfComp*(i+1),std::ostream_iterator<double>(oss,", "));
4181           oss << ") : Evaluation of function failed !";
4182           newArr->decrRef();
4183           throw INTERP_KERNEL::Exception(oss.str().c_str());
4184         }
4185     }
4186   return newArr;
4187 }
4188
4189 /*!
4190  * Returns a new DataArrayDouble created from \a this one by applying a function to every
4191  * tuple of \a this array. Textual data is not copied.
4192  * For more info see \ref MEDCouplingArrayApplyFunc1.
4193  *  \param [in] nbOfComp - number of components in the result array.
4194  *  \param [in] func - the expression defining how to transform a tuple of \a this array.
4195  *              Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
4196  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
4197  *          same number of tuples as \a this array and \a nbOfComp components.
4198  *          The caller is to delete this result array using decrRef() as it is no more
4199  *          needed.
4200  *  \throw If \a this is not allocated.
4201  *  \throw If computing \a func fails.
4202  */
4203 DataArrayDouble *DataArrayDouble::applyFunc(int nbOfComp, const char *func) const
4204 {
4205   checkAllocated();
4206   INTERP_KERNEL::ExprParser expr(func);
4207   expr.parse();
4208   std::set<std::string> vars;
4209   expr.getTrueSetOfVars(vars);
4210   int oldNbOfComp=getNumberOfComponents();
4211   if((int)vars.size()>oldNbOfComp)
4212     {
4213       std::ostringstream oss; oss << "The field has " << oldNbOfComp << " components and there are ";
4214       oss << vars.size() << " variables : ";
4215       std::copy(vars.begin(),vars.end(),std::ostream_iterator<std::string>(oss," "));
4216       throw INTERP_KERNEL::Exception(oss.str().c_str());
4217     }
4218   std::vector<std::string> varsV(vars.begin(),vars.end());
4219   expr.prepareExprEvaluation(varsV,oldNbOfComp,nbOfComp);
4220   //
4221   DataArrayDouble *newArr=DataArrayDouble::New();
4222   int nbOfTuples=getNumberOfTuples();
4223   newArr->alloc(nbOfTuples,nbOfComp);
4224   const double *ptr=getConstPointer();
4225   double *ptrToFill=newArr->getPointer();
4226   for(int i=0;i<nbOfTuples;i++)
4227     {
4228       try
4229         {
4230           expr.evaluateExpr(nbOfComp,ptr+i*oldNbOfComp,ptrToFill+i*nbOfComp);
4231         }
4232       catch(INTERP_KERNEL::Exception& e)
4233         {
4234           std::ostringstream oss; oss << "For tuple # " << i << " with value (";
4235           std::copy(ptr+oldNbOfComp*i,ptr+oldNbOfComp*(i+1),std::ostream_iterator<double>(oss,", "));
4236           oss << ") : Evaluation of function failed !" << e.what();
4237           newArr->decrRef();
4238           throw INTERP_KERNEL::Exception(oss.str().c_str());
4239         }
4240     }
4241   return newArr;
4242 }
4243
4244 /*!
4245  * Returns a new DataArrayDouble created from \a this one by applying a function to every
4246  * tuple of \a this array. Textual data is not copied.
4247  * For more info see \ref MEDCouplingArrayApplyFunc0.
4248  *  \param [in] func - the expression defining how to transform a tuple of \a this array.
4249  *              Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
4250  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
4251  *          same number of tuples and components as \a this array.
4252  *          The caller is to delete this result array using decrRef() as it is no more
4253  *          needed.
4254  *  \throw If \a this is not allocated.
4255  *  \throw If computing \a func fails.
4256  */
4257 DataArrayDouble *DataArrayDouble::applyFunc(const char *func) const
4258 {
4259   checkAllocated();
4260   INTERP_KERNEL::ExprParser expr(func);
4261   expr.parse();
4262   expr.prepareExprEvaluationVec();
4263   //
4264   DataArrayDouble *newArr=DataArrayDouble::New();
4265   int nbOfTuples=getNumberOfTuples();
4266   int nbOfComp=getNumberOfComponents();
4267   newArr->alloc(nbOfTuples,nbOfComp);
4268   const double *ptr=getConstPointer();
4269   double *ptrToFill=newArr->getPointer();
4270   for(int i=0;i<nbOfTuples;i++)
4271     {
4272       try
4273         {
4274           expr.evaluateExpr(nbOfComp,ptr+i*nbOfComp,ptrToFill+i*nbOfComp);
4275         }
4276       catch(INTERP_KERNEL::Exception& e)
4277         {
4278           std::ostringstream oss; oss << "For tuple # " << i << " with value (";
4279           std::copy(ptr+nbOfComp*i,ptr+nbOfComp*(i+1),std::ostream_iterator<double>(oss,", "));
4280           oss << ") : Evaluation of function failed ! " << e.what();
4281           newArr->decrRef();
4282           throw INTERP_KERNEL::Exception(oss.str().c_str());
4283         }
4284     }
4285   return newArr;
4286 }
4287
4288 /*!
4289  * Returns a new DataArrayDouble created from \a this one by applying a function to every
4290  * tuple of \a this array. Textual data is not copied.
4291  * For more info see \ref MEDCouplingArrayApplyFunc2.
4292  *  \param [in] nbOfComp - number of components in the result array.
4293  *  \param [in] func - the expression defining how to transform a tuple of \a this array.
4294  *              Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
4295  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
4296  *          same number of tuples as \a this array.
4297  *          The caller is to delete this result array using decrRef() as it is no more
4298  *          needed.
4299  *  \throw If \a this is not allocated.
4300  *  \throw If \a func contains vars that are not in \a this->getInfoOnComponent().
4301  *  \throw If computing \a func fails.
4302  */
4303 DataArrayDouble *DataArrayDouble::applyFunc2(int nbOfComp, const char *func) const
4304 {
4305   checkAllocated();
4306   INTERP_KERNEL::ExprParser expr(func);
4307   expr.parse();
4308   std::set<std::string> vars;
4309   expr.getTrueSetOfVars(vars);
4310   int oldNbOfComp=getNumberOfComponents();
4311   if((int)vars.size()>oldNbOfComp)
4312     {
4313       std::ostringstream oss; oss << "The field has " << oldNbOfComp << " components and there are ";
4314       oss << vars.size() << " variables : ";
4315       std::copy(vars.begin(),vars.end(),std::ostream_iterator<std::string>(oss," "));
4316       throw INTERP_KERNEL::Exception(oss.str().c_str());
4317     }
4318   expr.prepareExprEvaluation(getVarsOnComponent(),oldNbOfComp,nbOfComp);
4319   //
4320   DataArrayDouble *newArr=DataArrayDouble::New();
4321   int nbOfTuples=getNumberOfTuples();
4322   newArr->alloc(nbOfTuples,nbOfComp);
4323   const double *ptr=getConstPointer();
4324   double *ptrToFill=newArr->getPointer();
4325   for(int i=0;i<nbOfTuples;i++)
4326     {
4327       try
4328         {
4329           expr.evaluateExpr(nbOfComp,ptr+i*oldNbOfComp,ptrToFill+i*nbOfComp);
4330         }
4331       catch(INTERP_KERNEL::Exception& e)
4332         {
4333           std::ostringstream oss; oss << "For tuple # " << i << " with value (";
4334           std::copy(ptr+oldNbOfComp*i,ptr+oldNbOfComp*(i+1),std::ostream_iterator<double>(oss,", "));
4335           oss << ") : Evaluation of function failed !" << e.what();
4336           newArr->decrRef();
4337           throw INTERP_KERNEL::Exception(oss.str().c_str());
4338         }
4339     }
4340   return newArr;
4341 }
4342
4343 /*!
4344  * Returns a new DataArrayDouble created from \a this one by applying a function to every
4345  * tuple of \a this array. Textual data is not copied.
4346  * For more info see \ref MEDCouplingArrayApplyFunc3.
4347  *  \param [in] nbOfComp - number of components in the result array.
4348  *  \param [in] varsOrder - sequence of vars defining their order.
4349  *  \param [in] func - the expression defining how to transform a tuple of \a this array.
4350  *              Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
4351  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
4352  *          same number of tuples as \a this array.
4353  *          The caller is to delete this result array using decrRef() as it is no more
4354  *          needed.
4355  *  \throw If \a this is not allocated.
4356  *  \throw If \a func contains vars not in \a varsOrder.
4357  *  \throw If computing \a func fails.
4358  */
4359 DataArrayDouble *DataArrayDouble::applyFunc3(int nbOfComp, const std::vector<std::string>& varsOrder, const char *func) const
4360 {
4361   checkAllocated();
4362   INTERP_KERNEL::ExprParser expr(func);
4363   expr.parse();
4364   std::set<std::string> vars;
4365   expr.getTrueSetOfVars(vars);
4366   int oldNbOfComp=getNumberOfComponents();
4367   if((int)vars.size()>oldNbOfComp)
4368     {
4369       std::ostringstream oss; oss << "The field has " << oldNbOfComp << " components and there are ";
4370       oss << vars.size() << " variables : ";
4371       std::copy(vars.begin(),vars.end(),std::ostream_iterator<std::string>(oss," "));
4372       throw INTERP_KERNEL::Exception(oss.str().c_str());
4373     }
4374   expr.prepareExprEvaluation(varsOrder,oldNbOfComp,nbOfComp);
4375   //
4376   DataArrayDouble *newArr=DataArrayDouble::New();
4377   int nbOfTuples=getNumberOfTuples();
4378   newArr->alloc(nbOfTuples,nbOfComp);
4379   const double *ptr=getConstPointer();
4380   double *ptrToFill=newArr->getPointer();
4381   for(int i=0;i<nbOfTuples;i++)
4382     {
4383       try
4384         {
4385           expr.evaluateExpr(nbOfComp,ptr+i*oldNbOfComp,ptrToFill+i*nbOfComp);
4386         }
4387       catch(INTERP_KERNEL::Exception& e)
4388         {
4389           std::ostringstream oss; oss << "For tuple # " << i << " with value (";
4390           std::copy(ptr+oldNbOfComp*i,ptr+oldNbOfComp*(i+1),std::ostream_iterator<double>(oss,", "));
4391           oss << ") : Evaluation of function failed !" << e.what();
4392           newArr->decrRef();
4393           throw INTERP_KERNEL::Exception(oss.str().c_str());
4394         }
4395     }
4396   return newArr;
4397 }
4398
4399 void DataArrayDouble::applyFuncFast32(const char *func)
4400 {
4401   checkAllocated();
4402   INTERP_KERNEL::ExprParser expr(func);
4403   expr.parse();
4404   char *funcStr=expr.compileX86();
4405   MYFUNCPTR funcPtr;
4406   *((void **)&funcPtr)=funcStr;//he he...
4407   //
4408   double *ptr=getPointer();
4409   int nbOfComp=getNumberOfComponents();
4410   int nbOfTuples=getNumberOfTuples();
4411   int nbOfElems=nbOfTuples*nbOfComp;
4412   for(int i=0;i<nbOfElems;i++,ptr++)
4413     *ptr=funcPtr(*ptr);
4414   declareAsNew();
4415 }
4416
4417 void DataArrayDouble::applyFuncFast64(const char *func)
4418 {
4419   checkAllocated();
4420   INTERP_KERNEL::ExprParser expr(func);
4421   expr.parse();
4422   char *funcStr=expr.compileX86_64();
4423   MYFUNCPTR funcPtr;
4424   *((void **)&funcPtr)=funcStr;//he he...
4425   //
4426   double *ptr=getPointer();
4427   int nbOfComp=getNumberOfComponents();
4428   int nbOfTuples=getNumberOfTuples();
4429   int nbOfElems=nbOfTuples*nbOfComp;
4430   for(int i=0;i<nbOfElems;i++,ptr++)
4431     *ptr=funcPtr(*ptr);
4432   declareAsNew();
4433 }
4434
4435 DataArrayDoubleIterator *DataArrayDouble::iterator()
4436 {
4437   return new DataArrayDoubleIterator(this);
4438 }
4439
4440 /*!
4441  * Returns a new DataArrayInt contating indices of tuples of \a this one-dimensional
4442  * array whose values are within a given range. Textual data is not copied.
4443  *  \param [in] vmin - a lowest acceptable value (included).
4444  *  \param [in] vmax - a greatest acceptable value (included).
4445  *  \return DataArrayInt * - the new instance of DataArrayInt.
4446  *          The caller is to delete this result array using decrRef() as it is no more
4447  *          needed.
4448  *  \throw If \a this->getNumberOfComponents() != 1.
4449  *
4450  *  \ref cpp_mcdataarraydouble_getidsinrange "Here is a C++ example".<br>
4451  *  \ref py_mcdataarraydouble_getidsinrange "Here is a Python example".
4452  */
4453 DataArrayInt *DataArrayDouble::getIdsInRange(double vmin, double vmax) const
4454 {
4455   checkAllocated();
4456   if(getNumberOfComponents()!=1)
4457     throw INTERP_KERNEL::Exception("DataArrayDouble::getIdsInRange : this must have exactly one component !");
4458   const double *cptr=getConstPointer();
4459   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(0,1);
4460   int nbOfTuples=getNumberOfTuples();
4461   for(int i=0;i<nbOfTuples;i++,cptr++)
4462     if(*cptr>=vmin && *cptr<=vmax)
4463       ret->pushBackSilent(i);
4464   return ret.retn();
4465 }
4466
4467 /*!
4468  * Returns a new DataArrayDouble by concatenating two given arrays, so that (1) the number
4469  * of tuples in the result array is a sum of the number of tuples of given arrays and (2)
4470  * the number of component in the result array is same as that of each of given arrays.
4471  * Info on components is copied from the first of the given arrays. Number of components
4472  * in the given arrays must be  the same.
4473  *  \param [in] a1 - an array to include in the result array.
4474  *  \param [in] a2 - another array to include in the result array.
4475  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4476  *          The caller is to delete this result array using decrRef() as it is no more
4477  *          needed.
4478  *  \throw If both \a a1 and \a a2 are NULL.
4479  *  \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents().
4480  */
4481 DataArrayDouble *DataArrayDouble::Aggregate(const DataArrayDouble *a1, const DataArrayDouble *a2)
4482 {
4483   std::vector<const DataArrayDouble *> tmp(2);
4484   tmp[0]=a1; tmp[1]=a2;
4485   return Aggregate(tmp);
4486 }
4487
4488 /*!
4489  * Returns a new DataArrayDouble by concatenating all given arrays, so that (1) the number
4490  * of tuples in the result array is a sum of the number of tuples of given arrays and (2)
4491  * the number of component in the result array is same as that of each of given arrays.
4492  * Info on components is copied from the first of the given arrays. Number of components
4493  * in the given arrays must be  the same.
4494  *  \param [in] arr - a sequence of arrays to include in the result array.
4495  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4496  *          The caller is to delete this result array using decrRef() as it is no more
4497  *          needed.
4498  *  \throw If all arrays within \a arr are NULL.
4499  *  \throw If getNumberOfComponents() of arrays within \a arr.
4500  */
4501 DataArrayDouble *DataArrayDouble::Aggregate(const std::vector<const DataArrayDouble *>& arr)
4502 {
4503   std::vector<const DataArrayDouble *> a;
4504   for(std::vector<const DataArrayDouble *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
4505     if(*it4)
4506       a.push_back(*it4);
4507   if(a.empty())
4508     throw INTERP_KERNEL::Exception("DataArrayDouble::Aggregate : input list must contain at least one NON EMPTY DataArrayDouble !");
4509   std::vector<const DataArrayDouble *>::const_iterator it=a.begin();
4510   int nbOfComp=(*it)->getNumberOfComponents();
4511   int nbt=(*it++)->getNumberOfTuples();
4512   for(int i=1;it!=a.end();it++,i++)
4513     {
4514       if((*it)->getNumberOfComponents()!=nbOfComp)
4515         throw INTERP_KERNEL::Exception("DataArrayDouble::Aggregate : Nb of components mismatch for array aggregation !");
4516       nbt+=(*it)->getNumberOfTuples();
4517     }
4518   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
4519   ret->alloc(nbt,nbOfComp);
4520   double *pt=ret->getPointer();
4521   for(it=a.begin();it!=a.end();it++)
4522     pt=std::copy((*it)->getConstPointer(),(*it)->getConstPointer()+(*it)->getNbOfElems(),pt);
4523   ret->copyStringInfoFrom(*(a[0]));
4524   return ret.retn();
4525 }
4526
4527 /*!
4528  * Returns a new DataArrayDouble by aggregating two given arrays, so that (1) the number
4529  * of components in the result array is a sum of the number of components of given arrays
4530  * and (2) the number of tuples in the result array is same as that of each of given
4531  * arrays. In other words the i-th tuple of result array includes all components of
4532  * i-th tuples of all given arrays.
4533  * Number of tuples in the given arrays must be  the same.
4534  *  \param [in] a1 - an array to include in the result array.
4535  *  \param [in] a2 - another array to include in the result array.
4536  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4537  *          The caller is to delete this result array using decrRef() as it is no more
4538  *          needed.
4539  *  \throw If both \a a1 and \a a2 are NULL.
4540  *  \throw If any given array is not allocated.
4541  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
4542  */
4543 DataArrayDouble *DataArrayDouble::Meld(const DataArrayDouble *a1, const DataArrayDouble *a2)
4544 {
4545   std::vector<const DataArrayDouble *> arr(2);
4546   arr[0]=a1; arr[1]=a2;
4547   return Meld(arr);
4548 }
4549
4550 /*!
4551  * Returns a new DataArrayDouble by aggregating all given arrays, so that (1) the number
4552  * of components in the result array is a sum of the number of components of given arrays
4553  * and (2) the number of tuples in the result array is same as that of each of given
4554  * arrays. In other words the i-th tuple of result array includes all components of
4555  * i-th tuples of all given arrays.
4556  * Number of tuples in the given arrays must be  the same.
4557  *  \param [in] arr - a sequence of arrays to include in the result array.
4558  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4559  *          The caller is to delete this result array using decrRef() as it is no more
4560  *          needed.
4561  *  \throw If all arrays within \a arr are NULL.
4562  *  \throw If any given array is not allocated.
4563  *  \throw If getNumberOfTuples() of arrays within \a arr is different.
4564  */
4565 DataArrayDouble *DataArrayDouble::Meld(const std::vector<const DataArrayDouble *>& arr)
4566 {
4567   std::vector<const DataArrayDouble *> a;
4568   for(std::vector<const DataArrayDouble *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
4569     if(*it4)
4570       a.push_back(*it4);
4571   if(a.empty())
4572     throw INTERP_KERNEL::Exception("DataArrayDouble::Meld : input list must contain at least one NON EMPTY DataArrayDouble !");
4573   std::vector<const DataArrayDouble *>::const_iterator it;
4574   for(it=a.begin();it!=a.end();it++)
4575     (*it)->checkAllocated();
4576   it=a.begin();
4577   int nbOfTuples=(*it)->getNumberOfTuples();
4578   std::vector<int> nbc(a.size());
4579   std::vector<const double *> pts(a.size());
4580   nbc[0]=(*it)->getNumberOfComponents();
4581   pts[0]=(*it++)->getConstPointer();
4582   for(int i=1;it!=a.end();it++,i++)
4583     {
4584       if(nbOfTuples!=(*it)->getNumberOfTuples())
4585         throw INTERP_KERNEL::Exception("DataArrayDouble::Meld : mismatch of number of tuples !");
4586       nbc[i]=(*it)->getNumberOfComponents();
4587       pts[i]=(*it)->getConstPointer();
4588     }
4589   int totalNbOfComp=std::accumulate(nbc.begin(),nbc.end(),0);
4590   DataArrayDouble *ret=DataArrayDouble::New();
4591   ret->alloc(nbOfTuples,totalNbOfComp);
4592   double *retPtr=ret->getPointer();
4593   for(int i=0;i<nbOfTuples;i++)
4594     for(int j=0;j<(int)a.size();j++)
4595       {
4596         retPtr=std::copy(pts[j],pts[j]+nbc[j],retPtr);
4597         pts[j]+=nbc[j];
4598       }
4599   int k=0;
4600   for(int i=0;i<(int)a.size();i++)
4601     for(int j=0;j<nbc[i];j++,k++)
4602       ret->setInfoOnComponent(k,a[i]->getInfoOnComponent(j).c_str());
4603   return ret;
4604 }
4605
4606 /*!
4607  * Returns a new DataArrayDouble containing a dot product of two given arrays, so that
4608  * the i-th tuple of the result array is a sum of products of j-th components of i-th
4609  * tuples of given arrays (\f$ a_i = \sum_{j=1}^n a1_j * a2_j \f$).
4610  * Info on components and name is copied from the first of the given arrays.
4611  * Number of tuples and components in the given arrays must be the same.
4612  *  \param [in] a1 - a given array.
4613  *  \param [in] a2 - another given array.
4614  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4615  *          The caller is to delete this result array using decrRef() as it is no more
4616  *          needed.
4617  *  \throw If either \a a1 or \a a2 is NULL.
4618  *  \throw If any given array is not allocated.
4619  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
4620  *  \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents()
4621  */
4622 DataArrayDouble *DataArrayDouble::Dot(const DataArrayDouble *a1, const DataArrayDouble *a2)
4623 {
4624   if(!a1 || !a2)
4625     throw INTERP_KERNEL::Exception("DataArrayDouble::Dot : input DataArrayDouble instance is NULL !");
4626   a1->checkAllocated();
4627   a2->checkAllocated();
4628   int nbOfComp=a1->getNumberOfComponents();
4629   if(nbOfComp!=a2->getNumberOfComponents())
4630     throw INTERP_KERNEL::Exception("Nb of components mismatch for array Dot !");
4631   int nbOfTuple=a1->getNumberOfTuples();
4632   if(nbOfTuple!=a2->getNumberOfTuples())
4633     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Dot !");
4634   DataArrayDouble *ret=DataArrayDouble::New();
4635   ret->alloc(nbOfTuple,1);
4636   double *retPtr=ret->getPointer();
4637   const double *a1Ptr=a1->getConstPointer();
4638   const double *a2Ptr=a2->getConstPointer();
4639   for(int i=0;i<nbOfTuple;i++)
4640     {
4641       double sum=0.;
4642       for(int j=0;j<nbOfComp;j++)
4643         sum+=a1Ptr[i*nbOfComp+j]*a2Ptr[i*nbOfComp+j];
4644       retPtr[i]=sum;
4645     }
4646   ret->setInfoOnComponent(0,a1->getInfoOnComponent(0).c_str());
4647   ret->setName(a1->getName().c_str());
4648   return ret;
4649 }
4650
4651 /*!
4652  * Returns a new DataArrayDouble containing a cross product of two given arrays, so that
4653  * the i-th tuple of the result array contains 3 components of a vector which is a cross
4654  * product of two vectors defined by the i-th tuples of given arrays.
4655  * Info on components is copied from the first of the given arrays.
4656  * Number of tuples in the given arrays must be the same.
4657  * Number of components in the given arrays must be 3.
4658  *  \param [in] a1 - a given array.
4659  *  \param [in] a2 - another given array.
4660  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4661  *          The caller is to delete this result array using decrRef() as it is no more
4662  *          needed.
4663  *  \throw If either \a a1 or \a a2 is NULL.
4664  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
4665  *  \throw If \a a1->getNumberOfComponents() != 3
4666  *  \throw If \a a2->getNumberOfComponents() != 3
4667  */
4668 DataArrayDouble *DataArrayDouble::CrossProduct(const DataArrayDouble *a1, const DataArrayDouble *a2)
4669 {
4670   if(!a1 || !a2)
4671     throw INTERP_KERNEL::Exception("DataArrayDouble::CrossProduct : input DataArrayDouble instance is NULL !");
4672   int nbOfComp=a1->getNumberOfComponents();
4673   if(nbOfComp!=a2->getNumberOfComponents())
4674     throw INTERP_KERNEL::Exception("Nb of components mismatch for array crossProduct !");
4675   if(nbOfComp!=3)
4676     throw INTERP_KERNEL::Exception("Nb of components must be equal to 3 for array crossProduct !");
4677   int nbOfTuple=a1->getNumberOfTuples();
4678   if(nbOfTuple!=a2->getNumberOfTuples())
4679     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array crossProduct !");
4680   DataArrayDouble *ret=DataArrayDouble::New();
4681   ret->alloc(nbOfTuple,3);
4682   double *retPtr=ret->getPointer();
4683   const double *a1Ptr=a1->getConstPointer();
4684   const double *a2Ptr=a2->getConstPointer();
4685   for(int i=0;i<nbOfTuple;i++)
4686     {
4687       retPtr[3*i]=a1Ptr[3*i+1]*a2Ptr[3*i+2]-a1Ptr[3*i+2]*a2Ptr[3*i+1];
4688       retPtr[3*i+1]=a1Ptr[3*i+2]*a2Ptr[3*i]-a1Ptr[3*i]*a2Ptr[3*i+2];
4689       retPtr[3*i+2]=a1Ptr[3*i]*a2Ptr[3*i+1]-a1Ptr[3*i+1]*a2Ptr[3*i];
4690     }
4691   ret->copyStringInfoFrom(*a1);
4692   return ret;
4693 }
4694
4695 /*!
4696  * Returns a new DataArrayDouble containing maximal values of two given arrays.
4697  * Info on components is copied from the first of the given arrays.
4698  * Number of tuples and components in the given arrays must be the same.
4699  *  \param [in] a1 - an array to compare values with another one.
4700  *  \param [in] a2 - another array to compare values with the first one.
4701  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4702  *          The caller is to delete this result array using decrRef() as it is no more
4703  *          needed.
4704  *  \throw If either \a a1 or \a a2 is NULL.
4705  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
4706  *  \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents()
4707  */
4708 DataArrayDouble *DataArrayDouble::Max(const DataArrayDouble *a1, const DataArrayDouble *a2)
4709 {
4710   if(!a1 || !a2)
4711     throw INTERP_KERNEL::Exception("DataArrayDouble::Max : input DataArrayDouble instance is NULL !");
4712   int nbOfComp=a1->getNumberOfComponents();
4713   if(nbOfComp!=a2->getNumberOfComponents())
4714     throw INTERP_KERNEL::Exception("Nb of components mismatch for array Max !");
4715   int nbOfTuple=a1->getNumberOfTuples();
4716   if(nbOfTuple!=a2->getNumberOfTuples())
4717     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Max !");
4718   DataArrayDouble *ret=DataArrayDouble::New();
4719   ret->alloc(nbOfTuple,nbOfComp);
4720   double *retPtr=ret->getPointer();
4721   const double *a1Ptr=a1->getConstPointer();
4722   const double *a2Ptr=a2->getConstPointer();
4723   int nbElem=nbOfTuple*nbOfComp;
4724   for(int i=0;i<nbElem;i++)
4725     retPtr[i]=std::max(a1Ptr[i],a2Ptr[i]);
4726   ret->copyStringInfoFrom(*a1);
4727   return ret;
4728 }
4729
4730 /*!
4731  * Returns a new DataArrayDouble containing minimal values of two given arrays.
4732  * Info on components is copied from the first of the given arrays.
4733  * Number of tuples and components in the given arrays must be the same.
4734  *  \param [in] a1 - an array to compare values with another one.
4735  *  \param [in] a2 - another array to compare values with the first one.
4736  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4737  *          The caller is to delete this result array using decrRef() as it is no more
4738  *          needed.
4739  *  \throw If either \a a1 or \a a2 is NULL.
4740  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
4741  *  \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents()
4742  */
4743 DataArrayDouble *DataArrayDouble::Min(const DataArrayDouble *a1, const DataArrayDouble *a2)
4744 {
4745   if(!a1 || !a2)
4746     throw INTERP_KERNEL::Exception("DataArrayDouble::Min : input DataArrayDouble instance is NULL !");
4747   int nbOfComp=a1->getNumberOfComponents();
4748   if(nbOfComp!=a2->getNumberOfComponents())
4749     throw INTERP_KERNEL::Exception("Nb of components mismatch for array min !");
4750   int nbOfTuple=a1->getNumberOfTuples();
4751   if(nbOfTuple!=a2->getNumberOfTuples())
4752     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array min !");
4753   DataArrayDouble *ret=DataArrayDouble::New();
4754   ret->alloc(nbOfTuple,nbOfComp);
4755   double *retPtr=ret->getPointer();
4756   const double *a1Ptr=a1->getConstPointer();
4757   const double *a2Ptr=a2->getConstPointer();
4758   int nbElem=nbOfTuple*nbOfComp;
4759   for(int i=0;i<nbElem;i++)
4760     retPtr[i]=std::min(a1Ptr[i],a2Ptr[i]);
4761   ret->copyStringInfoFrom(*a1);
4762   return ret;
4763 }
4764
4765 /*!
4766  * Returns a new DataArrayDouble that is a sum of two given arrays. There are 3
4767  * valid cases.
4768  * 1.  The arrays have same number of tuples and components. Then each value of
4769  *   the result array (_a_) is a sum of the corresponding values of \a a1 and \a a2,
4770  *   i.e.: _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ i, j ].
4771  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
4772  *   component. Then
4773  *   _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ i, 0 ].
4774  * 3.  The arrays have same number of components and one array, say _a2_, has one
4775  *   tuple. Then
4776  *   _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ 0, j ].
4777  *
4778  * Info on components is copied either from the first array (in the first case) or from
4779  * the array with maximal number of elements (getNbOfElems()).
4780  *  \param [in] a1 - an array to sum up.
4781  *  \param [in] a2 - another array to sum up.
4782  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4783  *          The caller is to delete this result array using decrRef() as it is no more
4784  *          needed.
4785  *  \throw If either \a a1 or \a a2 is NULL.
4786  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
4787  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
4788  *         none of them has number of tuples or components equal to 1.
4789  */
4790 DataArrayDouble *DataArrayDouble::Add(const DataArrayDouble *a1, const DataArrayDouble *a2)
4791 {
4792   if(!a1 || !a2)
4793     throw INTERP_KERNEL::Exception("DataArrayDouble::Add : input DataArrayDouble instance is NULL !");
4794   int nbOfTuple=a1->getNumberOfTuples();
4795   int nbOfTuple2=a2->getNumberOfTuples();
4796   int nbOfComp=a1->getNumberOfComponents();
4797   int nbOfComp2=a2->getNumberOfComponents();
4798   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=0;
4799   if(nbOfTuple==nbOfTuple2)
4800     {
4801       if(nbOfComp==nbOfComp2)
4802         {
4803           ret=DataArrayDouble::New();
4804           ret->alloc(nbOfTuple,nbOfComp);
4805           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::plus<double>());
4806           ret->copyStringInfoFrom(*a1);
4807         }
4808       else
4809         {
4810           int nbOfCompMin,nbOfCompMax;
4811           const DataArrayDouble *aMin, *aMax;
4812           if(nbOfComp>nbOfComp2)
4813             {
4814               nbOfCompMin=nbOfComp2; nbOfCompMax=nbOfComp;
4815               aMin=a2; aMax=a1;
4816             }
4817           else
4818             {
4819               nbOfCompMin=nbOfComp; nbOfCompMax=nbOfComp2;
4820               aMin=a1; aMax=a2;
4821             }
4822           if(nbOfCompMin==1)
4823             {
4824               ret=DataArrayDouble::New();
4825               ret->alloc(nbOfTuple,nbOfCompMax);
4826               const double *aMinPtr=aMin->getConstPointer();
4827               const double *aMaxPtr=aMax->getConstPointer();
4828               double *res=ret->getPointer();
4829               for(int i=0;i<nbOfTuple;i++)
4830                 res=std::transform(aMaxPtr+i*nbOfCompMax,aMaxPtr+(i+1)*nbOfCompMax,res,std::bind2nd(std::plus<double>(),aMinPtr[i]));
4831               ret->copyStringInfoFrom(*aMax);
4832             }
4833           else
4834             throw INTERP_KERNEL::Exception("Nb of components mismatch for array Add !");
4835         }
4836     }
4837   else if((nbOfTuple==1 && nbOfTuple2>1) || (nbOfTuple>1 && nbOfTuple2==1))
4838     {
4839       if(nbOfComp==nbOfComp2)
4840         {
4841           int nbOfTupleMax=std::max(nbOfTuple,nbOfTuple2);
4842           const DataArrayDouble *aMin=nbOfTuple>nbOfTuple2?a2:a1;
4843           const DataArrayDouble *aMax=nbOfTuple>nbOfTuple2?a1:a2;
4844           const double *aMinPtr=aMin->getConstPointer(),*aMaxPtr=aMax->getConstPointer();
4845           ret=DataArrayDouble::New();
4846           ret->alloc(nbOfTupleMax,nbOfComp);
4847           double *res=ret->getPointer();
4848           for(int i=0;i<nbOfTupleMax;i++)
4849             res=std::transform(aMaxPtr+i*nbOfComp,aMaxPtr+(i+1)*nbOfComp,aMinPtr,res,std::plus<double>());
4850           ret->copyStringInfoFrom(*aMax);
4851         }
4852       else
4853         throw INTERP_KERNEL::Exception("Nb of components mismatch for array Add !");
4854     }
4855   else
4856     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Add !");
4857   return ret.retn();
4858 }
4859
4860 /*!
4861  * Adds values of another DataArrayDouble to values of \a this one. There are 3
4862  * valid cases.
4863  * 1.  The arrays have same number of tuples and components. Then each value of
4864  *   \a other array is added to the corresponding value of \a this array, i.e.:
4865  *   _a_ [ i, j ] += _other_ [ i, j ].
4866  * 2.  The arrays have same number of tuples and \a other array has one component. Then
4867  *   _a_ [ i, j ] += _other_ [ i, 0 ].
4868  * 3.  The arrays have same number of components and \a other array has one tuple. Then
4869  *   _a_ [ i, j ] += _a2_ [ 0, j ].
4870  *
4871  *  \param [in] other - an array to add to \a this one.
4872  *  \throw If \a other is NULL.
4873  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
4874  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
4875  *         \a other has number of both tuples and components not equal to 1.
4876  */
4877 void DataArrayDouble::addEqual(const DataArrayDouble *other)
4878 {
4879   if(!other)
4880     throw INTERP_KERNEL::Exception("DataArrayDouble::addEqual : input DataArrayDouble instance is NULL !");
4881   const char *msg="Nb of tuples mismatch for DataArrayDouble::addEqual  !";
4882   checkAllocated();
4883   other->checkAllocated();
4884   int nbOfTuple=getNumberOfTuples();
4885   int nbOfTuple2=other->getNumberOfTuples();
4886   int nbOfComp=getNumberOfComponents();
4887   int nbOfComp2=other->getNumberOfComponents();
4888   if(nbOfTuple==nbOfTuple2)
4889     {
4890       if(nbOfComp==nbOfComp2)
4891         {
4892           std::transform(begin(),end(),other->begin(),getPointer(),std::plus<double>());
4893         }
4894       else if(nbOfComp2==1)
4895         {
4896           double *ptr=getPointer();
4897           const double *ptrc=other->getConstPointer();
4898           for(int i=0;i<nbOfTuple;i++)
4899             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::plus<double>(),*ptrc++));
4900         }
4901       else
4902         throw INTERP_KERNEL::Exception(msg);
4903     }
4904   else if(nbOfTuple2==1)
4905     {
4906       if(nbOfComp2==nbOfComp)
4907         {
4908           double *ptr=getPointer();
4909           const double *ptrc=other->getConstPointer();
4910           for(int i=0;i<nbOfTuple;i++)
4911             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::plus<double>());
4912         }
4913       else
4914         throw INTERP_KERNEL::Exception(msg);
4915     }
4916   else
4917     throw INTERP_KERNEL::Exception(msg);
4918   declareAsNew();
4919 }
4920
4921 /*!
4922  * Returns a new DataArrayDouble that is a subtraction of two given arrays. There are 3
4923  * valid cases.
4924  * 1.  The arrays have same number of tuples and components. Then each value of
4925  *   the result array (_a_) is a subtraction of the corresponding values of \a a1 and
4926  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ i, j ].
4927  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
4928  *   component. Then
4929  *   _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ i, 0 ].
4930  * 3.  The arrays have same number of components and one array, say _a2_, has one
4931  *   tuple. Then
4932  *   _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ 0, j ].
4933  *
4934  * Info on components is copied either from the first array (in the first case) or from
4935  * the array with maximal number of elements (getNbOfElems()).
4936  *  \param [in] a1 - an array to subtract from.
4937  *  \param [in] a2 - an array to subtract.
4938  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4939  *          The caller is to delete this result array using decrRef() as it is no more
4940  *          needed.
4941  *  \throw If either \a a1 or \a a2 is NULL.
4942  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
4943  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
4944  *         none of them has number of tuples or components equal to 1.
4945  */
4946 DataArrayDouble *DataArrayDouble::Substract(const DataArrayDouble *a1, const DataArrayDouble *a2)
4947 {
4948   if(!a1 || !a2)
4949     throw INTERP_KERNEL::Exception("DataArrayDouble::Substract : input DataArrayDouble instance is NULL !");
4950   int nbOfTuple1=a1->getNumberOfTuples();
4951   int nbOfTuple2=a2->getNumberOfTuples();
4952   int nbOfComp1=a1->getNumberOfComponents();
4953   int nbOfComp2=a2->getNumberOfComponents();
4954   if(nbOfTuple2==nbOfTuple1)
4955     {
4956       if(nbOfComp1==nbOfComp2)
4957         {
4958           MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
4959           ret->alloc(nbOfTuple2,nbOfComp1);
4960           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::minus<double>());
4961           ret->copyStringInfoFrom(*a1);
4962           return ret.retn();
4963         }
4964       else if(nbOfComp2==1)
4965         {
4966           MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
4967           ret->alloc(nbOfTuple1,nbOfComp1);
4968           const double *a2Ptr=a2->getConstPointer();
4969           const double *a1Ptr=a1->getConstPointer();
4970           double *res=ret->getPointer();
4971           for(int i=0;i<nbOfTuple1;i++)
4972             res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::minus<double>(),a2Ptr[i]));
4973           ret->copyStringInfoFrom(*a1);
4974           return ret.retn();
4975         }
4976       else
4977         {
4978           a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Substract !");
4979           return 0;
4980         }
4981     }
4982   else if(nbOfTuple2==1)
4983     {
4984       a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Substract !");
4985       MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
4986       ret->alloc(nbOfTuple1,nbOfComp1);
4987       const double *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
4988       double *pt=ret->getPointer();
4989       for(int i=0;i<nbOfTuple1;i++)
4990         pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::minus<double>());
4991       ret->copyStringInfoFrom(*a1);
4992       return ret.retn();
4993     }
4994   else
4995     {
4996       a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Substract !");//will always throw an exception
4997       return 0;
4998     }
4999 }
5000
5001 /*!
5002  * Subtract values of another DataArrayDouble from values of \a this one. There are 3
5003  * valid cases.
5004  * 1.  The arrays have same number of tuples and components. Then each value of
5005  *   \a other array is subtracted from the corresponding value of \a this array, i.e.:
5006  *   _a_ [ i, j ] -= _other_ [ i, j ].
5007  * 2.  The arrays have same number of tuples and \a other array has one component. Then
5008  *   _a_ [ i, j ] -= _other_ [ i, 0 ].
5009  * 3.  The arrays have same number of components and \a other array has one tuple. Then
5010  *   _a_ [ i, j ] -= _a2_ [ 0, j ].
5011  *
5012  *  \param [in] other - an array to subtract from \a this one.
5013  *  \throw If \a other is NULL.
5014  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
5015  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
5016  *         \a other has number of both tuples and components not equal to 1.
5017  */
5018 void DataArrayDouble::substractEqual(const DataArrayDouble *other)
5019 {
5020   if(!other)
5021     throw INTERP_KERNEL::Exception("DataArrayDouble::substractEqual : input DataArrayDouble instance is NULL !");
5022   const char *msg="Nb of tuples mismatch for DataArrayDouble::substractEqual  !";
5023   checkAllocated();
5024   other->checkAllocated();
5025   int nbOfTuple=getNumberOfTuples();
5026   int nbOfTuple2=other->getNumberOfTuples();
5027   int nbOfComp=getNumberOfComponents();
5028   int nbOfComp2=other->getNumberOfComponents();
5029   if(nbOfTuple==nbOfTuple2)
5030     {
5031       if(nbOfComp==nbOfComp2)
5032         {
5033           std::transform(begin(),end(),other->begin(),getPointer(),std::minus<double>());
5034         }
5035       else if(nbOfComp2==1)
5036         {
5037           double *ptr=getPointer();
5038           const double *ptrc=other->getConstPointer();
5039           for(int i=0;i<nbOfTuple;i++)
5040             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::minus<double>(),*ptrc++)); 
5041         }
5042       else
5043         throw INTERP_KERNEL::Exception(msg);
5044     }
5045   else if(nbOfTuple2==1)
5046     {
5047       if(nbOfComp2==nbOfComp)
5048         {
5049           double *ptr=getPointer();
5050           const double *ptrc=other->getConstPointer();
5051           for(int i=0;i<nbOfTuple;i++)
5052             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::minus<double>());
5053         }
5054       else
5055         throw INTERP_KERNEL::Exception(msg);
5056     }
5057   else
5058     throw INTERP_KERNEL::Exception(msg);
5059   declareAsNew();
5060 }
5061
5062 /*!
5063  * Returns a new DataArrayDouble that is a product of two given arrays. There are 3
5064  * valid cases.
5065  * 1.  The arrays have same number of tuples and components. Then each value of
5066  *   the result array (_a_) is a product of the corresponding values of \a a1 and
5067  *   \a a2, i.e. _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ i, j ].
5068  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
5069  *   component. Then
5070  *   _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ i, 0 ].
5071  * 3.  The arrays have same number of components and one array, say _a2_, has one
5072  *   tuple. Then
5073  *   _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ 0, j ].
5074  *
5075  * Info on components is copied either from the first array (in the first case) or from
5076  * the array with maximal number of elements (getNbOfElems()).
5077  *  \param [in] a1 - a factor array.
5078  *  \param [in] a2 - another factor array.
5079  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
5080  *          The caller is to delete this result array using decrRef() as it is no more
5081  *          needed.
5082  *  \throw If either \a a1 or \a a2 is NULL.
5083  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
5084  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
5085  *         none of them has number of tuples or components equal to 1.
5086  */
5087 DataArrayDouble *DataArrayDouble::Multiply(const DataArrayDouble *a1, const DataArrayDouble *a2)
5088 {
5089   if(!a1 || !a2)
5090     throw INTERP_KERNEL::Exception("DataArrayDouble::Multiply : input DataArrayDouble instance is NULL !");
5091   int nbOfTuple=a1->getNumberOfTuples();
5092   int nbOfTuple2=a2->getNumberOfTuples();
5093   int nbOfComp=a1->getNumberOfComponents();
5094   int nbOfComp2=a2->getNumberOfComponents();
5095   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=0;
5096   if(nbOfTuple==nbOfTuple2)
5097     {
5098       if(nbOfComp==nbOfComp2)
5099         {
5100           ret=DataArrayDouble::New();
5101           ret->alloc(nbOfTuple,nbOfComp);
5102           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::multiplies<double>());
5103           ret->copyStringInfoFrom(*a1);
5104         }
5105       else
5106         {
5107           int nbOfCompMin,nbOfCompMax;
5108           const DataArrayDouble *aMin, *aMax;
5109           if(nbOfComp>nbOfComp2)
5110             {
5111               nbOfCompMin=nbOfComp2; nbOfCompMax=nbOfComp;
5112               aMin=a2; aMax=a1;
5113             }
5114           else
5115             {
5116               nbOfCompMin=nbOfComp; nbOfCompMax=nbOfComp2;
5117               aMin=a1; aMax=a2;
5118             }
5119           if(nbOfCompMin==1)
5120             {
5121               ret=DataArrayDouble::New();
5122               ret->alloc(nbOfTuple,nbOfCompMax);
5123               const double *aMinPtr=aMin->getConstPointer();
5124               const double *aMaxPtr=aMax->getConstPointer();
5125               double *res=ret->getPointer();
5126               for(int i=0;i<nbOfTuple;i++)
5127                 res=std::transform(aMaxPtr+i*nbOfCompMax,aMaxPtr+(i+1)*nbOfCompMax,res,std::bind2nd(std::multiplies<double>(),aMinPtr[i]));
5128               ret->copyStringInfoFrom(*aMax);
5129             }
5130           else
5131             throw INTERP_KERNEL::Exception("Nb of components mismatch for array Multiply !");
5132         }
5133     }
5134   else if((nbOfTuple==1 && nbOfTuple2>1) || (nbOfTuple>1 && nbOfTuple2==1))
5135     {
5136       if(nbOfComp==nbOfComp2)
5137         {
5138           int nbOfTupleMax=std::max(nbOfTuple,nbOfTuple2);
5139           const DataArrayDouble *aMin=nbOfTuple>nbOfTuple2?a2:a1;
5140           const DataArrayDouble *aMax=nbOfTuple>nbOfTuple2?a1:a2;
5141           const double *aMinPtr=aMin->getConstPointer(),*aMaxPtr=aMax->getConstPointer();
5142           ret=DataArrayDouble::New();
5143           ret->alloc(nbOfTupleMax,nbOfComp);
5144           double *res=ret->getPointer();
5145           for(int i=0;i<nbOfTupleMax;i++)
5146             res=std::transform(aMaxPtr+i*nbOfComp,aMaxPtr+(i+1)*nbOfComp,aMinPtr,res,std::multiplies<double>());
5147           ret->copyStringInfoFrom(*aMax);
5148         }
5149       else
5150         throw INTERP_KERNEL::Exception("Nb of components mismatch for array Multiply !");
5151     }
5152   else
5153     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Multiply !");
5154   return ret.retn();
5155 }
5156
5157 /*!
5158  * Multiply values of another DataArrayDouble to values of \a this one. There are 3
5159  * valid cases.
5160  * 1.  The arrays have same number of tuples and components. Then each value of
5161  *   \a other array is multiplied to the corresponding value of \a this array, i.e.
5162  *   _this_ [ i, j ] *= _other_ [ i, j ].
5163  * 2.  The arrays have same number of tuples and \a other array has one component. Then
5164  *   _this_ [ i, j ] *= _other_ [ i, 0 ].
5165  * 3.  The arrays have same number of components and \a other array has one tuple. Then
5166  *   _this_ [ i, j ] *= _a2_ [ 0, j ].
5167  *
5168  *  \param [in] other - an array to multiply to \a this one.
5169  *  \throw If \a other is NULL.
5170  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
5171  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
5172  *         \a other has number of both tuples and components not equal to 1.
5173  */
5174 void DataArrayDouble::multiplyEqual(const DataArrayDouble *other)
5175 {
5176   if(!other)
5177     throw INTERP_KERNEL::Exception("DataArrayDouble::multiplyEqual : input DataArrayDouble instance is NULL !");
5178   const char *msg="Nb of tuples mismatch for DataArrayDouble::multiplyEqual !";
5179   checkAllocated();
5180   other->checkAllocated();
5181   int nbOfTuple=getNumberOfTuples();
5182   int nbOfTuple2=other->getNumberOfTuples();
5183   int nbOfComp=getNumberOfComponents();
5184   int nbOfComp2=other->getNumberOfComponents();
5185   if(nbOfTuple==nbOfTuple2)
5186     {
5187       if(nbOfComp==nbOfComp2)
5188         {
5189           std::transform(begin(),end(),other->begin(),getPointer(),std::multiplies<double>());
5190         }
5191       else if(nbOfComp2==1)
5192         {
5193           double *ptr=getPointer();
5194           const double *ptrc=other->getConstPointer();
5195           for(int i=0;i<nbOfTuple;i++)
5196             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::multiplies<double>(),*ptrc++));
5197         }
5198       else
5199         throw INTERP_KERNEL::Exception(msg);
5200     }
5201   else if(nbOfTuple2==1)
5202     {
5203       if(nbOfComp2==nbOfComp)
5204         {
5205           double *ptr=getPointer();
5206           const double *ptrc=other->getConstPointer();
5207           for(int i=0;i<nbOfTuple;i++)
5208             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::multiplies<double>());
5209         }
5210       else
5211         throw INTERP_KERNEL::Exception(msg);
5212     }
5213   else
5214     throw INTERP_KERNEL::Exception(msg);
5215   declareAsNew();
5216 }
5217
5218 /*!
5219  * Returns a new DataArrayDouble that is a division of two given arrays. There are 3
5220  * valid cases.
5221  * 1.  The arrays have same number of tuples and components. Then each value of
5222  *   the result array (_a_) is a division of the corresponding values of \a a1 and
5223  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ i, j ].
5224  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
5225  *   component. Then
5226  *   _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ i, 0 ].
5227  * 3.  The arrays have same number of components and one array, say _a2_, has one
5228  *   tuple. Then
5229  *   _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ 0, j ].
5230  *
5231  * Info on components is copied either from the first array (in the first case) or from
5232  * the array with maximal number of elements (getNbOfElems()).
5233  *  \warning No check of division by zero is performed!
5234  *  \param [in] a1 - a numerator array.
5235  *  \param [in] a2 - a denominator array.
5236  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
5237  *          The caller is to delete this result array using decrRef() as it is no more
5238  *          needed.
5239  *  \throw If either \a a1 or \a a2 is NULL.
5240  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
5241  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
5242  *         none of them has number of tuples or components equal to 1.
5243  */
5244 DataArrayDouble *DataArrayDouble::Divide(const DataArrayDouble *a1, const DataArrayDouble *a2)
5245 {
5246   if(!a1 || !a2)
5247     throw INTERP_KERNEL::Exception("DataArrayDouble::Divide : input DataArrayDouble instance is NULL !");
5248   int nbOfTuple1=a1->getNumberOfTuples();
5249   int nbOfTuple2=a2->getNumberOfTuples();
5250   int nbOfComp1=a1->getNumberOfComponents();
5251   int nbOfComp2=a2->getNumberOfComponents();
5252   if(nbOfTuple2==nbOfTuple1)
5253     {
5254       if(nbOfComp1==nbOfComp2)
5255         {
5256           MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
5257           ret->alloc(nbOfTuple2,nbOfComp1);
5258           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::divides<double>());
5259           ret->copyStringInfoFrom(*a1);
5260           return ret.retn();
5261         }
5262       else if(nbOfComp2==1)
5263         {
5264           MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
5265           ret->alloc(nbOfTuple1,nbOfComp1);
5266           const double *a2Ptr=a2->getConstPointer();
5267           const double *a1Ptr=a1->getConstPointer();
5268           double *res=ret->getPointer();
5269           for(int i=0;i<nbOfTuple1;i++)
5270             res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::divides<double>(),a2Ptr[i]));
5271           ret->copyStringInfoFrom(*a1);
5272           return ret.retn();
5273         }
5274       else
5275         {
5276           a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Divide !");
5277           return 0;
5278         }
5279     }
5280   else if(nbOfTuple2==1)
5281     {
5282       a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Divide !");
5283       MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
5284       ret->alloc(nbOfTuple1,nbOfComp1);
5285       const double *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
5286       double *pt=ret->getPointer();
5287       for(int i=0;i<nbOfTuple1;i++)
5288         pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::divides<double>());
5289       ret->copyStringInfoFrom(*a1);
5290       return ret.retn();
5291     }
5292   else
5293     {
5294       a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Divide !");//will always throw an exception
5295       return 0;
5296     }
5297 }
5298
5299 /*!
5300  * Divide values of \a this array by values of another DataArrayDouble. There are 3
5301  * valid cases.
5302  * 1.  The arrays have same number of tuples and components. Then each value of
5303  *    \a this array is divided by the corresponding value of \a other one, i.e.:
5304  *   _a_ [ i, j ] /= _other_ [ i, j ].
5305  * 2.  The arrays have same number of tuples and \a other array has one component. Then
5306  *   _a_ [ i, j ] /= _other_ [ i, 0 ].
5307  * 3.  The arrays have same number of components and \a other array has one tuple. Then
5308  *   _a_ [ i, j ] /= _a2_ [ 0, j ].
5309  *
5310  *  \warning No check of division by zero is performed!
5311  *  \param [in] other - an array to divide \a this one by.
5312  *  \throw If \a other is NULL.
5313  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
5314  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
5315  *         \a other has number of both tuples and components not equal to 1.
5316  */
5317 void DataArrayDouble::divideEqual(const DataArrayDouble *other)
5318 {
5319   if(!other)
5320     throw INTERP_KERNEL::Exception("DataArrayDouble::divideEqual : input DataArrayDouble instance is NULL !");
5321   const char *msg="Nb of tuples mismatch for DataArrayDouble::divideEqual !";
5322   checkAllocated();
5323   other->checkAllocated();
5324   int nbOfTuple=getNumberOfTuples();
5325   int nbOfTuple2=other->getNumberOfTuples();
5326   int nbOfComp=getNumberOfComponents();
5327   int nbOfComp2=other->getNumberOfComponents();
5328   if(nbOfTuple==nbOfTuple2)
5329     {
5330       if(nbOfComp==nbOfComp2)
5331         {
5332           std::transform(begin(),end(),other->begin(),getPointer(),std::divides<double>());
5333         }
5334       else if(nbOfComp2==1)
5335         {
5336           double *ptr=getPointer();
5337           const double *ptrc=other->getConstPointer();
5338           for(int i=0;i<nbOfTuple;i++)
5339             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::divides<double>(),*ptrc++));
5340         }
5341       else
5342         throw INTERP_KERNEL::Exception(msg);
5343     }
5344   else if(nbOfTuple2==1)
5345     {
5346       if(nbOfComp2==nbOfComp)
5347         {
5348           double *ptr=getPointer();
5349           const double *ptrc=other->getConstPointer();
5350           for(int i=0;i<nbOfTuple;i++)
5351             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::divides<double>());
5352         }
5353       else
5354         throw INTERP_KERNEL::Exception(msg);
5355     }
5356   else
5357     throw INTERP_KERNEL::Exception(msg);
5358   declareAsNew();
5359 }
5360
5361 /*!
5362  * Returns a new DataArrayDouble that is the result of pow of two given arrays. There are 3
5363  * valid cases.
5364  *
5365  *  \param [in] a1 - an array to pow up.
5366  *  \param [in] a2 - another array to sum up.
5367  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
5368  *          The caller is to delete this result array using decrRef() as it is no more
5369  *          needed.
5370  *  \throw If either \a a1 or \a a2 is NULL.
5371  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
5372  *  \throw If \a a1->getNumberOfComponents() != 1 or \a a2->getNumberOfComponents() != 1.
5373  *  \throw If there is a negative value in \a a1.
5374  */
5375 DataArrayDouble *DataArrayDouble::Pow(const DataArrayDouble *a1, const DataArrayDouble *a2)
5376 {
5377   if(!a1 || !a2)
5378     throw INTERP_KERNEL::Exception("DataArrayDouble::Pow : at least one of input instances is null !");
5379   int nbOfTuple=a1->getNumberOfTuples();
5380   int nbOfTuple2=a2->getNumberOfTuples();
5381   int nbOfComp=a1->getNumberOfComponents();
5382   int nbOfComp2=a2->getNumberOfComponents();
5383   if(nbOfTuple!=nbOfTuple2)
5384     throw INTERP_KERNEL::Exception("DataArrayDouble::Pow : number of tuples mismatches !");
5385   if(nbOfComp!=1 || nbOfComp2!=1)
5386     throw INTERP_KERNEL::Exception("DataArrayDouble::Pow : number of components of both arrays must be equal to 1 !");
5387   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New(); ret->alloc(nbOfTuple,1);
5388   const double *ptr1(a1->begin()),*ptr2(a2->begin());
5389   double *ptr=ret->getPointer();
5390   for(int i=0;i<nbOfTuple;i++,ptr1++,ptr2++,ptr++)
5391     {
5392       if(*ptr1>=0)
5393         {
5394           *ptr=pow(*ptr1,*ptr2);
5395         }
5396       else
5397         {
5398           std::ostringstream oss; oss << "DataArrayDouble::Pow : on tuple #" << i << " of a1 value is < 0 (" << *ptr1 << ") !";
5399           throw INTERP_KERNEL::Exception(oss.str().c_str());
5400         }
5401     }
5402   return ret.retn();
5403 }
5404
5405 /*!
5406  * Apply pow on values of another DataArrayDouble to values of \a this one.
5407  *
5408  *  \param [in] other - an array to pow to \a this one.
5409  *  \throw If \a other is NULL.
5410  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples()
5411  *  \throw If \a this->getNumberOfComponents() != 1 or \a other->getNumberOfComponents() != 1
5412  *  \throw If there is a negative value in \a this.
5413  */
5414 void DataArrayDouble::powEqual(const DataArrayDouble *other)
5415 {
5416   if(!other)
5417     throw INTERP_KERNEL::Exception("DataArrayDouble::powEqual : input instance is null !");
5418   int nbOfTuple=getNumberOfTuples();
5419   int nbOfTuple2=other->getNumberOfTuples();
5420   int nbOfComp=getNumberOfComponents();
5421   int nbOfComp2=other->getNumberOfComponents();
5422   if(nbOfTuple!=nbOfTuple2)
5423     throw INTERP_KERNEL::Exception("DataArrayDouble::powEqual : number of tuples mismatches !");
5424   if(nbOfComp!=1 || nbOfComp2!=1)
5425     throw INTERP_KERNEL::Exception("DataArrayDouble::powEqual : number of components of both arrays must be equal to 1 !");
5426   double *ptr=getPointer();
5427   const double *ptrc=other->begin();
5428   for(int i=0;i<nbOfTuple;i++,ptrc++,ptr++)
5429     {
5430       if(*ptr>=0)
5431         *ptr=pow(*ptr,*ptrc);
5432       else
5433         {
5434           std::ostringstream oss; oss << "DataArrayDouble::powEqual : on tuple #" << i << " of this value is < 0 (" << *ptr << ") !";
5435           throw INTERP_KERNEL::Exception(oss.str().c_str());
5436         }
5437     }
5438   declareAsNew();
5439 }
5440
5441 /*!
5442  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
5443  * Server side.
5444  */
5445 void DataArrayDouble::getTinySerializationIntInformation(std::vector<int>& tinyInfo) const
5446 {
5447   tinyInfo.resize(2);
5448   if(isAllocated())
5449     {
5450       tinyInfo[0]=getNumberOfTuples();
5451       tinyInfo[1]=getNumberOfComponents();
5452     }
5453   else
5454     {
5455       tinyInfo[0]=-1;
5456       tinyInfo[1]=-1;
5457     }
5458 }
5459
5460 /*!
5461  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
5462  * Server side.
5463  */
5464 void DataArrayDouble::getTinySerializationStrInformation(std::vector<std::string>& tinyInfo) const
5465 {
5466   if(isAllocated())
5467     {
5468       int nbOfCompo=getNumberOfComponents();
5469       tinyInfo.resize(nbOfCompo+1);
5470       tinyInfo[0]=getName();
5471       for(int i=0;i<nbOfCompo;i++)
5472         tinyInfo[i+1]=getInfoOnComponent(i);
5473     }
5474   else
5475     {
5476       tinyInfo.resize(1);
5477       tinyInfo[0]=getName();
5478     }
5479 }
5480
5481 /*!
5482  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
5483  * This method returns if a feeding is needed.
5484  */
5485 bool DataArrayDouble::resizeForUnserialization(const std::vector<int>& tinyInfoI)
5486 {
5487   int nbOfTuple=tinyInfoI[0];
5488   int nbOfComp=tinyInfoI[1];
5489   if(nbOfTuple!=-1 || nbOfComp!=-1)
5490     {
5491       alloc(nbOfTuple,nbOfComp);
5492       return true;
5493     }
5494   return false;
5495 }
5496
5497 /*!
5498  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
5499  */
5500 void DataArrayDouble::finishUnserialization(const std::vector<int>& tinyInfoI, const std::vector<std::string>& tinyInfoS)
5501 {
5502   setName(tinyInfoS[0].c_str());
5503   if(isAllocated())
5504     {
5505       int nbOfCompo=getNumberOfComponents();
5506       for(int i=0;i<nbOfCompo;i++)
5507         setInfoOnComponent(i,tinyInfoS[i+1].c_str());
5508     }
5509 }
5510
5511 DataArrayDoubleIterator::DataArrayDoubleIterator(DataArrayDouble *da):_da(da),_tuple_id(0),_nb_comp(0),_nb_tuple(0)
5512 {
5513   if(_da)
5514     {
5515       _da->incrRef();
5516       if(_da->isAllocated())
5517         {
5518           _nb_comp=da->getNumberOfComponents();
5519           _nb_tuple=da->getNumberOfTuples();
5520           _pt=da->getPointer();
5521         }
5522     }
5523 }
5524
5525 DataArrayDoubleIterator::~DataArrayDoubleIterator()
5526 {
5527   if(_da)
5528     _da->decrRef();
5529 }
5530
5531 DataArrayDoubleTuple *DataArrayDoubleIterator::nextt()
5532 {
5533   if(_tuple_id<_nb_tuple)
5534     {
5535       _tuple_id++;
5536       DataArrayDoubleTuple *ret=new DataArrayDoubleTuple(_pt,_nb_comp);
5537       _pt+=_nb_comp;
5538       return ret;
5539     }
5540   else
5541     return 0;
5542 }
5543
5544 DataArrayDoubleTuple::DataArrayDoubleTuple(double *pt, int nbOfComp):_pt(pt),_nb_of_compo(nbOfComp)
5545 {
5546 }
5547
5548
5549 std::string DataArrayDoubleTuple::repr() const
5550 {
5551   std::ostringstream oss; oss.precision(17); oss << "(";
5552   for(int i=0;i<_nb_of_compo-1;i++)
5553     oss << _pt[i] << ", ";
5554   oss << _pt[_nb_of_compo-1] << ")";
5555   return oss.str();
5556 }
5557
5558 double DataArrayDoubleTuple::doubleValue() const
5559 {
5560   if(_nb_of_compo==1)
5561     return *_pt;
5562   throw INTERP_KERNEL::Exception("DataArrayDoubleTuple::doubleValue : DataArrayDoubleTuple instance has not exactly 1 component -> Not possible to convert it into a double precision float !");
5563 }
5564
5565 /*!
5566  * This method returns a newly allocated instance the caller should dealed with by a ParaMEDMEM::DataArrayDouble::decrRef.
5567  * This method performs \b no copy of data. The content is only referenced using ParaMEDMEM::DataArrayDouble::useArray with ownership set to \b false.
5568  * 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
5569  * \b nbOfCompo=1 and \bnbOfTuples==this->_nb_of_elem.
5570  */
5571 DataArrayDouble *DataArrayDoubleTuple::buildDADouble(int nbOfTuples, int nbOfCompo) const
5572 {
5573   if((_nb_of_compo==nbOfCompo && nbOfTuples==1) || (_nb_of_compo==nbOfTuples && nbOfCompo==1))
5574     {
5575       DataArrayDouble *ret=DataArrayDouble::New();
5576       ret->useExternalArrayWithRWAccess(_pt,nbOfTuples,nbOfCompo);
5577       return ret;
5578     }
5579   else
5580     {
5581       std::ostringstream oss; oss << "DataArrayDoubleTuple::buildDADouble : unable to build a requested DataArrayDouble instance with nbofTuple=" << nbOfTuples << " and nbOfCompo=" << nbOfCompo;
5582       oss << ".\nBecause the number of elements in this is " << _nb_of_compo << " !";
5583       throw INTERP_KERNEL::Exception(oss.str().c_str());
5584     }
5585 }
5586
5587 /*!
5588  * Returns a new instance of DataArrayInt. The caller is to delete this array
5589  * using decrRef() as it is no more needed. 
5590  */
5591 DataArrayInt *DataArrayInt::New()
5592 {
5593   return new DataArrayInt;
5594 }
5595
5596 /*!
5597  * Checks if raw data is allocated. Read more on the raw data
5598  * in \ref MEDCouplingArrayBasicsTuplesAndCompo "DataArrays infos" for more information.
5599  *  \return bool - \a true if the raw data is allocated, \a false else.
5600  */
5601 bool DataArrayInt::isAllocated() const
5602 {
5603   return getConstPointer()!=0;
5604 }
5605
5606 /*!
5607  * Checks if raw data is allocated and throws an exception if it is not the case.
5608  *  \throw If the raw data is not allocated.
5609  */
5610 void DataArrayInt::checkAllocated() const
5611 {
5612   if(!isAllocated())
5613     throw INTERP_KERNEL::Exception("DataArrayInt::checkAllocated : Array is defined but not allocated ! Call alloc or setValues method first !");
5614 }
5615
5616 /*!
5617  * This method desallocated \a this without modification of informations relative to the components.
5618  * After call of this method, DataArrayInt::isAllocated will return false.
5619  * If \a this is already not allocated, \a this is let unchanged.
5620  */
5621 void DataArrayInt::desallocate()
5622 {
5623   _mem.destroy();
5624 }
5625
5626 std::size_t DataArrayInt::getHeapMemorySizeWithoutChildren() const
5627 {
5628   std::size_t sz(_mem.getNbOfElemAllocated());
5629   sz*=sizeof(int);
5630   return DataArray::getHeapMemorySizeWithoutChildren()+sz;
5631 }
5632
5633 /*!
5634  * Returns the only one value in \a this, if and only if number of elements
5635  * (nb of tuples * nb of components) is equal to 1, and that \a this is allocated.
5636  *  \return double - the sole value stored in \a this array.
5637  *  \throw If at least one of conditions stated above is not fulfilled.
5638  */
5639 int DataArrayInt::intValue() const
5640 {
5641   if(isAllocated())
5642     {
5643       if(getNbOfElems()==1)
5644         {
5645           return *getConstPointer();
5646         }
5647       else
5648         throw INTERP_KERNEL::Exception("DataArrayInt::intValue : DataArrayInt instance is allocated but number of elements is not equal to 1 !");
5649     }
5650   else
5651     throw INTERP_KERNEL::Exception("DataArrayInt::intValue : DataArrayInt instance is not allocated !");
5652 }
5653
5654 /*!
5655  * Returns an integer value characterizing \a this array, which is useful for a quick
5656  * comparison of many instances of DataArrayInt.
5657  *  \return int - the hash value.
5658  *  \throw If \a this is not allocated.
5659  */
5660 int DataArrayInt::getHashCode() const
5661 {
5662   checkAllocated();
5663   std::size_t nbOfElems=getNbOfElems();
5664   int ret=nbOfElems*65536;
5665   int delta=3;
5666   if(nbOfElems>48)
5667     delta=nbOfElems/8;
5668   int ret0=0;
5669   const int *pt=begin();
5670   for(std::size_t i=0;i<nbOfElems;i+=delta)
5671     ret0+=pt[i] & 0x1FFF;
5672   return ret+ret0;
5673 }
5674
5675 /*!
5676  * Checks the number of tuples.
5677  *  \return bool - \a true if getNumberOfTuples() == 0, \a false else.
5678  *  \throw If \a this is not allocated.
5679  */
5680 bool DataArrayInt::empty() const
5681 {
5682   checkAllocated();
5683   return getNumberOfTuples()==0;
5684 }
5685
5686 /*!
5687  * Returns a full copy of \a this. For more info on copying data arrays see
5688  * \ref MEDCouplingArrayBasicsCopyDeep.
5689  *  \return DataArrayInt * - a new instance of DataArrayInt.
5690  */
5691 DataArrayInt *DataArrayInt::deepCpy() const
5692 {
5693   return new DataArrayInt(*this);
5694 }
5695
5696 /*!
5697  * Returns either a \a deep or \a shallow copy of this array. For more info see
5698  * \ref MEDCouplingArrayBasicsCopyDeep and \ref MEDCouplingArrayBasicsCopyShallow.
5699  *  \param [in] dCpy - if \a true, a deep copy is returned, else, a shallow one.
5700  *  \return DataArrayInt * - either a new instance of DataArrayInt (if \a dCpy
5701  *          == \a true) or \a this instance (if \a dCpy == \a false).
5702  */
5703 DataArrayInt *DataArrayInt::performCpy(bool dCpy) const
5704 {
5705   if(dCpy)
5706     return deepCpy();
5707   else
5708     {
5709       incrRef();
5710       return const_cast<DataArrayInt *>(this);
5711     }
5712 }
5713
5714 /*!
5715  * Copies all the data from another DataArrayInt. For more info see
5716  * \ref MEDCouplingArrayBasicsCopyDeepAssign.
5717  *  \param [in] other - another instance of DataArrayInt to copy data from.
5718  *  \throw If the \a other is not allocated.
5719  */
5720 void DataArrayInt::cpyFrom(const DataArrayInt& other)
5721 {
5722   other.checkAllocated();
5723   int nbOfTuples=other.getNumberOfTuples();
5724   int nbOfComp=other.getNumberOfComponents();
5725   allocIfNecessary(nbOfTuples,nbOfComp);
5726   std::size_t nbOfElems=(std::size_t)nbOfTuples*nbOfComp;
5727   int *pt=getPointer();
5728   const int *ptI=other.getConstPointer();
5729   for(std::size_t i=0;i<nbOfElems;i++)
5730     pt[i]=ptI[i];
5731   copyStringInfoFrom(other);
5732 }
5733
5734 /*!
5735  * This method reserve nbOfElems elements in memory ( nbOfElems*4 bytes ) \b without impacting the number of tuples in \a this.
5736  * 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.
5737  * If \a this has not already been allocated, number of components is set to one.
5738  * This method allows to reduce number of reallocations on invokation of DataArrayInt::pushBackSilent and DataArrayInt::pushBackValsSilent on \a this.
5739  * 
5740  * \sa DataArrayInt::pack, DataArrayInt::pushBackSilent, DataArrayInt::pushBackValsSilent
5741  */
5742 void DataArrayInt::reserve(std::size_t nbOfElems)
5743 {
5744   int nbCompo=getNumberOfComponents();
5745   if(nbCompo==1)
5746     {
5747       _mem.reserve(nbOfElems);
5748     }
5749   else if(nbCompo==0)
5750     {
5751       _mem.reserve(nbOfElems);
5752       _info_on_compo.resize(1);
5753     }
5754   else
5755     throw INTERP_KERNEL::Exception("DataArrayInt::reserve : not available for DataArrayInt with number of components different than 1 !");
5756 }
5757
5758 /*!
5759  * 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
5760  * of counter. So the caller is expected to call TimeLabel::declareAsNew on \a this at the end of the push session.
5761  *
5762  * \param [in] val the value to be added in \a this
5763  * \throw If \a this has already been allocated with number of components different from one.
5764  * \sa DataArrayInt::pushBackValsSilent
5765  */
5766 void DataArrayInt::pushBackSilent(int val)
5767 {
5768   int nbCompo=getNumberOfComponents();
5769   if(nbCompo==1)
5770     _mem.pushBack(val);
5771   else if(nbCompo==0)
5772     {
5773       _info_on_compo.resize(1);
5774       _mem.pushBack(val);
5775     }
5776   else
5777     throw INTERP_KERNEL::Exception("DataArrayInt::pushBackSilent : not available for DataArrayInt with number of components different than 1 !");
5778 }
5779
5780 /*!
5781  * 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
5782  * of counter. So the caller is expected to call TimeLabel::declareAsNew on \a this at the end of the push session.
5783  *
5784  *  \param [in] valsBg - an array of values to push at the end of \this.
5785  *  \param [in] valsEnd - specifies the end of the array \a valsBg, so that
5786  *              the last value of \a valsBg is \a valsEnd[ -1 ].
5787  * \throw If \a this has already been allocated with number of components different from one.
5788  * \sa DataArrayInt::pushBackSilent
5789  */
5790 void DataArrayInt::pushBackValsSilent(const int *valsBg, const int *valsEnd)
5791 {
5792   int nbCompo=getNumberOfComponents();
5793   if(nbCompo==1)
5794     _mem.insertAtTheEnd(valsBg,valsEnd);
5795   else if(nbCompo==0)
5796     {
5797       _info_on_compo.resize(1);
5798       _mem.insertAtTheEnd(valsBg,valsEnd);
5799     }
5800   else
5801     throw INTERP_KERNEL::Exception("DataArrayInt::pushBackValsSilent : not available for DataArrayInt with number of components different than 1 !");
5802 }
5803
5804 /*!
5805  * This method returns silently ( without updating time label in \a this ) the last value, if any and suppress it.
5806  * \throw If \a this is already empty.
5807  * \throw If \a this has number of components different from one.
5808  */
5809 int DataArrayInt::popBackSilent()
5810 {
5811   if(getNumberOfComponents()==1)
5812     return _mem.popBack();
5813   else
5814     throw INTERP_KERNEL::Exception("DataArrayInt::popBackSilent : not available for DataArrayInt with number of components different than 1 !");
5815 }
5816
5817 /*!
5818  * 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.
5819  *
5820  * \sa DataArrayInt::getHeapMemorySizeWithoutChildren, DataArrayInt::reserve
5821  */
5822 void DataArrayInt::pack() const
5823 {
5824   _mem.pack();
5825 }
5826
5827 /*!
5828  * Allocates the raw data in memory. If exactly as same memory as needed already
5829  * allocated, it is not re-allocated.
5830  *  \param [in] nbOfTuple - number of tuples of data to allocate.
5831  *  \param [in] nbOfCompo - number of components of data to allocate.
5832  *  \throw If \a nbOfTuple < 0 or \a nbOfCompo < 0.
5833  */
5834 void DataArrayInt::allocIfNecessary(int nbOfTuple, int nbOfCompo)
5835 {
5836   if(isAllocated())
5837     {
5838       if(nbOfTuple!=getNumberOfTuples() || nbOfCompo!=getNumberOfComponents())
5839         alloc(nbOfTuple,nbOfCompo);
5840     }
5841   else
5842     alloc(nbOfTuple,nbOfCompo);
5843 }
5844
5845 /*!
5846  * Allocates the raw data in memory. If the memory was already allocated, then it is
5847  * freed and re-allocated. See an example of this method use
5848  * \ref MEDCouplingArraySteps1WC "here".
5849  *  \param [in] nbOfTuple - number of tuples of data to allocate.
5850  *  \param [in] nbOfCompo - number of components of data to allocate.
5851  *  \throw If \a nbOfTuple < 0 or \a nbOfCompo < 0.
5852  */
5853 void DataArrayInt::alloc(int nbOfTuple, int nbOfCompo)
5854 {
5855   if(nbOfTuple<0 || nbOfCompo<0)
5856     throw INTERP_KERNEL::Exception("DataArrayInt::alloc : request for negative length of data !");
5857   _info_on_compo.resize(nbOfCompo);
5858   _mem.alloc(nbOfCompo*(std::size_t)nbOfTuple);
5859   declareAsNew();
5860 }
5861
5862 /*!
5863  * Assign zero to all values in \a this array. To know more on filling arrays see
5864  * \ref MEDCouplingArrayFill.
5865  * \throw If \a this is not allocated.
5866  */
5867 void DataArrayInt::fillWithZero()
5868 {
5869   checkAllocated();
5870   _mem.fillWithValue(0);
5871   declareAsNew();
5872 }
5873
5874 /*!
5875  * Assign \a val to all values in \a this array. To know more on filling arrays see
5876  * \ref MEDCouplingArrayFill.
5877  *  \param [in] val - the value to fill with.
5878  *  \throw If \a this is not allocated.
5879  */
5880 void DataArrayInt::fillWithValue(int val)
5881 {
5882   checkAllocated();
5883   _mem.fillWithValue(val);
5884   declareAsNew();
5885 }
5886
5887 /*!
5888  * Set all values in \a this array so that the i-th element equals to \a init + i
5889  * (i starts from zero). To know more on filling arrays see \ref MEDCouplingArrayFill.
5890  *  \param [in] init - value to assign to the first element of array.
5891  *  \throw If \a this->getNumberOfComponents() != 1
5892  *  \throw If \a this is not allocated.
5893  */
5894 void DataArrayInt::iota(int init)
5895 {
5896   checkAllocated();
5897   if(getNumberOfComponents()!=1)
5898     throw INTERP_KERNEL::Exception("DataArrayInt::iota : works only for arrays with only one component, you can call 'rearrange' method before !");
5899   int *ptr=getPointer();
5900   int ntuples=getNumberOfTuples();
5901   for(int i=0;i<ntuples;i++)
5902     ptr[i]=init+i;
5903   declareAsNew();
5904 }
5905
5906 /*!
5907  * Returns a textual and human readable representation of \a this instance of
5908  * DataArrayInt. This text is shown when a DataArrayInt is printed in Python.
5909  *  \return std::string - text describing \a this DataArrayInt.
5910  */
5911 std::string DataArrayInt::repr() const
5912 {
5913   std::ostringstream ret;
5914   reprStream(ret);
5915   return ret.str();
5916 }
5917
5918 std::string DataArrayInt::reprZip() const
5919 {
5920   std::ostringstream ret;
5921   reprZipStream(ret);
5922   return ret.str();
5923 }
5924
5925 void DataArrayInt::writeVTK(std::ostream& ofs, int indent, const char *type, const char *nameInFile, DataArrayByte *byteArr) const
5926 {
5927   static const char SPACE[4]={' ',' ',' ',' '};
5928   checkAllocated();
5929   std::string idt(indent,' ');
5930   ofs << idt << "<DataArray type=\"" << type << "\" Name=\"" << nameInFile << "\" NumberOfComponents=\"" << getNumberOfComponents() << "\"";
5931   if(byteArr)
5932     {
5933       ofs << " format=\"appended\" offset=\"" << byteArr->getNumberOfTuples() << "\">";
5934       if(std::string(type)=="Int32")
5935         {
5936           const char *data(reinterpret_cast<const char *>(begin()));
5937           std::size_t sz(getNbOfElems()*sizeof(int));
5938           byteArr->insertAtTheEnd(data,data+sz);
5939           byteArr->insertAtTheEnd(SPACE,SPACE+4);
5940         }
5941       else if(std::string(type)=="Int8")
5942         {
5943           INTERP_KERNEL::AutoPtr<char> tmp(new char[getNbOfElems()]);
5944           std::copy(begin(),end(),(char *)tmp);
5945           byteArr->insertAtTheEnd((char *)tmp,(char *)tmp+getNbOfElems());
5946           byteArr->insertAtTheEnd(SPACE,SPACE+4);
5947         }
5948       else if(std::string(type)=="UInt8")
5949         {
5950           INTERP_KERNEL::AutoPtr<unsigned char> tmp(new unsigned char[getNbOfElems()]);
5951           std::copy(begin(),end(),(unsigned char *)tmp);
5952           byteArr->insertAtTheEnd((unsigned char *)tmp,(unsigned char *)tmp+getNbOfElems());
5953           byteArr->insertAtTheEnd(SPACE,SPACE+4);
5954         }
5955       else
5956         throw INTERP_KERNEL::Exception("DataArrayInt::writeVTK : Only Int32, Int8 and UInt8 supported !");
5957     }
5958   else
5959     {
5960       ofs << " RangeMin=\"" << getMinValueInArray() << "\" RangeMax=\"" << getMaxValueInArray() << "\" format=\"ascii\">\n" << idt;
5961       std::copy(begin(),end(),std::ostream_iterator<int>(ofs," "));
5962     }
5963   ofs << std::endl << idt << "</DataArray>\n";
5964 }
5965
5966 void DataArrayInt::reprStream(std::ostream& stream) const
5967 {
5968   stream << "Name of int array : \"" << _name << "\"\n";
5969   reprWithoutNameStream(stream);
5970 }
5971
5972 void DataArrayInt::reprZipStream(std::ostream& stream) const
5973 {
5974   stream << "Name of int array : \"" << _name << "\"\n";
5975   reprZipWithoutNameStream(stream);
5976 }
5977
5978 void DataArrayInt::reprWithoutNameStream(std::ostream& stream) const
5979 {
5980   DataArray::reprWithoutNameStream(stream);
5981   _mem.repr(getNumberOfComponents(),stream);
5982 }
5983
5984 void DataArrayInt::reprZipWithoutNameStream(std::ostream& stream) const
5985 {
5986   DataArray::reprWithoutNameStream(stream);
5987   _mem.reprZip(getNumberOfComponents(),stream);
5988 }
5989
5990 void DataArrayInt::reprCppStream(const char *varName, std::ostream& stream) const
5991 {
5992   int nbTuples=getNumberOfTuples(),nbComp=getNumberOfComponents();
5993   const int *data=getConstPointer();
5994   stream << "DataArrayInt *" << varName << "=DataArrayInt::New();" << std::endl;
5995   if(nbTuples*nbComp>=1)
5996     {
5997       stream << "const int " << varName << "Data[" << nbTuples*nbComp << "]={";
5998       std::copy(data,data+nbTuples*nbComp-1,std::ostream_iterator<int>(stream,","));
5999       stream << data[nbTuples*nbComp-1] << "};" << std::endl;
6000       stream << varName << "->useArray(" << varName << "Data,false,CPP_DEALLOC," << nbTuples << "," << nbComp << ");" << std::endl;
6001     }
6002   else
6003     stream << varName << "->alloc(" << nbTuples << "," << nbComp << ");" << std::endl;
6004   stream << varName << "->setName(\"" << getName() << "\");" << std::endl;
6005 }
6006
6007 /*!
6008  * Method that gives a quick overvien of \a this for python.
6009  */
6010 void DataArrayInt::reprQuickOverview(std::ostream& stream) const
6011 {
6012   static const std::size_t MAX_NB_OF_BYTE_IN_REPR=300;
6013   stream << "DataArrayInt C++ instance at " << this << ". ";
6014   if(isAllocated())
6015     {
6016       int nbOfCompo=(int)_info_on_compo.size();
6017       if(nbOfCompo>=1)
6018         {
6019           int nbOfTuples=getNumberOfTuples();
6020           stream << "Number of tuples : " << nbOfTuples << ". Number of components : " << nbOfCompo << "." << std::endl;
6021           reprQuickOverviewData(stream,MAX_NB_OF_BYTE_IN_REPR);
6022         }
6023       else
6024         stream << "Number of components : 0.";
6025     }
6026   else
6027     stream << "*** No data allocated ****";
6028 }
6029
6030 void DataArrayInt::reprQuickOverviewData(std::ostream& stream, std::size_t maxNbOfByteInRepr) const
6031 {
6032   const int *data=begin();
6033   int nbOfTuples=getNumberOfTuples();
6034   int nbOfCompo=(int)_info_on_compo.size();
6035   std::ostringstream oss2; oss2 << "[";
6036   std::string oss2Str(oss2.str());
6037   bool isFinished=true;
6038   for(int i=0;i<nbOfTuples && isFinished;i++)
6039     {
6040       if(nbOfCompo>1)
6041         {
6042           oss2 << "(";
6043           for(int j=0;j<nbOfCompo;j++,data++)
6044             {
6045               oss2 << *data;
6046               if(j!=nbOfCompo-1) oss2 << ", ";
6047             }
6048           oss2 << ")";
6049         }
6050       else
6051         oss2 << *data++;
6052       if(i!=nbOfTuples-1) oss2 << ", ";
6053       std::string oss3Str(oss2.str());
6054       if(oss3Str.length()<maxNbOfByteInRepr)
6055         oss2Str=oss3Str;
6056       else
6057         isFinished=false;
6058     }
6059   stream << oss2Str;
6060   if(!isFinished)
6061     stream << "... ";
6062   stream << "]";
6063 }
6064
6065 /*!
6066  * Modifies \a this one-dimensional array so that each value \a v = \a indArrBg[ \a v ],
6067  * i.e. a current value is used as in index to get a new value from \a indArrBg.
6068  *  \param [in] indArrBg - pointer to the first element of array of new values to assign
6069  *         to \a this array.
6070  *  \param [in] indArrEnd - specifies the end of the array \a indArrBg, so that
6071  *              the last value of \a indArrBg is \a indArrEnd[ -1 ].
6072  *  \throw If \a this->getNumberOfComponents() != 1
6073  *  \throw If any value of \a this can't be used as a valid index for 
6074  *         [\a indArrBg, \a indArrEnd).
6075  */
6076 void DataArrayInt::transformWithIndArr(const int *indArrBg, const int *indArrEnd)
6077 {
6078   checkAllocated();
6079   if(getNumberOfComponents()!=1)
6080     throw INTERP_KERNEL::Exception("Call transformWithIndArr method on DataArrayInt with only one component, you can call 'rearrange' method before !");
6081   int nbElemsIn=(int)std::distance(indArrBg,indArrEnd);
6082   int nbOfTuples=getNumberOfTuples();
6083   int *pt=getPointer();
6084   for(int i=0;i<nbOfTuples;i++,pt++)
6085     {
6086       if(*pt>=0 && *pt<nbElemsIn)
6087         *pt=indArrBg[*pt];
6088       else
6089         {
6090           std::ostringstream oss; oss << "DataArrayInt::transformWithIndArr : error on tuple #" << i << " of this value is " << *pt << ", should be in [0," << nbElemsIn << ") !";
6091           throw INTERP_KERNEL::Exception(oss.str().c_str());
6092         }
6093     }
6094   declareAsNew();
6095 }
6096
6097 /*!
6098  * Computes distribution of values of \a this one-dimensional array between given value
6099  * ranges (casts). This method is typically useful for entity number spliting by types,
6100  * for example. 
6101  *  \warning The values contained in \a arrBg should be sorted ascendently. No
6102  *           check of this is be done. If not, the result is not warranted. 
6103  *  \param [in] arrBg - the array of ascending values defining the value ranges. The i-th
6104  *         value of \a arrBg (\a arrBg[ i ]) gives the lowest value of the i-th range,
6105  *         and the greatest value of the i-th range equals to \a arrBg[ i+1 ] - 1. \a
6106  *         arrBg containing \a n values defines \a n-1 ranges. The last value of \a arrBg
6107  *         should be more than every value in \a this array.
6108  *  \param [in] arrEnd - specifies the end of the array \a arrBg, so that
6109  *              the last value of \a arrBg is \a arrEnd[ -1 ].
6110  *  \param [out] castArr - a new instance of DataArrayInt, of same size as \a this array
6111  *         (same number of tuples and components), the caller is to delete 
6112  *         using decrRef() as it is no more needed.
6113  *         This array contains indices of ranges for every value of \a this array. I.e.
6114  *         the i-th value of \a castArr gives the index of range the i-th value of \a this
6115  *         belongs to. Or, in other words, this parameter contains for each tuple in \a
6116  *         this in which cast it holds.
6117  *  \param [out] rankInsideCast - a new instance of DataArrayInt, of same size as \a this
6118  *         array, the caller is to delete using decrRef() as it is no more needed.
6119  *         This array contains ranks of values of \a this array within ranges
6120  *         they belongs to. I.e. the i-th value of \a rankInsideCast gives the rank of
6121  *         the i-th value of \a this array within the \a castArr[ i ]-th range, to which
6122  *         the i-th value of \a this belongs to. Or, in other words, this param contains 
6123  *         for each tuple its rank inside its cast. The rank is computed as difference
6124  *         between the value and the lowest value of range.
6125  *  \param [out] castsPresent - a new instance of DataArrayInt, containing indices of
6126  *         ranges (casts) to which at least one value of \a this array belongs.
6127  *         Or, in other words, this param contains the casts that \a this contains.
6128  *         The caller is to delete this array using decrRef() as it is no more needed.
6129  *
6130  * \b Example: If \a this contains [6,5,0,3,2,7,8,1,4] and \a arrBg contains [0,4,9] then
6131  *            the output of this method will be : 
6132  * - \a castArr       : [1,1,0,0,0,1,1,0,1]
6133  * - \a rankInsideCast: [2,1,0,3,2,3,4,1,0]
6134  * - \a castsPresent  : [0,1]
6135  *
6136  * I.e. values of \a this array belong to 2 ranges: #0 and #1. Value 6 belongs to the
6137  * range #1 and its rank within this range is 2; etc.
6138  *
6139  *  \throw If \a this->getNumberOfComponents() != 1.
6140  *  \throw If \a arrEnd - arrBg < 2.
6141  *  \throw If any value of \a this is not less than \a arrEnd[-1].
6142  */
6143 void DataArrayInt::splitByValueRange(const int *arrBg, const int *arrEnd,
6144                                      DataArrayInt *& castArr, DataArrayInt *& rankInsideCast, DataArrayInt *& castsPresent) const throw(INTERP_KERNEL::Exception)
6145 {
6146   checkAllocated();
6147   if(getNumberOfComponents()!=1)
6148     throw INTERP_KERNEL::Exception("Call splitByValueRange  method on DataArrayInt with only one component, you can call 'rearrange' method before !");
6149   int nbOfTuples=getNumberOfTuples();
6150   std::size_t nbOfCast=std::distance(arrBg,arrEnd);
6151   if(nbOfCast<2)
6152     throw INTERP_KERNEL::Exception("DataArrayInt::splitByValueRange : The input array giving the cast range values should be of size >=2 !");
6153   nbOfCast--;
6154   const int *work=getConstPointer();
6155   typedef std::reverse_iterator<const int *> rintstart;
6156   rintstart bg(arrEnd);//OK no problem because size of 'arr' is greater or equal 2
6157   rintstart end2(arrBg);
6158   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret1=DataArrayInt::New();
6159   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret2=DataArrayInt::New();
6160   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret3=DataArrayInt::New();
6161   ret1->alloc(nbOfTuples,1);
6162   ret2->alloc(nbOfTuples,1);
6163   int *ret1Ptr=ret1->getPointer();
6164   int *ret2Ptr=ret2->getPointer();
6165   std::set<std::size_t> castsDetected;
6166   for(int i=0;i<nbOfTuples;i++)
6167     {
6168       rintstart res=std::find_if(bg,end2,std::bind2nd(std::less_equal<int>(), work[i]));
6169       std::size_t pos=std::distance(bg,res);
6170       std::size_t pos2=nbOfCast-pos;
6171       if(pos2<nbOfCast)
6172         {
6173           ret1Ptr[i]=(int)pos2;
6174           ret2Ptr[i]=work[i]-arrBg[pos2];
6175           castsDetected.insert(pos2);
6176         }
6177       else
6178         {
6179           std::ostringstream oss; oss << "DataArrayInt::splitByValueRange : At rank #" << i << " the value is " << work[i] << " should be in [0," << *bg << ") !";
6180           throw INTERP_KERNEL::Exception(oss.str().c_str());
6181         }
6182     }
6183   ret3->alloc((int)castsDetected.size(),1);
6184   std::copy(castsDetected.begin(),castsDetected.end(),ret3->getPointer());
6185   castArr=ret1.retn();
6186   rankInsideCast=ret2.retn();
6187   castsPresent=ret3.retn();
6188 }
6189
6190 /*!
6191  * Creates a one-dimensional DataArrayInt (\a res) whose contents are computed from 
6192  * values of \a this (\a a) and the given (\a indArr) arrays as follows:
6193  * \a res[ \a indArr[ \a a[ i ]]] = i. I.e. for each value in place i \a v = \a a[ i ],
6194  * new value in place \a indArr[ \a v ] is i.
6195  *  \param [in] indArrBg - the array holding indices within the result array to assign
6196  *         indices of values of \a this array pointing to values of \a indArrBg.
6197  *  \param [in] indArrEnd - specifies the end of the array \a indArrBg, so that
6198  *              the last value of \a indArrBg is \a indArrEnd[ -1 ].
6199  *  \return DataArrayInt * - the new instance of DataArrayInt.
6200  *          The caller is to delete this result array using decrRef() as it is no more
6201  *          needed.
6202  *  \throw If \a this->getNumberOfComponents() != 1.
6203  *  \throw If any value of \a this array is not a valid index for \a indArrBg array.
6204  *  \throw If any value of \a indArrBg is not a valid index for \a this array.
6205  */
6206 DataArrayInt *DataArrayInt::transformWithIndArrR(const int *indArrBg, const int *indArrEnd) const
6207 {
6208   checkAllocated();
6209   if(getNumberOfComponents()!=1)
6210     throw INTERP_KERNEL::Exception("Call transformWithIndArrR method on DataArrayInt with only one component, you can call 'rearrange' method before !");
6211   int nbElemsIn=(int)std::distance(indArrBg,indArrEnd);
6212   int nbOfTuples=getNumberOfTuples();
6213   const int *pt=getConstPointer();
6214   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6215   ret->alloc(nbOfTuples,1);
6216   ret->fillWithValue(-1);
6217   int *tmp=ret->getPointer();
6218   for(int i=0;i<nbOfTuples;i++,pt++)
6219     {
6220       if(*pt>=0 && *pt<nbElemsIn)
6221         {
6222           int pos=indArrBg[*pt];
6223           if(pos>=0 && pos<nbOfTuples)
6224             tmp[pos]=i;
6225           else
6226             {
6227               std::ostringstream oss; oss << "DataArrayInt::transformWithIndArrR : error on tuple #" << i << " value of new pos is " << pos << " ( indArrBg[" << *pt << "]) ! Should be in [0," << nbOfTuples << ") !";
6228               throw INTERP_KERNEL::Exception(oss.str().c_str());
6229             }
6230         }
6231       else
6232         {
6233           std::ostringstream oss; oss << "DataArrayInt::transformWithIndArrR : error on tuple #" << i << " value is " << *pt << " and indirectionnal array as a size equal to " << nbElemsIn << " !";
6234           throw INTERP_KERNEL::Exception(oss.str().c_str());
6235         }
6236     }
6237   return ret.retn();
6238 }
6239
6240 /*!
6241  * Creates a one-dimensional DataArrayInt of given length, whose contents are computed
6242  * from values of \a this array, which is supposed to contain a renumbering map in 
6243  * "Old to New" mode. The result array contains a renumbering map in "New to Old" mode.
6244  * To know how to use the renumbering maps see \ref MEDCouplingArrayRenumbering.
6245  *  \param [in] newNbOfElem - the number of tuples in the result array.
6246  *  \return DataArrayInt * - the new instance of DataArrayInt.
6247  *          The caller is to delete this result array using decrRef() as it is no more
6248  *          needed.
6249  * 
6250  *  \ref cpp_mcdataarrayint_invertarrayo2n2n2o "Here is a C++ example".<br>
6251  *  \ref py_mcdataarrayint_invertarrayo2n2n2o  "Here is a Python example".
6252  */
6253 DataArrayInt *DataArrayInt::invertArrayO2N2N2O(int newNbOfElem) const
6254 {
6255   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6256   ret->alloc(newNbOfElem,1);
6257   int nbOfOldNodes=getNumberOfTuples();
6258   const int *old2New=getConstPointer();
6259   int *pt=ret->getPointer();
6260   for(int i=0;i!=nbOfOldNodes;i++)
6261     {
6262       int newp(old2New[i]);
6263       if(newp!=-1)
6264         {
6265           if(newp>=0 && newp<newNbOfElem)
6266             pt[newp]=i;
6267           else
6268             {
6269               std::ostringstream oss; oss << "DataArrayInt::invertArrayO2N2N2O : At place #" << i << " the newplace is " << newp << " must be in [0," << newNbOfElem << ") !";
6270               throw INTERP_KERNEL::Exception(oss.str().c_str());
6271             }
6272         }
6273     }
6274   return ret.retn();
6275 }
6276
6277 /*!
6278  * This method is similar to DataArrayInt::invertArrayO2N2N2O except that 
6279  * 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]
6280  */
6281 DataArrayInt *DataArrayInt::invertArrayO2N2N2OBis(int newNbOfElem) const
6282 {
6283   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6284   ret->alloc(newNbOfElem,1);
6285   int nbOfOldNodes=getNumberOfTuples();
6286   const int *old2New=getConstPointer();
6287   int *pt=ret->getPointer();
6288   for(int i=nbOfOldNodes-1;i>=0;i--)
6289     {
6290       int newp(old2New[i]);
6291       if(newp!=-1)
6292         {
6293           if(newp>=0 && newp<newNbOfElem)
6294             pt[newp]=i;
6295           else
6296             {
6297               std::ostringstream oss; oss << "DataArrayInt::invertArrayO2N2N2OBis : At place #" << i << " the newplace is " << newp << " must be in [0," << newNbOfElem << ") !";
6298               throw INTERP_KERNEL::Exception(oss.str().c_str());
6299             }
6300         }
6301     }
6302   return ret.retn();
6303 }
6304
6305 /*!
6306  * Creates a one-dimensional DataArrayInt of given length, whose contents are computed
6307  * from values of \a this array, which is supposed to contain a renumbering map in 
6308  * "New to Old" mode. The result array contains a renumbering map in "Old to New" mode.
6309  * To know how to use the renumbering maps see \ref MEDCouplingArrayRenumbering.
6310  *  \param [in] newNbOfElem - the number of tuples in the result array.
6311  *  \return DataArrayInt * - the new instance of DataArrayInt.
6312  *          The caller is to delete this result array using decrRef() as it is no more
6313  *          needed.
6314  * 
6315  *  \ref cpp_mcdataarrayint_invertarrayn2o2o2n "Here is a C++ example".
6316  *
6317  *  \ref py_mcdataarrayint_invertarrayn2o2o2n "Here is a Python example".
6318  */
6319 DataArrayInt *DataArrayInt::invertArrayN2O2O2N(int oldNbOfElem) const
6320 {
6321   checkAllocated();
6322   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6323   ret->alloc(oldNbOfElem,1);
6324   const int *new2Old=getConstPointer();
6325   int *pt=ret->getPointer();
6326   std::fill(pt,pt+oldNbOfElem,-1);
6327   int nbOfNewElems=getNumberOfTuples();
6328   for(int i=0;i<nbOfNewElems;i++)
6329     {
6330       int v(new2Old[i]);
6331       if(v>=0 && v<oldNbOfElem)
6332          pt[v]=i;
6333       else
6334         {
6335           std::ostringstream oss; oss << "DataArrayInt::invertArrayN2O2O2N : in new id #" << i << " old value is " << v << " expected to be in [0," << oldNbOfElem << ") !";
6336           throw INTERP_KERNEL::Exception(oss.str().c_str());
6337         }
6338     }
6339   return ret.retn();
6340 }
6341
6342 /*!
6343  * Equivalent to DataArrayInt::isEqual except that if false the reason of
6344  * mismatch is given.
6345  * 
6346  * \param [in] other the instance to be compared with \a this
6347  * \param [out] reason In case of inequality returns the reason.
6348  * \sa DataArrayInt::isEqual
6349  */
6350 bool DataArrayInt::isEqualIfNotWhy(const DataArrayInt& other, std::string& reason) const
6351 {
6352   if(!areInfoEqualsIfNotWhy(other,reason))
6353     return false;
6354   return _mem.isEqual(other._mem,0,reason);
6355 }
6356
6357 /*!
6358  * Checks if \a this and another DataArrayInt are fully equal. For more info see
6359  * \ref MEDCouplingArrayBasicsCompare.
6360  *  \param [in] other - an instance of DataArrayInt to compare with \a this one.
6361  *  \return bool - \a true if the two arrays are equal, \a false else.
6362  */
6363 bool DataArrayInt::isEqual(const DataArrayInt& other) const
6364 {
6365   std::string tmp;
6366   return isEqualIfNotWhy(other,tmp);
6367 }
6368
6369 /*!
6370  * Checks if values of \a this and another DataArrayInt are equal. For more info see
6371  * \ref MEDCouplingArrayBasicsCompare.
6372  *  \param [in] other - an instance of DataArrayInt to compare with \a this one.
6373  *  \return bool - \a true if the values of two arrays are equal, \a false else.
6374  */
6375 bool DataArrayInt::isEqualWithoutConsideringStr(const DataArrayInt& other) const
6376 {
6377   std::string tmp;
6378   return _mem.isEqual(other._mem,0,tmp);
6379 }
6380
6381 /*!
6382  * Checks if values of \a this and another DataArrayInt are equal. Comparison is
6383  * performed on sorted value sequences.
6384  * For more info see\ref MEDCouplingArrayBasicsCompare.
6385  *  \param [in] other - an instance of DataArrayInt to compare with \a this one.
6386  *  \return bool - \a true if the sorted values of two arrays are equal, \a false else.
6387  */
6388 bool DataArrayInt::isEqualWithoutConsideringStrAndOrder(const DataArrayInt& other) const
6389 {
6390   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> a=deepCpy();
6391   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> b=other.deepCpy();
6392   a->sort();
6393   b->sort();
6394   return a->isEqualWithoutConsideringStr(*b);
6395 }
6396
6397 /*!
6398  * This method compares content of input vector \a v and \a this.
6399  * 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.
6400  * For performance reasons \a this is expected to be sorted ascendingly. If not an exception will be thrown.
6401  *
6402  * \param [in] v - the vector of 'flags' to be compared with \a this.
6403  *
6404  * \throw If \a this is not sorted ascendingly.
6405  * \throw If \a this has not exactly one component.
6406  * \throw If \a this is not allocated.
6407  */
6408 bool DataArrayInt::isFittingWith(const std::vector<bool>& v) const
6409 {
6410   checkAllocated();
6411   if(getNumberOfComponents()!=1)
6412     throw INTERP_KERNEL::Exception("DataArrayInt::isFittingWith : number of components of this should be equal to one !");
6413   int nbOfTuples(getNumberOfTuples());
6414   const int *w(begin()),*end2(end());
6415   int refVal=-std::numeric_limits<int>::max();
6416   int i=0;
6417   std::vector<bool>::const_iterator it(v.begin());
6418   for(;it!=v.end();it++,i++)
6419     {
6420       if(*it)
6421         {
6422           if(w!=end2)
6423             {
6424               if(*w++==i)
6425                 {
6426                   if(i>refVal)
6427                     refVal=i;
6428                   else
6429                     {
6430                       std::ostringstream oss; oss << "DataArrayInt::isFittingWith : At pos #" << std::distance(begin(),w-1) << " this is not sorted ascendingly !";
6431                       throw INTERP_KERNEL::Exception(oss.str().c_str());
6432                     }
6433                 }
6434               else
6435                 return false;
6436             }
6437           else
6438             return false;
6439         }
6440     }
6441   return w==end2;
6442 }
6443
6444 /*!
6445  * Sorts values of the array.
6446  *  \param [in] asc - \a true means ascending order, \a false, descending.
6447  *  \throw If \a this is not allocated.
6448  *  \throw If \a this->getNumberOfComponents() != 1.
6449  */
6450 void DataArrayInt::sort(bool asc)
6451 {
6452   checkAllocated();
6453   if(getNumberOfComponents()!=1)
6454     throw INTERP_KERNEL::Exception("DataArrayInt::sort : only supported with 'this' array with ONE component !");
6455   _mem.sort(asc);
6456   declareAsNew();
6457 }
6458
6459 /*!
6460  * Reverse the array values.
6461  *  \throw If \a this->getNumberOfComponents() < 1.
6462  *  \throw If \a this is not allocated.
6463  */
6464 void DataArrayInt::reverse()
6465 {
6466   checkAllocated();
6467   _mem.reverse(getNumberOfComponents());
6468   declareAsNew();
6469 }
6470
6471 /*!
6472  * Checks that \a this array is consistently **increasing** or **decreasing** in value.
6473  * If not an exception is thrown.
6474  *  \param [in] increasing - if \a true, the array values should be increasing.
6475  *  \throw If sequence of values is not strictly monotonic in agreement with \a
6476  *         increasing arg.
6477  *  \throw If \a this->getNumberOfComponents() != 1.
6478  *  \throw If \a this is not allocated.
6479  */
6480 void DataArrayInt::checkMonotonic(bool increasing) const
6481 {
6482   if(!isMonotonic(increasing))
6483     {
6484       if (increasing)
6485         throw INTERP_KERNEL::Exception("DataArrayInt::checkMonotonic : 'this' is not INCREASING monotonic !");
6486       else
6487         throw INTERP_KERNEL::Exception("DataArrayInt::checkMonotonic : 'this' is not DECREASING monotonic !");
6488     }
6489 }
6490
6491 /*!
6492  * Checks that \a this array is consistently **increasing** or **decreasing** in value.
6493  *  \param [in] increasing - if \a true, array values should be increasing.
6494  *  \return bool - \a true if values change in accordance with \a increasing arg.
6495  *  \throw If \a this->getNumberOfComponents() != 1.
6496  *  \throw If \a this is not allocated.
6497  */
6498 bool DataArrayInt::isMonotonic(bool increasing) const
6499 {
6500   checkAllocated();
6501   if(getNumberOfComponents()!=1)
6502     throw INTERP_KERNEL::Exception("DataArrayInt::isMonotonic : only supported with 'this' array with ONE component !");
6503   int nbOfElements=getNumberOfTuples();
6504   const int *ptr=getConstPointer();
6505   if(nbOfElements==0)
6506     return true;
6507   int ref=ptr[0];
6508   if(increasing)
6509     {
6510       for(int i=1;i<nbOfElements;i++)
6511         {
6512           if(ptr[i]>=ref)
6513             ref=ptr[i];
6514           else
6515             return false;
6516         }
6517     }
6518   else
6519     {
6520       for(int i=1;i<nbOfElements;i++)
6521         {
6522           if(ptr[i]<=ref)
6523             ref=ptr[i];
6524           else
6525             return false;
6526         }
6527     }
6528   return true;
6529 }
6530
6531 /*!
6532  * This method check that array consistently INCREASING or DECREASING in value.
6533  */
6534 bool DataArrayInt::isStrictlyMonotonic(bool increasing) const
6535 {
6536   checkAllocated();
6537   if(getNumberOfComponents()!=1)
6538     throw INTERP_KERNEL::Exception("DataArrayInt::isStrictlyMonotonic : only supported with 'this' array with ONE component !");
6539   int nbOfElements=getNumberOfTuples();
6540   const int *ptr=getConstPointer();
6541   if(nbOfElements==0)
6542     return true;
6543   int ref=ptr[0];
6544   if(increasing)
6545     {
6546       for(int i=1;i<nbOfElements;i++)
6547         {
6548           if(ptr[i]>ref)
6549             ref=ptr[i];
6550           else
6551             return false;
6552         }
6553     }
6554   else
6555     {
6556       for(int i=1;i<nbOfElements;i++)
6557         {
6558           if(ptr[i]<ref)
6559             ref=ptr[i];
6560           else
6561             return false;
6562         }
6563     }
6564   return true;
6565 }
6566
6567 /*!
6568  * This method check that array consistently INCREASING or DECREASING in value.
6569  */
6570 void DataArrayInt::checkStrictlyMonotonic(bool increasing) const
6571 {
6572   if(!isStrictlyMonotonic(increasing))
6573     {
6574       if (increasing)
6575         throw INTERP_KERNEL::Exception("DataArrayInt::checkStrictlyMonotonic : 'this' is not strictly INCREASING monotonic !");
6576       else
6577         throw INTERP_KERNEL::Exception("DataArrayInt::checkStrictlyMonotonic : 'this' is not strictly DECREASING monotonic !");
6578     }
6579 }
6580
6581 /*!
6582  * Creates a new one-dimensional DataArrayInt of the same size as \a this and a given
6583  * one-dimensional arrays that must be of the same length. The result array describes
6584  * correspondence between \a this and \a other arrays, so that 
6585  * <em> other.getIJ(i,0) == this->getIJ(ret->getIJ(i),0)</em>. If such a permutation is
6586  * not possible because some element in \a other is not in \a this, an exception is thrown.
6587  *  \param [in] other - an array to compute permutation to.
6588  *  \return DataArrayInt * - a new instance of DataArrayInt, which is a permutation array
6589  * from \a this to \a other. The caller is to delete this array using decrRef() as it is
6590  * no more needed.
6591  *  \throw If \a this->getNumberOfComponents() != 1.
6592  *  \throw If \a other->getNumberOfComponents() != 1.
6593  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples().
6594  *  \throw If \a other includes a value which is not in \a this array.
6595  * 
6596  *  \ref cpp_mcdataarrayint_buildpermutationarr "Here is a C++ example".
6597  *
6598  *  \ref py_mcdataarrayint_buildpermutationarr "Here is a Python example".
6599  */
6600 DataArrayInt *DataArrayInt::buildPermutationArr(const DataArrayInt& other) const
6601 {
6602   checkAllocated();
6603   if(getNumberOfComponents()!=1 || other.getNumberOfComponents()!=1)
6604     throw INTERP_KERNEL::Exception("DataArrayInt::buildPermutationArr : 'this' and 'other' have to have exactly ONE component !");
6605   int nbTuple=getNumberOfTuples();
6606   other.checkAllocated();
6607   if(nbTuple!=other.getNumberOfTuples())
6608     throw INTERP_KERNEL::Exception("DataArrayInt::buildPermutationArr : 'this' and 'other' must have the same number of tuple !");
6609   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6610   ret->alloc(nbTuple,1);
6611   ret->fillWithValue(-1);
6612   const int *pt=getConstPointer();
6613   std::map<int,int> mm;
6614   for(int i=0;i<nbTuple;i++)
6615     mm[pt[i]]=i;
6616   pt=other.getConstPointer();
6617   int *retToFill=ret->getPointer();
6618   for(int i=0;i<nbTuple;i++)
6619     {
6620       std::map<int,int>::const_iterator it=mm.find(pt[i]);
6621       if(it==mm.end())
6622         {
6623           std::ostringstream oss; oss << "DataArrayInt::buildPermutationArr : Arrays mismatch : element (" << pt[i] << ") in 'other' not findable in 'this' !";
6624           throw INTERP_KERNEL::Exception(oss.str().c_str());
6625         }
6626       retToFill[i]=(*it).second;
6627     }
6628   return ret.retn();
6629 }
6630
6631 /*!
6632  * Sets a C array to be used as raw data of \a this. The previously set info
6633  *  of components is retained and re-sized. 
6634  * For more info see \ref MEDCouplingArraySteps1.
6635  *  \param [in] array - the C array to be used as raw data of \a this.
6636  *  \param [in] ownership - if \a true, \a array will be deallocated at destruction of \a this.
6637  *  \param [in] type - specifies how to deallocate \a array. If \a type == ParaMEDMEM::CPP_DEALLOC,
6638  *                     \c delete [] \c array; will be called. If \a type == ParaMEDMEM::C_DEALLOC,
6639  *                     \c free(\c array ) will be called.
6640  *  \param [in] nbOfTuple - new number of tuples in \a this.
6641  *  \param [in] nbOfCompo - new number of components in \a this.
6642  */
6643 void DataArrayInt::useArray(const int *array, bool ownership,  DeallocType type, int nbOfTuple, int nbOfCompo)
6644 {
6645   _info_on_compo.resize(nbOfCompo);
6646   _mem.useArray(array,ownership,type,nbOfTuple*nbOfCompo);
6647   declareAsNew();
6648 }
6649
6650 void DataArrayInt::useExternalArrayWithRWAccess(const int *array, int nbOfTuple, int nbOfCompo)
6651 {
6652   _info_on_compo.resize(nbOfCompo);
6653   _mem.useExternalArrayWithRWAccess(array,nbOfTuple*nbOfCompo);
6654   declareAsNew();
6655 }
6656
6657 /*!
6658  * Returns a new DataArrayInt holding the same values as \a this array but differently
6659  * arranged in memory. If \a this array holds 2 components of 3 values:
6660  * \f$ x_0,x_1,x_2,y_0,y_1,y_2 \f$, then the result array holds these values arranged
6661  * as follows: \f$ x_0,y_0,x_1,y_1,x_2,y_2 \f$.
6662  *  \warning Do not confuse this method with transpose()!
6663  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
6664  *          is to delete using decrRef() as it is no more needed.
6665  *  \throw If \a this is not allocated.
6666  */
6667 DataArrayInt *DataArrayInt::fromNoInterlace() const
6668 {
6669   checkAllocated();
6670   if(_mem.isNull())
6671     throw INTERP_KERNEL::Exception("DataArrayInt::fromNoInterlace : Not defined array !");
6672   int *tab=_mem.fromNoInterlace(getNumberOfComponents());
6673   DataArrayInt *ret=DataArrayInt::New();
6674   ret->useArray(tab,true,C_DEALLOC,getNumberOfTuples(),getNumberOfComponents());
6675   return ret;
6676 }
6677
6678 /*!
6679  * Returns a new DataArrayInt holding the same values as \a this array but differently
6680  * arranged in memory. If \a this array holds 2 components of 3 values:
6681  * \f$ x_0,y_0,x_1,y_1,x_2,y_2 \f$, then the result array holds these values arranged
6682  * as follows: \f$ x_0,x_1,x_2,y_0,y_1,y_2 \f$.
6683  *  \warning Do not confuse this method with transpose()!
6684  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
6685  *          is to delete using decrRef() as it is no more needed.
6686  *  \throw If \a this is not allocated.
6687  */
6688 DataArrayInt *DataArrayInt::toNoInterlace() const
6689 {
6690   checkAllocated();
6691   if(_mem.isNull())
6692     throw INTERP_KERNEL::Exception("DataArrayInt::toNoInterlace : Not defined array !");
6693   int *tab=_mem.toNoInterlace(getNumberOfComponents());
6694   DataArrayInt *ret=DataArrayInt::New();
6695   ret->useArray(tab,true,C_DEALLOC,getNumberOfTuples(),getNumberOfComponents());
6696   return ret;
6697 }
6698
6699 /*!
6700  * Permutes values of \a this array as required by \a old2New array. The values are
6701  * permuted so that \c new[ \a old2New[ i ]] = \c old[ i ]. Number of tuples remains
6702  * the same as in \this one.
6703  * If a permutation reduction is needed, substr() or selectByTupleId() should be used.
6704  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
6705  *  \param [in] old2New - C array of length equal to \a this->getNumberOfTuples()
6706  *     giving a new position for i-th old value.
6707  */
6708 void DataArrayInt::renumberInPlace(const int *old2New)
6709 {
6710   checkAllocated();
6711   int nbTuples=getNumberOfTuples();
6712   int nbOfCompo=getNumberOfComponents();
6713   int *tmp=new int[nbTuples*nbOfCompo];
6714   const int *iptr=getConstPointer();
6715   for(int i=0;i<nbTuples;i++)
6716     {
6717       int v=old2New[i];
6718       if(v>=0 && v<nbTuples)
6719         std::copy(iptr+nbOfCompo*i,iptr+nbOfCompo*(i+1),tmp+nbOfCompo*v);
6720       else
6721         {
6722           std::ostringstream oss; oss << "DataArrayInt::renumberInPlace : At place #" << i << " value is " << v << " ! Should be in [0," << nbTuples << ") !";
6723           throw INTERP_KERNEL::Exception(oss.str().c_str());
6724         }
6725     }
6726   std::copy(tmp,tmp+nbTuples*nbOfCompo,getPointer());
6727   delete [] tmp;
6728   declareAsNew();
6729 }
6730
6731 /*!
6732  * Permutes values of \a this array as required by \a new2Old array. The values are
6733  * permuted so that \c new[ i ] = \c old[ \a new2Old[ i ]]. Number of tuples remains
6734  * the same as in \this one.
6735  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
6736  *  \param [in] new2Old - C array of length equal to \a this->getNumberOfTuples()
6737  *     giving a previous position of i-th new value.
6738  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
6739  *          is to delete using decrRef() as it is no more needed.
6740  */
6741 void DataArrayInt::renumberInPlaceR(const int *new2Old)
6742 {
6743   checkAllocated();
6744   int nbTuples=getNumberOfTuples();
6745   int nbOfCompo=getNumberOfComponents();
6746   int *tmp=new int[nbTuples*nbOfCompo];
6747   const int *iptr=getConstPointer();
6748   for(int i=0;i<nbTuples;i++)
6749     {
6750       int v=new2Old[i];
6751       if(v>=0 && v<nbTuples)
6752         std::copy(iptr+nbOfCompo*v,iptr+nbOfCompo*(v+1),tmp+nbOfCompo*i);
6753       else
6754         {
6755           std::ostringstream oss; oss << "DataArrayInt::renumberInPlaceR : At place #" << i << " value is " << v << " ! Should be in [0," << nbTuples << ") !";
6756           throw INTERP_KERNEL::Exception(oss.str().c_str());
6757         }
6758     }
6759   std::copy(tmp,tmp+nbTuples*nbOfCompo,getPointer());
6760   delete [] tmp;
6761   declareAsNew();
6762 }
6763
6764 /*!
6765  * Returns a copy of \a this array with values permuted as required by \a old2New array.
6766  * The values are permuted so that  \c new[ \a old2New[ i ]] = \c old[ i ].
6767  * Number of tuples in the result array remains the same as in \this one.
6768  * If a permutation reduction is needed, renumberAndReduce() should be used.
6769  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
6770  *  \param [in] old2New - C array of length equal to \a this->getNumberOfTuples()
6771  *          giving a new position for i-th old value.
6772  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
6773  *          is to delete using decrRef() as it is no more needed.
6774  *  \throw If \a this is not allocated.
6775  */
6776 DataArrayInt *DataArrayInt::renumber(const int *old2New) const
6777 {
6778   checkAllocated();
6779   int nbTuples=getNumberOfTuples();
6780   int nbOfCompo=getNumberOfComponents();
6781   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6782   ret->alloc(nbTuples,nbOfCompo);
6783   ret->copyStringInfoFrom(*this);
6784   const int *iptr=getConstPointer();
6785   int *optr=ret->getPointer();
6786   for(int i=0;i<nbTuples;i++)
6787     std::copy(iptr+nbOfCompo*i,iptr+nbOfCompo*(i+1),optr+nbOfCompo*old2New[i]);
6788   ret->copyStringInfoFrom(*this);
6789   return ret.retn();
6790 }
6791
6792 /*!
6793  * Returns a copy of \a this array with values permuted as required by \a new2Old array.
6794  * The values are permuted so that  \c new[ i ] = \c old[ \a new2Old[ i ]]. Number of
6795  * tuples in the result array remains the same as in \this one.
6796  * If a permutation reduction is needed, substr() or selectByTupleId() should be used.
6797  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
6798  *  \param [in] new2Old - C array of length equal to \a this->getNumberOfTuples()
6799  *     giving a previous position of i-th new value.
6800  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
6801  *          is to delete using decrRef() as it is no more needed.
6802  */
6803 DataArrayInt *DataArrayInt::renumberR(const int *new2Old) const
6804 {
6805   checkAllocated();
6806   int nbTuples=getNumberOfTuples();
6807   int nbOfCompo=getNumberOfComponents();
6808   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6809   ret->alloc(nbTuples,nbOfCompo);
6810   ret->copyStringInfoFrom(*this);
6811   const int *iptr=getConstPointer();
6812   int *optr=ret->getPointer();
6813   for(int i=0;i<nbTuples;i++)
6814     std::copy(iptr+nbOfCompo*new2Old[i],iptr+nbOfCompo*(new2Old[i]+1),optr+nbOfCompo*i);
6815   ret->copyStringInfoFrom(*this);
6816   return ret.retn();
6817 }
6818
6819 /*!
6820  * Returns a shorten and permuted copy of \a this array. The new DataArrayInt is
6821  * of size \a newNbOfTuple and it's values are permuted as required by \a old2New array.
6822  * The values are permuted so that  \c new[ \a old2New[ i ]] = \c old[ i ] for all
6823  * \a old2New[ i ] >= 0. In other words every i-th tuple in \a this array, for which 
6824  * \a old2New[ i ] is negative, is missing from the result array.
6825  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
6826  *  \param [in] old2New - C array of length equal to \a this->getNumberOfTuples()
6827  *     giving a new position for i-th old tuple and giving negative position for
6828  *     for i-th old tuple that should be omitted.
6829  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
6830  *          is to delete using decrRef() as it is no more needed.
6831  */
6832 DataArrayInt *DataArrayInt::renumberAndReduce(const int *old2New, int newNbOfTuple) const
6833 {
6834   checkAllocated();
6835   int nbTuples=getNumberOfTuples();
6836   int nbOfCompo=getNumberOfComponents();
6837   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6838   ret->alloc(newNbOfTuple,nbOfCompo);
6839   const int *iptr=getConstPointer();
6840   int *optr=ret->getPointer();
6841   for(int i=0;i<nbTuples;i++)
6842     {
6843       int w=old2New[i];
6844       if(w>=0)
6845         std::copy(iptr+i*nbOfCompo,iptr+(i+1)*nbOfCompo,optr+w*nbOfCompo);
6846     }
6847   ret->copyStringInfoFrom(*this);
6848   return ret.retn();
6849 }
6850
6851 /*!
6852  * Returns a shorten and permuted copy of \a this array. The new DataArrayInt is
6853  * of size \a new2OldEnd - \a new2OldBg and it's values are permuted as required by
6854  * \a new2OldBg array.
6855  * The values are permuted so that  \c new[ i ] = \c old[ \a new2OldBg[ i ]].
6856  * This method is equivalent to renumberAndReduce() except that convention in input is
6857  * \c new2old and \b not \c old2new.
6858  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
6859  *  \param [in] new2OldBg - pointer to the beginning of a permutation array that gives a
6860  *              tuple index in \a this array to fill the i-th tuple in the new array.
6861  *  \param [in] new2OldEnd - specifies the end of the permutation array that starts at
6862  *              \a new2OldBg, so that pointer to a tuple index (\a pi) varies as this:
6863  *              \a new2OldBg <= \a pi < \a new2OldEnd.
6864  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
6865  *          is to delete using decrRef() as it is no more needed.
6866  */
6867 DataArrayInt *DataArrayInt::selectByTupleId(const int *new2OldBg, const int *new2OldEnd) const
6868 {
6869   checkAllocated();
6870   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6871   int nbComp=getNumberOfComponents();
6872   ret->alloc((int)std::distance(new2OldBg,new2OldEnd),nbComp);
6873   ret->copyStringInfoFrom(*this);
6874   int *pt=ret->getPointer();
6875   const int *srcPt=getConstPointer();
6876   int i=0;
6877   for(const int *w=new2OldBg;w!=new2OldEnd;w++,i++)
6878     std::copy(srcPt+(*w)*nbComp,srcPt+((*w)+1)*nbComp,pt+i*nbComp);
6879   ret->copyStringInfoFrom(*this);
6880   return ret.retn();
6881 }
6882
6883 /*!
6884  * Returns a shorten and permuted copy of \a this array. The new DataArrayInt is
6885  * of size \a new2OldEnd - \a new2OldBg and it's values are permuted as required by
6886  * \a new2OldBg array.
6887  * The values are permuted so that  \c new[ i ] = \c old[ \a new2OldBg[ i ]].
6888  * This method is equivalent to renumberAndReduce() except that convention in input is
6889  * \c new2old and \b not \c old2new.
6890  * This method is equivalent to selectByTupleId() except that it prevents coping data
6891  * from behind the end of \a this array.
6892  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
6893  *  \param [in] new2OldBg - pointer to the beginning of a permutation array that gives a
6894  *              tuple index in \a this array to fill the i-th tuple in the new array.
6895  *  \param [in] new2OldEnd - specifies the end of the permutation array that starts at
6896  *              \a new2OldBg, so that pointer to a tuple index (\a pi) varies as this:
6897  *              \a new2OldBg <= \a pi < \a new2OldEnd.
6898  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
6899  *          is to delete using decrRef() as it is no more needed.
6900  *  \throw If \a new2OldEnd - \a new2OldBg > \a this->getNumberOfTuples().
6901  */
6902 DataArrayInt *DataArrayInt::selectByTupleIdSafe(const int *new2OldBg, const int *new2OldEnd) const
6903 {
6904   checkAllocated();
6905   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6906   int nbComp=getNumberOfComponents();
6907   int oldNbOfTuples=getNumberOfTuples();
6908   ret->alloc((int)std::distance(new2OldBg,new2OldEnd),nbComp);
6909   ret->copyStringInfoFrom(*this);
6910   int *pt=ret->getPointer();
6911   const int *srcPt=getConstPointer();
6912   int i=0;
6913   for(const int *w=new2OldBg;w!=new2OldEnd;w++,i++)
6914     if(*w>=0 && *w<oldNbOfTuples)
6915       std::copy(srcPt+(*w)*nbComp,srcPt+((*w)+1)*nbComp,pt+i*nbComp);
6916     else
6917       throw INTERP_KERNEL::Exception("DataArrayInt::selectByTupleIdSafe : some ids has been detected to be out of [0,this->getNumberOfTuples) !");
6918   ret->copyStringInfoFrom(*this);
6919   return ret.retn();
6920 }
6921
6922 /*!
6923  * Returns a shorten copy of \a this array. The new DataArrayInt contains every
6924  * (\a bg + \c i * \a step)-th tuple of \a this array located before the \a end2-th
6925  * tuple. Indices of the selected tuples are the same as ones returned by the Python
6926  * command \c range( \a bg, \a end2, \a step ).
6927  * This method is equivalent to selectByTupleIdSafe() except that the input array is
6928  * not constructed explicitly.
6929  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
6930  *  \param [in] bg - index of the first tuple to copy from \a this array.
6931  *  \param [in] end2 - index of the tuple before which the tuples to copy are located.
6932  *  \param [in] step - index increment to get index of the next tuple to copy.
6933  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
6934  *          is to delete using decrRef() as it is no more needed.
6935  *  \sa DataArrayInt::substr.
6936  */
6937 DataArrayInt *DataArrayInt::selectByTupleId2(int bg, int end2, int step) const
6938 {
6939   checkAllocated();
6940   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6941   int nbComp=getNumberOfComponents();
6942   int newNbOfTuples=GetNumberOfItemGivenBESRelative(bg,end2,step,"DataArrayInt::selectByTupleId2 : ");
6943   ret->alloc(newNbOfTuples,nbComp);
6944   int *pt=ret->getPointer();
6945   const int *srcPt=getConstPointer()+bg*nbComp;
6946   for(int i=0;i<newNbOfTuples;i++,srcPt+=step*nbComp)
6947     std::copy(srcPt,srcPt+nbComp,pt+i*nbComp);
6948   ret->copyStringInfoFrom(*this);
6949   return ret.retn();
6950 }
6951
6952 /*!
6953  * Returns a shorten copy of \a this array. The new DataArrayInt contains ranges
6954  * of tuples specified by \a ranges parameter.
6955  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
6956  *  \param [in] ranges - std::vector of std::pair's each of which defines a range
6957  *              of tuples in [\c begin,\c end) format.
6958  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
6959  *          is to delete using decrRef() as it is no more needed.
6960  *  \throw If \a end < \a begin.
6961  *  \throw If \a end > \a this->getNumberOfTuples().
6962  *  \throw If \a this is not allocated.
6963  */
6964 DataArray *DataArrayInt::selectByTupleRanges(const std::vector<std::pair<int,int> >& ranges) const
6965 {
6966   checkAllocated();
6967   int nbOfComp=getNumberOfComponents();
6968   int nbOfTuplesThis=getNumberOfTuples();
6969   if(ranges.empty())
6970     {
6971       MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6972       ret->alloc(0,nbOfComp);
6973       ret->copyStringInfoFrom(*this);
6974       return ret.retn();
6975     }
6976   int ref=ranges.front().first;
6977   int nbOfTuples=0;
6978   bool isIncreasing=true;
6979   for(std::vector<std::pair<int,int> >::const_iterator it=ranges.begin();it!=ranges.end();it++)
6980     {
6981       if((*it).first<=(*it).second)
6982         {
6983           if((*it).first>=0 && (*it).second<=nbOfTuplesThis)
6984             {
6985               nbOfTuples+=(*it).second-(*it).first;
6986               if(isIncreasing)
6987                 isIncreasing=ref<=(*it).first;
6988               ref=(*it).second;
6989             }
6990           else
6991             {
6992               std::ostringstream oss; oss << "DataArrayInt::selectByTupleRanges : on range #" << std::distance(ranges.begin(),it);
6993               oss << " (" << (*it).first << "," << (*it).second << ") is greater than number of tuples of this :" << nbOfTuples << " !";
6994               throw INTERP_KERNEL::Exception(oss.str().c_str());
6995             }
6996         }
6997       else
6998         {
6999           std::ostringstream oss; oss << "DataArrayInt::selectByTupleRanges : on range #" << std::distance(ranges.begin(),it);
7000           oss << " (" << (*it).first << "," << (*it).second << ") end is before begin !";
7001           throw INTERP_KERNEL::Exception(oss.str().c_str());
7002         }
7003     }
7004   if(isIncreasing && nbOfTuplesThis==nbOfTuples)
7005     return deepCpy();
7006   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
7007   ret->alloc(nbOfTuples,nbOfComp);
7008   ret->copyStringInfoFrom(*this);
7009   const int *src=getConstPointer();
7010   int *work=ret->getPointer();
7011   for(std::vector<std::pair<int,int> >::const_iterator it=ranges.begin();it!=ranges.end();it++)
7012     work=std::copy(src+(*it).first*nbOfComp,src+(*it).second*nbOfComp,work);
7013   return ret.retn();
7014 }
7015
7016 /*!
7017  * Returns a new DataArrayInt containing a renumbering map in "Old to New" mode.
7018  * This map, if applied to \a this array, would make it sorted. For example, if
7019  * \a this array contents are [9,10,0,6,4,11,3,7] then the contents of the result array
7020  * are [5,6,0,3,2,7,1,4]; if this result array (\a res) is used as an argument in call
7021  * \a this->renumber(\a res) then the returned array contains [0,3,4,6,7,9,10,11].
7022  * This method is useful for renumbering (in MED file for example). For more info
7023  * on renumbering see \ref MEDCouplingArrayRenumbering.
7024  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
7025  *          array using decrRef() as it is no more needed.
7026  *  \throw If \a this is not allocated.
7027  *  \throw If \a this->getNumberOfComponents() != 1.
7028  *  \throw If there are equal values in \a this array.
7029  */
7030 DataArrayInt *DataArrayInt::checkAndPreparePermutation() const
7031 {
7032   checkAllocated();
7033   if(getNumberOfComponents()!=1)
7034     throw INTERP_KERNEL::Exception("DataArrayInt::checkAndPreparePermutation : number of components must == 1 !");
7035   int nbTuples=getNumberOfTuples();
7036   const int *pt=getConstPointer();
7037   int *pt2=CheckAndPreparePermutation(pt,pt+nbTuples);
7038   DataArrayInt *ret=DataArrayInt::New();
7039   ret->useArray(pt2,true,C_DEALLOC,nbTuples,1);
7040   return ret;
7041 }
7042
7043 /*!
7044  * 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
7045  * input array \a ids2.
7046  * \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.
7047  * 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
7048  * inversely.
7049  * In case of success (no throw) : \c ids1->renumber(ret)->isEqual(ids2) where \a ret is the return of this method.
7050  *
7051  * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
7052  *          array using decrRef() as it is no more needed.
7053  * \throw If either ids1 or ids2 is null not allocated or not with one components.
7054  * 
7055  */
7056 DataArrayInt *DataArrayInt::FindPermutationFromFirstToSecond(const DataArrayInt *ids1, const DataArrayInt *ids2)
7057 {
7058   if(!ids1 || !ids2)
7059     throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two input arrays must be not null !");
7060   if(!ids1->isAllocated() || !ids2->isAllocated())
7061     throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two input arrays must be allocated !");
7062   if(ids1->getNumberOfComponents()!=1 || ids2->getNumberOfComponents()!=1)
7063     throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two input arrays have exactly one component !");
7064   if(ids1->getNumberOfTuples()!=ids2->getNumberOfTuples())
7065     {
7066       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 !";
7067       throw INTERP_KERNEL::Exception(oss.str().c_str());
7068     }
7069   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> p1(ids1->deepCpy());
7070   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> p2(ids2->deepCpy());
7071   p1->sort(true); p2->sort(true);
7072   if(!p1->isEqualWithoutConsideringStr(*p2))
7073     throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two arrays are not lying on same ids ! Impossible to find a permutation between the 2 arrays !");
7074   p1=ids1->checkAndPreparePermutation();
7075   p2=ids2->checkAndPreparePermutation();
7076   p2=p2->invertArrayO2N2N2O(p2->getNumberOfTuples());
7077   p2=p2->selectByTupleIdSafe(p1->begin(),p1->end());
7078   return p2.retn();
7079 }
7080
7081 /*!
7082  * Returns two arrays describing a surjective mapping from \a this set of values (\a A)
7083  * onto a set of values of size \a targetNb (\a B). The surjective function is 
7084  * \a B[ \a A[ i ]] = i. That is to say that for each \a id in [0,\a targetNb), where \a
7085  * targetNb < \a this->getNumberOfTuples(), there exists at least one tupleId (\a tid) so
7086  * that <em> this->getIJ( tid, 0 ) == id</em>. <br>
7087  * The first of out arrays returns indices of elements of \a this array, grouped by their
7088  * place in the set \a B. The second out array is the index of the first one; it shows how
7089  * many elements of \a A are mapped into each element of \a B. <br>
7090  * For more info on
7091  * mapping and its usage in renumbering see \ref MEDCouplingArrayRenumbering. <br>
7092  * \b Example:
7093  * - \a this: [0,3,2,3,2,2,1,2]
7094  * - \a targetNb: 4
7095  * - \a arr:  [0,  6,  2,4,5,7,  1,3]
7096  * - \a arrI: [0,1,2,6,8]
7097  *
7098  * This result means: <br>
7099  * the element of \a B 0 encounters within \a A once (\a arrI[ 0+1 ] - \a arrI[ 0 ]) and
7100  * its index within \a A is 0 ( \a arr[ 0:1 ] == \a arr[ \a arrI[ 0 ] : \a arrI[ 0+1 ]]);<br>
7101  * the element of \a B 2 encounters within \a A 4 times (\a arrI[ 2+1 ] - \a arrI[ 2 ]) and
7102  * its indices within \a A are [2,4,5,7] ( \a arr[ 2:6 ] == \a arr[ \a arrI[ 2 ] : 
7103  * \a arrI[ 2+1 ]]); <br> etc.
7104  *  \param [in] targetNb - the size of the set \a B. \a targetNb must be equal or more
7105  *         than the maximal value of \a A.
7106  *  \param [out] arr - a new instance of DataArrayInt returning indices of
7107  *         elements of \a this, grouped by their place in the set \a B. The caller is to delete
7108  *         this array using decrRef() as it is no more needed.
7109  *  \param [out] arrI - a new instance of DataArrayInt returning size of groups of equal
7110  *         elements of \a this. The caller is to delete this array using decrRef() as it
7111  *         is no more needed.
7112  *  \throw If \a this is not allocated.
7113  *  \throw If \a this->getNumberOfComponents() != 1.
7114  *  \throw If any value in \a this is more or equal to \a targetNb.
7115  */
7116 void DataArrayInt::changeSurjectiveFormat(int targetNb, DataArrayInt *&arr, DataArrayInt *&arrI) const
7117 {
7118   checkAllocated();
7119   if(getNumberOfComponents()!=1)
7120     throw INTERP_KERNEL::Exception("DataArrayInt::changeSurjectiveFormat : number of components must == 1 !");
7121   int nbOfTuples=getNumberOfTuples();
7122   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New());
7123   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> retI(DataArrayInt::New());
7124   retI->alloc(targetNb+1,1);
7125   const int *input=getConstPointer();
7126   std::vector< std::vector<int> > tmp(targetNb);
7127   for(int i=0;i<nbOfTuples;i++)
7128     {
7129       int tmp2=input[i];
7130       if(tmp2>=0 && tmp2<targetNb)
7131         tmp[tmp2].push_back(i);
7132       else
7133         {
7134           std::ostringstream oss; oss << "DataArrayInt::changeSurjectiveFormat : At pos " << i << " presence of element " << tmp2 << " ! should be in [0," << targetNb << ") !";
7135           throw INTERP_KERNEL::Exception(oss.str().c_str());
7136         }
7137     }
7138   int *retIPtr=retI->getPointer();
7139   *retIPtr=0;
7140   for(std::vector< std::vector<int> >::const_iterator it1=tmp.begin();it1!=tmp.end();it1++,retIPtr++)
7141     retIPtr[1]=retIPtr[0]+(int)((*it1).size());
7142   if(nbOfTuples!=retI->getIJ(targetNb,0))
7143     throw INTERP_KERNEL::Exception("DataArrayInt::changeSurjectiveFormat : big problem should never happen !");
7144   ret->alloc(nbOfTuples,1);
7145   int *retPtr=ret->getPointer();
7146   for(std::vector< std::vector<int> >::const_iterator it1=tmp.begin();it1!=tmp.end();it1++)
7147     retPtr=std::copy((*it1).begin(),(*it1).end(),retPtr);
7148   arr=ret.retn();
7149   arrI=retI.retn();
7150 }
7151
7152
7153 /*!
7154  * Returns a new DataArrayInt containing a renumbering map in "Old to New" mode computed
7155  * from a zip representation of a surjective format (returned e.g. by
7156  * \ref ParaMEDMEM::DataArrayDouble::findCommonTuples() "DataArrayDouble::findCommonTuples()"
7157  * for example). The result array minimizes the permutation. <br>
7158  * For more info on renumbering see \ref MEDCouplingArrayRenumbering. <br>
7159  * \b Example: <br>
7160  * - \a nbOfOldTuples: 10 
7161  * - \a arr          : [0,3, 5,7,9]
7162  * - \a arrIBg       : [0,2,5]
7163  * - \a newNbOfTuples: 7
7164  * - result array    : [0,1,2,0,3,4,5,4,6,4]
7165  *
7166  *  \param [in] nbOfOldTuples - number of tuples in the initial array \a arr.
7167  *  \param [in] arr - the array of tuple indices grouped by \a arrIBg array.
7168  *  \param [in] arrIBg - the array dividing all indices stored in \a arr into groups of
7169  *         (indices of) equal values. Its every element (except the last one) points to
7170  *         the first element of a group of equal values.
7171  *  \param [in] arrIEnd - specifies the end of \a arrIBg, so that the last element of \a
7172  *          arrIBg is \a arrIEnd[ -1 ].
7173  *  \param [out] newNbOfTuples - number of tuples after surjection application.
7174  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
7175  *          array using decrRef() as it is no more needed.
7176  *  \throw If any value of \a arr breaks condition ( 0 <= \a arr[ i ] < \a nbOfOldTuples ).
7177  */
7178 DataArrayInt *DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2(int nbOfOldTuples, const int *arr, const int *arrIBg, const int *arrIEnd, int &newNbOfTuples)
7179 {
7180   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
7181   ret->alloc(nbOfOldTuples,1);
7182   int *pt=ret->getPointer();
7183   std::fill(pt,pt+nbOfOldTuples,-1);
7184   int nbOfGrps=((int)std::distance(arrIBg,arrIEnd))-1;
7185   const int *cIPtr=arrIBg;
7186   for(int i=0;i<nbOfGrps;i++)
7187     pt[arr[cIPtr[i]]]=-(i+2);
7188   int newNb=0;
7189   for(int iNode=0;iNode<nbOfOldTuples;iNode++)
7190     {
7191       if(pt[iNode]<0)
7192         {
7193           if(pt[iNode]==-1)
7194             pt[iNode]=newNb++;
7195           else
7196             {
7197               int grpId=-(pt[iNode]+2);
7198               for(int j=cIPtr[grpId];j<cIPtr[grpId+1];j++)
7199                 {
7200                   if(arr[j]>=0 && arr[j]<nbOfOldTuples)
7201                     pt[arr[j]]=newNb;
7202                   else
7203                     {
7204                       std::ostringstream oss; oss << "DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2 : With element #" << j << " value is " << arr[j] << " should be in [0," << nbOfOldTuples << ") !";
7205                       throw INTERP_KERNEL::Exception(oss.str().c_str());
7206                     }
7207                 }
7208               newNb++;
7209             }
7210         }
7211     }
7212   newNbOfTuples=newNb;
7213   return ret.retn();
7214 }
7215
7216 /*!
7217  * Returns a new DataArrayInt containing a renumbering map in "New to Old" mode,
7218  * which if applied to \a this array would make it sorted ascendingly.
7219  * For more info on renumbering see \ref MEDCouplingArrayRenumbering. <br>
7220  * \b Example: <br>
7221  * - \a this: [2,0,1,1,0,1,2,0,1,1,0,0]
7222  * - result: [10,0,5,6,1,7,11,2,8,9,3,4]
7223  * - after applying result to \a this: [0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2] 
7224  *
7225  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
7226  *          array using decrRef() as it is no more needed.
7227  *  \throw If \a this is not allocated.
7228  *  \throw If \a this->getNumberOfComponents() != 1.
7229  */
7230 DataArrayInt *DataArrayInt::buildPermArrPerLevel() const
7231 {
7232   checkAllocated();
7233   if(getNumberOfComponents()!=1)
7234     throw INTERP_KERNEL::Exception("DataArrayInt::buildPermArrPerLevel : number of components must == 1 !");
7235   int nbOfTuples=getNumberOfTuples();
7236   const int *pt=getConstPointer();
7237   std::map<int,int> m;
7238   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
7239   ret->alloc(nbOfTuples,1);
7240   int *opt=ret->getPointer();
7241   for(int i=0;i<nbOfTuples;i++,pt++,opt++)
7242     {
7243       int val=*pt;
7244       std::map<int,int>::iterator it=m.find(val);
7245       if(it!=m.end())
7246         {
7247           *opt=(*it).second;
7248           (*it).second++;
7249         }
7250       else
7251         {
7252           *opt=0;
7253           m.insert(std::pair<int,int>(val,1));
7254         }
7255     }
7256   int sum=0;
7257   for(std::map<int,int>::iterator it=m.begin();it!=m.end();it++)
7258     {
7259       int vt=(*it).second;
7260       (*it).second=sum;
7261       sum+=vt;
7262     }
7263   pt=getConstPointer();
7264   opt=ret->getPointer();
7265   for(int i=0;i<nbOfTuples;i++,pt++,opt++)
7266     *opt+=m[*pt];
7267   //
7268   return ret.retn();
7269 }
7270
7271 /*!
7272  * Checks if contents of \a this array are equal to that of an array filled with
7273  * iota(). This method is particularly useful for DataArrayInt instances that represent
7274  * a renumbering array to check the real need in renumbering. 
7275  *  \return bool - \a true if \a this array contents == \a range( \a this->getNumberOfTuples())
7276  *  \throw If \a this is not allocated.
7277  *  \throw If \a this->getNumberOfComponents() != 1.
7278  */
7279 bool DataArrayInt::isIdentity() const
7280 {
7281   checkAllocated();
7282   if(getNumberOfComponents()!=1)
7283     return false;
7284   int nbOfTuples=getNumberOfTuples();
7285   const int *pt=getConstPointer();
7286   for(int i=0;i<nbOfTuples;i++,pt++)
7287     if(*pt!=i)
7288       return false;
7289   return true;
7290 }
7291
7292 /*!
7293  * Checks if all values in \a this array are equal to \a val.
7294  *  \param [in] val - value to check equality of array values to.
7295  *  \return bool - \a true if all values are \a val.
7296  *  \throw If \a this is not allocated.
7297  *  \throw If \a this->getNumberOfComponents() != 1
7298  */
7299 bool DataArrayInt::isUniform(int val) const
7300 {
7301   checkAllocated();
7302   if(getNumberOfComponents()!=1)
7303     throw INTERP_KERNEL::Exception("DataArrayInt::isUniform : must be applied on DataArrayInt with only one component, you can call 'rearrange' method before !");
7304   int nbOfTuples=getNumberOfTuples();
7305   const int *w=getConstPointer();
7306   const int *end2=w+nbOfTuples;
7307   for(;w!=end2;w++)
7308     if(*w!=val)
7309       return false;
7310   return true;
7311 }
7312
7313 /*!
7314  * Creates a new DataArrayDouble and assigns all (textual and numerical) data of \a this
7315  * array to the new one.
7316  *  \return DataArrayDouble * - the new instance of DataArrayInt.
7317  */
7318 DataArrayDouble *DataArrayInt::convertToDblArr() const
7319 {
7320   checkAllocated();
7321   DataArrayDouble *ret=DataArrayDouble::New();
7322   ret->alloc(getNumberOfTuples(),getNumberOfComponents());
7323   std::size_t nbOfVals=getNbOfElems();
7324   const int *src=getConstPointer();
7325   double *dest=ret->getPointer();
7326   std::copy(src,src+nbOfVals,dest);
7327   ret->copyStringInfoFrom(*this);
7328   return ret;
7329 }
7330
7331 /*!
7332  * Returns a shorten copy of \a this array. The new DataArrayInt contains all
7333  * tuples starting from the \a tupleIdBg-th tuple and including all tuples located before
7334  * the \a tupleIdEnd-th one. This methods has a similar behavior as std::string::substr().
7335  * This method is a specialization of selectByTupleId2().
7336  *  \param [in] tupleIdBg - index of the first tuple to copy from \a this array.
7337  *  \param [in] tupleIdEnd - index of the tuple before which the tuples to copy are located.
7338  *          If \a tupleIdEnd == -1, all the tuples till the end of \a this array are copied.
7339  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
7340  *          is to delete using decrRef() as it is no more needed.
7341  *  \throw If \a tupleIdBg < 0.
7342  *  \throw If \a tupleIdBg > \a this->getNumberOfTuples().
7343     \throw If \a tupleIdEnd != -1 && \a tupleIdEnd < \a this->getNumberOfTuples().
7344  *  \sa DataArrayInt::selectByTupleId2
7345  */
7346 DataArrayInt *DataArrayInt::substr(int tupleIdBg, int tupleIdEnd) const
7347 {
7348   checkAllocated();
7349   int nbt=getNumberOfTuples();
7350   if(tupleIdBg<0)
7351     throw INTERP_KERNEL::Exception("DataArrayInt::substr : The tupleIdBg parameter must be greater than 0 !");
7352   if(tupleIdBg>nbt)
7353     throw INTERP_KERNEL::Exception("DataArrayInt::substr : The tupleIdBg parameter is greater than number of tuples !");
7354   int trueEnd=tupleIdEnd;
7355   if(tupleIdEnd!=-1)
7356     {
7357       if(tupleIdEnd>nbt)
7358         throw INTERP_KERNEL::Exception("DataArrayInt::substr : The tupleIdBg parameter is greater or equal than number of tuples !");
7359     }
7360   else
7361     trueEnd=nbt;
7362   int nbComp=getNumberOfComponents();
7363   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
7364   ret->alloc(trueEnd-tupleIdBg,nbComp);
7365   ret->copyStringInfoFrom(*this);
7366   std::copy(getConstPointer()+tupleIdBg*nbComp,getConstPointer()+trueEnd*nbComp,ret->getPointer());
7367   return ret.retn();
7368 }
7369
7370 /*!
7371  * Changes the number of components within \a this array so that its raw data **does
7372  * not** change, instead splitting this data into tuples changes.
7373  *  \warning This method erases all (name and unit) component info set before!
7374  *  \param [in] newNbOfComp - number of components for \a this array to have.
7375  *  \throw If \a this is not allocated
7376  *  \throw If getNbOfElems() % \a newNbOfCompo != 0.
7377  *  \throw If \a newNbOfCompo is lower than 1.
7378  *  \throw If the rearrange method would lead to a number of tuples higher than 2147483647 (maximal capacity of int32 !).
7379  *  \warning This method erases all (name and unit) component info set before!
7380  */
7381 void DataArrayInt::rearrange(int newNbOfCompo)
7382 {
7383   checkAllocated();
7384   if(newNbOfCompo<1)
7385     throw INTERP_KERNEL::Exception("DataArrayInt::rearrange : input newNbOfCompo must be > 0 !");
7386   std::size_t nbOfElems=getNbOfElems();
7387   if(nbOfElems%newNbOfCompo!=0)
7388     throw INTERP_KERNEL::Exception("DataArrayInt::rearrange : nbOfElems%newNbOfCompo!=0 !");
7389   if(nbOfElems/newNbOfCompo>(std::size_t)std::numeric_limits<int>::max())
7390     throw INTERP_KERNEL::Exception("DataArrayInt::rearrange : the rearrangement leads to too high number of tuples (> 2147483647) !");
7391   _info_on_compo.clear();
7392   _info_on_compo.resize(newNbOfCompo);
7393   declareAsNew();
7394 }
7395
7396 /*!
7397  * Changes the number of components within \a this array to be equal to its number
7398  * of tuples, and inversely its number of tuples to become equal to its number of 
7399  * components. So that its raw data **does not** change, instead splitting this
7400  * data into tuples changes.
7401  *  \warning This method erases all (name and unit) component info set before!
7402  *  \warning Do not confuse this method with fromNoInterlace() and toNoInterlace()!
7403  *  \throw If \a this is not allocated.
7404  *  \sa rearrange()
7405  */
7406 void DataArrayInt::transpose()
7407 {
7408   checkAllocated();
7409   int nbOfTuples=getNumberOfTuples();
7410   rearrange(nbOfTuples);
7411 }
7412
7413 /*!
7414  * Returns a shorten or extended copy of \a this array. If \a newNbOfComp is less
7415  * than \a this->getNumberOfComponents() then the result array is shorten as each tuple
7416  * is truncated to have \a newNbOfComp components, keeping first components. If \a
7417  * newNbOfComp is more than \a this->getNumberOfComponents() then the result array is
7418  * expanded as each tuple is populated with \a dftValue to have \a newNbOfComp
7419  * components.  
7420  *  \param [in] newNbOfComp - number of components for the new array to have.
7421  *  \param [in] dftValue - value assigned to new values added to the new array.
7422  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
7423  *          is to delete using decrRef() as it is no more needed.
7424  *  \throw If \a this is not allocated.
7425  */
7426 DataArrayInt *DataArrayInt::changeNbOfComponents(int newNbOfComp, int dftValue) const
7427 {
7428   checkAllocated();
7429   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
7430   ret->alloc(getNumberOfTuples(),newNbOfComp);
7431   const int *oldc=getConstPointer();
7432   int *nc=ret->getPointer();
7433   int nbOfTuples=getNumberOfTuples();
7434   int oldNbOfComp=getNumberOfComponents();
7435   int dim=std::min(oldNbOfComp,newNbOfComp);
7436   for(int i=0;i<nbOfTuples;i++)
7437     {
7438       int j=0;
7439       for(;j<dim;j++)
7440         nc[newNbOfComp*i+j]=oldc[i*oldNbOfComp+j];
7441       for(;j<newNbOfComp;j++)
7442         nc[newNbOfComp*i+j]=dftValue;
7443     }
7444   ret->setName(getName().c_str());
7445   for(int i=0;i<dim;i++)
7446     ret->setInfoOnComponent(i,getInfoOnComponent(i).c_str());
7447   ret->setName(getName().c_str());
7448   return ret.retn();
7449 }
7450
7451 /*!
7452  * Changes number of tuples in the array. If the new number of tuples is smaller
7453  * than the current number the array is truncated, otherwise the array is extended.
7454  *  \param [in] nbOfTuples - new number of tuples. 
7455  *  \throw If \a this is not allocated.
7456  *  \throw If \a nbOfTuples is negative.
7457  */
7458 void DataArrayInt::reAlloc(int nbOfTuples)
7459 {
7460   if(nbOfTuples<0)
7461     throw INTERP_KERNEL::Exception("DataArrayInt::reAlloc : input new number of tuples should be >=0 !");
7462   checkAllocated();
7463   _mem.reAlloc(getNumberOfComponents()*(std::size_t)nbOfTuples);
7464   declareAsNew();
7465 }
7466
7467
7468 /*!
7469  * Returns a copy of \a this array composed of selected components.
7470  * The new DataArrayInt has the same number of tuples but includes components
7471  * specified by \a compoIds parameter. So that getNbOfElems() of the result array
7472  * can be either less, same or more than \a this->getNbOfElems().
7473  *  \param [in] compoIds - sequence of zero based indices of components to include
7474  *              into the new array.
7475  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
7476  *          is to delete using decrRef() as it is no more needed.
7477  *  \throw If \a this is not allocated.
7478  *  \throw If a component index (\a i) is not valid: 
7479  *         \a i < 0 || \a i >= \a this->getNumberOfComponents().
7480  *
7481  *  \ref py_mcdataarrayint_keepselectedcomponents "Here is a Python example".
7482  */
7483 DataArray *DataArrayInt::keepSelectedComponents(const std::vector<int>& compoIds) const
7484 {
7485   checkAllocated();
7486   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New());
7487   int newNbOfCompo=(int)compoIds.size();
7488   int oldNbOfCompo=getNumberOfComponents();
7489   for(std::vector<int>::const_iterator it=compoIds.begin();it!=compoIds.end();it++)
7490     DataArray::CheckValueInRange(oldNbOfCompo,(*it),"keepSelectedComponents invalid requested component");
7491   int nbOfTuples=getNumberOfTuples();
7492   ret->alloc(nbOfTuples,newNbOfCompo);
7493   ret->copyPartOfStringInfoFrom(*this,compoIds);
7494   const int *oldc=getConstPointer();
7495   int *nc=ret->getPointer();
7496   for(int i=0;i<nbOfTuples;i++)
7497     for(int j=0;j<newNbOfCompo;j++,nc++)
7498       *nc=oldc[i*oldNbOfCompo+compoIds[j]];
7499   return ret.retn();
7500 }
7501
7502 /*!
7503  * Appends components of another array to components of \a this one, tuple by tuple.
7504  * So that the number of tuples of \a this array remains the same and the number of 
7505  * components increases.
7506  *  \param [in] other - the DataArrayInt to append to \a this one.
7507  *  \throw If \a this is not allocated.
7508  *  \throw If \a this and \a other arrays have different number of tuples.
7509  *
7510  *  \ref cpp_mcdataarrayint_meldwith "Here is a C++ example".
7511  *
7512  *  \ref py_mcdataarrayint_meldwith "Here is a Python example".
7513  */
7514 void DataArrayInt::meldWith(const DataArrayInt *other)
7515 {
7516   if(!other)
7517     throw INTERP_KERNEL::Exception("DataArrayInt::meldWith : DataArrayInt pointer in input is NULL !");
7518   checkAllocated();
7519   other->checkAllocated();
7520   int nbOfTuples=getNumberOfTuples();
7521   if(nbOfTuples!=other->getNumberOfTuples())
7522     throw INTERP_KERNEL::Exception("DataArrayInt::meldWith : mismatch of number of tuples !");
7523   int nbOfComp1=getNumberOfComponents();
7524   int nbOfComp2=other->getNumberOfComponents();
7525   int *newArr=(int *)malloc(nbOfTuples*(nbOfComp1+nbOfComp2)*sizeof(int));
7526   int *w=newArr;
7527   const int *inp1=getConstPointer();
7528   const int *inp2=other->getConstPointer();
7529   for(int i=0;i<nbOfTuples;i++,inp1+=nbOfComp1,inp2+=nbOfComp2)
7530     {
7531       w=std::copy(inp1,inp1+nbOfComp1,w);
7532       w=std::copy(inp2,inp2+nbOfComp2,w);
7533     }
7534   useArray(newArr,true,C_DEALLOC,nbOfTuples,nbOfComp1+nbOfComp2);
7535   std::vector<int> compIds(nbOfComp2);
7536   for(int i=0;i<nbOfComp2;i++)
7537     compIds[i]=nbOfComp1+i;
7538   copyPartOfStringInfoFrom2(compIds,*other);
7539 }
7540
7541 /*!
7542  * Copy all components in a specified order from another DataArrayInt.
7543  * The specified components become the first ones in \a this array.
7544  * Both numerical and textual data is copied. The number of tuples in \a this and
7545  * the other array can be different.
7546  *  \param [in] a - the array to copy data from.
7547  *  \param [in] compoIds - sequence of zero based indices of components, data of which is
7548  *              to be copied.
7549  *  \throw If \a a is NULL.
7550  *  \throw If \a compoIds.size() != \a a->getNumberOfComponents().
7551  *  \throw If \a compoIds[i] < 0 or \a compoIds[i] > \a this->getNumberOfComponents().
7552  *
7553  *  \ref py_mcdataarrayint_setselectedcomponents "Here is a Python example".
7554  */
7555 void DataArrayInt::setSelectedComponents(const DataArrayInt *a, const std::vector<int>& compoIds)
7556 {
7557   if(!a)
7558     throw INTERP_KERNEL::Exception("DataArrayInt::setSelectedComponents : input DataArrayInt is NULL !");
7559   checkAllocated();
7560   a->checkAllocated();
7561   copyPartOfStringInfoFrom2(compoIds,*a);
7562   std::size_t partOfCompoSz=compoIds.size();
7563   int nbOfCompo=getNumberOfComponents();
7564   int nbOfTuples=std::min(getNumberOfTuples(),a->getNumberOfTuples());
7565   const int *ac=a->getConstPointer();
7566   int *nc=getPointer();
7567   for(int i=0;i<nbOfTuples;i++)
7568     for(std::size_t j=0;j<partOfCompoSz;j++,ac++)
7569       nc[nbOfCompo*i+compoIds[j]]=*ac;
7570 }
7571
7572 /*!
7573  * Copy all values from another DataArrayInt into specified tuples and components
7574  * of \a this array. Textual data is not copied.
7575  * The tree parameters defining set of indices of tuples and components are similar to
7576  * the tree parameters of the Python function \c range(\c start,\c stop,\c step).
7577  *  \param [in] a - the array to copy values from.
7578  *  \param [in] bgTuples - index of the first tuple of \a this array to assign values to.
7579  *  \param [in] endTuples - index of the tuple before which the tuples to assign to
7580  *              are located.
7581  *  \param [in] stepTuples - index increment to get index of the next tuple to assign to.
7582  *  \param [in] bgComp - index of the first component of \a this array to assign values to.
7583  *  \param [in] endComp - index of the component before which the components to assign
7584  *              to are located.
7585  *  \param [in] stepComp - index increment to get index of the next component to assign to.
7586  *  \param [in] strictCompoCompare - if \a true (by default), then \a a->getNumberOfComponents() 
7587  *              must be equal to the number of columns to assign to, else an
7588  *              exception is thrown; if \a false, then it is only required that \a
7589  *              a->getNbOfElems() equals to number of values to assign to (this condition
7590  *              must be respected even if \a strictCompoCompare is \a true). The number of 
7591  *              values to assign to is given by following Python expression:
7592  *              \a nbTargetValues = 
7593  *              \c len(\c range(\a bgTuples,\a endTuples,\a stepTuples)) *
7594  *              \c len(\c range(\a bgComp,\a endComp,\a stepComp)).
7595  *  \throw If \a a is NULL.
7596  *  \throw If \a a is not allocated.
7597  *  \throw If \a this is not allocated.
7598  *  \throw If parameters specifying tuples and components to assign to do not give a
7599  *            non-empty range of increasing indices.
7600  *  \throw If \a a->getNbOfElems() != \a nbTargetValues.
7601  *  \throw If \a strictCompoCompare == \a true && \a a->getNumberOfComponents() !=
7602  *            \c len(\c range(\a bgComp,\a endComp,\a stepComp)).
7603  *
7604  *  \ref py_mcdataarrayint_setpartofvalues1 "Here is a Python example".
7605  */
7606 void DataArrayInt::setPartOfValues1(const DataArrayInt *a, int bgTuples, int endTuples, int stepTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare)
7607 {
7608   if(!a)
7609     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValues1 : DataArrayInt pointer in input is NULL !");
7610   const char msg[]="DataArrayInt::setPartOfValues1";
7611   checkAllocated();
7612   a->checkAllocated();
7613   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
7614   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
7615   int nbComp=getNumberOfComponents();
7616   int nbOfTuples=getNumberOfTuples();
7617   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
7618   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
7619   bool assignTech=true;
7620   if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
7621     {
7622       if(strictCompoCompare)
7623         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
7624     }
7625   else
7626     {
7627       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
7628       assignTech=false;
7629     }
7630   int *pt=getPointer()+bgTuples*nbComp+bgComp;
7631   const int *srcPt=a->getConstPointer();
7632   if(assignTech)
7633     {
7634       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
7635         for(int j=0;j<newNbOfComp;j++,srcPt++)
7636           pt[j*stepComp]=*srcPt;
7637     }
7638   else
7639     {
7640       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
7641         {
7642           const int *srcPt2=srcPt;
7643           for(int j=0;j<newNbOfComp;j++,srcPt2++)
7644             pt[j*stepComp]=*srcPt2;
7645         }
7646     }
7647 }
7648
7649 /*!
7650  * Assign a given value to values at specified tuples and components of \a this array.
7651  * The tree parameters defining set of indices of tuples and components are similar to
7652  * the tree parameters of the Python function \c range(\c start,\c stop,\c step)..
7653  *  \param [in] a - the value to assign.
7654  *  \param [in] bgTuples - index of the first tuple of \a this array to assign to.
7655  *  \param [in] endTuples - index of the tuple before which the tuples to assign to
7656  *              are located.
7657  *  \param [in] stepTuples - index increment to get index of the next tuple to assign to.
7658  *  \param [in] bgComp - index of the first component of \a this array to assign to.
7659  *  \param [in] endComp - index of the component before which the components to assign
7660  *              to are located.
7661  *  \param [in] stepComp - index increment to get index of the next component to assign to.
7662  *  \throw If \a this is not allocated.
7663  *  \throw If parameters specifying tuples and components to assign to, do not give a
7664  *            non-empty range of increasing indices or indices are out of a valid range
7665  *            for \this array.
7666  *
7667  *  \ref py_mcdataarrayint_setpartofvaluessimple1 "Here is a Python example".
7668  */
7669 void DataArrayInt::setPartOfValuesSimple1(int a, int bgTuples, int endTuples, int stepTuples, int bgComp, int endComp, int stepComp)
7670 {
7671   const char msg[]="DataArrayInt::setPartOfValuesSimple1";
7672   checkAllocated();
7673   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
7674   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
7675   int nbComp=getNumberOfComponents();
7676   int nbOfTuples=getNumberOfTuples();
7677   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
7678   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
7679   int *pt=getPointer()+bgTuples*nbComp+bgComp;
7680   for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
7681     for(int j=0;j<newNbOfComp;j++)
7682       pt[j*stepComp]=a;
7683 }
7684
7685
7686 /*!
7687  * Copy all values from another DataArrayInt (\a a) into specified tuples and 
7688  * components of \a this array. Textual data is not copied.
7689  * The tuples and components to assign to are defined by C arrays of indices.
7690  * There are two *modes of usage*:
7691  * - If \a a->getNbOfElems() equals to number of values to assign to, then every value
7692  *   of \a a is assigned to its own location within \a this array. 
7693  * - If \a a includes one tuple, then all values of \a a are assigned to the specified
7694  *   components of every specified tuple of \a this array. In this mode it is required
7695  *   that \a a->getNumberOfComponents() equals to the number of specified components.
7696  * 
7697  *  \param [in] a - the array to copy values from.
7698  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
7699  *              assign values of \a a to.
7700  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
7701  *              pointer to a tuple index <em>(pi)</em> varies as this: 
7702  *              \a bgTuples <= \a pi < \a endTuples.
7703  *  \param [in] bgComp - pointer to an array of component indices of \a this array to
7704  *              assign values of \a a to.
7705  *  \param [in] endComp - specifies the end of the array \a bgTuples, so that
7706  *              pointer to a component index <em>(pi)</em> varies as this: 
7707  *              \a bgComp <= \a pi < \a endComp.
7708  *  \param [in] strictCompoCompare - this parameter is checked only if the
7709  *               *mode of usage* is the first; if it is \a true (default), 
7710  *               then \a a->getNumberOfComponents() must be equal 
7711  *               to the number of specified columns, else this is not required.
7712  *  \throw If \a a is NULL.
7713  *  \throw If \a a is not allocated.
7714  *  \throw If \a this is not allocated.
7715  *  \throw If any index of tuple/component given by <em>bgTuples / bgComp</em> is
7716  *         out of a valid range for \a this array.
7717  *  \throw In the first *mode of usage*, if <em>strictCompoCompare == true </em> and
7718  *         if <em> a->getNumberOfComponents() != (endComp - bgComp) </em>.
7719  *  \throw In the second *mode of usage*, if \a a->getNumberOfTuples() != 1 or
7720  *         <em> a->getNumberOfComponents() != (endComp - bgComp)</em>.
7721  *
7722  *  \ref py_mcdataarrayint_setpartofvalues2 "Here is a Python example".
7723  */
7724 void DataArrayInt::setPartOfValues2(const DataArrayInt *a, const int *bgTuples, const int *endTuples, const int *bgComp, const int *endComp, bool strictCompoCompare)
7725 {
7726   if(!a)
7727     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValues2 : DataArrayInt pointer in input is NULL !");
7728   const char msg[]="DataArrayInt::setPartOfValues2";
7729   checkAllocated();
7730   a->checkAllocated();
7731   int nbComp=getNumberOfComponents();
7732   int nbOfTuples=getNumberOfTuples();
7733   for(const int *z=bgComp;z!=endComp;z++)
7734     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
7735   int newNbOfTuples=(int)std::distance(bgTuples,endTuples);
7736   int newNbOfComp=(int)std::distance(bgComp,endComp);
7737   bool assignTech=true;
7738   if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
7739     {
7740       if(strictCompoCompare)
7741         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
7742     }
7743   else
7744     {
7745       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
7746       assignTech=false;
7747     }
7748   int *pt=getPointer();
7749   const int *srcPt=a->getConstPointer();
7750   if(assignTech)
7751     {    
7752       for(const int *w=bgTuples;w!=endTuples;w++)
7753         {
7754           DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
7755           for(const int *z=bgComp;z!=endComp;z++,srcPt++)
7756             {    
7757               pt[(std::size_t)(*w)*nbComp+(*z)]=*srcPt;
7758             }
7759         }
7760     }
7761   else
7762     {
7763       for(const int *w=bgTuples;w!=endTuples;w++)
7764         {
7765           const int *srcPt2=srcPt;
7766           DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
7767           for(const int *z=bgComp;z!=endComp;z++,srcPt2++)
7768             {    
7769               pt[(std::size_t)(*w)*nbComp+(*z)]=*srcPt2;
7770             }
7771         }
7772     }
7773 }
7774
7775 /*!
7776  * Assign a given value to values at specified tuples and components of \a this array.
7777  * The tuples and components to assign to are defined by C arrays of indices.
7778  *  \param [in] a - the value to assign.
7779  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
7780  *              assign \a a to.
7781  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
7782  *              pointer to a tuple index (\a pi) varies as this: 
7783  *              \a bgTuples <= \a pi < \a endTuples.
7784  *  \param [in] bgComp - pointer to an array of component indices of \a this array to
7785  *              assign \a a to.
7786  *  \param [in] endComp - specifies the end of the array \a bgTuples, so that
7787  *              pointer to a component index (\a pi) varies as this: 
7788  *              \a bgComp <= \a pi < \a endComp.
7789  *  \throw If \a this is not allocated.
7790  *  \throw If any index of tuple/component given by <em>bgTuples / bgComp</em> is
7791  *         out of a valid range for \a this array.
7792  *
7793  *  \ref py_mcdataarrayint_setpartofvaluessimple2 "Here is a Python example".
7794  */
7795 void DataArrayInt::setPartOfValuesSimple2(int a, const int *bgTuples, const int *endTuples, const int *bgComp, const int *endComp)
7796 {
7797   checkAllocated();
7798   int nbComp=getNumberOfComponents();
7799   int nbOfTuples=getNumberOfTuples();
7800   for(const int *z=bgComp;z!=endComp;z++)
7801     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
7802   int *pt=getPointer();
7803   for(const int *w=bgTuples;w!=endTuples;w++)
7804     for(const int *z=bgComp;z!=endComp;z++)
7805       {
7806         DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
7807         pt[(std::size_t)(*w)*nbComp+(*z)]=a;
7808       }
7809 }
7810
7811 /*!
7812  * Copy all values from another DataArrayInt (\a a) into specified tuples and 
7813  * components of \a this array. Textual data is not copied.
7814  * The tuples to assign to are defined by a C array of indices.
7815  * The components to assign to are defined by three values similar to parameters of
7816  * the Python function \c range(\c start,\c stop,\c step).
7817  * There are two *modes of usage*:
7818  * - If \a a->getNbOfElems() equals to number of values to assign to, then every value
7819  *   of \a a is assigned to its own location within \a this array. 
7820  * - If \a a includes one tuple, then all values of \a a are assigned to the specified
7821  *   components of every specified tuple of \a this array. In this mode it is required
7822  *   that \a a->getNumberOfComponents() equals to the number of specified components.
7823  *
7824  *  \param [in] a - the array to copy values from.
7825  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
7826  *              assign values of \a a to.
7827  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
7828  *              pointer to a tuple index <em>(pi)</em> varies as this: 
7829  *              \a bgTuples <= \a pi < \a endTuples.
7830  *  \param [in] bgComp - index of the first component of \a this array to assign to.
7831  *  \param [in] endComp - index of the component before which the components to assign
7832  *              to are located.
7833  *  \param [in] stepComp - index increment to get index of the next component to assign to.
7834  *  \param [in] strictCompoCompare - this parameter is checked only in the first
7835  *               *mode of usage*; if \a strictCompoCompare is \a true (default), 
7836  *               then \a a->getNumberOfComponents() must be equal 
7837  *               to the number of specified columns, else this is not required.
7838  *  \throw If \a a is NULL.
7839  *  \throw If \a a is not allocated.
7840  *  \throw If \a this is not allocated.
7841  *  \throw If any index of tuple given by \a bgTuples is out of a valid range for 
7842  *         \a this array.
7843  *  \throw In the first *mode of usage*, if <em>strictCompoCompare == true </em> and
7844  *         if <em> a->getNumberOfComponents()</em> is unequal to the number of components
7845  *         defined by <em>(bgComp,endComp,stepComp)</em>.
7846  *  \throw In the second *mode of usage*, if \a a->getNumberOfTuples() != 1 or
7847  *         <em> a->getNumberOfComponents()</em> is unequal to the number of components
7848  *         defined by <em>(bgComp,endComp,stepComp)</em>.
7849  *  \throw If parameters specifying components to assign to, do not give a
7850  *            non-empty range of increasing indices or indices are out of a valid range
7851  *            for \this array.
7852  *
7853  *  \ref py_mcdataarrayint_setpartofvalues3 "Here is a Python example".
7854  */
7855 void DataArrayInt::setPartOfValues3(const DataArrayInt *a, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare)
7856 {
7857   if(!a)
7858     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValues3 : DataArrayInt pointer in input is NULL !");
7859   const char msg[]="DataArrayInt::setPartOfValues3";
7860   checkAllocated();
7861   a->checkAllocated();
7862   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
7863   int nbComp=getNumberOfComponents();
7864   int nbOfTuples=getNumberOfTuples();
7865   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
7866   int newNbOfTuples=(int)std::distance(bgTuples,endTuples);
7867   bool assignTech=true;
7868   if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
7869     {
7870       if(strictCompoCompare)
7871         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
7872     }
7873   else
7874     {
7875       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
7876       assignTech=false;
7877     }
7878   int *pt=getPointer()+bgComp;
7879   const int *srcPt=a->getConstPointer();
7880   if(assignTech)
7881     {
7882       for(const int *w=bgTuples;w!=endTuples;w++)
7883         for(int j=0;j<newNbOfComp;j++,srcPt++)
7884           {
7885             DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
7886             pt[(std::size_t)(*w)*nbComp+j*stepComp]=*srcPt;
7887           }
7888     }
7889   else
7890     {
7891       for(const int *w=bgTuples;w!=endTuples;w++)
7892         {
7893           const int *srcPt2=srcPt;
7894           for(int j=0;j<newNbOfComp;j++,srcPt2++)
7895             {
7896               DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
7897               pt[(std::size_t)(*w)*nbComp+j*stepComp]=*srcPt2;
7898             }
7899         }
7900     }
7901 }
7902
7903 /*!
7904  * Assign a given value to values at specified tuples and components of \a this array.
7905  * The tuples to assign to are defined by a C array of indices.
7906  * The components to assign to are defined by three values similar to parameters of
7907  * the Python function \c range(\c start,\c stop,\c step).
7908  *  \param [in] a - the value to assign.
7909  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
7910  *              assign \a a to.
7911  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
7912  *              pointer to a tuple index <em>(pi)</em> varies as this: 
7913  *              \a bgTuples <= \a pi < \a endTuples.
7914  *  \param [in] bgComp - index of the first component of \a this array to assign to.
7915  *  \param [in] endComp - index of the component before which the components to assign
7916  *              to are located.
7917  *  \param [in] stepComp - index increment to get index of the next component to assign to.
7918  *  \throw If \a this is not allocated.
7919  *  \throw If any index of tuple given by \a bgTuples is out of a valid range for 
7920  *         \a this array.
7921  *  \throw If parameters specifying components to assign to, do not give a
7922  *            non-empty range of increasing indices or indices are out of a valid range
7923  *            for \this array.
7924  *
7925  *  \ref py_mcdataarrayint_setpartofvaluessimple3 "Here is a Python example".
7926  */
7927 void DataArrayInt::setPartOfValuesSimple3(int a, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp)
7928 {
7929   const char msg[]="DataArrayInt::setPartOfValuesSimple3";
7930   checkAllocated();
7931   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
7932   int nbComp=getNumberOfComponents();
7933   int nbOfTuples=getNumberOfTuples();
7934   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
7935   int *pt=getPointer()+bgComp;
7936   for(const int *w=bgTuples;w!=endTuples;w++)
7937     for(int j=0;j<newNbOfComp;j++)
7938       {
7939         DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
7940         pt[(std::size_t)(*w)*nbComp+j*stepComp]=a;
7941       }
7942 }
7943
7944 void DataArrayInt::setPartOfValues4(const DataArrayInt *a, int bgTuples, int endTuples, int stepTuples, const int *bgComp, const int *endComp, bool strictCompoCompare)
7945 {
7946   if(!a)
7947     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValues4 : input DataArrayInt is NULL !");
7948   const char msg[]="DataArrayInt::setPartOfValues4";
7949   checkAllocated();
7950   a->checkAllocated();
7951   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
7952   int newNbOfComp=(int)std::distance(bgComp,endComp);
7953   int nbComp=getNumberOfComponents();
7954   for(const int *z=bgComp;z!=endComp;z++)
7955     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
7956   int nbOfTuples=getNumberOfTuples();
7957   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
7958   bool assignTech=true;
7959   if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
7960     {
7961       if(strictCompoCompare)
7962         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
7963     }
7964   else
7965     {
7966       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
7967       assignTech=false;
7968     }
7969   const int *srcPt=a->getConstPointer();
7970   int *pt=getPointer()+bgTuples*nbComp;
7971   if(assignTech)
7972     {
7973       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
7974         for(const int *z=bgComp;z!=endComp;z++,srcPt++)
7975           pt[*z]=*srcPt;
7976     }
7977   else
7978     {
7979       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
7980         {
7981           const int *srcPt2=srcPt;
7982           for(const int *z=bgComp;z!=endComp;z++,srcPt2++)
7983             pt[*z]=*srcPt2;
7984         }
7985     }
7986 }
7987
7988 void DataArrayInt::setPartOfValuesSimple4(int a, int bgTuples, int endTuples, int stepTuples, const int *bgComp, const int *endComp)
7989 {
7990   const char msg[]="DataArrayInt::setPartOfValuesSimple4";
7991   checkAllocated();
7992   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
7993   int nbComp=getNumberOfComponents();
7994   for(const int *z=bgComp;z!=endComp;z++)
7995     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
7996   int nbOfTuples=getNumberOfTuples();
7997   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
7998   int *pt=getPointer()+bgTuples*nbComp;
7999   for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
8000     for(const int *z=bgComp;z!=endComp;z++)
8001       pt[*z]=a;
8002 }
8003
8004 /*!
8005  * Copy some tuples from another DataArrayInt into specified tuples
8006  * of \a this array. Textual data is not copied. Both arrays must have equal number of
8007  * components.
8008  * Both the tuples to assign and the tuples to assign to are defined by a DataArrayInt.
8009  * All components of selected tuples are copied.
8010  *  \param [in] a - the array to copy values from.
8011  *  \param [in] tuplesSelec - the array specifying both source tuples of \a a and
8012  *              target tuples of \a this. \a tuplesSelec has two components, and the
8013  *              first component specifies index of the source tuple and the second
8014  *              one specifies index of the target tuple.
8015  *  \throw If \a this is not allocated.
8016  *  \throw If \a a is NULL.
8017  *  \throw If \a a is not allocated.
8018  *  \throw If \a tuplesSelec is NULL.
8019  *  \throw If \a tuplesSelec is not allocated.
8020  *  \throw If <em>this->getNumberOfComponents() != a->getNumberOfComponents()</em>.
8021  *  \throw If \a tuplesSelec->getNumberOfComponents() != 2.
8022  *  \throw If any tuple index given by \a tuplesSelec is out of a valid range for 
8023  *         the corresponding (\a this or \a a) array.
8024  */
8025 void DataArrayInt::setPartOfValuesAdv(const DataArrayInt *a, const DataArrayInt *tuplesSelec)
8026 {
8027   if(!a || !tuplesSelec)
8028     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValuesAdv : DataArrayInt pointer in input is NULL !");
8029   checkAllocated();
8030   a->checkAllocated();
8031   tuplesSelec->checkAllocated();
8032   int nbOfComp=getNumberOfComponents();
8033   if(nbOfComp!=a->getNumberOfComponents())
8034     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValuesAdv : This and a do not have the same number of components !");
8035   if(tuplesSelec->getNumberOfComponents()!=2)
8036     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValuesAdv : Expecting to have a tuple selector DataArrayInt instance with exactly 2 components !");
8037   int thisNt=getNumberOfTuples();
8038   int aNt=a->getNumberOfTuples();
8039   int *valsToSet=getPointer();
8040   const int *valsSrc=a->getConstPointer();
8041   for(const int *tuple=tuplesSelec->begin();tuple!=tuplesSelec->end();tuple+=2)
8042     {
8043       if(tuple[1]>=0 && tuple[1]<aNt)
8044         {
8045           if(tuple[0]>=0 && tuple[0]<thisNt)
8046             std::copy(valsSrc+nbOfComp*tuple[1],valsSrc+nbOfComp*(tuple[1]+1),valsToSet+nbOfComp*tuple[0]);
8047           else
8048             {
8049               std::ostringstream oss; oss << "DataArrayInt::setPartOfValuesAdv : Tuple #" << std::distance(tuplesSelec->begin(),tuple)/2;
8050               oss << " of 'tuplesSelec' request of tuple id #" << tuple[0] << " in 'this' ! It should be in [0," << thisNt << ") !";
8051               throw INTERP_KERNEL::Exception(oss.str().c_str());
8052             }
8053         }
8054       else
8055         {
8056           std::ostringstream oss; oss << "DataArrayInt::setPartOfValuesAdv : Tuple #" << std::distance(tuplesSelec->begin(),tuple)/2;
8057           oss << " of 'tuplesSelec' request of tuple id #" << tuple[1] << " in 'a' ! It should be in [0," << aNt << ") !";
8058           throw INTERP_KERNEL::Exception(oss.str().c_str());
8059         }
8060     }
8061 }
8062
8063 /*!
8064  * Copy some tuples from another DataArrayInt (\a aBase) into contiguous tuples
8065  * of \a this array. Textual data is not copied. Both arrays must have equal number of
8066  * components.
8067  * The tuples to assign to are defined by index of the first tuple, and
8068  * their number is defined by \a tuplesSelec->getNumberOfTuples().
8069  * The tuples to copy are defined by values of a DataArrayInt.
8070  * All components of selected tuples are copied.
8071  *  \param [in] tupleIdStart - index of the first tuple of \a this array to assign
8072  *              values to.
8073  *  \param [in] aBase - the array to copy values from.
8074  *  \param [in] tuplesSelec - the array specifying tuples of \a aBase to copy.
8075  *  \throw If \a this is not allocated.
8076  *  \throw If \a aBase is NULL.
8077  *  \throw If \a aBase is not allocated.
8078  *  \throw If \a tuplesSelec is NULL.
8079  *  \throw If \a tuplesSelec is not allocated.
8080  *  \throw If <em>this->getNumberOfComponents() != a->getNumberOfComponents()</em>.
8081  *  \throw If \a tuplesSelec->getNumberOfComponents() != 1.
8082  *  \throw If <em>tupleIdStart + tuplesSelec->getNumberOfTuples() > this->getNumberOfTuples().</em>
8083  *  \throw If any tuple index given by \a tuplesSelec is out of a valid range for 
8084  *         \a aBase array.
8085  */
8086 void DataArrayInt::setContigPartOfSelectedValues(int tupleIdStart, const DataArray *aBase, const DataArrayInt *tuplesSelec)
8087 {
8088   if(!aBase || !tuplesSelec)
8089     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues : input DataArray is NULL !");
8090   const DataArrayInt *a=dynamic_cast<const DataArrayInt *>(aBase);
8091   if(!a)
8092     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues : input DataArray aBase is not a DataArrayInt !");
8093   checkAllocated();
8094   a->checkAllocated();
8095   tuplesSelec->checkAllocated();
8096   int nbOfComp=getNumberOfComponents();
8097   if(nbOfComp!=a->getNumberOfComponents())
8098     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues : This and a do not have the same number of components !");
8099   if(tuplesSelec->getNumberOfComponents()!=1)
8100     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues : Expecting to have a tuple selector DataArrayInt instance with exactly 1 component !");
8101   int thisNt=getNumberOfTuples();
8102   int aNt=a->getNumberOfTuples();
8103   int nbOfTupleToWrite=tuplesSelec->getNumberOfTuples();
8104   int *valsToSet=getPointer()+tupleIdStart*nbOfComp;
8105   if(tupleIdStart+nbOfTupleToWrite>thisNt)
8106     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues : invalid number range of values to write !");
8107   const int *valsSrc=a->getConstPointer();
8108   for(const int *tuple=tuplesSelec->begin();tuple!=tuplesSelec->end();tuple++,valsToSet+=nbOfComp)
8109     {
8110       if(*tuple>=0 && *tuple<aNt)
8111         {
8112           std::copy(valsSrc+nbOfComp*(*tuple),valsSrc+nbOfComp*(*tuple+1),valsToSet);
8113         }
8114       else
8115         {
8116           std::ostringstream oss; oss << "DataArrayInt::setContigPartOfSelectedValues : Tuple #" << std::distance(tuplesSelec->begin(),tuple);
8117           oss << " of 'tuplesSelec' request of tuple id #" << *tuple << " in 'a' ! It should be in [0," << aNt << ") !";
8118           throw INTERP_KERNEL::Exception(oss.str().c_str());
8119         }
8120     }
8121 }
8122
8123 /*!
8124  * Copy some tuples from another DataArrayInt (\a aBase) into contiguous tuples
8125  * of \a this array. Textual data is not copied. Both arrays must have equal number of
8126  * components.
8127  * The tuples to copy are defined by three values similar to parameters of
8128  * the Python function \c range(\c start,\c stop,\c step).
8129  * The tuples to assign to are defined by index of the first tuple, and
8130  * their number is defined by number of tuples to copy.
8131  * All components of selected tuples are copied.
8132  *  \param [in] tupleIdStart - index of the first tuple of \a this array to assign
8133  *              values to.
8134  *  \param [in] aBase - the array to copy values from.
8135  *  \param [in] bg - index of the first tuple to copy of the array \a aBase.
8136  *  \param [in] end2 - index of the tuple of \a aBase before which the tuples to copy
8137  *              are located.
8138  *  \param [in] step - index increment to get index of the next tuple to copy.
8139  *  \throw If \a this is not allocated.
8140  *  \throw If \a aBase is NULL.
8141  *  \throw If \a aBase is not allocated.
8142  *  \throw If <em>this->getNumberOfComponents() != aBase->getNumberOfComponents()</em>.
8143  *  \throw If <em>tupleIdStart + len(range(bg,end2,step)) > this->getNumberOfTuples().</em>
8144  *  \throw If parameters specifying tuples to copy, do not give a
8145  *            non-empty range of increasing indices or indices are out of a valid range
8146  *            for the array \a aBase.
8147  */
8148 void DataArrayInt::setContigPartOfSelectedValues2(int tupleIdStart, const DataArray *aBase, int bg, int end2, int step)
8149 {
8150   if(!aBase)
8151     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues2 : input DataArray is NULL !");
8152   const DataArrayInt *a=dynamic_cast<const DataArrayInt *>(aBase);
8153   if(!a)
8154     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues2 : input DataArray aBase is not a DataArrayInt !");
8155   checkAllocated();
8156   a->checkAllocated();
8157   int nbOfComp=getNumberOfComponents();
8158   const char msg[]="DataArrayInt::setContigPartOfSelectedValues2";
8159   int nbOfTupleToWrite=DataArray::GetNumberOfItemGivenBES(bg,end2,step,msg);
8160   if(nbOfComp!=a->getNumberOfComponents())
8161     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues2 : This and a do not have the same number of components !");
8162   int thisNt=getNumberOfTuples();
8163   int aNt=a->getNumberOfTuples();
8164   int *valsToSet=getPointer()+tupleIdStart*nbOfComp;
8165   if(tupleIdStart+nbOfTupleToWrite>thisNt)
8166     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues2 : invalid number range of values to write !");
8167   if(end2>aNt)
8168     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues2 : invalid range of values to read !");
8169   const int *valsSrc=a->getConstPointer()+bg*nbOfComp;
8170   for(int i=0;i<nbOfTupleToWrite;i++,valsToSet+=nbOfComp,valsSrc+=step*nbOfComp)
8171     {
8172       std::copy(valsSrc,valsSrc+nbOfComp,valsToSet);
8173     }
8174 }
8175
8176 /*!
8177  * Returns a value located at specified tuple and component.
8178  * This method is equivalent to DataArrayInt::getIJ() except that validity of
8179  * parameters is checked. So this method is safe but expensive if used to go through
8180  * all values of \a this.
8181  *  \param [in] tupleId - index of tuple of interest.
8182  *  \param [in] compoId - index of component of interest.
8183  *  \return double - value located by \a tupleId and \a compoId.
8184  *  \throw If \a this is not allocated.
8185  *  \throw If condition <em>( 0 <= tupleId < this->getNumberOfTuples() )</em> is violated.
8186  *  \throw If condition <em>( 0 <= compoId < this->getNumberOfComponents() )</em> is violated.
8187  */
8188 int DataArrayInt::getIJSafe(int tupleId, int compoId) const
8189 {
8190   checkAllocated();
8191   if(tupleId<0 || tupleId>=getNumberOfTuples())
8192     {
8193       std::ostringstream oss; oss << "DataArrayInt::getIJSafe : request for tupleId " << tupleId << " should be in [0," << getNumberOfTuples() << ") !";
8194       throw INTERP_KERNEL::Exception(oss.str().c_str());
8195     }
8196   if(compoId<0 || compoId>=getNumberOfComponents())
8197     {
8198       std::ostringstream oss; oss << "DataArrayInt::getIJSafe : request for compoId " << compoId << " should be in [0," << getNumberOfComponents() << ") !";
8199       throw INTERP_KERNEL::Exception(oss.str().c_str());
8200     }
8201   return _mem[tupleId*_info_on_compo.size()+compoId];
8202 }
8203
8204 /*!
8205  * Returns the first value of \a this. 
8206  *  \return int - the last value of \a this array.
8207  *  \throw If \a this is not allocated.
8208  *  \throw If \a this->getNumberOfComponents() != 1.
8209  *  \throw If \a this->getNumberOfTuples() < 1.
8210  */
8211 int DataArrayInt::front() const
8212 {
8213   checkAllocated();
8214   if(getNumberOfComponents()!=1)
8215     throw INTERP_KERNEL::Exception("DataArrayInt::front : number of components not equal to one !");
8216   int nbOfTuples=getNumberOfTuples();
8217   if(nbOfTuples<1)
8218     throw INTERP_KERNEL::Exception("DataArrayInt::front : number of tuples must be >= 1 !");
8219   return *(getConstPointer());
8220 }
8221
8222 /*!
8223  * Returns the last value of \a this. 
8224  *  \return int - the last value of \a this array.
8225  *  \throw If \a this is not allocated.
8226  *  \throw If \a this->getNumberOfComponents() != 1.
8227  *  \throw If \a this->getNumberOfTuples() < 1.
8228  */
8229 int DataArrayInt::back() const
8230 {
8231   checkAllocated();
8232   if(getNumberOfComponents()!=1)
8233     throw INTERP_KERNEL::Exception("DataArrayInt::back : number of components not equal to one !");
8234   int nbOfTuples=getNumberOfTuples();
8235   if(nbOfTuples<1)
8236     throw INTERP_KERNEL::Exception("DataArrayInt::back : number of tuples must be >= 1 !");
8237   return *(getConstPointer()+nbOfTuples-1);
8238 }
8239
8240 /*!
8241  * Assign pointer to one array to a pointer to another appay. Reference counter of
8242  * \a arrayToSet is incremented / decremented.
8243  *  \param [in] newArray - the pointer to array to assign to \a arrayToSet.
8244  *  \param [in,out] arrayToSet - the pointer to array to assign to.
8245  */
8246 void DataArrayInt::SetArrayIn(DataArrayInt *newArray, DataArrayInt* &arrayToSet)
8247 {
8248   if(newArray!=arrayToSet)
8249     {
8250       if(arrayToSet)
8251         arrayToSet->decrRef();
8252       arrayToSet=newArray;
8253       if(arrayToSet)
8254         arrayToSet->incrRef();
8255     }
8256 }
8257
8258 DataArrayIntIterator *DataArrayInt::iterator()
8259 {
8260   return new DataArrayIntIterator(this);
8261 }
8262
8263 /*!
8264  * Creates a new DataArrayInt containing IDs (indices) of tuples holding value equal to a
8265  * given one.
8266  *  \param [in] val - the value to find within \a this.
8267  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
8268  *          array using decrRef() as it is no more needed.
8269  *  \throw If \a this is not allocated.
8270  *  \throw If \a this->getNumberOfComponents() != 1.
8271  */
8272 DataArrayInt *DataArrayInt::getIdsEqual(int val) const
8273 {
8274   checkAllocated();
8275   if(getNumberOfComponents()!=1)
8276     throw INTERP_KERNEL::Exception("DataArrayInt::getIdsEqual : the array must have only one component, you can call 'rearrange' method before !");
8277   const int *cptr=getConstPointer();
8278   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
8279   int nbOfTuples=getNumberOfTuples();
8280   for(int i=0;i<nbOfTuples;i++,cptr++)
8281     if(*cptr==val)
8282       ret->pushBackSilent(i);
8283   return ret.retn();
8284 }
8285
8286 /*!
8287  * Creates a new DataArrayInt containing IDs (indices) of tuples holding value \b not
8288  * equal to a given one. 
8289  *  \param [in] val - the value to ignore within \a this.
8290  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
8291  *          array using decrRef() as it is no more needed.
8292  *  \throw If \a this is not allocated.
8293  *  \throw If \a this->getNumberOfComponents() != 1.
8294  */
8295 DataArrayInt *DataArrayInt::getIdsNotEqual(int val) const
8296 {
8297   checkAllocated();
8298   if(getNumberOfComponents()!=1)
8299     throw INTERP_KERNEL::Exception("DataArrayInt::getIdsNotEqual : the array must have only one component, you can call 'rearrange' method before !");
8300   const int *cptr=getConstPointer();
8301   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
8302   int nbOfTuples=getNumberOfTuples();
8303   for(int i=0;i<nbOfTuples;i++,cptr++)
8304     if(*cptr!=val)
8305       ret->pushBackSilent(i);
8306   return ret.retn();
8307 }
8308
8309
8310 /*!
8311  * Assigns \a newValue to all elements holding \a oldValue within \a this
8312  * one-dimensional array.
8313  *  \param [in] oldValue - the value to replace.
8314  *  \param [in] newValue - the value to assign.
8315  *  \return int - number of replacements performed.
8316  *  \throw If \a this is not allocated.
8317  *  \throw If \a this->getNumberOfComponents() != 1.
8318  */
8319 int DataArrayInt::changeValue(int oldValue, int newValue)
8320 {
8321   checkAllocated();
8322   if(getNumberOfComponents()!=1)
8323     throw INTERP_KERNEL::Exception("DataArrayInt::changeValue : the array must have only one component, you can call 'rearrange' method before !");
8324   int *start=getPointer();
8325   int *end2=start+getNbOfElems();
8326   int ret=0;
8327   for(int *val=start;val!=end2;val++)
8328     {
8329       if(*val==oldValue)
8330         {
8331           *val=newValue;
8332           ret++;
8333         }
8334     }
8335   return ret;
8336 }
8337
8338 /*!
8339  * Creates a new DataArrayInt containing IDs (indices) of tuples holding value equal to
8340  * one of given values.
8341  *  \param [in] valsBg - an array of values to find within \a this array.
8342  *  \param [in] valsEnd - specifies the end of the array \a valsBg, so that
8343  *              the last value of \a valsBg is \a valsEnd[ -1 ].
8344  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
8345  *          array using decrRef() as it is no more needed.
8346  *  \throw If \a this->getNumberOfComponents() != 1.
8347  */
8348 DataArrayInt *DataArrayInt::getIdsEqualList(const int *valsBg, const int *valsEnd) const
8349 {
8350   if(getNumberOfComponents()!=1)
8351     throw INTERP_KERNEL::Exception("DataArrayInt::getIdsEqualList : the array must have only one component, you can call 'rearrange' method before !");
8352   std::set<int> vals2(valsBg,valsEnd);
8353   const int *cptr=getConstPointer();
8354   std::vector<int> res;
8355   int nbOfTuples=getNumberOfTuples();
8356   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
8357   for(int i=0;i<nbOfTuples;i++,cptr++)
8358     if(vals2.find(*cptr)!=vals2.end())
8359       ret->pushBackSilent(i);
8360   return ret.retn();
8361 }
8362
8363 /*!
8364  * Creates a new DataArrayInt containing IDs (indices) of tuples holding values \b not
8365  * equal to any of given values.
8366  *  \param [in] valsBg - an array of values to ignore within \a this array.
8367  *  \param [in] valsEnd - specifies the end of the array \a valsBg, so that
8368  *              the last value of \a valsBg is \a valsEnd[ -1 ].
8369  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
8370  *          array using decrRef() as it is no more needed.
8371  *  \throw If \a this->getNumberOfComponents() != 1.
8372  */
8373 DataArrayInt *DataArrayInt::getIdsNotEqualList(const int *valsBg, const int *valsEnd) const
8374 {
8375   if(getNumberOfComponents()!=1)
8376     throw INTERP_KERNEL::Exception("DataArrayInt::getIdsNotEqualList : the array must have only one component, you can call 'rearrange' method before !");
8377   std::set<int> vals2(valsBg,valsEnd);
8378   const int *cptr=getConstPointer();
8379   std::vector<int> res;
8380   int nbOfTuples=getNumberOfTuples();
8381   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
8382   for(int i=0;i<nbOfTuples;i++,cptr++)
8383     if(vals2.find(*cptr)==vals2.end())
8384       ret->pushBackSilent(i);
8385   return ret.retn();
8386 }
8387
8388 /*!
8389  * This method is an extension of DataArrayInt::locateValue method because this method works for DataArrayInt with
8390  * any number of components excepted 0 (an INTERP_KERNEL::Exception is thrown in this case).
8391  * This method searches in \b this is there is a tuple that matched the input parameter \b tupl.
8392  * If any the tuple id is returned. If not -1 is returned.
8393  * 
8394  * This method throws an INTERP_KERNEL::Exception if the number of components in \b this mismatches with the size of
8395  * the input vector. An INTERP_KERNEL::Exception is thrown too if \b this is not allocated.
8396  *
8397  * \return tuple id where \b tupl is. -1 if no such tuple exists in \b this.
8398  * \sa DataArrayInt::search, DataArrayInt::presenceOfTuple.
8399  */
8400 int DataArrayInt::locateTuple(const std::vector<int>& tupl) const
8401 {
8402   checkAllocated();
8403   int nbOfCompo=getNumberOfComponents();
8404   if(nbOfCompo==0)
8405     throw INTERP_KERNEL::Exception("DataArrayInt::locateTuple : 0 components in 'this' !");
8406   if(nbOfCompo!=(int)tupl.size())
8407     {
8408       std::ostringstream oss; oss << "DataArrayInt::locateTuple : 'this' contains " << nbOfCompo << " components and searching for a tuple of length " << tupl.size() << " !";
8409       throw INTERP_KERNEL::Exception(oss.str().c_str());
8410     }
8411   const int *cptr=getConstPointer();
8412   std::size_t nbOfVals=getNbOfElems();
8413   for(const int *work=cptr;work!=cptr+nbOfVals;)
8414     {
8415       work=std::search(work,cptr+nbOfVals,tupl.begin(),tupl.end());
8416       if(work!=cptr+nbOfVals)
8417         {
8418           if(std::distance(cptr,work)%nbOfCompo!=0)
8419             work++;
8420           else
8421             return std::distance(cptr,work)/nbOfCompo;
8422         }
8423     }
8424   return -1;
8425 }
8426
8427 /*!
8428  * This method searches the sequence specified in input parameter \b vals in \b this.
8429  * This works only for DataArrayInt having number of components equal to one (if not an INTERP_KERNEL::Exception will be thrown).
8430  * This method differs from DataArrayInt::locateTuple in that the position is internal raw data is not considered here contrary to DataArrayInt::locateTuple.
8431  * \sa DataArrayInt::locateTuple
8432  */
8433 int DataArrayInt::search(const std::vector<int>& vals) const
8434 {
8435   checkAllocated();
8436   int nbOfCompo=getNumberOfComponents();
8437   if(nbOfCompo!=1)
8438     throw INTERP_KERNEL::Exception("DataArrayInt::search : works only for DataArrayInt instance with one component !");
8439   const int *cptr=getConstPointer();
8440   std::size_t nbOfVals=getNbOfElems();
8441   const int *loc=std::search(cptr,cptr+nbOfVals,vals.begin(),vals.end());
8442   if(loc!=cptr+nbOfVals)
8443     return std::distance(cptr,loc);
8444   return -1;
8445 }
8446
8447 /*!
8448  * This method expects to be called when number of components of this is equal to one.
8449  * This method returns the tuple id, if it exists, of the first tuple equal to \b value.
8450  * If not any tuple contains \b value -1 is returned.
8451  * \sa DataArrayInt::presenceOfValue
8452  */
8453 int DataArrayInt::locateValue(int value) const
8454 {
8455   checkAllocated();
8456   if(getNumberOfComponents()!=1)
8457     throw INTERP_KERNEL::Exception("DataArrayInt::presenceOfValue : the array must have only one component, you can call 'rearrange' method before !");
8458   const int *cptr=getConstPointer();
8459   int nbOfTuples=getNumberOfTuples();
8460   const int *ret=std::find(cptr,cptr+nbOfTuples,value);
8461   if(ret!=cptr+nbOfTuples)
8462     return std::distance(cptr,ret);
8463   return -1;
8464 }
8465
8466 /*!
8467  * This method expects to be called when number of components of this is equal to one.
8468  * This method returns the tuple id, if it exists, of the first tuple so that the value is contained in \b vals.
8469  * If not any tuple contains one of the values contained in 'vals' false is returned.
8470  * \sa DataArrayInt::presenceOfValue
8471  */
8472 int DataArrayInt::locateValue(const std::vector<int>& vals) const
8473 {
8474   checkAllocated();
8475   if(getNumberOfComponents()!=1)
8476     throw INTERP_KERNEL::Exception("DataArrayInt::presenceOfValue : the array must have only one component, you can call 'rearrange' method before !");
8477   std::set<int> vals2(vals.begin(),vals.end());
8478   const int *cptr=getConstPointer();
8479   int nbOfTuples=getNumberOfTuples();
8480   for(const int *w=cptr;w!=cptr+nbOfTuples;w++)
8481     if(vals2.find(*w)!=vals2.end())
8482       return std::distance(cptr,w);
8483   return -1;
8484 }
8485
8486 /*!
8487  * This method returns the number of values in \a this that are equals to input parameter \a value.
8488  * This method only works for single component array.
8489  *
8490  * \return a value in [ 0, \c this->getNumberOfTuples() )
8491  *
8492  * \throw If \a this is not allocated
8493  *
8494  */
8495 int DataArrayInt::count(int value) const
8496 {
8497   int ret=0;
8498   checkAllocated();
8499   if(getNumberOfComponents()!=1)
8500     throw INTERP_KERNEL::Exception("DataArrayInt::count : must be applied on DataArrayInt with only one component, you can call 'rearrange' method before !");
8501   const int *vals=begin();
8502   int nbOfTuples=getNumberOfTuples();
8503   for(int i=0;i<nbOfTuples;i++,vals++)
8504     if(*vals==value)
8505       ret++;
8506   return ret;
8507 }
8508
8509 /*!
8510  * This method is an extension of DataArrayInt::presenceOfValue method because this method works for DataArrayInt with
8511  * any number of components excepted 0 (an INTERP_KERNEL::Exception is thrown in this case).
8512  * This method searches in \b this is there is a tuple that matched the input parameter \b tupl.
8513  * This method throws an INTERP_KERNEL::Exception if the number of components in \b this mismatches with the size of
8514  * the input vector. An INTERP_KERNEL::Exception is thrown too if \b this is not allocated.
8515  * \sa DataArrayInt::locateTuple
8516  */
8517 bool DataArrayInt::presenceOfTuple(const std::vector<int>& tupl) const
8518 {
8519   return locateTuple(tupl)!=-1;
8520 }
8521
8522
8523 /*!
8524  * Returns \a true if a given value is present within \a this one-dimensional array.
8525  *  \param [in] value - the value to find within \a this array.
8526  *  \return bool - \a true in case if \a value is present within \a this array.
8527  *  \throw If \a this is not allocated.
8528  *  \throw If \a this->getNumberOfComponents() != 1.
8529  *  \sa locateValue()
8530  */
8531 bool DataArrayInt::presenceOfValue(int value) const
8532 {
8533   return locateValue(value)!=-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 true if it exists a 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::locateValue
8541  */
8542 bool DataArrayInt::presenceOfValue(const std::vector<int>& vals) const
8543 {
8544   return locateValue(vals)!=-1;
8545 }
8546
8547 /*!
8548  * Accumulates values of each component of \a this array.
8549  *  \param [out] res - an array of length \a this->getNumberOfComponents(), allocated 
8550  *         by the caller, that is filled by this method with sum value for each
8551  *         component.
8552  *  \throw If \a this is not allocated.
8553  */
8554 void DataArrayInt::accumulate(int *res) const
8555 {
8556   checkAllocated();
8557   const int *ptr=getConstPointer();
8558   int nbTuple=getNumberOfTuples();
8559   int nbComps=getNumberOfComponents();
8560   std::fill(res,res+nbComps,0);
8561   for(int i=0;i<nbTuple;i++)
8562     std::transform(ptr+i*nbComps,ptr+(i+1)*nbComps,res,res,std::plus<int>());
8563 }
8564
8565 int DataArrayInt::accumulate(int compId) const
8566 {
8567   checkAllocated();
8568   const int *ptr=getConstPointer();
8569   int nbTuple=getNumberOfTuples();
8570   int nbComps=getNumberOfComponents();
8571   if(compId<0 || compId>=nbComps)
8572     throw INTERP_KERNEL::Exception("DataArrayInt::accumulate : Invalid compId specified : No such nb of components !");
8573   int ret=0;
8574   for(int i=0;i<nbTuple;i++)
8575     ret+=ptr[i*nbComps+compId];
8576   return ret;
8577 }
8578
8579 /*!
8580  * This method accumulate using addition tuples in \a this using input index array [ \a bgOfIndex, \a endOfIndex ).
8581  * The returned array will have same number of components than \a this and number of tuples equal to
8582  * \c std::distance(bgOfIndex,endOfIndex) \b minus \b one.
8583  *
8584  * The input index array is expected to be ascendingly sorted in which the all referenced ids should be in [0, \c this->getNumberOfTuples).
8585  *
8586  * \param [in] bgOfIndex - begin (included) of the input index array.
8587  * \param [in] endOfIndex - end (excluded) of the input index array.
8588  * \return DataArrayInt * - the new instance having the same number of components than \a this.
8589  * 
8590  * \throw If bgOfIndex or end is NULL.
8591  * \throw If input index array is not ascendingly sorted.
8592  * \throw If there is an id in [ \a bgOfIndex, \a endOfIndex ) not in [0, \c this->getNumberOfTuples).
8593  * \throw If std::distance(bgOfIndex,endOfIndex)==0.
8594  */
8595 DataArrayInt *DataArrayInt::accumulatePerChunck(const int *bgOfIndex, const int *endOfIndex) const
8596 {
8597   if(!bgOfIndex || !endOfIndex)
8598     throw INTERP_KERNEL::Exception("DataArrayInt::accumulatePerChunck : input pointer NULL !");
8599   checkAllocated();
8600   int nbCompo=getNumberOfComponents();
8601   int nbOfTuples=getNumberOfTuples();
8602   int sz=(int)std::distance(bgOfIndex,endOfIndex);
8603   if(sz<1)
8604     throw INTERP_KERNEL::Exception("DataArrayInt::accumulatePerChunck : invalid size of input index array !");
8605   sz--;
8606   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(sz,nbCompo);
8607   const int *w=bgOfIndex;
8608   if(*w<0 || *w>=nbOfTuples)
8609     throw INTERP_KERNEL::Exception("DataArrayInt::accumulatePerChunck : The first element of the input index not in [0,nbOfTuples) !");
8610   const int *srcPt=begin()+(*w)*nbCompo;
8611   int *tmp=ret->getPointer();
8612   for(int i=0;i<sz;i++,tmp+=nbCompo,w++)
8613     {
8614       std::fill(tmp,tmp+nbCompo,0);
8615       if(w[1]>=w[0])
8616         {
8617           for(int j=w[0];j<w[1];j++,srcPt+=nbCompo)
8618             {
8619               if(j>=0 && j<nbOfTuples)
8620                 std::transform(srcPt,srcPt+nbCompo,tmp,tmp,std::plus<int>());
8621               else
8622                 {
8623                   std::ostringstream oss; oss << "DataArrayInt::accumulatePerChunck : At rank #" << i << " the input index array points to id " << j << " should be in [0," << nbOfTuples << ") !";
8624                   throw INTERP_KERNEL::Exception(oss.str().c_str());
8625                 }
8626             }
8627         }
8628       else
8629         {
8630           std::ostringstream oss; oss << "DataArrayInt::accumulatePerChunck : At rank #" << i << " the input index array is not in ascendingly sorted.";
8631           throw INTERP_KERNEL::Exception(oss.str().c_str());
8632         }
8633     }
8634   ret->copyStringInfoFrom(*this);
8635   return ret.retn();
8636 }
8637
8638 /*!
8639  * Returns a new DataArrayInt by concatenating two given arrays, so that (1) the number
8640  * of tuples in the result array is <em> a1->getNumberOfTuples() + a2->getNumberOfTuples() -
8641  * offsetA2</em> and (2)
8642  * the number of component in the result array is same as that of each of given arrays.
8643  * First \a offsetA2 tuples of \a a2 are skipped and thus are missing from the result array.
8644  * Info on components is copied from the first of the given arrays. Number of components
8645  * in the given arrays must be the same.
8646  *  \param [in] a1 - an array to include in the result array.
8647  *  \param [in] a2 - another array to include in the result array.
8648  *  \param [in] offsetA2 - number of tuples of \a a2 to skip.
8649  *  \return DataArrayInt * - the new instance of DataArrayInt.
8650  *          The caller is to delete this result array using decrRef() as it is no more
8651  *          needed.
8652  *  \throw If either \a a1 or \a a2 is NULL.
8653  *  \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents().
8654  */
8655 DataArrayInt *DataArrayInt::Aggregate(const DataArrayInt *a1, const DataArrayInt *a2, int offsetA2)
8656 {
8657   if(!a1 || !a2)
8658     throw INTERP_KERNEL::Exception("DataArrayInt::Aggregate : input DataArrayInt instance is NULL !");
8659   int nbOfComp=a1->getNumberOfComponents();
8660   if(nbOfComp!=a2->getNumberOfComponents())
8661     throw INTERP_KERNEL::Exception("Nb of components mismatch for array Aggregation !");
8662   int nbOfTuple1=a1->getNumberOfTuples();
8663   int nbOfTuple2=a2->getNumberOfTuples();
8664   DataArrayInt *ret=DataArrayInt::New();
8665   ret->alloc(nbOfTuple1+nbOfTuple2-offsetA2,nbOfComp);
8666   int *pt=std::copy(a1->getConstPointer(),a1->getConstPointer()+nbOfTuple1*nbOfComp,ret->getPointer());
8667   std::copy(a2->getConstPointer()+offsetA2*nbOfComp,a2->getConstPointer()+nbOfTuple2*nbOfComp,pt);
8668   ret->copyStringInfoFrom(*a1);
8669   return ret;
8670 }
8671
8672 /*!
8673  * Returns a new DataArrayInt by concatenating all given arrays, so that (1) the number
8674  * of tuples in the result array is a sum of the number of tuples of given arrays and (2)
8675  * the number of component in the result array is same as that of each of given arrays.
8676  * Info on components is copied from the first of the given arrays. Number of components
8677  * in the given arrays must be  the same.
8678  *  \param [in] arr - a sequence of arrays to include in the result array.
8679  *  \return DataArrayInt * - the new instance of DataArrayInt.
8680  *          The caller is to delete this result array using decrRef() as it is no more
8681  *          needed.
8682  *  \throw If all arrays within \a arr are NULL.
8683  *  \throw If getNumberOfComponents() of arrays within \a arr.
8684  */
8685 DataArrayInt *DataArrayInt::Aggregate(const std::vector<const DataArrayInt *>& arr)
8686 {
8687   std::vector<const DataArrayInt *> a;
8688   for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
8689     if(*it4)
8690       a.push_back(*it4);
8691   if(a.empty())
8692     throw INTERP_KERNEL::Exception("DataArrayInt::Aggregate : input list must be NON EMPTY !");
8693   std::vector<const DataArrayInt *>::const_iterator it=a.begin();
8694   int nbOfComp=(*it)->getNumberOfComponents();
8695   int nbt=(*it++)->getNumberOfTuples();
8696   for(int i=1;it!=a.end();it++,i++)
8697     {
8698       if((*it)->getNumberOfComponents()!=nbOfComp)
8699         throw INTERP_KERNEL::Exception("DataArrayInt::Aggregate : Nb of components mismatch for array aggregation !");
8700       nbt+=(*it)->getNumberOfTuples();
8701     }
8702   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
8703   ret->alloc(nbt,nbOfComp);
8704   int *pt=ret->getPointer();
8705   for(it=a.begin();it!=a.end();it++)
8706     pt=std::copy((*it)->getConstPointer(),(*it)->getConstPointer()+(*it)->getNbOfElems(),pt);
8707   ret->copyStringInfoFrom(*(a[0]));
8708   return ret.retn();
8709 }
8710
8711 /*!
8712  * This method takes as input a list of DataArrayInt instances \a arrs that represent each a packed index arrays.
8713  * A packed index array is an allocated array with one component, and at least one tuple. The first element
8714  * of each array in \a arrs must be 0. Each array in \a arrs is expected to be increasingly monotonic.
8715  * 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.
8716  * 
8717  * \return DataArrayInt * - a new object to be managed by the caller.
8718  */
8719 DataArrayInt *DataArrayInt::AggregateIndexes(const std::vector<const DataArrayInt *>& arrs)
8720 {
8721   int retSz=1;
8722   for(std::vector<const DataArrayInt *>::const_iterator it4=arrs.begin();it4!=arrs.end();it4++)
8723     {
8724       if(*it4)
8725         {
8726           (*it4)->checkAllocated();
8727           if((*it4)->getNumberOfComponents()!=1)
8728             {
8729               std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a DataArrayInt instance with nb of compo != 1 at pos " << std::distance(arrs.begin(),it4) << " !";
8730               throw INTERP_KERNEL::Exception(oss.str().c_str());
8731             }
8732           int nbTupl=(*it4)->getNumberOfTuples();
8733           if(nbTupl<1)
8734             {
8735               std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a DataArrayInt instance with nb of tuples < 1 at pos " << std::distance(arrs.begin(),it4) << " !";
8736               throw INTERP_KERNEL::Exception(oss.str().c_str());
8737             }
8738           if((*it4)->front()!=0)
8739             {
8740               std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a DataArrayInt instance with front value != 0 at pos " << std::distance(arrs.begin(),it4) << " !";
8741               throw INTERP_KERNEL::Exception(oss.str().c_str());
8742             }
8743           retSz+=nbTupl-1;
8744         }
8745       else
8746         {
8747           std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a null instance at pos " << std::distance(arrs.begin(),it4) << " !";
8748           throw INTERP_KERNEL::Exception(oss.str().c_str());
8749         }
8750     }
8751   if(arrs.empty())
8752     throw INTERP_KERNEL::Exception("DataArrayInt::AggregateIndexes : input list must be NON EMPTY !");
8753   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
8754   ret->alloc(retSz,1);
8755   int *pt=ret->getPointer(); *pt++=0;
8756   for(std::vector<const DataArrayInt *>::const_iterator it=arrs.begin();it!=arrs.end();it++)
8757     pt=std::transform((*it)->begin()+1,(*it)->end(),pt,std::bind2nd(std::plus<int>(),pt[-1]));
8758   ret->copyStringInfoFrom(*(arrs[0]));
8759   return ret.retn();
8760 }
8761
8762 /*!
8763  * Returns the maximal value and its location within \a this one-dimensional array.
8764  *  \param [out] tupleId - index of the tuple holding the maximal value.
8765  *  \return int - the maximal value among all values of \a this array.
8766  *  \throw If \a this->getNumberOfComponents() != 1
8767  *  \throw If \a this->getNumberOfTuples() < 1
8768  */
8769 int DataArrayInt::getMaxValue(int& tupleId) const
8770 {
8771   checkAllocated();
8772   if(getNumberOfComponents()!=1)
8773     throw INTERP_KERNEL::Exception("DataArrayInt::getMaxValue : must be applied on DataArrayInt with only one component !");
8774   int nbOfTuples=getNumberOfTuples();
8775   if(nbOfTuples<=0)
8776     throw INTERP_KERNEL::Exception("DataArrayInt::getMaxValue : array exists but number of tuples must be > 0 !");
8777   const int *vals=getConstPointer();
8778   const int *loc=std::max_element(vals,vals+nbOfTuples);
8779   tupleId=(int)std::distance(vals,loc);
8780   return *loc;
8781 }
8782
8783 /*!
8784  * Returns the maximal value within \a this array that is allowed to have more than
8785  *  one component.
8786  *  \return int - the maximal value among all values of \a this array.
8787  *  \throw If \a this is not allocated.
8788  */
8789 int DataArrayInt::getMaxValueInArray() const
8790 {
8791   checkAllocated();
8792   const int *loc=std::max_element(begin(),end());
8793   return *loc;
8794 }
8795
8796 /*!
8797  * Returns the minimal value and its location within \a this one-dimensional array.
8798  *  \param [out] tupleId - index of the tuple holding the minimal value.
8799  *  \return int - the minimal value among all values of \a this array.
8800  *  \throw If \a this->getNumberOfComponents() != 1
8801  *  \throw If \a this->getNumberOfTuples() < 1
8802  */
8803 int DataArrayInt::getMinValue(int& tupleId) const
8804 {
8805   checkAllocated();
8806   if(getNumberOfComponents()!=1)
8807     throw INTERP_KERNEL::Exception("DataArrayInt::getMaxValue : must be applied on DataArrayInt with only one component !");
8808   int nbOfTuples=getNumberOfTuples();
8809   if(nbOfTuples<=0)
8810     throw INTERP_KERNEL::Exception("DataArrayInt::getMaxValue : array exists but number of tuples must be > 0 !");
8811   const int *vals=getConstPointer();
8812   const int *loc=std::min_element(vals,vals+nbOfTuples);
8813   tupleId=(int)std::distance(vals,loc);
8814   return *loc;
8815 }
8816
8817 /*!
8818  * Returns the minimal value within \a this array that is allowed to have more than
8819  *  one component.
8820  *  \return int - the minimal value among all values of \a this array.
8821  *  \throw If \a this is not allocated.
8822  */
8823 int DataArrayInt::getMinValueInArray() const
8824 {
8825   checkAllocated();
8826   const int *loc=std::min_element(begin(),end());
8827   return *loc;
8828 }
8829
8830 /*!
8831  * Converts every value of \a this array to its absolute value.
8832  *  \throw If \a this is not allocated.
8833  */
8834 void DataArrayInt::abs()
8835 {
8836   checkAllocated();
8837   int *ptr=getPointer();
8838   std::size_t nbOfElems=getNbOfElems();
8839   std::transform(ptr,ptr+nbOfElems,ptr,std::ptr_fun<int,int>(std::abs));
8840   declareAsNew();
8841 }
8842
8843 /*!
8844  * Apply a liner function to a given component of \a this array, so that
8845  * an array element <em>(x)</em> becomes \f$ a * x + b \f$.
8846  *  \param [in] a - the first coefficient of the function.
8847  *  \param [in] b - the second coefficient of the function.
8848  *  \param [in] compoId - the index of component to modify.
8849  *  \throw If \a this is not allocated.
8850  */
8851 void DataArrayInt::applyLin(int a, int b, int compoId)
8852 {
8853   checkAllocated();
8854   int *ptr=getPointer()+compoId;
8855   int nbOfComp=getNumberOfComponents();
8856   int nbOfTuple=getNumberOfTuples();
8857   for(int i=0;i<nbOfTuple;i++,ptr+=nbOfComp)
8858     *ptr=a*(*ptr)+b;
8859   declareAsNew();
8860 }
8861
8862 /*!
8863  * Apply a liner function to all elements of \a this array, so that
8864  * an element _x_ becomes \f$ a * x + b \f$.
8865  *  \param [in] a - the first coefficient of the function.
8866  *  \param [in] b - the second coefficient of the function.
8867  *  \throw If \a this is not allocated.
8868  */
8869 void DataArrayInt::applyLin(int a, int b)
8870 {
8871   checkAllocated();
8872   int *ptr=getPointer();
8873   std::size_t nbOfElems=getNbOfElems();
8874   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
8875     *ptr=a*(*ptr)+b;
8876   declareAsNew();
8877 }
8878
8879 /*!
8880  * Returns a full copy of \a this array except that sign of all elements is reversed.
8881  *  \return DataArrayInt * - the new instance of DataArrayInt containing the
8882  *          same number of tuples and component as \a this array.
8883  *          The caller is to delete this result array using decrRef() as it is no more
8884  *          needed.
8885  *  \throw If \a this is not allocated.
8886  */
8887 DataArrayInt *DataArrayInt::negate() const
8888 {
8889   checkAllocated();
8890   DataArrayInt *newArr=DataArrayInt::New();
8891   int nbOfTuples=getNumberOfTuples();
8892   int nbOfComp=getNumberOfComponents();
8893   newArr->alloc(nbOfTuples,nbOfComp);
8894   const int *cptr=getConstPointer();
8895   std::transform(cptr,cptr+nbOfTuples*nbOfComp,newArr->getPointer(),std::negate<int>());
8896   newArr->copyStringInfoFrom(*this);
8897   return newArr;
8898 }
8899
8900 /*!
8901  * Modify all elements of \a this array, so that
8902  * an element _x_ becomes \f$ numerator / x \f$.
8903  *  \warning If an exception is thrown because of presence of 0 element in \a this 
8904  *           array, all elements processed before detection of the zero element remain
8905  *           modified.
8906  *  \param [in] numerator - the numerator used to modify array elements.
8907  *  \throw If \a this is not allocated.
8908  *  \throw If there is an element equal to 0 in \a this array.
8909  */
8910 void DataArrayInt::applyInv(int numerator)
8911 {
8912   checkAllocated();
8913   int *ptr=getPointer();
8914   std::size_t nbOfElems=getNbOfElems();
8915   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
8916     {
8917       if(*ptr!=0)
8918         {
8919           *ptr=numerator/(*ptr);
8920         }
8921       else
8922         {
8923           std::ostringstream oss; oss << "DataArrayInt::applyInv : presence of null value in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
8924           oss << " !";
8925           throw INTERP_KERNEL::Exception(oss.str().c_str());
8926         }
8927     }
8928   declareAsNew();
8929 }
8930
8931 /*!
8932  * Modify all elements of \a this array, so that
8933  * an element _x_ becomes \f$ x / val \f$.
8934  *  \param [in] val - the denominator used to modify array elements.
8935  *  \throw If \a this is not allocated.
8936  *  \throw If \a val == 0.
8937  */
8938 void DataArrayInt::applyDivideBy(int val)
8939 {
8940   if(val==0)
8941     throw INTERP_KERNEL::Exception("DataArrayInt::applyDivideBy : Trying to divide by 0 !");
8942   checkAllocated();
8943   int *ptr=getPointer();
8944   std::size_t nbOfElems=getNbOfElems();
8945   std::transform(ptr,ptr+nbOfElems,ptr,std::bind2nd(std::divides<int>(),val));
8946   declareAsNew();
8947 }
8948
8949 /*!
8950  * Modify all elements of \a this array, so that
8951  * an element _x_ becomes  <em> x % val </em>.
8952  *  \param [in] val - the divisor used to modify array elements.
8953  *  \throw If \a this is not allocated.
8954  *  \throw If \a val <= 0.
8955  */
8956 void DataArrayInt::applyModulus(int val)
8957 {
8958   if(val<=0)
8959     throw INTERP_KERNEL::Exception("DataArrayInt::applyDivideBy : Trying to operate modulus on value <= 0 !");
8960   checkAllocated();
8961   int *ptr=getPointer();
8962   std::size_t nbOfElems=getNbOfElems();
8963   std::transform(ptr,ptr+nbOfElems,ptr,std::bind2nd(std::modulus<int>(),val));
8964   declareAsNew();
8965 }
8966
8967 /*!
8968  * This method works only on data array with one component.
8969  * This method returns a newly allocated array storing stored ascendantly tuple ids in \b this so that
8970  * this[*id] in [\b vmin,\b vmax)
8971  * 
8972  * \param [in] vmin begin of range. This value is included in range (included).
8973  * \param [in] vmax end of range. This value is \b not included in range (excluded).
8974  * \return a newly allocated data array that the caller should deal with.
8975  */
8976 DataArrayInt *DataArrayInt::getIdsInRange(int vmin, int vmax) const
8977 {
8978   checkAllocated();
8979   if(getNumberOfComponents()!=1)
8980     throw INTERP_KERNEL::Exception("DataArrayInt::getIdsInRange : this must have exactly one component !");
8981   const int *cptr=getConstPointer();
8982   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(0,1);
8983   int nbOfTuples=getNumberOfTuples();
8984   for(int i=0;i<nbOfTuples;i++,cptr++)
8985     if(*cptr>=vmin && *cptr<vmax)
8986       ret->pushBackSilent(i);
8987   return ret.retn();
8988 }
8989
8990 /*!
8991  * This method works only on data array with one component.
8992  * 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.
8993  * 
8994  * \param [in] vmin begin of range. This value is included in range (included).
8995  * \param [in] vmax end of range. This value is \b not included in range (excluded).
8996  * \return if all ids in \a this are so that (*this)[i]==i for all i in [ 0, \c this->getNumberOfTuples() ).
8997  */
8998 bool DataArrayInt::checkAllIdsInRange(int vmin, int vmax) const
8999 {
9000   checkAllocated();
9001   if(getNumberOfComponents()!=1)
9002     throw INTERP_KERNEL::Exception("DataArrayInt::checkAllIdsInRange : this must have exactly one component !");
9003   int nbOfTuples=getNumberOfTuples();
9004   bool ret=true;
9005   const int *cptr=getConstPointer();
9006   for(int i=0;i<nbOfTuples;i++,cptr++)
9007     {
9008       if(*cptr>=vmin && *cptr<vmax)
9009         { ret=ret && *cptr==i; }
9010       else
9011         {
9012           std::ostringstream oss; oss << "DataArrayInt::checkAllIdsInRange : tuple #" << i << " has value " << *cptr << " should be in [" << vmin << "," << vmax << ") !";
9013           throw INTERP_KERNEL::Exception(oss.str().c_str());
9014         }
9015     }
9016   return ret;
9017 }
9018
9019 /*!
9020  * Modify all elements of \a this array, so that
9021  * an element _x_ becomes <em> val % x </em>.
9022  *  \warning If an exception is thrown because of presence of an element <= 0 in \a this 
9023  *           array, all elements processed before detection of the zero element remain
9024  *           modified.
9025  *  \param [in] val - the divident used to modify array elements.
9026  *  \throw If \a this is not allocated.
9027  *  \throw If there is an element equal to or less than 0 in \a this array.
9028  */
9029 void DataArrayInt::applyRModulus(int val)
9030 {
9031   checkAllocated();
9032   int *ptr=getPointer();
9033   std::size_t nbOfElems=getNbOfElems();
9034   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
9035     {
9036       if(*ptr>0)
9037         {
9038           *ptr=val%(*ptr);
9039         }
9040       else
9041         {
9042           std::ostringstream oss; oss << "DataArrayInt::applyRModulus : presence of value <=0 in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
9043           oss << " !";
9044           throw INTERP_KERNEL::Exception(oss.str().c_str());
9045         }
9046     }
9047   declareAsNew();
9048 }
9049
9050 /*!
9051  * Modify all elements of \a this array, so that
9052  * an element _x_ becomes <em> val ^ x </em>.
9053  *  \param [in] val - the value used to apply pow on all array elements.
9054  *  \throw If \a this is not allocated.
9055  *  \throw If \a val < 0.
9056  */
9057 void DataArrayInt::applyPow(int val)
9058 {
9059   checkAllocated();
9060   if(val<0)
9061     throw INTERP_KERNEL::Exception("DataArrayInt::applyPow : input pow in < 0 !");
9062   int *ptr=getPointer();
9063   std::size_t nbOfElems=getNbOfElems();
9064   if(val==0)
9065     {
9066       std::fill(ptr,ptr+nbOfElems,1);
9067       return ;
9068     }
9069   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
9070     {
9071       int tmp=1;
9072       for(int j=0;j<val;j++)
9073         tmp*=*ptr;
9074       *ptr=tmp;
9075     }
9076   declareAsNew();
9077 }
9078
9079 /*!
9080  * Modify all elements of \a this array, so that
9081  * an element _x_ becomes \f$ val ^ x \f$.
9082  *  \param [in] val - the value used to apply pow on all array elements.
9083  *  \throw If \a this is not allocated.
9084  *  \throw If there is an element < 0 in \a this array.
9085  *  \warning If an exception is thrown because of presence of 0 element in \a this 
9086  *           array, all elements processed before detection of the zero element remain
9087  *           modified.
9088  */
9089 void DataArrayInt::applyRPow(int val)
9090 {
9091   checkAllocated();
9092   int *ptr=getPointer();
9093   std::size_t nbOfElems=getNbOfElems();
9094   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
9095     {
9096       if(*ptr>=0)
9097         {
9098           int tmp=1;
9099           for(int j=0;j<*ptr;j++)
9100             tmp*=val;
9101           *ptr=tmp;
9102         }
9103       else
9104         {
9105           std::ostringstream oss; oss << "DataArrayInt::applyRPow : presence of negative value in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
9106           oss << " !";
9107           throw INTERP_KERNEL::Exception(oss.str().c_str());
9108         }
9109     }
9110   declareAsNew();
9111 }
9112
9113 /*!
9114  * Returns a new DataArrayInt by aggregating two given arrays, so that (1) the number
9115  * of components in the result array is a sum of the number of components of given arrays
9116  * and (2) the number of tuples in the result array is same as that of each of given
9117  * arrays. In other words the i-th tuple of result array includes all components of
9118  * i-th tuples of all given arrays.
9119  * Number of tuples in the given arrays must be the same.
9120  *  \param [in] a1 - an array to include in the result array.
9121  *  \param [in] a2 - another array to include in the result array.
9122  *  \return DataArrayInt * - the new instance of DataArrayInt.
9123  *          The caller is to delete this result array using decrRef() as it is no more
9124  *          needed.
9125  *  \throw If both \a a1 and \a a2 are NULL.
9126  *  \throw If any given array is not allocated.
9127  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
9128  */
9129 DataArrayInt *DataArrayInt::Meld(const DataArrayInt *a1, const DataArrayInt *a2)
9130 {
9131   std::vector<const DataArrayInt *> arr(2);
9132   arr[0]=a1; arr[1]=a2;
9133   return Meld(arr);
9134 }
9135
9136 /*!
9137  * Returns a new DataArrayInt by aggregating all given arrays, so that (1) the number
9138  * of components in the result array is a sum of the number of components of given arrays
9139  * and (2) the number of tuples in the result array is same as that of each of given
9140  * arrays. In other words the i-th tuple of result array includes all components of
9141  * i-th tuples of all given arrays.
9142  * Number of tuples in the given arrays must be  the same.
9143  *  \param [in] arr - a sequence of arrays to include in the result array.
9144  *  \return DataArrayInt * - the new instance of DataArrayInt.
9145  *          The caller is to delete this result array using decrRef() as it is no more
9146  *          needed.
9147  *  \throw If all arrays within \a arr are NULL.
9148  *  \throw If any given array is not allocated.
9149  *  \throw If getNumberOfTuples() of arrays within \a arr is different.
9150  */
9151 DataArrayInt *DataArrayInt::Meld(const std::vector<const DataArrayInt *>& arr)
9152 {
9153   std::vector<const DataArrayInt *> a;
9154   for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
9155     if(*it4)
9156       a.push_back(*it4);
9157   if(a.empty())
9158     throw INTERP_KERNEL::Exception("DataArrayInt::Meld : array must be NON empty !");
9159   std::vector<const DataArrayInt *>::const_iterator it;
9160   for(it=a.begin();it!=a.end();it++)
9161     (*it)->checkAllocated();
9162   it=a.begin();
9163   int nbOfTuples=(*it)->getNumberOfTuples();
9164   std::vector<int> nbc(a.size());
9165   std::vector<const int *> pts(a.size());
9166   nbc[0]=(*it)->getNumberOfComponents();
9167   pts[0]=(*it++)->getConstPointer();
9168   for(int i=1;it!=a.end();it++,i++)
9169     {
9170       if(nbOfTuples!=(*it)->getNumberOfTuples())
9171         throw INTERP_KERNEL::Exception("DataArrayInt::meld : mismatch of number of tuples !");
9172       nbc[i]=(*it)->getNumberOfComponents();
9173       pts[i]=(*it)->getConstPointer();
9174     }
9175   int totalNbOfComp=std::accumulate(nbc.begin(),nbc.end(),0);
9176   DataArrayInt *ret=DataArrayInt::New();
9177   ret->alloc(nbOfTuples,totalNbOfComp);
9178   int *retPtr=ret->getPointer();
9179   for(int i=0;i<nbOfTuples;i++)
9180     for(int j=0;j<(int)a.size();j++)
9181       {
9182         retPtr=std::copy(pts[j],pts[j]+nbc[j],retPtr);
9183         pts[j]+=nbc[j];
9184       }
9185   int k=0;
9186   for(int i=0;i<(int)a.size();i++)
9187     for(int j=0;j<nbc[i];j++,k++)
9188       ret->setInfoOnComponent(k,a[i]->getInfoOnComponent(j).c_str());
9189   return ret;
9190 }
9191
9192 /*!
9193  * Returns a new DataArrayInt which is a minimal partition of elements of \a groups.
9194  * The i-th item of the result array is an ID of a set of elements belonging to a
9195  * unique set of groups, which the i-th element is a part of. This set of elements
9196  * belonging to a unique set of groups is called \a family, so the result array contains
9197  * IDs of families each element belongs to.
9198  *
9199  * \b Example: if we have two groups of elements: \a group1 [0,4] and \a group2 [ 0,1,2 ],
9200  * then there are 3 families:
9201  * - \a family1 (with ID 1) contains element [0] belonging to ( \a group1 + \a group2 ),
9202  * - \a family2 (with ID 2) contains elements [4] belonging to ( \a group1 ),
9203  * - \a family3 (with ID 3) contains element [1,2] belonging to ( \a group2 ), <br>
9204  * and the result array contains IDs of families [ 1,3,3,0,2 ]. <br> Note a family ID 0 which
9205  * stands for the element #3 which is in none of groups.
9206  *
9207  *  \param [in] groups - sequence of groups of element IDs.
9208  *  \param [in] newNb - total number of elements; it must be more than max ID of element
9209  *         in \a groups.
9210  *  \param [out] fidsOfGroups - IDs of families the elements of each group belong to.
9211  *  \return DataArrayInt * - a new instance of DataArrayInt containing IDs of families
9212  *         each element with ID from range [0, \a newNb ) belongs to. The caller is to
9213  *         delete this array using decrRef() as it is no more needed.
9214  *  \throw If any element ID in \a groups violates condition ( 0 <= ID < \a newNb ).
9215  */
9216 DataArrayInt *DataArrayInt::MakePartition(const std::vector<const DataArrayInt *>& groups, int newNb, std::vector< std::vector<int> >& fidsOfGroups)
9217 {
9218   std::vector<const DataArrayInt *> groups2;
9219   for(std::vector<const DataArrayInt *>::const_iterator it4=groups.begin();it4!=groups.end();it4++)
9220     if(*it4)
9221       groups2.push_back(*it4);
9222   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
9223   ret->alloc(newNb,1);
9224   int *retPtr=ret->getPointer();
9225   std::fill(retPtr,retPtr+newNb,0);
9226   int fid=1;
9227   for(std::vector<const DataArrayInt *>::const_iterator iter=groups2.begin();iter!=groups2.end();iter++)
9228     {
9229       const int *ptr=(*iter)->getConstPointer();
9230       std::size_t nbOfElem=(*iter)->getNbOfElems();
9231       int sfid=fid;
9232       for(int j=0;j<sfid;j++)
9233         {
9234           bool found=false;
9235           for(std::size_t i=0;i<nbOfElem;i++)
9236             {
9237               if(ptr[i]>=0 && ptr[i]<newNb)
9238                 {
9239                   if(retPtr[ptr[i]]==j)
9240                     {
9241                       retPtr[ptr[i]]=fid;
9242                       found=true;
9243                     }
9244                 }
9245               else
9246                 {
9247                   std::ostringstream oss; oss << "DataArrayInt::MakePartition : In group \"" << (*iter)->getName() << "\" in tuple #" << i << " value = " << ptr[i] << " ! Should be in [0," << newNb;
9248                   oss << ") !";
9249                   throw INTERP_KERNEL::Exception(oss.str().c_str());
9250                 }
9251             }
9252           if(found)
9253             fid++;
9254         }
9255     }
9256   fidsOfGroups.clear();
9257   fidsOfGroups.resize(groups2.size());
9258   int grId=0;
9259   for(std::vector<const DataArrayInt *>::const_iterator iter=groups2.begin();iter!=groups2.end();iter++,grId++)
9260     {
9261       std::set<int> tmp;
9262       const int *ptr=(*iter)->getConstPointer();
9263       std::size_t nbOfElem=(*iter)->getNbOfElems();
9264       for(const int *p=ptr;p!=ptr+nbOfElem;p++)
9265         tmp.insert(retPtr[*p]);
9266       fidsOfGroups[grId].insert(fidsOfGroups[grId].end(),tmp.begin(),tmp.end());
9267     }
9268   return ret.retn();
9269 }
9270
9271 /*!
9272  * Returns a new DataArrayInt which contains all elements of given one-dimensional
9273  * arrays. The result array does not contain any duplicates and its values
9274  * are sorted in ascending order.
9275  *  \param [in] arr - sequence of DataArrayInt's to unite.
9276  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
9277  *         array using decrRef() as it is no more needed.
9278  *  \throw If any \a arr[i] is not allocated.
9279  *  \throw If \a arr[i]->getNumberOfComponents() != 1.
9280  */
9281 DataArrayInt *DataArrayInt::BuildUnion(const std::vector<const DataArrayInt *>& arr)
9282 {
9283   std::vector<const DataArrayInt *> a;
9284   for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
9285     if(*it4)
9286       a.push_back(*it4);
9287   for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
9288     {
9289       (*it)->checkAllocated();
9290       if((*it)->getNumberOfComponents()!=1)
9291         throw INTERP_KERNEL::Exception("DataArrayInt::BuildUnion : only single component allowed !");
9292     }
9293   //
9294   std::set<int> r;
9295   for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
9296     {
9297       const int *pt=(*it)->getConstPointer();
9298       int nbOfTuples=(*it)->getNumberOfTuples();
9299       r.insert(pt,pt+nbOfTuples);
9300     }
9301   DataArrayInt *ret=DataArrayInt::New();
9302   ret->alloc((int)r.size(),1);
9303   std::copy(r.begin(),r.end(),ret->getPointer());
9304   return ret;
9305 }
9306
9307 /*!
9308  * Returns a new DataArrayInt which contains elements present in each of given one-dimensional
9309  * arrays. The result array does not contain any duplicates and its values
9310  * are sorted in ascending order.
9311  *  \param [in] arr - sequence of DataArrayInt's to intersect.
9312  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
9313  *         array using decrRef() as it is no more needed.
9314  *  \throw If any \a arr[i] is not allocated.
9315  *  \throw If \a arr[i]->getNumberOfComponents() != 1.
9316  */
9317 DataArrayInt *DataArrayInt::BuildIntersection(const std::vector<const DataArrayInt *>& arr)
9318 {
9319   std::vector<const DataArrayInt *> a;
9320   for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
9321     if(*it4)
9322       a.push_back(*it4);
9323   for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
9324     {
9325       (*it)->checkAllocated();
9326       if((*it)->getNumberOfComponents()!=1)
9327         throw INTERP_KERNEL::Exception("DataArrayInt::BuildIntersection : only single component allowed !");
9328     }
9329   //
9330   std::set<int> r;
9331   for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
9332     {
9333       const int *pt=(*it)->getConstPointer();
9334       int nbOfTuples=(*it)->getNumberOfTuples();
9335       std::set<int> s1(pt,pt+nbOfTuples);
9336       if(it!=a.begin())
9337         {
9338           std::set<int> r2;
9339           std::set_intersection(r.begin(),r.end(),s1.begin(),s1.end(),inserter(r2,r2.end()));
9340           r=r2;
9341         }
9342       else
9343         r=s1;
9344     }
9345   DataArrayInt *ret=DataArrayInt::New();
9346   ret->alloc((int)r.size(),1);
9347   std::copy(r.begin(),r.end(),ret->getPointer());
9348   return ret;
9349 }
9350
9351 /*!
9352  * Returns a new DataArrayInt which contains a complement of elements of \a this
9353  * one-dimensional array. I.e. the result array contains all elements from the range [0,
9354  * \a nbOfElement) not present in \a this array.
9355  *  \param [in] nbOfElement - maximal size of the result array.
9356  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
9357  *         array using decrRef() as it is no more needed.
9358  *  \throw If \a this is not allocated.
9359  *  \throw If \a this->getNumberOfComponents() != 1.
9360  *  \throw If any element \a x of \a this array violates condition ( 0 <= \a x < \a
9361  *         nbOfElement ).
9362  */
9363 DataArrayInt *DataArrayInt::buildComplement(int nbOfElement) const
9364 {
9365    checkAllocated();
9366    if(getNumberOfComponents()!=1)
9367      throw INTERP_KERNEL::Exception("DataArrayInt::buildComplement : only single component allowed !");
9368    std::vector<bool> tmp(nbOfElement);
9369    const int *pt=getConstPointer();
9370    int nbOfTuples=getNumberOfTuples();
9371    for(const int *w=pt;w!=pt+nbOfTuples;w++)
9372      if(*w>=0 && *w<nbOfElement)
9373        tmp[*w]=true;
9374      else
9375        throw INTERP_KERNEL::Exception("DataArrayInt::buildComplement : an element is not in valid range : [0,nbOfElement) !");
9376    int nbOfRetVal=(int)std::count(tmp.begin(),tmp.end(),false);
9377    DataArrayInt *ret=DataArrayInt::New();
9378    ret->alloc(nbOfRetVal,1);
9379    int j=0;
9380    int *retPtr=ret->getPointer();
9381    for(int i=0;i<nbOfElement;i++)
9382      if(!tmp[i])
9383        retPtr[j++]=i;
9384    return ret;
9385 }
9386
9387 /*!
9388  * Returns a new DataArrayInt containing elements of \a this one-dimensional missing
9389  * from an \a other one-dimensional array.
9390  *  \param [in] other - a DataArrayInt containing elements not to include in the result array.
9391  *  \return DataArrayInt * - a new instance of DataArrayInt with one component. The
9392  *         caller is to delete this array using decrRef() as it is no more needed.
9393  *  \throw If \a other is NULL.
9394  *  \throw If \a other is not allocated.
9395  *  \throw If \a other->getNumberOfComponents() != 1.
9396  *  \throw If \a this is not allocated.
9397  *  \throw If \a this->getNumberOfComponents() != 1.
9398  *  \sa DataArrayInt::buildSubstractionOptimized()
9399  */
9400 DataArrayInt *DataArrayInt::buildSubstraction(const DataArrayInt *other) const
9401 {
9402   if(!other)
9403     throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstraction : DataArrayInt pointer in input is NULL !");
9404   checkAllocated();
9405   other->checkAllocated();
9406   if(getNumberOfComponents()!=1)
9407      throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstraction : only single component allowed !");
9408   if(other->getNumberOfComponents()!=1)
9409      throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstraction : only single component allowed for other type !");
9410   const int *pt=getConstPointer();
9411   int nbOfTuples=getNumberOfTuples();
9412   std::set<int> s1(pt,pt+nbOfTuples);
9413   pt=other->getConstPointer();
9414   nbOfTuples=other->getNumberOfTuples();
9415   std::set<int> s2(pt,pt+nbOfTuples);
9416   std::vector<int> r;
9417   std::set_difference(s1.begin(),s1.end(),s2.begin(),s2.end(),std::back_insert_iterator< std::vector<int> >(r));
9418   DataArrayInt *ret=DataArrayInt::New();
9419   ret->alloc((int)r.size(),1);
9420   std::copy(r.begin(),r.end(),ret->getPointer());
9421   return ret;
9422 }
9423
9424 /*!
9425  * \a this is expected to have one component and to be sorted ascendingly (as for \a other).
9426  * \a other is expected to be a part of \a this. If not DataArrayInt::buildSubstraction should be called instead.
9427  * 
9428  * \param [in] other an array with one component and expected to be sorted ascendingly.
9429  * \ret list of ids in \a this but not in \a other.
9430  * \sa DataArrayInt::buildSubstraction
9431  */
9432 DataArrayInt *DataArrayInt::buildSubstractionOptimized(const DataArrayInt *other) const
9433 {
9434   static const char *MSG="DataArrayInt::buildSubstractionOptimized : only single component allowed !";
9435   if(!other) throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstractionOptimized : NULL input array !");
9436   checkAllocated(); other->checkAllocated();
9437   if(getNumberOfComponents()!=1) throw INTERP_KERNEL::Exception(MSG);
9438   if(other->getNumberOfComponents()!=1) throw INTERP_KERNEL::Exception(MSG);
9439   const int *pt1Bg(begin()),*pt1End(end()),*pt2Bg(other->begin()),*pt2End(other->end()),*work1(pt1Bg),*work2(pt2Bg);
9440   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
9441   for(;work1!=pt1End;work1++)
9442     {
9443       if(work2!=pt2End && *work1==*work2)
9444         work2++;
9445       else
9446         ret->pushBackSilent(*work1);
9447     }
9448   return ret.retn();
9449 }
9450
9451
9452 /*!
9453  * Returns a new DataArrayInt which contains all elements of \a this and a given
9454  * one-dimensional arrays. The result array does not contain any duplicates
9455  * and its values are sorted in ascending order.
9456  *  \param [in] other - an array to unite with \a this one.
9457  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
9458  *         array using decrRef() as it is no more needed.
9459  *  \throw If \a this or \a other is not allocated.
9460  *  \throw If \a this->getNumberOfComponents() != 1.
9461  *  \throw If \a other->getNumberOfComponents() != 1.
9462  */
9463 DataArrayInt *DataArrayInt::buildUnion(const DataArrayInt *other) const
9464 {
9465   std::vector<const DataArrayInt *>arrs(2);
9466   arrs[0]=this; arrs[1]=other;
9467   return BuildUnion(arrs);
9468 }
9469
9470
9471 /*!
9472  * Returns a new DataArrayInt which contains elements present in both \a this and a given
9473  * one-dimensional arrays. The result array does not contain any duplicates
9474  * and its values are sorted in ascending order.
9475  *  \param [in] other - an array to intersect with \a this one.
9476  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
9477  *         array using decrRef() as it is no more needed.
9478  *  \throw If \a this or \a other is not allocated.
9479  *  \throw If \a this->getNumberOfComponents() != 1.
9480  *  \throw If \a other->getNumberOfComponents() != 1.
9481  */
9482 DataArrayInt *DataArrayInt::buildIntersection(const DataArrayInt *other) const
9483 {
9484   std::vector<const DataArrayInt *>arrs(2);
9485   arrs[0]=this; arrs[1]=other;
9486   return BuildIntersection(arrs);
9487 }
9488
9489 /*!
9490  * This method can be applied on allocated with one component DataArrayInt instance.
9491  * This method is typically relevant for sorted arrays. All consecutive duplicated items in \a this will appear only once in returned DataArrayInt instance.
9492  * 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]
9493  * 
9494  * \return a newly allocated array that contain the result of the unique operation applied on \a this.
9495  * \throw if \a this is not allocated or if \a this has not exactly one component.
9496  */
9497 DataArrayInt *DataArrayInt::buildUnique() const
9498 {
9499   checkAllocated();
9500   if(getNumberOfComponents()!=1)
9501      throw INTERP_KERNEL::Exception("DataArrayInt::buildUnique : only single component allowed !");
9502   int nbOfTuples=getNumberOfTuples();
9503   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp=deepCpy();
9504   int *data=tmp->getPointer();
9505   int *last=std::unique(data,data+nbOfTuples);
9506   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
9507   ret->alloc(std::distance(data,last),1);
9508   std::copy(data,last,ret->getPointer());
9509   return ret.retn();
9510 }
9511
9512 /*!
9513  * Returns a new DataArrayInt which contains size of every of groups described by \a this
9514  * "index" array. Such "index" array is returned for example by 
9515  * \ref ParaMEDMEM::MEDCouplingUMesh::buildDescendingConnectivity
9516  * "MEDCouplingUMesh::buildDescendingConnectivity" and
9517  * \ref ParaMEDMEM::MEDCouplingUMesh::getNodalConnectivityIndex
9518  * "MEDCouplingUMesh::getNodalConnectivityIndex" etc.
9519  * This method preforms the reverse operation of DataArrayInt::computeOffsets2.
9520  *  \return DataArrayInt * - a new instance of DataArrayInt, whose number of tuples
9521  *          equals to \a this->getNumberOfComponents() - 1, and number of components is 1.
9522  *          The caller is to delete this array using decrRef() as it is no more needed. 
9523  *  \throw If \a this is not allocated.
9524  *  \throw If \a this->getNumberOfComponents() != 1.
9525  *  \throw If \a this->getNumberOfTuples() < 2.
9526  *
9527  *  \b Example: <br> 
9528  *         - this contains [1,3,6,7,7,9,15]
9529  *         - result array contains [2,3,1,0,2,6],
9530  *          where 2 = 3 - 1, 3 = 6 - 3, 1 = 7 - 6 etc.
9531  *
9532  * \sa DataArrayInt::computeOffsets2
9533  */
9534 DataArrayInt *DataArrayInt::deltaShiftIndex() const
9535 {
9536   checkAllocated();
9537   if(getNumberOfComponents()!=1)
9538      throw INTERP_KERNEL::Exception("DataArrayInt::deltaShiftIndex : only single component allowed !");
9539   int nbOfTuples=getNumberOfTuples();
9540   if(nbOfTuples<2)
9541     throw INTERP_KERNEL::Exception("DataArrayInt::deltaShiftIndex : 1 tuple at least must be present in 'this' !");
9542   const int *ptr=getConstPointer();
9543   DataArrayInt *ret=DataArrayInt::New();
9544   ret->alloc(nbOfTuples-1,1);
9545   int *out=ret->getPointer();
9546   std::transform(ptr+1,ptr+nbOfTuples,ptr,out,std::minus<int>());
9547   return ret;
9548 }
9549
9550 /*!
9551  * Modifies \a this one-dimensional array so that value of each element \a x
9552  * of \a this array (\a a) is computed as \f$ x_i = \sum_{j=0}^{i-1} a[ j ] \f$.
9553  * Or: for each i>0 new[i]=new[i-1]+old[i-1] for i==0 new[i]=0. Number of tuples
9554  * and components remains the same.<br>
9555  * This method is useful for allToAllV in MPI with contiguous policy. This method
9556  * differs from computeOffsets2() in that the number of tuples is \b not changed by
9557  * this one.
9558  *  \throw If \a this is not allocated.
9559  *  \throw If \a this->getNumberOfComponents() != 1.
9560  *
9561  *  \b Example: <br>
9562  *          - Before \a this contains [3,5,1,2,0,8]
9563  *          - After \a this contains  [0,3,8,9,11,11]<br>
9564  *          Note that the last element 19 = 11 + 8 is missing because size of \a this
9565  *          array is retained and thus there is no space to store the last element.
9566  */
9567 void DataArrayInt::computeOffsets()
9568 {
9569   checkAllocated();
9570   if(getNumberOfComponents()!=1)
9571      throw INTERP_KERNEL::Exception("DataArrayInt::computeOffsets : only single component allowed !");
9572   int nbOfTuples=getNumberOfTuples();
9573   if(nbOfTuples==0)
9574     return ;
9575   int *work=getPointer();
9576   int tmp=work[0];
9577   work[0]=0;
9578   for(int i=1;i<nbOfTuples;i++)
9579     {
9580       int tmp2=work[i];
9581       work[i]=work[i-1]+tmp;
9582       tmp=tmp2;
9583     }
9584   declareAsNew();
9585 }
9586
9587
9588 /*!
9589  * Modifies \a this one-dimensional array so that value of each element \a x
9590  * of \a this array (\a a) is computed as \f$ x_i = \sum_{j=0}^{i-1} a[ j ] \f$.
9591  * Or: for each i>0 new[i]=new[i-1]+old[i-1] for i==0 new[i]=0. Number
9592  * components remains the same and number of tuples is inceamented by one.<br>
9593  * This method is useful for allToAllV in MPI with contiguous policy. This method
9594  * differs from computeOffsets() in that the number of tuples is changed by this one.
9595  * This method preforms the reverse operation of DataArrayInt::deltaShiftIndex.
9596  *  \throw If \a this is not allocated.
9597  *  \throw If \a this->getNumberOfComponents() != 1.
9598  *
9599  *  \b Example: <br>
9600  *          - Before \a this contains [3,5,1,2,0,8]
9601  *          - After \a this contains  [0,3,8,9,11,11,19]<br>
9602  * \sa DataArrayInt::deltaShiftIndex
9603  */
9604 void DataArrayInt::computeOffsets2()
9605 {
9606   checkAllocated();
9607   if(getNumberOfComponents()!=1)
9608     throw INTERP_KERNEL::Exception("DataArrayInt::computeOffsets2 : only single component allowed !");
9609   int nbOfTuples=getNumberOfTuples();
9610   int *ret=(int *)malloc((nbOfTuples+1)*sizeof(int));
9611   if(nbOfTuples==0)
9612     return ;
9613   const int *work=getConstPointer();
9614   ret[0]=0;
9615   for(int i=0;i<nbOfTuples;i++)
9616     ret[i+1]=work[i]+ret[i];
9617   useArray(ret,true,C_DEALLOC,nbOfTuples+1,1);
9618   declareAsNew();
9619 }
9620
9621 /*!
9622  * Returns two new DataArrayInt instances whose contents is computed from that of \a this and \a listOfIds arrays as follows.
9623  * \a this is expected to be an offset format ( as returned by DataArrayInt::computeOffsets2 ) that is to say with one component
9624  * and ** sorted strictly increasingly **. \a listOfIds is expected to be sorted ascendingly (not strictly needed for \a listOfIds).
9625  * This methods searches in \a this, considered as a set of contiguous \c this->getNumberOfComponents() ranges, all ids in \a listOfIds
9626  * filling completely one of the ranges in \a this.
9627  *
9628  * \param [in] listOfIds a list of ids that has to be sorted ascendingly.
9629  * \param [out] rangeIdsFetched the range ids fetched
9630  * \param [out] idsInInputListThatFetch contains the list of ids in \a listOfIds that are \b fully included in a range in \a this. So
9631  *              \a idsInInputListThatFetch is a part of input \a listOfIds.
9632  *
9633  * \sa DataArrayInt::computeOffsets2
9634  *
9635  *  \b Example: <br>
9636  *          - \a this : [0,3,7,9,15,18]
9637  *          - \a listOfIds contains  [0,1,2,3,7,8,15,16,17]
9638  *          - \a rangeIdsFetched result array: [0,2,4]
9639  *          - \a idsInInputListThatFetch result array: [0,1,2,7,8,15,16,17]
9640  * In this example id 3 in input \a listOfIds is alone so it do not appear in output \a idsInInputListThatFetch.
9641  * <br>
9642  */
9643 void DataArrayInt::searchRangesInListOfIds(const DataArrayInt *listOfIds, DataArrayInt *& rangeIdsFetched, DataArrayInt *& idsInInputListThatFetch) const
9644 {
9645   if(!listOfIds)
9646     throw INTERP_KERNEL::Exception("DataArrayInt::searchRangesInListOfIds : input list of ids is null !");
9647   listOfIds->checkAllocated(); checkAllocated();
9648   if(listOfIds->getNumberOfComponents()!=1)
9649     throw INTERP_KERNEL::Exception("DataArrayInt::searchRangesInListOfIds : input list of ids must have exactly one component !");
9650   if(getNumberOfComponents()!=1)
9651     throw INTERP_KERNEL::Exception("DataArrayInt::searchRangesInListOfIds : this must have exactly one component !");
9652   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret0=DataArrayInt::New(); ret0->alloc(0,1);
9653   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret1=DataArrayInt::New(); ret1->alloc(0,1);
9654   const int *tupEnd(listOfIds->end()),*offBg(begin()),*offEnd(end()-1);
9655   const int *tupPtr(listOfIds->begin()),*offPtr(offBg);
9656   while(tupPtr!=tupEnd && offPtr!=offEnd)
9657     {
9658       if(*tupPtr==*offPtr)
9659         {
9660           int i=offPtr[0];
9661           while(i<offPtr[1] && *tupPtr==i && tupPtr!=tupEnd) { i++; tupPtr++; }
9662           if(i==offPtr[1])
9663             {
9664               ret0->pushBackSilent((int)std::distance(offBg,offPtr));
9665               ret1->pushBackValsSilent(tupPtr-(offPtr[1]-offPtr[0]),tupPtr);
9666               offPtr++;
9667             }
9668         }
9669       else
9670         { if(*tupPtr<*offPtr) tupPtr++; else offPtr++; }
9671     }
9672   rangeIdsFetched=ret0.retn();
9673   idsInInputListThatFetch=ret1.retn();
9674 }
9675
9676 /*!
9677  * Returns a new DataArrayInt whose contents is computed from that of \a this and \a
9678  * offsets arrays as follows. \a offsets is a one-dimensional array considered as an
9679  * "index" array of a "iota" array, thus, whose each element gives an index of a group
9680  * beginning within the "iota" array. And \a this is a one-dimensional array
9681  * considered as a selector of groups described by \a offsets to include into the result array.
9682  *  \throw If \a offsets is NULL.
9683  *  \throw If \a offsets is not allocated.
9684  *  \throw If \a offsets->getNumberOfComponents() != 1.
9685  *  \throw If \a offsets is not monotonically increasing.
9686  *  \throw If \a this is not allocated.
9687  *  \throw If \a this->getNumberOfComponents() != 1.
9688  *  \throw If any element of \a this is not a valid index for \a offsets array.
9689  *
9690  *  \b Example: <br>
9691  *          - \a this: [0,2,3]
9692  *          - \a offsets: [0,3,6,10,14,20]
9693  *          - result array: [0,1,2,6,7,8,9,10,11,12,13] == <br>
9694  *            \c range(0,3) + \c range(6,10) + \c range(10,14) ==<br>
9695  *            \c range( \a offsets[ \a this[0] ], offsets[ \a this[0]+1 ]) + 
9696  *            \c range( \a offsets[ \a this[1] ], offsets[ \a this[1]+1 ]) + 
9697  *            \c range( \a offsets[ \a this[2] ], offsets[ \a this[2]+1 ])
9698  */
9699 DataArrayInt *DataArrayInt::buildExplicitArrByRanges(const DataArrayInt *offsets) const
9700 {
9701   if(!offsets)
9702     throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrByRanges : DataArrayInt pointer in input is NULL !");
9703   checkAllocated();
9704   if(getNumberOfComponents()!=1)
9705      throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrByRanges : only single component allowed !");
9706   offsets->checkAllocated();
9707   if(offsets->getNumberOfComponents()!=1)
9708      throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrByRanges : input array should have only single component !");
9709   int othNbTuples=offsets->getNumberOfTuples()-1;
9710   int nbOfTuples=getNumberOfTuples();
9711   int retNbOftuples=0;
9712   const int *work=getConstPointer();
9713   const int *offPtr=offsets->getConstPointer();
9714   for(int i=0;i<nbOfTuples;i++)
9715     {
9716       int val=work[i];
9717       if(val>=0 && val<othNbTuples)
9718         {
9719           int delta=offPtr[val+1]-offPtr[val];
9720           if(delta>=0)
9721             retNbOftuples+=delta;
9722           else
9723             {
9724               std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrByRanges : Tuple #" << val << " of offset array has a delta < 0 !";
9725               throw INTERP_KERNEL::Exception(oss.str().c_str());
9726             }
9727         }
9728       else
9729         {
9730           std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrByRanges : Tuple #" << i << " in this contains " << val;
9731           oss << " whereas offsets array is of size " << othNbTuples+1 << " !";
9732           throw INTERP_KERNEL::Exception(oss.str().c_str());
9733         }
9734     }
9735   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
9736   ret->alloc(retNbOftuples,1);
9737   int *retPtr=ret->getPointer();
9738   for(int i=0;i<nbOfTuples;i++)
9739     {
9740       int val=work[i];
9741       int start=offPtr[val];
9742       int off=offPtr[val+1]-start;
9743       for(int j=0;j<off;j++,retPtr++)
9744         *retPtr=start+j;
9745     }
9746   return ret.retn();
9747 }
9748
9749 /*!
9750  * Returns a new DataArrayInt whose contents is computed using \a this that must be a 
9751  * scaled array (monotonically increasing).
9752 from that of \a this and \a
9753  * offsets arrays as follows. \a offsets is a one-dimensional array considered as an
9754  * "index" array of a "iota" array, thus, whose each element gives an index of a group
9755  * beginning within the "iota" array. And \a this is a one-dimensional array
9756  * considered as a selector of groups described by \a offsets to include into the result array.
9757  *  \throw If \a  is NULL.
9758  *  \throw If \a this is not allocated.
9759  *  \throw If \a this->getNumberOfComponents() != 1.
9760  *  \throw If \a this->getNumberOfTuples() == 0.
9761  *  \throw If \a this is not monotonically increasing.
9762  *  \throw If any element of ids in ( \a gb \a end \a step ) points outside the scale in \a this.
9763  *
9764  *  \b Example: <br>
9765  *          - \a bg , \a end and \a step : (0,5,2)
9766  *          - \a this: [0,3,6,10,14,20]
9767  *          - result array: [0,0,0, 2,2,2,2, 4,4,4,4,4,4] == <br>
9768  */
9769 DataArrayInt *DataArrayInt::buildExplicitArrOfSliceOnScaledArr(int bg, int end, int step) const
9770 {
9771   if(!isAllocated())
9772     throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrOfSliceOnScaledArr : not allocated array !");
9773   if(getNumberOfComponents()!=1)
9774     throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrOfSliceOnScaledArr : number of components is expected to be equal to one !");
9775   int nbOfTuples(getNumberOfTuples());
9776   if(nbOfTuples==0)
9777     throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrOfSliceOnScaledArr : number of tuples must be != 0 !");
9778   const int *ids(begin());
9779   int nbOfEltsInSlc(GetNumberOfItemGivenBESRelative(bg,end,step,"DataArrayInt::buildExplicitArrOfSliceOnScaledArr")),sz(0),pos(bg);
9780   for(int i=0;i<nbOfEltsInSlc;i++,pos+=step)
9781     {
9782       if(pos>=0 && pos<nbOfTuples-1)
9783         {
9784           int delta(ids[pos+1]-ids[pos]);
9785           sz+=delta;
9786           if(delta<0)
9787             {
9788               std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrOfSliceOnScaledArr : At pos #" << i << " of input slice, value is " << pos << " and at this pos this is not monotonically increasing !";
9789               throw INTERP_KERNEL::Exception(oss.str().c_str());
9790             }          
9791         }
9792       else
9793         {
9794           std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrOfSliceOnScaledArr : At pos #" << i << " of input slice, value is " << pos << " should be in [0," << nbOfTuples-1 << ") !";  
9795           throw INTERP_KERNEL::Exception(oss.str().c_str());
9796         }
9797     }
9798   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(sz,1);
9799   int *retPtr(ret->getPointer());
9800   pos=bg;
9801   for(int i=0;i<nbOfEltsInSlc;i++,pos+=step)
9802     {
9803       int delta(ids[pos+1]-ids[pos]);
9804       for(int j=0;j<delta;j++,retPtr++)
9805         *retPtr=pos;
9806     }
9807   return ret.retn();
9808 }
9809
9810 /*!
9811  * 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.
9812  * 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
9813  * in tuple **i** of returned DataArrayInt.
9814  * If ranges overlapped (in theory it should not) this method do not detect it and always returns the first range.
9815  *
9816  * 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)]
9817  * The return DataArrayInt will contain : **[0,4,1,2,2,3]**
9818  * 
9819  * \param [in] ranges typically come from output of MEDCouplingUMesh::ComputeRangesFromTypeDistribution. Each range is specified like this : 1st component is
9820  *             for lower value included and 2nd component is the upper value of corresponding range **excluded**.
9821  * \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
9822  *        is thrown if no ranges in \a ranges contains value in \a this.
9823  * 
9824  * \sa DataArrayInt::findIdInRangeForEachTuple
9825  */
9826 DataArrayInt *DataArrayInt::findRangeIdForEachTuple(const DataArrayInt *ranges) const
9827 {
9828   if(!ranges)
9829     throw INTERP_KERNEL::Exception("DataArrayInt::findRangeIdForEachTuple : null input pointer !");
9830   if(ranges->getNumberOfComponents()!=2)
9831     throw INTERP_KERNEL::Exception("DataArrayInt::findRangeIdForEachTuple : input DataArrayInt instance should have 2 components !");
9832   checkAllocated();
9833   if(getNumberOfComponents()!=1)
9834     throw INTERP_KERNEL::Exception("DataArrayInt::findRangeIdForEachTuple : this should have only one component !");
9835   int nbTuples=getNumberOfTuples();
9836   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbTuples,1);
9837   int nbOfRanges=ranges->getNumberOfTuples();
9838   const int *rangesPtr=ranges->getConstPointer();
9839   int *retPtr=ret->getPointer();
9840   const int *inPtr=getConstPointer();
9841   for(int i=0;i<nbTuples;i++,retPtr++)
9842     {
9843       int val=inPtr[i];
9844       bool found=false;
9845       for(int j=0;j<nbOfRanges && !found;j++)
9846         if(val>=rangesPtr[2*j] && val<rangesPtr[2*j+1])
9847           { *retPtr=j; found=true; }
9848       if(found)
9849         continue;
9850       else
9851         {
9852           std::ostringstream oss; oss << "DataArrayInt::findRangeIdForEachTuple : tuple #" << i << " not found by any ranges !";
9853           throw INTERP_KERNEL::Exception(oss.str().c_str());
9854         }
9855     }
9856   return ret.retn();
9857 }
9858
9859 /*!
9860  * 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.
9861  * 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
9862  * in tuple **i** of returned DataArrayInt.
9863  * If ranges overlapped (in theory it should not) this method do not detect it and always returns the sub position of the first range.
9864  *
9865  * 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)]
9866  * The return DataArrayInt will contain : **[1,2,4,0,2,2]**
9867  * This method is often called in pair with DataArrayInt::findRangeIdForEachTuple method.
9868  * 
9869  * \param [in] ranges typically come from output of MEDCouplingUMesh::ComputeRangesFromTypeDistribution. Each range is specified like this : 1st component is
9870  *             for lower value included and 2nd component is the upper value of corresponding range **excluded**.
9871  * \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
9872  *        is thrown if no ranges in \a ranges contains value in \a this.
9873  * \sa DataArrayInt::findRangeIdForEachTuple
9874  */
9875 DataArrayInt *DataArrayInt::findIdInRangeForEachTuple(const DataArrayInt *ranges) const
9876 {
9877   if(!ranges)
9878     throw INTERP_KERNEL::Exception("DataArrayInt::findIdInRangeForEachTuple : null input pointer !");
9879   if(ranges->getNumberOfComponents()!=2)
9880     throw INTERP_KERNEL::Exception("DataArrayInt::findIdInRangeForEachTuple : input DataArrayInt instance should have 2 components !");
9881   checkAllocated();
9882   if(getNumberOfComponents()!=1)
9883     throw INTERP_KERNEL::Exception("DataArrayInt::findIdInRangeForEachTuple : this should have only one component !");
9884   int nbTuples=getNumberOfTuples();
9885   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbTuples,1);
9886   int nbOfRanges=ranges->getNumberOfTuples();
9887   const int *rangesPtr=ranges->getConstPointer();
9888   int *retPtr=ret->getPointer();
9889   const int *inPtr=getConstPointer();
9890   for(int i=0;i<nbTuples;i++,retPtr++)
9891     {
9892       int val=inPtr[i];
9893       bool found=false;
9894       for(int j=0;j<nbOfRanges && !found;j++)
9895         if(val>=rangesPtr[2*j] && val<rangesPtr[2*j+1])
9896           { *retPtr=val-rangesPtr[2*j]; found=true; }
9897       if(found)
9898         continue;
9899       else
9900         {
9901           std::ostringstream oss; oss << "DataArrayInt::findIdInRangeForEachTuple : tuple #" << i << " not found by any ranges !";
9902           throw INTERP_KERNEL::Exception(oss.str().c_str());
9903         }
9904     }
9905   return ret.retn();
9906 }
9907
9908 /*!
9909  * 
9910  * \param [in] nbTimes specifies the nb of times each tuples in \a this will be duplicated contiguouly in returned DataArrayInt instance.
9911  *             \a nbTimes  should be at least equal to 1.
9912  * \return a newly allocated DataArrayInt having one component and number of tuples equal to \a nbTimes * \c this->getNumberOfTuples.
9913  * \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.
9914  */
9915 DataArrayInt *DataArrayInt::duplicateEachTupleNTimes(int nbTimes) const
9916 {
9917   checkAllocated();
9918   if(getNumberOfComponents()!=1)
9919     throw INTERP_KERNEL::Exception("DataArrayInt::duplicateEachTupleNTimes : this should have only one component !");
9920   if(nbTimes<1)
9921     throw INTERP_KERNEL::Exception("DataArrayInt::duplicateEachTupleNTimes : nb times should be >= 1 !");
9922   int nbTuples=getNumberOfTuples();
9923   const int *inPtr=getConstPointer();
9924   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbTimes*nbTuples,1);
9925   int *retPtr=ret->getPointer();
9926   for(int i=0;i<nbTuples;i++,inPtr++)
9927     {
9928       int val=*inPtr;
9929       for(int j=0;j<nbTimes;j++,retPtr++)
9930         *retPtr=val;
9931     }
9932   ret->copyStringInfoFrom(*this);
9933   return ret.retn();
9934 }
9935
9936 /*!
9937  * This method returns all different values found in \a this. This method throws if \a this has not been allocated.
9938  * But the number of components can be different from one.
9939  * \return a newly allocated array (that should be dealt by the caller) containing different values in \a this.
9940  */
9941 DataArrayInt *DataArrayInt::getDifferentValues() const
9942 {
9943   checkAllocated();
9944   std::set<int> ret;
9945   ret.insert(begin(),end());
9946   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret2=DataArrayInt::New(); ret2->alloc((int)ret.size(),1);
9947   std::copy(ret.begin(),ret.end(),ret2->getPointer());
9948   return ret2.retn();
9949 }
9950
9951 /*!
9952  * This method is a refinement of DataArrayInt::getDifferentValues because it returns not only different values in \a this but also, for each of
9953  * them it tells which tuple id have this id.
9954  * This method works only on arrays with one component (if it is not the case call DataArrayInt::rearrange(1) ).
9955  * This method returns two arrays having same size.
9956  * 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.
9957  * 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]]
9958  */
9959 std::vector<DataArrayInt *> DataArrayInt::partitionByDifferentValues(std::vector<int>& differentIds) const
9960 {
9961   checkAllocated();
9962   if(getNumberOfComponents()!=1)
9963     throw INTERP_KERNEL::Exception("DataArrayInt::partitionByDifferentValues : this should have only one component !");
9964   int id=0;
9965   std::map<int,int> m,m2,m3;
9966   for(const int *w=begin();w!=end();w++)
9967     m[*w]++;
9968   differentIds.resize(m.size());
9969   std::vector<DataArrayInt *> ret(m.size());
9970   std::vector<int *> retPtr(m.size());
9971   for(std::map<int,int>::const_iterator it=m.begin();it!=m.end();it++,id++)
9972     {
9973       m2[(*it).first]=id;
9974       ret[id]=DataArrayInt::New();
9975       ret[id]->alloc((*it).second,1);
9976       retPtr[id]=ret[id]->getPointer();
9977       differentIds[id]=(*it).first;
9978     }
9979   id=0;
9980   for(const int *w=begin();w!=end();w++,id++)
9981     {
9982       retPtr[m2[*w]][m3[*w]++]=id;
9983     }
9984   return ret;
9985 }
9986
9987 /*!
9988  * This method split ids in [0, \c this->getNumberOfTuples() ) using \a this array as a field of weight (>=0 each).
9989  * The aim of this method is to return a set of \a nbOfSlices chunk of contiguous ids as balanced as possible.
9990  *
9991  * \param [in] nbOfSlices - number of slices expected.
9992  * \return - a vector having a size equal to \a nbOfSlices giving the start (included) and the stop (excluded) of each chunks.
9993  * 
9994  * \sa DataArray::GetSlice
9995  * \throw If \a this is not allocated or not with exactly one component.
9996  * \throw If an element in \a this if < 0.
9997  */
9998 std::vector< std::pair<int,int> > DataArrayInt::splitInBalancedSlices(int nbOfSlices) const
9999 {
10000   if(!isAllocated() || getNumberOfComponents()!=1)
10001     throw INTERP_KERNEL::Exception("DataArrayInt::splitInBalancedSlices : this array should have number of components equal to one and must be allocated !");
10002   if(nbOfSlices<=0)
10003     throw INTERP_KERNEL::Exception("DataArrayInt::splitInBalancedSlices : number of slices must be >= 1 !");
10004   int sum(accumulate(0)),nbOfTuples(getNumberOfTuples());
10005   int sumPerSlc(sum/nbOfSlices),pos(0);
10006   const int *w(begin());
10007   std::vector< std::pair<int,int> > ret(nbOfSlices);
10008   for(int i=0;i<nbOfSlices;i++)
10009     {
10010       std::pair<int,int> p(pos,-1);
10011       int locSum(0);
10012       while(locSum<sumPerSlc && pos<nbOfTuples) { pos++; locSum+=*w++; }
10013       if(i!=nbOfSlices-1)
10014         p.second=pos;
10015       else
10016         p.second=nbOfTuples;
10017       ret[i]=p;
10018     }
10019   return ret;
10020 }
10021
10022 /*!
10023  * Returns a new DataArrayInt that is a sum of two given arrays. There are 3
10024  * valid cases.
10025  * 1.  The arrays have same number of tuples and components. Then each value of
10026  *   the result array (_a_) is a sum of the corresponding values of \a a1 and \a a2,
10027  *   i.e.: _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ i, j ].
10028  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
10029  *   component. Then
10030  *   _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ i, 0 ].
10031  * 3.  The arrays have same number of components and one array, say _a2_, has one
10032  *   tuple. Then
10033  *   _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ 0, j ].
10034  *
10035  * Info on components is copied either from the first array (in the first case) or from
10036  * the array with maximal number of elements (getNbOfElems()).
10037  *  \param [in] a1 - an array to sum up.
10038  *  \param [in] a2 - another array to sum up.
10039  *  \return DataArrayInt * - the new instance of DataArrayInt.
10040  *          The caller is to delete this result array using decrRef() as it is no more
10041  *          needed.
10042  *  \throw If either \a a1 or \a a2 is NULL.
10043  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
10044  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
10045  *         none of them has number of tuples or components equal to 1.
10046  */
10047 DataArrayInt *DataArrayInt::Add(const DataArrayInt *a1, const DataArrayInt *a2)
10048 {
10049   if(!a1 || !a2)
10050     throw INTERP_KERNEL::Exception("DataArrayInt::Add : input DataArrayInt instance is NULL !");
10051   int nbOfTuple=a1->getNumberOfTuples();
10052   int nbOfTuple2=a2->getNumberOfTuples();
10053   int nbOfComp=a1->getNumberOfComponents();
10054   int nbOfComp2=a2->getNumberOfComponents();
10055   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=0;
10056   if(nbOfTuple==nbOfTuple2)
10057     {
10058       if(nbOfComp==nbOfComp2)
10059         {
10060           ret=DataArrayInt::New();
10061           ret->alloc(nbOfTuple,nbOfComp);
10062           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::plus<int>());
10063           ret->copyStringInfoFrom(*a1);
10064         }
10065       else
10066         {
10067           int nbOfCompMin,nbOfCompMax;
10068           const DataArrayInt *aMin, *aMax;
10069           if(nbOfComp>nbOfComp2)
10070             {
10071               nbOfCompMin=nbOfComp2; nbOfCompMax=nbOfComp;
10072               aMin=a2; aMax=a1;
10073             }
10074           else
10075             {
10076               nbOfCompMin=nbOfComp; nbOfCompMax=nbOfComp2;
10077               aMin=a1; aMax=a2;
10078             }
10079           if(nbOfCompMin==1)
10080             {
10081               ret=DataArrayInt::New();
10082               ret->alloc(nbOfTuple,nbOfCompMax);
10083               const int *aMinPtr=aMin->getConstPointer();
10084               const int *aMaxPtr=aMax->getConstPointer();
10085               int *res=ret->getPointer();
10086               for(int i=0;i<nbOfTuple;i++)
10087                 res=std::transform(aMaxPtr+i*nbOfCompMax,aMaxPtr+(i+1)*nbOfCompMax,res,std::bind2nd(std::plus<int>(),aMinPtr[i]));
10088               ret->copyStringInfoFrom(*aMax);
10089             }
10090           else
10091             throw INTERP_KERNEL::Exception("Nb of components mismatch for array Add !");
10092         }
10093     }
10094   else if((nbOfTuple==1 && nbOfTuple2>1) || (nbOfTuple>1 && nbOfTuple2==1))
10095     {
10096       if(nbOfComp==nbOfComp2)
10097         {
10098           int nbOfTupleMax=std::max(nbOfTuple,nbOfTuple2);
10099           const DataArrayInt *aMin=nbOfTuple>nbOfTuple2?a2:a1;
10100           const DataArrayInt *aMax=nbOfTuple>nbOfTuple2?a1:a2;
10101           const int *aMinPtr=aMin->getConstPointer(),*aMaxPtr=aMax->getConstPointer();
10102           ret=DataArrayInt::New();
10103           ret->alloc(nbOfTupleMax,nbOfComp);
10104           int *res=ret->getPointer();
10105           for(int i=0;i<nbOfTupleMax;i++)
10106             res=std::transform(aMaxPtr+i*nbOfComp,aMaxPtr+(i+1)*nbOfComp,aMinPtr,res,std::plus<int>());
10107           ret->copyStringInfoFrom(*aMax);
10108         }
10109       else
10110         throw INTERP_KERNEL::Exception("Nb of components mismatch for array Add !");
10111     }
10112   else
10113     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Add !");
10114   return ret.retn();
10115 }
10116
10117 /*!
10118  * Adds values of another DataArrayInt to values of \a this one. There are 3
10119  * valid cases.
10120  * 1.  The arrays have same number of tuples and components. Then each value of
10121  *   \a other array is added to the corresponding value of \a this array, i.e.:
10122  *   _a_ [ i, j ] += _other_ [ i, j ].
10123  * 2.  The arrays have same number of tuples and \a other array has one component. Then
10124  *   _a_ [ i, j ] += _other_ [ i, 0 ].
10125  * 3.  The arrays have same number of components and \a other array has one tuple. Then
10126  *   _a_ [ i, j ] += _a2_ [ 0, j ].
10127  *
10128  *  \param [in] other - an array to add to \a this one.
10129  *  \throw If \a other is NULL.
10130  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
10131  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
10132  *         \a other has number of both tuples and components not equal to 1.
10133  */
10134 void DataArrayInt::addEqual(const DataArrayInt *other)
10135 {
10136   if(!other)
10137     throw INTERP_KERNEL::Exception("DataArrayInt::addEqual : input DataArrayInt instance is NULL !");
10138   const char *msg="Nb of tuples mismatch for DataArrayInt::addEqual  !";
10139   checkAllocated(); other->checkAllocated();
10140   int nbOfTuple=getNumberOfTuples();
10141   int nbOfTuple2=other->getNumberOfTuples();
10142   int nbOfComp=getNumberOfComponents();
10143   int nbOfComp2=other->getNumberOfComponents();
10144   if(nbOfTuple==nbOfTuple2)
10145     {
10146       if(nbOfComp==nbOfComp2)
10147         {
10148           std::transform(begin(),end(),other->begin(),getPointer(),std::plus<int>());
10149         }
10150       else if(nbOfComp2==1)
10151         {
10152           int *ptr=getPointer();
10153           const int *ptrc=other->getConstPointer();
10154           for(int i=0;i<nbOfTuple;i++)
10155             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::plus<int>(),*ptrc++));
10156         }
10157       else
10158         throw INTERP_KERNEL::Exception(msg);
10159     }
10160   else if(nbOfTuple2==1)
10161     {
10162       if(nbOfComp2==nbOfComp)
10163         {
10164           int *ptr=getPointer();
10165           const int *ptrc=other->getConstPointer();
10166           for(int i=0;i<nbOfTuple;i++)
10167             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::plus<int>());
10168         }
10169       else
10170         throw INTERP_KERNEL::Exception(msg);
10171     }
10172   else
10173     throw INTERP_KERNEL::Exception(msg);
10174   declareAsNew();
10175 }
10176
10177 /*!
10178  * Returns a new DataArrayInt that is a subtraction of two given arrays. There are 3
10179  * valid cases.
10180  * 1.  The arrays have same number of tuples and components. Then each value of
10181  *   the result array (_a_) is a subtraction of the corresponding values of \a a1 and
10182  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ i, j ].
10183  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
10184  *   component. Then
10185  *   _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ i, 0 ].
10186  * 3.  The arrays have same number of components and one array, say _a2_, has one
10187  *   tuple. Then
10188  *   _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ 0, j ].
10189  *
10190  * Info on components is copied either from the first array (in the first case) or from
10191  * the array with maximal number of elements (getNbOfElems()).
10192  *  \param [in] a1 - an array to subtract from.
10193  *  \param [in] a2 - an array to subtract.
10194  *  \return DataArrayInt * - the new instance of DataArrayInt.
10195  *          The caller is to delete this result array using decrRef() as it is no more
10196  *          needed.
10197  *  \throw If either \a a1 or \a a2 is NULL.
10198  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
10199  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
10200  *         none of them has number of tuples or components equal to 1.
10201  */
10202 DataArrayInt *DataArrayInt::Substract(const DataArrayInt *a1, const DataArrayInt *a2)
10203 {
10204   if(!a1 || !a2)
10205     throw INTERP_KERNEL::Exception("DataArrayInt::Substract : input DataArrayInt instance is NULL !");
10206   int nbOfTuple1=a1->getNumberOfTuples();
10207   int nbOfTuple2=a2->getNumberOfTuples();
10208   int nbOfComp1=a1->getNumberOfComponents();
10209   int nbOfComp2=a2->getNumberOfComponents();
10210   if(nbOfTuple2==nbOfTuple1)
10211     {
10212       if(nbOfComp1==nbOfComp2)
10213         {
10214           MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
10215           ret->alloc(nbOfTuple2,nbOfComp1);
10216           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::minus<int>());
10217           ret->copyStringInfoFrom(*a1);
10218           return ret.retn();
10219         }
10220       else if(nbOfComp2==1)
10221         {
10222           MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
10223           ret->alloc(nbOfTuple1,nbOfComp1);
10224           const int *a2Ptr=a2->getConstPointer();
10225           const int *a1Ptr=a1->getConstPointer();
10226           int *res=ret->getPointer();
10227           for(int i=0;i<nbOfTuple1;i++)
10228             res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::minus<int>(),a2Ptr[i]));
10229           ret->copyStringInfoFrom(*a1);
10230           return ret.retn();
10231         }
10232       else
10233         {
10234           a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Substract !");
10235           return 0;
10236         }
10237     }
10238   else if(nbOfTuple2==1)
10239     {
10240       a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Substract !");
10241       MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
10242       ret->alloc(nbOfTuple1,nbOfComp1);
10243       const int *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
10244       int *pt=ret->getPointer();
10245       for(int i=0;i<nbOfTuple1;i++)
10246         pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::minus<int>());
10247       ret->copyStringInfoFrom(*a1);
10248       return ret.retn();
10249     }
10250   else
10251     {
10252       a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Substract !");//will always throw an exception
10253       return 0;
10254     }
10255 }
10256
10257 /*!
10258  * Subtract values of another DataArrayInt from values of \a this one. There are 3
10259  * valid cases.
10260  * 1.  The arrays have same number of tuples and components. Then each value of
10261  *   \a other array is subtracted from the corresponding value of \a this array, i.e.:
10262  *   _a_ [ i, j ] -= _other_ [ i, j ].
10263  * 2.  The arrays have same number of tuples and \a other array has one component. Then
10264  *   _a_ [ i, j ] -= _other_ [ i, 0 ].
10265  * 3.  The arrays have same number of components and \a other array has one tuple. Then
10266  *   _a_ [ i, j ] -= _a2_ [ 0, j ].
10267  *
10268  *  \param [in] other - an array to subtract from \a this one.
10269  *  \throw If \a other is NULL.
10270  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
10271  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
10272  *         \a other has number of both tuples and components not equal to 1.
10273  */
10274 void DataArrayInt::substractEqual(const DataArrayInt *other)
10275 {
10276   if(!other)
10277     throw INTERP_KERNEL::Exception("DataArrayInt::substractEqual : input DataArrayInt instance is NULL !");
10278   const char *msg="Nb of tuples mismatch for DataArrayInt::substractEqual  !";
10279   checkAllocated(); other->checkAllocated();
10280   int nbOfTuple=getNumberOfTuples();
10281   int nbOfTuple2=other->getNumberOfTuples();
10282   int nbOfComp=getNumberOfComponents();
10283   int nbOfComp2=other->getNumberOfComponents();
10284   if(nbOfTuple==nbOfTuple2)
10285     {
10286       if(nbOfComp==nbOfComp2)
10287         {
10288           std::transform(begin(),end(),other->begin(),getPointer(),std::minus<int>());
10289         }
10290       else if(nbOfComp2==1)
10291         {
10292           int *ptr=getPointer();
10293           const int *ptrc=other->getConstPointer();
10294           for(int i=0;i<nbOfTuple;i++)
10295             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::minus<int>(),*ptrc++));
10296         }
10297       else
10298         throw INTERP_KERNEL::Exception(msg);
10299     }
10300   else if(nbOfTuple2==1)
10301     {
10302       int *ptr=getPointer();
10303       const int *ptrc=other->getConstPointer();
10304       for(int i=0;i<nbOfTuple;i++)
10305         std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::minus<int>());
10306     }
10307   else
10308     throw INTERP_KERNEL::Exception(msg);
10309   declareAsNew();
10310 }
10311
10312 /*!
10313  * Returns a new DataArrayInt that is a product of two given arrays. There are 3
10314  * valid cases.
10315  * 1.  The arrays have same number of tuples and components. Then each value of
10316  *   the result array (_a_) is a product of the corresponding values of \a a1 and
10317  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ i, j ].
10318  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
10319  *   component. Then
10320  *   _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ i, 0 ].
10321  * 3.  The arrays have same number of components and one array, say _a2_, has one
10322  *   tuple. Then
10323  *   _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ 0, j ].
10324  *
10325  * Info on components is copied either from the first array (in the first case) or from
10326  * the array with maximal number of elements (getNbOfElems()).
10327  *  \param [in] a1 - a factor array.
10328  *  \param [in] a2 - another factor array.
10329  *  \return DataArrayInt * - the new instance of DataArrayInt.
10330  *          The caller is to delete this result array using decrRef() as it is no more
10331  *          needed.
10332  *  \throw If either \a a1 or \a a2 is NULL.
10333  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
10334  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
10335  *         none of them has number of tuples or components equal to 1.
10336  */
10337 DataArrayInt *DataArrayInt::Multiply(const DataArrayInt *a1, const DataArrayInt *a2)
10338 {
10339   if(!a1 || !a2)
10340     throw INTERP_KERNEL::Exception("DataArrayInt::Multiply : input DataArrayInt instance is NULL !");
10341   int nbOfTuple=a1->getNumberOfTuples();
10342   int nbOfTuple2=a2->getNumberOfTuples();
10343   int nbOfComp=a1->getNumberOfComponents();
10344   int nbOfComp2=a2->getNumberOfComponents();
10345   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=0;
10346   if(nbOfTuple==nbOfTuple2)
10347     {
10348       if(nbOfComp==nbOfComp2)
10349         {
10350           ret=DataArrayInt::New();
10351           ret->alloc(nbOfTuple,nbOfComp);
10352           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::multiplies<int>());
10353           ret->copyStringInfoFrom(*a1);
10354         }
10355       else
10356         {
10357           int nbOfCompMin,nbOfCompMax;
10358           const DataArrayInt *aMin, *aMax;
10359           if(nbOfComp>nbOfComp2)
10360             {
10361               nbOfCompMin=nbOfComp2; nbOfCompMax=nbOfComp;
10362               aMin=a2; aMax=a1;
10363             }
10364           else
10365             {
10366               nbOfCompMin=nbOfComp; nbOfCompMax=nbOfComp2;
10367               aMin=a1; aMax=a2;
10368             }
10369           if(nbOfCompMin==1)
10370             {
10371               ret=DataArrayInt::New();
10372               ret->alloc(nbOfTuple,nbOfCompMax);
10373               const int *aMinPtr=aMin->getConstPointer();
10374               const int *aMaxPtr=aMax->getConstPointer();
10375               int *res=ret->getPointer();
10376               for(int i=0;i<nbOfTuple;i++)
10377                 res=std::transform(aMaxPtr+i*nbOfCompMax,aMaxPtr+(i+1)*nbOfCompMax,res,std::bind2nd(std::multiplies<int>(),aMinPtr[i]));
10378               ret->copyStringInfoFrom(*aMax);
10379             }
10380           else
10381             throw INTERP_KERNEL::Exception("Nb of components mismatch for array Multiply !");
10382         }
10383     }
10384   else if((nbOfTuple==1 && nbOfTuple2>1) || (nbOfTuple>1 && nbOfTuple2==1))
10385     {
10386       if(nbOfComp==nbOfComp2)
10387         {
10388           int nbOfTupleMax=std::max(nbOfTuple,nbOfTuple2);
10389           const DataArrayInt *aMin=nbOfTuple>nbOfTuple2?a2:a1;
10390           const DataArrayInt *aMax=nbOfTuple>nbOfTuple2?a1:a2;
10391           const int *aMinPtr=aMin->getConstPointer(),*aMaxPtr=aMax->getConstPointer();
10392           ret=DataArrayInt::New();
10393           ret->alloc(nbOfTupleMax,nbOfComp);
10394           int *res=ret->getPointer();
10395           for(int i=0;i<nbOfTupleMax;i++)
10396             res=std::transform(aMaxPtr+i*nbOfComp,aMaxPtr+(i+1)*nbOfComp,aMinPtr,res,std::multiplies<int>());
10397           ret->copyStringInfoFrom(*aMax);
10398         }
10399       else
10400         throw INTERP_KERNEL::Exception("Nb of components mismatch for array Multiply !");
10401     }
10402   else
10403     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Multiply !");
10404   return ret.retn();
10405 }
10406
10407
10408 /*!
10409  * Multiply values of another DataArrayInt to values of \a this one. There are 3
10410  * valid cases.
10411  * 1.  The arrays have same number of tuples and components. Then each value of
10412  *   \a other array is multiplied to the corresponding value of \a this array, i.e.:
10413  *   _a_ [ i, j ] *= _other_ [ i, j ].
10414  * 2.  The arrays have same number of tuples and \a other array has one component. Then
10415  *   _a_ [ i, j ] *= _other_ [ i, 0 ].
10416  * 3.  The arrays have same number of components and \a other array has one tuple. Then
10417  *   _a_ [ i, j ] *= _a2_ [ 0, j ].
10418  *
10419  *  \param [in] other - an array to multiply to \a this one.
10420  *  \throw If \a other is NULL.
10421  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
10422  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
10423  *         \a other has number of both tuples and components not equal to 1.
10424  */
10425 void DataArrayInt::multiplyEqual(const DataArrayInt *other)
10426 {
10427   if(!other)
10428     throw INTERP_KERNEL::Exception("DataArrayInt::multiplyEqual : input DataArrayInt instance is NULL !");
10429   const char *msg="Nb of tuples mismatch for DataArrayInt::multiplyEqual !";
10430   checkAllocated(); other->checkAllocated();
10431   int nbOfTuple=getNumberOfTuples();
10432   int nbOfTuple2=other->getNumberOfTuples();
10433   int nbOfComp=getNumberOfComponents();
10434   int nbOfComp2=other->getNumberOfComponents();
10435   if(nbOfTuple==nbOfTuple2)
10436     {
10437       if(nbOfComp==nbOfComp2)
10438         {
10439           std::transform(begin(),end(),other->begin(),getPointer(),std::multiplies<int>());
10440         }
10441       else if(nbOfComp2==1)
10442         {
10443           int *ptr=getPointer();
10444           const int *ptrc=other->getConstPointer();
10445           for(int i=0;i<nbOfTuple;i++)
10446             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::multiplies<int>(),*ptrc++));    
10447         }
10448       else
10449         throw INTERP_KERNEL::Exception(msg);
10450     }
10451   else if(nbOfTuple2==1)
10452     {
10453       if(nbOfComp2==nbOfComp)
10454         {
10455           int *ptr=getPointer();
10456           const int *ptrc=other->getConstPointer();
10457           for(int i=0;i<nbOfTuple;i++)
10458             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::multiplies<int>());
10459         }
10460       else
10461         throw INTERP_KERNEL::Exception(msg);
10462     }
10463   else
10464     throw INTERP_KERNEL::Exception(msg);
10465   declareAsNew();
10466 }
10467
10468
10469 /*!
10470  * Returns a new DataArrayInt that is a division of two given arrays. There are 3
10471  * valid cases.
10472  * 1.  The arrays have same number of tuples and components. Then each value of
10473  *   the result array (_a_) is a division of the corresponding values of \a a1 and
10474  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ i, j ].
10475  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
10476  *   component. Then
10477  *   _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ i, 0 ].
10478  * 3.  The arrays have same number of components and one array, say _a2_, has one
10479  *   tuple. Then
10480  *   _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ 0, j ].
10481  *
10482  * Info on components is copied either from the first array (in the first case) or from
10483  * the array with maximal number of elements (getNbOfElems()).
10484  *  \warning No check of division by zero is performed!
10485  *  \param [in] a1 - a numerator array.
10486  *  \param [in] a2 - a denominator array.
10487  *  \return DataArrayInt * - the new instance of DataArrayInt.
10488  *          The caller is to delete this result array using decrRef() as it is no more
10489  *          needed.
10490  *  \throw If either \a a1 or \a a2 is NULL.
10491  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
10492  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
10493  *         none of them has number of tuples or components equal to 1.
10494  */
10495 DataArrayInt *DataArrayInt::Divide(const DataArrayInt *a1, const DataArrayInt *a2)
10496 {
10497   if(!a1 || !a2)
10498     throw INTERP_KERNEL::Exception("DataArrayInt::Divide : input DataArrayInt instance is NULL !");
10499   int nbOfTuple1=a1->getNumberOfTuples();
10500   int nbOfTuple2=a2->getNumberOfTuples();
10501   int nbOfComp1=a1->getNumberOfComponents();
10502   int nbOfComp2=a2->getNumberOfComponents();
10503   if(nbOfTuple2==nbOfTuple1)
10504     {
10505       if(nbOfComp1==nbOfComp2)
10506         {
10507           MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
10508           ret->alloc(nbOfTuple2,nbOfComp1);
10509           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::divides<int>());
10510           ret->copyStringInfoFrom(*a1);
10511           return ret.retn();
10512         }
10513       else if(nbOfComp2==1)
10514         {
10515           MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
10516           ret->alloc(nbOfTuple1,nbOfComp1);
10517           const int *a2Ptr=a2->getConstPointer();
10518           const int *a1Ptr=a1->getConstPointer();
10519           int *res=ret->getPointer();
10520           for(int i=0;i<nbOfTuple1;i++)
10521             res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::divides<int>(),a2Ptr[i]));
10522           ret->copyStringInfoFrom(*a1);
10523           return ret.retn();
10524         }
10525       else
10526         {
10527           a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Divide !");
10528           return 0;
10529         }
10530     }
10531   else if(nbOfTuple2==1)
10532     {
10533       a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Divide !");
10534       MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
10535       ret->alloc(nbOfTuple1,nbOfComp1);
10536       const int *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
10537       int *pt=ret->getPointer();
10538       for(int i=0;i<nbOfTuple1;i++)
10539         pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::divides<int>());
10540       ret->copyStringInfoFrom(*a1);
10541       return ret.retn();
10542     }
10543   else
10544     {
10545       a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Divide !");//will always throw an exception
10546       return 0;
10547     }
10548 }
10549
10550 /*!
10551  * Divide values of \a this array by values of another DataArrayInt. There are 3
10552  * valid cases.
10553  * 1.  The arrays have same number of tuples and components. Then each value of
10554  *    \a this array is divided by the corresponding value of \a other one, i.e.:
10555  *   _a_ [ i, j ] /= _other_ [ i, j ].
10556  * 2.  The arrays have same number of tuples and \a other array has one component. Then
10557  *   _a_ [ i, j ] /= _other_ [ i, 0 ].
10558  * 3.  The arrays have same number of components and \a other array has one tuple. Then
10559  *   _a_ [ i, j ] /= _a2_ [ 0, j ].
10560  *
10561  *  \warning No check of division by zero is performed!
10562  *  \param [in] other - an array to divide \a this one by.
10563  *  \throw If \a other is NULL.
10564  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
10565  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
10566  *         \a other has number of both tuples and components not equal to 1.
10567  */
10568 void DataArrayInt::divideEqual(const DataArrayInt *other)
10569 {
10570   if(!other)
10571     throw INTERP_KERNEL::Exception("DataArrayInt::divideEqual : input DataArrayInt instance is NULL !");
10572   const char *msg="Nb of tuples mismatch for DataArrayInt::divideEqual !";
10573   checkAllocated(); other->checkAllocated();
10574   int nbOfTuple=getNumberOfTuples();
10575   int nbOfTuple2=other->getNumberOfTuples();
10576   int nbOfComp=getNumberOfComponents();
10577   int nbOfComp2=other->getNumberOfComponents();
10578   if(nbOfTuple==nbOfTuple2)
10579     {
10580       if(nbOfComp==nbOfComp2)
10581         {
10582           std::transform(begin(),end(),other->begin(),getPointer(),std::divides<int>());
10583         }
10584       else if(nbOfComp2==1)
10585         {
10586           int *ptr=getPointer();
10587           const int *ptrc=other->getConstPointer();
10588           for(int i=0;i<nbOfTuple;i++)
10589             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::divides<int>(),*ptrc++));
10590         }
10591       else
10592         throw INTERP_KERNEL::Exception(msg);
10593     }
10594   else if(nbOfTuple2==1)
10595     {
10596       if(nbOfComp2==nbOfComp)
10597         {
10598           int *ptr=getPointer();
10599           const int *ptrc=other->getConstPointer();
10600           for(int i=0;i<nbOfTuple;i++)
10601             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::divides<int>());
10602         }
10603       else
10604         throw INTERP_KERNEL::Exception(msg);
10605     }
10606   else
10607     throw INTERP_KERNEL::Exception(msg);
10608   declareAsNew();
10609 }
10610
10611
10612 /*!
10613  * Returns a new DataArrayInt that is a modulus of two given arrays. There are 3
10614  * valid cases.
10615  * 1.  The arrays have same number of tuples and components. Then each value of
10616  *   the result array (_a_) is a division of the corresponding values of \a a1 and
10617  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] % _a2_ [ i, j ].
10618  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
10619  *   component. Then
10620  *   _a_ [ i, j ] = _a1_ [ i, j ] % _a2_ [ i, 0 ].
10621  * 3.  The arrays have same number of components and one array, say _a2_, has one
10622  *   tuple. Then
10623  *   _a_ [ i, j ] = _a1_ [ i, j ] % _a2_ [ 0, j ].
10624  *
10625  * Info on components is copied either from the first array (in the first case) or from
10626  * the array with maximal number of elements (getNbOfElems()).
10627  *  \warning No check of division by zero is performed!
10628  *  \param [in] a1 - a dividend array.
10629  *  \param [in] a2 - a divisor array.
10630  *  \return DataArrayInt * - the new instance of DataArrayInt.
10631  *          The caller is to delete this result array using decrRef() as it is no more
10632  *          needed.
10633  *  \throw If either \a a1 or \a a2 is NULL.
10634  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
10635  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
10636  *         none of them has number of tuples or components equal to 1.
10637  */
10638 DataArrayInt *DataArrayInt::Modulus(const DataArrayInt *a1, const DataArrayInt *a2)
10639 {
10640     if(!a1 || !a2)
10641     throw INTERP_KERNEL::Exception("DataArrayInt::Modulus : input DataArrayInt instance is NULL !");
10642   int nbOfTuple1=a1->getNumberOfTuples();
10643   int nbOfTuple2=a2->getNumberOfTuples();
10644   int nbOfComp1=a1->getNumberOfComponents();
10645   int nbOfComp2=a2->getNumberOfComponents();
10646   if(nbOfTuple2==nbOfTuple1)
10647     {
10648       if(nbOfComp1==nbOfComp2)
10649         {
10650           MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
10651           ret->alloc(nbOfTuple2,nbOfComp1);
10652           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::modulus<int>());
10653           ret->copyStringInfoFrom(*a1);
10654           return ret.retn();
10655         }
10656       else if(nbOfComp2==1)
10657         {
10658           MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
10659           ret->alloc(nbOfTuple1,nbOfComp1);
10660           const int *a2Ptr=a2->getConstPointer();
10661           const int *a1Ptr=a1->getConstPointer();
10662           int *res=ret->getPointer();
10663           for(int i=0;i<nbOfTuple1;i++)
10664             res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::modulus<int>(),a2Ptr[i]));
10665           ret->copyStringInfoFrom(*a1);
10666           return ret.retn();
10667         }
10668       else
10669         {
10670           a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Modulus !");
10671           return 0;
10672         }
10673     }
10674   else if(nbOfTuple2==1)
10675     {
10676       a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Modulus !");
10677       MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
10678       ret->alloc(nbOfTuple1,nbOfComp1);
10679       const int *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
10680       int *pt=ret->getPointer();
10681       for(int i=0;i<nbOfTuple1;i++)
10682         pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::modulus<int>());
10683       ret->copyStringInfoFrom(*a1);
10684       return ret.retn();
10685     }
10686   else
10687     {
10688       a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Modulus !");//will always throw an exception
10689       return 0;
10690     }
10691 }
10692
10693 /*!
10694  * Modify \a this array so that each value becomes a modulus of division of this value by
10695  * a value of another DataArrayInt. There are 3 valid cases.
10696  * 1.  The arrays have same number of tuples and components. Then each value of
10697  *    \a this array is divided by the corresponding value of \a other one, i.e.:
10698  *   _a_ [ i, j ] %= _other_ [ i, j ].
10699  * 2.  The arrays have same number of tuples and \a other array has one component. Then
10700  *   _a_ [ i, j ] %= _other_ [ i, 0 ].
10701  * 3.  The arrays have same number of components and \a other array has one tuple. Then
10702  *   _a_ [ i, j ] %= _a2_ [ 0, j ].
10703  *
10704  *  \warning No check of division by zero is performed!
10705  *  \param [in] other - a divisor array.
10706  *  \throw If \a other is NULL.
10707  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
10708  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
10709  *         \a other has number of both tuples and components not equal to 1.
10710  */
10711 void DataArrayInt::modulusEqual(const DataArrayInt *other)
10712 {
10713   if(!other)
10714     throw INTERP_KERNEL::Exception("DataArrayInt::modulusEqual : input DataArrayInt instance is NULL !");
10715   const char *msg="Nb of tuples mismatch for DataArrayInt::modulusEqual !";
10716   checkAllocated(); other->checkAllocated();
10717   int nbOfTuple=getNumberOfTuples();
10718   int nbOfTuple2=other->getNumberOfTuples();
10719   int nbOfComp=getNumberOfComponents();
10720   int nbOfComp2=other->getNumberOfComponents();
10721   if(nbOfTuple==nbOfTuple2)
10722     {
10723       if(nbOfComp==nbOfComp2)
10724         {
10725           std::transform(begin(),end(),other->begin(),getPointer(),std::modulus<int>());
10726         }
10727       else if(nbOfComp2==1)
10728         {
10729           if(nbOfComp2==nbOfComp)
10730             {
10731               int *ptr=getPointer();
10732               const int *ptrc=other->getConstPointer();
10733               for(int i=0;i<nbOfTuple;i++)
10734                 std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::modulus<int>(),*ptrc++));
10735             }
10736           else
10737             throw INTERP_KERNEL::Exception(msg);
10738         }
10739       else
10740         throw INTERP_KERNEL::Exception(msg);
10741     }
10742   else if(nbOfTuple2==1)
10743     {
10744       int *ptr=getPointer();
10745       const int *ptrc=other->getConstPointer();
10746       for(int i=0;i<nbOfTuple;i++)
10747         std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::modulus<int>());
10748     }
10749   else
10750     throw INTERP_KERNEL::Exception(msg);
10751   declareAsNew();
10752 }
10753
10754 /*!
10755  * Returns a new DataArrayInt that is the result of pow of two given arrays. There are 3
10756  * valid cases.
10757  *
10758  *  \param [in] a1 - an array to pow up.
10759  *  \param [in] a2 - another array to sum up.
10760  *  \return DataArrayInt * - the new instance of DataArrayInt.
10761  *          The caller is to delete this result array using decrRef() as it is no more
10762  *          needed.
10763  *  \throw If either \a a1 or \a a2 is NULL.
10764  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
10765  *  \throw If \a a1->getNumberOfComponents() != 1 or \a a2->getNumberOfComponents() != 1.
10766  *  \throw If there is a negative value in \a a2.
10767  */
10768 DataArrayInt *DataArrayInt::Pow(const DataArrayInt *a1, const DataArrayInt *a2)
10769 {
10770   if(!a1 || !a2)
10771     throw INTERP_KERNEL::Exception("DataArrayInt::Pow : at least one of input instances is null !");
10772   int nbOfTuple=a1->getNumberOfTuples();
10773   int nbOfTuple2=a2->getNumberOfTuples();
10774   int nbOfComp=a1->getNumberOfComponents();
10775   int nbOfComp2=a2->getNumberOfComponents();
10776   if(nbOfTuple!=nbOfTuple2)
10777     throw INTERP_KERNEL::Exception("DataArrayInt::Pow : number of tuples mismatches !");
10778   if(nbOfComp!=1 || nbOfComp2!=1)
10779     throw INTERP_KERNEL::Exception("DataArrayInt::Pow : number of components of both arrays must be equal to 1 !");
10780   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbOfTuple,1);
10781   const int *ptr1(a1->begin()),*ptr2(a2->begin());
10782   int *ptr=ret->getPointer();
10783   for(int i=0;i<nbOfTuple;i++,ptr1++,ptr2++,ptr++)
10784     {
10785       if(*ptr2>=0)
10786         {
10787           int tmp=1;
10788           for(int j=0;j<*ptr2;j++)
10789             tmp*=*ptr1;
10790           *ptr=tmp;
10791         }
10792       else
10793         {
10794           std::ostringstream oss; oss << "DataArrayInt::Pow : on tuple #" << i << " of a2 value is < 0 (" << *ptr2 << ") !";
10795           throw INTERP_KERNEL::Exception(oss.str().c_str());
10796         }
10797     }
10798   return ret.retn();
10799 }
10800
10801 /*!
10802  * Apply pow on values of another DataArrayInt to values of \a this one.
10803  *
10804  *  \param [in] other - an array to pow to \a this one.
10805  *  \throw If \a other is NULL.
10806  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples()
10807  *  \throw If \a this->getNumberOfComponents() != 1 or \a other->getNumberOfComponents() != 1
10808  *  \throw If there is a negative value in \a other.
10809  */
10810 void DataArrayInt::powEqual(const DataArrayInt *other)
10811 {
10812   if(!other)
10813     throw INTERP_KERNEL::Exception("DataArrayInt::powEqual : input instance is null !");
10814   int nbOfTuple=getNumberOfTuples();
10815   int nbOfTuple2=other->getNumberOfTuples();
10816   int nbOfComp=getNumberOfComponents();
10817   int nbOfComp2=other->getNumberOfComponents();
10818   if(nbOfTuple!=nbOfTuple2)
10819     throw INTERP_KERNEL::Exception("DataArrayInt::powEqual : number of tuples mismatches !");
10820   if(nbOfComp!=1 || nbOfComp2!=1)
10821     throw INTERP_KERNEL::Exception("DataArrayInt::powEqual : number of components of both arrays must be equal to 1 !");
10822   int *ptr=getPointer();
10823   const int *ptrc=other->begin();
10824   for(int i=0;i<nbOfTuple;i++,ptrc++,ptr++)
10825     {
10826       if(*ptrc>=0)
10827         {
10828           int tmp=1;
10829           for(int j=0;j<*ptrc;j++)
10830             tmp*=*ptr;
10831           *ptr=tmp;
10832         }
10833       else
10834         {
10835           std::ostringstream oss; oss << "DataArrayInt::powEqual : on tuple #" << i << " of other value is < 0 (" << *ptrc << ") !";
10836           throw INTERP_KERNEL::Exception(oss.str().c_str());
10837         }
10838     }
10839   declareAsNew();
10840 }
10841
10842 /*!
10843  * Returns a C array which is a renumbering map in "Old to New" mode for the input array.
10844  * This map, if applied to \a start array, would make it sorted. For example, if
10845  * \a start array contents are [9,10,0,6,4,11,3,7] then the contents of the result array is
10846  * [5,6,0,3,2,7,1,4].
10847  *  \param [in] start - pointer to the first element of the array for which the
10848  *         permutation map is computed.
10849  *  \param [in] end - pointer specifying the end of the array \a start, so that
10850  *         the last value of \a start is \a end[ -1 ].
10851  *  \return int * - the result permutation array that the caller is to delete as it is no
10852  *         more needed.
10853  *  \throw If there are equal values in the input array.
10854  */
10855 int *DataArrayInt::CheckAndPreparePermutation(const int *start, const int *end)
10856 {
10857   std::size_t sz=std::distance(start,end);
10858   int *ret=(int *)malloc(sz*sizeof(int));
10859   int *work=new int[sz];
10860   std::copy(start,end,work);
10861   std::sort(work,work+sz);
10862   if(std::unique(work,work+sz)!=work+sz)
10863     {
10864       delete [] work;
10865       free(ret);
10866       throw INTERP_KERNEL::Exception("Some elements are equals in the specified array !");
10867     }
10868   std::map<int,int> m;
10869   for(int *workPt=work;workPt!=work+sz;workPt++)
10870     m[*workPt]=(int)std::distance(work,workPt);
10871   int *iter2=ret;
10872   for(const int *iter=start;iter!=end;iter++,iter2++)
10873     *iter2=m[*iter];
10874   delete [] work;
10875   return ret;
10876 }
10877
10878 /*!
10879  * Returns a new DataArrayInt containing an arithmetic progression
10880  * that is equal to the sequence returned by Python \c range(\a begin,\a  end,\a  step )
10881  * function.
10882  *  \param [in] begin - the start value of the result sequence.
10883  *  \param [in] end - limiting value, so that every value of the result array is less than
10884  *              \a end.
10885  *  \param [in] step - specifies the increment or decrement.
10886  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
10887  *          array using decrRef() as it is no more needed.
10888  *  \throw If \a step == 0.
10889  *  \throw If \a end < \a begin && \a step > 0.
10890  *  \throw If \a end > \a begin && \a step < 0.
10891  */
10892 DataArrayInt *DataArrayInt::Range(int begin, int end, int step)
10893 {
10894   int nbOfTuples=GetNumberOfItemGivenBESRelative(begin,end,step,"DataArrayInt::Range");
10895   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
10896   ret->alloc(nbOfTuples,1);
10897   int *ptr=ret->getPointer();
10898   if(step>0)
10899     {
10900       for(int i=begin;i<end;i+=step,ptr++)
10901         *ptr=i;
10902     }
10903   else
10904     {
10905       for(int i=begin;i>end;i+=step,ptr++)
10906         *ptr=i;
10907     }
10908   return ret.retn();
10909 }
10910
10911 /*!
10912  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
10913  * Server side.
10914  */
10915 void DataArrayInt::getTinySerializationIntInformation(std::vector<int>& tinyInfo) const
10916 {
10917   tinyInfo.resize(2);
10918   if(isAllocated())
10919     {
10920       tinyInfo[0]=getNumberOfTuples();
10921       tinyInfo[1]=getNumberOfComponents();
10922     }
10923   else
10924     {
10925       tinyInfo[0]=-1;
10926       tinyInfo[1]=-1;
10927     }
10928 }
10929
10930 /*!
10931  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
10932  * Server side.
10933  */
10934 void DataArrayInt::getTinySerializationStrInformation(std::vector<std::string>& tinyInfo) const
10935 {
10936   if(isAllocated())
10937     {
10938       int nbOfCompo=getNumberOfComponents();
10939       tinyInfo.resize(nbOfCompo+1);
10940       tinyInfo[0]=getName();
10941       for(int i=0;i<nbOfCompo;i++)
10942         tinyInfo[i+1]=getInfoOnComponent(i);
10943     }
10944   else
10945     {
10946       tinyInfo.resize(1);
10947       tinyInfo[0]=getName();
10948     }
10949 }
10950
10951 /*!
10952  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
10953  * This method returns if a feeding is needed.
10954  */
10955 bool DataArrayInt::resizeForUnserialization(const std::vector<int>& tinyInfoI)
10956 {
10957   int nbOfTuple=tinyInfoI[0];
10958   int nbOfComp=tinyInfoI[1];
10959   if(nbOfTuple!=-1 || nbOfComp!=-1)
10960     {
10961       alloc(nbOfTuple,nbOfComp);
10962       return true;
10963     }
10964   return false;
10965 }
10966
10967 /*!
10968  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
10969  * This method returns if a feeding is needed.
10970  */
10971 void DataArrayInt::finishUnserialization(const std::vector<int>& tinyInfoI, const std::vector<std::string>& tinyInfoS)
10972 {
10973   setName(tinyInfoS[0].c_str());
10974   if(isAllocated())
10975     {
10976       int nbOfCompo=tinyInfoI[1];
10977       for(int i=0;i<nbOfCompo;i++)
10978         setInfoOnComponent(i,tinyInfoS[i+1].c_str());
10979     }
10980 }
10981
10982 DataArrayIntIterator::DataArrayIntIterator(DataArrayInt *da):_da(da),_pt(0),_tuple_id(0),_nb_comp(0),_nb_tuple(0)
10983 {
10984   if(_da)
10985     {
10986       _da->incrRef();
10987       if(_da->isAllocated())
10988         {
10989           _nb_comp=da->getNumberOfComponents();
10990           _nb_tuple=da->getNumberOfTuples();
10991           _pt=da->getPointer();
10992         }
10993     }
10994 }
10995
10996 DataArrayIntIterator::~DataArrayIntIterator()
10997 {
10998   if(_da)
10999     _da->decrRef();
11000 }
11001
11002 DataArrayIntTuple *DataArrayIntIterator::nextt()
11003 {
11004   if(_tuple_id<_nb_tuple)
11005     {
11006       _tuple_id++;
11007       DataArrayIntTuple *ret=new DataArrayIntTuple(_pt,_nb_comp);
11008       _pt+=_nb_comp;
11009       return ret;
11010     }
11011   else
11012     return 0;
11013 }
11014
11015 DataArrayIntTuple::DataArrayIntTuple(int *pt, int nbOfComp):_pt(pt),_nb_of_compo(nbOfComp)
11016 {
11017 }
11018
11019 std::string DataArrayIntTuple::repr() const
11020 {
11021   std::ostringstream oss; oss << "(";
11022   for(int i=0;i<_nb_of_compo-1;i++)
11023     oss << _pt[i] << ", ";
11024   oss << _pt[_nb_of_compo-1] << ")";
11025   return oss.str();
11026 }
11027
11028 int DataArrayIntTuple::intValue() const
11029 {
11030   if(_nb_of_compo==1)
11031     return *_pt;
11032   throw INTERP_KERNEL::Exception("DataArrayIntTuple::intValue : DataArrayIntTuple instance has not exactly 1 component -> Not possible to convert it into an integer !");
11033 }
11034
11035 /*!
11036  * This method returns a newly allocated instance the caller should dealed with by a ParaMEDMEM::DataArrayInt::decrRef.
11037  * This method performs \b no copy of data. The content is only referenced using ParaMEDMEM::DataArrayInt::useArray with ownership set to \b false.
11038  * 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
11039  * \b nbOfCompo=1 and \bnbOfTuples==this->_nb_of_elem.
11040  */
11041 DataArrayInt *DataArrayIntTuple::buildDAInt(int nbOfTuples, int nbOfCompo) const
11042 {
11043   if((_nb_of_compo==nbOfCompo && nbOfTuples==1) || (_nb_of_compo==nbOfTuples && nbOfCompo==1))
11044     {
11045       DataArrayInt *ret=DataArrayInt::New();
11046       ret->useExternalArrayWithRWAccess(_pt,nbOfTuples,nbOfCompo);
11047       return ret;
11048     }
11049   else
11050     {
11051       std::ostringstream oss; oss << "DataArrayIntTuple::buildDAInt : unable to build a requested DataArrayInt instance with nbofTuple=" << nbOfTuples << " and nbOfCompo=" << nbOfCompo;
11052       oss << ".\nBecause the number of elements in this is " << _nb_of_compo << " !";
11053       throw INTERP_KERNEL::Exception(oss.str().c_str());
11054     }
11055 }