Salome HOME
Memory leaks hunting
[modules/med.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 "GenMathFormulae.hxx"
25 #include "InterpKernelExprParser.hxx"
26
27 #include <set>
28 #include <cmath>
29 #include <limits>
30 #include <numeric>
31 #include <algorithm>
32 #include <functional>
33
34 typedef double (*MYFUNCPTR)(double);
35
36 using namespace ParaMEDMEM;
37
38 template<int SPACEDIM>
39 void DataArrayDouble::findCommonTuplesAlg(const double *bbox, int nbNodes, int limitNodeId, double prec, DataArrayInt *c, DataArrayInt *cI) const
40 {
41   const double *coordsPtr=getConstPointer();
42   BBTreePts<SPACEDIM,int> myTree(bbox,0,0,nbNodes,prec);
43   std::vector<bool> isDone(nbNodes);
44   for(int i=0;i<nbNodes;i++)
45     {
46       if(!isDone[i])
47         {
48           std::vector<int> intersectingElems;
49           myTree.getElementsAroundPoint(coordsPtr+i*SPACEDIM,intersectingElems);
50           if(intersectingElems.size()>1)
51             {
52               std::vector<int> commonNodes;
53               for(std::vector<int>::const_iterator it=intersectingElems.begin();it!=intersectingElems.end();it++)
54                 if(*it!=i)
55                   if(*it>=limitNodeId)
56                     {
57                       commonNodes.push_back(*it);
58                       isDone[*it]=true;
59                     }
60               if(!commonNodes.empty())
61                 {
62                   cI->pushBackSilent(cI->back()+(int)commonNodes.size()+1);
63                   c->pushBackSilent(i);
64                   c->insertAtTheEnd(commonNodes.begin(),commonNodes.end());
65                 }
66             }
67         }
68     }
69 }
70
71 template<int SPACEDIM>
72 void DataArrayDouble::FindTupleIdsNearTuplesAlg(const BBTreePts<SPACEDIM,int>& myTree, const double *pos, int nbOfTuples, double eps,
73                                                 DataArrayInt *c, DataArrayInt *cI)
74 {
75   for(int i=0;i<nbOfTuples;i++)
76     {
77       std::vector<int> intersectingElems;
78       myTree.getElementsAroundPoint(pos+i*SPACEDIM,intersectingElems);
79       std::vector<int> commonNodes;
80       for(std::vector<int>::const_iterator it=intersectingElems.begin();it!=intersectingElems.end();it++)
81         commonNodes.push_back(*it);
82       cI->pushBackSilent(cI->back()+(int)commonNodes.size());
83       c->insertAtTheEnd(commonNodes.begin(),commonNodes.end());
84     }
85 }
86
87 template<int SPACEDIM>
88 void DataArrayDouble::FindClosestTupleIdAlg(const BBTreePts<SPACEDIM,int>& myTree, double dist, const double *pos, int nbOfTuples, const double *thisPt, int thisNbOfTuples, int *res)
89 {
90   double distOpt(dist);
91   const double *p(pos);
92   int *r(res);
93   for(int i=0;i<nbOfTuples;i++,p+=SPACEDIM,r++)
94     {
95       while(true)
96         {
97           int elem=-1;
98           double ret=myTree.getElementsAroundPoint2(p,distOpt,elem);
99           if(ret!=std::numeric_limits<double>::max())
100             {
101               distOpt=std::max(ret,1e-4);
102               *r=elem;
103               break;
104             }
105           else
106             { distOpt=2*distOpt; continue; }
107         }
108     }
109 }
110
111 std::size_t DataArray::getHeapMemorySize() const
112 {
113   std::size_t sz1=_name.capacity();
114   std::size_t sz2=_info_on_compo.capacity();
115   std::size_t sz3=0;
116   for(std::vector<std::string>::const_iterator it=_info_on_compo.begin();it!=_info_on_compo.end();it++)
117     sz3+=(*it).capacity();
118   return sz1+sz2+sz3;
119 }
120
121 /*!
122  * Sets the attribute \a _name of \a this array.
123  * See \ref MEDCouplingArrayBasicsName "DataArrays infos" for more information.
124  *  \param [in] name - new array name
125  */
126 void DataArray::setName(const char *name)
127 {
128   _name=name;
129 }
130
131 /*!
132  * Copies textual data from an \a other DataArray. The copied data are
133  * - the name attribute,
134  * - the information of components.
135  *
136  * For more information on these data see \ref MEDCouplingArrayBasicsName "DataArrays infos".
137  *
138  *  \param [in] other - another instance of DataArray to copy the textual data from.
139  *  \throw If number of components of \a this array differs from that of the \a other.
140  */
141 void DataArray::copyStringInfoFrom(const DataArray& other) throw(INTERP_KERNEL::Exception)
142 {
143   if(_info_on_compo.size()!=other._info_on_compo.size())
144     throw INTERP_KERNEL::Exception("Size of arrays mismatches on copyStringInfoFrom !");
145   _name=other._name;
146   _info_on_compo=other._info_on_compo;
147 }
148
149 void DataArray::copyPartOfStringInfoFrom(const DataArray& other, const std::vector<int>& compoIds) throw(INTERP_KERNEL::Exception)
150 {
151   int nbOfCompoOth=other.getNumberOfComponents();
152   std::size_t newNbOfCompo=compoIds.size();
153   for(std::size_t i=0;i<newNbOfCompo;i++)
154     if(compoIds[i]>=nbOfCompoOth || compoIds[i]<0)
155       {
156         std::ostringstream oss; oss << "Specified component id is out of range (" << compoIds[i] << ") compared with nb of actual components (" << nbOfCompoOth << ")";
157         throw INTERP_KERNEL::Exception(oss.str().c_str());
158       }
159   for(std::size_t i=0;i<newNbOfCompo;i++)
160     setInfoOnComponent((int)i,other.getInfoOnComponent(compoIds[i]).c_str());
161 }
162
163 void DataArray::copyPartOfStringInfoFrom2(const std::vector<int>& compoIds, const DataArray& other) throw(INTERP_KERNEL::Exception)
164 {
165   int nbOfCompo=getNumberOfComponents();
166   std::size_t partOfCompoToSet=compoIds.size();
167   if((int)partOfCompoToSet!=other.getNumberOfComponents())
168     throw INTERP_KERNEL::Exception("Given compoIds has not the same size as number of components of given array !");
169   for(std::size_t i=0;i<partOfCompoToSet;i++)
170     if(compoIds[i]>=nbOfCompo || compoIds[i]<0)
171       {
172         std::ostringstream oss; oss << "Specified component id is out of range (" << compoIds[i] << ") compared with nb of actual components (" << nbOfCompo << ")";
173         throw INTERP_KERNEL::Exception(oss.str().c_str());
174       }
175   for(std::size_t i=0;i<partOfCompoToSet;i++)
176     setInfoOnComponent(compoIds[i],other.getInfoOnComponent((int)i).c_str());
177 }
178
179 bool DataArray::areInfoEqualsIfNotWhy(const DataArray& other, std::string& reason) const throw(INTERP_KERNEL::Exception)
180 {
181   std::ostringstream oss;
182   if(_name!=other._name)
183     {
184       oss << "Names DataArray mismatch : this name=\"" << _name << " other name=\"" << other._name << "\" !";
185       reason=oss.str();
186       return false;
187     }
188   if(_info_on_compo!=other._info_on_compo)
189     {
190       oss << "Components DataArray mismatch : \nThis components=";
191       for(std::vector<std::string>::const_iterator it=_info_on_compo.begin();it!=_info_on_compo.end();it++)
192         oss << "\"" << *it << "\",";
193       oss << "\nOther components=";
194       for(std::vector<std::string>::const_iterator it=other._info_on_compo.begin();it!=other._info_on_compo.end();it++)
195         oss << "\"" << *it << "\",";
196       reason=oss.str();
197       return false;
198     }
199   return true;
200 }
201
202 /*!
203  * Compares textual information of \a this DataArray with that of an \a other one.
204  * The compared data are
205  * - the name attribute,
206  * - the information of components.
207  *
208  * For more information on these data see \ref MEDCouplingArrayBasicsName "DataArrays infos".
209  *  \param [in] other - another instance of DataArray to compare the textual data of.
210  *  \return bool - \a true if the textual information is same, \a false else.
211  */
212 bool DataArray::areInfoEquals(const DataArray& other) const throw(INTERP_KERNEL::Exception)
213 {
214   std::string tmp;
215   return areInfoEqualsIfNotWhy(other,tmp);
216 }
217
218 void DataArray::reprWithoutNameStream(std::ostream& stream) const throw(INTERP_KERNEL::Exception)
219 {
220   stream << "Number of components : "<< getNumberOfComponents() << "\n";
221   stream << "Info of these components : ";
222   for(std::vector<std::string>::const_iterator iter=_info_on_compo.begin();iter!=_info_on_compo.end();iter++)
223     stream << "\"" << *iter << "\"   ";
224   stream << "\n";
225 }
226
227 std::string DataArray::cppRepr(const char *varName) const throw(INTERP_KERNEL::Exception)
228 {
229   std::ostringstream ret;
230   reprCppStream(varName,ret);
231   return ret.str();
232 }
233
234 /*!
235  * Sets information on all components. To know more on format of this information
236  * see \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
237  *  \param [in] info - a vector of strings.
238  *  \throw If size of \a info differs from the number of components of \a this.
239  */
240 void DataArray::setInfoOnComponents(const std::vector<std::string>& info) throw(INTERP_KERNEL::Exception)
241 {
242   if(getNumberOfComponents()!=(int)info.size())
243     {
244       std::ostringstream oss; oss << "DataArray::setInfoOnComponents : input is of size " << info.size() << " whereas number of components is equal to " << getNumberOfComponents() << " !";
245       throw INTERP_KERNEL::Exception(oss.str().c_str());
246     }
247   _info_on_compo=info;
248 }
249
250 std::vector<std::string> DataArray::getVarsOnComponent() const throw(INTERP_KERNEL::Exception)
251 {
252   int nbOfCompo=(int)_info_on_compo.size();
253   std::vector<std::string> ret(nbOfCompo);
254   for(int i=0;i<nbOfCompo;i++)
255     ret[i]=getVarOnComponent(i);
256   return ret;
257 }
258
259 std::vector<std::string> DataArray::getUnitsOnComponent() const throw(INTERP_KERNEL::Exception)
260 {
261   int nbOfCompo=(int)_info_on_compo.size();
262   std::vector<std::string> ret(nbOfCompo);
263   for(int i=0;i<nbOfCompo;i++)
264     ret[i]=getUnitOnComponent(i);
265   return ret;
266 }
267
268 /*!
269  * Returns information on a component specified by an index.
270  * To know more on format of this information
271  * see \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
272  *  \param [in] i - the index (zero based) of the component of interest.
273  *  \return std::string - a string containing the information on \a i-th component.
274  *  \throw If \a i is not a valid component index.
275  */
276 std::string DataArray::getInfoOnComponent(int i) const throw(INTERP_KERNEL::Exception)
277 {
278   if(i<(int)_info_on_compo.size() && i>=0)
279     return _info_on_compo[i];
280   else
281     {
282       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();
283       throw INTERP_KERNEL::Exception(oss.str().c_str());
284     }
285 }
286
287 /*!
288  * Returns the var part of the full information of the \a i-th component.
289  * For example, if \c getInfoOnComponent(0) returns "SIGXY [N/m^2]", then
290  * \c getVarOnComponent(0) returns "SIGXY".
291  * If a unit part of information is not detected by presence of
292  * two square brackets, then the full information is returned.
293  * To read more about the component information format, see
294  * \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
295  *  \param [in] i - the index (zero based) of the component of interest.
296  *  \return std::string - a string containing the var information, or the full info.
297  *  \throw If \a i is not a valid component index.
298  */
299 std::string DataArray::getVarOnComponent(int i) const throw(INTERP_KERNEL::Exception)
300 {
301   if(i<(int)_info_on_compo.size() && i>=0)
302     {
303       return GetVarNameFromInfo(_info_on_compo[i]);
304     }
305   else
306     {
307       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();
308       throw INTERP_KERNEL::Exception(oss.str().c_str());
309     }
310 }
311
312 /*!
313  * Returns the unit part of the full information of the \a i-th component.
314  * For example, if \c getInfoOnComponent(0) returns "SIGXY [ N/m^2]", then
315  * \c getUnitOnComponent(0) returns " N/m^2".
316  * If a unit part of information is not detected by presence of
317  * two square brackets, then an empty string is returned.
318  * To read more about the component information format, see
319  * \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
320  *  \param [in] i - the index (zero based) of the component of interest.
321  *  \return std::string - a string containing the unit information, if any, or "".
322  *  \throw If \a i is not a valid component index.
323  */
324 std::string DataArray::getUnitOnComponent(int i) const throw(INTERP_KERNEL::Exception)
325 {
326   if(i<(int)_info_on_compo.size() && i>=0)
327     {
328       return GetUnitFromInfo(_info_on_compo[i]);
329     }
330   else
331     {
332       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();
333       throw INTERP_KERNEL::Exception(oss.str().c_str());
334     }
335 }
336
337 /*!
338  * Returns the var part of the full component information.
339  * For example, if \a info == "SIGXY [N/m^2]", then this method returns "SIGXY".
340  * If a unit part of information is not detected by presence of
341  * two square brackets, then the whole \a info is returned.
342  * To read more about the component information format, see
343  * \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
344  *  \param [in] info - the full component information.
345  *  \return std::string - a string containing only var information, or the \a info.
346  */
347 std::string DataArray::GetVarNameFromInfo(const std::string& info) throw(INTERP_KERNEL::Exception)
348 {
349   std::size_t p1=info.find_last_of('[');
350   std::size_t p2=info.find_last_of(']');
351   if(p1==std::string::npos || p2==std::string::npos)
352     return info;
353   if(p1>p2)
354     return info;
355   if(p1==0)
356     return std::string();
357   std::size_t p3=info.find_last_not_of(' ',p1-1);
358   return info.substr(0,p3+1);
359 }
360
361 /*!
362  * Returns the unit part of the full component information.
363  * For example, if \a info == "SIGXY [ N/m^2]", then this method returns " N/m^2".
364  * If a unit part of information is not detected by presence of
365  * two square brackets, then an empty string is returned.
366  * To read more about the component information format, see
367  * \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
368  *  \param [in] info - the full component information.
369  *  \return std::string - a string containing only unit information, if any, or "".
370  */
371 std::string DataArray::GetUnitFromInfo(const std::string& info) throw(INTERP_KERNEL::Exception)
372 {
373   std::size_t p1=info.find_last_of('[');
374   std::size_t p2=info.find_last_of(']');
375   if(p1==std::string::npos || p2==std::string::npos)
376     return std::string();
377   if(p1>p2)
378     return std::string();
379   return info.substr(p1+1,p2-p1-1);
380 }
381
382 /*!
383  * Sets information on a component specified by an index.
384  * To know more on format of this information
385  * see \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
386  *  \warning Don't pass NULL as \a info!
387  *  \param [in] i - the index (zero based) of the component of interest.
388  *  \param [in] info - the string containing the information.
389  *  \throw If \a i is not a valid component index.
390  */
391 void DataArray::setInfoOnComponent(int i, const char *info) throw(INTERP_KERNEL::Exception)
392 {
393   if(i<(int)_info_on_compo.size() && i>=0)
394     _info_on_compo[i]=info;
395   else
396     {
397       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();
398       throw INTERP_KERNEL::Exception(oss.str().c_str());
399     }
400 }
401
402 /*!
403  * Sets information on all components. This method can change number of components
404  * at certain conditions; if the conditions are not respected, an exception is thrown.
405  * The number of components can be changed provided that \a this is not allocated.
406  *
407  * To know more on format of the component information see
408  * \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
409  *  \param [in] info - a vector of component infos.
410  *  \throw If \a this->getNumberOfComponents() != \a info.size() && \a this->isAllocated()
411  */
412 void DataArray::setInfoAndChangeNbOfCompo(const std::vector<std::string>& info) throw(INTERP_KERNEL::Exception)
413 {
414   if(getNumberOfComponents()!=(int)info.size())
415     {
416       if(!isAllocated())
417         _info_on_compo=info;
418       else
419         {
420           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 !";
421           throw INTERP_KERNEL::Exception(oss.str().c_str());
422         }
423     }
424   else
425     _info_on_compo=info;
426 }
427
428 void DataArray::checkNbOfTuples(int nbOfTuples, const char *msg) const throw(INTERP_KERNEL::Exception)
429 {
430   if(getNumberOfTuples()!=nbOfTuples)
431     {
432       std::ostringstream oss; oss << msg << " : mismatch number of tuples : expected " <<  nbOfTuples << " having " << getNumberOfTuples() << " !";
433       throw INTERP_KERNEL::Exception(oss.str().c_str());
434     }
435 }
436
437 void DataArray::checkNbOfComps(int nbOfCompo, const char *msg) const throw(INTERP_KERNEL::Exception)
438 {
439   if(getNumberOfComponents()!=nbOfCompo)
440     {
441       std::ostringstream oss; oss << msg << " : mismatch number of components : expected " << nbOfCompo << " having " << getNumberOfComponents() << " !";
442       throw INTERP_KERNEL::Exception(oss.str().c_str());
443     }
444 }
445
446 void DataArray::checkNbOfElems(std::size_t nbOfElems, const char *msg) const throw(INTERP_KERNEL::Exception)
447 {
448   if(getNbOfElems()!=nbOfElems)
449     {
450       std::ostringstream oss; oss << msg << " : mismatch number of elems : Expected " << nbOfElems << " having " << getNbOfElems() << " !";
451       throw INTERP_KERNEL::Exception(oss.str().c_str());
452     }
453 }
454
455 void DataArray::checkNbOfTuplesAndComp(const DataArray& other, const char *msg) const throw(INTERP_KERNEL::Exception)
456 {
457    if(getNumberOfTuples()!=other.getNumberOfTuples())
458     {
459       std::ostringstream oss; oss << msg << " : mismatch number of tuples : expected " <<  other.getNumberOfTuples() << " having " << getNumberOfTuples() << " !";
460       throw INTERP_KERNEL::Exception(oss.str().c_str());
461     }
462   if(getNumberOfComponents()!=other.getNumberOfComponents())
463     {
464       std::ostringstream oss; oss << msg << " : mismatch number of components : expected " << other.getNumberOfComponents() << " having " << getNumberOfComponents() << " !";
465       throw INTERP_KERNEL::Exception(oss.str().c_str());
466     }
467 }
468
469 void DataArray::checkNbOfTuplesAndComp(int nbOfTuples, int nbOfCompo, const char *msg) const throw(INTERP_KERNEL::Exception)
470 {
471   checkNbOfTuples(nbOfTuples,msg);
472   checkNbOfComps(nbOfCompo,msg);
473 }
474
475 /*!
476  * Simply this method checks that \b value is in [0,\b ref).
477  */
478 void DataArray::CheckValueInRange(int ref, int value, const char *msg) throw(INTERP_KERNEL::Exception)
479 {
480   if(value<0 || value>=ref)
481     {
482       std::ostringstream oss; oss << "DataArray::CheckValueInRange : " << msg  << " ! Expected in range [0," << ref << "[ having " << value << " !";
483       throw INTERP_KERNEL::Exception(oss.str().c_str());
484     }
485 }
486
487 /*!
488  * This method checks that [\b start, \b end) is compliant with ref length \b value.
489  * typicaly start in [0,\b value) and end in [0,\b value). If value==start and start==end, it is supported.
490  */
491 void DataArray::CheckValueInRangeEx(int value, int start, int end, const char *msg) throw(INTERP_KERNEL::Exception)
492 {
493   if(start<0 || start>=value)
494     {
495       if(value!=start || end!=start)
496         {
497           std::ostringstream oss; oss << "DataArray::CheckValueInRangeEx : " << msg  << " ! Expected start " << start << " of input range, in [0," << value << "[ !";
498           throw INTERP_KERNEL::Exception(oss.str().c_str());
499         }
500     }
501   if(end<0 || end>value)
502     {
503       std::ostringstream oss; oss << "DataArray::CheckValueInRangeEx : " << msg  << " ! Expected end " << end << " of input range, in [0," << value << "] !";
504       throw INTERP_KERNEL::Exception(oss.str().c_str());
505     }
506 }
507
508 void DataArray::CheckClosingParInRange(int ref, int value, const char *msg) throw(INTERP_KERNEL::Exception)
509 {
510   if(value<0 || value>ref)
511     {
512       std::ostringstream oss; oss << "DataArray::CheckClosingParInRange : " << msg  << " ! Expected input range in [0," << ref << "] having closing open parenthesis " << value << " !";
513       throw INTERP_KERNEL::Exception(oss.str().c_str());
514     }
515 }
516
517 /*!
518  * 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, 
519  * typically it is a whole slice of tuples of DataArray or cells, nodes of a mesh...
520  *
521  * The input \a sliceId should be an id in [0, \a nbOfSlices) that specifies the slice of work.
522  *
523  * \param [in] start - the start of the input slice of the whole work to perform splitted into slices.
524  * \param [in] stop - the stop of the input slice of the whole work to perform splitted into slices.
525  * \param [in] step - the step (that can be <0) of the input slice of the whole work to perform splitted into slices.
526  * \param [in] sliceId - the slice id considered
527  * \param [in] nbOfSlices - the number of slices (typically the number of cores on which the work is expected to be sliced)
528  * \param [out] startSlice - the start of the slice considered
529  * \param [out] stopSlice - the stop of the slice consided
530  * 
531  * \throw If \a step == 0
532  * \throw If \a nbOfSlices not > 0
533  * \throw If \a sliceId not in [0,nbOfSlices)
534  */
535 void DataArray::GetSlice(int start, int stop, int step, int sliceId, int nbOfSlices, int& startSlice, int& stopSlice) throw(INTERP_KERNEL::Exception)
536 {
537   if(nbOfSlices<=0)
538     {
539       std::ostringstream oss; oss << "DataArray::GetSlice : nbOfSlices (" << nbOfSlices << ") must be > 0 !";
540       throw INTERP_KERNEL::Exception(oss.str().c_str());
541     }
542   if(sliceId<0 || sliceId>=nbOfSlices)
543     {
544       std::ostringstream oss; oss << "DataArray::GetSlice : sliceId (" << nbOfSlices << ") must be in [0 , nbOfSlices (" << nbOfSlices << ") ) !";
545       throw INTERP_KERNEL::Exception(oss.str().c_str());
546     }
547   int nbElems=GetNumberOfItemGivenBESRelative(start,stop,step,"DataArray::GetSlice");
548   int minNbOfElemsPerSlice=nbElems/nbOfSlices;
549   startSlice=start+minNbOfElemsPerSlice*step*sliceId;
550   if(sliceId<nbOfSlices-1)
551     stopSlice=start+minNbOfElemsPerSlice*step*(sliceId+1);
552   else
553     stopSlice=stop;
554 }
555
556 int DataArray::GetNumberOfItemGivenBES(int begin, int end, int step, const char *msg) throw(INTERP_KERNEL::Exception)
557 {
558   if(end<begin)
559     {
560       std::ostringstream oss; oss << msg << " : end before begin !";
561       throw INTERP_KERNEL::Exception(oss.str().c_str());
562     }
563   if(end==begin)
564     return 0;
565   if(step<=0)
566     {
567       std::ostringstream oss; oss << msg << " : invalid step should be > 0 !";
568       throw INTERP_KERNEL::Exception(oss.str().c_str());
569     }
570   return (end-1-begin)/step+1;
571 }
572
573 int DataArray::GetNumberOfItemGivenBESRelative(int begin, int end, int step, const char *msg) throw(INTERP_KERNEL::Exception)
574 {
575   if(step==0)
576     throw INTERP_KERNEL::Exception("DataArray::GetNumberOfItemGivenBES : step=0 is not allowed !");
577   if(end<begin && step>0)
578     {
579       std::ostringstream oss; oss << msg << " : end before begin whereas step is positive !";
580       throw INTERP_KERNEL::Exception(oss.str().c_str());
581     }
582   if(begin<end && step<0)
583     {
584       std::ostringstream oss; oss << msg << " : invalid step should be > 0 !";
585       throw INTERP_KERNEL::Exception(oss.str().c_str());
586     }
587   if(begin!=end)
588     return (std::max(begin,end)-1-std::min(begin,end))/std::abs(step)+1;
589   else
590     return 0;
591 }
592
593 int DataArray::GetPosOfItemGivenBESRelativeNoThrow(int value, int begin, int end, int step) throw(INTERP_KERNEL::Exception)
594 {
595   if(step!=0)
596     {
597       if(step>0)
598         {
599           if(begin<=value && value<end)
600             {
601               if((value-begin)%step==0)
602                 return (value-begin)/step;
603               else
604                 return -1;
605             }
606           else
607             return -1;
608         }
609       else
610         {
611           if(begin>=value && value>end)
612             {
613               if((begin-value)%(-step)==0)
614                 return (begin-value)/(-step);
615               else
616                 return -1;
617             }
618           else
619             return -1;
620         }
621     }
622   else
623     return -1;
624 }
625
626 /*!
627  * Returns a new instance of DataArrayDouble. The caller is to delete this array
628  * using decrRef() as it is no more needed. 
629  */
630 DataArrayDouble *DataArrayDouble::New()
631 {
632   return new DataArrayDouble;
633 }
634
635 /*!
636  * Checks if raw data is allocated. Read more on the raw data
637  * in \ref MEDCouplingArrayBasicsTuplesAndCompo "DataArrays infos" for more information.
638  *  \return bool - \a true if the raw data is allocated, \a false else.
639  */
640 bool DataArrayDouble::isAllocated() const throw(INTERP_KERNEL::Exception)
641 {
642   return getConstPointer()!=0;
643 }
644
645 /*!
646  * Checks if raw data is allocated and throws an exception if it is not the case.
647  *  \throw If the raw data is not allocated.
648  */
649 void DataArrayDouble::checkAllocated() const throw(INTERP_KERNEL::Exception)
650 {
651   if(!isAllocated())
652     throw INTERP_KERNEL::Exception("DataArrayDouble::checkAllocated : Array is defined but not allocated ! Call alloc or setValues method first !");
653 }
654
655 std::size_t DataArrayDouble::getHeapMemorySize() const
656 {
657   std::size_t sz=_mem.getNbOfElemAllocated();
658   sz*=sizeof(double);
659   return DataArray::getHeapMemorySize()+sz;
660 }
661
662 /*!
663  * Returns the only one value in \a this, if and only if number of elements
664  * (nb of tuples * nb of components) is equal to 1, and that \a this is allocated.
665  *  \return double - the sole value stored in \a this array.
666  *  \throw If at least one of conditions stated above is not fulfilled.
667  */
668 double DataArrayDouble::doubleValue() const throw(INTERP_KERNEL::Exception)
669 {
670   if(isAllocated())
671     {
672       if(getNbOfElems()==1)
673         {
674           return *getConstPointer();
675         }
676       else
677         throw INTERP_KERNEL::Exception("DataArrayDouble::doubleValue : DataArrayDouble instance is allocated but number of elements is not equal to 1 !");
678     }
679   else
680     throw INTERP_KERNEL::Exception("DataArrayDouble::doubleValue : DataArrayDouble instance is not allocated !");
681 }
682
683 /*!
684  * Checks the number of tuples.
685  *  \return bool - \a true if getNumberOfTuples() == 0, \a false else.
686  *  \throw If \a this is not allocated.
687  */
688 bool DataArrayDouble::empty() const throw(INTERP_KERNEL::Exception)
689 {
690   checkAllocated();
691   return getNumberOfTuples()==0;
692 }
693
694 /*!
695  * Returns a full copy of \a this. For more info on copying data arrays see
696  * \ref MEDCouplingArrayBasicsCopyDeep.
697  *  \return DataArrayDouble * - a new instance of DataArrayDouble. The caller is to
698  *          delete this array using decrRef() as it is no more needed. 
699  */
700 DataArrayDouble *DataArrayDouble::deepCpy() const throw(INTERP_KERNEL::Exception)
701 {
702   return new DataArrayDouble(*this);
703 }
704
705 /*!
706  * Returns either a \a deep or \a shallow copy of this array. For more info see
707  * \ref MEDCouplingArrayBasicsCopyDeep and \ref MEDCouplingArrayBasicsCopyShallow.
708  *  \param [in] dCpy - if \a true, a deep copy is returned, else, a shallow one.
709  *  \return DataArrayDouble * - either a new instance of DataArrayDouble (if \a dCpy
710  *          == \a true) or \a this instance (if \a dCpy == \a false).
711  */
712 DataArrayDouble *DataArrayDouble::performCpy(bool dCpy) const throw(INTERP_KERNEL::Exception)
713 {
714   if(dCpy)
715     return deepCpy();
716   else
717     {
718       incrRef();
719       return const_cast<DataArrayDouble *>(this);
720     }
721 }
722
723 /*!
724  * Copies all the data from another DataArrayDouble. For more info see
725  * \ref MEDCouplingArrayBasicsCopyDeepAssign.
726  *  \param [in] other - another instance of DataArrayDouble to copy data from.
727  *  \throw If the \a other is not allocated.
728  */
729 void DataArrayDouble::cpyFrom(const DataArrayDouble& other) throw(INTERP_KERNEL::Exception)
730 {
731   other.checkAllocated();
732   int nbOfTuples=other.getNumberOfTuples();
733   int nbOfComp=other.getNumberOfComponents();
734   allocIfNecessary(nbOfTuples,nbOfComp);
735   std::size_t nbOfElems=(std::size_t)nbOfTuples*nbOfComp;
736   double *pt=getPointer();
737   const double *ptI=other.getConstPointer();
738   for(std::size_t i=0;i<nbOfElems;i++)
739     pt[i]=ptI[i];
740   copyStringInfoFrom(other);
741 }
742
743 /*!
744  * This method reserve nbOfElems elements in memory ( nbOfElems*8 bytes ) \b without impacting the number of tuples in \a this.
745  * 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.
746  * If \a this has not already been allocated, number of components is set to one.
747  * This method allows to reduce number of reallocations on invokation of DataArrayDouble::pushBackSilent and DataArrayDouble::pushBackValsSilent on \a this.
748  * 
749  * \sa DataArrayDouble::pack, DataArrayDouble::pushBackSilent, DataArrayDouble::pushBackValsSilent
750  */
751 void DataArrayDouble::reserve(std::size_t nbOfElems) throw(INTERP_KERNEL::Exception)
752 {
753   int nbCompo=getNumberOfComponents();
754   if(nbCompo==1)
755     {
756       _mem.reserve(nbOfElems);
757     }
758   else if(nbCompo==0)
759     {
760       _mem.reserve(nbOfElems);
761       _info_on_compo.resize(1);
762     }
763   else
764     throw INTERP_KERNEL::Exception("DataArrayDouble::reserve : not available for DataArrayDouble with number of components different than 1 !");
765 }
766
767 /*!
768  * 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
769  * of counter. So the caller is expected to call TimeLabel::declareAsNew on \a this at the end of the push session.
770  *
771  * \param [in] val the value to be added in \a this
772  * \throw If \a this has already been allocated with number of components different from one.
773  * \sa DataArrayDouble::pushBackValsSilent
774  */
775 void DataArrayDouble::pushBackSilent(double val) throw(INTERP_KERNEL::Exception)
776 {
777   int nbCompo=getNumberOfComponents();
778   if(nbCompo==1)
779     _mem.pushBack(val);
780   else if(nbCompo==0)
781     {
782       _info_on_compo.resize(1);
783       _mem.pushBack(val);
784     }
785   else
786     throw INTERP_KERNEL::Exception("DataArrayDouble::pushBackSilent : not available for DataArrayDouble with number of components different than 1 !");
787 }
788
789 /*!
790  * 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
791  * of counter. So the caller is expected to call TimeLabel::declareAsNew on \a this at the end of the push session.
792  *
793  *  \param [in] valsBg - an array of values to push at the end of \this.
794  *  \param [in] valsEnd - specifies the end of the array \a valsBg, so that
795  *              the last value of \a valsBg is \a valsEnd[ -1 ].
796  * \throw If \a this has already been allocated with number of components different from one.
797  * \sa DataArrayDouble::pushBackSilent
798  */
799 void DataArrayDouble::pushBackValsSilent(const double *valsBg, const double *valsEnd) throw(INTERP_KERNEL::Exception)
800 {
801   int nbCompo=getNumberOfComponents();
802   if(nbCompo==1)
803     _mem.insertAtTheEnd(valsBg,valsEnd);
804   else if(nbCompo==0)
805     {
806       _info_on_compo.resize(1);
807       _mem.insertAtTheEnd(valsBg,valsEnd);
808     }
809   else
810     throw INTERP_KERNEL::Exception("DataArrayDouble::pushBackValsSilent : not available for DataArrayDouble with number of components different than 1 !");
811 }
812
813 /*!
814  * This method returns silently ( without updating time label in \a this ) the last value, if any and suppress it.
815  * \throw If \a this is already empty.
816  * \throw If \a this has number of components different from one.
817  */
818 double DataArrayDouble::popBackSilent() throw(INTERP_KERNEL::Exception)
819 {
820   if(getNumberOfComponents()==1)
821     return _mem.popBack();
822   else
823     throw INTERP_KERNEL::Exception("DataArrayDouble::popBackSilent : not available for DataArrayDouble with number of components different than 1 !");
824 }
825
826 /*!
827  * 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.
828  *
829  * \sa DataArrayDouble::getHeapMemorySize, DataArrayDouble::reserve
830  */
831 void DataArrayDouble::pack() const throw(INTERP_KERNEL::Exception)
832 {
833   _mem.pack();
834 }
835
836 /*!
837  * Allocates the raw data in memory. If exactly same memory as needed already
838  * allocated, it is not re-allocated.
839  *  \param [in] nbOfTuple - number of tuples of data to allocate.
840  *  \param [in] nbOfCompo - number of components of data to allocate.
841  *  \throw If \a nbOfTuple < 0 or \a nbOfCompo < 0.
842  */
843 void DataArrayDouble::allocIfNecessary(int nbOfTuple, int nbOfCompo) throw(INTERP_KERNEL::Exception)
844 {
845   if(isAllocated())
846     {
847       if(nbOfTuple!=getNumberOfTuples() || nbOfCompo!=getNumberOfComponents())
848         alloc(nbOfTuple,nbOfCompo);
849     }
850   else
851     alloc(nbOfTuple,nbOfCompo);
852 }
853
854 /*!
855  * Allocates the raw data in memory. If the memory was already allocated, then it is
856  * freed and re-allocated. See an example of this method use
857  * \ref MEDCouplingArraySteps1WC "here".
858  *  \param [in] nbOfTuple - number of tuples of data to allocate.
859  *  \param [in] nbOfCompo - number of components of data to allocate.
860  *  \throw If \a nbOfTuple < 0 or \a nbOfCompo < 0.
861  */
862 void DataArrayDouble::alloc(int nbOfTuple, int nbOfCompo) throw(INTERP_KERNEL::Exception)
863 {
864   if(nbOfTuple<0 || nbOfCompo<0)
865     throw INTERP_KERNEL::Exception("DataArrayDouble::alloc : request for negative length of data !");
866   _info_on_compo.resize(nbOfCompo);
867   _mem.alloc(nbOfCompo*(std::size_t)nbOfTuple);
868   declareAsNew();
869 }
870
871 /*!
872  * Assign zero to all values in \a this array. To know more on filling arrays see
873  * \ref MEDCouplingArrayFill.
874  * \throw If \a this is not allocated.
875  */
876 void DataArrayDouble::fillWithZero() throw(INTERP_KERNEL::Exception)
877 {
878   checkAllocated();
879   _mem.fillWithValue(0.);
880   declareAsNew();
881 }
882
883 /*!
884  * Assign \a val to all values in \a this array. To know more on filling arrays see
885  * \ref MEDCouplingArrayFill.
886  *  \param [in] val - the value to fill with.
887  *  \throw If \a this is not allocated.
888  */
889 void DataArrayDouble::fillWithValue(double val) throw(INTERP_KERNEL::Exception)
890 {
891   checkAllocated();
892   _mem.fillWithValue(val);
893   declareAsNew();
894 }
895
896 /*!
897  * Set all values in \a this array so that the i-th element equals to \a init + i
898  * (i starts from zero). To know more on filling arrays see \ref MEDCouplingArrayFill.
899  *  \param [in] init - value to assign to the first element of array.
900  *  \throw If \a this->getNumberOfComponents() != 1
901  *  \throw If \a this is not allocated.
902  */
903 void DataArrayDouble::iota(double init) throw(INTERP_KERNEL::Exception)
904 {
905   checkAllocated();
906   if(getNumberOfComponents()!=1)
907     throw INTERP_KERNEL::Exception("DataArrayDouble::iota : works only for arrays with only one component, you can call 'rearrange' method before !");
908   double *ptr=getPointer();
909   int ntuples=getNumberOfTuples();
910   for(int i=0;i<ntuples;i++)
911     ptr[i]=init+double(i);
912   declareAsNew();
913 }
914
915 /*!
916  * Checks if all values in \a this array are equal to \a val at precision \a eps.
917  *  \param [in] val - value to check equality of array values to.
918  *  \param [in] eps - precision to check the equality.
919  *  \return bool - \a true if all values are in range (_val_ - _eps_; _val_ + _eps_),
920  *                 \a false else.
921  *  \throw If \a this->getNumberOfComponents() != 1
922  *  \throw If \a this is not allocated.
923  */
924 bool DataArrayDouble::isUniform(double val, double eps) const throw(INTERP_KERNEL::Exception)
925 {
926   checkAllocated();
927   if(getNumberOfComponents()!=1)
928     throw INTERP_KERNEL::Exception("DataArrayDouble::isUniform : must be applied on DataArrayDouble with only one component, you can call 'rearrange' method before !");
929   int nbOfTuples=getNumberOfTuples();
930   const double *w=getConstPointer();
931   const double *end2=w+nbOfTuples;
932   const double vmin=val-eps;
933   const double vmax=val+eps;
934   for(;w!=end2;w++)
935     if(*w<vmin || *w>vmax)
936       return false;
937   return true;
938 }
939
940 /*!
941  * Sorts values of the array.
942  *  \param [in] asc - \a true means ascending order, \a false, descending.
943  *  \throw If \a this is not allocated.
944  *  \throw If \a this->getNumberOfComponents() != 1.
945  */
946 void DataArrayDouble::sort(bool asc) throw(INTERP_KERNEL::Exception)
947 {
948   checkAllocated();
949   if(getNumberOfComponents()!=1)
950     throw INTERP_KERNEL::Exception("DataArrayDouble::sort : only supported with 'this' array with ONE component !");
951   _mem.sort(asc);
952   declareAsNew();
953 }
954
955 /*!
956  * Reverse the array values.
957  *  \throw If \a this->getNumberOfComponents() < 1.
958  *  \throw If \a this is not allocated.
959  */
960 void DataArrayDouble::reverse() throw(INTERP_KERNEL::Exception)
961 {
962   checkAllocated();
963   _mem.reverse(getNumberOfComponents());
964   declareAsNew();
965 }
966
967 /*!
968  * Checks that \a this array is consistently **increasing** or **decreasing** in value,
969  * with at least absolute difference value of |\a eps| at each step.
970  * If not an exception is thrown.
971  *  \param [in] increasing - if \a true, the array values should be increasing.
972  *  \param [in] eps - minimal absolute difference between the neighbor values at which 
973  *                    the values are considered different.
974  *  \throw If sequence of values is not strictly monotonic in agreement with \a
975  *         increasing arg.
976  *  \throw If \a this->getNumberOfComponents() != 1.
977  *  \throw If \a this is not allocated.
978  */
979 void DataArrayDouble::checkMonotonic(bool increasing, double eps) const throw(INTERP_KERNEL::Exception)
980 {
981   if(!isMonotonic(increasing,eps))
982     {
983       if (increasing)
984         throw INTERP_KERNEL::Exception("DataArrayDouble::checkMonotonic : 'this' is not INCREASING monotonic !");
985       else
986         throw INTERP_KERNEL::Exception("DataArrayDouble::checkMonotonic : 'this' is not DECREASING monotonic !");
987     }
988 }
989
990 /*!
991  * Checks that \a this array is consistently **increasing** or **decreasing** in value,
992  * with at least absolute difference value of |\a eps| at each step.
993  *  \param [in] increasing - if \a true, array values should be increasing.
994  *  \param [in] eps - minimal absolute difference between the neighbor values at which 
995  *                    the values are considered different.
996  *  \return bool - \a true if values change in accordance with \a increasing arg.
997  *  \throw If \a this->getNumberOfComponents() != 1.
998  *  \throw If \a this is not allocated.
999  */
1000 bool DataArrayDouble::isMonotonic(bool increasing, double eps) const throw(INTERP_KERNEL::Exception)
1001 {
1002   checkAllocated();
1003   if(getNumberOfComponents()!=1)
1004     throw INTERP_KERNEL::Exception("DataArrayDouble::isMonotonic : only supported with 'this' array with ONE component !");
1005   int nbOfElements=getNumberOfTuples();
1006   const double *ptr=getConstPointer();
1007   if(nbOfElements==0)
1008     return true;
1009   double ref=ptr[0];
1010   double absEps=fabs(eps);
1011   if(increasing)
1012     {
1013       for(int i=1;i<nbOfElements;i++)
1014         {
1015           if(ptr[i]<(ref+absEps))
1016             return false;
1017           ref=ptr[i];
1018         }
1019       return true;
1020     }
1021   else
1022     {
1023       for(int i=1;i<nbOfElements;i++)
1024         {
1025           if(ptr[i]>(ref-absEps))
1026             return false;
1027           ref=ptr[i];
1028         }
1029       return true;
1030     }
1031 }
1032
1033 /*!
1034  * Returns a textual and human readable representation of \a this instance of
1035  * DataArrayDouble. This text is shown when a DataArrayDouble is printed in Python.
1036  *  \return std::string - text describing \a this DataArrayDouble.
1037  */
1038 std::string DataArrayDouble::repr() const throw(INTERP_KERNEL::Exception)
1039 {
1040   std::ostringstream ret;
1041   reprStream(ret);
1042   return ret.str();
1043 }
1044
1045 std::string DataArrayDouble::reprZip() const throw(INTERP_KERNEL::Exception)
1046 {
1047   std::ostringstream ret;
1048   reprZipStream(ret);
1049   return ret.str();
1050 }
1051
1052 void DataArrayDouble::writeVTK(std::ostream& ofs, int indent, const char *nameInFile) const throw(INTERP_KERNEL::Exception)
1053 {
1054   std::string idt(indent,' ');
1055   ofs.precision(17);
1056   ofs << idt << "<DataArray type=\"Float32\" Name=\"" << nameInFile << "\" NumberOfComponents=\"" << getNumberOfComponents() << "\"";
1057   ofs << " format=\"ascii\" RangeMin=\"" << getMinValueInArray() << "\" RangeMax=\"" << getMaxValueInArray() << "\">\n" << idt;
1058   std::copy(begin(),end(),std::ostream_iterator<double>(ofs," "));
1059   ofs << std::endl << idt << "</DataArray>\n";
1060 }
1061
1062 void DataArrayDouble::reprStream(std::ostream& stream) const throw(INTERP_KERNEL::Exception)
1063 {
1064   stream << "Name of double array : \"" << _name << "\"\n";
1065   reprWithoutNameStream(stream);
1066 }
1067
1068 void DataArrayDouble::reprZipStream(std::ostream& stream) const throw(INTERP_KERNEL::Exception)
1069 {
1070   stream << "Name of double array : \"" << _name << "\"\n";
1071   reprZipWithoutNameStream(stream);
1072 }
1073
1074 void DataArrayDouble::reprWithoutNameStream(std::ostream& stream) const throw(INTERP_KERNEL::Exception)
1075 {
1076   DataArray::reprWithoutNameStream(stream);
1077   stream.precision(17);
1078   _mem.repr(getNumberOfComponents(),stream);
1079 }
1080
1081 void DataArrayDouble::reprZipWithoutNameStream(std::ostream& stream) const throw(INTERP_KERNEL::Exception)
1082 {
1083   DataArray::reprWithoutNameStream(stream);
1084   stream.precision(17);
1085   _mem.reprZip(getNumberOfComponents(),stream);
1086 }
1087
1088 void DataArrayDouble::reprCppStream(const char *varName, std::ostream& stream) const throw(INTERP_KERNEL::Exception)
1089 {
1090   int nbTuples=getNumberOfTuples(),nbComp=getNumberOfComponents();
1091   const double *data=getConstPointer();
1092   stream.precision(17);
1093   stream << "DataArrayDouble *" << varName << "=DataArrayDouble::New();" << std::endl;
1094   if(nbTuples*nbComp>=1)
1095     {
1096       stream << "const double " << varName << "Data[" << nbTuples*nbComp << "]={";
1097       std::copy(data,data+nbTuples*nbComp-1,std::ostream_iterator<double>(stream,","));
1098       stream << data[nbTuples*nbComp-1] << "};" << std::endl;
1099       stream << varName << "->useArray(" << varName << "Data,false,CPP_DEALLOC," << nbTuples << "," << nbComp << ");" << std::endl;
1100     }
1101   else
1102     stream << varName << "->alloc(" << nbTuples << "," << nbComp << ");" << std::endl;
1103   stream << varName << "->setName(\"" << getName() << "\");" << std::endl;
1104 }
1105
1106 /*!
1107  * Method that gives a quick overvien of \a this for python.
1108  */
1109 void DataArrayDouble::reprQuickOverview(std::ostream& stream) const throw(INTERP_KERNEL::Exception)
1110 {
1111   static const std::size_t MAX_NB_OF_BYTE_IN_REPR=300;
1112   stream << "DataArrayDouble C++ instance at " << this << ". ";
1113   if(isAllocated())
1114     {
1115       int nbOfCompo=(int)_info_on_compo.size();
1116       if(nbOfCompo>=1)
1117         {
1118           int nbOfTuples=getNumberOfTuples();
1119           stream << "Number of tuples : " << nbOfTuples << ". Number of components : " << nbOfCompo << "." << std::endl;
1120           reprQuickOverviewData(stream,MAX_NB_OF_BYTE_IN_REPR);
1121         }
1122       else
1123         stream << "Number of components : 0.";
1124     }
1125   else
1126     stream << "*** No data allocated ****";
1127 }
1128
1129 void DataArrayDouble::reprQuickOverviewData(std::ostream& stream, std::size_t maxNbOfByteInRepr) const throw(INTERP_KERNEL::Exception)
1130 {
1131   const double *data=begin();
1132   int nbOfTuples=getNumberOfTuples();
1133   int nbOfCompo=(int)_info_on_compo.size();
1134   std::ostringstream oss2; oss2 << "[";
1135   oss2.precision(17);
1136   std::string oss2Str(oss2.str());
1137   bool isFinished=true;
1138   for(int i=0;i<nbOfTuples && isFinished;i++)
1139     {
1140       if(nbOfCompo>1)
1141         {
1142           oss2 << "(";
1143           for(int j=0;j<nbOfCompo;j++,data++)
1144             {
1145               oss2 << *data;
1146               if(j!=nbOfCompo-1) oss2 << ", ";
1147             }
1148           oss2 << ")";
1149         }
1150       else
1151         oss2 << *data++;
1152       if(i!=nbOfTuples-1) oss2 << ", ";
1153       std::string oss3Str(oss2.str());
1154       if(oss3Str.length()<maxNbOfByteInRepr)
1155         oss2Str=oss3Str;
1156       else
1157         isFinished=false;
1158     }
1159   stream << oss2Str;
1160   if(!isFinished)
1161     stream << "... ";
1162   stream << "]";
1163 }
1164
1165 /*!
1166  * Equivalent to DataArrayDouble::isEqual except that if false the reason of
1167  * mismatch is given.
1168  * 
1169  * \param [in] other the instance to be compared with \a this
1170  * \param [in] prec the precision to compare numeric data of the arrays.
1171  * \param [out] reason In case of inequality returns the reason.
1172  * \sa DataArrayDouble::isEqual
1173  */
1174 bool DataArrayDouble::isEqualIfNotWhy(const DataArrayDouble& other, double prec, std::string& reason) const throw(INTERP_KERNEL::Exception)
1175 {
1176   if(!areInfoEqualsIfNotWhy(other,reason))
1177     return false;
1178   return _mem.isEqual(other._mem,prec,reason);
1179 }
1180
1181 /*!
1182  * Checks if \a this and another DataArrayDouble are fully equal. For more info see
1183  * \ref MEDCouplingArrayBasicsCompare.
1184  *  \param [in] other - an instance of DataArrayDouble to compare with \a this one.
1185  *  \param [in] prec - precision value to compare numeric data of the arrays.
1186  *  \return bool - \a true if the two arrays are equal, \a false else.
1187  */
1188 bool DataArrayDouble::isEqual(const DataArrayDouble& other, double prec) const throw(INTERP_KERNEL::Exception)
1189 {
1190   std::string tmp;
1191   return isEqualIfNotWhy(other,prec,tmp);
1192 }
1193
1194 /*!
1195  * Checks if values of \a this and another DataArrayDouble are equal. For more info see
1196  * \ref MEDCouplingArrayBasicsCompare.
1197  *  \param [in] other - an instance of DataArrayDouble to compare with \a this one.
1198  *  \param [in] prec - precision value to compare numeric data of the arrays.
1199  *  \return bool - \a true if the values of two arrays are equal, \a false else.
1200  */
1201 bool DataArrayDouble::isEqualWithoutConsideringStr(const DataArrayDouble& other, double prec) const throw(INTERP_KERNEL::Exception)
1202 {
1203   std::string tmp;
1204   return _mem.isEqual(other._mem,prec,tmp);
1205 }
1206
1207 /*!
1208  * Changes number of tuples in the array. If the new number of tuples is smaller
1209  * than the current number the array is truncated, otherwise the array is extended.
1210  *  \param [in] nbOfTuples - new number of tuples. 
1211  *  \throw If \a this is not allocated.
1212  */
1213 void DataArrayDouble::reAlloc(int nbOfTuples) throw(INTERP_KERNEL::Exception)
1214 {
1215   checkAllocated();
1216   _mem.reAlloc(getNumberOfComponents()*(std::size_t)nbOfTuples);
1217   declareAsNew();
1218 }
1219
1220 /*!
1221  * Creates a new DataArrayInt and assigns all (textual and numerical) data of \a this
1222  * array to the new one.
1223  *  \return DataArrayInt * - the new instance of DataArrayInt.
1224  */
1225 DataArrayInt *DataArrayDouble::convertToIntArr() const
1226 {
1227   DataArrayInt *ret=DataArrayInt::New();
1228   ret->alloc(getNumberOfTuples(),getNumberOfComponents());
1229   std::size_t nbOfVals=getNbOfElems();
1230   const double *src=getConstPointer();
1231   int *dest=ret->getPointer();
1232   std::copy(src,src+nbOfVals,dest);
1233   ret->copyStringInfoFrom(*this);
1234   return ret;
1235 }
1236
1237 /*!
1238  * Returns a new DataArrayDouble holding the same values as \a this array but differently
1239  * arranged in memory. If \a this array holds 2 components of 3 values:
1240  * \f$ x_0,x_1,x_2,y_0,y_1,y_2 \f$, then the result array holds these values arranged
1241  * as follows: \f$ x_0,y_0,x_1,y_1,x_2,y_2 \f$.
1242  *  \warning Do not confuse this method with transpose()!
1243  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1244  *          is to delete using decrRef() as it is no more needed.
1245  *  \throw If \a this is not allocated.
1246  */
1247 DataArrayDouble *DataArrayDouble::fromNoInterlace() const throw(INTERP_KERNEL::Exception)
1248 {
1249   if(_mem.isNull())
1250     throw INTERP_KERNEL::Exception("DataArrayDouble::fromNoInterlace : Not defined array !");
1251   double *tab=_mem.fromNoInterlace(getNumberOfComponents());
1252   DataArrayDouble *ret=DataArrayDouble::New();
1253   ret->useArray(tab,true,C_DEALLOC,getNumberOfTuples(),getNumberOfComponents());
1254   return ret;
1255 }
1256
1257 /*!
1258  * Returns a new DataArrayDouble holding the same values as \a this array but differently
1259  * arranged in memory. If \a this array holds 2 components of 3 values:
1260  * \f$ x_0,y_0,x_1,y_1,x_2,y_2 \f$, then the result array holds these values arranged
1261  * as follows: \f$ x_0,x_1,x_2,y_0,y_1,y_2 \f$.
1262  *  \warning Do not confuse this method with transpose()!
1263  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1264  *          is to delete using decrRef() as it is no more needed.
1265  *  \throw If \a this is not allocated.
1266  */
1267 DataArrayDouble *DataArrayDouble::toNoInterlace() const throw(INTERP_KERNEL::Exception)
1268 {
1269   if(_mem.isNull())
1270     throw INTERP_KERNEL::Exception("DataArrayDouble::toNoInterlace : Not defined array !");
1271   double *tab=_mem.toNoInterlace(getNumberOfComponents());
1272   DataArrayDouble *ret=DataArrayDouble::New();
1273   ret->useArray(tab,true,C_DEALLOC,getNumberOfTuples(),getNumberOfComponents());
1274   return ret;
1275 }
1276
1277 /*!
1278  * Permutes values of \a this array as required by \a old2New array. The values are
1279  * permuted so that \c new[ \a old2New[ i ]] = \c old[ i ]. Number of tuples remains
1280  * the same as in \this one.
1281  * If a permutation reduction is needed, substr() or selectByTupleId() should be used.
1282  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
1283  *  \param [in] old2New - C array of length equal to \a this->getNumberOfTuples()
1284  *     giving a new position for i-th old value.
1285  */
1286 void DataArrayDouble::renumberInPlace(const int *old2New) throw(INTERP_KERNEL::Exception)
1287 {
1288   checkAllocated();
1289   int nbTuples=getNumberOfTuples();
1290   int nbOfCompo=getNumberOfComponents();
1291   double *tmp=new double[nbTuples*nbOfCompo];
1292   const double *iptr=getConstPointer();
1293   for(int i=0;i<nbTuples;i++)
1294     {
1295       int v=old2New[i];
1296       if(v>=0 && v<nbTuples)
1297         std::copy(iptr+nbOfCompo*i,iptr+nbOfCompo*(i+1),tmp+nbOfCompo*v);
1298       else
1299         {
1300           std::ostringstream oss; oss << "DataArrayDouble::renumberInPlace : At place #" << i << " value is " << v << " ! Should be in [0," << nbTuples << ") !";
1301           throw INTERP_KERNEL::Exception(oss.str().c_str());
1302         }
1303     }
1304   std::copy(tmp,tmp+nbTuples*nbOfCompo,getPointer());
1305   delete [] tmp;
1306   declareAsNew();
1307 }
1308
1309 /*!
1310  * Permutes values of \a this array as required by \a new2Old array. The values are
1311  * permuted so that \c new[ i ] = \c old[ \a new2Old[ i ]]. Number of tuples remains
1312  * the same as in \this one.
1313  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
1314  *  \param [in] new2Old - C array of length equal to \a this->getNumberOfTuples()
1315  *     giving a previous position of i-th new value.
1316  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1317  *          is to delete using decrRef() as it is no more needed.
1318  */
1319 void DataArrayDouble::renumberInPlaceR(const int *new2Old) throw(INTERP_KERNEL::Exception)
1320 {
1321   checkAllocated();
1322   int nbTuples=getNumberOfTuples();
1323   int nbOfCompo=getNumberOfComponents();
1324   double *tmp=new double[nbTuples*nbOfCompo];
1325   const double *iptr=getConstPointer();
1326   for(int i=0;i<nbTuples;i++)
1327     {
1328       int v=new2Old[i];
1329       if(v>=0 && v<nbTuples)
1330         std::copy(iptr+nbOfCompo*v,iptr+nbOfCompo*(v+1),tmp+nbOfCompo*i);
1331       else
1332         {
1333           std::ostringstream oss; oss << "DataArrayDouble::renumberInPlaceR : At place #" << i << " value is " << v << " ! Should be in [0," << nbTuples << ") !";
1334           throw INTERP_KERNEL::Exception(oss.str().c_str());
1335         }
1336     }
1337   std::copy(tmp,tmp+nbTuples*nbOfCompo,getPointer());
1338   delete [] tmp;
1339   declareAsNew();
1340 }
1341
1342 /*!
1343  * Returns a copy of \a this array with values permuted as required by \a old2New array.
1344  * The values are permuted so that  \c new[ \a old2New[ i ]] = \c old[ i ].
1345  * Number of tuples in the result array remains the same as in \this one.
1346  * If a permutation reduction is needed, renumberAndReduce() should be used.
1347  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
1348  *  \param [in] old2New - C array of length equal to \a this->getNumberOfTuples()
1349  *          giving a new position for i-th old value.
1350  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1351  *          is to delete using decrRef() as it is no more needed.
1352  *  \throw If \a this is not allocated.
1353  */
1354 DataArrayDouble *DataArrayDouble::renumber(const int *old2New) const throw(INTERP_KERNEL::Exception)
1355 {
1356   checkAllocated();
1357   int nbTuples=getNumberOfTuples();
1358   int nbOfCompo=getNumberOfComponents();
1359   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
1360   ret->alloc(nbTuples,nbOfCompo);
1361   ret->copyStringInfoFrom(*this);
1362   const double *iptr=getConstPointer();
1363   double *optr=ret->getPointer();
1364   for(int i=0;i<nbTuples;i++)
1365     std::copy(iptr+nbOfCompo*i,iptr+nbOfCompo*(i+1),optr+nbOfCompo*old2New[i]);
1366   ret->copyStringInfoFrom(*this);
1367   return ret.retn();
1368 }
1369
1370 /*!
1371  * Returns a copy of \a this array with values permuted as required by \a new2Old array.
1372  * The values are permuted so that  \c new[ i ] = \c old[ \a new2Old[ i ]]. Number of
1373  * tuples in the result array remains the same as in \this one.
1374  * If a permutation reduction is needed, substr() or selectByTupleId() should be used.
1375  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
1376  *  \param [in] new2Old - C array of length equal to \a this->getNumberOfTuples()
1377  *     giving a previous position of i-th new value.
1378  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1379  *          is to delete using decrRef() as it is no more needed.
1380  */
1381 DataArrayDouble *DataArrayDouble::renumberR(const int *new2Old) const throw(INTERP_KERNEL::Exception)
1382 {
1383   checkAllocated();
1384   int nbTuples=getNumberOfTuples();
1385   int nbOfCompo=getNumberOfComponents();
1386   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
1387   ret->alloc(nbTuples,nbOfCompo);
1388   ret->copyStringInfoFrom(*this);
1389   const double *iptr=getConstPointer();
1390   double *optr=ret->getPointer();
1391   for(int i=0;i<nbTuples;i++)
1392     std::copy(iptr+nbOfCompo*new2Old[i],iptr+nbOfCompo*(new2Old[i]+1),optr+i*nbOfCompo);
1393   ret->copyStringInfoFrom(*this);
1394   return ret.retn();
1395 }
1396
1397 /*!
1398  * Returns a shorten and permuted copy of \a this array. The new DataArrayDouble is
1399  * of size \a newNbOfTuple and it's values are permuted as required by \a old2New array.
1400  * The values are permuted so that  \c new[ \a old2New[ i ]] = \c old[ i ] for all
1401  * \a old2New[ i ] >= 0. In other words every i-th tuple in \a this array, for which 
1402  * \a old2New[ i ] is negative, is missing from the result array.
1403  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
1404  *  \param [in] old2New - C array of length equal to \a this->getNumberOfTuples()
1405  *     giving a new position for i-th old tuple and giving negative position for
1406  *     for i-th old tuple that should be omitted.
1407  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1408  *          is to delete using decrRef() as it is no more needed.
1409  */
1410 DataArrayDouble *DataArrayDouble::renumberAndReduce(const int *old2New, int newNbOfTuple) const throw(INTERP_KERNEL::Exception)
1411 {
1412   checkAllocated();
1413   int nbTuples=getNumberOfTuples();
1414   int nbOfCompo=getNumberOfComponents();
1415   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
1416   ret->alloc(newNbOfTuple,nbOfCompo);
1417   const double *iptr=getConstPointer();
1418   double *optr=ret->getPointer();
1419   for(int i=0;i<nbTuples;i++)
1420     {
1421       int w=old2New[i];
1422       if(w>=0)
1423         std::copy(iptr+i*nbOfCompo,iptr+(i+1)*nbOfCompo,optr+w*nbOfCompo);
1424     }
1425   ret->copyStringInfoFrom(*this);
1426   return ret.retn();
1427 }
1428
1429 /*!
1430  * Returns a shorten and permuted copy of \a this array. The new DataArrayDouble is
1431  * of size \a new2OldEnd - \a new2OldBg and it's values are permuted as required by
1432  * \a new2OldBg array.
1433  * The values are permuted so that  \c new[ i ] = \c old[ \a new2OldBg[ i ]].
1434  * This method is equivalent to renumberAndReduce() except that convention in input is
1435  * \c new2old and \b not \c old2new.
1436  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
1437  *  \param [in] new2OldBg - pointer to the beginning of a permutation array that gives a
1438  *              tuple index in \a this array to fill the i-th tuple in the new array.
1439  *  \param [in] new2OldEnd - specifies the end of the permutation array that starts at
1440  *              \a new2OldBg, so that pointer to a tuple index (\a pi) varies as this:
1441  *              \a new2OldBg <= \a pi < \a new2OldEnd.
1442  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1443  *          is to delete using decrRef() as it is no more needed.
1444  */
1445 DataArrayDouble *DataArrayDouble::selectByTupleId(const int *new2OldBg, const int *new2OldEnd) const
1446 {
1447   checkAllocated();
1448   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
1449   int nbComp=getNumberOfComponents();
1450   ret->alloc((int)std::distance(new2OldBg,new2OldEnd),nbComp);
1451   ret->copyStringInfoFrom(*this);
1452   double *pt=ret->getPointer();
1453   const double *srcPt=getConstPointer();
1454   int i=0;
1455   for(const int *w=new2OldBg;w!=new2OldEnd;w++,i++)
1456     std::copy(srcPt+(*w)*nbComp,srcPt+((*w)+1)*nbComp,pt+i*nbComp);
1457   ret->copyStringInfoFrom(*this);
1458   return ret.retn();
1459 }
1460
1461 /*!
1462  * Returns a shorten and permuted copy of \a this array. The new DataArrayDouble is
1463  * of size \a new2OldEnd - \a new2OldBg and it's values are permuted as required by
1464  * \a new2OldBg array.
1465  * The values are permuted so that  \c new[ i ] = \c old[ \a new2OldBg[ i ]].
1466  * This method is equivalent to renumberAndReduce() except that convention in input is
1467  * \c new2old and \b not \c old2new.
1468  * This method is equivalent to selectByTupleId() except that it prevents coping data
1469  * from behind the end of \a this array.
1470  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
1471  *  \param [in] new2OldBg - pointer to the beginning of a permutation array that gives a
1472  *              tuple index in \a this array to fill the i-th tuple in the new array.
1473  *  \param [in] new2OldEnd - specifies the end of the permutation array that starts at
1474  *              \a new2OldBg, so that pointer to a tuple index (\a pi) varies as this:
1475  *              \a new2OldBg <= \a pi < \a new2OldEnd.
1476  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1477  *          is to delete using decrRef() as it is no more needed.
1478  *  \throw If \a new2OldEnd - \a new2OldBg > \a this->getNumberOfTuples().
1479  */
1480 DataArrayDouble *DataArrayDouble::selectByTupleIdSafe(const int *new2OldBg, const int *new2OldEnd) const throw(INTERP_KERNEL::Exception)
1481 {
1482   checkAllocated();
1483   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
1484   int nbComp=getNumberOfComponents();
1485   int oldNbOfTuples=getNumberOfTuples();
1486   ret->alloc((int)std::distance(new2OldBg,new2OldEnd),nbComp);
1487   ret->copyStringInfoFrom(*this);
1488   double *pt=ret->getPointer();
1489   const double *srcPt=getConstPointer();
1490   int i=0;
1491   for(const int *w=new2OldBg;w!=new2OldEnd;w++,i++)
1492     if(*w>=0 && *w<oldNbOfTuples)
1493       std::copy(srcPt+(*w)*nbComp,srcPt+((*w)+1)*nbComp,pt+i*nbComp);
1494     else
1495       throw INTERP_KERNEL::Exception("DataArrayDouble::selectByTupleIdSafe : some ids has been detected to be out of [0,this->getNumberOfTuples) !");
1496   ret->copyStringInfoFrom(*this);
1497   return ret.retn();
1498 }
1499
1500 /*!
1501  * Returns a shorten copy of \a this array. The new DataArrayDouble contains every
1502  * (\a bg + \c i * \a step)-th tuple of \a this array located before the \a end2-th
1503  * tuple. Indices of the selected tuples are the same as ones returned by the Python
1504  * command \c range( \a bg, \a end2, \a step ).
1505  * This method is equivalent to selectByTupleIdSafe() except that the input array is
1506  * not constructed explicitly.
1507  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
1508  *  \param [in] bg - index of the first tuple to copy from \a this array.
1509  *  \param [in] end2 - index of the tuple before which the tuples to copy are located.
1510  *  \param [in] step - index increment to get index of the next tuple to copy.
1511  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1512  *          is to delete using decrRef() as it is no more needed.
1513  *  \sa DataArrayDouble::substr.
1514  */
1515 DataArrayDouble *DataArrayDouble::selectByTupleId2(int bg, int end2, int step) const throw(INTERP_KERNEL::Exception)
1516 {
1517   checkAllocated();
1518   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
1519   int nbComp=getNumberOfComponents();
1520   int newNbOfTuples=GetNumberOfItemGivenBESRelative(bg,end2,step,"DataArrayDouble::selectByTupleId2 : ");
1521   ret->alloc(newNbOfTuples,nbComp);
1522   double *pt=ret->getPointer();
1523   const double *srcPt=getConstPointer()+bg*nbComp;
1524   for(int i=0;i<newNbOfTuples;i++,srcPt+=step*nbComp)
1525     std::copy(srcPt,srcPt+nbComp,pt+i*nbComp);
1526   ret->copyStringInfoFrom(*this);
1527   return ret.retn();
1528 }
1529
1530 /*!
1531  * Returns a shorten copy of \a this array. The new DataArrayDouble contains ranges
1532  * of tuples specified by \a ranges parameter.
1533  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
1534  *  \param [in] ranges - std::vector of std::pair's each of which defines a range
1535  *              of tuples in [\c begin,\c end) format.
1536  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1537  *          is to delete using decrRef() as it is no more needed.
1538  *  \throw If \a end < \a begin.
1539  *  \throw If \a end > \a this->getNumberOfTuples().
1540  *  \throw If \a this is not allocated.
1541  */
1542 DataArray *DataArrayDouble::selectByTupleRanges(const std::vector<std::pair<int,int> >& ranges) const throw(INTERP_KERNEL::Exception)
1543 {
1544   checkAllocated();
1545   int nbOfComp=getNumberOfComponents();
1546   int nbOfTuplesThis=getNumberOfTuples();
1547   if(ranges.empty())
1548     {
1549       DataArrayDouble *ret=DataArrayDouble::New();
1550       ret->alloc(0,nbOfComp);
1551       ret->copyStringInfoFrom(*this);
1552       return ret;
1553     }
1554   int ref=ranges.front().first;
1555   int nbOfTuples=0;
1556   bool isIncreasing=true;
1557   for(std::vector<std::pair<int,int> >::const_iterator it=ranges.begin();it!=ranges.end();it++)
1558     {
1559       if((*it).first<=(*it).second)
1560         {
1561           if((*it).first>=0 && (*it).second<=nbOfTuplesThis)
1562             {
1563               nbOfTuples+=(*it).second-(*it).first;
1564               if(isIncreasing)
1565                 isIncreasing=ref<=(*it).first;
1566               ref=(*it).second;
1567             }
1568           else
1569             {
1570               std::ostringstream oss; oss << "DataArrayDouble::selectByTupleRanges : on range #" << std::distance(ranges.begin(),it);
1571               oss << " (" << (*it).first << "," << (*it).second << ") is greater than number of tuples of this :" << nbOfTuples << " !";
1572               throw INTERP_KERNEL::Exception(oss.str().c_str());
1573             }
1574         }
1575       else
1576         {
1577           std::ostringstream oss; oss << "DataArrayDouble::selectByTupleRanges : on range #" << std::distance(ranges.begin(),it);
1578           oss << " (" << (*it).first << "," << (*it).second << ") end is before begin !";
1579           throw INTERP_KERNEL::Exception(oss.str().c_str());
1580         }
1581     }
1582   if(isIncreasing && nbOfTuplesThis==nbOfTuples)
1583     return deepCpy();
1584   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
1585   ret->alloc(nbOfTuples,nbOfComp);
1586   ret->copyStringInfoFrom(*this);
1587   const double *src=getConstPointer();
1588   double *work=ret->getPointer();
1589   for(std::vector<std::pair<int,int> >::const_iterator it=ranges.begin();it!=ranges.end();it++)
1590     work=std::copy(src+(*it).first*nbOfComp,src+(*it).second*nbOfComp,work);
1591   return ret.retn();
1592 }
1593
1594 /*!
1595  * Returns a shorten copy of \a this array. The new DataArrayDouble contains all
1596  * tuples starting from the \a tupleIdBg-th tuple and including all tuples located before
1597  * the \a tupleIdEnd-th one. This methods has a similar behavior as std::string::substr().
1598  * This method is a specialization of selectByTupleId2().
1599  *  \param [in] tupleIdBg - index of the first tuple to copy from \a this array.
1600  *  \param [in] tupleIdEnd - index of the tuple before which the tuples to copy are located.
1601  *          If \a tupleIdEnd == -1, all the tuples till the end of \a this array are copied.
1602  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1603  *          is to delete using decrRef() as it is no more needed.
1604  *  \throw If \a tupleIdBg < 0.
1605  *  \throw If \a tupleIdBg > \a this->getNumberOfTuples().
1606     \throw If \a tupleIdEnd != -1 && \a tupleIdEnd < \a this->getNumberOfTuples().
1607  *  \sa DataArrayDouble::selectByTupleId2
1608  */
1609 DataArrayDouble *DataArrayDouble::substr(int tupleIdBg, int tupleIdEnd) const throw(INTERP_KERNEL::Exception)
1610 {
1611   checkAllocated();
1612   int nbt=getNumberOfTuples();
1613   if(tupleIdBg<0)
1614     throw INTERP_KERNEL::Exception("DataArrayDouble::substr : The tupleIdBg parameter must be greater than 0 !");
1615   if(tupleIdBg>nbt)
1616     throw INTERP_KERNEL::Exception("DataArrayDouble::substr : The tupleIdBg parameter is greater than number of tuples !");
1617   int trueEnd=tupleIdEnd;
1618   if(tupleIdEnd!=-1)
1619     {
1620       if(tupleIdEnd>nbt)
1621         throw INTERP_KERNEL::Exception("DataArrayDouble::substr : The tupleIdBg parameter is greater or equal than number of tuples !");
1622     }
1623   else
1624     trueEnd=nbt;
1625   int nbComp=getNumberOfComponents();
1626   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
1627   ret->alloc(trueEnd-tupleIdBg,nbComp);
1628   ret->copyStringInfoFrom(*this);
1629   std::copy(getConstPointer()+tupleIdBg*nbComp,getConstPointer()+trueEnd*nbComp,ret->getPointer());
1630   return ret.retn();
1631 }
1632
1633 /*!
1634  * Returns a shorten or extended copy of \a this array. If \a newNbOfComp is less
1635  * than \a this->getNumberOfComponents() then the result array is shorten as each tuple
1636  * is truncated to have \a newNbOfComp components, keeping first components. If \a
1637  * newNbOfComp is more than \a this->getNumberOfComponents() then the result array is
1638  * expanded as each tuple is populated with \a dftValue to have \a newNbOfComp
1639  * components.  
1640  *  \param [in] newNbOfComp - number of components for the new array to have.
1641  *  \param [in] dftValue - value assigned to new values added to the new array.
1642  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1643  *          is to delete using decrRef() as it is no more needed.
1644  *  \throw If \a this is not allocated.
1645  */
1646 DataArrayDouble *DataArrayDouble::changeNbOfComponents(int newNbOfComp, double dftValue) const throw(INTERP_KERNEL::Exception)
1647 {
1648   checkAllocated();
1649   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
1650   ret->alloc(getNumberOfTuples(),newNbOfComp);
1651   const double *oldc=getConstPointer();
1652   double *nc=ret->getPointer();
1653   int nbOfTuples=getNumberOfTuples();
1654   int oldNbOfComp=getNumberOfComponents();
1655   int dim=std::min(oldNbOfComp,newNbOfComp);
1656   for(int i=0;i<nbOfTuples;i++)
1657     {
1658       int j=0;
1659       for(;j<dim;j++)
1660         nc[newNbOfComp*i+j]=oldc[i*oldNbOfComp+j];
1661       for(;j<newNbOfComp;j++)
1662         nc[newNbOfComp*i+j]=dftValue;
1663     }
1664   ret->setName(getName().c_str());
1665   for(int i=0;i<dim;i++)
1666     ret->setInfoOnComponent(i,getInfoOnComponent(i).c_str());
1667   ret->setName(getName().c_str());
1668   return ret.retn();
1669 }
1670
1671 /*!
1672  * Changes the number of components within \a this array so that its raw data **does
1673  * not** change, instead splitting this data into tuples changes.
1674  *  \warning This method erases all (name and unit) component info set before!
1675  *  \param [in] newNbOfComp - number of components for \a this array to have.
1676  *  \throw If \a this is not allocated
1677  *  \throw If getNbOfElems() % \a newNbOfCompo != 0.
1678  *  \throw If \a newNbOfCompo is lower than 1.
1679  *  \throw If the rearrange method would lead to a number of tuples higher than 2147483647 (maximal capacity of int32 !).
1680  *  \warning This method erases all (name and unit) component info set before!
1681  */
1682 void DataArrayDouble::rearrange(int newNbOfCompo) throw(INTERP_KERNEL::Exception)
1683 {
1684   checkAllocated();
1685   if(newNbOfCompo<1)
1686     throw INTERP_KERNEL::Exception("DataArrayDouble::rearrange : input newNbOfCompo must be > 0 !");
1687   std::size_t nbOfElems=getNbOfElems();
1688   if(nbOfElems%newNbOfCompo!=0)
1689     throw INTERP_KERNEL::Exception("DataArrayDouble::rearrange : nbOfElems%newNbOfCompo!=0 !");
1690   if(nbOfElems/newNbOfCompo>(std::size_t)std::numeric_limits<int>::max())
1691     throw INTERP_KERNEL::Exception("DataArrayDouble::rearrange : the rearrangement leads to too high number of tuples (> 2147483647) !");
1692   _info_on_compo.clear();
1693   _info_on_compo.resize(newNbOfCompo);
1694   declareAsNew();
1695 }
1696
1697 /*!
1698  * Changes the number of components within \a this array to be equal to its number
1699  * of tuples, and inversely its number of tuples to become equal to its number of 
1700  * components. So that its raw data **does not** change, instead splitting this
1701  * data into tuples changes.
1702  *  \warning This method erases all (name and unit) component info set before!
1703  *  \warning Do not confuse this method with fromNoInterlace() and toNoInterlace()!
1704  *  \throw If \a this is not allocated.
1705  *  \sa rearrange()
1706  */
1707 void DataArrayDouble::transpose() throw(INTERP_KERNEL::Exception)
1708 {
1709   checkAllocated();
1710   int nbOfTuples=getNumberOfTuples();
1711   rearrange(nbOfTuples);
1712 }
1713
1714 /*!
1715  * Returns a copy of \a this array composed of selected components.
1716  * The new DataArrayDouble has the same number of tuples but includes components
1717  * specified by \a compoIds parameter. So that getNbOfElems() of the result array
1718  * can be either less, same or more than \a this->getNbOfElems().
1719  *  \param [in] compoIds - sequence of zero based indices of components to include
1720  *              into the new array.
1721  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1722  *          is to delete using decrRef() as it is no more needed.
1723  *  \throw If \a this is not allocated.
1724  *  \throw If a component index (\a i) is not valid: 
1725  *         \a i < 0 || \a i >= \a this->getNumberOfComponents().
1726  *
1727  *  \ref py_mcdataarraydouble_KeepSelectedComponents "Here is a Python example".
1728  */
1729 DataArray *DataArrayDouble::keepSelectedComponents(const std::vector<int>& compoIds) const throw(INTERP_KERNEL::Exception)
1730 {
1731   checkAllocated();
1732   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret(DataArrayDouble::New());
1733   std::size_t newNbOfCompo=compoIds.size();
1734   int oldNbOfCompo=getNumberOfComponents();
1735   for(std::vector<int>::const_iterator it=compoIds.begin();it!=compoIds.end();it++)
1736     if((*it)<0 || (*it)>=oldNbOfCompo)
1737       {
1738         std::ostringstream oss; oss << "DataArrayDouble::keepSelectedComponents : invalid requested component : " << *it << " whereas it should be in [0," << oldNbOfCompo << ") !";
1739         throw INTERP_KERNEL::Exception(oss.str().c_str());
1740       }
1741   int nbOfTuples=getNumberOfTuples();
1742   ret->alloc(nbOfTuples,(int)newNbOfCompo);
1743   ret->copyPartOfStringInfoFrom(*this,compoIds);
1744   const double *oldc=getConstPointer();
1745   double *nc=ret->getPointer();
1746   for(int i=0;i<nbOfTuples;i++)
1747     for(std::size_t j=0;j<newNbOfCompo;j++,nc++)
1748       *nc=oldc[i*oldNbOfCompo+compoIds[j]];
1749   return ret.retn();
1750 }
1751
1752 /*!
1753  * Appends components of another array to components of \a this one, tuple by tuple.
1754  * So that the number of tuples of \a this array remains the same and the number of 
1755  * components increases.
1756  *  \param [in] other - the DataArrayDouble to append to \a this one.
1757  *  \throw If \a this is not allocated.
1758  *  \throw If \a this and \a other arrays have different number of tuples.
1759  *
1760  *  \ref cpp_mcdataarraydouble_meldwith "Here is a C++ example".
1761  *
1762  *  \ref py_mcdataarraydouble_meldwith "Here is a Python example".
1763  */
1764 void DataArrayDouble::meldWith(const DataArrayDouble *other) throw(INTERP_KERNEL::Exception)
1765 {
1766   checkAllocated();
1767   other->checkAllocated();
1768   int nbOfTuples=getNumberOfTuples();
1769   if(nbOfTuples!=other->getNumberOfTuples())
1770     throw INTERP_KERNEL::Exception("DataArrayDouble::meldWith : mismatch of number of tuples !");
1771   int nbOfComp1=getNumberOfComponents();
1772   int nbOfComp2=other->getNumberOfComponents();
1773   double *newArr=(double *)malloc((nbOfTuples*(nbOfComp1+nbOfComp2))*sizeof(double));
1774   double *w=newArr;
1775   const double *inp1=getConstPointer();
1776   const double *inp2=other->getConstPointer();
1777   for(int i=0;i<nbOfTuples;i++,inp1+=nbOfComp1,inp2+=nbOfComp2)
1778     {
1779       w=std::copy(inp1,inp1+nbOfComp1,w);
1780       w=std::copy(inp2,inp2+nbOfComp2,w);
1781     }
1782   useArray(newArr,true,C_DEALLOC,nbOfTuples,nbOfComp1+nbOfComp2);
1783   std::vector<int> compIds(nbOfComp2);
1784   for(int i=0;i<nbOfComp2;i++)
1785     compIds[i]=nbOfComp1+i;
1786   copyPartOfStringInfoFrom2(compIds,*other);
1787 }
1788
1789 /*!
1790  * This method checks that all tuples in \a other are in \a this.
1791  * If true, the output param \a tupleIds contains the tuples ids of \a this that correspond to tupes in \a this.
1792  * 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.
1793  *
1794  * \param [in] other - the array having the same number of components than \a this.
1795  * \param [out] tupleIds - the tuple ids containing the same number of tuples than \a other has.
1796  * \sa DataArrayDouble::findCommonTuples
1797  */
1798 bool DataArrayDouble::areIncludedInMe(const DataArrayDouble *other, double prec, DataArrayInt *&tupleIds) const throw(INTERP_KERNEL::Exception)
1799 {
1800   if(!other)
1801     throw INTERP_KERNEL::Exception("DataArrayDouble::areIncludedInMe : input array is NULL !");
1802   checkAllocated(); other->checkAllocated();
1803   if(getNumberOfComponents()!=other->getNumberOfComponents())
1804     throw INTERP_KERNEL::Exception("DataArrayDouble::areIncludedInMe : the number of components does not match !");
1805   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> a=DataArrayDouble::Aggregate(this,other);
1806   DataArrayInt *c=0,*ci=0;
1807   a->findCommonTuples(prec,getNumberOfTuples(),c,ci);
1808   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cSafe(c),ciSafe(ci);
1809   int newNbOfTuples=-1;
1810   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ids=DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2(a->getNumberOfTuples(),c->begin(),ci->begin(),ci->end(),newNbOfTuples);
1811   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret1=ids->selectByTupleId2(getNumberOfTuples(),a->getNumberOfTuples(),1);
1812   tupleIds=ret1.retn();
1813   return newNbOfTuples==getNumberOfTuples();
1814 }
1815
1816 /*!
1817  * Searches for tuples coincident within \a prec tolerance. Each tuple is considered
1818  * as coordinates of a point in getNumberOfComponents()-dimensional space. The
1819  * distance separating two points is computed with the infinite norm.
1820  *
1821  * Indices of coincident tuples are stored in output arrays.
1822  * A pair of arrays (\a comm, \a commIndex) is called "Surjective Format 2".
1823  *
1824  * This method is typically used by MEDCouplingPointSet::findCommonNodes() and
1825  * MEDCouplingUMesh::mergeNodes().
1826  *  \param [in] prec - minimal absolute distance between two tuples (infinite norm) at which they are
1827  *              considered not coincident.
1828  *  \param [in] limitTupleId - limit tuple id. If all tuples within a group of coincident
1829  *              tuples have id strictly lower than \a limitTupleId then they are not returned.
1830  *  \param [out] comm - the array holding ids (== indices) of coincident tuples. 
1831  *               \a comm->getNumberOfComponents() == 1. 
1832  *               \a comm->getNumberOfTuples() == \a commIndex->back().
1833  *  \param [out] commIndex - the array dividing all indices stored in \a comm into
1834  *               groups of (indices of) coincident tuples. Its every value is a tuple
1835  *               index where a next group of tuples begins. For example the second
1836  *               group of tuples in \a comm is described by following range of indices:
1837  *               [ \a commIndex[1], \a commIndex[2] ). \a commIndex->getNumberOfTuples()-1
1838  *               gives the number of groups of coincident tuples.
1839  *  \throw If \a this is not allocated.
1840  *  \throw If the number of components is not in [1,2,3].
1841  *
1842  *  \ref cpp_mcdataarraydouble_findcommontuples "Here is a C++ example".
1843  *
1844  *  \ref py_mcdataarraydouble_findcommontuples  "Here is a Python example".
1845  *  \sa DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2(), DataArrayDouble::areIncludedInMe
1846  */
1847 void DataArrayDouble::findCommonTuples(double prec, int limitTupleId, DataArrayInt *&comm, DataArrayInt *&commIndex) const throw(INTERP_KERNEL::Exception)
1848 {
1849   checkAllocated();
1850   int nbOfCompo=getNumberOfComponents();
1851   if ((nbOfCompo<1) || (nbOfCompo>3)) //test before work
1852     throw INTERP_KERNEL::Exception("DataArrayDouble::findCommonTuples : Unexpected spacedim of coords. Must be 1, 2 or 3.");
1853   
1854   int nbOfTuples=getNumberOfTuples();
1855   //
1856   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> c(DataArrayInt::New()),cI(DataArrayInt::New()); c->alloc(0,1); cI->pushBackSilent(0);
1857   switch(nbOfCompo)
1858     {
1859     case 3:
1860       findCommonTuplesAlg<3>(begin(),nbOfTuples,limitTupleId,prec,c,cI);
1861       break;
1862     case 2:
1863       findCommonTuplesAlg<2>(begin(),nbOfTuples,limitTupleId,prec,c,cI);
1864       break;
1865     case 1:
1866       findCommonTuplesAlg<1>(begin(),nbOfTuples,limitTupleId,prec,c,cI);
1867       break;
1868     default:
1869       throw INTERP_KERNEL::Exception("DataArrayDouble::findCommonTuples : nb of components managed are 1,2 and 3 ! not implemented for other number of components !");
1870     }
1871   comm=c.retn();
1872   commIndex=cI.retn();
1873 }
1874
1875 /*!
1876  * 
1877  * \param [in] nbTimes specifies the nb of times each tuples in \a this will be duplicated contiguouly in returned DataArrayDouble instance.
1878  *             \a nbTimes  should be at least equal to 1.
1879  * \return a newly allocated DataArrayDouble having one component and number of tuples equal to \a nbTimes * \c this->getNumberOfTuples.
1880  * \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.
1881  */
1882 DataArrayDouble *DataArrayDouble::duplicateEachTupleNTimes(int nbTimes) const throw(INTERP_KERNEL::Exception)
1883 {
1884   checkAllocated();
1885   if(getNumberOfComponents()!=1)
1886     throw INTERP_KERNEL::Exception("DataArrayDouble::duplicateEachTupleNTimes : this should have only one component !");
1887   if(nbTimes<1)
1888     throw INTERP_KERNEL::Exception("DataArrayDouble::duplicateEachTupleNTimes : nb times should be >= 1 !");
1889   int nbTuples=getNumberOfTuples();
1890   const double *inPtr=getConstPointer();
1891   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New(); ret->alloc(nbTimes*nbTuples,1);
1892   double *retPtr=ret->getPointer();
1893   for(int i=0;i<nbTuples;i++,inPtr++)
1894     {
1895       double val=*inPtr;
1896       for(int j=0;j<nbTimes;j++,retPtr++)
1897         *retPtr=val;
1898     }
1899   ret->copyStringInfoFrom(*this);
1900   return ret.retn();
1901 }
1902
1903 /*!
1904  * This methods returns the minimal distance between the two set of points \a this and \a other.
1905  * So \a this and \a other have to have the same number of components. If not an INTERP_KERNEL::Exception will be thrown.
1906  * This method works only if number of components of \a this (equal to those of \a other) is in 1, 2 or 3.
1907  *
1908  * \param [out] thisTupleId the tuple id in \a this corresponding to the returned minimal distance
1909  * \param [out] otherTupleId the tuple id in \a other corresponding to the returned minimal distance
1910  * \return the minimal distance between the two set of points \a this and \a other.
1911  * \sa DataArrayDouble::findClosestTupleId
1912  */
1913 double DataArrayDouble::minimalDistanceTo(const DataArrayDouble *other, int& thisTupleId, int& otherTupleId) const throw(INTERP_KERNEL::Exception)
1914 {
1915   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> part1=findClosestTupleId(other);
1916   int nbOfCompo(getNumberOfComponents());
1917   int otherNbTuples(other->getNumberOfTuples());
1918   const double *thisPt(begin()),*otherPt(other->begin());
1919   const int *part1Pt(part1->begin());
1920   double ret=std::numeric_limits<double>::max();
1921   for(int i=0;i<otherNbTuples;i++,part1Pt++,otherPt+=nbOfCompo)
1922     {
1923       double tmp(0.);
1924       for(int j=0;j<nbOfCompo;j++)
1925         tmp+=(otherPt[j]-thisPt[nbOfCompo*(*part1Pt)+j])*(otherPt[j]-thisPt[nbOfCompo*(*part1Pt)+j]);
1926       if(tmp<ret)
1927         { ret=tmp; thisTupleId=*part1Pt; otherTupleId=i; }
1928     }
1929   return sqrt(ret);
1930 }
1931
1932 /*!
1933  * This methods returns for each tuple in \a other which tuple in \a this is the closest.
1934  * So \a this and \a other have to have the same number of components. If not an INTERP_KERNEL::Exception will be thrown.
1935  * This method works only if number of components of \a this (equal to those of \a other) is in 1, 2 or 3.
1936  *
1937  * \return a newly allocated (new object to be dealt by the caller) DataArrayInt having \c other->getNumberOfTuples() tuples and one components.
1938  * \sa DataArrayDouble::minimalDistanceTo
1939  */
1940 DataArrayInt *DataArrayDouble::findClosestTupleId(const DataArrayDouble *other) const throw(INTERP_KERNEL::Exception)
1941 {
1942   if(!other)
1943     throw INTERP_KERNEL::Exception("DataArrayDouble::findClosestTupleId : other instance is NULL !");
1944   checkAllocated(); other->checkAllocated();
1945   int nbOfCompo=getNumberOfComponents();
1946   if(nbOfCompo!=other->getNumberOfComponents())
1947     {
1948       std::ostringstream oss; oss << "DataArrayDouble::findClosestTupleId : number of components in this is " << nbOfCompo;
1949       oss << ", whereas number of components in other is " << other->getNumberOfComponents() << "! Should be equal !";
1950       throw INTERP_KERNEL::Exception(oss.str().c_str());
1951     }
1952   int nbOfTuples=other->getNumberOfTuples();
1953   int thisNbOfTuples=getNumberOfTuples();
1954   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbOfTuples,1);
1955   double bounds[6];
1956   getMinMaxPerComponent(bounds);
1957   switch(nbOfCompo)
1958     {
1959     case 3:
1960       {
1961         double xDelta(fabs(bounds[1]-bounds[0])),yDelta(fabs(bounds[3]-bounds[2])),zDelta(fabs(bounds[5]-bounds[4]));
1962         double delta=std::max(xDelta,yDelta); delta=std::max(delta,zDelta);
1963         double characSize=pow((delta*delta*delta)/((double)thisNbOfTuples),1./3.);
1964         BBTreePts<3,int> myTree(begin(),0,0,getNumberOfTuples(),characSize*1e-12);
1965         FindClosestTupleIdAlg<3>(myTree,3.*characSize*characSize,other->begin(),nbOfTuples,begin(),thisNbOfTuples,ret->getPointer());
1966         break;
1967       }
1968     case 2:
1969       {
1970         double xDelta(fabs(bounds[1]-bounds[0])),yDelta(fabs(bounds[3]-bounds[2]));
1971         double delta=std::max(xDelta,yDelta);
1972         double characSize=sqrt(delta/(double)thisNbOfTuples);
1973         BBTreePts<2,int> myTree(begin(),0,0,getNumberOfTuples(),characSize*1e-12);
1974         FindClosestTupleIdAlg<2>(myTree,2.*characSize*characSize,other->begin(),nbOfTuples,begin(),thisNbOfTuples,ret->getPointer());
1975         break;
1976       }
1977     case 1:
1978       {
1979         double characSize=fabs(bounds[1]-bounds[0])/thisNbOfTuples;
1980         BBTreePts<1,int> myTree(begin(),0,0,getNumberOfTuples(),characSize*1e-12);
1981         FindClosestTupleIdAlg<1>(myTree,1.*characSize*characSize,other->begin(),nbOfTuples,begin(),thisNbOfTuples,ret->getPointer());
1982         break;
1983       }
1984     default:
1985       throw INTERP_KERNEL::Exception("Unexpected spacedim of coords for findClosestTupleId. Must be 1, 2 or 3.");
1986     }
1987   return ret.retn();
1988 }
1989
1990 /*!
1991  * Returns a copy of \a this array by excluding coincident tuples. Each tuple is
1992  * considered as coordinates of a point in getNumberOfComponents()-dimensional
1993  * space. The distance between tuples is computed using norm2. If several tuples are
1994  * not far each from other than \a prec, only one of them remains in the result
1995  * array. The order of tuples in the result array is same as in \a this one except
1996  * that coincident tuples are excluded.
1997  *  \param [in] prec - minimal absolute distance between two tuples at which they are
1998  *              considered not coincident.
1999  *  \param [in] limitTupleId - limit tuple id. If all tuples within a group of coincident
2000  *              tuples have id strictly lower than \a limitTupleId then they are not excluded.
2001  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
2002  *          is to delete using decrRef() as it is no more needed.
2003  *  \throw If \a this is not allocated.
2004  *  \throw If the number of components is not in [1,2,3].
2005  *
2006  *  \ref py_mcdataarraydouble_getdifferentvalues "Here is a Python example".
2007  */
2008 DataArrayDouble *DataArrayDouble::getDifferentValues(double prec, int limitTupleId) const throw(INTERP_KERNEL::Exception)
2009 {
2010   checkAllocated();
2011   DataArrayInt *c0=0,*cI0=0;
2012   findCommonTuples(prec,limitTupleId,c0,cI0);
2013   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> c(c0),cI(cI0);
2014   int newNbOfTuples=-1;
2015   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> o2n=DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2(getNumberOfTuples(),c0->begin(),cI0->begin(),cI0->end(),newNbOfTuples);
2016   return renumberAndReduce(o2n->getConstPointer(),newNbOfTuples);
2017 }
2018
2019 /*!
2020  * Copy all components in a specified order from another DataArrayDouble.
2021  * Both numerical and textual data is copied. The number of tuples in \a this and
2022  * the other array can be different.
2023  *  \param [in] a - the array to copy data from.
2024  *  \param [in] compoIds - sequence of zero based indices of components, data of which is
2025  *              to be copied.
2026  *  \throw If \a a is NULL.
2027  *  \throw If \a compoIds.size() != \a a->getNumberOfComponents().
2028  *  \throw If \a compoIds[i] < 0 or \a compoIds[i] > \a this->getNumberOfComponents().
2029  *
2030  *  \ref py_mcdataarraydouble_setselectedcomponents "Here is a Python example".
2031  */
2032 void DataArrayDouble::setSelectedComponents(const DataArrayDouble *a, const std::vector<int>& compoIds) throw(INTERP_KERNEL::Exception)
2033 {
2034   if(!a)
2035     throw INTERP_KERNEL::Exception("DataArrayDouble::setSelectedComponents : input DataArrayDouble is NULL !");
2036   checkAllocated();
2037   copyPartOfStringInfoFrom2(compoIds,*a);
2038   std::size_t partOfCompoSz=compoIds.size();
2039   int nbOfCompo=getNumberOfComponents();
2040   int nbOfTuples=std::min(getNumberOfTuples(),a->getNumberOfTuples());
2041   const double *ac=a->getConstPointer();
2042   double *nc=getPointer();
2043   for(int i=0;i<nbOfTuples;i++)
2044     for(std::size_t j=0;j<partOfCompoSz;j++,ac++)
2045       nc[nbOfCompo*i+compoIds[j]]=*ac;
2046 }
2047
2048 /*!
2049  * Copy all values from another DataArrayDouble into specified tuples and components
2050  * of \a this array. Textual data is not copied.
2051  * The tree parameters defining set of indices of tuples and components are similar to
2052  * the tree parameters of the Python function \c range(\c start,\c stop,\c step).
2053  *  \param [in] a - the array to copy values from.
2054  *  \param [in] bgTuples - index of the first tuple of \a this array to assign values to.
2055  *  \param [in] endTuples - index of the tuple before which the tuples to assign to
2056  *              are located.
2057  *  \param [in] stepTuples - index increment to get index of the next tuple to assign to.
2058  *  \param [in] bgComp - index of the first component of \a this array to assign values to.
2059  *  \param [in] endComp - index of the component before which the components to assign
2060  *              to are located.
2061  *  \param [in] stepComp - index increment to get index of the next component to assign to.
2062  *  \param [in] strictCompoCompare - if \a true (by default), then \a a->getNumberOfComponents() 
2063  *              must be equal to the number of columns to assign to, else an
2064  *              exception is thrown; if \a false, then it is only required that \a
2065  *              a->getNbOfElems() equals to number of values to assign to (this condition
2066  *              must be respected even if \a strictCompoCompare is \a true). The number of 
2067  *              values to assign to is given by following Python expression:
2068  *              \a nbTargetValues = 
2069  *              \c len(\c range(\a bgTuples,\a endTuples,\a stepTuples)) *
2070  *              \c len(\c range(\a bgComp,\a endComp,\a stepComp)).
2071  *  \throw If \a a is NULL.
2072  *  \throw If \a a is not allocated.
2073  *  \throw If \a this is not allocated.
2074  *  \throw If parameters specifying tuples and components to assign to do not give a
2075  *            non-empty range of increasing indices.
2076  *  \throw If \a a->getNbOfElems() != \a nbTargetValues.
2077  *  \throw If \a strictCompoCompare == \a true && \a a->getNumberOfComponents() !=
2078  *            \c len(\c range(\a bgComp,\a endComp,\a stepComp)).
2079  *
2080  *  \ref py_mcdataarraydouble_setpartofvalues1 "Here is a Python example".
2081  */
2082 void DataArrayDouble::setPartOfValues1(const DataArrayDouble *a, int bgTuples, int endTuples, int stepTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare) throw(INTERP_KERNEL::Exception)
2083 {
2084   if(!a)
2085     throw INTERP_KERNEL::Exception("DataArrayDouble::setPartOfValues1 : input DataArrayDouble is NULL !");
2086   const char msg[]="DataArrayDouble::setPartOfValues1";
2087   checkAllocated();
2088   a->checkAllocated();
2089   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
2090   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
2091   int nbComp=getNumberOfComponents();
2092   int nbOfTuples=getNumberOfTuples();
2093   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
2094   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
2095   bool assignTech=true;
2096   if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
2097     {
2098       if(strictCompoCompare)
2099         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
2100     }
2101   else
2102     {
2103       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
2104       assignTech=false;
2105     }
2106   const double *srcPt=a->getConstPointer();
2107   double *pt=getPointer()+bgTuples*nbComp+bgComp;
2108   if(assignTech)
2109     {
2110       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
2111         for(int j=0;j<newNbOfComp;j++,srcPt++)
2112           pt[j*stepComp]=*srcPt;
2113     }
2114   else
2115     {
2116       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
2117         {
2118           const double *srcPt2=srcPt;
2119           for(int j=0;j<newNbOfComp;j++,srcPt2++)
2120             pt[j*stepComp]=*srcPt2;
2121         }
2122     }
2123 }
2124
2125 /*!
2126  * Assign a given value to values at specified tuples and components of \a this array.
2127  * The tree parameters defining set of indices of tuples and components are similar to
2128  * the tree parameters of the Python function \c range(\c start,\c stop,\c step)..
2129  *  \param [in] a - the value to assign.
2130  *  \param [in] bgTuples - index of the first tuple of \a this array to assign to.
2131  *  \param [in] endTuples - index of the tuple before which the tuples to assign to
2132  *              are located.
2133  *  \param [in] stepTuples - index increment to get index of the next tuple to assign to.
2134  *  \param [in] bgComp - index of the first component of \a this array to assign to.
2135  *  \param [in] endComp - index of the component before which the components to assign
2136  *              to are located.
2137  *  \param [in] stepComp - index increment to get index of the next component to assign to.
2138  *  \throw If \a this is not allocated.
2139  *  \throw If parameters specifying tuples and components to assign to, do not give a
2140  *            non-empty range of increasing indices or indices are out of a valid range
2141  *            for \this array.
2142  *
2143  *  \ref py_mcdataarraydouble_setpartofvaluessimple1 "Here is a Python example".
2144  */
2145 void DataArrayDouble::setPartOfValuesSimple1(double a, int bgTuples, int endTuples, int stepTuples, int bgComp, int endComp, int stepComp) throw(INTERP_KERNEL::Exception)
2146 {
2147   const char msg[]="DataArrayDouble::setPartOfValuesSimple1";
2148   checkAllocated();
2149   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
2150   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
2151   int nbComp=getNumberOfComponents();
2152   int nbOfTuples=getNumberOfTuples();
2153   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
2154   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
2155   double *pt=getPointer()+bgTuples*nbComp+bgComp;
2156   for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
2157     for(int j=0;j<newNbOfComp;j++)
2158       pt[j*stepComp]=a;
2159 }
2160
2161 /*!
2162  * Copy all values from another DataArrayDouble (\a a) into specified tuples and 
2163  * components of \a this array. Textual data is not copied.
2164  * The tuples and components to assign to are defined by C arrays of indices.
2165  * There are two *modes of usage*:
2166  * - If \a a->getNbOfElems() equals to number of values to assign to, then every value
2167  *   of \a a is assigned to its own location within \a this array. 
2168  * - If \a a includes one tuple, then all values of \a a are assigned to the specified
2169  *   components of every specified tuple of \a this array. In this mode it is required
2170  *   that \a a->getNumberOfComponents() equals to the number of specified components.
2171  *
2172  *  \param [in] a - the array to copy values from.
2173  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
2174  *              assign values of \a a to.
2175  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
2176  *              pointer to a tuple index <em>(pi)</em> varies as this: 
2177  *              \a bgTuples <= \a pi < \a endTuples.
2178  *  \param [in] bgComp - pointer to an array of component indices of \a this array to
2179  *              assign values of \a a to.
2180  *  \param [in] endComp - specifies the end of the array \a bgTuples, so that
2181  *              pointer to a component index <em>(pi)</em> varies as this: 
2182  *              \a bgComp <= \a pi < \a endComp.
2183  *  \param [in] strictCompoCompare - this parameter is checked only if the
2184  *               *mode of usage* is the first; if it is \a true (default), 
2185  *               then \a a->getNumberOfComponents() must be equal 
2186  *               to the number of specified columns, else this is not required.
2187  *  \throw If \a a is NULL.
2188  *  \throw If \a a is not allocated.
2189  *  \throw If \a this is not allocated.
2190  *  \throw If any index of tuple/component given by <em>bgTuples / bgComp</em> is
2191  *         out of a valid range for \a this array.
2192  *  \throw In the first *mode of usage*, if <em>strictCompoCompare == true </em> and
2193  *         if <em> a->getNumberOfComponents() != (endComp - bgComp) </em>.
2194  *  \throw In the second *mode of usage*, if \a a->getNumberOfTuples() != 1 or
2195  *         <em> a->getNumberOfComponents() != (endComp - bgComp)</em>.
2196  *
2197  *  \ref py_mcdataarraydouble_setpartofvalues2 "Here is a Python example".
2198  */
2199 void DataArrayDouble::setPartOfValues2(const DataArrayDouble *a, const int *bgTuples, const int *endTuples, const int *bgComp, const int *endComp, bool strictCompoCompare) throw(INTERP_KERNEL::Exception)
2200 {
2201   if(!a)
2202     throw INTERP_KERNEL::Exception("DataArrayDouble::setPartOfValues2 : input DataArrayDouble is NULL !");
2203   const char msg[]="DataArrayDouble::setPartOfValues2";
2204   checkAllocated();
2205   a->checkAllocated();
2206   int nbComp=getNumberOfComponents();
2207   int nbOfTuples=getNumberOfTuples();
2208   for(const int *z=bgComp;z!=endComp;z++)
2209     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
2210   int newNbOfTuples=(int)std::distance(bgTuples,endTuples);
2211   int newNbOfComp=(int)std::distance(bgComp,endComp);
2212   bool assignTech=true;
2213   if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
2214     {
2215       if(strictCompoCompare)
2216         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
2217     }
2218   else
2219     {
2220       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
2221       assignTech=false;
2222     }
2223   double *pt=getPointer();
2224   const double *srcPt=a->getConstPointer();
2225   if(assignTech)
2226     {    
2227       for(const int *w=bgTuples;w!=endTuples;w++)
2228         {
2229           DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
2230           for(const int *z=bgComp;z!=endComp;z++,srcPt++)
2231             {    
2232               pt[(std::size_t)(*w)*nbComp+(*z)]=*srcPt;
2233             }
2234         }
2235     }
2236   else
2237     {
2238       for(const int *w=bgTuples;w!=endTuples;w++)
2239         {
2240           const double *srcPt2=srcPt;
2241           DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
2242           for(const int *z=bgComp;z!=endComp;z++,srcPt2++)
2243             {    
2244               pt[(std::size_t)(*w)*nbComp+(*z)]=*srcPt2;
2245             }
2246         }
2247     }
2248 }
2249
2250 /*!
2251  * Assign a given value to values at specified tuples and components of \a this array.
2252  * The tuples and components to assign to are defined by C arrays of indices.
2253  *  \param [in] a - the value to assign.
2254  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
2255  *              assign \a a to.
2256  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
2257  *              pointer to a tuple index (\a pi) varies as this: 
2258  *              \a bgTuples <= \a pi < \a endTuples.
2259  *  \param [in] bgComp - pointer to an array of component indices of \a this array to
2260  *              assign \a a to.
2261  *  \param [in] endComp - specifies the end of the array \a bgTuples, so that
2262  *              pointer to a component index (\a pi) varies as this: 
2263  *              \a bgComp <= \a pi < \a endComp.
2264  *  \throw If \a this is not allocated.
2265  *  \throw If any index of tuple/component given by <em>bgTuples / bgComp</em> is
2266  *         out of a valid range for \a this array.
2267  *
2268  *  \ref py_mcdataarraydouble_setpartofvaluessimple2 "Here is a Python example".
2269  */
2270 void DataArrayDouble::setPartOfValuesSimple2(double a, const int *bgTuples, const int *endTuples, const int *bgComp, const int *endComp) throw(INTERP_KERNEL::Exception)
2271 {
2272   checkAllocated();
2273   int nbComp=getNumberOfComponents();
2274   int nbOfTuples=getNumberOfTuples();
2275   for(const int *z=bgComp;z!=endComp;z++)
2276     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
2277   double *pt=getPointer();
2278   for(const int *w=bgTuples;w!=endTuples;w++)
2279     for(const int *z=bgComp;z!=endComp;z++)
2280       {
2281         DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
2282         pt[(std::size_t)(*w)*nbComp+(*z)]=a;
2283       }
2284 }
2285
2286 /*!
2287  * Copy all values from another DataArrayDouble (\a a) into specified tuples and 
2288  * components of \a this array. Textual data is not copied.
2289  * The tuples to assign to are defined by a C array of indices.
2290  * The components to assign to are defined by three values similar to parameters of
2291  * the Python function \c range(\c start,\c stop,\c step).
2292  * There are two *modes of usage*:
2293  * - If \a a->getNbOfElems() equals to number of values to assign to, then every value
2294  *   of \a a is assigned to its own location within \a this array. 
2295  * - If \a a includes one tuple, then all values of \a a are assigned to the specified
2296  *   components of every specified tuple of \a this array. In this mode it is required
2297  *   that \a a->getNumberOfComponents() equals to the number of specified components.
2298  *
2299  *  \param [in] a - the array to copy values from.
2300  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
2301  *              assign values of \a a to.
2302  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
2303  *              pointer to a tuple index <em>(pi)</em> varies as this: 
2304  *              \a bgTuples <= \a pi < \a endTuples.
2305  *  \param [in] bgComp - index of the first component of \a this array to assign to.
2306  *  \param [in] endComp - index of the component before which the components to assign
2307  *              to are located.
2308  *  \param [in] stepComp - index increment to get index of the next component to assign to.
2309  *  \param [in] strictCompoCompare - this parameter is checked only in the first
2310  *               *mode of usage*; if \a strictCompoCompare is \a true (default), 
2311  *               then \a a->getNumberOfComponents() must be equal 
2312  *               to the number of specified columns, else this is not required.
2313  *  \throw If \a a is NULL.
2314  *  \throw If \a a is not allocated.
2315  *  \throw If \a this is not allocated.
2316  *  \throw If any index of tuple given by \a bgTuples is out of a valid range for 
2317  *         \a this array.
2318  *  \throw In the first *mode of usage*, if <em>strictCompoCompare == true </em> and
2319  *         if <em> a->getNumberOfComponents()</em> is unequal to the number of components
2320  *         defined by <em>(bgComp,endComp,stepComp)</em>.
2321  *  \throw In the second *mode of usage*, if \a a->getNumberOfTuples() != 1 or
2322  *         <em> a->getNumberOfComponents()</em> is unequal to the number of components
2323  *         defined by <em>(bgComp,endComp,stepComp)</em>.
2324  *  \throw If parameters specifying 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_setpartofvalues3 "Here is a Python example".
2329  */
2330 void DataArrayDouble::setPartOfValues3(const DataArrayDouble *a, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare) throw(INTERP_KERNEL::Exception)
2331 {
2332   if(!a)
2333     throw INTERP_KERNEL::Exception("DataArrayDouble::setPartOfValues3 : input DataArrayDouble is NULL !");
2334   const char msg[]="DataArrayDouble::setPartOfValues3";
2335   checkAllocated();
2336   a->checkAllocated();
2337   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
2338   int nbComp=getNumberOfComponents();
2339   int nbOfTuples=getNumberOfTuples();
2340   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
2341   int newNbOfTuples=(int)std::distance(bgTuples,endTuples);
2342   bool assignTech=true;
2343   if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
2344     {
2345       if(strictCompoCompare)
2346         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
2347     }
2348   else
2349     {
2350       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
2351       assignTech=false;
2352     }
2353   double *pt=getPointer()+bgComp;
2354   const double *srcPt=a->getConstPointer();
2355   if(assignTech)
2356     {
2357       for(const int *w=bgTuples;w!=endTuples;w++)
2358         for(int j=0;j<newNbOfComp;j++,srcPt++)
2359           {
2360             DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
2361             pt[(std::size_t)(*w)*nbComp+j*stepComp]=*srcPt;
2362           }
2363     }
2364   else
2365     {
2366       for(const int *w=bgTuples;w!=endTuples;w++)
2367         {
2368           const double *srcPt2=srcPt;
2369           for(int j=0;j<newNbOfComp;j++,srcPt2++)
2370             {
2371               DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
2372               pt[(std::size_t)(*w)*nbComp+j*stepComp]=*srcPt2;
2373             }
2374         }
2375     }
2376 }
2377
2378 /*!
2379  * Assign a given value to values at specified tuples and components of \a this array.
2380  * The tuples to assign to are defined by a C array of indices.
2381  * The components to assign to are defined by three values similar to parameters of
2382  * the Python function \c range(\c start,\c stop,\c step).
2383  *  \param [in] a - the value to assign.
2384  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
2385  *              assign \a a to.
2386  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
2387  *              pointer to a tuple index <em>(pi)</em> varies as this: 
2388  *              \a bgTuples <= \a pi < \a endTuples.
2389  *  \param [in] bgComp - index of the first component of \a this array to assign to.
2390  *  \param [in] endComp - index of the component before which the components to assign
2391  *              to are located.
2392  *  \param [in] stepComp - index increment to get index of the next component to assign to.
2393  *  \throw If \a this is not allocated.
2394  *  \throw If any index of tuple given by \a bgTuples is out of a valid range for 
2395  *         \a this array.
2396  *  \throw If parameters specifying components to assign to, do not give a
2397  *            non-empty range of increasing indices or indices are out of a valid range
2398  *            for \this array.
2399  *
2400  *  \ref py_mcdataarraydouble_setpartofvaluessimple3 "Here is a Python example".
2401  */
2402 void DataArrayDouble::setPartOfValuesSimple3(double a, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp) throw(INTERP_KERNEL::Exception)
2403 {
2404   const char msg[]="DataArrayDouble::setPartOfValuesSimple3";
2405   checkAllocated();
2406   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
2407   int nbComp=getNumberOfComponents();
2408   int nbOfTuples=getNumberOfTuples();
2409   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
2410   double *pt=getPointer()+bgComp;
2411   for(const int *w=bgTuples;w!=endTuples;w++)
2412     for(int j=0;j<newNbOfComp;j++)
2413       {
2414         DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
2415         pt[(std::size_t)(*w)*nbComp+j*stepComp]=a;
2416       }
2417 }
2418
2419 /*!
2420  * Copy all values from another DataArrayDouble into specified tuples and components
2421  * of \a this array. Textual data is not copied.
2422  * The tree parameters defining set of indices of tuples and components are similar to
2423  * the tree parameters of the Python function \c range(\c start,\c stop,\c step).
2424  *  \param [in] a - the array to copy values from.
2425  *  \param [in] bgTuples - index of the first tuple of \a this array to assign values to.
2426  *  \param [in] endTuples - index of the tuple before which the tuples to assign to
2427  *              are located.
2428  *  \param [in] stepTuples - index increment to get index of the next tuple to assign to.
2429  *  \param [in] bgComp - pointer to an array of component indices of \a this array to
2430  *              assign \a a to.
2431  *  \param [in] endComp - specifies the end of the array \a bgTuples, so that
2432  *              pointer to a component index (\a pi) varies as this: 
2433  *              \a bgComp <= \a pi < \a endComp.
2434  *  \param [in] strictCompoCompare - if \a true (by default), then \a a->getNumberOfComponents() 
2435  *              must be equal to the number of columns to assign to, else an
2436  *              exception is thrown; if \a false, then it is only required that \a
2437  *              a->getNbOfElems() equals to number of values to assign to (this condition
2438  *              must be respected even if \a strictCompoCompare is \a true). The number of 
2439  *              values to assign to is given by following Python expression:
2440  *              \a nbTargetValues = 
2441  *              \c len(\c range(\a bgTuples,\a endTuples,\a stepTuples)) *
2442  *              \c len(\c range(\a bgComp,\a endComp,\a stepComp)).
2443  *  \throw If \a a is NULL.
2444  *  \throw If \a a is not allocated.
2445  *  \throw If \a this is not allocated.
2446  *  \throw If parameters specifying tuples and components to assign to do not give a
2447  *            non-empty range of increasing indices.
2448  *  \throw If \a a->getNbOfElems() != \a nbTargetValues.
2449  *  \throw If \a strictCompoCompare == \a true && \a a->getNumberOfComponents() !=
2450  *            \c len(\c range(\a bgComp,\a endComp,\a stepComp)).
2451  *
2452  */
2453 void DataArrayDouble::setPartOfValues4(const DataArrayDouble *a, int bgTuples, int endTuples, int stepTuples, const int *bgComp, const int *endComp, bool strictCompoCompare) throw(INTERP_KERNEL::Exception)
2454 {
2455   if(!a)
2456     throw INTERP_KERNEL::Exception("DataArrayDouble::setPartOfValues4 : input DataArrayDouble is NULL !");
2457   const char msg[]="DataArrayDouble::setPartOfValues4";
2458   checkAllocated();
2459   a->checkAllocated();
2460   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
2461   int newNbOfComp=(int)std::distance(bgComp,endComp);
2462   int nbComp=getNumberOfComponents();
2463   for(const int *z=bgComp;z!=endComp;z++)
2464     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
2465   int nbOfTuples=getNumberOfTuples();
2466   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
2467   bool assignTech=true;
2468   if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
2469     {
2470       if(strictCompoCompare)
2471         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
2472     }
2473   else
2474     {
2475       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
2476       assignTech=false;
2477     }
2478   const double *srcPt=a->getConstPointer();
2479   double *pt=getPointer()+bgTuples*nbComp;
2480   if(assignTech)
2481     {
2482       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
2483         for(const int *z=bgComp;z!=endComp;z++,srcPt++)
2484           pt[*z]=*srcPt;
2485     }
2486   else
2487     {
2488       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
2489         {
2490           const double *srcPt2=srcPt;
2491           for(const int *z=bgComp;z!=endComp;z++,srcPt2++)
2492             pt[*z]=*srcPt2;
2493         }
2494     }
2495 }
2496
2497 void DataArrayDouble::setPartOfValuesSimple4(double a, int bgTuples, int endTuples, int stepTuples, const int *bgComp, const int *endComp) throw(INTERP_KERNEL::Exception)
2498 {
2499   const char msg[]="DataArrayDouble::setPartOfValuesSimple4";
2500   checkAllocated();
2501   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
2502   int nbComp=getNumberOfComponents();
2503   for(const int *z=bgComp;z!=endComp;z++)
2504     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
2505   int nbOfTuples=getNumberOfTuples();
2506   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
2507   double *pt=getPointer()+bgTuples*nbComp;
2508   for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
2509     for(const int *z=bgComp;z!=endComp;z++)
2510       pt[*z]=a;
2511 }
2512
2513 /*!
2514  * Copy some tuples from another DataArrayDouble into specified tuples
2515  * of \a this array. Textual data is not copied. Both arrays must have equal number of
2516  * components.
2517  * Both the tuples to assign and the tuples to assign to are defined by a DataArrayInt.
2518  * All components of selected tuples are copied.
2519  *  \param [in] a - the array to copy values from.
2520  *  \param [in] tuplesSelec - the array specifying both source tuples of \a a and
2521  *              target tuples of \a this. \a tuplesSelec has two components, and the
2522  *              first component specifies index of the source tuple and the second
2523  *              one specifies index of the target tuple.
2524  *  \throw If \a this is not allocated.
2525  *  \throw If \a a is NULL.
2526  *  \throw If \a a is not allocated.
2527  *  \throw If \a tuplesSelec is NULL.
2528  *  \throw If \a tuplesSelec is not allocated.
2529  *  \throw If <em>this->getNumberOfComponents() != a->getNumberOfComponents()</em>.
2530  *  \throw If \a tuplesSelec->getNumberOfComponents() != 2.
2531  *  \throw If any tuple index given by \a tuplesSelec is out of a valid range for 
2532  *         the corresponding (\a this or \a a) array.
2533  */
2534 void DataArrayDouble::setPartOfValuesAdv(const DataArrayDouble *a, const DataArrayInt *tuplesSelec) throw(INTERP_KERNEL::Exception)
2535 {
2536   if(!a || !tuplesSelec)
2537     throw INTERP_KERNEL::Exception("DataArrayDouble::setPartOfValuesAdv : input DataArrayDouble is NULL !");
2538   checkAllocated();
2539   a->checkAllocated();
2540   tuplesSelec->checkAllocated();
2541   int nbOfComp=getNumberOfComponents();
2542   if(nbOfComp!=a->getNumberOfComponents())
2543     throw INTERP_KERNEL::Exception("DataArrayDouble::setPartOfValuesAdv : This and a do not have the same number of components !");
2544   if(tuplesSelec->getNumberOfComponents()!=2)
2545     throw INTERP_KERNEL::Exception("DataArrayDouble::setPartOfValuesAdv : Expecting to have a tuple selector DataArrayInt instance with exactly 2 components !");
2546   int thisNt=getNumberOfTuples();
2547   int aNt=a->getNumberOfTuples();
2548   double *valsToSet=getPointer();
2549   const double *valsSrc=a->getConstPointer();
2550   for(const int *tuple=tuplesSelec->begin();tuple!=tuplesSelec->end();tuple+=2)
2551     {
2552       if(tuple[1]>=0 && tuple[1]<aNt)
2553         {
2554           if(tuple[0]>=0 && tuple[0]<thisNt)
2555             std::copy(valsSrc+nbOfComp*tuple[1],valsSrc+nbOfComp*(tuple[1]+1),valsToSet+nbOfComp*tuple[0]);
2556           else
2557             {
2558               std::ostringstream oss; oss << "DataArrayDouble::setPartOfValuesAdv : Tuple #" << std::distance(tuplesSelec->begin(),tuple)/2;
2559               oss << " of 'tuplesSelec' request of tuple id #" << tuple[0] << " in 'this' ! It should be in [0," << thisNt << ") !";
2560               throw INTERP_KERNEL::Exception(oss.str().c_str());
2561             }
2562         }
2563       else
2564         {
2565           std::ostringstream oss; oss << "DataArrayDouble::setPartOfValuesAdv : Tuple #" << std::distance(tuplesSelec->begin(),tuple)/2;
2566           oss << " of 'tuplesSelec' request of tuple id #" << tuple[1] << " in 'a' ! It should be in [0," << aNt << ") !";
2567           throw INTERP_KERNEL::Exception(oss.str().c_str());
2568         }
2569     }
2570 }
2571
2572 /*!
2573  * Copy some tuples from another DataArrayDouble (\a a) into contiguous tuples
2574  * of \a this array. Textual data is not copied. Both arrays must have equal number of
2575  * components.
2576  * The tuples to assign to are defined by index of the first tuple, and
2577  * their number is defined by \a tuplesSelec->getNumberOfTuples().
2578  * The tuples to copy are defined by values of a DataArrayInt.
2579  * All components of selected tuples are copied.
2580  *  \param [in] tupleIdStart - index of the first tuple of \a this array to assign
2581  *              values to.
2582  *  \param [in] a - the array to copy values from.
2583  *  \param [in] tuplesSelec - the array specifying tuples of \a a to copy.
2584  *  \throw If \a this is not allocated.
2585  *  \throw If \a a is NULL.
2586  *  \throw If \a a is not allocated.
2587  *  \throw If \a tuplesSelec is NULL.
2588  *  \throw If \a tuplesSelec is not allocated.
2589  *  \throw If <em>this->getNumberOfComponents() != a->getNumberOfComponents()</em>.
2590  *  \throw If \a tuplesSelec->getNumberOfComponents() != 1.
2591  *  \throw If <em>tupleIdStart + tuplesSelec->getNumberOfTuples() > this->getNumberOfTuples().</em>
2592  *  \throw If any tuple index given by \a tuplesSelec is out of a valid range for 
2593  *         \a a array.
2594  */
2595 void DataArrayDouble::setContigPartOfSelectedValues(int tupleIdStart, const DataArray *aBase, const DataArrayInt *tuplesSelec) throw(INTERP_KERNEL::Exception)
2596 {
2597   if(!aBase || !tuplesSelec)
2598     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues : input DataArray is NULL !");
2599   const DataArrayDouble *a=dynamic_cast<const DataArrayDouble *>(aBase);
2600   if(!a)
2601     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues : input DataArray aBase is not a DataArrayDouble !");
2602   checkAllocated();
2603   a->checkAllocated();
2604   tuplesSelec->checkAllocated();
2605   int nbOfComp=getNumberOfComponents();
2606   if(nbOfComp!=a->getNumberOfComponents())
2607     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues : This and a do not have the same number of components !");
2608   if(tuplesSelec->getNumberOfComponents()!=1)
2609     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues : Expecting to have a tuple selector DataArrayInt instance with exactly 1 component !");
2610   int thisNt=getNumberOfTuples();
2611   int aNt=a->getNumberOfTuples();
2612   int nbOfTupleToWrite=tuplesSelec->getNumberOfTuples();
2613   double *valsToSet=getPointer()+tupleIdStart*nbOfComp;
2614   if(tupleIdStart+nbOfTupleToWrite>thisNt)
2615     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues : invalid number range of values to write !");
2616   const double *valsSrc=a->getConstPointer();
2617   for(const int *tuple=tuplesSelec->begin();tuple!=tuplesSelec->end();tuple++,valsToSet+=nbOfComp)
2618     {
2619       if(*tuple>=0 && *tuple<aNt)
2620         {
2621           std::copy(valsSrc+nbOfComp*(*tuple),valsSrc+nbOfComp*(*tuple+1),valsToSet);
2622         }
2623       else
2624         {
2625           std::ostringstream oss; oss << "DataArrayDouble::setContigPartOfSelectedValues : Tuple #" << std::distance(tuplesSelec->begin(),tuple);
2626           oss << " of 'tuplesSelec' request of tuple id #" << *tuple << " in 'a' ! It should be in [0," << aNt << ") !";
2627           throw INTERP_KERNEL::Exception(oss.str().c_str());
2628         }
2629     }
2630 }
2631
2632 /*!
2633  * Copy some tuples from another DataArrayDouble (\a a) into contiguous tuples
2634  * of \a this array. Textual data is not copied. Both arrays must have equal number of
2635  * components.
2636  * The tuples to copy are defined by three values similar to parameters of
2637  * the Python function \c range(\c start,\c stop,\c step).
2638  * The tuples to assign to are defined by index of the first tuple, and
2639  * their number is defined by number of tuples to copy.
2640  * All components of selected tuples are copied.
2641  *  \param [in] tupleIdStart - index of the first tuple of \a this array to assign
2642  *              values to.
2643  *  \param [in] a - the array to copy values from.
2644  *  \param [in] bg - index of the first tuple to copy of the array \a a.
2645  *  \param [in] end2 - index of the tuple of \a a before which the tuples to copy
2646  *              are located.
2647  *  \param [in] step - index increment to get index of the next tuple to copy.
2648  *  \throw If \a this is not allocated.
2649  *  \throw If \a a is NULL.
2650  *  \throw If \a a is not allocated.
2651  *  \throw If <em>this->getNumberOfComponents() != a->getNumberOfComponents()</em>.
2652  *  \throw If <em>tupleIdStart + len(range(bg,end2,step)) > this->getNumberOfTuples().</em>
2653  *  \throw If parameters specifying tuples to copy, do not give a
2654  *            non-empty range of increasing indices or indices are out of a valid range
2655  *            for the array \a a.
2656  */
2657 void DataArrayDouble::setContigPartOfSelectedValues2(int tupleIdStart, const DataArray *aBase, int bg, int end2, int step) throw(INTERP_KERNEL::Exception)
2658 {
2659   if(!aBase)
2660     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues2 : input DataArray is NULL !");
2661   const DataArrayDouble *a=dynamic_cast<const DataArrayDouble *>(aBase);
2662   if(!a)
2663     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues2 : input DataArray aBase is not a DataArrayDouble !");
2664   checkAllocated();
2665   a->checkAllocated();
2666   int nbOfComp=getNumberOfComponents();
2667   const char msg[]="DataArrayDouble::setContigPartOfSelectedValues2";
2668   int nbOfTupleToWrite=DataArray::GetNumberOfItemGivenBES(bg,end2,step,msg);
2669   if(nbOfComp!=a->getNumberOfComponents())
2670     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues2 : This and a do not have the same number of components !");
2671   int thisNt=getNumberOfTuples();
2672   int aNt=a->getNumberOfTuples();
2673   double *valsToSet=getPointer()+tupleIdStart*nbOfComp;
2674   if(tupleIdStart+nbOfTupleToWrite>thisNt)
2675     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues2 : invalid number range of values to write !");
2676   if(end2>aNt)
2677     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues2 : invalid range of values to read !");
2678   const double *valsSrc=a->getConstPointer()+bg*nbOfComp;
2679   for(int i=0;i<nbOfTupleToWrite;i++,valsToSet+=nbOfComp,valsSrc+=step*nbOfComp)
2680     {
2681       std::copy(valsSrc,valsSrc+nbOfComp,valsToSet);
2682     }
2683 }
2684
2685 /*!
2686  * Returns a value located at specified tuple and component.
2687  * This method is equivalent to DataArrayDouble::getIJ() except that validity of
2688  * parameters is checked. So this method is safe but expensive if used to go through
2689  * all values of \a this.
2690  *  \param [in] tupleId - index of tuple of interest.
2691  *  \param [in] compoId - index of component of interest.
2692  *  \return double - value located by \a tupleId and \a compoId.
2693  *  \throw If \a this is not allocated.
2694  *  \throw If condition <em>( 0 <= tupleId < this->getNumberOfTuples() )</em> is violated.
2695  *  \throw If condition <em>( 0 <= compoId < this->getNumberOfComponents() )</em> is violated.
2696  */
2697 double DataArrayDouble::getIJSafe(int tupleId, int compoId) const throw(INTERP_KERNEL::Exception)
2698 {
2699   checkAllocated();
2700   if(tupleId<0 || tupleId>=getNumberOfTuples())
2701     {
2702       std::ostringstream oss; oss << "DataArrayDouble::getIJSafe : request for tupleId " << tupleId << " should be in [0," << getNumberOfTuples() << ") !";
2703       throw INTERP_KERNEL::Exception(oss.str().c_str());
2704     }
2705   if(compoId<0 || compoId>=getNumberOfComponents())
2706     {
2707       std::ostringstream oss; oss << "DataArrayDouble::getIJSafe : request for compoId " << compoId << " should be in [0," << getNumberOfComponents() << ") !";
2708       throw INTERP_KERNEL::Exception(oss.str().c_str());
2709     }
2710   return _mem[tupleId*_info_on_compo.size()+compoId];
2711 }
2712
2713 /*!
2714  * Returns the first value of \a this. 
2715  *  \return double - the last value of \a this array.
2716  *  \throw If \a this is not allocated.
2717  *  \throw If \a this->getNumberOfComponents() != 1.
2718  *  \throw If \a this->getNumberOfTuples() < 1.
2719  */
2720 double DataArrayDouble::front() const throw(INTERP_KERNEL::Exception)
2721 {
2722   checkAllocated();
2723   if(getNumberOfComponents()!=1)
2724     throw INTERP_KERNEL::Exception("DataArrayDouble::front : number of components not equal to one !");
2725   int nbOfTuples=getNumberOfTuples();
2726   if(nbOfTuples<1)
2727     throw INTERP_KERNEL::Exception("DataArrayDouble::front : number of tuples must be >= 1 !");
2728   return *(getConstPointer());
2729 }
2730
2731 /*!
2732  * Returns the last value of \a this. 
2733  *  \return double - the last value of \a this array.
2734  *  \throw If \a this is not allocated.
2735  *  \throw If \a this->getNumberOfComponents() != 1.
2736  *  \throw If \a this->getNumberOfTuples() < 1.
2737  */
2738 double DataArrayDouble::back() const throw(INTERP_KERNEL::Exception)
2739 {
2740   checkAllocated();
2741   if(getNumberOfComponents()!=1)
2742     throw INTERP_KERNEL::Exception("DataArrayDouble::back : number of components not equal to one !");
2743   int nbOfTuples=getNumberOfTuples();
2744   if(nbOfTuples<1)
2745     throw INTERP_KERNEL::Exception("DataArrayDouble::back : number of tuples must be >= 1 !");
2746   return *(getConstPointer()+nbOfTuples-1);
2747 }
2748
2749 void DataArrayDouble::SetArrayIn(DataArrayDouble *newArray, DataArrayDouble* &arrayToSet)
2750 {
2751   if(newArray!=arrayToSet)
2752     {
2753       if(arrayToSet)
2754         arrayToSet->decrRef();
2755       arrayToSet=newArray;
2756       if(arrayToSet)
2757         arrayToSet->incrRef();
2758     }
2759 }
2760
2761 /*!
2762  * Sets a C array to be used as raw data of \a this. The previously set info
2763  *  of components is retained and re-sized. 
2764  * For more info see \ref MEDCouplingArraySteps1.
2765  *  \param [in] array - the C array to be used as raw data of \a this.
2766  *  \param [in] ownership - if \a true, \a array will be deallocated at destruction of \a this.
2767  *  \param [in] type - specifies how to deallocate \a array. If \a type == ParaMEDMEM::CPP_DEALLOC,
2768  *                     \c delete [] \c array; will be called. If \a type == ParaMEDMEM::C_DEALLOC,
2769  *                     \c free(\c array ) will be called.
2770  *  \param [in] nbOfTuple - new number of tuples in \a this.
2771  *  \param [in] nbOfCompo - new number of components in \a this.
2772  */
2773 void DataArrayDouble::useArray(const double *array, bool ownership, DeallocType type, int nbOfTuple, int nbOfCompo) throw(INTERP_KERNEL::Exception)
2774 {
2775   _info_on_compo.resize(nbOfCompo);
2776   _mem.useArray(array,ownership,type,(std::size_t)nbOfTuple*nbOfCompo);
2777   declareAsNew();
2778 }
2779
2780 void DataArrayDouble::useExternalArrayWithRWAccess(const double *array, int nbOfTuple, int nbOfCompo) throw(INTERP_KERNEL::Exception)
2781 {
2782   _info_on_compo.resize(nbOfCompo);
2783   _mem.useExternalArrayWithRWAccess(array,(std::size_t)nbOfTuple*nbOfCompo);
2784   declareAsNew();
2785 }
2786
2787 /*!
2788  * Checks if 0.0 value is present in \a this array. If it is the case, an exception
2789  * is thrown.
2790  * \throw If zero is found in \a this array.
2791  */
2792 void DataArrayDouble::checkNoNullValues() const throw(INTERP_KERNEL::Exception)
2793 {
2794   const double *tmp=getConstPointer();
2795   std::size_t nbOfElems=getNbOfElems();
2796   const double *where=std::find(tmp,tmp+nbOfElems,0.);
2797   if(where!=tmp+nbOfElems)
2798     throw INTERP_KERNEL::Exception("A value 0.0 have been detected !");
2799 }
2800
2801 /*!
2802  * Computes minimal and maximal value in each component. An output array is filled
2803  * with \c 2 * \a this->getNumberOfComponents() values, so the caller is to allocate
2804  * enough memory before calling this method.
2805  *  \param [out] bounds - array of size at least 2 *\a this->getNumberOfComponents().
2806  *               It is filled as follows:<br>
2807  *               \a bounds[0] = \c min_of_component_0 <br>
2808  *               \a bounds[1] = \c max_of_component_0 <br>
2809  *               \a bounds[2] = \c min_of_component_1 <br>
2810  *               \a bounds[3] = \c max_of_component_1 <br>
2811  *               ...
2812  */
2813 void DataArrayDouble::getMinMaxPerComponent(double *bounds) const throw(INTERP_KERNEL::Exception)
2814 {
2815   checkAllocated();
2816   int dim=getNumberOfComponents();
2817   for (int idim=0; idim<dim; idim++)
2818     {
2819       bounds[idim*2]=std::numeric_limits<double>::max();
2820       bounds[idim*2+1]=-std::numeric_limits<double>::max();
2821     } 
2822   const double *ptr=getConstPointer();
2823   int nbOfTuples=getNumberOfTuples();
2824   for(int i=0;i<nbOfTuples;i++)
2825     {
2826       for(int idim=0;idim<dim;idim++)
2827         {
2828           if(bounds[idim*2]>ptr[i*dim+idim])
2829             {
2830               bounds[idim*2]=ptr[i*dim+idim];
2831             }
2832           if(bounds[idim*2+1]<ptr[i*dim+idim])
2833             {
2834               bounds[idim*2+1]=ptr[i*dim+idim];
2835             }
2836         }
2837     }
2838 }
2839
2840 /*!
2841  * This method retrieves a newly allocated DataArrayDouble instance having same number of tuples than \a this and twice number of components than \a this
2842  * to store both the min and max per component of each tuples. 
2843  * \param [in] epsilon the width of the bbox (identical in each direction) - 0.0 by default
2844  *
2845  * \return a newly created DataArrayDouble instance having \c this->getNumberOfTuples() tuples and 2 * \c this->getNumberOfComponent() components
2846  *
2847  * \throw If \a this is not allocated yet.
2848  */
2849 DataArrayDouble *DataArrayDouble::computeBBoxPerTuple(double epsilon)const throw(INTERP_KERNEL::Exception)
2850 {
2851   checkAllocated();
2852   const double *dataPtr=getConstPointer();
2853   int nbOfCompo=getNumberOfComponents();
2854   int nbTuples=getNumberOfTuples();
2855   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> bbox=DataArrayDouble::New();
2856   bbox->alloc(nbTuples,2*nbOfCompo);
2857   double *bboxPtr=bbox->getPointer();
2858   for(int i=0;i<nbTuples;i++)
2859     {
2860       for(int j=0;j<nbOfCompo;j++)
2861         {
2862           bboxPtr[2*nbOfCompo*i+2*j]=dataPtr[nbOfCompo*i+j]-epsilon;
2863           bboxPtr[2*nbOfCompo*i+2*j+1]=dataPtr[nbOfCompo*i+j]+epsilon;
2864         }
2865     }
2866   return bbox.retn();
2867 }
2868
2869 /*!
2870  * For each tuples **t** in \a other, this method retrieves tuples in \a this that are equal to **t**.
2871  * Two tuples are considered equal if the euclidian distance between the two tuples is lower than \a eps.
2872  * 
2873  * \param [in] other a DataArrayDouble having same number of components than \a this.
2874  * \param [in] eps absolute precision representing distance (using infinite norm) between 2 tuples behind which 2 tuples are considered equal.
2875  * \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.
2876  *             \a cI allows to extract information in \a c.
2877  * \param [out] cI is an indirection array that allows to extract the data contained in \a c.
2878  *
2879  * \throw In case of:
2880  *  - \a this is not allocated
2881  *  - \a other is not allocated or null
2882  *  - \a this and \a other do not have the same number of components
2883  *  - if number of components of \a this is not in [1,2,3]
2884  *
2885  * \sa MEDCouplingPointSet::getNodeIdsNearPoints, DataArrayDouble::getDifferentValues
2886  */
2887 void DataArrayDouble::computeTupleIdsNearTuples(const DataArrayDouble *other, double eps, DataArrayInt *& c, DataArrayInt *& cI) const throw(INTERP_KERNEL::Exception)
2888 {
2889   if(!other)
2890     throw INTERP_KERNEL::Exception("DataArrayDouble::computeTupleIdsNearTuples : input pointer other is null !");
2891   checkAllocated();
2892   other->checkAllocated();
2893   int nbOfCompo=getNumberOfComponents();
2894   int otherNbOfCompo=other->getNumberOfComponents();
2895   if(nbOfCompo!=otherNbOfCompo)
2896     throw INTERP_KERNEL::Exception("DataArrayDouble::computeTupleIdsNearTuples : number of components should be equal between this and other !");
2897   int nbOfTuplesOther=other->getNumberOfTuples();
2898   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cArr(DataArrayInt::New()),cIArr(DataArrayInt::New()); cArr->alloc(0,1); cIArr->pushBackSilent(0);
2899   switch(nbOfCompo)
2900     {
2901     case 3:
2902       {
2903         BBTreePts<3,int> myTree(begin(),0,0,getNumberOfTuples(),eps);
2904         FindTupleIdsNearTuplesAlg<3>(myTree,other->getConstPointer(),nbOfTuplesOther,eps,cArr,cIArr);
2905         break;
2906       }
2907     case 2:
2908       {
2909         BBTreePts<2,int> myTree(begin(),0,0,getNumberOfTuples(),eps);
2910         FindTupleIdsNearTuplesAlg<2>(myTree,other->getConstPointer(),nbOfTuplesOther,eps,cArr,cIArr);
2911         break;
2912       }
2913     case 1:
2914       {
2915         BBTreePts<1,int> myTree(begin(),0,0,getNumberOfTuples(),eps);
2916         FindTupleIdsNearTuplesAlg<1>(myTree,other->getConstPointer(),nbOfTuplesOther,eps,cArr,cIArr);
2917         break;
2918       }
2919     default:
2920       throw INTERP_KERNEL::Exception("Unexpected spacedim of coords for computeTupleIdsNearTuples. Must be 1, 2 or 3.");
2921     }
2922   c=cArr.retn(); cI=cIArr.retn();
2923 }
2924
2925 /*!
2926  * 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
2927  * around origin of 'radius' 1.
2928  * 
2929  * \param [in] eps absolute epsilon. under that value of delta between max and min no scale is performed.
2930  */
2931 void DataArrayDouble::recenterForMaxPrecision(double eps) throw(INTERP_KERNEL::Exception)
2932 {
2933   checkAllocated();
2934   int dim=getNumberOfComponents();
2935   std::vector<double> bounds(2*dim);
2936   getMinMaxPerComponent(&bounds[0]);
2937   for(int i=0;i<dim;i++)
2938     {
2939       double delta=bounds[2*i+1]-bounds[2*i];
2940       double offset=(bounds[2*i]+bounds[2*i+1])/2.;
2941       if(delta>eps)
2942         applyLin(1./delta,-offset/delta,i);
2943       else
2944         applyLin(1.,-offset,i);
2945     }
2946 }
2947
2948 /*!
2949  * Returns the maximal value and its location within \a this one-dimensional array.
2950  *  \param [out] tupleId - index of the tuple holding the maximal value.
2951  *  \return double - the maximal value among all values of \a this array.
2952  *  \throw If \a this->getNumberOfComponents() != 1
2953  *  \throw If \a this->getNumberOfTuples() < 1
2954  */
2955 double DataArrayDouble::getMaxValue(int& tupleId) const throw(INTERP_KERNEL::Exception)
2956 {
2957   checkAllocated();
2958   if(getNumberOfComponents()!=1)
2959     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 !");
2960   int nbOfTuples=getNumberOfTuples();
2961   if(nbOfTuples<=0)
2962     throw INTERP_KERNEL::Exception("DataArrayDouble::getMaxValue : array exists but number of tuples must be > 0 !");
2963   const double *vals=getConstPointer();
2964   const double *loc=std::max_element(vals,vals+nbOfTuples);
2965   tupleId=(int)std::distance(vals,loc);
2966   return *loc;
2967 }
2968
2969 /*!
2970  * Returns the maximal value within \a this array that is allowed to have more than
2971  *  one component.
2972  *  \return double - the maximal value among all values of \a this array.
2973  *  \throw If \a this is not allocated.
2974  */
2975 double DataArrayDouble::getMaxValueInArray() const throw(INTERP_KERNEL::Exception)
2976 {
2977   checkAllocated();
2978   const double *loc=std::max_element(begin(),end());
2979   return *loc;
2980 }
2981
2982 /*!
2983  * Returns the maximal value and all its locations within \a this one-dimensional array.
2984  *  \param [out] tupleIds - a new instance of DataArrayInt containg indices of
2985  *               tuples holding the maximal value. The caller is to delete it using
2986  *               decrRef() as it is no more needed.
2987  *  \return double - the maximal value among all values of \a this array.
2988  *  \throw If \a this->getNumberOfComponents() != 1
2989  *  \throw If \a this->getNumberOfTuples() < 1
2990  */
2991 double DataArrayDouble::getMaxValue2(DataArrayInt*& tupleIds) const throw(INTERP_KERNEL::Exception)
2992 {
2993   int tmp;
2994   tupleIds=0;
2995   double ret=getMaxValue(tmp);
2996   tupleIds=getIdsInRange(ret,ret);
2997   return ret;
2998 }
2999
3000 /*!
3001  * Returns the minimal value and its location within \a this one-dimensional array.
3002  *  \param [out] tupleId - index of the tuple holding the minimal value.
3003  *  \return double - the minimal value among all values of \a this array.
3004  *  \throw If \a this->getNumberOfComponents() != 1
3005  *  \throw If \a this->getNumberOfTuples() < 1
3006  */
3007 double DataArrayDouble::getMinValue(int& tupleId) const throw(INTERP_KERNEL::Exception)
3008 {
3009   checkAllocated();
3010   if(getNumberOfComponents()!=1)
3011     throw INTERP_KERNEL::Exception("DataArrayDouble::getMinValue : must be applied on DataArrayDouble with only one component, you can call 'rearrange' method before call 'getMinValueInArray' method !");
3012   int nbOfTuples=getNumberOfTuples();
3013   if(nbOfTuples<=0)
3014     throw INTERP_KERNEL::Exception("DataArrayDouble::getMinValue : array exists but number of tuples must be > 0 !");
3015   const double *vals=getConstPointer();
3016   const double *loc=std::min_element(vals,vals+nbOfTuples);
3017   tupleId=(int)std::distance(vals,loc);
3018   return *loc;
3019 }
3020
3021 /*!
3022  * Returns the minimal value within \a this array that is allowed to have more than
3023  *  one component.
3024  *  \return double - the minimal value among all values of \a this array.
3025  *  \throw If \a this is not allocated.
3026  */
3027 double DataArrayDouble::getMinValueInArray() const throw(INTERP_KERNEL::Exception)
3028 {
3029   checkAllocated();
3030   const double *loc=std::min_element(begin(),end());
3031   return *loc;
3032 }
3033
3034 /*!
3035  * Returns the minimal value and all its locations within \a this one-dimensional array.
3036  *  \param [out] tupleIds - a new instance of DataArrayInt containg indices of
3037  *               tuples holding the minimal value. The caller is to delete it using
3038  *               decrRef() as it is no more needed.
3039  *  \return double - the minimal value among all values of \a this array.
3040  *  \throw If \a this->getNumberOfComponents() != 1
3041  *  \throw If \a this->getNumberOfTuples() < 1
3042  */
3043 double DataArrayDouble::getMinValue2(DataArrayInt*& tupleIds) const throw(INTERP_KERNEL::Exception)
3044 {
3045   int tmp;
3046   tupleIds=0;
3047   double ret=getMinValue(tmp);
3048   tupleIds=getIdsInRange(ret,ret);
3049   return ret;
3050 }
3051
3052 /*!
3053  * 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.
3054  * This method only works for single component array.
3055  *
3056  * \return a value in [ 0, \c this->getNumberOfTuples() )
3057  *
3058  * \throw If \a this is not allocated
3059  *
3060  */
3061 int DataArrayDouble::count(double value, double eps) const throw(INTERP_KERNEL::Exception)
3062 {
3063   int ret=0;
3064   checkAllocated();
3065   if(getNumberOfComponents()!=1)
3066     throw INTERP_KERNEL::Exception("DataArrayDouble::count : must be applied on DataArrayDouble with only one component, you can call 'rearrange' method before !");
3067   const double *vals=begin();
3068   int nbOfTuples=getNumberOfTuples();
3069   for(int i=0;i<nbOfTuples;i++,vals++)
3070     if(fabs(*vals-value)<=eps)
3071       ret++;
3072   return ret;
3073 }
3074
3075 /*!
3076  * Returns the average value of \a this one-dimensional array.
3077  *  \return double - the average value over all values of \a this array.
3078  *  \throw If \a this->getNumberOfComponents() != 1
3079  *  \throw If \a this->getNumberOfTuples() < 1
3080  */
3081 double DataArrayDouble::getAverageValue() const throw(INTERP_KERNEL::Exception)
3082 {
3083   if(getNumberOfComponents()!=1)
3084     throw INTERP_KERNEL::Exception("DataArrayDouble::getAverageValue : must be applied on DataArrayDouble with only one component, you can call 'rearrange' method before !");
3085   int nbOfTuples=getNumberOfTuples();
3086   if(nbOfTuples<=0)
3087     throw INTERP_KERNEL::Exception("DataArrayDouble::getAverageValue : array exists but number of tuples must be > 0 !");
3088   const double *vals=getConstPointer();
3089   double ret=std::accumulate(vals,vals+nbOfTuples,0.);
3090   return ret/nbOfTuples;
3091 }
3092
3093 /*!
3094  * Returns the Euclidean norm of the vector defined by \a this array.
3095  *  \return double - the value of the Euclidean norm, i.e.
3096  *          the square root of the inner product of vector.
3097  *  \throw If \a this is not allocated.
3098  */
3099 double DataArrayDouble::norm2() const throw(INTERP_KERNEL::Exception)
3100 {
3101   checkAllocated();
3102   double ret=0.;
3103   std::size_t nbOfElems=getNbOfElems();
3104   const double *pt=getConstPointer();
3105   for(std::size_t i=0;i<nbOfElems;i++,pt++)
3106     ret+=(*pt)*(*pt);
3107   return sqrt(ret);
3108 }
3109
3110 /*!
3111  * Returns the maximum norm of the vector defined by \a this array.
3112  *  \return double - the value of the maximum norm, i.e.
3113  *          the maximal absolute value among values of \a this array.
3114  *  \throw If \a this is not allocated.
3115  */
3116 double DataArrayDouble::normMax() const throw(INTERP_KERNEL::Exception)
3117 {
3118   checkAllocated();
3119   double ret=-1.;
3120   std::size_t nbOfElems=getNbOfElems();
3121   const double *pt=getConstPointer();
3122   for(std::size_t i=0;i<nbOfElems;i++,pt++)
3123     {
3124       double val=std::abs(*pt);
3125       if(val>ret)
3126         ret=val;
3127     }
3128   return ret;
3129 }
3130
3131 /*!
3132  * Accumulates values of each component of \a this array.
3133  *  \param [out] res - an array of length \a this->getNumberOfComponents(), allocated 
3134  *         by the caller, that is filled by this method with sum value for each
3135  *         component.
3136  *  \throw If \a this is not allocated.
3137  */
3138 void DataArrayDouble::accumulate(double *res) const throw(INTERP_KERNEL::Exception)
3139 {
3140   checkAllocated();
3141   const double *ptr=getConstPointer();
3142   int nbTuple=getNumberOfTuples();
3143   int nbComps=getNumberOfComponents();
3144   std::fill(res,res+nbComps,0.);
3145   for(int i=0;i<nbTuple;i++)
3146     std::transform(ptr+i*nbComps,ptr+(i+1)*nbComps,res,res,std::plus<double>());
3147 }
3148
3149 /*!
3150  * This method returns the min distance from an external tuple defined by [ \a tupleBg , \a tupleEnd ) to \a this and
3151  * the first tuple in \a this that matches the returned distance. If there is no tuples in \a this an exception will be thrown.
3152  *
3153  *
3154  * \a this is expected to be allocated and expected to have a number of components equal to the distance from \a tupleBg to
3155  * \a tupleEnd. If not an exception will be thrown.
3156  *
3157  * \param [in] tupleBg start pointer (included) of input external tuple
3158  * \param [in] tupleEnd end pointer (not included) of input external tuple
3159  * \param [out] tupleId the tuple id in \a this that matches the min of distance between \a this and input external tuple
3160  * \return the min distance.
3161  * \sa MEDCouplingUMesh::distanceToPoint
3162  */
3163 double DataArrayDouble::distanceToTuple(const double *tupleBg, const double *tupleEnd, int& tupleId) const throw(INTERP_KERNEL::Exception)
3164 {
3165   checkAllocated();
3166   int nbTuple=getNumberOfTuples();
3167   int nbComps=getNumberOfComponents();
3168   if(nbComps!=(int)std::distance(tupleBg,tupleEnd))
3169     { 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()); }
3170   if(nbTuple==0)
3171     throw INTERP_KERNEL::Exception("DataArrayDouble::distanceToTuple : no tuple in this ! No distance to compute !");
3172   double ret0=std::numeric_limits<double>::max();
3173   tupleId=-1;
3174   const double *work=getConstPointer();
3175   for(int i=0;i<nbTuple;i++)
3176     {
3177       double val=0.;
3178       for(int j=0;j<nbComps;j++,work++) 
3179         val+=(*work-tupleBg[j])*((*work-tupleBg[j]));
3180       if(val>=ret0)
3181         continue;
3182       else
3183         { ret0=val; tupleId=i; }
3184     }
3185   return sqrt(ret0);
3186 }
3187
3188 /*!
3189  * Accumulate values of the given component of \a this array.
3190  *  \param [in] compId - the index of the component of interest.
3191  *  \return double - a sum value of \a compId-th component.
3192  *  \throw If \a this is not allocated.
3193  *  \throw If \a the condition ( 0 <= \a compId < \a this->getNumberOfComponents() ) is
3194  *         not respected.
3195  */
3196 double DataArrayDouble::accumulate(int compId) const throw(INTERP_KERNEL::Exception)
3197 {
3198   checkAllocated();
3199   const double *ptr=getConstPointer();
3200   int nbTuple=getNumberOfTuples();
3201   int nbComps=getNumberOfComponents();
3202   if(compId<0 || compId>=nbComps)
3203     throw INTERP_KERNEL::Exception("DataArrayDouble::accumulate : Invalid compId specified : No such nb of components !");
3204   double ret=0.;
3205   for(int i=0;i<nbTuple;i++)
3206     ret+=ptr[i*nbComps+compId];
3207   return ret;
3208 }
3209
3210 /*!
3211  * This method accumulate using addition tuples in \a this using input index array [ \a bgOfIndex, \a endOfIndex ).
3212  * The returned array will have same number of components than \a this and number of tuples equal to
3213  * \c std::distance(bgOfIndex,endOfIndex) \b minus \b one.
3214  *
3215  * The input index array is expected to be ascendingly sorted in which the all referenced ids should be in [0, \c this->getNumberOfTuples).
3216  * 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.
3217  *
3218  * \param [in] bgOfIndex - begin (included) of the input index array.
3219  * \param [in] endOfIndex - end (excluded) of the input index array.
3220  * \return DataArrayDouble * - the new instance having the same number of components than \a this.
3221  * 
3222  * \throw If bgOfIndex or end is NULL.
3223  * \throw If input index array is not ascendingly sorted.
3224  * \throw If there is an id in [ \a bgOfIndex, \a endOfIndex ) not in [0, \c this->getNumberOfTuples).
3225  * \throw If std::distance(bgOfIndex,endOfIndex)==0.
3226  */
3227 DataArrayDouble *DataArrayDouble::accumulatePerChunck(const int *bgOfIndex, const int *endOfIndex) const throw(INTERP_KERNEL::Exception)
3228 {
3229   if(!bgOfIndex || !endOfIndex)
3230     throw INTERP_KERNEL::Exception("DataArrayDouble::accumulatePerChunck : input pointer NULL !");
3231   checkAllocated();
3232   int nbCompo=getNumberOfComponents();
3233   int nbOfTuples=getNumberOfTuples();
3234   int sz=(int)std::distance(bgOfIndex,endOfIndex);
3235   if(sz<1)
3236     throw INTERP_KERNEL::Exception("DataArrayDouble::accumulatePerChunck : invalid size of input index array !");
3237   sz--;
3238   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New(); ret->alloc(sz,nbCompo);
3239   const int *w=bgOfIndex;
3240   if(*w<0 || *w>=nbOfTuples)
3241     throw INTERP_KERNEL::Exception("DataArrayDouble::accumulatePerChunck : The first element of the input index not in [0,nbOfTuples) !");
3242   const double *srcPt=begin()+(*w)*nbCompo;
3243   double *tmp=ret->getPointer();
3244   for(int i=0;i<sz;i++,tmp+=nbCompo,w++)
3245     {
3246       std::fill(tmp,tmp+nbCompo,0.);
3247       if(w[1]>=w[0])
3248         {
3249           for(int j=w[0];j<w[1];j++,srcPt+=nbCompo)
3250             {
3251               if(j>=0 && j<nbOfTuples)
3252                 std::transform(srcPt,srcPt+nbCompo,tmp,tmp,std::plus<double>());
3253               else
3254                 {
3255                   std::ostringstream oss; oss << "DataArrayDouble::accumulatePerChunck : At rank #" << i << " the input index array points to id " << j << " should be in [0," << nbOfTuples << ") !";
3256                   throw INTERP_KERNEL::Exception(oss.str().c_str());
3257                 }
3258             }
3259         }
3260       else
3261         {
3262           std::ostringstream oss; oss << "DataArrayDouble::accumulatePerChunck : At rank #" << i << " the input index array is not in ascendingly sorted.";
3263           throw INTERP_KERNEL::Exception(oss.str().c_str());
3264         }
3265     }
3266   ret->copyStringInfoFrom(*this);
3267   return ret.retn();
3268 }
3269
3270 /*!
3271  * Converts each 2D point defined by the tuple of \a this array from the Polar to the
3272  * Cartesian coordinate system. The two components of the tuple of \a this array are 
3273  * considered to contain (1) radius and (2) angle of the point in the Polar CS.
3274  *  \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
3275  *          contains X and Y coordinates of the point in the Cartesian CS. The caller
3276  *          is to delete this array using decrRef() as it is no more needed. The array
3277  *          does not contain any textual info on components.
3278  *  \throw If \a this->getNumberOfComponents() != 2.
3279  */
3280 DataArrayDouble *DataArrayDouble::fromPolarToCart() const throw(INTERP_KERNEL::Exception)
3281 {
3282   checkAllocated();
3283   int nbOfComp=getNumberOfComponents();
3284   if(nbOfComp!=2)
3285     throw INTERP_KERNEL::Exception("DataArrayDouble::fromPolarToCart : must be an array with exactly 2 components !");
3286   int nbOfTuple=getNumberOfTuples();
3287   DataArrayDouble *ret=DataArrayDouble::New();
3288   ret->alloc(nbOfTuple,2);
3289   double *w=ret->getPointer();
3290   const double *wIn=getConstPointer();
3291   for(int i=0;i<nbOfTuple;i++,w+=2,wIn+=2)
3292     {
3293       w[0]=wIn[0]*cos(wIn[1]);
3294       w[1]=wIn[0]*sin(wIn[1]);
3295     }
3296   return ret;
3297 }
3298
3299 /*!
3300  * Converts each 3D point defined by the tuple of \a this array from the Cylindrical to
3301  * the Cartesian coordinate system. The three components of the tuple of \a this array 
3302  * are considered to contain (1) radius, (2) azimuth and (3) altitude of the point in
3303  * the Cylindrical CS.
3304  *  \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
3305  *          contains X, Y and Z coordinates of the point in the Cartesian CS. The info
3306  *          on the third component is copied from \a this array. The caller
3307  *          is to delete this array using decrRef() as it is no more needed. 
3308  *  \throw If \a this->getNumberOfComponents() != 3.
3309  */
3310 DataArrayDouble *DataArrayDouble::fromCylToCart() const throw(INTERP_KERNEL::Exception)
3311 {
3312   checkAllocated();
3313   int nbOfComp=getNumberOfComponents();
3314   if(nbOfComp!=3)
3315     throw INTERP_KERNEL::Exception("DataArrayDouble::fromCylToCart : must be an array with exactly 3 components !");
3316   int nbOfTuple=getNumberOfTuples();
3317   DataArrayDouble *ret=DataArrayDouble::New();
3318   ret->alloc(getNumberOfTuples(),3);
3319   double *w=ret->getPointer();
3320   const double *wIn=getConstPointer();
3321   for(int i=0;i<nbOfTuple;i++,w+=3,wIn+=3)
3322     {
3323       w[0]=wIn[0]*cos(wIn[1]);
3324       w[1]=wIn[0]*sin(wIn[1]);
3325       w[2]=wIn[2];
3326     }
3327   ret->setInfoOnComponent(2,getInfoOnComponent(2).c_str());
3328   return ret;
3329 }
3330
3331 /*!
3332  * Converts each 3D point defined by the tuple of \a this array from the Spherical to
3333  * the Cartesian coordinate system. The three components of the tuple of \a this array 
3334  * are considered to contain (1) radius, (2) polar angle and (3) azimuthal angle of the
3335  * point in the Cylindrical CS.
3336  *  \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
3337  *          contains X, Y and Z coordinates of the point in the Cartesian CS. The info
3338  *          on the third component is copied from \a this array. The caller
3339  *          is to delete this array using decrRef() as it is no more needed.
3340  *  \throw If \a this->getNumberOfComponents() != 3.
3341  */
3342 DataArrayDouble *DataArrayDouble::fromSpherToCart() const throw(INTERP_KERNEL::Exception)
3343 {
3344   checkAllocated();
3345   int nbOfComp=getNumberOfComponents();
3346   if(nbOfComp!=3)
3347     throw INTERP_KERNEL::Exception("DataArrayDouble::fromSpherToCart : must be an array with exactly 3 components !");
3348   int nbOfTuple=getNumberOfTuples();
3349   DataArrayDouble *ret=DataArrayDouble::New();
3350   ret->alloc(getNumberOfTuples(),3);
3351   double *w=ret->getPointer();
3352   const double *wIn=getConstPointer();
3353   for(int i=0;i<nbOfTuple;i++,w+=3,wIn+=3)
3354     {
3355       w[0]=wIn[0]*cos(wIn[2])*sin(wIn[1]);
3356       w[1]=wIn[0]*sin(wIn[2])*sin(wIn[1]);
3357       w[2]=wIn[0]*cos(wIn[1]);
3358     }
3359   return ret;
3360 }
3361
3362 /*!
3363  * Computes the doubly contracted product of every tensor defined by the tuple of \a this
3364  * array contating 6 components.
3365  *  \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
3366  *          is calculated from the tuple <em>(t)</em> of \a this array as follows:
3367  *          \f$ t[0]^2+t[1]^2+t[2]^2+2*t[3]^2+2*t[4]^2+2*t[5]^2\f$.
3368  *         The caller is to delete this result array using decrRef() as it is no more needed. 
3369  *  \throw If \a this->getNumberOfComponents() != 6.
3370  */
3371 DataArrayDouble *DataArrayDouble::doublyContractedProduct() const throw(INTERP_KERNEL::Exception)
3372 {
3373   checkAllocated();
3374   int nbOfComp=getNumberOfComponents();
3375   if(nbOfComp!=6)
3376     throw INTERP_KERNEL::Exception("DataArrayDouble::doublyContractedProduct : must be an array with exactly 6 components !");
3377   DataArrayDouble *ret=DataArrayDouble::New();
3378   int nbOfTuple=getNumberOfTuples();
3379   ret->alloc(nbOfTuple,1);
3380   const double *src=getConstPointer();
3381   double *dest=ret->getPointer();
3382   for(int i=0;i<nbOfTuple;i++,dest++,src+=6)
3383     *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];
3384   return ret;
3385 }
3386
3387 /*!
3388  * Computes the determinant of every square matrix defined by the tuple of \a this
3389  * array, which contains either 4, 6 or 9 components. The case of 6 components
3390  * corresponds to that of the upper triangular matrix.
3391  *  \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
3392  *          is the determinant of matrix of the corresponding tuple of \a this array.
3393  *          The caller is to delete this result array using decrRef() as it is no more
3394  *          needed. 
3395  *  \throw If \a this->getNumberOfComponents() is not in [4,6,9].
3396  */
3397 DataArrayDouble *DataArrayDouble::determinant() const throw(INTERP_KERNEL::Exception)
3398 {
3399   checkAllocated();
3400   DataArrayDouble *ret=DataArrayDouble::New();
3401   int nbOfTuple=getNumberOfTuples();
3402   ret->alloc(nbOfTuple,1);
3403   const double *src=getConstPointer();
3404   double *dest=ret->getPointer();
3405   switch(getNumberOfComponents())
3406     {
3407     case 6:
3408       for(int i=0;i<nbOfTuple;i++,dest++,src+=6)
3409         *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];
3410       return ret;
3411     case 4:
3412       for(int i=0;i<nbOfTuple;i++,dest++,src+=4)
3413         *dest=src[0]*src[3]-src[1]*src[2];
3414       return ret;
3415     case 9:
3416       for(int i=0;i<nbOfTuple;i++,dest++,src+=9)
3417         *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];
3418       return ret;
3419     default:
3420       ret->decrRef();
3421       throw INTERP_KERNEL::Exception("DataArrayDouble::determinant : Invalid number of components ! must be in 4,6,9 !");
3422     }
3423 }
3424
3425 /*!
3426  * Computes 3 eigenvalues of every upper triangular matrix defined by the tuple of
3427  * \a this array, which contains 6 components.
3428  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing 3
3429  *          components, whose each tuple contains the eigenvalues of the matrix of
3430  *          corresponding tuple of \a this array. 
3431  *          The caller is to delete this result array using decrRef() as it is no more
3432  *          needed. 
3433  *  \throw If \a this->getNumberOfComponents() != 6.
3434  */
3435 DataArrayDouble *DataArrayDouble::eigenValues() const throw(INTERP_KERNEL::Exception)
3436 {
3437   checkAllocated();
3438   int nbOfComp=getNumberOfComponents();
3439   if(nbOfComp!=6)
3440     throw INTERP_KERNEL::Exception("DataArrayDouble::eigenValues : must be an array with exactly 6 components !");
3441   DataArrayDouble *ret=DataArrayDouble::New();
3442   int nbOfTuple=getNumberOfTuples();
3443   ret->alloc(nbOfTuple,3);
3444   const double *src=getConstPointer();
3445   double *dest=ret->getPointer();
3446   for(int i=0;i<nbOfTuple;i++,dest+=3,src+=6)
3447     INTERP_KERNEL::computeEigenValues6(src,dest);
3448   return ret;
3449 }
3450
3451 /*!
3452  * Computes 3 eigenvectors of every upper triangular matrix defined by the tuple of
3453  * \a this array, which contains 6 components.
3454  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing 9
3455  *          components, whose each tuple contains 3 eigenvectors of the matrix of
3456  *          corresponding tuple of \a this array.
3457  *          The caller is to delete this result array using decrRef() as it is no more
3458  *          needed.
3459  *  \throw If \a this->getNumberOfComponents() != 6.
3460  */
3461 DataArrayDouble *DataArrayDouble::eigenVectors() const throw(INTERP_KERNEL::Exception)
3462 {
3463   checkAllocated();
3464   int nbOfComp=getNumberOfComponents();
3465   if(nbOfComp!=6)
3466     throw INTERP_KERNEL::Exception("DataArrayDouble::eigenVectors : must be an array with exactly 6 components !");
3467   DataArrayDouble *ret=DataArrayDouble::New();
3468   int nbOfTuple=getNumberOfTuples();
3469   ret->alloc(nbOfTuple,9);
3470   const double *src=getConstPointer();
3471   double *dest=ret->getPointer();
3472   for(int i=0;i<nbOfTuple;i++,src+=6)
3473     {
3474       double tmp[3];
3475       INTERP_KERNEL::computeEigenValues6(src,tmp);
3476       for(int j=0;j<3;j++,dest+=3)
3477         INTERP_KERNEL::computeEigenVectorForEigenValue6(src,tmp[j],1e-12,dest);
3478     }
3479   return ret;
3480 }
3481
3482 /*!
3483  * Computes the inverse matrix of every matrix defined by the tuple of \a this
3484  * array, which contains either 4, 6 or 9 components. The case of 6 components
3485  * corresponds to that of the upper triangular matrix.
3486  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
3487  *          same number of components as \a this one, whose each tuple is the inverse
3488  *          matrix of the matrix of corresponding tuple of \a this array. 
3489  *          The caller is to delete this result array using decrRef() as it is no more
3490  *          needed. 
3491  *  \throw If \a this->getNumberOfComponents() is not in [4,6,9].
3492  */
3493 DataArrayDouble *DataArrayDouble::inverse() const throw(INTERP_KERNEL::Exception)
3494 {
3495   checkAllocated();
3496   int nbOfComp=getNumberOfComponents();
3497   if(nbOfComp!=6 && nbOfComp!=9 && nbOfComp!=4)
3498     throw INTERP_KERNEL::Exception("DataArrayDouble::inversion : must be an array with 4,6 or 9 components !");
3499   DataArrayDouble *ret=DataArrayDouble::New();
3500   int nbOfTuple=getNumberOfTuples();
3501   ret->alloc(nbOfTuple,nbOfComp);
3502   const double *src=getConstPointer();
3503   double *dest=ret->getPointer();
3504 if(nbOfComp==6)
3505     for(int i=0;i<nbOfTuple;i++,dest+=6,src+=6)
3506       {
3507         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];
3508         dest[0]=(src[1]*src[2]-src[4]*src[4])/det;
3509         dest[1]=(src[0]*src[2]-src[5]*src[5])/det;
3510         dest[2]=(src[0]*src[1]-src[3]*src[3])/det;
3511         dest[3]=(src[5]*src[4]-src[3]*src[2])/det;
3512         dest[4]=(src[5]*src[3]-src[0]*src[4])/det;
3513         dest[5]=(src[3]*src[4]-src[1]*src[5])/det;
3514       }
3515   else if(nbOfComp==4)
3516     for(int i=0;i<nbOfTuple;i++,dest+=4,src+=4)
3517       {
3518         double det=src[0]*src[3]-src[1]*src[2];
3519         dest[0]=src[3]/det;
3520         dest[1]=-src[1]/det;
3521         dest[2]=-src[2]/det;
3522         dest[3]=src[0]/det;
3523       }
3524   else
3525     for(int i=0;i<nbOfTuple;i++,dest+=9,src+=9)
3526       {
3527         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];
3528         dest[0]=(src[4]*src[8]-src[7]*src[5])/det;
3529         dest[1]=(src[7]*src[2]-src[1]*src[8])/det;
3530         dest[2]=(src[1]*src[5]-src[4]*src[2])/det;
3531         dest[3]=(src[6]*src[5]-src[3]*src[8])/det;
3532         dest[4]=(src[0]*src[8]-src[6]*src[2])/det;
3533         dest[5]=(src[2]*src[3]-src[0]*src[5])/det;
3534         dest[6]=(src[3]*src[7]-src[6]*src[4])/det;
3535         dest[7]=(src[6]*src[1]-src[0]*src[7])/det;
3536         dest[8]=(src[0]*src[4]-src[1]*src[3])/det;
3537       }
3538   return ret;
3539 }
3540
3541 /*!
3542  * Computes the trace of every matrix defined by the tuple of \a this
3543  * array, which contains either 4, 6 or 9 components. The case of 6 components
3544  * corresponds to that of the upper triangular matrix.
3545  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing 
3546  *          1 component, whose each tuple is the trace of
3547  *          the matrix of corresponding tuple of \a this array. 
3548  *          The caller is to delete this result array using decrRef() as it is no more
3549  *          needed. 
3550  *  \throw If \a this->getNumberOfComponents() is not in [4,6,9].
3551  */
3552 DataArrayDouble *DataArrayDouble::trace() const throw(INTERP_KERNEL::Exception)
3553 {
3554   checkAllocated();
3555   int nbOfComp=getNumberOfComponents();
3556   if(nbOfComp!=6 && nbOfComp!=9 && nbOfComp!=4)
3557     throw INTERP_KERNEL::Exception("DataArrayDouble::trace : must be an array with 4,6 or 9 components !");
3558   DataArrayDouble *ret=DataArrayDouble::New();
3559   int nbOfTuple=getNumberOfTuples();
3560   ret->alloc(nbOfTuple,1);
3561   const double *src=getConstPointer();
3562   double *dest=ret->getPointer();
3563   if(nbOfComp==6)
3564     for(int i=0;i<nbOfTuple;i++,dest++,src+=6)
3565       *dest=src[0]+src[1]+src[2];
3566   else if(nbOfComp==4)
3567     for(int i=0;i<nbOfTuple;i++,dest++,src+=4)
3568       *dest=src[0]+src[3];
3569   else
3570     for(int i=0;i<nbOfTuple;i++,dest++,src+=9)
3571       *dest=src[0]+src[4]+src[8];
3572   return ret;
3573 }
3574
3575 /*!
3576  * Computes the stress deviator tensor of every stress tensor defined by the tuple of
3577  * \a this array, which contains 6 components.
3578  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
3579  *          same number of components and tuples as \a this array.
3580  *          The caller is to delete this result array using decrRef() as it is no more
3581  *          needed.
3582  *  \throw If \a this->getNumberOfComponents() != 6.
3583  */
3584 DataArrayDouble *DataArrayDouble::deviator() const throw(INTERP_KERNEL::Exception)
3585 {
3586   checkAllocated();
3587   int nbOfComp=getNumberOfComponents();
3588   if(nbOfComp!=6)
3589     throw INTERP_KERNEL::Exception("DataArrayDouble::deviator : must be an array with exactly 6 components !");
3590   DataArrayDouble *ret=DataArrayDouble::New();
3591   int nbOfTuple=getNumberOfTuples();
3592   ret->alloc(nbOfTuple,6);
3593   const double *src=getConstPointer();
3594   double *dest=ret->getPointer();
3595   for(int i=0;i<nbOfTuple;i++,dest+=6,src+=6)
3596     {
3597       double tr=(src[0]+src[1]+src[2])/3.;
3598       dest[0]=src[0]-tr;
3599       dest[1]=src[1]-tr;
3600       dest[2]=src[2]-tr;
3601       dest[3]=src[3];
3602       dest[4]=src[4];
3603       dest[5]=src[5];
3604     }
3605   return ret;
3606 }
3607
3608 /*!
3609  * Computes the magnitude of every vector defined by the tuple of
3610  * \a this array.
3611  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
3612  *          same number of tuples as \a this array and one component.
3613  *          The caller is to delete this result array using decrRef() as it is no more
3614  *          needed.
3615  *  \throw If \a this is not allocated.
3616  */
3617 DataArrayDouble *DataArrayDouble::magnitude() const throw(INTERP_KERNEL::Exception)
3618 {
3619   checkAllocated();
3620   int nbOfComp=getNumberOfComponents();
3621   DataArrayDouble *ret=DataArrayDouble::New();
3622   int nbOfTuple=getNumberOfTuples();
3623   ret->alloc(nbOfTuple,1);
3624   const double *src=getConstPointer();
3625   double *dest=ret->getPointer();
3626   for(int i=0;i<nbOfTuple;i++,dest++)
3627     {
3628       double sum=0.;
3629       for(int j=0;j<nbOfComp;j++,src++)
3630         sum+=(*src)*(*src);
3631       *dest=sqrt(sum);
3632     }
3633   return ret;
3634 }
3635
3636 /*!
3637  * Computes the maximal value within every tuple of \a this array.
3638  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
3639  *          same number of tuples as \a this array and one component.
3640  *          The caller is to delete this result array using decrRef() as it is no more
3641  *          needed.
3642  *  \throw If \a this is not allocated.
3643  *  \sa DataArrayDouble::maxPerTupleWithCompoId
3644  */
3645 DataArrayDouble *DataArrayDouble::maxPerTuple() const throw(INTERP_KERNEL::Exception)
3646 {
3647   checkAllocated();
3648   int nbOfComp=getNumberOfComponents();
3649   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
3650   int nbOfTuple=getNumberOfTuples();
3651   ret->alloc(nbOfTuple,1);
3652   const double *src=getConstPointer();
3653   double *dest=ret->getPointer();
3654   for(int i=0;i<nbOfTuple;i++,dest++,src+=nbOfComp)
3655     *dest=*std::max_element(src,src+nbOfComp);
3656   return ret.retn();
3657 }
3658
3659 /*!
3660  * Computes the maximal value within every tuple of \a this array and it returns the first component
3661  * id for each tuple that corresponds to the maximal value within the tuple.
3662  * 
3663  *  \param [out] compoIdOfMaxPerTuple - the new new instance of DataArrayInt containing the
3664  *          same number of tuples and only one component.
3665  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
3666  *          same number of tuples as \a this array and one component.
3667  *          The caller is to delete this result array using decrRef() as it is no more
3668  *          needed.
3669  *  \throw If \a this is not allocated.
3670  *  \sa DataArrayDouble::maxPerTuple
3671  */
3672 DataArrayDouble *DataArrayDouble::maxPerTupleWithCompoId(DataArrayInt* &compoIdOfMaxPerTuple) const throw(INTERP_KERNEL::Exception)
3673 {
3674   checkAllocated();
3675   int nbOfComp=getNumberOfComponents();
3676   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret0=DataArrayDouble::New();
3677   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret1=DataArrayInt::New();
3678   int nbOfTuple=getNumberOfTuples();
3679   ret0->alloc(nbOfTuple,1); ret1->alloc(nbOfTuple,1);
3680   const double *src=getConstPointer();
3681   double *dest=ret0->getPointer(); int *dest1=ret1->getPointer();
3682   for(int i=0;i<nbOfTuple;i++,dest++,dest1++,src+=nbOfComp)
3683     {
3684       const double *loc=std::max_element(src,src+nbOfComp);
3685       *dest=*loc;
3686       *dest1=(int)std::distance(src,loc);
3687     }
3688   compoIdOfMaxPerTuple=ret1.retn();
3689   return ret0.retn();
3690 }
3691
3692 /*!
3693  * This method returns a newly allocated DataArrayDouble instance having one component and \c this->getNumberOfTuples() * \c this->getNumberOfTuples() tuples.
3694  * \n This returned array contains the euclidian distance for each tuple in \a this. 
3695  * \n So the returned array can be seen as a dense symmetrical matrix whose diagonal elements are equal to 0.
3696  * \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)
3697  *
3698  * \warning use this method with care because it can leads to big amount of consumed memory !
3699  * 
3700  * \return A newly allocated (huge) ParaMEDMEM::DataArrayDouble instance that the caller should deal with.
3701  *
3702  * \throw If \a this is not allocated.
3703  *
3704  * \sa DataArrayDouble::buildEuclidianDistanceDenseMatrixWith
3705  */
3706 DataArrayDouble *DataArrayDouble::buildEuclidianDistanceDenseMatrix() const throw(INTERP_KERNEL::Exception)
3707 {
3708   checkAllocated();
3709   int nbOfComp=getNumberOfComponents();
3710   int nbOfTuples=getNumberOfTuples();
3711   const double *inData=getConstPointer();
3712   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
3713   ret->alloc(nbOfTuples*nbOfTuples,1);
3714   double *outData=ret->getPointer();
3715   for(int i=0;i<nbOfTuples;i++)
3716     {
3717       outData[i*nbOfTuples+i]=0.;
3718       for(int j=i+1;j<nbOfTuples;j++)
3719         {
3720           double dist=0.;
3721           for(int k=0;k<nbOfComp;k++)
3722             { double delta=inData[i*nbOfComp+k]-inData[j*nbOfComp+k]; dist+=delta*delta; }
3723           dist=sqrt(dist);
3724           outData[i*nbOfTuples+j]=dist;
3725           outData[j*nbOfTuples+i]=dist;
3726         }
3727     }
3728   return ret.retn();
3729 }
3730
3731 /*!
3732  * This method returns a newly allocated DataArrayDouble instance having one component and \c this->getNumberOfTuples() * \c other->getNumberOfTuples() tuples.
3733  * \n This returned array contains the euclidian distance for each tuple in \a other with each tuple in \a this. 
3734  * \n So the returned array can be seen as a dense rectangular matrix with \c other->getNumberOfTuples() rows and \c this->getNumberOfTuples() columns.
3735  * \n Output rectangular matrix is sorted along rows.
3736  * \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)
3737  *
3738  * \warning use this method with care because it can leads to big amount of consumed memory !
3739  * 
3740  * \param [in] other DataArrayDouble instance having same number of components than \a this.
3741  * \return A newly allocated (huge) ParaMEDMEM::DataArrayDouble instance that the caller should deal with.
3742  *
3743  * \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.
3744  *
3745  * \sa DataArrayDouble::buildEuclidianDistanceDenseMatrix
3746  */
3747 DataArrayDouble *DataArrayDouble::buildEuclidianDistanceDenseMatrixWith(const DataArrayDouble *other) const throw(INTERP_KERNEL::Exception)
3748 {
3749   if(!other)
3750     throw INTERP_KERNEL::Exception("DataArrayDouble::buildEuclidianDistanceDenseMatrixWith : input parameter is null !");
3751   checkAllocated();
3752   other->checkAllocated();
3753   int nbOfComp=getNumberOfComponents();
3754   int otherNbOfComp=other->getNumberOfComponents();
3755   if(nbOfComp!=otherNbOfComp)
3756     {
3757       std::ostringstream oss; oss << "DataArrayDouble::buildEuclidianDistanceDenseMatrixWith : this nb of compo=" << nbOfComp << " and other nb of compo=" << otherNbOfComp << ". It should match !";
3758       throw INTERP_KERNEL::Exception(oss.str().c_str());
3759     }
3760   int nbOfTuples=getNumberOfTuples();
3761   int otherNbOfTuples=other->getNumberOfTuples();
3762   const double *inData=getConstPointer();
3763   const double *inDataOther=other->getConstPointer();
3764   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
3765   ret->alloc(otherNbOfTuples*nbOfTuples,1);
3766   double *outData=ret->getPointer();
3767   for(int i=0;i<otherNbOfTuples;i++,inDataOther+=nbOfComp)
3768     {
3769       for(int j=0;j<nbOfTuples;j++)
3770         {
3771           double dist=0.;
3772           for(int k=0;k<nbOfComp;k++)
3773             { double delta=inDataOther[k]-inData[j*nbOfComp+k]; dist+=delta*delta; }
3774           dist=sqrt(dist);
3775           outData[i*nbOfTuples+j]=dist;
3776         }
3777     }
3778   return ret.retn();
3779 }
3780
3781 /*!
3782  * Sorts value within every tuple of \a this array.
3783  *  \param [in] asc - if \a true, the values are sorted in ascending order, else,
3784  *              in descending order.
3785  *  \throw If \a this is not allocated.
3786  */
3787 void DataArrayDouble::sortPerTuple(bool asc) throw(INTERP_KERNEL::Exception)
3788 {
3789   checkAllocated();
3790   double *pt=getPointer();
3791   int nbOfTuple=getNumberOfTuples();
3792   int nbOfComp=getNumberOfComponents();
3793   if(asc)
3794     for(int i=0;i<nbOfTuple;i++,pt+=nbOfComp)
3795       std::sort(pt,pt+nbOfComp);
3796   else
3797     for(int i=0;i<nbOfTuple;i++,pt+=nbOfComp)
3798       std::sort(pt,pt+nbOfComp,std::greater<double>());
3799   declareAsNew();
3800 }
3801
3802 /*!
3803  * Converts every value of \a this array to its absolute value.
3804  *  \throw If \a this is not allocated.
3805  */
3806 void DataArrayDouble::abs() throw(INTERP_KERNEL::Exception)
3807 {
3808   checkAllocated();
3809   double *ptr=getPointer();
3810   std::size_t nbOfElems=getNbOfElems();
3811   std::transform(ptr,ptr+nbOfElems,ptr,std::ptr_fun<double,double>(fabs));
3812   declareAsNew();
3813 }
3814
3815 /*!
3816  * Apply a liner function to a given component of \a this array, so that
3817  * an array element <em>(x)</em> becomes \f$ a * x + b \f$.
3818  *  \param [in] a - the first coefficient of the function.
3819  *  \param [in] b - the second coefficient of the function.
3820  *  \param [in] compoId - the index of component to modify.
3821  *  \throw If \a this is not allocated.
3822  */
3823 void DataArrayDouble::applyLin(double a, double b, int compoId) throw(INTERP_KERNEL::Exception)
3824 {
3825   checkAllocated();
3826   double *ptr=getPointer()+compoId;
3827   int nbOfComp=getNumberOfComponents();
3828   int nbOfTuple=getNumberOfTuples();
3829   for(int i=0;i<nbOfTuple;i++,ptr+=nbOfComp)
3830     *ptr=a*(*ptr)+b;
3831   declareAsNew();
3832 }
3833
3834 /*!
3835  * Apply a liner function to all elements of \a this array, so that
3836  * an element _x_ becomes \f$ a * x + b \f$.
3837  *  \param [in] a - the first coefficient of the function.
3838  *  \param [in] b - the second coefficient of the function.
3839  *  \throw If \a this is not allocated.
3840  */
3841 void DataArrayDouble::applyLin(double a, double b) throw(INTERP_KERNEL::Exception)
3842 {
3843   checkAllocated();
3844   double *ptr=getPointer();
3845   std::size_t nbOfElems=getNbOfElems();
3846   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
3847     *ptr=a*(*ptr)+b;
3848   declareAsNew();
3849 }
3850
3851 /*!
3852  * Modify all elements of \a this array, so that
3853  * an element _x_ becomes \f$ numerator / x \f$.
3854  *  \warning If an exception is thrown because of presence of 0.0 element in \a this 
3855  *           array, all elements processed before detection of the zero element remain
3856  *           modified.
3857  *  \param [in] numerator - the numerator used to modify array elements.
3858  *  \throw If \a this is not allocated.
3859  *  \throw If there is an element equal to 0.0 in \a this array.
3860  */
3861 void DataArrayDouble::applyInv(double numerator) throw(INTERP_KERNEL::Exception)
3862 {
3863   checkAllocated();
3864   double *ptr=getPointer();
3865   std::size_t nbOfElems=getNbOfElems();
3866   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
3867     {
3868       if(std::abs(*ptr)>std::numeric_limits<double>::min())
3869         {
3870           *ptr=numerator/(*ptr);
3871         }
3872       else
3873         {
3874           std::ostringstream oss; oss << "DataArrayDouble::applyInv : presence of null value in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
3875           oss << " !";
3876           throw INTERP_KERNEL::Exception(oss.str().c_str());
3877         }
3878     }
3879   declareAsNew();
3880 }
3881
3882 /*!
3883  * Returns a full copy of \a this array except that sign of all elements is reversed.
3884  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
3885  *          same number of tuples and component as \a this array.
3886  *          The caller is to delete this result array using decrRef() as it is no more
3887  *          needed.
3888  *  \throw If \a this is not allocated.
3889  */
3890 DataArrayDouble *DataArrayDouble::negate() const throw(INTERP_KERNEL::Exception)
3891 {
3892   checkAllocated();
3893   DataArrayDouble *newArr=DataArrayDouble::New();
3894   int nbOfTuples=getNumberOfTuples();
3895   int nbOfComp=getNumberOfComponents();
3896   newArr->alloc(nbOfTuples,nbOfComp);
3897   const double *cptr=getConstPointer();
3898   std::transform(cptr,cptr+nbOfTuples*nbOfComp,newArr->getPointer(),std::negate<double>());
3899   newArr->copyStringInfoFrom(*this);
3900   return newArr;
3901 }
3902
3903 /*!
3904  * Modify all elements of \a this array, so that
3905  * an element _x_ becomes <em> val ^ x </em>. Contrary to DataArrayInt::applyPow
3906  * all values in \a this have to be >= 0 if val is \b not integer.
3907  *  \param [in] val - the value used to apply pow on all array elements.
3908  *  \throw If \a this is not allocated.
3909  *  \warning If an exception is thrown because of presence of 0 element in \a this 
3910  *           array and \a val is \b not integer, all elements processed before detection of the zero element remain
3911  *           modified.
3912  */
3913 void DataArrayDouble::applyPow(double val) throw(INTERP_KERNEL::Exception)
3914 {
3915   checkAllocated();
3916   double *ptr=getPointer();
3917   std::size_t nbOfElems=getNbOfElems();
3918   int val2=(int)val;
3919   bool isInt=((double)val2)==val;
3920   if(!isInt)
3921     {
3922       for(std::size_t i=0;i<nbOfElems;i++,ptr++)
3923         {
3924           if(*ptr>=0)
3925             *ptr=pow(*ptr,val);
3926           else
3927             {
3928               std::ostringstream oss; oss << "DataArrayDouble::applyPow (double) : At elem # " << i << " value is " << *ptr << " ! must be >=0. !";
3929               throw INTERP_KERNEL::Exception(oss.str().c_str());
3930             }
3931         }
3932     }
3933   else
3934     {
3935       for(std::size_t i=0;i<nbOfElems;i++,ptr++)
3936         *ptr=pow(*ptr,val2);
3937     }
3938   declareAsNew();
3939 }
3940
3941 /*!
3942  * Modify all elements of \a this array, so that
3943  * an element _x_ becomes \f$ val ^ x \f$.
3944  *  \param [in] val - the value used to apply pow on all array elements.
3945  *  \throw If \a this is not allocated.
3946  *  \throw If \a val < 0.
3947  *  \warning If an exception is thrown because of presence of 0 element in \a this 
3948  *           array, all elements processed before detection of the zero element remain
3949  *           modified.
3950  */
3951 void DataArrayDouble::applyRPow(double val) throw(INTERP_KERNEL::Exception)
3952 {
3953   checkAllocated();
3954   if(val<0.)
3955     throw INTERP_KERNEL::Exception("DataArrayDouble::applyRPow : the input value has to be >= 0 !");
3956   double *ptr=getPointer();
3957   std::size_t nbOfElems=getNbOfElems();
3958   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
3959     *ptr=pow(val,*ptr);
3960   declareAsNew();
3961 }
3962
3963 /*!
3964  * Returns a new DataArrayDouble created from \a this one by applying \a
3965  * FunctionToEvaluate to every tuple of \a this array. Textual data is not copied.
3966  * For more info see \ref MEDCouplingArrayApplyFunc
3967  *  \param [in] nbOfComp - number of components in the result array.
3968  *  \param [in] func - the \a FunctionToEvaluate declared as 
3969  *              \c bool (*\a func)(\c const \c double *\a pos, \c double *\a res), 
3970  *              where \a pos points to the first component of a tuple of \a this array
3971  *              and \a res points to the first component of a tuple of the result array.
3972  *              Note that length (number of components) of \a pos can differ from
3973  *              that of \a res.
3974  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
3975  *          same number of tuples as \a this array.
3976  *          The caller is to delete this result array using decrRef() as it is no more
3977  *          needed.
3978  *  \throw If \a this is not allocated.
3979  *  \throw If \a func returns \a false.
3980  */
3981 DataArrayDouble *DataArrayDouble::applyFunc(int nbOfComp, FunctionToEvaluate func) const throw(INTERP_KERNEL::Exception)
3982 {
3983   checkAllocated();
3984   DataArrayDouble *newArr=DataArrayDouble::New();
3985   int nbOfTuples=getNumberOfTuples();
3986   int oldNbOfComp=getNumberOfComponents();
3987   newArr->alloc(nbOfTuples,nbOfComp);
3988   const double *ptr=getConstPointer();
3989   double *ptrToFill=newArr->getPointer();
3990   for(int i=0;i<nbOfTuples;i++)
3991     {
3992       if(!func(ptr+i*oldNbOfComp,ptrToFill+i*nbOfComp))
3993         {
3994           std::ostringstream oss; oss << "For tuple # " << i << " with value (";
3995           std::copy(ptr+oldNbOfComp*i,ptr+oldNbOfComp*(i+1),std::ostream_iterator<double>(oss,", "));
3996           oss << ") : Evaluation of function failed !";
3997           newArr->decrRef();
3998           throw INTERP_KERNEL::Exception(oss.str().c_str());
3999         }
4000     }
4001   return newArr;
4002 }
4003
4004 /*!
4005  * Returns a new DataArrayDouble created from \a this one by applying a function to every
4006  * tuple of \a this array. Textual data is not copied.
4007  * For more info see \ref MEDCouplingArrayApplyFunc1.
4008  *  \param [in] nbOfComp - number of components in the result array.
4009  *  \param [in] func - the expression defining how to transform a tuple of \a this array.
4010  *              Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
4011  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
4012  *          same number of tuples as \a this array and \a nbOfComp components.
4013  *          The caller is to delete this result array using decrRef() as it is no more
4014  *          needed.
4015  *  \throw If \a this is not allocated.
4016  *  \throw If computing \a func fails.
4017  */
4018 DataArrayDouble *DataArrayDouble::applyFunc(int nbOfComp, const char *func) const throw(INTERP_KERNEL::Exception)
4019 {
4020   checkAllocated();
4021   INTERP_KERNEL::ExprParser expr(func);
4022   expr.parse();
4023   std::set<std::string> vars;
4024   expr.getTrueSetOfVars(vars);
4025   int oldNbOfComp=getNumberOfComponents();
4026   if((int)vars.size()>oldNbOfComp)
4027     {
4028       std::ostringstream oss; oss << "The field has " << oldNbOfComp << " components and there are ";
4029       oss << vars.size() << " variables : ";
4030       std::copy(vars.begin(),vars.end(),std::ostream_iterator<std::string>(oss," "));
4031       throw INTERP_KERNEL::Exception(oss.str().c_str());
4032     }
4033   std::vector<std::string> varsV(vars.begin(),vars.end());
4034   expr.prepareExprEvaluation(varsV,oldNbOfComp,nbOfComp);
4035   //
4036   DataArrayDouble *newArr=DataArrayDouble::New();
4037   int nbOfTuples=getNumberOfTuples();
4038   newArr->alloc(nbOfTuples,nbOfComp);
4039   const double *ptr=getConstPointer();
4040   double *ptrToFill=newArr->getPointer();
4041   for(int i=0;i<nbOfTuples;i++)
4042     {
4043       try
4044         {
4045           expr.evaluateExpr(nbOfComp,ptr+i*oldNbOfComp,ptrToFill+i*nbOfComp);
4046         }
4047       catch(INTERP_KERNEL::Exception& e)
4048         {
4049           std::ostringstream oss; oss << "For tuple # " << i << " with value (";
4050           std::copy(ptr+oldNbOfComp*i,ptr+oldNbOfComp*(i+1),std::ostream_iterator<double>(oss,", "));
4051           oss << ") : Evaluation of function failed !" << e.what();
4052           newArr->decrRef();
4053           throw INTERP_KERNEL::Exception(oss.str().c_str());
4054         }
4055     }
4056   return newArr;
4057 }
4058
4059 /*!
4060  * Returns a new DataArrayDouble created from \a this one by applying a function to every
4061  * tuple of \a this array. Textual data is not copied.
4062  * For more info see \ref MEDCouplingArrayApplyFunc0.
4063  *  \param [in] func - the expression defining how to transform a tuple of \a this array.
4064  *              Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
4065  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
4066  *          same number of tuples and components as \a this array.
4067  *          The caller is to delete this result array using decrRef() as it is no more
4068  *          needed.
4069  *  \throw If \a this is not allocated.
4070  *  \throw If computing \a func fails.
4071  */
4072 DataArrayDouble *DataArrayDouble::applyFunc(const char *func) const throw(INTERP_KERNEL::Exception)
4073 {
4074   checkAllocated();
4075   INTERP_KERNEL::ExprParser expr(func);
4076   expr.parse();
4077   expr.prepareExprEvaluationVec();
4078   //
4079   DataArrayDouble *newArr=DataArrayDouble::New();
4080   int nbOfTuples=getNumberOfTuples();
4081   int nbOfComp=getNumberOfComponents();
4082   newArr->alloc(nbOfTuples,nbOfComp);
4083   const double *ptr=getConstPointer();
4084   double *ptrToFill=newArr->getPointer();
4085   for(int i=0;i<nbOfTuples;i++)
4086     {
4087       try
4088         {
4089           expr.evaluateExpr(nbOfComp,ptr+i*nbOfComp,ptrToFill+i*nbOfComp);
4090         }
4091       catch(INTERP_KERNEL::Exception& e)
4092         {
4093           std::ostringstream oss; oss << "For tuple # " << i << " with value (";
4094           std::copy(ptr+nbOfComp*i,ptr+nbOfComp*(i+1),std::ostream_iterator<double>(oss,", "));
4095           oss << ") : Evaluation of function failed ! " << e.what();
4096           newArr->decrRef();
4097           throw INTERP_KERNEL::Exception(oss.str().c_str());
4098         }
4099     }
4100   return newArr;
4101 }
4102
4103 /*!
4104  * Returns a new DataArrayDouble created from \a this one by applying a function to every
4105  * tuple of \a this array. Textual data is not copied.
4106  * For more info see \ref MEDCouplingArrayApplyFunc2.
4107  *  \param [in] nbOfComp - number of components in the result array.
4108  *  \param [in] func - the expression defining how to transform a tuple of \a this array.
4109  *              Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
4110  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
4111  *          same number of tuples as \a this array.
4112  *          The caller is to delete this result array using decrRef() as it is no more
4113  *          needed.
4114  *  \throw If \a this is not allocated.
4115  *  \throw If \a func contains vars that are not in \a this->getInfoOnComponent().
4116  *  \throw If computing \a func fails.
4117  */
4118 DataArrayDouble *DataArrayDouble::applyFunc2(int nbOfComp, const char *func) const throw(INTERP_KERNEL::Exception)
4119 {
4120   checkAllocated();
4121   INTERP_KERNEL::ExprParser expr(func);
4122   expr.parse();
4123   std::set<std::string> vars;
4124   expr.getTrueSetOfVars(vars);
4125   int oldNbOfComp=getNumberOfComponents();
4126   if((int)vars.size()>oldNbOfComp)
4127     {
4128       std::ostringstream oss; oss << "The field has " << oldNbOfComp << " components and there are ";
4129       oss << vars.size() << " variables : ";
4130       std::copy(vars.begin(),vars.end(),std::ostream_iterator<std::string>(oss," "));
4131       throw INTERP_KERNEL::Exception(oss.str().c_str());
4132     }
4133   expr.prepareExprEvaluation(getVarsOnComponent(),oldNbOfComp,nbOfComp);
4134   //
4135   DataArrayDouble *newArr=DataArrayDouble::New();
4136   int nbOfTuples=getNumberOfTuples();
4137   newArr->alloc(nbOfTuples,nbOfComp);
4138   const double *ptr=getConstPointer();
4139   double *ptrToFill=newArr->getPointer();
4140   for(int i=0;i<nbOfTuples;i++)
4141     {
4142       try
4143         {
4144           expr.evaluateExpr(nbOfComp,ptr+i*oldNbOfComp,ptrToFill+i*nbOfComp);
4145         }
4146       catch(INTERP_KERNEL::Exception& e)
4147         {
4148           std::ostringstream oss; oss << "For tuple # " << i << " with value (";
4149           std::copy(ptr+oldNbOfComp*i,ptr+oldNbOfComp*(i+1),std::ostream_iterator<double>(oss,", "));
4150           oss << ") : Evaluation of function failed !" << e.what();
4151           newArr->decrRef();
4152           throw INTERP_KERNEL::Exception(oss.str().c_str());
4153         }
4154     }
4155   return newArr;
4156 }
4157
4158 /*!
4159  * Returns a new DataArrayDouble created from \a this one by applying a function to every
4160  * tuple of \a this array. Textual data is not copied.
4161  * For more info see \ref MEDCouplingArrayApplyFunc3.
4162  *  \param [in] nbOfComp - number of components in the result array.
4163  *  \param [in] varsOrder - sequence of vars defining their order.
4164  *  \param [in] func - the expression defining how to transform a tuple of \a this array.
4165  *              Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
4166  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
4167  *          same number of tuples as \a this array.
4168  *          The caller is to delete this result array using decrRef() as it is no more
4169  *          needed.
4170  *  \throw If \a this is not allocated.
4171  *  \throw If \a func contains vars not in \a varsOrder.
4172  *  \throw If computing \a func fails.
4173  */
4174 DataArrayDouble *DataArrayDouble::applyFunc3(int nbOfComp, const std::vector<std::string>& varsOrder, const char *func) const throw(INTERP_KERNEL::Exception)
4175 {
4176   checkAllocated();
4177   INTERP_KERNEL::ExprParser expr(func);
4178   expr.parse();
4179   std::set<std::string> vars;
4180   expr.getTrueSetOfVars(vars);
4181   int oldNbOfComp=getNumberOfComponents();
4182   if((int)vars.size()>oldNbOfComp)
4183     {
4184       std::ostringstream oss; oss << "The field has " << oldNbOfComp << " components and there are ";
4185       oss << vars.size() << " variables : ";
4186       std::copy(vars.begin(),vars.end(),std::ostream_iterator<std::string>(oss," "));
4187       throw INTERP_KERNEL::Exception(oss.str().c_str());
4188     }
4189   expr.prepareExprEvaluation(varsOrder,oldNbOfComp,nbOfComp);
4190   //
4191   DataArrayDouble *newArr=DataArrayDouble::New();
4192   int nbOfTuples=getNumberOfTuples();
4193   newArr->alloc(nbOfTuples,nbOfComp);
4194   const double *ptr=getConstPointer();
4195   double *ptrToFill=newArr->getPointer();
4196   for(int i=0;i<nbOfTuples;i++)
4197     {
4198       try
4199         {
4200           expr.evaluateExpr(nbOfComp,ptr+i*oldNbOfComp,ptrToFill+i*nbOfComp);
4201         }
4202       catch(INTERP_KERNEL::Exception& e)
4203         {
4204           std::ostringstream oss; oss << "For tuple # " << i << " with value (";
4205           std::copy(ptr+oldNbOfComp*i,ptr+oldNbOfComp*(i+1),std::ostream_iterator<double>(oss,", "));
4206           oss << ") : Evaluation of function failed !" << e.what();
4207           newArr->decrRef();
4208           throw INTERP_KERNEL::Exception(oss.str().c_str());
4209         }
4210     }
4211   return newArr;
4212 }
4213
4214 void DataArrayDouble::applyFuncFast32(const char *func) throw(INTERP_KERNEL::Exception)
4215 {
4216   checkAllocated();
4217   INTERP_KERNEL::ExprParser expr(func);
4218   expr.parse();
4219   char *funcStr=expr.compileX86();
4220   MYFUNCPTR funcPtr;
4221   *((void **)&funcPtr)=funcStr;//he he...
4222   //
4223   double *ptr=getPointer();
4224   int nbOfComp=getNumberOfComponents();
4225   int nbOfTuples=getNumberOfTuples();
4226   int nbOfElems=nbOfTuples*nbOfComp;
4227   for(int i=0;i<nbOfElems;i++,ptr++)
4228     *ptr=funcPtr(*ptr);
4229   declareAsNew();
4230 }
4231
4232 void DataArrayDouble::applyFuncFast64(const char *func) throw(INTERP_KERNEL::Exception)
4233 {
4234   checkAllocated();
4235   INTERP_KERNEL::ExprParser expr(func);
4236   expr.parse();
4237   char *funcStr=expr.compileX86_64();
4238   MYFUNCPTR funcPtr;
4239   *((void **)&funcPtr)=funcStr;//he he...
4240   //
4241   double *ptr=getPointer();
4242   int nbOfComp=getNumberOfComponents();
4243   int nbOfTuples=getNumberOfTuples();
4244   int nbOfElems=nbOfTuples*nbOfComp;
4245   for(int i=0;i<nbOfElems;i++,ptr++)
4246     *ptr=funcPtr(*ptr);
4247   declareAsNew();
4248 }
4249
4250 DataArrayDoubleIterator *DataArrayDouble::iterator() throw(INTERP_KERNEL::Exception)
4251 {
4252   return new DataArrayDoubleIterator(this);
4253 }
4254
4255 /*!
4256  * Returns a new DataArrayInt contating indices of tuples of \a this one-dimensional
4257  * array whose values are within a given range. Textual data is not copied.
4258  *  \param [in] vmin - a lowest acceptable value (included).
4259  *  \param [in] vmax - a greatest acceptable value (included).
4260  *  \return DataArrayInt * - the new instance of DataArrayInt.
4261  *          The caller is to delete this result array using decrRef() as it is no more
4262  *          needed.
4263  *  \throw If \a this->getNumberOfComponents() != 1.
4264  *
4265  *  \ref cpp_mcdataarraydouble_getidsinrange "Here is a C++ example".<br>
4266  *  \ref py_mcdataarraydouble_getidsinrange "Here is a Python example".
4267  */
4268 DataArrayInt *DataArrayDouble::getIdsInRange(double vmin, double vmax) const throw(INTERP_KERNEL::Exception)
4269 {
4270   checkAllocated();
4271   if(getNumberOfComponents()!=1)
4272     throw INTERP_KERNEL::Exception("DataArrayDouble::getIdsInRange : this must have exactly one component !");
4273   const double *cptr=getConstPointer();
4274   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(0,1);
4275   int nbOfTuples=getNumberOfTuples();
4276   for(int i=0;i<nbOfTuples;i++,cptr++)
4277     if(*cptr>=vmin && *cptr<=vmax)
4278       ret->pushBackSilent(i);
4279   return ret.retn();
4280 }
4281
4282 /*!
4283  * Returns a new DataArrayDouble by concatenating two given arrays, so that (1) the number
4284  * of tuples in the result array is a sum of the number of tuples of given arrays and (2)
4285  * the number of component in the result array is same as that of each of given arrays.
4286  * Info on components is copied from the first of the given arrays. Number of components
4287  * in the given arrays must be  the same.
4288  *  \param [in] a1 - an array to include in the result array.
4289  *  \param [in] a2 - another array to include in the result array.
4290  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4291  *          The caller is to delete this result array using decrRef() as it is no more
4292  *          needed.
4293  *  \throw If both \a a1 and \a a2 are NULL.
4294  *  \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents().
4295  */
4296 DataArrayDouble *DataArrayDouble::Aggregate(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception)
4297 {
4298   std::vector<const DataArrayDouble *> tmp(2);
4299   tmp[0]=a1; tmp[1]=a2;
4300   return Aggregate(tmp);
4301 }
4302
4303 /*!
4304  * Returns a new DataArrayDouble by concatenating all given arrays, so that (1) the number
4305  * of tuples in the result array is a sum of the number of tuples of given arrays and (2)
4306  * the number of component in the result array is same as that of each of given arrays.
4307  * Info on components is copied from the first of the given arrays. Number of components
4308  * in the given arrays must be  the same.
4309  *  \param [in] arr - a sequence of arrays to include in the result array.
4310  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4311  *          The caller is to delete this result array using decrRef() as it is no more
4312  *          needed.
4313  *  \throw If all arrays within \a arr are NULL.
4314  *  \throw If getNumberOfComponents() of arrays within \a arr.
4315  */
4316 DataArrayDouble *DataArrayDouble::Aggregate(const std::vector<const DataArrayDouble *>& arr) throw(INTERP_KERNEL::Exception)
4317 {
4318   std::vector<const DataArrayDouble *> a;
4319   for(std::vector<const DataArrayDouble *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
4320     if(*it4)
4321       a.push_back(*it4);
4322   if(a.empty())
4323     throw INTERP_KERNEL::Exception("DataArrayDouble::Aggregate : input list must contain at least one NON EMPTY DataArrayDouble !");
4324   std::vector<const DataArrayDouble *>::const_iterator it=a.begin();
4325   int nbOfComp=(*it)->getNumberOfComponents();
4326   int nbt=(*it++)->getNumberOfTuples();
4327   for(int i=1;it!=a.end();it++,i++)
4328     {
4329       if((*it)->getNumberOfComponents()!=nbOfComp)
4330         throw INTERP_KERNEL::Exception("DataArrayDouble::Aggregate : Nb of components mismatch for array aggregation !");
4331       nbt+=(*it)->getNumberOfTuples();
4332     }
4333   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
4334   ret->alloc(nbt,nbOfComp);
4335   double *pt=ret->getPointer();
4336   for(it=a.begin();it!=a.end();it++)
4337     pt=std::copy((*it)->getConstPointer(),(*it)->getConstPointer()+(*it)->getNbOfElems(),pt);
4338   ret->copyStringInfoFrom(*(a[0]));
4339   return ret.retn();
4340 }
4341
4342 /*!
4343  * Returns a new DataArrayDouble by aggregating two given arrays, so that (1) the number
4344  * of components in the result array is a sum of the number of components of given arrays
4345  * and (2) the number of tuples in the result array is same as that of each of given
4346  * arrays. In other words the i-th tuple of result array includes all components of
4347  * i-th tuples of all given arrays.
4348  * Number of tuples in the given arrays must be  the same.
4349  *  \param [in] a1 - an array to include in the result array.
4350  *  \param [in] a2 - another array to include in the result array.
4351  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4352  *          The caller is to delete this result array using decrRef() as it is no more
4353  *          needed.
4354  *  \throw If both \a a1 and \a a2 are NULL.
4355  *  \throw If any given array is not allocated.
4356  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
4357  */
4358 DataArrayDouble *DataArrayDouble::Meld(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception)
4359 {
4360   std::vector<const DataArrayDouble *> arr(2);
4361   arr[0]=a1; arr[1]=a2;
4362   return Meld(arr);
4363 }
4364
4365 /*!
4366  * Returns a new DataArrayDouble by aggregating all given arrays, so that (1) the number
4367  * of components in the result array is a sum of the number of components of given arrays
4368  * and (2) the number of tuples in the result array is same as that of each of given
4369  * arrays. In other words the i-th tuple of result array includes all components of
4370  * i-th tuples of all given arrays.
4371  * Number of tuples in the given arrays must be  the same.
4372  *  \param [in] arr - a sequence of arrays to include in the result array.
4373  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4374  *          The caller is to delete this result array using decrRef() as it is no more
4375  *          needed.
4376  *  \throw If all arrays within \a arr are NULL.
4377  *  \throw If any given array is not allocated.
4378  *  \throw If getNumberOfTuples() of arrays within \a arr is different.
4379  */
4380 DataArrayDouble *DataArrayDouble::Meld(const std::vector<const DataArrayDouble *>& arr) throw(INTERP_KERNEL::Exception)
4381 {
4382   std::vector<const DataArrayDouble *> a;
4383   for(std::vector<const DataArrayDouble *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
4384     if(*it4)
4385       a.push_back(*it4);
4386   if(a.empty())
4387     throw INTERP_KERNEL::Exception("DataArrayDouble::Meld : input list must contain at least one NON EMPTY DataArrayDouble !");
4388   std::vector<const DataArrayDouble *>::const_iterator it;
4389   for(it=a.begin();it!=a.end();it++)
4390     (*it)->checkAllocated();
4391   it=a.begin();
4392   int nbOfTuples=(*it)->getNumberOfTuples();
4393   std::vector<int> nbc(a.size());
4394   std::vector<const double *> pts(a.size());
4395   nbc[0]=(*it)->getNumberOfComponents();
4396   pts[0]=(*it++)->getConstPointer();
4397   for(int i=1;it!=a.end();it++,i++)
4398     {
4399       if(nbOfTuples!=(*it)->getNumberOfTuples())
4400         throw INTERP_KERNEL::Exception("DataArrayDouble::Meld : mismatch of number of tuples !");
4401       nbc[i]=(*it)->getNumberOfComponents();
4402       pts[i]=(*it)->getConstPointer();
4403     }
4404   int totalNbOfComp=std::accumulate(nbc.begin(),nbc.end(),0);
4405   DataArrayDouble *ret=DataArrayDouble::New();
4406   ret->alloc(nbOfTuples,totalNbOfComp);
4407   double *retPtr=ret->getPointer();
4408   for(int i=0;i<nbOfTuples;i++)
4409     for(int j=0;j<(int)a.size();j++)
4410       {
4411         retPtr=std::copy(pts[j],pts[j]+nbc[j],retPtr);
4412         pts[j]+=nbc[j];
4413       }
4414   int k=0;
4415   for(int i=0;i<(int)a.size();i++)
4416     for(int j=0;j<nbc[i];j++,k++)
4417       ret->setInfoOnComponent(k,a[i]->getInfoOnComponent(j).c_str());
4418   return ret;
4419 }
4420
4421 /*!
4422  * Returns a new DataArrayDouble containing a dot product of two given arrays, so that
4423  * the i-th tuple of the result array is a sum of products of j-th components of i-th
4424  * tuples of given arrays (\f$ a_i = \sum_{j=1}^n a1_j * a2_j \f$).
4425  * Info on components and name is copied from the first of the given arrays.
4426  * Number of tuples and components in the given arrays must be the same.
4427  *  \param [in] a1 - a given array.
4428  *  \param [in] a2 - another given array.
4429  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4430  *          The caller is to delete this result array using decrRef() as it is no more
4431  *          needed.
4432  *  \throw If either \a a1 or \a a2 is NULL.
4433  *  \throw If any given array is not allocated.
4434  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
4435  *  \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents()
4436  */
4437 DataArrayDouble *DataArrayDouble::Dot(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception)
4438 {
4439   if(!a1 || !a2)
4440     throw INTERP_KERNEL::Exception("DataArrayDouble::Dot : input DataArrayDouble instance is NULL !");
4441   a1->checkAllocated();
4442   a2->checkAllocated();
4443   int nbOfComp=a1->getNumberOfComponents();
4444   if(nbOfComp!=a2->getNumberOfComponents())
4445     throw INTERP_KERNEL::Exception("Nb of components mismatch for array Dot !");
4446   int nbOfTuple=a1->getNumberOfTuples();
4447   if(nbOfTuple!=a2->getNumberOfTuples())
4448     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Dot !");
4449   DataArrayDouble *ret=DataArrayDouble::New();
4450   ret->alloc(nbOfTuple,1);
4451   double *retPtr=ret->getPointer();
4452   const double *a1Ptr=a1->getConstPointer();
4453   const double *a2Ptr=a2->getConstPointer();
4454   for(int i=0;i<nbOfTuple;i++)
4455     {
4456       double sum=0.;
4457       for(int j=0;j<nbOfComp;j++)
4458         sum+=a1Ptr[i*nbOfComp+j]*a2Ptr[i*nbOfComp+j];
4459       retPtr[i]=sum;
4460     }
4461   ret->setInfoOnComponent(0,a1->getInfoOnComponent(0).c_str());
4462   ret->setName(a1->getName().c_str());
4463   return ret;
4464 }
4465
4466 /*!
4467  * Returns a new DataArrayDouble containing a cross product of two given arrays, so that
4468  * the i-th tuple of the result array contains 3 components of a vector which is a cross
4469  * product of two vectors defined by the i-th tuples of given arrays.
4470  * Info on components is copied from the first of the given arrays.
4471  * Number of tuples in the given arrays must be the same.
4472  * Number of components in the given arrays must be 3.
4473  *  \param [in] a1 - a given array.
4474  *  \param [in] a2 - another given 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 either \a a1 or \a a2 is NULL.
4479  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
4480  *  \throw If \a a1->getNumberOfComponents() != 3
4481  *  \throw If \a a2->getNumberOfComponents() != 3
4482  */
4483 DataArrayDouble *DataArrayDouble::CrossProduct(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception)
4484 {
4485   if(!a1 || !a2)
4486     throw INTERP_KERNEL::Exception("DataArrayDouble::CrossProduct : input DataArrayDouble instance is NULL !");
4487   int nbOfComp=a1->getNumberOfComponents();
4488   if(nbOfComp!=a2->getNumberOfComponents())
4489     throw INTERP_KERNEL::Exception("Nb of components mismatch for array crossProduct !");
4490   if(nbOfComp!=3)
4491     throw INTERP_KERNEL::Exception("Nb of components must be equal to 3 for array crossProduct !");
4492   int nbOfTuple=a1->getNumberOfTuples();
4493   if(nbOfTuple!=a2->getNumberOfTuples())
4494     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array crossProduct !");
4495   DataArrayDouble *ret=DataArrayDouble::New();
4496   ret->alloc(nbOfTuple,3);
4497   double *retPtr=ret->getPointer();
4498   const double *a1Ptr=a1->getConstPointer();
4499   const double *a2Ptr=a2->getConstPointer();
4500   for(int i=0;i<nbOfTuple;i++)
4501     {
4502       retPtr[3*i]=a1Ptr[3*i+1]*a2Ptr[3*i+2]-a1Ptr[3*i+2]*a2Ptr[3*i+1];
4503       retPtr[3*i+1]=a1Ptr[3*i+2]*a2Ptr[3*i]-a1Ptr[3*i]*a2Ptr[3*i+2];
4504       retPtr[3*i+2]=a1Ptr[3*i]*a2Ptr[3*i+1]-a1Ptr[3*i+1]*a2Ptr[3*i];
4505     }
4506   ret->copyStringInfoFrom(*a1);
4507   return ret;
4508 }
4509
4510 /*!
4511  * Returns a new DataArrayDouble containing maximal values of two given arrays.
4512  * Info on components is copied from the first of the given arrays.
4513  * Number of tuples and components in the given arrays must be the same.
4514  *  \param [in] a1 - an array to compare values with another one.
4515  *  \param [in] a2 - another array to compare values with the first one.
4516  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4517  *          The caller is to delete this result array using decrRef() as it is no more
4518  *          needed.
4519  *  \throw If either \a a1 or \a a2 is NULL.
4520  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
4521  *  \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents()
4522  */
4523 DataArrayDouble *DataArrayDouble::Max(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception)
4524 {
4525   if(!a1 || !a2)
4526     throw INTERP_KERNEL::Exception("DataArrayDouble::Max : input DataArrayDouble instance is NULL !");
4527   int nbOfComp=a1->getNumberOfComponents();
4528   if(nbOfComp!=a2->getNumberOfComponents())
4529     throw INTERP_KERNEL::Exception("Nb of components mismatch for array Max !");
4530   int nbOfTuple=a1->getNumberOfTuples();
4531   if(nbOfTuple!=a2->getNumberOfTuples())
4532     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Max !");
4533   DataArrayDouble *ret=DataArrayDouble::New();
4534   ret->alloc(nbOfTuple,nbOfComp);
4535   double *retPtr=ret->getPointer();
4536   const double *a1Ptr=a1->getConstPointer();
4537   const double *a2Ptr=a2->getConstPointer();
4538   int nbElem=nbOfTuple*nbOfComp;
4539   for(int i=0;i<nbElem;i++)
4540     retPtr[i]=std::max(a1Ptr[i],a2Ptr[i]);
4541   ret->copyStringInfoFrom(*a1);
4542   return ret;
4543 }
4544
4545 /*!
4546  * Returns a new DataArrayDouble containing minimal values of two given arrays.
4547  * Info on components is copied from the first of the given arrays.
4548  * Number of tuples and components in the given arrays must be the same.
4549  *  \param [in] a1 - an array to compare values with another one.
4550  *  \param [in] a2 - another array to compare values with the first one.
4551  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4552  *          The caller is to delete this result array using decrRef() as it is no more
4553  *          needed.
4554  *  \throw If either \a a1 or \a a2 is NULL.
4555  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
4556  *  \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents()
4557  */
4558 DataArrayDouble *DataArrayDouble::Min(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception)
4559 {
4560   if(!a1 || !a2)
4561     throw INTERP_KERNEL::Exception("DataArrayDouble::Min : input DataArrayDouble instance is NULL !");
4562   int nbOfComp=a1->getNumberOfComponents();
4563   if(nbOfComp!=a2->getNumberOfComponents())
4564     throw INTERP_KERNEL::Exception("Nb of components mismatch for array min !");
4565   int nbOfTuple=a1->getNumberOfTuples();
4566   if(nbOfTuple!=a2->getNumberOfTuples())
4567     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array min !");
4568   DataArrayDouble *ret=DataArrayDouble::New();
4569   ret->alloc(nbOfTuple,nbOfComp);
4570   double *retPtr=ret->getPointer();
4571   const double *a1Ptr=a1->getConstPointer();
4572   const double *a2Ptr=a2->getConstPointer();
4573   int nbElem=nbOfTuple*nbOfComp;
4574   for(int i=0;i<nbElem;i++)
4575     retPtr[i]=std::min(a1Ptr[i],a2Ptr[i]);
4576   ret->copyStringInfoFrom(*a1);
4577   return ret;
4578 }
4579
4580 /*!
4581  * Returns a new DataArrayDouble that is a sum of two given arrays. There are 3
4582  * valid cases.
4583  * 1.  The arrays have same number of tuples and components. Then each value of
4584  *   the result array (_a_) is a sum of the corresponding values of \a a1 and \a a2,
4585  *   i.e.: _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ i, j ].
4586  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
4587  *   component. Then
4588  *   _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ i, 0 ].
4589  * 3.  The arrays have same number of components and one array, say _a2_, has one
4590  *   tuple. Then
4591  *   _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ 0, j ].
4592  *
4593  * Info on components is copied either from the first array (in the first case) or from
4594  * the array with maximal number of elements (getNbOfElems()).
4595  *  \param [in] a1 - an array to sum up.
4596  *  \param [in] a2 - another array to sum up.
4597  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4598  *          The caller is to delete this result array using decrRef() as it is no more
4599  *          needed.
4600  *  \throw If either \a a1 or \a a2 is NULL.
4601  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
4602  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
4603  *         none of them has number of tuples or components equal to 1.
4604  */
4605 DataArrayDouble *DataArrayDouble::Add(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception)
4606 {
4607   if(!a1 || !a2)
4608     throw INTERP_KERNEL::Exception("DataArrayDouble::Add : input DataArrayDouble instance is NULL !");
4609   int nbOfTuple=a1->getNumberOfTuples();
4610   int nbOfTuple2=a2->getNumberOfTuples();
4611   int nbOfComp=a1->getNumberOfComponents();
4612   int nbOfComp2=a2->getNumberOfComponents();
4613   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=0;
4614   if(nbOfTuple==nbOfTuple2)
4615     {
4616       if(nbOfComp==nbOfComp2)
4617         {
4618           ret=DataArrayDouble::New();
4619           ret->alloc(nbOfTuple,nbOfComp);
4620           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::plus<double>());
4621           ret->copyStringInfoFrom(*a1);
4622         }
4623       else
4624         {
4625           int nbOfCompMin,nbOfCompMax;
4626           const DataArrayDouble *aMin, *aMax;
4627           if(nbOfComp>nbOfComp2)
4628             {
4629               nbOfCompMin=nbOfComp2; nbOfCompMax=nbOfComp;
4630               aMin=a2; aMax=a1;
4631             }
4632           else
4633             {
4634               nbOfCompMin=nbOfComp; nbOfCompMax=nbOfComp2;
4635               aMin=a1; aMax=a2;
4636             }
4637           if(nbOfCompMin==1)
4638             {
4639               ret=DataArrayDouble::New();
4640               ret->alloc(nbOfTuple,nbOfCompMax);
4641               const double *aMinPtr=aMin->getConstPointer();
4642               const double *aMaxPtr=aMax->getConstPointer();
4643               double *res=ret->getPointer();
4644               for(int i=0;i<nbOfTuple;i++)
4645                 res=std::transform(aMaxPtr+i*nbOfCompMax,aMaxPtr+(i+1)*nbOfCompMax,res,std::bind2nd(std::plus<double>(),aMinPtr[i]));
4646               ret->copyStringInfoFrom(*aMax);
4647             }
4648           else
4649             throw INTERP_KERNEL::Exception("Nb of components mismatch for array Add !");
4650         }
4651     }
4652   else if((nbOfTuple==1 && nbOfTuple2>1) || (nbOfTuple>1 && nbOfTuple2==1))
4653     {
4654       if(nbOfComp==nbOfComp2)
4655         {
4656           int nbOfTupleMax=std::max(nbOfTuple,nbOfTuple2);
4657           const DataArrayDouble *aMin=nbOfTuple>nbOfTuple2?a2:a1;
4658           const DataArrayDouble *aMax=nbOfTuple>nbOfTuple2?a1:a2;
4659           const double *aMinPtr=aMin->getConstPointer(),*aMaxPtr=aMax->getConstPointer();
4660           ret=DataArrayDouble::New();
4661           ret->alloc(nbOfTupleMax,nbOfComp);
4662           double *res=ret->getPointer();
4663           for(int i=0;i<nbOfTupleMax;i++)
4664             res=std::transform(aMaxPtr+i*nbOfComp,aMaxPtr+(i+1)*nbOfComp,aMinPtr,res,std::plus<double>());
4665           ret->copyStringInfoFrom(*aMax);
4666         }
4667       else
4668         throw INTERP_KERNEL::Exception("Nb of components mismatch for array Add !");
4669     }
4670   else
4671     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Add !");
4672   return ret.retn();
4673 }
4674
4675 /*!
4676  * Adds values of another DataArrayDouble to values of \a this one. There are 3
4677  * valid cases.
4678  * 1.  The arrays have same number of tuples and components. Then each value of
4679  *   \a other array is added to the corresponding value of \a this array, i.e.:
4680  *   _a_ [ i, j ] += _other_ [ i, j ].
4681  * 2.  The arrays have same number of tuples and \a other array has one component. Then
4682  *   _a_ [ i, j ] += _other_ [ i, 0 ].
4683  * 3.  The arrays have same number of components and \a other array has one tuple. Then
4684  *   _a_ [ i, j ] += _a2_ [ 0, j ].
4685  *
4686  *  \param [in] other - an array to add to \a this one.
4687  *  \throw If \a other is NULL.
4688  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
4689  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
4690  *         \a other has number of both tuples and components not equal to 1.
4691  */
4692 void DataArrayDouble::addEqual(const DataArrayDouble *other) throw(INTERP_KERNEL::Exception)
4693 {
4694   if(!other)
4695     throw INTERP_KERNEL::Exception("DataArrayDouble::addEqual : input DataArrayDouble instance is NULL !");
4696   const char *msg="Nb of tuples mismatch for DataArrayDouble::addEqual  !";
4697   checkAllocated();
4698   other->checkAllocated();
4699   int nbOfTuple=getNumberOfTuples();
4700   int nbOfTuple2=other->getNumberOfTuples();
4701   int nbOfComp=getNumberOfComponents();
4702   int nbOfComp2=other->getNumberOfComponents();
4703   if(nbOfTuple==nbOfTuple2)
4704     {
4705       if(nbOfComp==nbOfComp2)
4706         {
4707           std::transform(begin(),end(),other->begin(),getPointer(),std::plus<double>());
4708         }
4709       else if(nbOfComp2==1)
4710         {
4711           double *ptr=getPointer();
4712           const double *ptrc=other->getConstPointer();
4713           for(int i=0;i<nbOfTuple;i++)
4714             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::plus<double>(),*ptrc++));
4715         }
4716       else
4717         throw INTERP_KERNEL::Exception(msg);
4718     }
4719   else if(nbOfTuple2==1)
4720     {
4721       if(nbOfComp2==nbOfComp)
4722         {
4723           double *ptr=getPointer();
4724           const double *ptrc=other->getConstPointer();
4725           for(int i=0;i<nbOfTuple;i++)
4726             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::plus<double>());
4727         }
4728       else
4729         throw INTERP_KERNEL::Exception(msg);
4730     }
4731   else
4732     throw INTERP_KERNEL::Exception(msg);
4733   declareAsNew();
4734 }
4735
4736 /*!
4737  * Returns a new DataArrayDouble that is a subtraction of two given arrays. There are 3
4738  * valid cases.
4739  * 1.  The arrays have same number of tuples and components. Then each value of
4740  *   the result array (_a_) is a subtraction of the corresponding values of \a a1 and
4741  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ i, j ].
4742  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
4743  *   component. Then
4744  *   _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ i, 0 ].
4745  * 3.  The arrays have same number of components and one array, say _a2_, has one
4746  *   tuple. Then
4747  *   _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ 0, j ].
4748  *
4749  * Info on components is copied either from the first array (in the first case) or from
4750  * the array with maximal number of elements (getNbOfElems()).
4751  *  \param [in] a1 - an array to subtract from.
4752  *  \param [in] a2 - an array to subtract.
4753  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4754  *          The caller is to delete this result array using decrRef() as it is no more
4755  *          needed.
4756  *  \throw If either \a a1 or \a a2 is NULL.
4757  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
4758  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
4759  *         none of them has number of tuples or components equal to 1.
4760  */
4761 DataArrayDouble *DataArrayDouble::Substract(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception)
4762 {
4763   if(!a1 || !a2)
4764     throw INTERP_KERNEL::Exception("DataArrayDouble::Substract : input DataArrayDouble instance is NULL !");
4765   int nbOfTuple1=a1->getNumberOfTuples();
4766   int nbOfTuple2=a2->getNumberOfTuples();
4767   int nbOfComp1=a1->getNumberOfComponents();
4768   int nbOfComp2=a2->getNumberOfComponents();
4769   if(nbOfTuple2==nbOfTuple1)
4770     {
4771       if(nbOfComp1==nbOfComp2)
4772         {
4773           MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
4774           ret->alloc(nbOfTuple2,nbOfComp1);
4775           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::minus<double>());
4776           ret->copyStringInfoFrom(*a1);
4777           return ret.retn();
4778         }
4779       else if(nbOfComp2==1)
4780         {
4781           MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
4782           ret->alloc(nbOfTuple1,nbOfComp1);
4783           const double *a2Ptr=a2->getConstPointer();
4784           const double *a1Ptr=a1->getConstPointer();
4785           double *res=ret->getPointer();
4786           for(int i=0;i<nbOfTuple1;i++)
4787             res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::minus<double>(),a2Ptr[i]));
4788           ret->copyStringInfoFrom(*a1);
4789           return ret.retn();
4790         }
4791       else
4792         {
4793           a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Substract !");
4794           return 0;
4795         }
4796     }
4797   else if(nbOfTuple2==1)
4798     {
4799       a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Substract !");
4800       MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
4801       ret->alloc(nbOfTuple1,nbOfComp1);
4802       const double *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
4803       double *pt=ret->getPointer();
4804       for(int i=0;i<nbOfTuple1;i++)
4805         pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::minus<double>());
4806       ret->copyStringInfoFrom(*a1);
4807       return ret.retn();
4808     }
4809   else
4810     {
4811       a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Substract !");//will always throw an exception
4812       return 0;
4813     }
4814 }
4815
4816 /*!
4817  * Subtract values of another DataArrayDouble from values of \a this one. There are 3
4818  * valid cases.
4819  * 1.  The arrays have same number of tuples and components. Then each value of
4820  *   \a other array is subtracted from the corresponding value of \a this array, i.e.:
4821  *   _a_ [ i, j ] -= _other_ [ i, j ].
4822  * 2.  The arrays have same number of tuples and \a other array has one component. Then
4823  *   _a_ [ i, j ] -= _other_ [ i, 0 ].
4824  * 3.  The arrays have same number of components and \a other array has one tuple. Then
4825  *   _a_ [ i, j ] -= _a2_ [ 0, j ].
4826  *
4827  *  \param [in] other - an array to subtract from \a this one.
4828  *  \throw If \a other is NULL.
4829  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
4830  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
4831  *         \a other has number of both tuples and components not equal to 1.
4832  */
4833 void DataArrayDouble::substractEqual(const DataArrayDouble *other) throw(INTERP_KERNEL::Exception)
4834 {
4835   if(!other)
4836     throw INTERP_KERNEL::Exception("DataArrayDouble::substractEqual : input DataArrayDouble instance is NULL !");
4837   const char *msg="Nb of tuples mismatch for DataArrayDouble::substractEqual  !";
4838   checkAllocated();
4839   other->checkAllocated();
4840   int nbOfTuple=getNumberOfTuples();
4841   int nbOfTuple2=other->getNumberOfTuples();
4842   int nbOfComp=getNumberOfComponents();
4843   int nbOfComp2=other->getNumberOfComponents();
4844   if(nbOfTuple==nbOfTuple2)
4845     {
4846       if(nbOfComp==nbOfComp2)
4847         {
4848           std::transform(begin(),end(),other->begin(),getPointer(),std::minus<double>());
4849         }
4850       else if(nbOfComp2==1)
4851         {
4852           double *ptr=getPointer();
4853           const double *ptrc=other->getConstPointer();
4854           for(int i=0;i<nbOfTuple;i++)
4855             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::minus<double>(),*ptrc++)); 
4856         }
4857       else
4858         throw INTERP_KERNEL::Exception(msg);
4859     }
4860   else if(nbOfTuple2==1)
4861     {
4862       if(nbOfComp2==nbOfComp)
4863         {
4864           double *ptr=getPointer();
4865           const double *ptrc=other->getConstPointer();
4866           for(int i=0;i<nbOfTuple;i++)
4867             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::minus<double>());
4868         }
4869       else
4870         throw INTERP_KERNEL::Exception(msg);
4871     }
4872   else
4873     throw INTERP_KERNEL::Exception(msg);
4874   declareAsNew();
4875 }
4876
4877 /*!
4878  * Returns a new DataArrayDouble that is a product of two given arrays. There are 3
4879  * valid cases.
4880  * 1.  The arrays have same number of tuples and components. Then each value of
4881  *   the result array (_a_) is a product of the corresponding values of \a a1 and
4882  *   \a a2, i.e. _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ i, j ].
4883  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
4884  *   component. Then
4885  *   _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ i, 0 ].
4886  * 3.  The arrays have same number of components and one array, say _a2_, has one
4887  *   tuple. Then
4888  *   _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ 0, j ].
4889  *
4890  * Info on components is copied either from the first array (in the first case) or from
4891  * the array with maximal number of elements (getNbOfElems()).
4892  *  \param [in] a1 - a factor array.
4893  *  \param [in] a2 - another factor array.
4894  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4895  *          The caller is to delete this result array using decrRef() as it is no more
4896  *          needed.
4897  *  \throw If either \a a1 or \a a2 is NULL.
4898  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
4899  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
4900  *         none of them has number of tuples or components equal to 1.
4901  */
4902 DataArrayDouble *DataArrayDouble::Multiply(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception)
4903 {
4904   if(!a1 || !a2)
4905     throw INTERP_KERNEL::Exception("DataArrayDouble::Multiply : input DataArrayDouble instance is NULL !");
4906   int nbOfTuple=a1->getNumberOfTuples();
4907   int nbOfTuple2=a2->getNumberOfTuples();
4908   int nbOfComp=a1->getNumberOfComponents();
4909   int nbOfComp2=a2->getNumberOfComponents();
4910   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=0;
4911   if(nbOfTuple==nbOfTuple2)
4912     {
4913       if(nbOfComp==nbOfComp2)
4914         {
4915           ret=DataArrayDouble::New();
4916           ret->alloc(nbOfTuple,nbOfComp);
4917           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::multiplies<double>());
4918           ret->copyStringInfoFrom(*a1);
4919         }
4920       else
4921         {
4922           int nbOfCompMin,nbOfCompMax;
4923           const DataArrayDouble *aMin, *aMax;
4924           if(nbOfComp>nbOfComp2)
4925             {
4926               nbOfCompMin=nbOfComp2; nbOfCompMax=nbOfComp;
4927               aMin=a2; aMax=a1;
4928             }
4929           else
4930             {
4931               nbOfCompMin=nbOfComp; nbOfCompMax=nbOfComp2;
4932               aMin=a1; aMax=a2;
4933             }
4934           if(nbOfCompMin==1)
4935             {
4936               ret=DataArrayDouble::New();
4937               ret->alloc(nbOfTuple,nbOfCompMax);
4938               const double *aMinPtr=aMin->getConstPointer();
4939               const double *aMaxPtr=aMax->getConstPointer();
4940               double *res=ret->getPointer();
4941               for(int i=0;i<nbOfTuple;i++)
4942                 res=std::transform(aMaxPtr+i*nbOfCompMax,aMaxPtr+(i+1)*nbOfCompMax,res,std::bind2nd(std::multiplies<double>(),aMinPtr[i]));
4943               ret->copyStringInfoFrom(*aMax);
4944             }
4945           else
4946             throw INTERP_KERNEL::Exception("Nb of components mismatch for array Multiply !");
4947         }
4948     }
4949   else if((nbOfTuple==1 && nbOfTuple2>1) || (nbOfTuple>1 && nbOfTuple2==1))
4950     {
4951       if(nbOfComp==nbOfComp2)
4952         {
4953           int nbOfTupleMax=std::max(nbOfTuple,nbOfTuple2);
4954           const DataArrayDouble *aMin=nbOfTuple>nbOfTuple2?a2:a1;
4955           const DataArrayDouble *aMax=nbOfTuple>nbOfTuple2?a1:a2;
4956           const double *aMinPtr=aMin->getConstPointer(),*aMaxPtr=aMax->getConstPointer();
4957           ret=DataArrayDouble::New();
4958           ret->alloc(nbOfTupleMax,nbOfComp);
4959           double *res=ret->getPointer();
4960           for(int i=0;i<nbOfTupleMax;i++)
4961             res=std::transform(aMaxPtr+i*nbOfComp,aMaxPtr+(i+1)*nbOfComp,aMinPtr,res,std::multiplies<double>());
4962           ret->copyStringInfoFrom(*aMax);
4963         }
4964       else
4965         throw INTERP_KERNEL::Exception("Nb of components mismatch for array Multiply !");
4966     }
4967   else
4968     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Multiply !");
4969   return ret.retn();
4970 }
4971
4972 /*!
4973  * Multiply values of another DataArrayDouble to values of \a this one. There are 3
4974  * valid cases.
4975  * 1.  The arrays have same number of tuples and components. Then each value of
4976  *   \a other array is multiplied to the corresponding value of \a this array, i.e.
4977  *   _this_ [ i, j ] *= _other_ [ i, j ].
4978  * 2.  The arrays have same number of tuples and \a other array has one component. Then
4979  *   _this_ [ i, j ] *= _other_ [ i, 0 ].
4980  * 3.  The arrays have same number of components and \a other array has one tuple. Then
4981  *   _this_ [ i, j ] *= _a2_ [ 0, j ].
4982  *
4983  *  \param [in] other - an array to multiply to \a this one.
4984  *  \throw If \a other is NULL.
4985  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
4986  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
4987  *         \a other has number of both tuples and components not equal to 1.
4988  */
4989 void DataArrayDouble::multiplyEqual(const DataArrayDouble *other) throw(INTERP_KERNEL::Exception)
4990 {
4991   if(!other)
4992     throw INTERP_KERNEL::Exception("DataArrayDouble::multiplyEqual : input DataArrayDouble instance is NULL !");
4993   const char *msg="Nb of tuples mismatch for DataArrayDouble::multiplyEqual !";
4994   checkAllocated();
4995   other->checkAllocated();
4996   int nbOfTuple=getNumberOfTuples();
4997   int nbOfTuple2=other->getNumberOfTuples();
4998   int nbOfComp=getNumberOfComponents();
4999   int nbOfComp2=other->getNumberOfComponents();
5000   if(nbOfTuple==nbOfTuple2)
5001     {
5002       if(nbOfComp==nbOfComp2)
5003         {
5004           std::transform(begin(),end(),other->begin(),getPointer(),std::multiplies<double>());
5005         }
5006       else if(nbOfComp2==1)
5007         {
5008           double *ptr=getPointer();
5009           const double *ptrc=other->getConstPointer();
5010           for(int i=0;i<nbOfTuple;i++)
5011             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::multiplies<double>(),*ptrc++));
5012         }
5013       else
5014         throw INTERP_KERNEL::Exception(msg);
5015     }
5016   else if(nbOfTuple2==1)
5017     {
5018       if(nbOfComp2==nbOfComp)
5019         {
5020           double *ptr=getPointer();
5021           const double *ptrc=other->getConstPointer();
5022           for(int i=0;i<nbOfTuple;i++)
5023             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::multiplies<double>());
5024         }
5025       else
5026         throw INTERP_KERNEL::Exception(msg);
5027     }
5028   else
5029     throw INTERP_KERNEL::Exception(msg);
5030   declareAsNew();
5031 }
5032
5033 /*!
5034  * Returns a new DataArrayDouble that is a division of two given arrays. There are 3
5035  * valid cases.
5036  * 1.  The arrays have same number of tuples and components. Then each value of
5037  *   the result array (_a_) is a division of the corresponding values of \a a1 and
5038  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ i, j ].
5039  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
5040  *   component. Then
5041  *   _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ i, 0 ].
5042  * 3.  The arrays have same number of components and one array, say _a2_, has one
5043  *   tuple. Then
5044  *   _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ 0, j ].
5045  *
5046  * Info on components is copied either from the first array (in the first case) or from
5047  * the array with maximal number of elements (getNbOfElems()).
5048  *  \warning No check of division by zero is performed!
5049  *  \param [in] a1 - a numerator array.
5050  *  \param [in] a2 - a denominator array.
5051  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
5052  *          The caller is to delete this result array using decrRef() as it is no more
5053  *          needed.
5054  *  \throw If either \a a1 or \a a2 is NULL.
5055  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
5056  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
5057  *         none of them has number of tuples or components equal to 1.
5058  */
5059 DataArrayDouble *DataArrayDouble::Divide(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception)
5060 {
5061   if(!a1 || !a2)
5062     throw INTERP_KERNEL::Exception("DataArrayDouble::Divide : input DataArrayDouble instance is NULL !");
5063   int nbOfTuple1=a1->getNumberOfTuples();
5064   int nbOfTuple2=a2->getNumberOfTuples();
5065   int nbOfComp1=a1->getNumberOfComponents();
5066   int nbOfComp2=a2->getNumberOfComponents();
5067   if(nbOfTuple2==nbOfTuple1)
5068     {
5069       if(nbOfComp1==nbOfComp2)
5070         {
5071           MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
5072           ret->alloc(nbOfTuple2,nbOfComp1);
5073           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::divides<double>());
5074           ret->copyStringInfoFrom(*a1);
5075           return ret.retn();
5076         }
5077       else if(nbOfComp2==1)
5078         {
5079           MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
5080           ret->alloc(nbOfTuple1,nbOfComp1);
5081           const double *a2Ptr=a2->getConstPointer();
5082           const double *a1Ptr=a1->getConstPointer();
5083           double *res=ret->getPointer();
5084           for(int i=0;i<nbOfTuple1;i++)
5085             res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::divides<double>(),a2Ptr[i]));
5086           ret->copyStringInfoFrom(*a1);
5087           return ret.retn();
5088         }
5089       else
5090         {
5091           a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Divide !");
5092           return 0;
5093         }
5094     }
5095   else if(nbOfTuple2==1)
5096     {
5097       a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Divide !");
5098       MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
5099       ret->alloc(nbOfTuple1,nbOfComp1);
5100       const double *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
5101       double *pt=ret->getPointer();
5102       for(int i=0;i<nbOfTuple1;i++)
5103         pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::divides<double>());
5104       ret->copyStringInfoFrom(*a1);
5105       return ret.retn();
5106     }
5107   else
5108     {
5109       a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Divide !");//will always throw an exception
5110       return 0;
5111     }
5112 }
5113
5114 /*!
5115  * Divide values of \a this array by values of another DataArrayDouble. There are 3
5116  * valid cases.
5117  * 1.  The arrays have same number of tuples and components. Then each value of
5118  *    \a this array is divided by the corresponding value of \a other one, i.e.:
5119  *   _a_ [ i, j ] /= _other_ [ i, j ].
5120  * 2.  The arrays have same number of tuples and \a other array has one component. Then
5121  *   _a_ [ i, j ] /= _other_ [ i, 0 ].
5122  * 3.  The arrays have same number of components and \a other array has one tuple. Then
5123  *   _a_ [ i, j ] /= _a2_ [ 0, j ].
5124  *
5125  *  \warning No check of division by zero is performed!
5126  *  \param [in] other - an array to divide \a this one by.
5127  *  \throw If \a other is NULL.
5128  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
5129  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
5130  *         \a other has number of both tuples and components not equal to 1.
5131  */
5132 void DataArrayDouble::divideEqual(const DataArrayDouble *other) throw(INTERP_KERNEL::Exception)
5133 {
5134   if(!other)
5135     throw INTERP_KERNEL::Exception("DataArrayDouble::divideEqual : input DataArrayDouble instance is NULL !");
5136   const char *msg="Nb of tuples mismatch for DataArrayDouble::divideEqual !";
5137   checkAllocated();
5138   other->checkAllocated();
5139   int nbOfTuple=getNumberOfTuples();
5140   int nbOfTuple2=other->getNumberOfTuples();
5141   int nbOfComp=getNumberOfComponents();
5142   int nbOfComp2=other->getNumberOfComponents();
5143   if(nbOfTuple==nbOfTuple2)
5144     {
5145       if(nbOfComp==nbOfComp2)
5146         {
5147           std::transform(begin(),end(),other->begin(),getPointer(),std::divides<double>());
5148         }
5149       else if(nbOfComp2==1)
5150         {
5151           double *ptr=getPointer();
5152           const double *ptrc=other->getConstPointer();
5153           for(int i=0;i<nbOfTuple;i++)
5154             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::divides<double>(),*ptrc++));
5155         }
5156       else
5157         throw INTERP_KERNEL::Exception(msg);
5158     }
5159   else if(nbOfTuple2==1)
5160     {
5161       if(nbOfComp2==nbOfComp)
5162         {
5163           double *ptr=getPointer();
5164           const double *ptrc=other->getConstPointer();
5165           for(int i=0;i<nbOfTuple;i++)
5166             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::divides<double>());
5167         }
5168       else
5169         throw INTERP_KERNEL::Exception(msg);
5170     }
5171   else
5172     throw INTERP_KERNEL::Exception(msg);
5173   declareAsNew();
5174 }
5175
5176 /*!
5177  * Returns a new DataArrayDouble that is the result of pow of two given arrays. There are 3
5178  * valid cases.
5179  *
5180  *  \param [in] a1 - an array to pow up.
5181  *  \param [in] a2 - another array to sum up.
5182  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
5183  *          The caller is to delete this result array using decrRef() as it is no more
5184  *          needed.
5185  *  \throw If either \a a1 or \a a2 is NULL.
5186  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
5187  *  \throw If \a a1->getNumberOfComponents() != 1 or \a a2->getNumberOfComponents() != 1.
5188  *  \throw If there is a negative value in \a a1.
5189  */
5190 DataArrayDouble *DataArrayDouble::Pow(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception)
5191 {
5192   if(!a1 || !a2)
5193     throw INTERP_KERNEL::Exception("DataArrayDouble::Pow : at least one of input instances is null !");
5194   int nbOfTuple=a1->getNumberOfTuples();
5195   int nbOfTuple2=a2->getNumberOfTuples();
5196   int nbOfComp=a1->getNumberOfComponents();
5197   int nbOfComp2=a2->getNumberOfComponents();
5198   if(nbOfTuple!=nbOfTuple2)
5199     throw INTERP_KERNEL::Exception("DataArrayDouble::Pow : number of tuples mismatches !");
5200   if(nbOfComp!=1 || nbOfComp2!=1)
5201     throw INTERP_KERNEL::Exception("DataArrayDouble::Pow : number of components of both arrays must be equal to 1 !");
5202   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New(); ret->alloc(nbOfTuple,1);
5203   const double *ptr1(a1->begin()),*ptr2(a2->begin());
5204   double *ptr=ret->getPointer();
5205   for(int i=0;i<nbOfTuple;i++,ptr1++,ptr2++,ptr++)
5206     {
5207       if(*ptr1>=0)
5208         {
5209           *ptr=pow(*ptr1,*ptr2);
5210         }
5211       else
5212         {
5213           std::ostringstream oss; oss << "DataArrayDouble::Pow : on tuple #" << i << " of a1 value is < 0 (" << *ptr1 << ") !";
5214           throw INTERP_KERNEL::Exception(oss.str().c_str());
5215         }
5216     }
5217   return ret.retn();
5218 }
5219
5220 /*!
5221  * Apply pow on values of another DataArrayDouble to values of \a this one.
5222  *
5223  *  \param [in] other - an array to pow to \a this one.
5224  *  \throw If \a other is NULL.
5225  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples()
5226  *  \throw If \a this->getNumberOfComponents() != 1 or \a other->getNumberOfComponents() != 1
5227  *  \throw If there is a negative value in \a this.
5228  */
5229 void DataArrayDouble::powEqual(const DataArrayDouble *other) throw(INTERP_KERNEL::Exception)
5230 {
5231   if(!other)
5232     throw INTERP_KERNEL::Exception("DataArrayDouble::powEqual : input instance is null !");
5233   int nbOfTuple=getNumberOfTuples();
5234   int nbOfTuple2=other->getNumberOfTuples();
5235   int nbOfComp=getNumberOfComponents();
5236   int nbOfComp2=other->getNumberOfComponents();
5237   if(nbOfTuple!=nbOfTuple2)
5238     throw INTERP_KERNEL::Exception("DataArrayDouble::powEqual : number of tuples mismatches !");
5239   if(nbOfComp!=1 || nbOfComp2!=1)
5240     throw INTERP_KERNEL::Exception("DataArrayDouble::powEqual : number of components of both arrays must be equal to 1 !");
5241   double *ptr=getPointer();
5242   const double *ptrc=other->begin();
5243   for(int i=0;i<nbOfTuple;i++,ptrc++,ptr++)
5244     {
5245       if(*ptr>=0)
5246         *ptr=pow(*ptr,*ptrc);
5247       else
5248         {
5249           std::ostringstream oss; oss << "DataArrayDouble::powEqual : on tuple #" << i << " of this value is < 0 (" << *ptr << ") !";
5250           throw INTERP_KERNEL::Exception(oss.str().c_str());
5251         }
5252     }
5253   declareAsNew();
5254 }
5255
5256 /*!
5257  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
5258  * Server side.
5259  */
5260 void DataArrayDouble::getTinySerializationIntInformation(std::vector<int>& tinyInfo) const
5261 {
5262   tinyInfo.resize(2);
5263   if(isAllocated())
5264     {
5265       tinyInfo[0]=getNumberOfTuples();
5266       tinyInfo[1]=getNumberOfComponents();
5267     }
5268   else
5269     {
5270       tinyInfo[0]=-1;
5271       tinyInfo[1]=-1;
5272     }
5273 }
5274
5275 /*!
5276  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
5277  * Server side.
5278  */
5279 void DataArrayDouble::getTinySerializationStrInformation(std::vector<std::string>& tinyInfo) const
5280 {
5281   if(isAllocated())
5282     {
5283       int nbOfCompo=getNumberOfComponents();
5284       tinyInfo.resize(nbOfCompo+1);
5285       tinyInfo[0]=getName();
5286       for(int i=0;i<nbOfCompo;i++)
5287         tinyInfo[i+1]=getInfoOnComponent(i);
5288     }
5289   else
5290     {
5291       tinyInfo.resize(1);
5292       tinyInfo[0]=getName();
5293     }
5294 }
5295
5296 /*!
5297  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
5298  * This method returns if a feeding is needed.
5299  */
5300 bool DataArrayDouble::resizeForUnserialization(const std::vector<int>& tinyInfoI)
5301 {
5302   int nbOfTuple=tinyInfoI[0];
5303   int nbOfComp=tinyInfoI[1];
5304   if(nbOfTuple!=-1 || nbOfComp!=-1)
5305     {
5306       alloc(nbOfTuple,nbOfComp);
5307       return true;
5308     }
5309   return false;
5310 }
5311
5312 /*!
5313  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
5314  */
5315 void DataArrayDouble::finishUnserialization(const std::vector<int>& tinyInfoI, const std::vector<std::string>& tinyInfoS)
5316 {
5317   setName(tinyInfoS[0].c_str());
5318   if(isAllocated())
5319     {
5320       int nbOfCompo=getNumberOfComponents();
5321       for(int i=0;i<nbOfCompo;i++)
5322         setInfoOnComponent(i,tinyInfoS[i+1].c_str());
5323     }
5324 }
5325
5326 DataArrayDoubleIterator::DataArrayDoubleIterator(DataArrayDouble *da):_da(da),_tuple_id(0),_nb_comp(0),_nb_tuple(0)
5327 {
5328   if(_da)
5329     {
5330       _da->incrRef();
5331       if(_da->isAllocated())
5332         {
5333           _nb_comp=da->getNumberOfComponents();
5334           _nb_tuple=da->getNumberOfTuples();
5335           _pt=da->getPointer();
5336         }
5337     }
5338 }
5339
5340 DataArrayDoubleIterator::~DataArrayDoubleIterator()
5341 {
5342   if(_da)
5343     _da->decrRef();
5344 }
5345
5346 DataArrayDoubleTuple *DataArrayDoubleIterator::nextt() throw(INTERP_KERNEL::Exception)
5347 {
5348   if(_tuple_id<_nb_tuple)
5349     {
5350       _tuple_id++;
5351       DataArrayDoubleTuple *ret=new DataArrayDoubleTuple(_pt,_nb_comp);
5352       _pt+=_nb_comp;
5353       return ret;
5354     }
5355   else
5356     return 0;
5357 }
5358
5359 DataArrayDoubleTuple::DataArrayDoubleTuple(double *pt, int nbOfComp):_pt(pt),_nb_of_compo(nbOfComp)
5360 {
5361 }
5362
5363
5364 std::string DataArrayDoubleTuple::repr() const throw(INTERP_KERNEL::Exception)
5365 {
5366   std::ostringstream oss; oss.precision(17); oss << "(";
5367   for(int i=0;i<_nb_of_compo-1;i++)
5368     oss << _pt[i] << ", ";
5369   oss << _pt[_nb_of_compo-1] << ")";
5370   return oss.str();
5371 }
5372
5373 double DataArrayDoubleTuple::doubleValue() const throw(INTERP_KERNEL::Exception)
5374 {
5375   if(_nb_of_compo==1)
5376     return *_pt;
5377   throw INTERP_KERNEL::Exception("DataArrayDoubleTuple::doubleValue : DataArrayDoubleTuple instance has not exactly 1 component -> Not possible to convert it into a double precision float !");
5378 }
5379
5380 /*!
5381  * This method returns a newly allocated instance the caller should dealed with by a ParaMEDMEM::DataArrayDouble::decrRef.
5382  * This method performs \b no copy of data. The content is only referenced using ParaMEDMEM::DataArrayDouble::useArray with ownership set to \b false.
5383  * 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
5384  * \b nbOfCompo=1 and \bnbOfTuples==this->_nb_of_elem.
5385  */
5386 DataArrayDouble *DataArrayDoubleTuple::buildDADouble(int nbOfTuples, int nbOfCompo) const throw(INTERP_KERNEL::Exception)
5387 {
5388   if((_nb_of_compo==nbOfCompo && nbOfTuples==1) || (_nb_of_compo==nbOfTuples && nbOfCompo==1))
5389     {
5390       DataArrayDouble *ret=DataArrayDouble::New();
5391       ret->useExternalArrayWithRWAccess(_pt,nbOfTuples,nbOfCompo);
5392       return ret;
5393     }
5394   else
5395     {
5396       std::ostringstream oss; oss << "DataArrayDoubleTuple::buildDADouble : unable to build a requested DataArrayDouble instance with nbofTuple=" << nbOfTuples << " and nbOfCompo=" << nbOfCompo;
5397       oss << ".\nBecause the number of elements in this is " << _nb_of_compo << " !";
5398       throw INTERP_KERNEL::Exception(oss.str().c_str());
5399     }
5400 }
5401
5402 /*!
5403  * Returns a new instance of DataArrayInt. The caller is to delete this array
5404  * using decrRef() as it is no more needed. 
5405  */
5406 DataArrayInt *DataArrayInt::New()
5407 {
5408   return new DataArrayInt;
5409 }
5410
5411 /*!
5412  * Checks if raw data is allocated. Read more on the raw data
5413  * in \ref MEDCouplingArrayBasicsTuplesAndCompo "DataArrays infos" for more information.
5414  *  \return bool - \a true if the raw data is allocated, \a false else.
5415  */
5416 bool DataArrayInt::isAllocated() const throw(INTERP_KERNEL::Exception)
5417 {
5418   return getConstPointer()!=0;
5419 }
5420
5421 /*!
5422  * Checks if raw data is allocated and throws an exception if it is not the case.
5423  *  \throw If the raw data is not allocated.
5424  */
5425 void DataArrayInt::checkAllocated() const throw(INTERP_KERNEL::Exception)
5426 {
5427   if(!isAllocated())
5428     throw INTERP_KERNEL::Exception("DataArrayInt::checkAllocated : Array is defined but not allocated ! Call alloc or setValues method first !");
5429 }
5430
5431 std::size_t DataArrayInt::getHeapMemorySize() const
5432 {
5433   std::size_t sz=_mem.getNbOfElemAllocated();
5434   sz*=sizeof(int);
5435   return DataArray::getHeapMemorySize()+sz;
5436 }
5437
5438 /*!
5439  * Returns the only one value in \a this, if and only if number of elements
5440  * (nb of tuples * nb of components) is equal to 1, and that \a this is allocated.
5441  *  \return double - the sole value stored in \a this array.
5442  *  \throw If at least one of conditions stated above is not fulfilled.
5443  */
5444 int DataArrayInt::intValue() const throw(INTERP_KERNEL::Exception)
5445 {
5446   if(isAllocated())
5447     {
5448       if(getNbOfElems()==1)
5449         {
5450           return *getConstPointer();
5451         }
5452       else
5453         throw INTERP_KERNEL::Exception("DataArrayInt::intValue : DataArrayInt instance is allocated but number of elements is not equal to 1 !");
5454     }
5455   else
5456     throw INTERP_KERNEL::Exception("DataArrayInt::intValue : DataArrayInt instance is not allocated !");
5457 }
5458
5459 /*!
5460  * Returns an integer value characterizing \a this array, which is useful for a quick
5461  * comparison of many instances of DataArrayInt.
5462  *  \return int - the hash value.
5463  *  \throw If \a this is not allocated.
5464  */
5465 int DataArrayInt::getHashCode() const throw(INTERP_KERNEL::Exception)
5466 {
5467   checkAllocated();
5468   std::size_t nbOfElems=getNbOfElems();
5469   int ret=nbOfElems*65536;
5470   int delta=3;
5471   if(nbOfElems>48)
5472     delta=nbOfElems/8;
5473   int ret0=0;
5474   const int *pt=begin();
5475   for(std::size_t i=0;i<nbOfElems;i+=delta)
5476     ret0+=pt[i] & 0x1FFF;
5477   return ret+ret0;
5478 }
5479
5480 /*!
5481  * Checks the number of tuples.
5482  *  \return bool - \a true if getNumberOfTuples() == 0, \a false else.
5483  *  \throw If \a this is not allocated.
5484  */
5485 bool DataArrayInt::empty() const throw(INTERP_KERNEL::Exception)
5486 {
5487   checkAllocated();
5488   return getNumberOfTuples()==0;
5489 }
5490
5491 /*!
5492  * Returns a full copy of \a this. For more info on copying data arrays see
5493  * \ref MEDCouplingArrayBasicsCopyDeep.
5494  *  \return DataArrayInt * - a new instance of DataArrayInt.
5495  */
5496 DataArrayInt *DataArrayInt::deepCpy() const throw(INTERP_KERNEL::Exception)
5497 {
5498   return new DataArrayInt(*this);
5499 }
5500
5501 /*!
5502  * Returns either a \a deep or \a shallow copy of this array. For more info see
5503  * \ref MEDCouplingArrayBasicsCopyDeep and \ref MEDCouplingArrayBasicsCopyShallow.
5504  *  \param [in] dCpy - if \a true, a deep copy is returned, else, a shallow one.
5505  *  \return DataArrayInt * - either a new instance of DataArrayInt (if \a dCpy
5506  *          == \a true) or \a this instance (if \a dCpy == \a false).
5507  */
5508 DataArrayInt *DataArrayInt::performCpy(bool dCpy) const throw(INTERP_KERNEL::Exception)
5509 {
5510   if(dCpy)
5511     return deepCpy();
5512   else
5513     {
5514       incrRef();
5515       return const_cast<DataArrayInt *>(this);
5516     }
5517 }
5518
5519 /*!
5520  * Copies all the data from another DataArrayInt. For more info see
5521  * \ref MEDCouplingArrayBasicsCopyDeepAssign.
5522  *  \param [in] other - another instance of DataArrayInt to copy data from.
5523  *  \throw If the \a other is not allocated.
5524  */
5525 void DataArrayInt::cpyFrom(const DataArrayInt& other) throw(INTERP_KERNEL::Exception)
5526 {
5527   other.checkAllocated();
5528   int nbOfTuples=other.getNumberOfTuples();
5529   int nbOfComp=other.getNumberOfComponents();
5530   allocIfNecessary(nbOfTuples,nbOfComp);
5531   std::size_t nbOfElems=(std::size_t)nbOfTuples*nbOfComp;
5532   int *pt=getPointer();
5533   const int *ptI=other.getConstPointer();
5534   for(std::size_t i=0;i<nbOfElems;i++)
5535     pt[i]=ptI[i];
5536   copyStringInfoFrom(other);
5537 }
5538
5539 /*!
5540  * This method reserve nbOfElems elements in memory ( nbOfElems*4 bytes ) \b without impacting the number of tuples in \a this.
5541  * 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.
5542  * If \a this has not already been allocated, number of components is set to one.
5543  * This method allows to reduce number of reallocations on invokation of DataArrayInt::pushBackSilent and DataArrayInt::pushBackValsSilent on \a this.
5544  * 
5545  * \sa DataArrayInt::pack, DataArrayInt::pushBackSilent, DataArrayInt::pushBackValsSilent
5546  */
5547 void DataArrayInt::reserve(std::size_t nbOfElems) throw(INTERP_KERNEL::Exception)
5548 {
5549   int nbCompo=getNumberOfComponents();
5550   if(nbCompo==1)
5551     {
5552       _mem.reserve(nbOfElems);
5553     }
5554   else if(nbCompo==0)
5555     {
5556       _mem.reserve(nbOfElems);
5557       _info_on_compo.resize(1);
5558     }
5559   else
5560     throw INTERP_KERNEL::Exception("DataArrayInt::reserve : not available for DataArrayInt with number of components different than 1 !");
5561 }
5562
5563 /*!
5564  * 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
5565  * of counter. So the caller is expected to call TimeLabel::declareAsNew on \a this at the end of the push session.
5566  *
5567  * \param [in] val the value to be added in \a this
5568  * \throw If \a this has already been allocated with number of components different from one.
5569  * \sa DataArrayInt::pushBackValsSilent
5570  */
5571 void DataArrayInt::pushBackSilent(int val) throw(INTERP_KERNEL::Exception)
5572 {
5573   int nbCompo=getNumberOfComponents();
5574   if(nbCompo==1)
5575     _mem.pushBack(val);
5576   else if(nbCompo==0)
5577     {
5578       _info_on_compo.resize(1);
5579       _mem.pushBack(val);
5580     }
5581   else
5582     throw INTERP_KERNEL::Exception("DataArrayInt::pushBackSilent : not available for DataArrayInt with number of components different than 1 !");
5583 }
5584
5585 /*!
5586  * 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
5587  * of counter. So the caller is expected to call TimeLabel::declareAsNew on \a this at the end of the push session.
5588  *
5589  *  \param [in] valsBg - an array of values to push at the end of \this.
5590  *  \param [in] valsEnd - specifies the end of the array \a valsBg, so that
5591  *              the last value of \a valsBg is \a valsEnd[ -1 ].
5592  * \throw If \a this has already been allocated with number of components different from one.
5593  * \sa DataArrayInt::pushBackSilent
5594  */
5595 void DataArrayInt::pushBackValsSilent(const int *valsBg, const int *valsEnd) throw(INTERP_KERNEL::Exception)
5596 {
5597   int nbCompo=getNumberOfComponents();
5598   if(nbCompo==1)
5599     _mem.insertAtTheEnd(valsBg,valsEnd);
5600   else if(nbCompo==0)
5601     {
5602       _info_on_compo.resize(1);
5603       _mem.insertAtTheEnd(valsBg,valsEnd);
5604     }
5605   else
5606     throw INTERP_KERNEL::Exception("DataArrayInt::pushBackValsSilent : not available for DataArrayInt with number of components different than 1 !");
5607 }
5608
5609 /*!
5610  * This method returns silently ( without updating time label in \a this ) the last value, if any and suppress it.
5611  * \throw If \a this is already empty.
5612  * \throw If \a this has number of components different from one.
5613  */
5614 int DataArrayInt::popBackSilent() throw(INTERP_KERNEL::Exception)
5615 {
5616   if(getNumberOfComponents()==1)
5617     return _mem.popBack();
5618   else
5619     throw INTERP_KERNEL::Exception("DataArrayInt::popBackSilent : not available for DataArrayInt with number of components different than 1 !");
5620 }
5621
5622 /*!
5623  * 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.
5624  *
5625  * \sa DataArrayInt::getHeapMemorySize, DataArrayInt::reserve
5626  */
5627 void DataArrayInt::pack() const throw(INTERP_KERNEL::Exception)
5628 {
5629   _mem.pack();
5630 }
5631
5632 /*!
5633  * Allocates the raw data in memory. If exactly as same memory as needed already
5634  * allocated, it is not re-allocated.
5635  *  \param [in] nbOfTuple - number of tuples of data to allocate.
5636  *  \param [in] nbOfCompo - number of components of data to allocate.
5637  *  \throw If \a nbOfTuple < 0 or \a nbOfCompo < 0.
5638  */
5639 void DataArrayInt::allocIfNecessary(int nbOfTuple, int nbOfCompo) throw(INTERP_KERNEL::Exception)
5640 {
5641   if(isAllocated())
5642     {
5643       if(nbOfTuple!=getNumberOfTuples() || nbOfCompo!=getNumberOfComponents())
5644         alloc(nbOfTuple,nbOfCompo);
5645     }
5646   else
5647     alloc(nbOfTuple,nbOfCompo);
5648 }
5649
5650 /*!
5651  * Allocates the raw data in memory. If the memory was already allocated, then it is
5652  * freed and re-allocated. See an example of this method use
5653  * \ref MEDCouplingArraySteps1WC "here".
5654  *  \param [in] nbOfTuple - number of tuples of data to allocate.
5655  *  \param [in] nbOfCompo - number of components of data to allocate.
5656  *  \throw If \a nbOfTuple < 0 or \a nbOfCompo < 0.
5657  */
5658 void DataArrayInt::alloc(int nbOfTuple, int nbOfCompo) throw(INTERP_KERNEL::Exception)
5659 {
5660   if(nbOfTuple<0 || nbOfCompo<0)
5661     throw INTERP_KERNEL::Exception("DataArrayInt::alloc : request for negative length of data !");
5662   _info_on_compo.resize(nbOfCompo);
5663   _mem.alloc(nbOfCompo*(std::size_t)nbOfTuple);
5664   declareAsNew();
5665 }
5666
5667 /*!
5668  * Assign zero to all values in \a this array. To know more on filling arrays see
5669  * \ref MEDCouplingArrayFill.
5670  * \throw If \a this is not allocated.
5671  */
5672 void DataArrayInt::fillWithZero() throw(INTERP_KERNEL::Exception)
5673 {
5674   checkAllocated();
5675   _mem.fillWithValue(0);
5676   declareAsNew();
5677 }
5678
5679 /*!
5680  * Assign \a val to all values in \a this array. To know more on filling arrays see
5681  * \ref MEDCouplingArrayFill.
5682  *  \param [in] val - the value to fill with.
5683  *  \throw If \a this is not allocated.
5684  */
5685 void DataArrayInt::fillWithValue(int val) throw(INTERP_KERNEL::Exception)
5686 {
5687   checkAllocated();
5688   _mem.fillWithValue(val);
5689   declareAsNew();
5690 }
5691
5692 /*!
5693  * Set all values in \a this array so that the i-th element equals to \a init + i
5694  * (i starts from zero). To know more on filling arrays see \ref MEDCouplingArrayFill.
5695  *  \param [in] init - value to assign to the first element of array.
5696  *  \throw If \a this->getNumberOfComponents() != 1
5697  *  \throw If \a this is not allocated.
5698  */
5699 void DataArrayInt::iota(int init) throw(INTERP_KERNEL::Exception)
5700 {
5701   checkAllocated();
5702   if(getNumberOfComponents()!=1)
5703     throw INTERP_KERNEL::Exception("DataArrayInt::iota : works only for arrays with only one component, you can call 'rearrange' method before !");
5704   int *ptr=getPointer();
5705   int ntuples=getNumberOfTuples();
5706   for(int i=0;i<ntuples;i++)
5707     ptr[i]=init+i;
5708   declareAsNew();
5709 }
5710
5711 /*!
5712  * Returns a textual and human readable representation of \a this instance of
5713  * DataArrayInt. This text is shown when a DataArrayInt is printed in Python.
5714  *  \return std::string - text describing \a this DataArrayInt.
5715  */
5716 std::string DataArrayInt::repr() const throw(INTERP_KERNEL::Exception)
5717 {
5718   std::ostringstream ret;
5719   reprStream(ret);
5720   return ret.str();
5721 }
5722
5723 std::string DataArrayInt::reprZip() const throw(INTERP_KERNEL::Exception)
5724 {
5725   std::ostringstream ret;
5726   reprZipStream(ret);
5727   return ret.str();
5728 }
5729
5730 void DataArrayInt::writeVTK(std::ostream& ofs, int indent, const char *type, const char *nameInFile) const throw(INTERP_KERNEL::Exception)
5731 {
5732   checkAllocated();
5733   std::string idt(indent,' ');
5734   ofs << idt << "<DataArray type=\"" << type << "\" Name=\"" << nameInFile << "\" NumberOfComponents=\"" << getNumberOfComponents() << "\"";
5735   ofs << " format=\"ascii\" RangeMin=\"" << getMinValueInArray() << "\" RangeMax=\"" << getMaxValueInArray() << "\">\n" << idt;
5736   std::copy(begin(),end(),std::ostream_iterator<int>(ofs," "));
5737   ofs << std::endl << idt << "</DataArray>\n";
5738 }
5739
5740 void DataArrayInt::reprStream(std::ostream& stream) const throw(INTERP_KERNEL::Exception)
5741 {
5742   stream << "Name of int array : \"" << _name << "\"\n";
5743   reprWithoutNameStream(stream);
5744 }
5745
5746 void DataArrayInt::reprZipStream(std::ostream& stream) const throw(INTERP_KERNEL::Exception)
5747 {
5748   stream << "Name of int array : \"" << _name << "\"\n";
5749   reprZipWithoutNameStream(stream);
5750 }
5751
5752 void DataArrayInt::reprWithoutNameStream(std::ostream& stream) const throw(INTERP_KERNEL::Exception)
5753 {
5754   DataArray::reprWithoutNameStream(stream);
5755   _mem.repr(getNumberOfComponents(),stream);
5756 }
5757
5758 void DataArrayInt::reprZipWithoutNameStream(std::ostream& stream) const throw(INTERP_KERNEL::Exception)
5759 {
5760   DataArray::reprWithoutNameStream(stream);
5761   _mem.reprZip(getNumberOfComponents(),stream);
5762 }
5763
5764 void DataArrayInt::reprCppStream(const char *varName, std::ostream& stream) const throw(INTERP_KERNEL::Exception)
5765 {
5766   int nbTuples=getNumberOfTuples(),nbComp=getNumberOfComponents();
5767   const int *data=getConstPointer();
5768   stream << "DataArrayInt *" << varName << "=DataArrayInt::New();" << std::endl;
5769   if(nbTuples*nbComp>=1)
5770     {
5771       stream << "const int " << varName << "Data[" << nbTuples*nbComp << "]={";
5772       std::copy(data,data+nbTuples*nbComp-1,std::ostream_iterator<int>(stream,","));
5773       stream << data[nbTuples*nbComp-1] << "};" << std::endl;
5774       stream << varName << "->useArray(" << varName << "Data,false,CPP_DEALLOC," << nbTuples << "," << nbComp << ");" << std::endl;
5775     }
5776   else
5777     stream << varName << "->alloc(" << nbTuples << "," << nbComp << ");" << std::endl;
5778   stream << varName << "->setName(\"" << getName() << "\");" << std::endl;
5779 }
5780
5781 /*!
5782  * Method that gives a quick overvien of \a this for python.
5783  */
5784 void DataArrayInt::reprQuickOverview(std::ostream& stream) const throw(INTERP_KERNEL::Exception)
5785 {
5786   static const std::size_t MAX_NB_OF_BYTE_IN_REPR=300;
5787   stream << "DataArrayInt C++ instance at " << this << ". ";
5788   if(isAllocated())
5789     {
5790       int nbOfCompo=(int)_info_on_compo.size();
5791       if(nbOfCompo>=1)
5792         {
5793           int nbOfTuples=getNumberOfTuples();
5794           stream << "Number of tuples : " << nbOfTuples << ". Number of components : " << nbOfCompo << "." << std::endl;
5795           reprQuickOverviewData(stream,MAX_NB_OF_BYTE_IN_REPR);
5796         }
5797       else
5798         stream << "Number of components : 0.";
5799     }
5800   else
5801     stream << "*** No data allocated ****";
5802 }
5803
5804 void DataArrayInt::reprQuickOverviewData(std::ostream& stream, std::size_t maxNbOfByteInRepr) const throw(INTERP_KERNEL::Exception)
5805 {
5806   const int *data=begin();
5807   int nbOfTuples=getNumberOfTuples();
5808   int nbOfCompo=(int)_info_on_compo.size();
5809   std::ostringstream oss2; oss2 << "[";
5810   std::string oss2Str(oss2.str());
5811   bool isFinished=true;
5812   for(int i=0;i<nbOfTuples && isFinished;i++)
5813     {
5814       if(nbOfCompo>1)
5815         {
5816           oss2 << "(";
5817           for(int j=0;j<nbOfCompo;j++,data++)
5818             {
5819               oss2 << *data;
5820               if(j!=nbOfCompo-1) oss2 << ", ";
5821             }
5822           oss2 << ")";
5823         }
5824       else
5825         oss2 << *data++;
5826       if(i!=nbOfTuples-1) oss2 << ", ";
5827       std::string oss3Str(oss2.str());
5828       if(oss3Str.length()<maxNbOfByteInRepr)
5829         oss2Str=oss3Str;
5830       else
5831         isFinished=false;
5832     }
5833   stream << oss2Str;
5834   if(!isFinished)
5835     stream << "... ";
5836   stream << "]";
5837 }
5838
5839 /*!
5840  * Modifies \a this one-dimensional array so that each value \a v = \a indArrBg[ \a v ],
5841  * i.e. a current value is used as in index to get a new value from \a indArrBg.
5842  *  \param [in] indArrBg - pointer to the first element of array of new values to assign
5843  *         to \a this array.
5844  *  \param [in] indArrEnd - specifies the end of the array \a indArrBg, so that
5845  *              the last value of \a indArrBg is \a indArrEnd[ -1 ].
5846  *  \throw If \a this->getNumberOfComponents() != 1
5847  *  \throw If any value of \a this can't be used as a valid index for 
5848  *         [\a indArrBg, \a indArrEnd).
5849  */
5850 void DataArrayInt::transformWithIndArr(const int *indArrBg, const int *indArrEnd) throw(INTERP_KERNEL::Exception)
5851 {
5852   checkAllocated();
5853   if(getNumberOfComponents()!=1)
5854     throw INTERP_KERNEL::Exception("Call transformWithIndArr method on DataArrayInt with only one component, you can call 'rearrange' method before !");
5855   int nbElemsIn=(int)std::distance(indArrBg,indArrEnd);
5856   int nbOfTuples=getNumberOfTuples();
5857   int *pt=getPointer();
5858   for(int i=0;i<nbOfTuples;i++,pt++)
5859     {
5860       if(*pt>=0 && *pt<nbElemsIn)
5861         *pt=indArrBg[*pt];
5862       else
5863         {
5864           std::ostringstream oss; oss << "DataArrayInt::transformWithIndArr : error on tuple #" << i << " of this value is " << *pt << ", should be in [0," << nbElemsIn << ") !";
5865           throw INTERP_KERNEL::Exception(oss.str().c_str());
5866         }
5867     }
5868   declareAsNew();
5869 }
5870
5871 /*!
5872  * Computes distribution of values of \a this one-dimensional array between given value
5873  * ranges (casts). This method is typically useful for entity number spliting by types,
5874  * for example. 
5875  *  \warning The values contained in \a arrBg should be sorted ascendently. No
5876  *           check of this is be done. If not, the result is not warranted. 
5877  *  \param [in] arrBg - the array of ascending values defining the value ranges. The i-th
5878  *         value of \a arrBg (\a arrBg[ i ]) gives the lowest value of the i-th range,
5879  *         and the greatest value of the i-th range equals to \a arrBg[ i+1 ] - 1. \a
5880  *         arrBg containing \a n values defines \a n-1 ranges. The last value of \a arrBg
5881  *         should be more than every value in \a this array.
5882  *  \param [in] arrEnd - specifies the end of the array \a arrBg, so that
5883  *              the last value of \a arrBg is \a arrEnd[ -1 ].
5884  *  \param [out] castArr - a new instance of DataArrayInt, of same size as \a this array
5885  *         (same number of tuples and components), the caller is to delete 
5886  *         using decrRef() as it is no more needed.
5887  *         This array contains indices of ranges for every value of \a this array. I.e.
5888  *         the i-th value of \a castArr gives the index of range the i-th value of \a this
5889  *         belongs to. Or, in other words, this parameter contains for each tuple in \a
5890  *         this in which cast it holds.
5891  *  \param [out] rankInsideCast - a new instance of DataArrayInt, of same size as \a this
5892  *         array, the caller is to delete using decrRef() as it is no more needed.
5893  *         This array contains ranks of values of \a this array within ranges
5894  *         they belongs to. I.e. the i-th value of \a rankInsideCast gives the rank of
5895  *         the i-th value of \a this array within the \a castArr[ i ]-th range, to which
5896  *         the i-th value of \a this belongs to. Or, in other words, this param contains 
5897  *         for each tuple its rank inside its cast. The rank is computed as difference
5898  *         between the value and the lowest value of range.
5899  *  \param [out] castsPresent - a new instance of DataArrayInt, containing indices of
5900  *         ranges (casts) to which at least one value of \a this array belongs.
5901  *         Or, in other words, this param contains the casts that \a this contains.
5902  *         The caller is to delete this array using decrRef() as it is no more needed.
5903  *
5904  * \b Example: If \a this contains [6,5,0,3,2,7,8,1,4] and \a arrBg contains [0,4,9] then
5905  *            the output of this method will be : 
5906  * - \a castArr       : [1,1,0,0,0,1,1,0,1]
5907  * - \a rankInsideCast: [2,1,0,3,2,3,4,1,0]
5908  * - \a castsPresent  : [0,1]
5909  *
5910  * I.e. values of \a this array belong to 2 ranges: #0 and #1. Value 6 belongs to the
5911  * range #1 and its rank within this range is 2; etc.
5912  *
5913  *  \throw If \a this->getNumberOfComponents() != 1.
5914  *  \throw If \a arrEnd - arrBg < 2.
5915  *  \throw If any value of \a this is not less than \a arrEnd[-1].
5916  */
5917 void DataArrayInt::splitByValueRange(const int *arrBg, const int *arrEnd,
5918                                      DataArrayInt *& castArr, DataArrayInt *& rankInsideCast, DataArrayInt *& castsPresent) const throw(INTERP_KERNEL::Exception)
5919 {
5920   checkAllocated();
5921   if(getNumberOfComponents()!=1)
5922     throw INTERP_KERNEL::Exception("Call splitByValueRange  method on DataArrayInt with only one component, you can call 'rearrange' method before !");
5923   int nbOfTuples=getNumberOfTuples();
5924   std::size_t nbOfCast=std::distance(arrBg,arrEnd);
5925   if(nbOfCast<2)
5926     throw INTERP_KERNEL::Exception("DataArrayInt::splitByValueRange : The input array giving the cast range values should be of size >=2 !");
5927   nbOfCast--;
5928   const int *work=getConstPointer();
5929   typedef std::reverse_iterator<const int *> rintstart;
5930   rintstart bg(arrEnd);//OK no problem because size of 'arr' is greater or equal 2
5931   rintstart end2(arrBg);
5932   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret1=DataArrayInt::New();
5933   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret2=DataArrayInt::New();
5934   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret3=DataArrayInt::New();
5935   ret1->alloc(nbOfTuples,1);
5936   ret2->alloc(nbOfTuples,1);
5937   int *ret1Ptr=ret1->getPointer();
5938   int *ret2Ptr=ret2->getPointer();
5939   std::set<std::size_t> castsDetected;
5940   for(int i=0;i<nbOfTuples;i++)
5941     {
5942       rintstart res=std::find_if(bg,end2,std::bind2nd(std::less_equal<int>(), work[i]));
5943       std::size_t pos=std::distance(bg,res);
5944       std::size_t pos2=nbOfCast-pos;
5945       if(pos2<nbOfCast)
5946         {
5947           ret1Ptr[i]=(int)pos2;
5948           ret2Ptr[i]=work[i]-arrBg[pos2];
5949           castsDetected.insert(pos2);
5950         }
5951       else
5952         {
5953           std::ostringstream oss; oss << "DataArrayInt::splitByValueRange : At rank #" << i << " the value is " << work[i] << " should be in [0," << *bg << ") !";
5954           throw INTERP_KERNEL::Exception(oss.str().c_str());
5955         }
5956     }
5957   ret3->alloc((int)castsDetected.size(),1);
5958   std::copy(castsDetected.begin(),castsDetected.end(),ret3->getPointer());
5959   castArr=ret1.retn();
5960   rankInsideCast=ret2.retn();
5961   castsPresent=ret3.retn();
5962 }
5963
5964 /*!
5965  * Creates a one-dimensional DataArrayInt (\a res) whose contents are computed from 
5966  * values of \a this (\a a) and the given (\a indArr) arrays as follows:
5967  * \a res[ \a indArr[ \a a[ i ]]] = i. I.e. for each value in place i \a v = \a a[ i ],
5968  * new value in place \a indArr[ \a v ] is i.
5969  *  \param [in] indArrBg - the array holding indices within the result array to assign
5970  *         indices of values of \a this array pointing to values of \a indArrBg.
5971  *  \param [in] indArrEnd - specifies the end of the array \a indArrBg, so that
5972  *              the last value of \a indArrBg is \a indArrEnd[ -1 ].
5973  *  \return DataArrayInt * - the new instance of DataArrayInt.
5974  *          The caller is to delete this result array using decrRef() as it is no more
5975  *          needed.
5976  *  \throw If \a this->getNumberOfComponents() != 1.
5977  *  \throw If any value of \a this array is not a valid index for \a indArrBg array.
5978  *  \throw If any value of \a indArrBg is not a valid index for \a this array.
5979  */
5980 DataArrayInt *DataArrayInt::transformWithIndArrR(const int *indArrBg, const int *indArrEnd) const throw(INTERP_KERNEL::Exception)
5981 {
5982   checkAllocated();
5983   if(getNumberOfComponents()!=1)
5984     throw INTERP_KERNEL::Exception("Call transformWithIndArrR method on DataArrayInt with only one component, you can call 'rearrange' method before !");
5985   int nbElemsIn=(int)std::distance(indArrBg,indArrEnd);
5986   int nbOfTuples=getNumberOfTuples();
5987   const int *pt=getConstPointer();
5988   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
5989   ret->alloc(nbOfTuples,1);
5990   ret->fillWithValue(-1);
5991   int *tmp=ret->getPointer();
5992   for(int i=0;i<nbOfTuples;i++,pt++)
5993     {
5994       if(*pt>=0 && *pt<nbElemsIn)
5995         {
5996           int pos=indArrBg[*pt];
5997           if(pos>=0 && pos<nbOfTuples)
5998             tmp[pos]=i;
5999           else
6000             {
6001               std::ostringstream oss; oss << "DataArrayInt::transformWithIndArrR : error on tuple #" << i << " value of new pos is " << pos << " ( indArrBg[" << *pt << "]) ! Should be in [0," << nbOfTuples << ") !";
6002               throw INTERP_KERNEL::Exception(oss.str().c_str());
6003             }
6004         }
6005       else
6006         {
6007           std::ostringstream oss; oss << "DataArrayInt::transformWithIndArrR : error on tuple #" << i << " value is " << *pt << " and indirectionnal array as a size equal to " << nbElemsIn << " !";
6008           throw INTERP_KERNEL::Exception(oss.str().c_str());
6009         }
6010     }
6011   return ret.retn();
6012 }
6013
6014 /*!
6015  * Creates a one-dimensional DataArrayInt of given length, whose contents are computed
6016  * from values of \a this array, which is supposed to contain a renumbering map in 
6017  * "Old to New" mode. The result array contains a renumbering map in "New to Old" mode.
6018  * To know how to use the renumbering maps see \ref MEDCouplingArrayRenumbering.
6019  *  \param [in] newNbOfElem - the number of tuples in the result array.
6020  *  \return DataArrayInt * - the new instance of DataArrayInt.
6021  *          The caller is to delete this result array using decrRef() as it is no more
6022  *          needed.
6023  * 
6024  *  \ref cpp_mcdataarrayint_invertarrayo2n2n2o "Here is a C++ example".<br>
6025  *  \ref py_mcdataarrayint_invertarrayo2n2n2o  "Here is a Python example".
6026  */
6027 DataArrayInt *DataArrayInt::invertArrayO2N2N2O(int newNbOfElem) const
6028 {
6029   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6030   ret->alloc(newNbOfElem,1);
6031   int nbOfOldNodes=getNumberOfTuples();
6032   const int *old2New=getConstPointer();
6033   int *pt=ret->getPointer();
6034   for(int i=0;i!=nbOfOldNodes;i++)
6035     if(old2New[i]!=-1)
6036       pt[old2New[i]]=i;
6037   return ret.retn();
6038 }
6039
6040 /*!
6041  * This method is similar to DataArrayInt::invertArrayO2N2N2O except that 
6042  * 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]
6043  */
6044 DataArrayInt *DataArrayInt::invertArrayO2N2N2OBis(int newNbOfElem) const throw(INTERP_KERNEL::Exception)
6045 {
6046   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6047   ret->alloc(newNbOfElem,1);
6048   int nbOfOldNodes=getNumberOfTuples();
6049   const int *old2New=getConstPointer();
6050   int *pt=ret->getPointer();
6051   for(int i=nbOfOldNodes-1;i>=0;i--)
6052     if(old2New[i]!=-1)
6053       pt[old2New[i]]=i;
6054   return ret.retn();
6055 }
6056
6057 /*!
6058  * Creates a one-dimensional DataArrayInt of given length, whose contents are computed
6059  * from values of \a this array, which is supposed to contain a renumbering map in 
6060  * "New to Old" mode. The result array contains a renumbering map in "Old to New" mode.
6061  * To know how to use the renumbering maps see \ref MEDCouplingArrayRenumbering.
6062  *  \param [in] newNbOfElem - the number of tuples in the result array.
6063  *  \return DataArrayInt * - the new instance of DataArrayInt.
6064  *          The caller is to delete this result array using decrRef() as it is no more
6065  *          needed.
6066  * 
6067  *  \ref cpp_mcdataarrayint_invertarrayn2o2o2n "Here is a C++ example".
6068  *
6069  *  \ref py_mcdataarrayint_invertarrayn2o2o2n "Here is a Python example".
6070  */
6071 DataArrayInt *DataArrayInt::invertArrayN2O2O2N(int oldNbOfElem) const
6072 {
6073   checkAllocated();
6074   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6075   ret->alloc(oldNbOfElem,1);
6076   const int *new2Old=getConstPointer();
6077   int *pt=ret->getPointer();
6078   std::fill(pt,pt+oldNbOfElem,-1);
6079   int nbOfNewElems=getNumberOfTuples();
6080   for(int i=0;i<nbOfNewElems;i++)
6081     pt[new2Old[i]]=i;
6082   return ret.retn();
6083 }
6084
6085 /*!
6086  * Equivalent to DataArrayInt::isEqual except that if false the reason of
6087  * mismatch is given.
6088  * 
6089  * \param [in] other the instance to be compared with \a this
6090  * \param [out] reason In case of inequality returns the reason.
6091  * \sa DataArrayInt::isEqual
6092  */
6093 bool DataArrayInt::isEqualIfNotWhy(const DataArrayInt& other, std::string& reason) const throw(INTERP_KERNEL::Exception)
6094 {
6095   if(!areInfoEqualsIfNotWhy(other,reason))
6096     return false;
6097   return _mem.isEqual(other._mem,0,reason);
6098 }
6099
6100 /*!
6101  * Checks if \a this and another DataArrayInt are fully equal. For more info see
6102  * \ref MEDCouplingArrayBasicsCompare.
6103  *  \param [in] other - an instance of DataArrayInt to compare with \a this one.
6104  *  \return bool - \a true if the two arrays are equal, \a false else.
6105  */
6106 bool DataArrayInt::isEqual(const DataArrayInt& other) const throw(INTERP_KERNEL::Exception)
6107 {
6108   std::string tmp;
6109   return isEqualIfNotWhy(other,tmp);
6110 }
6111
6112 /*!
6113  * Checks if values of \a this and another DataArrayInt are equal. For more info see
6114  * \ref MEDCouplingArrayBasicsCompare.
6115  *  \param [in] other - an instance of DataArrayInt to compare with \a this one.
6116  *  \return bool - \a true if the values of two arrays are equal, \a false else.
6117  */
6118 bool DataArrayInt::isEqualWithoutConsideringStr(const DataArrayInt& other) const throw(INTERP_KERNEL::Exception)
6119 {
6120   std::string tmp;
6121   return _mem.isEqual(other._mem,0,tmp);
6122 }
6123
6124 /*!
6125  * Checks if values of \a this and another DataArrayInt are equal. Comparison is
6126  * performed on sorted value sequences.
6127  * For more info see\ref MEDCouplingArrayBasicsCompare.
6128  *  \param [in] other - an instance of DataArrayInt to compare with \a this one.
6129  *  \return bool - \a true if the sorted values of two arrays are equal, \a false else.
6130  */
6131 bool DataArrayInt::isEqualWithoutConsideringStrAndOrder(const DataArrayInt& other) const throw(INTERP_KERNEL::Exception)
6132 {
6133   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> a=deepCpy();
6134   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> b=other.deepCpy();
6135   a->sort();
6136   b->sort();
6137   return a->isEqualWithoutConsideringStr(*b);
6138 }
6139
6140 /*!
6141  * Sorts values of the array.
6142  *  \param [in] asc - \a true means ascending order, \a false, descending.
6143  *  \throw If \a this is not allocated.
6144  *  \throw If \a this->getNumberOfComponents() != 1.
6145  */
6146 void DataArrayInt::sort(bool asc) throw(INTERP_KERNEL::Exception)
6147 {
6148   checkAllocated();
6149   if(getNumberOfComponents()!=1)
6150     throw INTERP_KERNEL::Exception("DataArrayInt::sort : only supported with 'this' array with ONE component !");
6151   _mem.sort(asc);
6152   declareAsNew();
6153 }
6154
6155 /*!
6156  * Reverse the array values.
6157  *  \throw If \a this->getNumberOfComponents() < 1.
6158  *  \throw If \a this is not allocated.
6159  */
6160 void DataArrayInt::reverse() throw(INTERP_KERNEL::Exception)
6161 {
6162   checkAllocated();
6163   _mem.reverse(getNumberOfComponents());
6164   declareAsNew();
6165 }
6166
6167 /*!
6168  * Checks that \a this array is consistently **increasing** or **decreasing** in value.
6169  * If not an exception is thrown.
6170  *  \param [in] increasing - if \a true, the array values should be increasing.
6171  *  \throw If sequence of values is not strictly monotonic in agreement with \a
6172  *         increasing arg.
6173  *  \throw If \a this->getNumberOfComponents() != 1.
6174  *  \throw If \a this is not allocated.
6175  */
6176 void DataArrayInt::checkMonotonic(bool increasing) const throw(INTERP_KERNEL::Exception)
6177 {
6178   if(!isMonotonic(increasing))
6179     {
6180       if (increasing)
6181         throw INTERP_KERNEL::Exception("DataArrayInt::checkMonotonic : 'this' is not INCREASING monotonic !");
6182       else
6183         throw INTERP_KERNEL::Exception("DataArrayInt::checkMonotonic : 'this' is not DECREASING monotonic !");
6184     }
6185 }
6186
6187 /*!
6188  * Checks that \a this array is consistently **increasing** or **decreasing** in value.
6189  *  \param [in] increasing - if \a true, array values should be increasing.
6190  *  \return bool - \a true if values change in accordance with \a increasing arg.
6191  *  \throw If \a this->getNumberOfComponents() != 1.
6192  *  \throw If \a this is not allocated.
6193  */
6194 bool DataArrayInt::isMonotonic(bool increasing) const throw(INTERP_KERNEL::Exception)
6195 {
6196   checkAllocated();
6197   if(getNumberOfComponents()!=1)
6198     throw INTERP_KERNEL::Exception("DataArrayInt::isMonotonic : only supported with 'this' array with ONE component !");
6199   int nbOfElements=getNumberOfTuples();
6200   const int *ptr=getConstPointer();
6201   if(nbOfElements==0)
6202     return true;
6203   int ref=ptr[0];
6204   if(increasing)
6205     {
6206       for(int i=1;i<nbOfElements;i++)
6207         {
6208           if(ptr[i]>=ref)
6209             ref=ptr[i];
6210           else
6211             return false;
6212         }
6213     }
6214   else
6215     {
6216       for(int i=1;i<nbOfElements;i++)
6217         {
6218           if(ptr[i]<=ref)
6219             ref=ptr[i];
6220           else
6221             return false;
6222         }
6223     }
6224   return true;
6225 }
6226
6227 /*!
6228  * This method check that array consistently INCREASING or DECREASING in value.
6229  */
6230 bool DataArrayInt::isStrictlyMonotonic(bool increasing) const throw(INTERP_KERNEL::Exception)
6231 {
6232   checkAllocated();
6233   if(getNumberOfComponents()!=1)
6234     throw INTERP_KERNEL::Exception("DataArrayInt::isStrictlyMonotonic : only supported with 'this' array with ONE component !");
6235   int nbOfElements=getNumberOfTuples();
6236   const int *ptr=getConstPointer();
6237   if(nbOfElements==0)
6238     return true;
6239   int ref=ptr[0];
6240   if(increasing)
6241     {
6242       for(int i=1;i<nbOfElements;i++)
6243         {
6244           if(ptr[i]>ref)
6245             ref=ptr[i];
6246           else
6247             return false;
6248         }
6249     }
6250   else
6251     {
6252       for(int i=1;i<nbOfElements;i++)
6253         {
6254           if(ptr[i]<ref)
6255             ref=ptr[i];
6256           else
6257             return false;
6258         }
6259     }
6260   return true;
6261 }
6262
6263 /*!
6264  * This method check that array consistently INCREASING or DECREASING in value.
6265  */
6266 void DataArrayInt::checkStrictlyMonotonic(bool increasing) const throw(INTERP_KERNEL::Exception)
6267 {
6268   if(!isStrictlyMonotonic(increasing))
6269     {
6270       if (increasing)
6271         throw INTERP_KERNEL::Exception("DataArrayInt::checkStrictlyMonotonic : 'this' is not strictly INCREASING monotonic !");
6272       else
6273         throw INTERP_KERNEL::Exception("DataArrayInt::checkStrictlyMonotonic : 'this' is not strictly DECREASING monotonic !");
6274     }
6275 }
6276
6277 /*!
6278  * Creates a new one-dimensional DataArrayInt of the same size as \a this and a given
6279  * one-dimensional arrays that must be of the same length. The result array describes
6280  * correspondence between \a this and \a other arrays, so that 
6281  * <em> other.getIJ(i,0) == this->getIJ(ret->getIJ(i),0)</em>. If such a permutation is
6282  * not possible because some element in \a other is not in \a this, an exception is thrown.
6283  *  \param [in] other - an array to compute permutation to.
6284  *  \return DataArrayInt * - a new instance of DataArrayInt, which is a permutation array
6285  * from \a this to \a other. The caller is to delete this array using decrRef() as it is
6286  * no more needed.
6287  *  \throw If \a this->getNumberOfComponents() != 1.
6288  *  \throw If \a other->getNumberOfComponents() != 1.
6289  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples().
6290  *  \throw If \a other includes a value which is not in \a this array.
6291  * 
6292  *  \ref cpp_mcdataarrayint_buildpermutationarr "Here is a C++ example".
6293  *
6294  *  \ref py_mcdataarrayint_buildpermutationarr "Here is a Python example".
6295  */
6296 DataArrayInt *DataArrayInt::buildPermutationArr(const DataArrayInt& other) const throw(INTERP_KERNEL::Exception)
6297 {
6298   checkAllocated();
6299   if(getNumberOfComponents()!=1 || other.getNumberOfComponents()!=1)
6300     throw INTERP_KERNEL::Exception("DataArrayInt::buildPermutationArr : 'this' and 'other' have to have exactly ONE component !");
6301   int nbTuple=getNumberOfTuples();
6302   other.checkAllocated();
6303   if(nbTuple!=other.getNumberOfTuples())
6304     throw INTERP_KERNEL::Exception("DataArrayInt::buildPermutationArr : 'this' and 'other' must have the same number of tuple !");
6305   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6306   ret->alloc(nbTuple,1);
6307   ret->fillWithValue(-1);
6308   const int *pt=getConstPointer();
6309   std::map<int,int> mm;
6310   for(int i=0;i<nbTuple;i++)
6311     mm[pt[i]]=i;
6312   pt=other.getConstPointer();
6313   int *retToFill=ret->getPointer();
6314   for(int i=0;i<nbTuple;i++)
6315     {
6316       std::map<int,int>::const_iterator it=mm.find(pt[i]);
6317       if(it==mm.end())
6318         {
6319           std::ostringstream oss; oss << "DataArrayInt::buildPermutationArr : Arrays mismatch : element (" << pt[i] << ") in 'other' not findable in 'this' !";
6320           throw INTERP_KERNEL::Exception(oss.str().c_str());
6321         }
6322       retToFill[i]=(*it).second;
6323     }
6324   return ret.retn();
6325 }
6326
6327 /*!
6328  * Sets a C array to be used as raw data of \a this. The previously set info
6329  *  of components is retained and re-sized. 
6330  * For more info see \ref MEDCouplingArraySteps1.
6331  *  \param [in] array - the C array to be used as raw data of \a this.
6332  *  \param [in] ownership - if \a true, \a array will be deallocated at destruction of \a this.
6333  *  \param [in] type - specifies how to deallocate \a array. If \a type == ParaMEDMEM::CPP_DEALLOC,
6334  *                     \c delete [] \c array; will be called. If \a type == ParaMEDMEM::C_DEALLOC,
6335  *                     \c free(\c array ) will be called.
6336  *  \param [in] nbOfTuple - new number of tuples in \a this.
6337  *  \param [in] nbOfCompo - new number of components in \a this.
6338  */
6339 void DataArrayInt::useArray(const int *array, bool ownership,  DeallocType type, int nbOfTuple, int nbOfCompo) throw(INTERP_KERNEL::Exception)
6340 {
6341   _info_on_compo.resize(nbOfCompo);
6342   _mem.useArray(array,ownership,type,nbOfTuple*nbOfCompo);
6343   declareAsNew();
6344 }
6345
6346 void DataArrayInt::useExternalArrayWithRWAccess(const int *array, int nbOfTuple, int nbOfCompo) throw(INTERP_KERNEL::Exception)
6347 {
6348   _info_on_compo.resize(nbOfCompo);
6349   _mem.useExternalArrayWithRWAccess(array,nbOfTuple*nbOfCompo);
6350   declareAsNew();
6351 }
6352
6353 /*!
6354  * Returns a new DataArrayInt holding the same values as \a this array but differently
6355  * arranged in memory. If \a this array holds 2 components of 3 values:
6356  * \f$ x_0,x_1,x_2,y_0,y_1,y_2 \f$, then the result array holds these values arranged
6357  * as follows: \f$ x_0,y_0,x_1,y_1,x_2,y_2 \f$.
6358  *  \warning Do not confuse this method with transpose()!
6359  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
6360  *          is to delete using decrRef() as it is no more needed.
6361  *  \throw If \a this is not allocated.
6362  */
6363 DataArrayInt *DataArrayInt::fromNoInterlace() const throw(INTERP_KERNEL::Exception)
6364 {
6365   checkAllocated();
6366   if(_mem.isNull())
6367     throw INTERP_KERNEL::Exception("DataArrayInt::fromNoInterlace : Not defined array !");
6368   int *tab=_mem.fromNoInterlace(getNumberOfComponents());
6369   DataArrayInt *ret=DataArrayInt::New();
6370   ret->useArray(tab,true,C_DEALLOC,getNumberOfTuples(),getNumberOfComponents());
6371   return ret;
6372 }
6373
6374 /*!
6375  * Returns a new DataArrayInt holding the same values as \a this array but differently
6376  * arranged in memory. If \a this array holds 2 components of 3 values:
6377  * \f$ x_0,y_0,x_1,y_1,x_2,y_2 \f$, then the result array holds these values arranged
6378  * as follows: \f$ x_0,x_1,x_2,y_0,y_1,y_2 \f$.
6379  *  \warning Do not confuse this method with transpose()!
6380  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
6381  *          is to delete using decrRef() as it is no more needed.
6382  *  \throw If \a this is not allocated.
6383  */
6384 DataArrayInt *DataArrayInt::toNoInterlace() const throw(INTERP_KERNEL::Exception)
6385 {
6386   checkAllocated();
6387   if(_mem.isNull())
6388     throw INTERP_KERNEL::Exception("DataArrayInt::toNoInterlace : Not defined array !");
6389   int *tab=_mem.toNoInterlace(getNumberOfComponents());
6390   DataArrayInt *ret=DataArrayInt::New();
6391   ret->useArray(tab,true,C_DEALLOC,getNumberOfTuples(),getNumberOfComponents());
6392   return ret;
6393 }
6394
6395 /*!
6396  * Permutes values of \a this array as required by \a old2New array. The values are
6397  * permuted so that \c new[ \a old2New[ i ]] = \c old[ i ]. Number of tuples remains
6398  * the same as in \this one.
6399  * If a permutation reduction is needed, substr() or selectByTupleId() should be used.
6400  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
6401  *  \param [in] old2New - C array of length equal to \a this->getNumberOfTuples()
6402  *     giving a new position for i-th old value.
6403  */
6404 void DataArrayInt::renumberInPlace(const int *old2New) throw(INTERP_KERNEL::Exception)
6405 {
6406   checkAllocated();
6407   int nbTuples=getNumberOfTuples();
6408   int nbOfCompo=getNumberOfComponents();
6409   int *tmp=new int[nbTuples*nbOfCompo];
6410   const int *iptr=getConstPointer();
6411   for(int i=0;i<nbTuples;i++)
6412     {
6413       int v=old2New[i];
6414       if(v>=0 && v<nbTuples)
6415         std::copy(iptr+nbOfCompo*i,iptr+nbOfCompo*(i+1),tmp+nbOfCompo*v);
6416       else
6417         {
6418           std::ostringstream oss; oss << "DataArrayInt::renumberInPlace : At place #" << i << " value is " << v << " ! Should be in [0," << nbTuples << ") !";
6419           throw INTERP_KERNEL::Exception(oss.str().c_str());
6420         }
6421     }
6422   std::copy(tmp,tmp+nbTuples*nbOfCompo,getPointer());
6423   delete [] tmp;
6424   declareAsNew();
6425 }
6426
6427 /*!
6428  * Permutes values of \a this array as required by \a new2Old array. The values are
6429  * permuted so that \c new[ i ] = \c old[ \a new2Old[ i ]]. Number of tuples remains
6430  * the same as in \this one.
6431  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
6432  *  \param [in] new2Old - C array of length equal to \a this->getNumberOfTuples()
6433  *     giving a previous position of i-th new value.
6434  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
6435  *          is to delete using decrRef() as it is no more needed.
6436  */
6437 void DataArrayInt::renumberInPlaceR(const int *new2Old) throw(INTERP_KERNEL::Exception)
6438 {
6439   checkAllocated();
6440   int nbTuples=getNumberOfTuples();
6441   int nbOfCompo=getNumberOfComponents();
6442   int *tmp=new int[nbTuples*nbOfCompo];
6443   const int *iptr=getConstPointer();
6444   for(int i=0;i<nbTuples;i++)
6445     {
6446       int v=new2Old[i];
6447       if(v>=0 && v<nbTuples)
6448         std::copy(iptr+nbOfCompo*v,iptr+nbOfCompo*(v+1),tmp+nbOfCompo*i);
6449       else
6450         {
6451           std::ostringstream oss; oss << "DataArrayInt::renumberInPlaceR : At place #" << i << " value is " << v << " ! Should be in [0," << nbTuples << ") !";
6452           throw INTERP_KERNEL::Exception(oss.str().c_str());
6453         }
6454     }
6455   std::copy(tmp,tmp+nbTuples*nbOfCompo,getPointer());
6456   delete [] tmp;
6457   declareAsNew();
6458 }
6459
6460 /*!
6461  * Returns a copy of \a this array with values permuted as required by \a old2New array.
6462  * The values are permuted so that  \c new[ \a old2New[ i ]] = \c old[ i ].
6463  * Number of tuples in the result array remains the same as in \this one.
6464  * If a permutation reduction is needed, renumberAndReduce() should be used.
6465  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
6466  *  \param [in] old2New - C array of length equal to \a this->getNumberOfTuples()
6467  *          giving a new position for i-th old value.
6468  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
6469  *          is to delete using decrRef() as it is no more needed.
6470  *  \throw If \a this is not allocated.
6471  */
6472 DataArrayInt *DataArrayInt::renumber(const int *old2New) const throw(INTERP_KERNEL::Exception)
6473 {
6474   checkAllocated();
6475   int nbTuples=getNumberOfTuples();
6476   int nbOfCompo=getNumberOfComponents();
6477   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6478   ret->alloc(nbTuples,nbOfCompo);
6479   ret->copyStringInfoFrom(*this);
6480   const int *iptr=getConstPointer();
6481   int *optr=ret->getPointer();
6482   for(int i=0;i<nbTuples;i++)
6483     std::copy(iptr+nbOfCompo*i,iptr+nbOfCompo*(i+1),optr+nbOfCompo*old2New[i]);
6484   ret->copyStringInfoFrom(*this);
6485   return ret.retn();
6486 }
6487
6488 /*!
6489  * Returns a copy of \a this array with values permuted as required by \a new2Old array.
6490  * The values are permuted so that  \c new[ i ] = \c old[ \a new2Old[ i ]]. Number of
6491  * tuples in the result array remains the same as in \this one.
6492  * If a permutation reduction is needed, substr() or selectByTupleId() should be used.
6493  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
6494  *  \param [in] new2Old - C array of length equal to \a this->getNumberOfTuples()
6495  *     giving a previous position of i-th new value.
6496  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
6497  *          is to delete using decrRef() as it is no more needed.
6498  */
6499 DataArrayInt *DataArrayInt::renumberR(const int *new2Old) const throw(INTERP_KERNEL::Exception)
6500 {
6501   checkAllocated();
6502   int nbTuples=getNumberOfTuples();
6503   int nbOfCompo=getNumberOfComponents();
6504   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6505   ret->alloc(nbTuples,nbOfCompo);
6506   ret->copyStringInfoFrom(*this);
6507   const int *iptr=getConstPointer();
6508   int *optr=ret->getPointer();
6509   for(int i=0;i<nbTuples;i++)
6510     std::copy(iptr+nbOfCompo*new2Old[i],iptr+nbOfCompo*(new2Old[i]+1),optr+nbOfCompo*i);
6511   ret->copyStringInfoFrom(*this);
6512   return ret.retn();
6513 }
6514
6515 /*!
6516  * Returns a shorten and permuted copy of \a this array. The new DataArrayInt is
6517  * of size \a newNbOfTuple and it's values are permuted as required by \a old2New array.
6518  * The values are permuted so that  \c new[ \a old2New[ i ]] = \c old[ i ] for all
6519  * \a old2New[ i ] >= 0. In other words every i-th tuple in \a this array, for which 
6520  * \a old2New[ i ] is negative, is missing from the result array.
6521  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
6522  *  \param [in] old2New - C array of length equal to \a this->getNumberOfTuples()
6523  *     giving a new position for i-th old tuple and giving negative position for
6524  *     for i-th old tuple that should be omitted.
6525  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
6526  *          is to delete using decrRef() as it is no more needed.
6527  */
6528 DataArrayInt *DataArrayInt::renumberAndReduce(const int *old2New, int newNbOfTuple) const throw(INTERP_KERNEL::Exception)
6529 {
6530   checkAllocated();
6531   int nbTuples=getNumberOfTuples();
6532   int nbOfCompo=getNumberOfComponents();
6533   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6534   ret->alloc(newNbOfTuple,nbOfCompo);
6535   const int *iptr=getConstPointer();
6536   int *optr=ret->getPointer();
6537   for(int i=0;i<nbTuples;i++)
6538     {
6539       int w=old2New[i];
6540       if(w>=0)
6541         std::copy(iptr+i*nbOfCompo,iptr+(i+1)*nbOfCompo,optr+w*nbOfCompo);
6542     }
6543   ret->copyStringInfoFrom(*this);
6544   return ret.retn();
6545 }
6546
6547 /*!
6548  * Returns a shorten and permuted copy of \a this array. The new DataArrayInt is
6549  * of size \a new2OldEnd - \a new2OldBg and it's values are permuted as required by
6550  * \a new2OldBg array.
6551  * The values are permuted so that  \c new[ i ] = \c old[ \a new2OldBg[ i ]].
6552  * This method is equivalent to renumberAndReduce() except that convention in input is
6553  * \c new2old and \b not \c old2new.
6554  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
6555  *  \param [in] new2OldBg - pointer to the beginning of a permutation array that gives a
6556  *              tuple index in \a this array to fill the i-th tuple in the new array.
6557  *  \param [in] new2OldEnd - specifies the end of the permutation array that starts at
6558  *              \a new2OldBg, so that pointer to a tuple index (\a pi) varies as this:
6559  *              \a new2OldBg <= \a pi < \a new2OldEnd.
6560  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
6561  *          is to delete using decrRef() as it is no more needed.
6562  */
6563 DataArrayInt *DataArrayInt::selectByTupleId(const int *new2OldBg, const int *new2OldEnd) const
6564 {
6565   checkAllocated();
6566   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6567   int nbComp=getNumberOfComponents();
6568   ret->alloc((int)std::distance(new2OldBg,new2OldEnd),nbComp);
6569   ret->copyStringInfoFrom(*this);
6570   int *pt=ret->getPointer();
6571   const int *srcPt=getConstPointer();
6572   int i=0;
6573   for(const int *w=new2OldBg;w!=new2OldEnd;w++,i++)
6574     std::copy(srcPt+(*w)*nbComp,srcPt+((*w)+1)*nbComp,pt+i*nbComp);
6575   ret->copyStringInfoFrom(*this);
6576   return ret.retn();
6577 }
6578
6579 /*!
6580  * Returns a shorten and permuted copy of \a this array. The new DataArrayInt is
6581  * of size \a new2OldEnd - \a new2OldBg and it's values are permuted as required by
6582  * \a new2OldBg array.
6583  * The values are permuted so that  \c new[ i ] = \c old[ \a new2OldBg[ i ]].
6584  * This method is equivalent to renumberAndReduce() except that convention in input is
6585  * \c new2old and \b not \c old2new.
6586  * This method is equivalent to selectByTupleId() except that it prevents coping data
6587  * from behind the end of \a this array.
6588  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
6589  *  \param [in] new2OldBg - pointer to the beginning of a permutation array that gives a
6590  *              tuple index in \a this array to fill the i-th tuple in the new array.
6591  *  \param [in] new2OldEnd - specifies the end of the permutation array that starts at
6592  *              \a new2OldBg, so that pointer to a tuple index (\a pi) varies as this:
6593  *              \a new2OldBg <= \a pi < \a new2OldEnd.
6594  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
6595  *          is to delete using decrRef() as it is no more needed.
6596  *  \throw If \a new2OldEnd - \a new2OldBg > \a this->getNumberOfTuples().
6597  */
6598 DataArrayInt *DataArrayInt::selectByTupleIdSafe(const int *new2OldBg, const int *new2OldEnd) const throw(INTERP_KERNEL::Exception)
6599 {
6600   checkAllocated();
6601   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6602   int nbComp=getNumberOfComponents();
6603   int oldNbOfTuples=getNumberOfTuples();
6604   ret->alloc((int)std::distance(new2OldBg,new2OldEnd),nbComp);
6605   ret->copyStringInfoFrom(*this);
6606   int *pt=ret->getPointer();
6607   const int *srcPt=getConstPointer();
6608   int i=0;
6609   for(const int *w=new2OldBg;w!=new2OldEnd;w++,i++)
6610     if(*w>=0 && *w<oldNbOfTuples)
6611       std::copy(srcPt+(*w)*nbComp,srcPt+((*w)+1)*nbComp,pt+i*nbComp);
6612     else
6613       throw INTERP_KERNEL::Exception("DataArrayInt::selectByTupleIdSafe : some ids has been detected to be out of [0,this->getNumberOfTuples) !");
6614   ret->copyStringInfoFrom(*this);
6615   return ret.retn();
6616 }
6617
6618 /*!
6619  * Returns a shorten copy of \a this array. The new DataArrayInt contains every
6620  * (\a bg + \c i * \a step)-th tuple of \a this array located before the \a end2-th
6621  * tuple. Indices of the selected tuples are the same as ones returned by the Python
6622  * command \c range( \a bg, \a end2, \a step ).
6623  * This method is equivalent to selectByTupleIdSafe() except that the input array is
6624  * not constructed explicitly.
6625  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
6626  *  \param [in] bg - index of the first tuple to copy from \a this array.
6627  *  \param [in] end2 - index of the tuple before which the tuples to copy are located.
6628  *  \param [in] step - index increment to get index of the next tuple to copy.
6629  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
6630  *          is to delete using decrRef() as it is no more needed.
6631  *  \sa DataArrayInt::substr.
6632  */
6633 DataArrayInt *DataArrayInt::selectByTupleId2(int bg, int end2, int step) const throw(INTERP_KERNEL::Exception)
6634 {
6635   checkAllocated();
6636   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6637   int nbComp=getNumberOfComponents();
6638   int newNbOfTuples=GetNumberOfItemGivenBESRelative(bg,end2,step,"DataArrayInt::selectByTupleId2 : ");
6639   ret->alloc(newNbOfTuples,nbComp);
6640   int *pt=ret->getPointer();
6641   const int *srcPt=getConstPointer()+bg*nbComp;
6642   for(int i=0;i<newNbOfTuples;i++,srcPt+=step*nbComp)
6643     std::copy(srcPt,srcPt+nbComp,pt+i*nbComp);
6644   ret->copyStringInfoFrom(*this);
6645   return ret.retn();
6646 }
6647
6648 /*!
6649  * Returns a shorten copy of \a this array. The new DataArrayInt contains ranges
6650  * of tuples specified by \a ranges parameter.
6651  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
6652  *  \param [in] ranges - std::vector of std::pair's each of which defines a range
6653  *              of tuples in [\c begin,\c end) format.
6654  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
6655  *          is to delete using decrRef() as it is no more needed.
6656  *  \throw If \a end < \a begin.
6657  *  \throw If \a end > \a this->getNumberOfTuples().
6658  *  \throw If \a this is not allocated.
6659  */
6660 DataArray *DataArrayInt::selectByTupleRanges(const std::vector<std::pair<int,int> >& ranges) const throw(INTERP_KERNEL::Exception)
6661 {
6662   checkAllocated();
6663   int nbOfComp=getNumberOfComponents();
6664   int nbOfTuplesThis=getNumberOfTuples();
6665   if(ranges.empty())
6666     {
6667       MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6668       ret->alloc(0,nbOfComp);
6669       ret->copyStringInfoFrom(*this);
6670       return ret.retn();
6671     }
6672   int ref=ranges.front().first;
6673   int nbOfTuples=0;
6674   bool isIncreasing=true;
6675   for(std::vector<std::pair<int,int> >::const_iterator it=ranges.begin();it!=ranges.end();it++)
6676     {
6677       if((*it).first<=(*it).second)
6678         {
6679           if((*it).first>=0 && (*it).second<=nbOfTuplesThis)
6680             {
6681               nbOfTuples+=(*it).second-(*it).first;
6682               if(isIncreasing)
6683                 isIncreasing=ref<=(*it).first;
6684               ref=(*it).second;
6685             }
6686           else
6687             {
6688               std::ostringstream oss; oss << "DataArrayInt::selectByTupleRanges : on range #" << std::distance(ranges.begin(),it);
6689               oss << " (" << (*it).first << "," << (*it).second << ") is greater than number of tuples of this :" << nbOfTuples << " !";
6690               throw INTERP_KERNEL::Exception(oss.str().c_str());
6691             }
6692         }
6693       else
6694         {
6695           std::ostringstream oss; oss << "DataArrayInt::selectByTupleRanges : on range #" << std::distance(ranges.begin(),it);
6696           oss << " (" << (*it).first << "," << (*it).second << ") end is before begin !";
6697           throw INTERP_KERNEL::Exception(oss.str().c_str());
6698         }
6699     }
6700   if(isIncreasing && nbOfTuplesThis==nbOfTuples)
6701     return deepCpy();
6702   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6703   ret->alloc(nbOfTuples,nbOfComp);
6704   ret->copyStringInfoFrom(*this);
6705   const int *src=getConstPointer();
6706   int *work=ret->getPointer();
6707   for(std::vector<std::pair<int,int> >::const_iterator it=ranges.begin();it!=ranges.end();it++)
6708     work=std::copy(src+(*it).first*nbOfComp,src+(*it).second*nbOfComp,work);
6709   return ret.retn();
6710 }
6711
6712 /*!
6713  * Returns a new DataArrayInt containing a renumbering map in "Old to New" mode.
6714  * This map, if applied to \a this array, would make it sorted. For example, if
6715  * \a this array contents are [9,10,0,6,4,11,3,7] then the contents of the result array
6716  * are [5,6,0,3,2,7,1,4]; if this result array (\a res) is used as an argument in call
6717  * \a this->renumber(\a res) then the returned array contains [0,3,4,6,7,9,10,11].
6718  * This method is useful for renumbering (in MED file for example). For more info
6719  * on renumbering see \ref MEDCouplingArrayRenumbering.
6720  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
6721  *          array using decrRef() as it is no more needed.
6722  *  \throw If \a this is not allocated.
6723  *  \throw If \a this->getNumberOfComponents() != 1.
6724  *  \throw If there are equal values in \a this array.
6725  */
6726 DataArrayInt *DataArrayInt::checkAndPreparePermutation() const throw(INTERP_KERNEL::Exception)
6727 {
6728   checkAllocated();
6729   if(getNumberOfComponents()!=1)
6730     throw INTERP_KERNEL::Exception("DataArrayInt::checkAndPreparePermutation : number of components must == 1 !");
6731   int nbTuples=getNumberOfTuples();
6732   const int *pt=getConstPointer();
6733   int *pt2=CheckAndPreparePermutation(pt,pt+nbTuples);
6734   DataArrayInt *ret=DataArrayInt::New();
6735   ret->useArray(pt2,true,C_DEALLOC,nbTuples,1);
6736   return ret;
6737 }
6738
6739 /*!
6740  * Returns two arrays describing a surjective mapping from \a this set of values (\a A)
6741  * onto a set of values of size \a targetNb (\a B). The surjective function is 
6742  * \a B[ \a A[ i ]] = i. That is to say that for each \a id in [0,\a targetNb), where \a
6743  * targetNb < \a this->getNumberOfTuples(), there exists at least one tupleId (\a tid) so
6744  * that <em> this->getIJ( tid, 0 ) == id</em>. <br>
6745  * The first of out arrays returns indices of elements of \a this array, grouped by their
6746  * place in the set \a B. The second out array is the index of the first one; it shows how
6747  * many elements of \a A are mapped into each element of \a B. <br>
6748  * For more info on
6749  * mapping and its usage in renumbering see \ref MEDCouplingArrayRenumbering. <br>
6750  * \b Example:
6751  * - \a this: [0,3,2,3,2,2,1,2]
6752  * - \a targetNb: 4
6753  * - \a arr:  [0,  6,  2,4,5,7,  1,3]
6754  * - \a arrI: [0,1,2,6,8]
6755  *
6756  * This result means: <br>
6757  * the element of \a B 0 encounters within \a A once (\a arrI[ 0+1 ] - \a arrI[ 0 ]) and
6758  * its index within \a A is 0 ( \a arr[ 0:1 ] == \a arr[ \a arrI[ 0 ] : \a arrI[ 0+1 ]]);<br>
6759  * the element of \a B 2 encounters within \a A 4 times (\a arrI[ 2+1 ] - \a arrI[ 2 ]) and
6760  * its indices within \a A are [2,4,5,7] ( \a arr[ 2:6 ] == \a arr[ \a arrI[ 2 ] : 
6761  * \a arrI[ 2+1 ]]); <br> etc.
6762  *  \param [in] targetNb - the size of the set \a B. \a targetNb must be equal or more
6763  *         than the maximal value of \a A.
6764  *  \param [out] arr - a new instance of DataArrayInt returning indices of
6765  *         elements of \a this, grouped by their place in the set \a B. The caller is to delete
6766  *         this array using decrRef() as it is no more needed.
6767  *  \param [out] arrI - a new instance of DataArrayInt returning size of groups of equal
6768  *         elements of \a this. The caller is to delete this array using decrRef() as it
6769  *         is no more needed.
6770  *  \throw If \a this is not allocated.
6771  *  \throw If \a this->getNumberOfComponents() != 1.
6772  *  \throw If any value in \a this is more or equal to \a targetNb.
6773  */
6774 void DataArrayInt::changeSurjectiveFormat(int targetNb, DataArrayInt *&arr, DataArrayInt *&arrI) const throw(INTERP_KERNEL::Exception)
6775 {
6776   checkAllocated();
6777   if(getNumberOfComponents()!=1)
6778     throw INTERP_KERNEL::Exception("DataArrayInt::changeSurjectiveFormat : number of components must == 1 !");
6779   int nbOfTuples=getNumberOfTuples();
6780   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New());
6781   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> retI(DataArrayInt::New());
6782   retI->alloc(targetNb+1,1);
6783   const int *input=getConstPointer();
6784   std::vector< std::vector<int> > tmp(targetNb);
6785   for(int i=0;i<nbOfTuples;i++)
6786     {
6787       int tmp2=input[i];
6788       if(tmp2>=0 && tmp2<targetNb)
6789         tmp[tmp2].push_back(i);
6790       else
6791         {
6792           std::ostringstream oss; oss << "DataArrayInt::changeSurjectiveFormat : At pos " << i << " presence of element " << tmp2 << " ! should be in [0," << targetNb << ") !";
6793           throw INTERP_KERNEL::Exception(oss.str().c_str());
6794         }
6795     }
6796   int *retIPtr=retI->getPointer();
6797   *retIPtr=0;
6798   for(std::vector< std::vector<int> >::const_iterator it1=tmp.begin();it1!=tmp.end();it1++,retIPtr++)
6799     retIPtr[1]=retIPtr[0]+(int)((*it1).size());
6800   if(nbOfTuples!=retI->getIJ(targetNb,0))
6801     throw INTERP_KERNEL::Exception("DataArrayInt::changeSurjectiveFormat : big problem should never happen !");
6802   ret->alloc(nbOfTuples,1);
6803   int *retPtr=ret->getPointer();
6804   for(std::vector< std::vector<int> >::const_iterator it1=tmp.begin();it1!=tmp.end();it1++)
6805     retPtr=std::copy((*it1).begin(),(*it1).end(),retPtr);
6806   arr=ret.retn();
6807   arrI=retI.retn();
6808 }
6809
6810
6811 /*!
6812  * Returns a new DataArrayInt containing a renumbering map in "Old to New" mode computed
6813  * from a zip representation of a surjective format (returned e.g. by
6814  * \ref ParaMEDMEM::DataArrayDouble::findCommonTuples() "DataArrayDouble::findCommonTuples()"
6815  * for example). The result array minimizes the permutation. <br>
6816  * For more info on renumbering see \ref MEDCouplingArrayRenumbering. <br>
6817  * \b Example: <br>
6818  * - \a nbOfOldTuples: 10 
6819  * - \a arr          : [0,3, 5,7,9]
6820  * - \a arrIBg       : [0,2,5]
6821  * - \a newNbOfTuples: 7
6822  * - result array    : [0,1,2,0,3,4,5,4,6,4]
6823  *
6824  *  \param [in] nbOfOldTuples - number of tuples in the initial array \a arr.
6825  *  \param [in] arr - the array of tuple indices grouped by \a arrIBg array.
6826  *  \param [in] arrIBg - the array dividing all indices stored in \a arr into groups of
6827  *         (indices of) equal values. Its every element (except the last one) points to
6828  *         the first element of a group of equal values.
6829  *  \param [in] arrIEnd - specifies the end of \a arrIBg, so that the last element of \a
6830  *          arrIBg is \a arrIEnd[ -1 ].
6831  *  \param [out] newNbOfTuples - number of tuples after surjection application.
6832  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
6833  *          array using decrRef() as it is no more needed.
6834  *  \throw If any value of \a arr breaks condition ( 0 <= \a arr[ i ] < \a nbOfOldTuples ).
6835  */
6836 DataArrayInt *DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2(int nbOfOldTuples, const int *arr, const int *arrIBg, const int *arrIEnd, int &newNbOfTuples) throw(INTERP_KERNEL::Exception)
6837 {
6838   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6839   ret->alloc(nbOfOldTuples,1);
6840   int *pt=ret->getPointer();
6841   std::fill(pt,pt+nbOfOldTuples,-1);
6842   int nbOfGrps=((int)std::distance(arrIBg,arrIEnd))-1;
6843   const int *cIPtr=arrIBg;
6844   for(int i=0;i<nbOfGrps;i++)
6845     pt[arr[cIPtr[i]]]=-(i+2);
6846   int newNb=0;
6847   for(int iNode=0;iNode<nbOfOldTuples;iNode++)
6848     {
6849       if(pt[iNode]<0)
6850         {
6851           if(pt[iNode]==-1)
6852             pt[iNode]=newNb++;
6853           else
6854             {
6855               int grpId=-(pt[iNode]+2);
6856               for(int j=cIPtr[grpId];j<cIPtr[grpId+1];j++)
6857                 {
6858                   if(arr[j]>=0 && arr[j]<nbOfOldTuples)
6859                     pt[arr[j]]=newNb;
6860                   else
6861                     {
6862                       std::ostringstream oss; oss << "DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2 : With element #" << j << " value is " << arr[j] << " should be in [0," << nbOfOldTuples << ") !";
6863                       throw INTERP_KERNEL::Exception(oss.str().c_str());
6864                     }
6865                 }
6866               newNb++;
6867             }
6868         }
6869     }
6870   newNbOfTuples=newNb;
6871   return ret.retn();
6872 }
6873
6874 /*!
6875  * Returns a new DataArrayInt containing a renumbering map in "New to Old" mode,
6876  * which if applied to \a this array would make it sorted ascendingly.
6877  * For more info on renumbering see \ref MEDCouplingArrayRenumbering. <br>
6878  * \b Example: <br>
6879  * - \a this: [2,0,1,1,0,1,2,0,1,1,0,0]
6880  * - result: [10,0,5,6,1,7,11,2,8,9,3,4]
6881  * - after applying result to \a this: [0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2] 
6882  *
6883  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
6884  *          array using decrRef() as it is no more needed.
6885  *  \throw If \a this is not allocated.
6886  *  \throw If \a this->getNumberOfComponents() != 1.
6887  */
6888 DataArrayInt *DataArrayInt::buildPermArrPerLevel() const throw(INTERP_KERNEL::Exception)
6889 {
6890   checkAllocated();
6891   if(getNumberOfComponents()!=1)
6892     throw INTERP_KERNEL::Exception("DataArrayInt::buildPermArrPerLevel : number of components must == 1 !");
6893   int nbOfTuples=getNumberOfTuples();
6894   const int *pt=getConstPointer();
6895   std::map<int,int> m;
6896   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6897   ret->alloc(nbOfTuples,1);
6898   int *opt=ret->getPointer();
6899   for(int i=0;i<nbOfTuples;i++,pt++,opt++)
6900     {
6901       int val=*pt;
6902       std::map<int,int>::iterator it=m.find(val);
6903       if(it!=m.end())
6904         {
6905           *opt=(*it).second;
6906           (*it).second++;
6907         }
6908       else
6909         {
6910           *opt=0;
6911           m.insert(std::pair<int,int>(val,1));
6912         }
6913     }
6914   int sum=0;
6915   for(std::map<int,int>::iterator it=m.begin();it!=m.end();it++)
6916     {
6917       int vt=(*it).second;
6918       (*it).second=sum;
6919       sum+=vt;
6920     }
6921   pt=getConstPointer();
6922   opt=ret->getPointer();
6923   for(int i=0;i<nbOfTuples;i++,pt++,opt++)
6924     *opt+=m[*pt];
6925   //
6926   return ret.retn();
6927 }
6928
6929 /*!
6930  * Checks if contents of \a this array are equal to that of an array filled with
6931  * iota(). This method is particularly useful for DataArrayInt instances that represent
6932  * a renumbering array to check the real need in renumbering. 
6933  *  \return bool - \a true if \a this array contents == \a range( \a this->getNumberOfTuples())
6934  *  \throw If \a this is not allocated.
6935  *  \throw If \a this->getNumberOfComponents() != 1.
6936  */
6937 bool DataArrayInt::isIdentity() const throw(INTERP_KERNEL::Exception)
6938 {
6939   checkAllocated();
6940   if(getNumberOfComponents()!=1)
6941     return false;
6942   int nbOfTuples=getNumberOfTuples();
6943   const int *pt=getConstPointer();
6944   for(int i=0;i<nbOfTuples;i++,pt++)
6945     if(*pt!=i)
6946       return false;
6947   return true;
6948 }
6949
6950 /*!
6951  * Checks if all values in \a this array are equal to \a val.
6952  *  \param [in] val - value to check equality of array values to.
6953  *  \return bool - \a true if all values are \a val.
6954  *  \throw If \a this is not allocated.
6955  *  \throw If \a this->getNumberOfComponents() != 1
6956  */
6957 bool DataArrayInt::isUniform(int val) const throw(INTERP_KERNEL::Exception)
6958 {
6959   checkAllocated();
6960   if(getNumberOfComponents()!=1)
6961     throw INTERP_KERNEL::Exception("DataArrayInt::isUniform : must be applied on DataArrayInt with only one component, you can call 'rearrange' method before !");
6962   int nbOfTuples=getNumberOfTuples();
6963   const int *w=getConstPointer();
6964   const int *end2=w+nbOfTuples;
6965   for(;w!=end2;w++)
6966     if(*w!=val)
6967       return false;
6968   return true;
6969 }
6970
6971 /*!
6972  * Creates a new DataArrayDouble and assigns all (textual and numerical) data of \a this
6973  * array to the new one.
6974  *  \return DataArrayDouble * - the new instance of DataArrayInt.
6975  */
6976 DataArrayDouble *DataArrayInt::convertToDblArr() const
6977 {
6978   checkAllocated();
6979   DataArrayDouble *ret=DataArrayDouble::New();
6980   ret->alloc(getNumberOfTuples(),getNumberOfComponents());
6981   std::size_t nbOfVals=getNbOfElems();
6982   const int *src=getConstPointer();
6983   double *dest=ret->getPointer();
6984   std::copy(src,src+nbOfVals,dest);
6985   ret->copyStringInfoFrom(*this);
6986   return ret;
6987 }
6988
6989 /*!
6990  * Returns a shorten copy of \a this array. The new DataArrayInt contains all
6991  * tuples starting from the \a tupleIdBg-th tuple and including all tuples located before
6992  * the \a tupleIdEnd-th one. This methods has a similar behavior as std::string::substr().
6993  * This method is a specialization of selectByTupleId2().
6994  *  \param [in] tupleIdBg - index of the first tuple to copy from \a this array.
6995  *  \param [in] tupleIdEnd - index of the tuple before which the tuples to copy are located.
6996  *          If \a tupleIdEnd == -1, all the tuples till the end of \a this array are copied.
6997  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
6998  *          is to delete using decrRef() as it is no more needed.
6999  *  \throw If \a tupleIdBg < 0.
7000  *  \throw If \a tupleIdBg > \a this->getNumberOfTuples().
7001     \throw If \a tupleIdEnd != -1 && \a tupleIdEnd < \a this->getNumberOfTuples().
7002  *  \sa DataArrayInt::selectByTupleId2
7003  */
7004 DataArrayInt *DataArrayInt::substr(int tupleIdBg, int tupleIdEnd) const throw(INTERP_KERNEL::Exception)
7005 {
7006   checkAllocated();
7007   int nbt=getNumberOfTuples();
7008   if(tupleIdBg<0)
7009     throw INTERP_KERNEL::Exception("DataArrayInt::substr : The tupleIdBg parameter must be greater than 0 !");
7010   if(tupleIdBg>nbt)
7011     throw INTERP_KERNEL::Exception("DataArrayInt::substr : The tupleIdBg parameter is greater than number of tuples !");
7012   int trueEnd=tupleIdEnd;
7013   if(tupleIdEnd!=-1)
7014     {
7015       if(tupleIdEnd>nbt)
7016         throw INTERP_KERNEL::Exception("DataArrayInt::substr : The tupleIdBg parameter is greater or equal than number of tuples !");
7017     }
7018   else
7019     trueEnd=nbt;
7020   int nbComp=getNumberOfComponents();
7021   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
7022   ret->alloc(trueEnd-tupleIdBg,nbComp);
7023   ret->copyStringInfoFrom(*this);
7024   std::copy(getConstPointer()+tupleIdBg*nbComp,getConstPointer()+trueEnd*nbComp,ret->getPointer());
7025   return ret.retn();
7026 }
7027
7028 /*!
7029  * Changes the number of components within \a this array so that its raw data **does
7030  * not** change, instead splitting this data into tuples changes.
7031  *  \warning This method erases all (name and unit) component info set before!
7032  *  \param [in] newNbOfComp - number of components for \a this array to have.
7033  *  \throw If \a this is not allocated
7034  *  \throw If getNbOfElems() % \a newNbOfCompo != 0.
7035  *  \throw If \a newNbOfCompo is lower than 1.
7036  *  \throw If the rearrange method would lead to a number of tuples higher than 2147483647 (maximal capacity of int32 !).
7037  *  \warning This method erases all (name and unit) component info set before!
7038  */
7039 void DataArrayInt::rearrange(int newNbOfCompo) throw(INTERP_KERNEL::Exception)
7040 {
7041   checkAllocated();
7042   if(newNbOfCompo<1)
7043     throw INTERP_KERNEL::Exception("DataArrayInt::rearrange : input newNbOfCompo must be > 0 !");
7044   std::size_t nbOfElems=getNbOfElems();
7045   if(nbOfElems%newNbOfCompo!=0)
7046     throw INTERP_KERNEL::Exception("DataArrayInt::rearrange : nbOfElems%newNbOfCompo!=0 !");
7047   if(nbOfElems/newNbOfCompo>(std::size_t)std::numeric_limits<int>::max())
7048     throw INTERP_KERNEL::Exception("DataArrayInt::rearrange : the rearrangement leads to too high number of tuples (> 2147483647) !");
7049   _info_on_compo.clear();
7050   _info_on_compo.resize(newNbOfCompo);
7051   declareAsNew();
7052 }
7053
7054 /*!
7055  * Changes the number of components within \a this array to be equal to its number
7056  * of tuples, and inversely its number of tuples to become equal to its number of 
7057  * components. So that its raw data **does not** change, instead splitting this
7058  * data into tuples changes.
7059  *  \warning This method erases all (name and unit) component info set before!
7060  *  \warning Do not confuse this method with fromNoInterlace() and toNoInterlace()!
7061  *  \throw If \a this is not allocated.
7062  *  \sa rearrange()
7063  */
7064 void DataArrayInt::transpose() throw(INTERP_KERNEL::Exception)
7065 {
7066   checkAllocated();
7067   int nbOfTuples=getNumberOfTuples();
7068   rearrange(nbOfTuples);
7069 }
7070
7071 /*!
7072  * Returns a shorten or extended copy of \a this array. If \a newNbOfComp is less
7073  * than \a this->getNumberOfComponents() then the result array is shorten as each tuple
7074  * is truncated to have \a newNbOfComp components, keeping first components. If \a
7075  * newNbOfComp is more than \a this->getNumberOfComponents() then the result array is
7076  * expanded as each tuple is populated with \a dftValue to have \a newNbOfComp
7077  * components.  
7078  *  \param [in] newNbOfComp - number of components for the new array to have.
7079  *  \param [in] dftValue - value assigned to new values added to the new array.
7080  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
7081  *          is to delete using decrRef() as it is no more needed.
7082  *  \throw If \a this is not allocated.
7083  */
7084 DataArrayInt *DataArrayInt::changeNbOfComponents(int newNbOfComp, int dftValue) const throw(INTERP_KERNEL::Exception)
7085 {
7086   checkAllocated();
7087   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
7088   ret->alloc(getNumberOfTuples(),newNbOfComp);
7089   const int *oldc=getConstPointer();
7090   int *nc=ret->getPointer();
7091   int nbOfTuples=getNumberOfTuples();
7092   int oldNbOfComp=getNumberOfComponents();
7093   int dim=std::min(oldNbOfComp,newNbOfComp);
7094   for(int i=0;i<nbOfTuples;i++)
7095     {
7096       int j=0;
7097       for(;j<dim;j++)
7098         nc[newNbOfComp*i+j]=oldc[i*oldNbOfComp+j];
7099       for(;j<newNbOfComp;j++)
7100         nc[newNbOfComp*i+j]=dftValue;
7101     }
7102   ret->setName(getName().c_str());
7103   for(int i=0;i<dim;i++)
7104     ret->setInfoOnComponent(i,getInfoOnComponent(i).c_str());
7105   ret->setName(getName().c_str());
7106   return ret.retn();
7107 }
7108
7109 /*!
7110  * Changes number of tuples in the array. If the new number of tuples is smaller
7111  * than the current number the array is truncated, otherwise the array is extended.
7112  *  \param [in] nbOfTuples - new number of tuples. 
7113  *  \throw If \a this is not allocated.
7114  */
7115 void DataArrayInt::reAlloc(int nbOfTuples) throw(INTERP_KERNEL::Exception)
7116 {
7117   checkAllocated();
7118   _mem.reAlloc(getNumberOfComponents()*(std::size_t)nbOfTuples);
7119   declareAsNew();
7120 }
7121
7122
7123 /*!
7124  * Returns a copy of \a this array composed of selected components.
7125  * The new DataArrayInt has the same number of tuples but includes components
7126  * specified by \a compoIds parameter. So that getNbOfElems() of the result array
7127  * can be either less, same or more than \a this->getNbOfElems().
7128  *  \param [in] compoIds - sequence of zero based indices of components to include
7129  *              into the new array.
7130  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
7131  *          is to delete using decrRef() as it is no more needed.
7132  *  \throw If \a this is not allocated.
7133  *  \throw If a component index (\a i) is not valid: 
7134  *         \a i < 0 || \a i >= \a this->getNumberOfComponents().
7135  *
7136  *  \ref py_mcdataarrayint_keepselectedcomponents "Here is a Python example".
7137  */
7138 DataArray *DataArrayInt::keepSelectedComponents(const std::vector<int>& compoIds) const throw(INTERP_KERNEL::Exception)
7139 {
7140   checkAllocated();
7141   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New());
7142   int newNbOfCompo=(int)compoIds.size();
7143   int oldNbOfCompo=getNumberOfComponents();
7144   for(std::vector<int>::const_iterator it=compoIds.begin();it!=compoIds.end();it++)
7145     DataArray::CheckValueInRange(oldNbOfCompo,(*it),"keepSelectedComponents invalid requested component");
7146   int nbOfTuples=getNumberOfTuples();
7147   ret->alloc(nbOfTuples,newNbOfCompo);
7148   ret->copyPartOfStringInfoFrom(*this,compoIds);
7149   const int *oldc=getConstPointer();
7150   int *nc=ret->getPointer();
7151   for(int i=0;i<nbOfTuples;i++)
7152     for(int j=0;j<newNbOfCompo;j++,nc++)
7153       *nc=oldc[i*oldNbOfCompo+compoIds[j]];
7154   return ret.retn();
7155 }
7156
7157 /*!
7158  * Appends components of another array to components of \a this one, tuple by tuple.
7159  * So that the number of tuples of \a this array remains the same and the number of 
7160  * components increases.
7161  *  \param [in] other - the DataArrayInt to append to \a this one.
7162  *  \throw If \a this is not allocated.
7163  *  \throw If \a this and \a other arrays have different number of tuples.
7164  *
7165  *  \ref cpp_mcdataarrayint_meldwith "Here is a C++ example".
7166  *
7167  *  \ref py_mcdataarrayint_meldwith "Here is a Python example".
7168  */
7169 void DataArrayInt::meldWith(const DataArrayInt *other) throw(INTERP_KERNEL::Exception)
7170 {
7171   if(!other)
7172     throw INTERP_KERNEL::Exception("DataArrayInt::meldWith : DataArrayInt pointer in input is NULL !");
7173   checkAllocated();
7174   other->checkAllocated();
7175   int nbOfTuples=getNumberOfTuples();
7176   if(nbOfTuples!=other->getNumberOfTuples())
7177     throw INTERP_KERNEL::Exception("DataArrayInt::meldWith : mismatch of number of tuples !");
7178   int nbOfComp1=getNumberOfComponents();
7179   int nbOfComp2=other->getNumberOfComponents();
7180   int *newArr=(int *)malloc(nbOfTuples*(nbOfComp1+nbOfComp2)*sizeof(int));
7181   int *w=newArr;
7182   const int *inp1=getConstPointer();
7183   const int *inp2=other->getConstPointer();
7184   for(int i=0;i<nbOfTuples;i++,inp1+=nbOfComp1,inp2+=nbOfComp2)
7185     {
7186       w=std::copy(inp1,inp1+nbOfComp1,w);
7187       w=std::copy(inp2,inp2+nbOfComp2,w);
7188     }
7189   useArray(newArr,true,C_DEALLOC,nbOfTuples,nbOfComp1+nbOfComp2);
7190   std::vector<int> compIds(nbOfComp2);
7191   for(int i=0;i<nbOfComp2;i++)
7192     compIds[i]=nbOfComp1+i;
7193   copyPartOfStringInfoFrom2(compIds,*other);
7194 }
7195
7196 /*!
7197  * Copy all components in a specified order from another DataArrayInt.
7198  * The specified components become the first ones in \a this array.
7199  * Both numerical and textual data is copied. The number of tuples in \a this and
7200  * the other array can be different.
7201  *  \param [in] a - the array to copy data from.
7202  *  \param [in] compoIds - sequence of zero based indices of components, data of which is
7203  *              to be copied.
7204  *  \throw If \a a is NULL.
7205  *  \throw If \a compoIds.size() != \a a->getNumberOfComponents().
7206  *  \throw If \a compoIds[i] < 0 or \a compoIds[i] > \a this->getNumberOfComponents().
7207  *
7208  *  \ref py_mcdataarrayint_setselectedcomponents "Here is a Python example".
7209  */
7210 void DataArrayInt::setSelectedComponents(const DataArrayInt *a, const std::vector<int>& compoIds) throw(INTERP_KERNEL::Exception)
7211 {
7212   if(!a)
7213     throw INTERP_KERNEL::Exception("DataArrayInt::setSelectedComponents : input DataArrayInt is NULL !");
7214   checkAllocated();
7215   a->checkAllocated();
7216   copyPartOfStringInfoFrom2(compoIds,*a);
7217   std::size_t partOfCompoSz=compoIds.size();
7218   int nbOfCompo=getNumberOfComponents();
7219   int nbOfTuples=std::min(getNumberOfTuples(),a->getNumberOfTuples());
7220   const int *ac=a->getConstPointer();
7221   int *nc=getPointer();
7222   for(int i=0;i<nbOfTuples;i++)
7223     for(std::size_t j=0;j<partOfCompoSz;j++,ac++)
7224       nc[nbOfCompo*i+compoIds[j]]=*ac;
7225 }
7226
7227 /*!
7228  * Copy all values from another DataArrayInt into specified tuples and components
7229  * of \a this array. Textual data is not copied.
7230  * The tree parameters defining set of indices of tuples and components are similar to
7231  * the tree parameters of the Python function \c range(\c start,\c stop,\c step).
7232  *  \param [in] a - the array to copy values from.
7233  *  \param [in] bgTuples - index of the first tuple of \a this array to assign values to.
7234  *  \param [in] endTuples - index of the tuple before which the tuples to assign to
7235  *              are located.
7236  *  \param [in] stepTuples - index increment to get index of the next tuple to assign to.
7237  *  \param [in] bgComp - index of the first component of \a this array to assign values to.
7238  *  \param [in] endComp - index of the component before which the components to assign
7239  *              to are located.
7240  *  \param [in] stepComp - index increment to get index of the next component to assign to.
7241  *  \param [in] strictCompoCompare - if \a true (by default), then \a a->getNumberOfComponents() 
7242  *              must be equal to the number of columns to assign to, else an
7243  *              exception is thrown; if \a false, then it is only required that \a
7244  *              a->getNbOfElems() equals to number of values to assign to (this condition
7245  *              must be respected even if \a strictCompoCompare is \a true). The number of 
7246  *              values to assign to is given by following Python expression:
7247  *              \a nbTargetValues = 
7248  *              \c len(\c range(\a bgTuples,\a endTuples,\a stepTuples)) *
7249  *              \c len(\c range(\a bgComp,\a endComp,\a stepComp)).
7250  *  \throw If \a a is NULL.
7251  *  \throw If \a a is not allocated.
7252  *  \throw If \a this is not allocated.
7253  *  \throw If parameters specifying tuples and components to assign to do not give a
7254  *            non-empty range of increasing indices.
7255  *  \throw If \a a->getNbOfElems() != \a nbTargetValues.
7256  *  \throw If \a strictCompoCompare == \a true && \a a->getNumberOfComponents() !=
7257  *            \c len(\c range(\a bgComp,\a endComp,\a stepComp)).
7258  *
7259  *  \ref py_mcdataarrayint_setpartofvalues1 "Here is a Python example".
7260  */
7261 void DataArrayInt::setPartOfValues1(const DataArrayInt *a, int bgTuples, int endTuples, int stepTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare) throw(INTERP_KERNEL::Exception)
7262 {
7263   if(!a)
7264     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValues1 : DataArrayInt pointer in input is NULL !");
7265   const char msg[]="DataArrayInt::setPartOfValues1";
7266   checkAllocated();
7267   a->checkAllocated();
7268   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
7269   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
7270   int nbComp=getNumberOfComponents();
7271   int nbOfTuples=getNumberOfTuples();
7272   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
7273   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
7274   bool assignTech=true;
7275   if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
7276     {
7277       if(strictCompoCompare)
7278         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
7279     }
7280   else
7281     {
7282       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
7283       assignTech=false;
7284     }
7285   int *pt=getPointer()+bgTuples*nbComp+bgComp;
7286   const int *srcPt=a->getConstPointer();
7287   if(assignTech)
7288     {
7289       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
7290         for(int j=0;j<newNbOfComp;j++,srcPt++)
7291           pt[j*stepComp]=*srcPt;
7292     }
7293   else
7294     {
7295       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
7296         {
7297           const int *srcPt2=srcPt;
7298           for(int j=0;j<newNbOfComp;j++,srcPt2++)
7299             pt[j*stepComp]=*srcPt2;
7300         }
7301     }
7302 }
7303
7304 /*!
7305  * Assign a given value to values at specified tuples and components of \a this array.
7306  * The tree parameters defining set of indices of tuples and components are similar to
7307  * the tree parameters of the Python function \c range(\c start,\c stop,\c step)..
7308  *  \param [in] a - the value to assign.
7309  *  \param [in] bgTuples - index of the first tuple of \a this array to assign to.
7310  *  \param [in] endTuples - index of the tuple before which the tuples to assign to
7311  *              are located.
7312  *  \param [in] stepTuples - index increment to get index of the next tuple to assign to.
7313  *  \param [in] bgComp - index of the first component of \a this array to assign to.
7314  *  \param [in] endComp - index of the component before which the components to assign
7315  *              to are located.
7316  *  \param [in] stepComp - index increment to get index of the next component to assign to.
7317  *  \throw If \a this is not allocated.
7318  *  \throw If parameters specifying tuples and components to assign to, do not give a
7319  *            non-empty range of increasing indices or indices are out of a valid range
7320  *            for \this array.
7321  *
7322  *  \ref py_mcdataarrayint_setpartofvaluessimple1 "Here is a Python example".
7323  */
7324 void DataArrayInt::setPartOfValuesSimple1(int a, int bgTuples, int endTuples, int stepTuples, int bgComp, int endComp, int stepComp) throw(INTERP_KERNEL::Exception)
7325 {
7326   const char msg[]="DataArrayInt::setPartOfValuesSimple1";
7327   checkAllocated();
7328   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
7329   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
7330   int nbComp=getNumberOfComponents();
7331   int nbOfTuples=getNumberOfTuples();
7332   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
7333   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
7334   int *pt=getPointer()+bgTuples*nbComp+bgComp;
7335   for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
7336     for(int j=0;j<newNbOfComp;j++)
7337       pt[j*stepComp]=a;
7338 }
7339
7340
7341 /*!
7342  * Copy all values from another DataArrayInt (\a a) into specified tuples and 
7343  * components of \a this array. Textual data is not copied.
7344  * The tuples and components to assign to are defined by C arrays of indices.
7345  * There are two *modes of usage*:
7346  * - If \a a->getNbOfElems() equals to number of values to assign to, then every value
7347  *   of \a a is assigned to its own location within \a this array. 
7348  * - If \a a includes one tuple, then all values of \a a are assigned to the specified
7349  *   components of every specified tuple of \a this array. In this mode it is required
7350  *   that \a a->getNumberOfComponents() equals to the number of specified components.
7351  * 
7352  *  \param [in] a - the array to copy values from.
7353  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
7354  *              assign values of \a a to.
7355  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
7356  *              pointer to a tuple index <em>(pi)</em> varies as this: 
7357  *              \a bgTuples <= \a pi < \a endTuples.
7358  *  \param [in] bgComp - pointer to an array of component indices of \a this array to
7359  *              assign values of \a a to.
7360  *  \param [in] endComp - specifies the end of the array \a bgTuples, so that
7361  *              pointer to a component index <em>(pi)</em> varies as this: 
7362  *              \a bgComp <= \a pi < \a endComp.
7363  *  \param [in] strictCompoCompare - this parameter is checked only if the
7364  *               *mode of usage* is the first; if it is \a true (default), 
7365  *               then \a a->getNumberOfComponents() must be equal 
7366  *               to the number of specified columns, else this is not required.
7367  *  \throw If \a a is NULL.
7368  *  \throw If \a a is not allocated.
7369  *  \throw If \a this is not allocated.
7370  *  \throw If any index of tuple/component given by <em>bgTuples / bgComp</em> is
7371  *         out of a valid range for \a this array.
7372  *  \throw In the first *mode of usage*, if <em>strictCompoCompare == true </em> and
7373  *         if <em> a->getNumberOfComponents() != (endComp - bgComp) </em>.
7374  *  \throw In the second *mode of usage*, if \a a->getNumberOfTuples() != 1 or
7375  *         <em> a->getNumberOfComponents() != (endComp - bgComp)</em>.
7376  *
7377  *  \ref py_mcdataarrayint_setpartofvalues2 "Here is a Python example".
7378  */
7379 void DataArrayInt::setPartOfValues2(const DataArrayInt *a, const int *bgTuples, const int *endTuples, const int *bgComp, const int *endComp, bool strictCompoCompare) throw(INTERP_KERNEL::Exception)
7380 {
7381   if(!a)
7382     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValues2 : DataArrayInt pointer in input is NULL !");
7383   const char msg[]="DataArrayInt::setPartOfValues2";
7384   checkAllocated();
7385   a->checkAllocated();
7386   int nbComp=getNumberOfComponents();
7387   int nbOfTuples=getNumberOfTuples();
7388   for(const int *z=bgComp;z!=endComp;z++)
7389     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
7390   int newNbOfTuples=(int)std::distance(bgTuples,endTuples);
7391   int newNbOfComp=(int)std::distance(bgComp,endComp);
7392   bool assignTech=true;
7393   if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
7394     {
7395       if(strictCompoCompare)
7396         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
7397     }
7398   else
7399     {
7400       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
7401       assignTech=false;
7402     }
7403   int *pt=getPointer();
7404   const int *srcPt=a->getConstPointer();
7405   if(assignTech)
7406     {    
7407       for(const int *w=bgTuples;w!=endTuples;w++)
7408         {
7409           DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
7410           for(const int *z=bgComp;z!=endComp;z++,srcPt++)
7411             {    
7412               pt[(std::size_t)(*w)*nbComp+(*z)]=*srcPt;
7413             }
7414         }
7415     }
7416   else
7417     {
7418       for(const int *w=bgTuples;w!=endTuples;w++)
7419         {
7420           const int *srcPt2=srcPt;
7421           DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
7422           for(const int *z=bgComp;z!=endComp;z++,srcPt2++)
7423             {    
7424               pt[(std::size_t)(*w)*nbComp+(*z)]=*srcPt2;
7425             }
7426         }
7427     }
7428 }
7429
7430 /*!
7431  * Assign a given value to values at specified tuples and components of \a this array.
7432  * The tuples and components to assign to are defined by C arrays of indices.
7433  *  \param [in] a - the value to assign.
7434  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
7435  *              assign \a a to.
7436  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
7437  *              pointer to a tuple index (\a pi) varies as this: 
7438  *              \a bgTuples <= \a pi < \a endTuples.
7439  *  \param [in] bgComp - pointer to an array of component indices of \a this array to
7440  *              assign \a a to.
7441  *  \param [in] endComp - specifies the end of the array \a bgTuples, so that
7442  *              pointer to a component index (\a pi) varies as this: 
7443  *              \a bgComp <= \a pi < \a endComp.
7444  *  \throw If \a this is not allocated.
7445  *  \throw If any index of tuple/component given by <em>bgTuples / bgComp</em> is
7446  *         out of a valid range for \a this array.
7447  *
7448  *  \ref py_mcdataarrayint_setpartofvaluessimple2 "Here is a Python example".
7449  */
7450 void DataArrayInt::setPartOfValuesSimple2(int a, const int *bgTuples, const int *endTuples, const int *bgComp, const int *endComp) throw(INTERP_KERNEL::Exception)
7451 {
7452   checkAllocated();
7453   int nbComp=getNumberOfComponents();
7454   int nbOfTuples=getNumberOfTuples();
7455   for(const int *z=bgComp;z!=endComp;z++)
7456     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
7457   int *pt=getPointer();
7458   for(const int *w=bgTuples;w!=endTuples;w++)
7459     for(const int *z=bgComp;z!=endComp;z++)
7460       {
7461         DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
7462         pt[(std::size_t)(*w)*nbComp+(*z)]=a;
7463       }
7464 }
7465
7466 /*!
7467  * Copy all values from another DataArrayInt (\a a) into specified tuples and 
7468  * components of \a this array. Textual data is not copied.
7469  * The tuples to assign to are defined by a C array of indices.
7470  * The components to assign to are defined by three values similar to parameters of
7471  * the Python function \c range(\c start,\c stop,\c step).
7472  * There are two *modes of usage*:
7473  * - If \a a->getNbOfElems() equals to number of values to assign to, then every value
7474  *   of \a a is assigned to its own location within \a this array. 
7475  * - If \a a includes one tuple, then all values of \a a are assigned to the specified
7476  *   components of every specified tuple of \a this array. In this mode it is required
7477  *   that \a a->getNumberOfComponents() equals to the number of specified components.
7478  *
7479  *  \param [in] a - the array to copy values from.
7480  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
7481  *              assign values of \a a to.
7482  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
7483  *              pointer to a tuple index <em>(pi)</em> varies as this: 
7484  *              \a bgTuples <= \a pi < \a endTuples.
7485  *  \param [in] bgComp - index of the first component of \a this array to assign to.
7486  *  \param [in] endComp - index of the component before which the components to assign
7487  *              to are located.
7488  *  \param [in] stepComp - index increment to get index of the next component to assign to.
7489  *  \param [in] strictCompoCompare - this parameter is checked only in the first
7490  *               *mode of usage*; if \a strictCompoCompare is \a true (default), 
7491  *               then \a a->getNumberOfComponents() must be equal 
7492  *               to the number of specified columns, else this is not required.
7493  *  \throw If \a a is NULL.
7494  *  \throw If \a a is not allocated.
7495  *  \throw If \a this is not allocated.
7496  *  \throw If any index of tuple given by \a bgTuples is out of a valid range for 
7497  *         \a this array.
7498  *  \throw In the first *mode of usage*, if <em>strictCompoCompare == true </em> and
7499  *         if <em> a->getNumberOfComponents()</em> is unequal to the number of components
7500  *         defined by <em>(bgComp,endComp,stepComp)</em>.
7501  *  \throw In the second *mode of usage*, if \a a->getNumberOfTuples() != 1 or
7502  *         <em> a->getNumberOfComponents()</em> is unequal to the number of components
7503  *         defined by <em>(bgComp,endComp,stepComp)</em>.
7504  *  \throw If parameters specifying components to assign to, do not give a
7505  *            non-empty range of increasing indices or indices are out of a valid range
7506  *            for \this array.
7507  *
7508  *  \ref py_mcdataarrayint_setpartofvalues3 "Here is a Python example".
7509  */
7510 void DataArrayInt::setPartOfValues3(const DataArrayInt *a, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare) throw(INTERP_KERNEL::Exception)
7511 {
7512   if(!a)
7513     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValues3 : DataArrayInt pointer in input is NULL !");
7514   const char msg[]="DataArrayInt::setPartOfValues3";
7515   checkAllocated();
7516   a->checkAllocated();
7517   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
7518   int nbComp=getNumberOfComponents();
7519   int nbOfTuples=getNumberOfTuples();
7520   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
7521   int newNbOfTuples=(int)std::distance(bgTuples,endTuples);
7522   bool assignTech=true;
7523   if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
7524     {
7525       if(strictCompoCompare)
7526         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
7527     }
7528   else
7529     {
7530       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
7531       assignTech=false;
7532     }
7533   int *pt=getPointer()+bgComp;
7534   const int *srcPt=a->getConstPointer();
7535   if(assignTech)
7536     {
7537       for(const int *w=bgTuples;w!=endTuples;w++)
7538         for(int j=0;j<newNbOfComp;j++,srcPt++)
7539           {
7540             DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
7541             pt[(std::size_t)(*w)*nbComp+j*stepComp]=*srcPt;
7542           }
7543     }
7544   else
7545     {
7546       for(const int *w=bgTuples;w!=endTuples;w++)
7547         {
7548           const int *srcPt2=srcPt;
7549           for(int j=0;j<newNbOfComp;j++,srcPt2++)
7550             {
7551               DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
7552               pt[(std::size_t)(*w)*nbComp+j*stepComp]=*srcPt2;
7553             }
7554         }
7555     }
7556 }
7557
7558 /*!
7559  * Assign a given value to values at specified tuples and components of \a this array.
7560  * The tuples to assign to are defined by a C array of indices.
7561  * The components to assign to are defined by three values similar to parameters of
7562  * the Python function \c range(\c start,\c stop,\c step).
7563  *  \param [in] a - the value to assign.
7564  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
7565  *              assign \a a to.
7566  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
7567  *              pointer to a tuple index <em>(pi)</em> varies as this: 
7568  *              \a bgTuples <= \a pi < \a endTuples.
7569  *  \param [in] bgComp - index of the first component of \a this array to assign to.
7570  *  \param [in] endComp - index of the component before which the components to assign
7571  *              to are located.
7572  *  \param [in] stepComp - index increment to get index of the next component to assign to.
7573  *  \throw If \a this is not allocated.
7574  *  \throw If any index of tuple given by \a bgTuples is out of a valid range for 
7575  *         \a this array.
7576  *  \throw If parameters specifying components to assign to, do not give a
7577  *            non-empty range of increasing indices or indices are out of a valid range
7578  *            for \this array.
7579  *
7580  *  \ref py_mcdataarrayint_setpartofvaluessimple3 "Here is a Python example".
7581  */
7582 void DataArrayInt::setPartOfValuesSimple3(int a, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp) throw(INTERP_KERNEL::Exception)
7583 {
7584   const char msg[]="DataArrayInt::setPartOfValuesSimple3";
7585   checkAllocated();
7586   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
7587   int nbComp=getNumberOfComponents();
7588   int nbOfTuples=getNumberOfTuples();
7589   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
7590   int *pt=getPointer()+bgComp;
7591   for(const int *w=bgTuples;w!=endTuples;w++)
7592     for(int j=0;j<newNbOfComp;j++)
7593       {
7594         DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
7595         pt[(std::size_t)(*w)*nbComp+j*stepComp]=a;
7596       }
7597 }
7598
7599 void DataArrayInt::setPartOfValues4(const DataArrayInt *a, int bgTuples, int endTuples, int stepTuples, const int *bgComp, const int *endComp, bool strictCompoCompare) throw(INTERP_KERNEL::Exception)
7600 {
7601   if(!a)
7602     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValues4 : input DataArrayInt is NULL !");
7603   const char msg[]="DataArrayInt::setPartOfValues4";
7604   checkAllocated();
7605   a->checkAllocated();
7606   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
7607   int newNbOfComp=(int)std::distance(bgComp,endComp);
7608   int nbComp=getNumberOfComponents();
7609   for(const int *z=bgComp;z!=endComp;z++)
7610     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
7611   int nbOfTuples=getNumberOfTuples();
7612   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
7613   bool assignTech=true;
7614   if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
7615     {
7616       if(strictCompoCompare)
7617         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
7618     }
7619   else
7620     {
7621       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
7622       assignTech=false;
7623     }
7624   const int *srcPt=a->getConstPointer();
7625   int *pt=getPointer()+bgTuples*nbComp;
7626   if(assignTech)
7627     {
7628       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
7629         for(const int *z=bgComp;z!=endComp;z++,srcPt++)
7630           pt[*z]=*srcPt;
7631     }
7632   else
7633     {
7634       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
7635         {
7636           const int *srcPt2=srcPt;
7637           for(const int *z=bgComp;z!=endComp;z++,srcPt2++)
7638             pt[*z]=*srcPt2;
7639         }
7640     }
7641 }
7642
7643 void DataArrayInt::setPartOfValuesSimple4(int a, int bgTuples, int endTuples, int stepTuples, const int *bgComp, const int *endComp) throw(INTERP_KERNEL::Exception)
7644 {
7645   const char msg[]="DataArrayInt::setPartOfValuesSimple4";
7646   checkAllocated();
7647   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
7648   int nbComp=getNumberOfComponents();
7649   for(const int *z=bgComp;z!=endComp;z++)
7650     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
7651   int nbOfTuples=getNumberOfTuples();
7652   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
7653   int *pt=getPointer()+bgTuples*nbComp;
7654   for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
7655     for(const int *z=bgComp;z!=endComp;z++)
7656       pt[*z]=a;
7657 }
7658
7659 /*!
7660  * Copy some tuples from another DataArrayInt into specified tuples
7661  * of \a this array. Textual data is not copied. Both arrays must have equal number of
7662  * components.
7663  * Both the tuples to assign and the tuples to assign to are defined by a DataArrayInt.
7664  * All components of selected tuples are copied.
7665  *  \param [in] a - the array to copy values from.
7666  *  \param [in] tuplesSelec - the array specifying both source tuples of \a a and
7667  *              target tuples of \a this. \a tuplesSelec has two components, and the
7668  *              first component specifies index of the source tuple and the second
7669  *              one specifies index of the target tuple.
7670  *  \throw If \a this is not allocated.
7671  *  \throw If \a a is NULL.
7672  *  \throw If \a a is not allocated.
7673  *  \throw If \a tuplesSelec is NULL.
7674  *  \throw If \a tuplesSelec is not allocated.
7675  *  \throw If <em>this->getNumberOfComponents() != a->getNumberOfComponents()</em>.
7676  *  \throw If \a tuplesSelec->getNumberOfComponents() != 2.
7677  *  \throw If any tuple index given by \a tuplesSelec is out of a valid range for 
7678  *         the corresponding (\a this or \a a) array.
7679  */
7680 void DataArrayInt::setPartOfValuesAdv(const DataArrayInt *a, const DataArrayInt *tuplesSelec) throw(INTERP_KERNEL::Exception)
7681 {
7682   if(!a || !tuplesSelec)
7683     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValuesAdv : DataArrayInt pointer in input is NULL !");
7684   checkAllocated();
7685   a->checkAllocated();
7686   tuplesSelec->checkAllocated();
7687   int nbOfComp=getNumberOfComponents();
7688   if(nbOfComp!=a->getNumberOfComponents())
7689     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValuesAdv : This and a do not have the same number of components !");
7690   if(tuplesSelec->getNumberOfComponents()!=2)
7691     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValuesAdv : Expecting to have a tuple selector DataArrayInt instance with exactly 2 components !");
7692   int thisNt=getNumberOfTuples();
7693   int aNt=a->getNumberOfTuples();
7694   int *valsToSet=getPointer();
7695   const int *valsSrc=a->getConstPointer();
7696   for(const int *tuple=tuplesSelec->begin();tuple!=tuplesSelec->end();tuple+=2)
7697     {
7698       if(tuple[1]>=0 && tuple[1]<aNt)
7699         {
7700           if(tuple[0]>=0 && tuple[0]<thisNt)
7701             std::copy(valsSrc+nbOfComp*tuple[1],valsSrc+nbOfComp*(tuple[1]+1),valsToSet+nbOfComp*tuple[0]);
7702           else
7703             {
7704               std::ostringstream oss; oss << "DataArrayInt::setPartOfValuesAdv : Tuple #" << std::distance(tuplesSelec->begin(),tuple)/2;
7705               oss << " of 'tuplesSelec' request of tuple id #" << tuple[0] << " in 'this' ! It should be in [0," << thisNt << ") !";
7706               throw INTERP_KERNEL::Exception(oss.str().c_str());
7707             }
7708         }
7709       else
7710         {
7711           std::ostringstream oss; oss << "DataArrayInt::setPartOfValuesAdv : Tuple #" << std::distance(tuplesSelec->begin(),tuple)/2;
7712           oss << " of 'tuplesSelec' request of tuple id #" << tuple[1] << " in 'a' ! It should be in [0," << aNt << ") !";
7713           throw INTERP_KERNEL::Exception(oss.str().c_str());
7714         }
7715     }
7716 }
7717
7718 /*!
7719  * Copy some tuples from another DataArrayInt (\a a) into contiguous tuples
7720  * of \a this array. Textual data is not copied. Both arrays must have equal number of
7721  * components.
7722  * The tuples to assign to are defined by index of the first tuple, and
7723  * their number is defined by \a tuplesSelec->getNumberOfTuples().
7724  * The tuples to copy are defined by values of a DataArrayInt.
7725  * All components of selected tuples are copied.
7726  *  \param [in] tupleIdStart - index of the first tuple of \a this array to assign
7727  *              values to.
7728  *  \param [in] a - the array to copy values from.
7729  *  \param [in] tuplesSelec - the array specifying tuples of \a a to copy.
7730  *  \throw If \a this is not allocated.
7731  *  \throw If \a a is NULL.
7732  *  \throw If \a a is not allocated.
7733  *  \throw If \a tuplesSelec is NULL.
7734  *  \throw If \a tuplesSelec is not allocated.
7735  *  \throw If <em>this->getNumberOfComponents() != a->getNumberOfComponents()</em>.
7736  *  \throw If \a tuplesSelec->getNumberOfComponents() != 1.
7737  *  \throw If <em>tupleIdStart + tuplesSelec->getNumberOfTuples() > this->getNumberOfTuples().</em>
7738  *  \throw If any tuple index given by \a tuplesSelec is out of a valid range for 
7739  *         \a a array.
7740  */
7741 void DataArrayInt::setContigPartOfSelectedValues(int tupleIdStart, const DataArray *aBase, const DataArrayInt *tuplesSelec) throw(INTERP_KERNEL::Exception)
7742 {
7743   if(!aBase || !tuplesSelec)
7744     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues : input DataArray is NULL !");
7745   const DataArrayInt *a=dynamic_cast<const DataArrayInt *>(aBase);
7746   if(!a)
7747     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues : input DataArray aBase is not a DataArrayInt !");
7748   checkAllocated();
7749   a->checkAllocated();
7750   tuplesSelec->checkAllocated();
7751   int nbOfComp=getNumberOfComponents();
7752   if(nbOfComp!=a->getNumberOfComponents())
7753     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues : This and a do not have the same number of components !");
7754   if(tuplesSelec->getNumberOfComponents()!=1)
7755     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues : Expecting to have a tuple selector DataArrayInt instance with exactly 1 component !");
7756   int thisNt=getNumberOfTuples();
7757   int aNt=a->getNumberOfTuples();
7758   int nbOfTupleToWrite=tuplesSelec->getNumberOfTuples();
7759   int *valsToSet=getPointer()+tupleIdStart*nbOfComp;
7760   if(tupleIdStart+nbOfTupleToWrite>thisNt)
7761     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues : invalid number range of values to write !");
7762   const int *valsSrc=a->getConstPointer();
7763   for(const int *tuple=tuplesSelec->begin();tuple!=tuplesSelec->end();tuple++,valsToSet+=nbOfComp)
7764     {
7765       if(*tuple>=0 && *tuple<aNt)
7766         {
7767           std::copy(valsSrc+nbOfComp*(*tuple),valsSrc+nbOfComp*(*tuple+1),valsToSet);
7768         }
7769       else
7770         {
7771           std::ostringstream oss; oss << "DataArrayInt::setContigPartOfSelectedValues : Tuple #" << std::distance(tuplesSelec->begin(),tuple);
7772           oss << " of 'tuplesSelec' request of tuple id #" << *tuple << " in 'a' ! It should be in [0," << aNt << ") !";
7773           throw INTERP_KERNEL::Exception(oss.str().c_str());
7774         }
7775     }
7776 }
7777
7778 /*!
7779  * Copy some tuples from another DataArrayInt (\a a) into contiguous tuples
7780  * of \a this array. Textual data is not copied. Both arrays must have equal number of
7781  * components.
7782  * The tuples to copy are defined by three values similar to parameters of
7783  * the Python function \c range(\c start,\c stop,\c step).
7784  * The tuples to assign to are defined by index of the first tuple, and
7785  * their number is defined by number of tuples to copy.
7786  * All components of selected tuples are copied.
7787  *  \param [in] tupleIdStart - index of the first tuple of \a this array to assign
7788  *              values to.
7789  *  \param [in] a - the array to copy values from.
7790  *  \param [in] bg - index of the first tuple to copy of the array \a a.
7791  *  \param [in] end2 - index of the tuple of \a a before which the tuples to copy
7792  *              are located.
7793  *  \param [in] step - index increment to get index of the next tuple to copy.
7794  *  \throw If \a this is not allocated.
7795  *  \throw If \a a is NULL.
7796  *  \throw If \a a is not allocated.
7797  *  \throw If <em>this->getNumberOfComponents() != a->getNumberOfComponents()</em>.
7798  *  \throw If <em>tupleIdStart + len(range(bg,end2,step)) > this->getNumberOfTuples().</em>
7799  *  \throw If parameters specifying tuples to copy, do not give a
7800  *            non-empty range of increasing indices or indices are out of a valid range
7801  *            for the array \a a.
7802  */
7803 void DataArrayInt::setContigPartOfSelectedValues2(int tupleIdStart, const DataArray *aBase, int bg, int end2, int step) throw(INTERP_KERNEL::Exception)
7804 {
7805   if(!aBase)
7806     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues2 : input DataArray is NULL !");
7807   const DataArrayInt *a=dynamic_cast<const DataArrayInt *>(aBase);
7808   if(!a)
7809     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues2 : input DataArray aBase is not a DataArrayInt !");
7810   checkAllocated();
7811   a->checkAllocated();
7812   int nbOfComp=getNumberOfComponents();
7813   const char msg[]="DataArrayInt::setContigPartOfSelectedValues2";
7814   int nbOfTupleToWrite=DataArray::GetNumberOfItemGivenBES(bg,end2,step,msg);
7815   if(nbOfComp!=a->getNumberOfComponents())
7816     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues2 : This and a do not have the same number of components !");
7817   int thisNt=getNumberOfTuples();
7818   int aNt=a->getNumberOfTuples();
7819   int *valsToSet=getPointer()+tupleIdStart*nbOfComp;
7820   if(tupleIdStart+nbOfTupleToWrite>thisNt)
7821     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues2 : invalid number range of values to write !");
7822   if(end2>aNt)
7823     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues2 : invalid range of values to read !");
7824   const int *valsSrc=a->getConstPointer()+bg*nbOfComp;
7825   for(int i=0;i<nbOfTupleToWrite;i++,valsToSet+=nbOfComp,valsSrc+=step*nbOfComp)
7826     {
7827       std::copy(valsSrc,valsSrc+nbOfComp,valsToSet);
7828     }
7829 }
7830
7831 /*!
7832  * Returns a value located at specified tuple and component.
7833  * This method is equivalent to DataArrayInt::getIJ() except that validity of
7834  * parameters is checked. So this method is safe but expensive if used to go through
7835  * all values of \a this.
7836  *  \param [in] tupleId - index of tuple of interest.
7837  *  \param [in] compoId - index of component of interest.
7838  *  \return double - value located by \a tupleId and \a compoId.
7839  *  \throw If \a this is not allocated.
7840  *  \throw If condition <em>( 0 <= tupleId < this->getNumberOfTuples() )</em> is violated.
7841  *  \throw If condition <em>( 0 <= compoId < this->getNumberOfComponents() )</em> is violated.
7842  */
7843 int DataArrayInt::getIJSafe(int tupleId, int compoId) const throw(INTERP_KERNEL::Exception)
7844 {
7845   checkAllocated();
7846   if(tupleId<0 || tupleId>=getNumberOfTuples())
7847     {
7848       std::ostringstream oss; oss << "DataArrayInt::getIJSafe : request for tupleId " << tupleId << " should be in [0," << getNumberOfTuples() << ") !";
7849       throw INTERP_KERNEL::Exception(oss.str().c_str());
7850     }
7851   if(compoId<0 || compoId>=getNumberOfComponents())
7852     {
7853       std::ostringstream oss; oss << "DataArrayInt::getIJSafe : request for compoId " << compoId << " should be in [0," << getNumberOfComponents() << ") !";
7854       throw INTERP_KERNEL::Exception(oss.str().c_str());
7855     }
7856   return _mem[tupleId*_info_on_compo.size()+compoId];
7857 }
7858
7859 /*!
7860  * Returns the first value of \a this. 
7861  *  \return int - the last value of \a this array.
7862  *  \throw If \a this is not allocated.
7863  *  \throw If \a this->getNumberOfComponents() != 1.
7864  *  \throw If \a this->getNumberOfTuples() < 1.
7865  */
7866 int DataArrayInt::front() const throw(INTERP_KERNEL::Exception)
7867 {
7868   checkAllocated();
7869   if(getNumberOfComponents()!=1)
7870     throw INTERP_KERNEL::Exception("DataArrayInt::front : number of components not equal to one !");
7871   int nbOfTuples=getNumberOfTuples();
7872   if(nbOfTuples<1)
7873     throw INTERP_KERNEL::Exception("DataArrayInt::front : number of tuples must be >= 1 !");
7874   return *(getConstPointer());
7875 }
7876
7877 /*!
7878  * Returns the last value of \a this. 
7879  *  \return int - the last value of \a this array.
7880  *  \throw If \a this is not allocated.
7881  *  \throw If \a this->getNumberOfComponents() != 1.
7882  *  \throw If \a this->getNumberOfTuples() < 1.
7883  */
7884 int DataArrayInt::back() const throw(INTERP_KERNEL::Exception)
7885 {
7886   checkAllocated();
7887   if(getNumberOfComponents()!=1)
7888     throw INTERP_KERNEL::Exception("DataArrayInt::back : number of components not equal to one !");
7889   int nbOfTuples=getNumberOfTuples();
7890   if(nbOfTuples<1)
7891     throw INTERP_KERNEL::Exception("DataArrayInt::back : number of tuples must be >= 1 !");
7892   return *(getConstPointer()+nbOfTuples-1);
7893 }
7894
7895 /*!
7896  * Assign pointer to one array to a pointer to another appay. Reference counter of
7897  * \a arrayToSet is incremented / decremented.
7898  *  \param [in] newArray - the pointer to array to assign to \a arrayToSet.
7899  *  \param [in,out] arrayToSet - the pointer to array to assign to.
7900  */
7901 void DataArrayInt::SetArrayIn(DataArrayInt *newArray, DataArrayInt* &arrayToSet)
7902 {
7903   if(newArray!=arrayToSet)
7904     {
7905       if(arrayToSet)
7906         arrayToSet->decrRef();
7907       arrayToSet=newArray;
7908       if(arrayToSet)
7909         arrayToSet->incrRef();
7910     }
7911 }
7912
7913 DataArrayIntIterator *DataArrayInt::iterator() throw(INTERP_KERNEL::Exception)
7914 {
7915   return new DataArrayIntIterator(this);
7916 }
7917
7918 /*!
7919  * Creates a new DataArrayInt containing IDs (indices) of tuples holding value equal to a
7920  * given one.
7921  *  \param [in] val - the value to find within \a this.
7922  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
7923  *          array using decrRef() as it is no more needed.
7924  *  \throw If \a this is not allocated.
7925  *  \throw If \a this->getNumberOfComponents() != 1.
7926  */
7927 DataArrayInt *DataArrayInt::getIdsEqual(int val) const throw(INTERP_KERNEL::Exception)
7928 {
7929   checkAllocated();
7930   if(getNumberOfComponents()!=1)
7931     throw INTERP_KERNEL::Exception("DataArrayInt::getIdsEqual : the array must have only one component, you can call 'rearrange' method before !");
7932   const int *cptr=getConstPointer();
7933   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
7934   int nbOfTuples=getNumberOfTuples();
7935   for(int i=0;i<nbOfTuples;i++,cptr++)
7936     if(*cptr==val)
7937       ret->pushBackSilent(i);
7938   return ret.retn();
7939 }
7940
7941 /*!
7942  * Creates a new DataArrayInt containing IDs (indices) of tuples holding value \b not
7943  * equal to a given one. 
7944  *  \param [in] val - the value to ignore within \a this.
7945  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
7946  *          array using decrRef() as it is no more needed.
7947  *  \throw If \a this is not allocated.
7948  *  \throw If \a this->getNumberOfComponents() != 1.
7949  */
7950 DataArrayInt *DataArrayInt::getIdsNotEqual(int val) const throw(INTERP_KERNEL::Exception)
7951 {
7952   checkAllocated();
7953   if(getNumberOfComponents()!=1)
7954     throw INTERP_KERNEL::Exception("DataArrayInt::getIdsNotEqual : the array must have only one component, you can call 'rearrange' method before !");
7955   const int *cptr=getConstPointer();
7956   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
7957   int nbOfTuples=getNumberOfTuples();
7958   for(int i=0;i<nbOfTuples;i++,cptr++)
7959     if(*cptr!=val)
7960       ret->pushBackSilent(i);
7961   return ret.retn();
7962 }
7963
7964
7965 /*!
7966  * Assigns \a newValue to all elements holding \a oldValue within \a this
7967  * one-dimensional array.
7968  *  \param [in] oldValue - the value to replace.
7969  *  \param [in] newValue - the value to assign.
7970  *  \return int - number of replacements performed.
7971  *  \throw If \a this is not allocated.
7972  *  \throw If \a this->getNumberOfComponents() != 1.
7973  */
7974 int DataArrayInt::changeValue(int oldValue, int newValue) throw(INTERP_KERNEL::Exception)
7975 {
7976   checkAllocated();
7977   if(getNumberOfComponents()!=1)
7978     throw INTERP_KERNEL::Exception("DataArrayInt::changeValue : the array must have only one component, you can call 'rearrange' method before !");
7979   int *start=getPointer();
7980   int *end2=start+getNbOfElems();
7981   int ret=0;
7982   for(int *val=start;val!=end2;val++)
7983     {
7984       if(*val==oldValue)
7985         {
7986           *val=newValue;
7987           ret++;
7988         }
7989     }
7990   return ret;
7991 }
7992
7993 /*!
7994  * Creates a new DataArrayInt containing IDs (indices) of tuples holding value equal to
7995  * one of given values.
7996  *  \param [in] valsBg - an array of values to find within \a this array.
7997  *  \param [in] valsEnd - specifies the end of the array \a valsBg, so that
7998  *              the last value of \a valsBg is \a valsEnd[ -1 ].
7999  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
8000  *          array using decrRef() as it is no more needed.
8001  *  \throw If \a this->getNumberOfComponents() != 1.
8002  */
8003 DataArrayInt *DataArrayInt::getIdsEqualList(const int *valsBg, const int *valsEnd) const throw(INTERP_KERNEL::Exception)
8004 {
8005   if(getNumberOfComponents()!=1)
8006     throw INTERP_KERNEL::Exception("DataArrayInt::getIdsEqualList : the array must have only one component, you can call 'rearrange' method before !");
8007   std::set<int> vals2(valsBg,valsEnd);
8008   const int *cptr=getConstPointer();
8009   std::vector<int> res;
8010   int nbOfTuples=getNumberOfTuples();
8011   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
8012   for(int i=0;i<nbOfTuples;i++,cptr++)
8013     if(vals2.find(*cptr)!=vals2.end())
8014       ret->pushBackSilent(i);
8015   return ret.retn();
8016 }
8017
8018 /*!
8019  * Creates a new DataArrayInt containing IDs (indices) of tuples holding values \b not
8020  * equal to any of given values.
8021  *  \param [in] valsBg - an array of values to ignore within \a this array.
8022  *  \param [in] valsEnd - specifies the end of the array \a valsBg, so that
8023  *              the last value of \a valsBg is \a valsEnd[ -1 ].
8024  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
8025  *          array using decrRef() as it is no more needed.
8026  *  \throw If \a this->getNumberOfComponents() != 1.
8027  */
8028 DataArrayInt *DataArrayInt::getIdsNotEqualList(const int *valsBg, const int *valsEnd) const throw(INTERP_KERNEL::Exception)
8029 {
8030   if(getNumberOfComponents()!=1)
8031     throw INTERP_KERNEL::Exception("DataArrayInt::getIdsNotEqualList : the array must have only one component, you can call 'rearrange' method before !");
8032   std::set<int> vals2(valsBg,valsEnd);
8033   const int *cptr=getConstPointer();
8034   std::vector<int> res;
8035   int nbOfTuples=getNumberOfTuples();
8036   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
8037   for(int i=0;i<nbOfTuples;i++,cptr++)
8038     if(vals2.find(*cptr)==vals2.end())
8039       ret->pushBackSilent(i);
8040   return ret.retn();
8041 }
8042
8043 /*!
8044  * This method is an extension of DataArrayInt::locateValue method because this method works for DataArrayInt with
8045  * any number of components excepted 0 (an INTERP_KERNEL::Exception is thrown in this case).
8046  * This method searches in \b this is there is a tuple that matched the input parameter \b tupl.
8047  * If any the tuple id is returned. If not -1 is returned.
8048  * 
8049  * This method throws an INTERP_KERNEL::Exception if the number of components in \b this mismatches with the size of
8050  * the input vector. An INTERP_KERNEL::Exception is thrown too if \b this is not allocated.
8051  *
8052  * \return tuple id where \b tupl is. -1 if no such tuple exists in \b this.
8053  * \sa DataArrayInt::search, DataArrayInt::presenceOfTuple.
8054  */
8055 int DataArrayInt::locateTuple(const std::vector<int>& tupl) const throw(INTERP_KERNEL::Exception)
8056 {
8057   checkAllocated();
8058   int nbOfCompo=getNumberOfComponents();
8059   if(nbOfCompo==0)
8060     throw INTERP_KERNEL::Exception("DataArrayInt::locateTuple : 0 components in 'this' !");
8061   if(nbOfCompo!=(int)tupl.size())
8062     {
8063       std::ostringstream oss; oss << "DataArrayInt::locateTuple : 'this' contains " << nbOfCompo << " components and searching for a tuple of length " << tupl.size() << " !";
8064       throw INTERP_KERNEL::Exception(oss.str().c_str());
8065     }
8066   const int *cptr=getConstPointer();
8067   std::size_t nbOfVals=getNbOfElems();
8068   for(const int *work=cptr;work!=cptr+nbOfVals;)
8069     {
8070       work=std::search(work,cptr+nbOfVals,tupl.begin(),tupl.end());
8071       if(work!=cptr+nbOfVals)
8072         {
8073           if(std::distance(cptr,work)%nbOfCompo!=0)
8074             work++;
8075           else
8076             return std::distance(cptr,work)/nbOfCompo;
8077         }
8078     }
8079   return -1;
8080 }
8081
8082 /*!
8083  * This method searches the sequence specified in input parameter \b vals in \b this.
8084  * This works only for DataArrayInt having number of components equal to one (if not an INTERP_KERNEL::Exception will be thrown).
8085  * This method differs from DataArrayInt::locateTuple in that the position is internal raw data is not considered here contrary to DataArrayInt::locateTuple.
8086  * \sa DataArrayInt::locateTuple
8087  */
8088 int DataArrayInt::search(const std::vector<int>& vals) const throw(INTERP_KERNEL::Exception)
8089 {
8090   checkAllocated();
8091   int nbOfCompo=getNumberOfComponents();
8092   if(nbOfCompo!=1)
8093     throw INTERP_KERNEL::Exception("DataArrayInt::search : works only for DataArrayInt instance with one component !");
8094   const int *cptr=getConstPointer();
8095   std::size_t nbOfVals=getNbOfElems();
8096   const int *loc=std::search(cptr,cptr+nbOfVals,vals.begin(),vals.end());
8097   if(loc!=cptr+nbOfVals)
8098     return std::distance(cptr,loc);
8099   return -1;
8100 }
8101
8102 /*!
8103  * This method expects to be called when number of components of this is equal to one.
8104  * This method returns the tuple id, if it exists, of the first tuple equal to \b value.
8105  * If not any tuple contains \b value -1 is returned.
8106  * \sa DataArrayInt::presenceOfValue
8107  */
8108 int DataArrayInt::locateValue(int value) const throw(INTERP_KERNEL::Exception)
8109 {
8110   checkAllocated();
8111   if(getNumberOfComponents()!=1)
8112     throw INTERP_KERNEL::Exception("DataArrayInt::presenceOfValue : the array must have only one component, you can call 'rearrange' method before !");
8113   const int *cptr=getConstPointer();
8114   int nbOfTuples=getNumberOfTuples();
8115   const int *ret=std::find(cptr,cptr+nbOfTuples,value);
8116   if(ret!=cptr+nbOfTuples)
8117     return std::distance(cptr,ret);
8118   return -1;
8119 }
8120
8121 /*!
8122  * This method expects to be called when number of components of this is equal to one.
8123  * This method returns the tuple id, if it exists, of the first tuple so that the value is contained in \b vals.
8124  * If not any tuple contains one of the values contained in 'vals' false is returned.
8125  * \sa DataArrayInt::presenceOfValue
8126  */
8127 int DataArrayInt::locateValue(const std::vector<int>& vals) const throw(INTERP_KERNEL::Exception)
8128 {
8129   checkAllocated();
8130   if(getNumberOfComponents()!=1)
8131     throw INTERP_KERNEL::Exception("DataArrayInt::presenceOfValue : the array must have only one component, you can call 'rearrange' method before !");
8132   std::set<int> vals2(vals.begin(),vals.end());
8133   const int *cptr=getConstPointer();
8134   int nbOfTuples=getNumberOfTuples();
8135   for(const int *w=cptr;w!=cptr+nbOfTuples;w++)
8136     if(vals2.find(*w)!=vals2.end())
8137       return std::distance(cptr,w);
8138   return -1;
8139 }
8140
8141 /*!
8142  * This method returns the number of values in \a this that are equals to input parameter \a value.
8143  * This method only works for single component array.
8144  *
8145  * \return a value in [ 0, \c this->getNumberOfTuples() )
8146  *
8147  * \throw If \a this is not allocated
8148  *
8149  */
8150 int DataArrayInt::count(int value) const throw(INTERP_KERNEL::Exception)
8151 {
8152   int ret=0;
8153   checkAllocated();
8154   if(getNumberOfComponents()!=1)
8155     throw INTERP_KERNEL::Exception("DataArrayInt::count : must be applied on DataArrayInt with only one component, you can call 'rearrange' method before !");
8156   const int *vals=begin();
8157   int nbOfTuples=getNumberOfTuples();
8158   for(int i=0;i<nbOfTuples;i++,vals++)
8159     if(*vals==value)
8160       ret++;
8161   return ret;
8162 }
8163
8164 /*!
8165  * This method is an extension of DataArrayInt::presenceOfValue method because this method works for DataArrayInt with
8166  * any number of components excepted 0 (an INTERP_KERNEL::Exception is thrown in this case).
8167  * This method searches in \b this is there is a tuple that matched the input parameter \b tupl.
8168  * This method throws an INTERP_KERNEL::Exception if the number of components in \b this mismatches with the size of
8169  * the input vector. An INTERP_KERNEL::Exception is thrown too if \b this is not allocated.
8170  * \sa DataArrayInt::locateTuple
8171  */
8172 bool DataArrayInt::presenceOfTuple(const std::vector<int>& tupl) const throw(INTERP_KERNEL::Exception)
8173 {
8174   return locateTuple(tupl)!=-1;
8175 }
8176
8177
8178 /*!
8179  * Returns \a true if a given value is present within \a this one-dimensional array.
8180  *  \param [in] value - the value to find within \a this array.
8181  *  \return bool - \a true in case if \a value is present within \a this array.
8182  *  \throw If \a this is not allocated.
8183  *  \throw If \a this->getNumberOfComponents() != 1.
8184  *  \sa locateValue()
8185  */
8186 bool DataArrayInt::presenceOfValue(int value) const throw(INTERP_KERNEL::Exception)
8187 {
8188   return locateValue(value)!=-1;
8189 }
8190
8191 /*!
8192  * This method expects to be called when number of components of this is equal to one.
8193  * This method returns true if it exists a tuple so that the value is contained in \b vals.
8194  * If not any tuple contains one of the values contained in 'vals' false is returned.
8195  * \sa DataArrayInt::locateValue
8196  */
8197 bool DataArrayInt::presenceOfValue(const std::vector<int>& vals) const throw(INTERP_KERNEL::Exception)
8198 {
8199   return locateValue(vals)!=-1;
8200 }
8201
8202 /*!
8203  * Accumulates values of each component of \a this array.
8204  *  \param [out] res - an array of length \a this->getNumberOfComponents(), allocated 
8205  *         by the caller, that is filled by this method with sum value for each
8206  *         component.
8207  *  \throw If \a this is not allocated.
8208  */
8209 void DataArrayInt::accumulate(int *res) const throw(INTERP_KERNEL::Exception)
8210 {
8211   checkAllocated();
8212   const int *ptr=getConstPointer();
8213   int nbTuple=getNumberOfTuples();
8214   int nbComps=getNumberOfComponents();
8215   std::fill(res,res+nbComps,0);
8216   for(int i=0;i<nbTuple;i++)
8217     std::transform(ptr+i*nbComps,ptr+(i+1)*nbComps,res,res,std::plus<int>());
8218 }
8219
8220 int DataArrayInt::accumulate(int compId) const throw(INTERP_KERNEL::Exception)
8221 {
8222   checkAllocated();
8223   const int *ptr=getConstPointer();
8224   int nbTuple=getNumberOfTuples();
8225   int nbComps=getNumberOfComponents();
8226   if(compId<0 || compId>=nbComps)
8227     throw INTERP_KERNEL::Exception("DataArrayInt::accumulate : Invalid compId specified : No such nb of components !");
8228   int ret=0;
8229   for(int i=0;i<nbTuple;i++)
8230     ret+=ptr[i*nbComps+compId];
8231   return ret;
8232 }
8233
8234 /*!
8235  * This method accumulate using addition tuples in \a this using input index array [ \a bgOfIndex, \a endOfIndex ).
8236  * The returned array will have same number of components than \a this and number of tuples equal to
8237  * \c std::distance(bgOfIndex,endOfIndex) \b minus \b one.
8238  *
8239  * The input index array is expected to be ascendingly sorted in which the all referenced ids should be in [0, \c this->getNumberOfTuples).
8240  *
8241  * \param [in] bgOfIndex - begin (included) of the input index array.
8242  * \param [in] endOfIndex - end (excluded) of the input index array.
8243  * \return DataArrayInt * - the new instance having the same number of components than \a this.
8244  * 
8245  * \throw If bgOfIndex or end is NULL.
8246  * \throw If input index array is not ascendingly sorted.
8247  * \throw If there is an id in [ \a bgOfIndex, \a endOfIndex ) not in [0, \c this->getNumberOfTuples).
8248  * \throw If std::distance(bgOfIndex,endOfIndex)==0.
8249  */
8250 DataArrayInt *DataArrayInt::accumulatePerChunck(const int *bgOfIndex, const int *endOfIndex) const throw(INTERP_KERNEL::Exception)
8251 {
8252   if(!bgOfIndex || !endOfIndex)
8253     throw INTERP_KERNEL::Exception("DataArrayInt::accumulatePerChunck : input pointer NULL !");
8254   checkAllocated();
8255   int nbCompo=getNumberOfComponents();
8256   int nbOfTuples=getNumberOfTuples();
8257   int sz=(int)std::distance(bgOfIndex,endOfIndex);
8258   if(sz<1)
8259     throw INTERP_KERNEL::Exception("DataArrayInt::accumulatePerChunck : invalid size of input index array !");
8260   sz--;
8261   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(sz,nbCompo);
8262   const int *w=bgOfIndex;
8263   if(*w<0 || *w>=nbOfTuples)
8264     throw INTERP_KERNEL::Exception("DataArrayInt::accumulatePerChunck : The first element of the input index not in [0,nbOfTuples) !");
8265   const int *srcPt=begin()+(*w)*nbCompo;
8266   int *tmp=ret->getPointer();
8267   for(int i=0;i<sz;i++,tmp+=nbCompo,w++)
8268     {
8269       std::fill(tmp,tmp+nbCompo,0.);
8270       if(w[1]>=w[0])
8271         {
8272           for(int j=w[0];j<w[1];j++,srcPt+=nbCompo)
8273             {
8274               if(j>=0 && j<nbOfTuples)
8275                 std::transform(srcPt,srcPt+nbCompo,tmp,tmp,std::plus<int>());
8276               else
8277                 {
8278                   std::ostringstream oss; oss << "DataArrayInt::accumulatePerChunck : At rank #" << i << " the input index array points to id " << j << " should be in [0," << nbOfTuples << ") !";
8279                   throw INTERP_KERNEL::Exception(oss.str().c_str());
8280                 }
8281             }
8282         }
8283       else
8284         {
8285           std::ostringstream oss; oss << "DataArrayInt::accumulatePerChunck : At rank #" << i << " the input index array is not in ascendingly sorted.";
8286           throw INTERP_KERNEL::Exception(oss.str().c_str());
8287         }
8288     }
8289   ret->copyStringInfoFrom(*this);
8290   return ret.retn();
8291 }
8292
8293 /*!
8294  * Returns a new DataArrayInt by concatenating two given arrays, so that (1) the number
8295  * of tuples in the result array is <em> a1->getNumberOfTuples() + a2->getNumberOfTuples() -
8296  * offsetA2</em> and (2)
8297  * the number of component in the result array is same as that of each of given arrays.
8298  * First \a offsetA2 tuples of \a a2 are skipped and thus are missing from the result array.
8299  * Info on components is copied from the first of the given arrays. Number of components
8300  * in the given arrays must be the same.
8301  *  \param [in] a1 - an array to include in the result array.
8302  *  \param [in] a2 - another array to include in the result array.
8303  *  \param [in] offsetA2 - number of tuples of \a a2 to skip.
8304  *  \return DataArrayInt * - the new instance of DataArrayInt.
8305  *          The caller is to delete this result array using decrRef() as it is no more
8306  *          needed.
8307  *  \throw If either \a a1 or \a a2 is NULL.
8308  *  \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents().
8309  */
8310 DataArrayInt *DataArrayInt::Aggregate(const DataArrayInt *a1, const DataArrayInt *a2, int offsetA2)
8311 {
8312   if(!a1 || !a2)
8313     throw INTERP_KERNEL::Exception("DataArrayInt::Aggregate : input DataArrayInt instance is NULL !");
8314   int nbOfComp=a1->getNumberOfComponents();
8315   if(nbOfComp!=a2->getNumberOfComponents())
8316     throw INTERP_KERNEL::Exception("Nb of components mismatch for array Aggregation !");
8317   int nbOfTuple1=a1->getNumberOfTuples();
8318   int nbOfTuple2=a2->getNumberOfTuples();
8319   DataArrayInt *ret=DataArrayInt::New();
8320   ret->alloc(nbOfTuple1+nbOfTuple2-offsetA2,nbOfComp);
8321   int *pt=std::copy(a1->getConstPointer(),a1->getConstPointer()+nbOfTuple1*nbOfComp,ret->getPointer());
8322   std::copy(a2->getConstPointer()+offsetA2*nbOfComp,a2->getConstPointer()+nbOfTuple2*nbOfComp,pt);
8323   ret->copyStringInfoFrom(*a1);
8324   return ret;
8325 }
8326
8327 /*!
8328  * Returns a new DataArrayInt by concatenating all given arrays, so that (1) the number
8329  * of tuples in the result array is a sum of the number of tuples of given arrays and (2)
8330  * the number of component in the result array is same as that of each of given arrays.
8331  * Info on components is copied from the first of the given arrays. Number of components
8332  * in the given arrays must be  the same.
8333  *  \param [in] arr - a sequence of arrays to include in the result array.
8334  *  \return DataArrayInt * - the new instance of DataArrayInt.
8335  *          The caller is to delete this result array using decrRef() as it is no more
8336  *          needed.
8337  *  \throw If all arrays within \a arr are NULL.
8338  *  \throw If getNumberOfComponents() of arrays within \a arr.
8339  */
8340 DataArrayInt *DataArrayInt::Aggregate(const std::vector<const DataArrayInt *>& arr) throw(INTERP_KERNEL::Exception)
8341 {
8342   std::vector<const DataArrayInt *> a;
8343   for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
8344     if(*it4)
8345       a.push_back(*it4);
8346   if(a.empty())
8347     throw INTERP_KERNEL::Exception("DataArrayInt::Aggregate : input list must be NON EMPTY !");
8348   std::vector<const DataArrayInt *>::const_iterator it=a.begin();
8349   int nbOfComp=(*it)->getNumberOfComponents();
8350   int nbt=(*it++)->getNumberOfTuples();
8351   for(int i=1;it!=a.end();it++,i++)
8352     {
8353       if((*it)->getNumberOfComponents()!=nbOfComp)
8354         throw INTERP_KERNEL::Exception("DataArrayInt::Aggregate : Nb of components mismatch for array aggregation !");
8355       nbt+=(*it)->getNumberOfTuples();
8356     }
8357   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
8358   ret->alloc(nbt,nbOfComp);
8359   int *pt=ret->getPointer();
8360   for(it=a.begin();it!=a.end();it++)
8361     pt=std::copy((*it)->getConstPointer(),(*it)->getConstPointer()+(*it)->getNbOfElems(),pt);
8362   ret->copyStringInfoFrom(*(a[0]));
8363   return ret.retn();
8364 }
8365
8366 /*!
8367  * This method takes as input a list of DataArrayInt instances \a arrs that represent each a packed index arrays.
8368  * A packed index array is an allocated array with one component, and at least one tuple. The first element
8369  * of each array in \a arrs must be 0. Each array in \a arrs is expected to be increasingly monotonic.
8370  * 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.
8371  * 
8372  * \return DataArrayInt * - a new object to be managed by the caller.
8373  */
8374 DataArrayInt *DataArrayInt::AggregateIndexes(const std::vector<const DataArrayInt *>& arrs) throw(INTERP_KERNEL::Exception)
8375 {
8376   int retSz=1;
8377   for(std::vector<const DataArrayInt *>::const_iterator it4=arrs.begin();it4!=arrs.end();it4++)
8378     {
8379       if(*it4)
8380         {
8381           (*it4)->checkAllocated();
8382           if((*it4)->getNumberOfComponents()!=1)
8383             {
8384               std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a DataArrayInt instance with nb of compo != 1 at pos " << std::distance(arrs.begin(),it4) << " !";
8385               throw INTERP_KERNEL::Exception(oss.str().c_str());
8386             }
8387           int nbTupl=(*it4)->getNumberOfTuples();
8388           if(nbTupl<1)
8389             {
8390               std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a DataArrayInt instance with nb of tuples < 1 at pos " << std::distance(arrs.begin(),it4) << " !";
8391               throw INTERP_KERNEL::Exception(oss.str().c_str());
8392             }
8393           if((*it4)->front()!=0)
8394             {
8395               std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a DataArrayInt instance with front value != 0 at pos " << std::distance(arrs.begin(),it4) << " !";
8396               throw INTERP_KERNEL::Exception(oss.str().c_str());
8397             }
8398           retSz+=nbTupl-1;
8399         }
8400       else
8401         {
8402           std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a null instance at pos " << std::distance(arrs.begin(),it4) << " !";
8403           throw INTERP_KERNEL::Exception(oss.str().c_str());
8404         }
8405     }
8406   if(arrs.empty())
8407     throw INTERP_KERNEL::Exception("DataArrayInt::AggregateIndexes : input list must be NON EMPTY !");
8408   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
8409   ret->alloc(retSz,1);
8410   int *pt=ret->getPointer(); *pt++=0;
8411   for(std::vector<const DataArrayInt *>::const_iterator it=arrs.begin();it!=arrs.end();it++)
8412     pt=std::transform((*it)->begin()+1,(*it)->end(),pt,std::bind2nd(std::plus<int>(),pt[-1]));
8413   ret->copyStringInfoFrom(*(arrs[0]));
8414   return ret.retn();
8415 }
8416
8417 /*!
8418  * Returns the maximal value and its location within \a this one-dimensional array.
8419  *  \param [out] tupleId - index of the tuple holding the maximal value.
8420  *  \return int - the maximal value among all values of \a this array.
8421  *  \throw If \a this->getNumberOfComponents() != 1
8422  *  \throw If \a this->getNumberOfTuples() < 1
8423  */
8424 int DataArrayInt::getMaxValue(int& tupleId) const throw(INTERP_KERNEL::Exception)
8425 {
8426   checkAllocated();
8427   if(getNumberOfComponents()!=1)
8428     throw INTERP_KERNEL::Exception("DataArrayInt::getMaxValue : must be applied on DataArrayInt with only one component !");
8429   int nbOfTuples=getNumberOfTuples();
8430   if(nbOfTuples<=0)
8431     throw INTERP_KERNEL::Exception("DataArrayInt::getMaxValue : array exists but number of tuples must be > 0 !");
8432   const int *vals=getConstPointer();
8433   const int *loc=std::max_element(vals,vals+nbOfTuples);
8434   tupleId=(int)std::distance(vals,loc);
8435   return *loc;
8436 }
8437
8438 /*!
8439  * Returns the maximal value within \a this array that is allowed to have more than
8440  *  one component.
8441  *  \return int - the maximal value among all values of \a this array.
8442  *  \throw If \a this is not allocated.
8443  */
8444 int DataArrayInt::getMaxValueInArray() const throw(INTERP_KERNEL::Exception)
8445 {
8446   checkAllocated();
8447   const int *loc=std::max_element(begin(),end());
8448   return *loc;
8449 }
8450
8451 /*!
8452  * Returns the minimal value and its location within \a this one-dimensional array.
8453  *  \param [out] tupleId - index of the tuple holding the minimal value.
8454  *  \return int - the minimal value among all values of \a this array.
8455  *  \throw If \a this->getNumberOfComponents() != 1
8456  *  \throw If \a this->getNumberOfTuples() < 1
8457  */
8458 int DataArrayInt::getMinValue(int& tupleId) const throw(INTERP_KERNEL::Exception)
8459 {
8460   checkAllocated();
8461   if(getNumberOfComponents()!=1)
8462     throw INTERP_KERNEL::Exception("DataArrayInt::getMaxValue : must be applied on DataArrayInt with only one component !");
8463   int nbOfTuples=getNumberOfTuples();
8464   if(nbOfTuples<=0)
8465     throw INTERP_KERNEL::Exception("DataArrayInt::getMaxValue : array exists but number of tuples must be > 0 !");
8466   const int *vals=getConstPointer();
8467   const int *loc=std::min_element(vals,vals+nbOfTuples);
8468   tupleId=(int)std::distance(vals,loc);
8469   return *loc;
8470 }
8471
8472 /*!
8473  * Returns the minimal value within \a this array that is allowed to have more than
8474  *  one component.
8475  *  \return int - the minimal value among all values of \a this array.
8476  *  \throw If \a this is not allocated.
8477  */
8478 int DataArrayInt::getMinValueInArray() const throw(INTERP_KERNEL::Exception)
8479 {
8480   checkAllocated();
8481   const int *loc=std::min_element(begin(),end());
8482   return *loc;
8483 }
8484
8485 /*!
8486  * Converts every value of \a this array to its absolute value.
8487  *  \throw If \a this is not allocated.
8488  */
8489 void DataArrayInt::abs() throw(INTERP_KERNEL::Exception)
8490 {
8491   checkAllocated();
8492   int *ptr=getPointer();
8493   std::size_t nbOfElems=getNbOfElems();
8494   std::transform(ptr,ptr+nbOfElems,ptr,std::ptr_fun<int,int>(std::abs));
8495   declareAsNew();
8496 }
8497
8498 /*!
8499  * Apply a liner function to a given component of \a this array, so that
8500  * an array element <em>(x)</em> becomes \f$ a * x + b \f$.
8501  *  \param [in] a - the first coefficient of the function.
8502  *  \param [in] b - the second coefficient of the function.
8503  *  \param [in] compoId - the index of component to modify.
8504  *  \throw If \a this is not allocated.
8505  */
8506 void DataArrayInt::applyLin(int a, int b, int compoId) throw(INTERP_KERNEL::Exception)
8507 {
8508   checkAllocated();
8509   int *ptr=getPointer()+compoId;
8510   int nbOfComp=getNumberOfComponents();
8511   int nbOfTuple=getNumberOfTuples();
8512   for(int i=0;i<nbOfTuple;i++,ptr+=nbOfComp)
8513     *ptr=a*(*ptr)+b;
8514   declareAsNew();
8515 }
8516
8517 /*!
8518  * Apply a liner function to all elements of \a this array, so that
8519  * an element _x_ becomes \f$ a * x + b \f$.
8520  *  \param [in] a - the first coefficient of the function.
8521  *  \param [in] b - the second coefficient of the function.
8522  *  \throw If \a this is not allocated.
8523  */
8524 void DataArrayInt::applyLin(int a, int b) throw(INTERP_KERNEL::Exception)
8525 {
8526   checkAllocated();
8527   int *ptr=getPointer();
8528   std::size_t nbOfElems=getNbOfElems();
8529   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
8530     *ptr=a*(*ptr)+b;
8531   declareAsNew();
8532 }
8533
8534 /*!
8535  * Returns a full copy of \a this array except that sign of all elements is reversed.
8536  *  \return DataArrayInt * - the new instance of DataArrayInt containing the
8537  *          same number of tuples and component as \a this array.
8538  *          The caller is to delete this result array using decrRef() as it is no more
8539  *          needed.
8540  *  \throw If \a this is not allocated.
8541  */
8542 DataArrayInt *DataArrayInt::negate() const throw(INTERP_KERNEL::Exception)
8543 {
8544   checkAllocated();
8545   DataArrayInt *newArr=DataArrayInt::New();
8546   int nbOfTuples=getNumberOfTuples();
8547   int nbOfComp=getNumberOfComponents();
8548   newArr->alloc(nbOfTuples,nbOfComp);
8549   const int *cptr=getConstPointer();
8550   std::transform(cptr,cptr+nbOfTuples*nbOfComp,newArr->getPointer(),std::negate<int>());
8551   newArr->copyStringInfoFrom(*this);
8552   return newArr;
8553 }
8554
8555 /*!
8556  * Modify all elements of \a this array, so that
8557  * an element _x_ becomes \f$ numerator / x \f$.
8558  *  \warning If an exception is thrown because of presence of 0 element in \a this 
8559  *           array, all elements processed before detection of the zero element remain
8560  *           modified.
8561  *  \param [in] numerator - the numerator used to modify array elements.
8562  *  \throw If \a this is not allocated.
8563  *  \throw If there is an element equal to 0 in \a this array.
8564  */
8565 void DataArrayInt::applyInv(int numerator) throw(INTERP_KERNEL::Exception)
8566 {
8567   checkAllocated();
8568   int *ptr=getPointer();
8569   std::size_t nbOfElems=getNbOfElems();
8570   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
8571     {
8572       if(*ptr!=0)
8573         {
8574           *ptr=numerator/(*ptr);
8575         }
8576       else
8577         {
8578           std::ostringstream oss; oss << "DataArrayInt::applyInv : presence of null value in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
8579           oss << " !";
8580           throw INTERP_KERNEL::Exception(oss.str().c_str());
8581         }
8582     }
8583   declareAsNew();
8584 }
8585
8586 /*!
8587  * Modify all elements of \a this array, so that
8588  * an element _x_ becomes \f$ x / val \f$.
8589  *  \param [in] val - the denominator used to modify array elements.
8590  *  \throw If \a this is not allocated.
8591  *  \throw If \a val == 0.
8592  */
8593 void DataArrayInt::applyDivideBy(int val) throw(INTERP_KERNEL::Exception)
8594 {
8595   if(val==0)
8596     throw INTERP_KERNEL::Exception("DataArrayInt::applyDivideBy : Trying to divide by 0 !");
8597   checkAllocated();
8598   int *ptr=getPointer();
8599   std::size_t nbOfElems=getNbOfElems();
8600   std::transform(ptr,ptr+nbOfElems,ptr,std::bind2nd(std::divides<int>(),val));
8601   declareAsNew();
8602 }
8603
8604 /*!
8605  * Modify all elements of \a this array, so that
8606  * an element _x_ becomes  <em> x % val </em>.
8607  *  \param [in] val - the divisor used to modify array elements.
8608  *  \throw If \a this is not allocated.
8609  *  \throw If \a val <= 0.
8610  */
8611 void DataArrayInt::applyModulus(int val) throw(INTERP_KERNEL::Exception)
8612 {
8613   if(val<=0)
8614     throw INTERP_KERNEL::Exception("DataArrayInt::applyDivideBy : Trying to operate modulus on value <= 0 !");
8615   checkAllocated();
8616   int *ptr=getPointer();
8617   std::size_t nbOfElems=getNbOfElems();
8618   std::transform(ptr,ptr+nbOfElems,ptr,std::bind2nd(std::modulus<int>(),val));
8619   declareAsNew();
8620 }
8621
8622 /*!
8623  * This method works only on data array with one component.
8624  * This method returns a newly allocated array storing stored ascendantly tuple ids in \b this so that
8625  * this[*id] in [\b vmin,\b vmax)
8626  * 
8627  * \param [in] vmin begin of range. This value is included in range (included).
8628  * \param [in] vmax end of range. This value is \b not included in range (excluded).
8629  * \return a newly allocated data array that the caller should deal with.
8630  */
8631 DataArrayInt *DataArrayInt::getIdsInRange(int vmin, int vmax) const throw(INTERP_KERNEL::Exception)
8632 {
8633   checkAllocated();
8634   if(getNumberOfComponents()!=1)
8635     throw INTERP_KERNEL::Exception("DataArrayInt::getIdsInRange : this must have exactly one component !");
8636   const int *cptr=getConstPointer();
8637   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(0,1);
8638   int nbOfTuples=getNumberOfTuples();
8639   for(int i=0;i<nbOfTuples;i++,cptr++)
8640     if(*cptr>=vmin && *cptr<vmax)
8641       ret->pushBackSilent(i);
8642   return ret.retn();
8643 }
8644
8645 /*!
8646  * This method works only on data array with one component.
8647  * 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.
8648  * 
8649  * \param [in] vmin begin of range. This value is included in range (included).
8650  * \param [in] vmax end of range. This value is \b not included in range (excluded).
8651  * \return if all ids in \a this are so that (*this)[i]==i for all i in [ 0, \c this->getNumberOfTuples() ).
8652  */
8653 bool DataArrayInt::checkAllIdsInRange(int vmin, int vmax) const throw(INTERP_KERNEL::Exception)
8654 {
8655   checkAllocated();
8656   if(getNumberOfComponents()!=1)
8657     throw INTERP_KERNEL::Exception("DataArrayInt::checkAllIdsInRange : this must have exactly one component !");
8658   int nbOfTuples=getNumberOfTuples();
8659   bool ret=true;
8660   const int *cptr=getConstPointer();
8661   for(int i=0;i<nbOfTuples;i++,cptr++)
8662     {
8663       if(*cptr>=vmin && *cptr<vmax)
8664         { ret=ret && *cptr==i; }
8665       else
8666         {
8667           std::ostringstream oss; oss << "DataArrayInt::checkAllIdsInRange : tuple #" << i << " has value " << *cptr << " should be in [" << vmin << "," << vmax << ") !";
8668           throw INTERP_KERNEL::Exception(oss.str().c_str());
8669         }
8670     }
8671   return ret;
8672 }
8673
8674 /*!
8675  * Modify all elements of \a this array, so that
8676  * an element _x_ becomes <em> val % x </em>.
8677  *  \warning If an exception is thrown because of presence of an element <= 0 in \a this 
8678  *           array, all elements processed before detection of the zero element remain
8679  *           modified.
8680  *  \param [in] val - the divident used to modify array elements.
8681  *  \throw If \a this is not allocated.
8682  *  \throw If there is an element equal to or less than 0 in \a this array.
8683  */
8684 void DataArrayInt::applyRModulus(int val) throw(INTERP_KERNEL::Exception)
8685 {
8686   checkAllocated();
8687   int *ptr=getPointer();
8688   std::size_t nbOfElems=getNbOfElems();
8689   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
8690     {
8691       if(*ptr>0)
8692         {
8693           *ptr=val%(*ptr);
8694         }
8695       else
8696         {
8697           std::ostringstream oss; oss << "DataArrayInt::applyRModulus : presence of value <=0 in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
8698           oss << " !";
8699           throw INTERP_KERNEL::Exception(oss.str().c_str());
8700         }
8701     }
8702   declareAsNew();
8703 }
8704
8705 /*!
8706  * Modify all elements of \a this array, so that
8707  * an element _x_ becomes <em> val ^ x </em>.
8708  *  \param [in] val - the value used to apply pow on all array elements.
8709  *  \throw If \a this is not allocated.
8710  *  \throw If \a val < 0.
8711  */
8712 void DataArrayInt::applyPow(int val) throw(INTERP_KERNEL::Exception)
8713 {
8714   checkAllocated();
8715   if(val<0)
8716     throw INTERP_KERNEL::Exception("DataArrayInt::applyPow : input pow in < 0 !");
8717   int *ptr=getPointer();
8718   std::size_t nbOfElems=getNbOfElems();
8719   if(val==0)
8720     {
8721       std::fill(ptr,ptr+nbOfElems,1.);
8722       return ;
8723     }
8724   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
8725     {
8726       int tmp=1;
8727       for(int j=0;j<val;j++)
8728         tmp*=*ptr;
8729       *ptr=tmp;
8730     }
8731   declareAsNew();
8732 }
8733
8734 /*!
8735  * Modify all elements of \a this array, so that
8736  * an element _x_ becomes \f$ val ^ x \f$.
8737  *  \param [in] val - the value used to apply pow on all array elements.
8738  *  \throw If \a this is not allocated.
8739  *  \throw If there is an element < 0 in \a this array.
8740  *  \warning If an exception is thrown because of presence of 0 element in \a this 
8741  *           array, all elements processed before detection of the zero element remain
8742  *           modified.
8743  */
8744 void DataArrayInt::applyRPow(int val) throw(INTERP_KERNEL::Exception)
8745 {
8746   checkAllocated();
8747   int *ptr=getPointer();
8748   std::size_t nbOfElems=getNbOfElems();
8749   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
8750     {
8751       if(*ptr>=0)
8752         {
8753           int tmp=1;
8754           for(int j=0;j<*ptr;j++)
8755             tmp*=val;
8756           *ptr=tmp;
8757         }
8758       else
8759         {
8760           std::ostringstream oss; oss << "DataArrayInt::applyRPow : presence of negative value in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
8761           oss << " !";
8762           throw INTERP_KERNEL::Exception(oss.str().c_str());
8763         }
8764     }
8765   declareAsNew();
8766 }
8767
8768 /*!
8769  * Returns a new DataArrayInt by aggregating two given arrays, so that (1) the number
8770  * of components in the result array is a sum of the number of components of given arrays
8771  * and (2) the number of tuples in the result array is same as that of each of given
8772  * arrays. In other words the i-th tuple of result array includes all components of
8773  * i-th tuples of all given arrays.
8774  * Number of tuples in the given arrays must be the same.
8775  *  \param [in] a1 - an array to include in the result array.
8776  *  \param [in] a2 - another array to include in the result array.
8777  *  \return DataArrayInt * - the new instance of DataArrayInt.
8778  *          The caller is to delete this result array using decrRef() as it is no more
8779  *          needed.
8780  *  \throw If both \a a1 and \a a2 are NULL.
8781  *  \throw If any given array is not allocated.
8782  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
8783  */
8784 DataArrayInt *DataArrayInt::Meld(const DataArrayInt *a1, const DataArrayInt *a2) throw(INTERP_KERNEL::Exception)
8785 {
8786   std::vector<const DataArrayInt *> arr(2);
8787   arr[0]=a1; arr[1]=a2;
8788   return Meld(arr);
8789 }
8790
8791 /*!
8792  * Returns a new DataArrayInt by aggregating all given arrays, so that (1) the number
8793  * of components in the result array is a sum of the number of components of given arrays
8794  * and (2) the number of tuples in the result array is same as that of each of given
8795  * arrays. In other words the i-th tuple of result array includes all components of
8796  * i-th tuples of all given arrays.
8797  * Number of tuples in the given arrays must be  the same.
8798  *  \param [in] arr - a sequence of arrays to include in the result array.
8799  *  \return DataArrayInt * - the new instance of DataArrayInt.
8800  *          The caller is to delete this result array using decrRef() as it is no more
8801  *          needed.
8802  *  \throw If all arrays within \a arr are NULL.
8803  *  \throw If any given array is not allocated.
8804  *  \throw If getNumberOfTuples() of arrays within \a arr is different.
8805  */
8806 DataArrayInt *DataArrayInt::Meld(const std::vector<const DataArrayInt *>& arr) throw(INTERP_KERNEL::Exception)
8807 {
8808   std::vector<const DataArrayInt *> a;
8809   for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
8810     if(*it4)
8811       a.push_back(*it4);
8812   if(a.empty())
8813     throw INTERP_KERNEL::Exception("DataArrayInt::Meld : array must be NON empty !");
8814   std::vector<const DataArrayInt *>::const_iterator it;
8815   for(it=a.begin();it!=a.end();it++)
8816     (*it)->checkAllocated();
8817   it=a.begin();
8818   int nbOfTuples=(*it)->getNumberOfTuples();
8819   std::vector<int> nbc(a.size());
8820   std::vector<const int *> pts(a.size());
8821   nbc[0]=(*it)->getNumberOfComponents();
8822   pts[0]=(*it++)->getConstPointer();
8823   for(int i=1;it!=a.end();it++,i++)
8824     {
8825       if(nbOfTuples!=(*it)->getNumberOfTuples())
8826         throw INTERP_KERNEL::Exception("DataArrayInt::meld : mismatch of number of tuples !");
8827       nbc[i]=(*it)->getNumberOfComponents();
8828       pts[i]=(*it)->getConstPointer();
8829     }
8830   int totalNbOfComp=std::accumulate(nbc.begin(),nbc.end(),0);
8831   DataArrayInt *ret=DataArrayInt::New();
8832   ret->alloc(nbOfTuples,totalNbOfComp);
8833   int *retPtr=ret->getPointer();
8834   for(int i=0;i<nbOfTuples;i++)
8835     for(int j=0;j<(int)a.size();j++)
8836       {
8837         retPtr=std::copy(pts[j],pts[j]+nbc[j],retPtr);
8838         pts[j]+=nbc[j];
8839       }
8840   int k=0;
8841   for(int i=0;i<(int)a.size();i++)
8842     for(int j=0;j<nbc[i];j++,k++)
8843       ret->setInfoOnComponent(k,a[i]->getInfoOnComponent(j).c_str());
8844   return ret;
8845 }
8846
8847 /*!
8848  * Returns a new DataArrayInt which is a minimal partition of elements of \a groups.
8849  * The i-th item of the result array is an ID of a set of elements belonging to a
8850  * unique set of groups, which the i-th element is a part of. This set of elements
8851  * belonging to a unique set of groups is called \a family, so the result array contains
8852  * IDs of families each element belongs to.
8853  *
8854  * \b Example: if we have two groups of elements: \a group1 [0,4] and \a group2 [ 0,1,2 ],
8855  * then there are 3 families:
8856  * - \a family1 (with ID 1) contains element [0] belonging to ( \a group1 + \a group2 ),
8857  * - \a family2 (with ID 2) contains elements [4] belonging to ( \a group1 ),
8858  * - \a family3 (with ID 3) contains element [1,2] belonging to ( \a group2 ), <br>
8859  * and the result array contains IDs of families [ 1,3,3,0,2 ]. <br> Note a family ID 0 which
8860  * stands for the element #3 which is in none of groups.
8861  *
8862  *  \param [in] groups - sequence of groups of element IDs.
8863  *  \param [in] newNb - total number of elements; it must be more than max ID of element
8864  *         in \a groups.
8865  *  \param [out] fidsOfGroups - IDs of families the elements of each group belong to.
8866  *  \return DataArrayInt * - a new instance of DataArrayInt containing IDs of families
8867  *         each element with ID from range [0, \a newNb ) belongs to. The caller is to
8868  *         delete this array using decrRef() as it is no more needed.
8869  *  \throw If any element ID in \a groups violates condition ( 0 <= ID < \a newNb ).
8870  */
8871 DataArrayInt *DataArrayInt::MakePartition(const std::vector<const DataArrayInt *>& groups, int newNb, std::vector< std::vector<int> >& fidsOfGroups) throw(INTERP_KERNEL::Exception)
8872 {
8873   std::vector<const DataArrayInt *> groups2;
8874   for(std::vector<const DataArrayInt *>::const_iterator it4=groups.begin();it4!=groups.end();it4++)
8875     if(*it4)
8876       groups2.push_back(*it4);
8877   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
8878   ret->alloc(newNb,1);
8879   int *retPtr=ret->getPointer();
8880   std::fill(retPtr,retPtr+newNb,0);
8881   int fid=1;
8882   for(std::vector<const DataArrayInt *>::const_iterator iter=groups2.begin();iter!=groups2.end();iter++)
8883     {
8884       const int *ptr=(*iter)->getConstPointer();
8885       std::size_t nbOfElem=(*iter)->getNbOfElems();
8886       int sfid=fid;
8887       for(int j=0;j<sfid;j++)
8888         {
8889           bool found=false;
8890           for(std::size_t i=0;i<nbOfElem;i++)
8891             {
8892               if(ptr[i]>=0 && ptr[i]<newNb)
8893                 {
8894                   if(retPtr[ptr[i]]==j)
8895                     {
8896                       retPtr[ptr[i]]=fid;
8897                       found=true;
8898                     }
8899                 }
8900               else
8901                 {
8902                   std::ostringstream oss; oss << "DataArrayInt::MakePartition : In group \"" << (*iter)->getName() << "\" in tuple #" << i << " value = " << ptr[i] << " ! Should be in [0," << newNb;
8903                   oss << ") !";
8904                   throw INTERP_KERNEL::Exception(oss.str().c_str());
8905                 }
8906             }
8907           if(found)
8908             fid++;
8909         }
8910     }
8911   fidsOfGroups.clear();
8912   fidsOfGroups.resize(groups2.size());
8913   int grId=0;
8914   for(std::vector<const DataArrayInt *>::const_iterator iter=groups2.begin();iter!=groups2.end();iter++,grId++)
8915     {
8916       std::set<int> tmp;
8917       const int *ptr=(*iter)->getConstPointer();
8918       std::size_t nbOfElem=(*iter)->getNbOfElems();
8919       for(const int *p=ptr;p!=ptr+nbOfElem;p++)
8920         tmp.insert(retPtr[*p]);
8921       fidsOfGroups[grId].insert(fidsOfGroups[grId].end(),tmp.begin(),tmp.end());
8922     }
8923   return ret.retn();
8924 }
8925
8926 /*!
8927  * Returns a new DataArrayInt which contains all elements of given one-dimensional
8928  * arrays. The result array does not contain any duplicates and its values
8929  * are sorted in ascending order.
8930  *  \param [in] arr - sequence of DataArrayInt's to unite.
8931  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
8932  *         array using decrRef() as it is no more needed.
8933  *  \throw If any \a arr[i] is not allocated.
8934  *  \throw If \a arr[i]->getNumberOfComponents() != 1.
8935  */
8936 DataArrayInt *DataArrayInt::BuildUnion(const std::vector<const DataArrayInt *>& arr) throw(INTERP_KERNEL::Exception)
8937 {
8938   std::vector<const DataArrayInt *> a;
8939   for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
8940     if(*it4)
8941       a.push_back(*it4);
8942   for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
8943     {
8944       (*it)->checkAllocated();
8945       if((*it)->getNumberOfComponents()!=1)
8946         throw INTERP_KERNEL::Exception("DataArrayInt::BuildUnion : only single component allowed !");
8947     }
8948   //
8949   std::set<int> r;
8950   for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
8951     {
8952       const int *pt=(*it)->getConstPointer();
8953       int nbOfTuples=(*it)->getNumberOfTuples();
8954       r.insert(pt,pt+nbOfTuples);
8955     }
8956   DataArrayInt *ret=DataArrayInt::New();
8957   ret->alloc((int)r.size(),1);
8958   std::copy(r.begin(),r.end(),ret->getPointer());
8959   return ret;
8960 }
8961
8962 /*!
8963  * Returns a new DataArrayInt which contains elements present in each of given one-dimensional
8964  * arrays. The result array does not contain any duplicates and its values
8965  * are sorted in ascending order.
8966  *  \param [in] arr - sequence of DataArrayInt's to intersect.
8967  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
8968  *         array using decrRef() as it is no more needed.
8969  *  \throw If any \a arr[i] is not allocated.
8970  *  \throw If \a arr[i]->getNumberOfComponents() != 1.
8971  */
8972 DataArrayInt *DataArrayInt::BuildIntersection(const std::vector<const DataArrayInt *>& arr) throw(INTERP_KERNEL::Exception)
8973 {
8974   std::vector<const DataArrayInt *> a;
8975   for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
8976     if(*it4)
8977       a.push_back(*it4);
8978   for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
8979     {
8980       (*it)->checkAllocated();
8981       if((*it)->getNumberOfComponents()!=1)
8982         throw INTERP_KERNEL::Exception("DataArrayInt::BuildIntersection : only single component allowed !");
8983     }
8984   //
8985   std::set<int> r;
8986   for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
8987     {
8988       const int *pt=(*it)->getConstPointer();
8989       int nbOfTuples=(*it)->getNumberOfTuples();
8990       std::set<int> s1(pt,pt+nbOfTuples);
8991       if(it!=a.begin())
8992         {
8993           std::set<int> r2;
8994           std::set_intersection(r.begin(),r.end(),s1.begin(),s1.end(),inserter(r2,r2.end()));
8995           r=r2;
8996         }
8997       else
8998         r=s1;
8999     }
9000   DataArrayInt *ret=DataArrayInt::New();
9001   ret->alloc((int)r.size(),1);
9002   std::copy(r.begin(),r.end(),ret->getPointer());
9003   return ret;
9004 }
9005
9006 /*!
9007  * Returns a new DataArrayInt which contains a complement of elements of \a this
9008  * one-dimensional array. I.e. the result array contains all elements from the range [0,
9009  * \a nbOfElement) not present in \a this array.
9010  *  \param [in] nbOfElement - maximal size of the result array.
9011  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
9012  *         array using decrRef() as it is no more needed.
9013  *  \throw If \a this is not allocated.
9014  *  \throw If \a this->getNumberOfComponents() != 1.
9015  *  \throw If any element \a x of \a this array violates condition ( 0 <= \a x < \a
9016  *         nbOfElement ).
9017  */
9018 DataArrayInt *DataArrayInt::buildComplement(int nbOfElement) const throw(INTERP_KERNEL::Exception)
9019 {
9020    checkAllocated();
9021    if(getNumberOfComponents()!=1)
9022      throw INTERP_KERNEL::Exception("DataArrayInt::buildComplement : only single component allowed !");
9023    std::vector<bool> tmp(nbOfElement);
9024    const int *pt=getConstPointer();
9025    int nbOfTuples=getNumberOfTuples();
9026    for(const int *w=pt;w!=pt+nbOfTuples;w++)
9027      if(*w>=0 && *w<nbOfElement)
9028        tmp[*w]=true;
9029      else
9030        throw INTERP_KERNEL::Exception("DataArrayInt::buildComplement : an element is not in valid range : [0,nbOfElement) !");
9031    int nbOfRetVal=(int)std::count(tmp.begin(),tmp.end(),false);
9032    DataArrayInt *ret=DataArrayInt::New();
9033    ret->alloc(nbOfRetVal,1);
9034    int j=0;
9035    int *retPtr=ret->getPointer();
9036    for(int i=0;i<nbOfElement;i++)
9037      if(!tmp[i])
9038        retPtr[j++]=i;
9039    return ret;
9040 }
9041
9042 /*!
9043  * Returns a new DataArrayInt containing elements of \a this one-dimensional missing
9044  * from an \a other one-dimensional array.
9045  *  \param [in] other - a DataArrayInt containing elements not to include in the result array.
9046  *  \return DataArrayInt * - a new instance of DataArrayInt with one component. The
9047  *         caller is to delete this array using decrRef() as it is no more needed.
9048  *  \throw If \a other is NULL.
9049  *  \throw If \a other is not allocated.
9050  *  \throw If \a other->getNumberOfComponents() != 1.
9051  *  \throw If \a this is not allocated.
9052  *  \throw If \a this->getNumberOfComponents() != 1.
9053  *  \sa DataArrayInt::buildSubstractionOptimized()
9054  */
9055 DataArrayInt *DataArrayInt::buildSubstraction(const DataArrayInt *other) const throw(INTERP_KERNEL::Exception)
9056 {
9057   if(!other)
9058     throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstraction : DataArrayInt pointer in input is NULL !");
9059   checkAllocated();
9060   other->checkAllocated();
9061   if(getNumberOfComponents()!=1)
9062      throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstraction : only single component allowed !");
9063   if(other->getNumberOfComponents()!=1)
9064      throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstraction : only single component allowed for other type !");
9065   const int *pt=getConstPointer();
9066   int nbOfTuples=getNumberOfTuples();
9067   std::set<int> s1(pt,pt+nbOfTuples);
9068   pt=other->getConstPointer();
9069   nbOfTuples=other->getNumberOfTuples();
9070   std::set<int> s2(pt,pt+nbOfTuples);
9071   std::vector<int> r;
9072   std::set_difference(s1.begin(),s1.end(),s2.begin(),s2.end(),std::back_insert_iterator< std::vector<int> >(r));
9073   DataArrayInt *ret=DataArrayInt::New();
9074   ret->alloc((int)r.size(),1);
9075   std::copy(r.begin(),r.end(),ret->getPointer());
9076   return ret;
9077 }
9078
9079 /*!
9080  * \a this is expected to have one component and to be sorted ascendingly (as for \a other).
9081  * \a other is expected to be a part of \a this. If not DataArrayInt::buildSubstraction should be called instead.
9082  * 
9083  * \param [in] other an array with one component and expected to be sorted ascendingly.
9084  * \ret list of ids in \a this but not in \a other.
9085  * \sa DataArrayInt::buildSubstraction
9086  */
9087 DataArrayInt *DataArrayInt::buildSubstractionOptimized(const DataArrayInt *other) const throw(INTERP_KERNEL::Exception)
9088 {
9089   static const char *MSG="DataArrayInt::buildSubstractionOptimized : only single component allowed !";
9090   if(!other) throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstractionOptimized : NULL input array !");
9091   checkAllocated(); other->checkAllocated();
9092   if(getNumberOfComponents()!=1) throw INTERP_KERNEL::Exception(MSG);
9093   if(other->getNumberOfComponents()!=1) throw INTERP_KERNEL::Exception(MSG);
9094   const int *pt1Bg(begin()),*pt1End(end()),*pt2Bg(other->begin()),*pt2End(other->end()),*work1(pt1Bg),*work2(pt2Bg);
9095   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
9096   for(;work1!=pt1End;work1++)
9097     {
9098       if(work2!=pt2End && *work1==*work2)
9099         work2++;
9100       else
9101         ret->pushBackSilent(*work1);
9102     }
9103   return ret.retn();
9104 }
9105
9106
9107 /*!
9108  * Returns a new DataArrayInt which contains all elements of \a this and a given
9109  * one-dimensional arrays. The result array does not contain any duplicates
9110  * and its values are sorted in ascending order.
9111  *  \param [in] other - an array to unite with \a this one.
9112  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
9113  *         array using decrRef() as it is no more needed.
9114  *  \throw If \a this or \a other is not allocated.
9115  *  \throw If \a this->getNumberOfComponents() != 1.
9116  *  \throw If \a other->getNumberOfComponents() != 1.
9117  */
9118 DataArrayInt *DataArrayInt::buildUnion(const DataArrayInt *other) const throw(INTERP_KERNEL::Exception)
9119 {
9120   std::vector<const DataArrayInt *>arrs(2);
9121   arrs[0]=this; arrs[1]=other;
9122   return BuildUnion(arrs);
9123 }
9124
9125
9126 /*!
9127  * Returns a new DataArrayInt which contains elements present in both \a this and a given
9128  * one-dimensional arrays. The result array does not contain any duplicates
9129  * and its values are sorted in ascending order.
9130  *  \param [in] other - an array to intersect with \a this one.
9131  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
9132  *         array using decrRef() as it is no more needed.
9133  *  \throw If \a this or \a other is not allocated.
9134  *  \throw If \a this->getNumberOfComponents() != 1.
9135  *  \throw If \a other->getNumberOfComponents() != 1.
9136  */
9137 DataArrayInt *DataArrayInt::buildIntersection(const DataArrayInt *other) const throw(INTERP_KERNEL::Exception)
9138 {
9139   std::vector<const DataArrayInt *>arrs(2);
9140   arrs[0]=this; arrs[1]=other;
9141   return BuildIntersection(arrs);
9142 }
9143
9144 /*!
9145  * This method can be applied on allocated with one component DataArrayInt instance.
9146  * This method is typically relevant for sorted arrays. All consecutive duplicated items in \a this will appear only once in returned DataArrayInt instance.
9147  * 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]
9148  * 
9149  * \return a newly allocated array that contain the result of the unique operation applied on \a this.
9150  * \throw if \a this is not allocated or if \a this has not exactly one component.
9151  */
9152 DataArrayInt *DataArrayInt::buildUnique() const throw(INTERP_KERNEL::Exception)
9153 {
9154   checkAllocated();
9155   if(getNumberOfComponents()!=1)
9156      throw INTERP_KERNEL::Exception("DataArrayInt::buildUnique : only single component allowed !");
9157   int nbOfTuples=getNumberOfTuples();
9158   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp=deepCpy();
9159   int *data=tmp->getPointer();
9160   int *last=std::unique(data,data+nbOfTuples);
9161   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
9162   ret->alloc(std::distance(data,last),1);
9163   std::copy(data,last,ret->getPointer());
9164   return ret.retn();
9165 }
9166
9167 /*!
9168  * Returns a new DataArrayInt which contains size of every of groups described by \a this
9169  * "index" array. Such "index" array is returned for example by 
9170  * \ref ParaMEDMEM::MEDCouplingUMesh::buildDescendingConnectivity
9171  * "MEDCouplingUMesh::buildDescendingConnectivity" and
9172  * \ref ParaMEDMEM::MEDCouplingUMesh::getNodalConnectivityIndex
9173  * "MEDCouplingUMesh::getNodalConnectivityIndex" etc.
9174  * This method preforms the reverse operation of DataArrayInt::computeOffsets2.
9175  *  \return DataArrayInt * - a new instance of DataArrayInt, whose number of tuples
9176  *          equals to \a this->getNumberOfComponents() - 1, and number of components is 1.
9177  *          The caller is to delete this array using decrRef() as it is no more needed. 
9178  *  \throw If \a this is not allocated.
9179  *  \throw If \a this->getNumberOfComponents() != 1.
9180  *  \throw If \a this->getNumberOfTuples() < 2.
9181  *
9182  *  \b Example: <br> 
9183  *         - this contains [1,3,6,7,7,9,15]
9184  *         - result array contains [2,3,1,0,2,6],
9185  *          where 2 = 3 - 1, 3 = 6 - 3, 1 = 7 - 6 etc.
9186  *
9187  * \sa DataArrayInt::computeOffsets2
9188  */
9189 DataArrayInt *DataArrayInt::deltaShiftIndex() const throw(INTERP_KERNEL::Exception)
9190 {
9191   checkAllocated();
9192   if(getNumberOfComponents()!=1)
9193      throw INTERP_KERNEL::Exception("DataArrayInt::deltaShiftIndex : only single component allowed !");
9194   int nbOfTuples=getNumberOfTuples();
9195   if(nbOfTuples<2)
9196     throw INTERP_KERNEL::Exception("DataArrayInt::deltaShiftIndex : 1 tuple at least must be present in 'this' !");
9197   const int *ptr=getConstPointer();
9198   DataArrayInt *ret=DataArrayInt::New();
9199   ret->alloc(nbOfTuples-1,1);
9200   int *out=ret->getPointer();
9201   std::transform(ptr+1,ptr+nbOfTuples,ptr,out,std::minus<int>());
9202   return ret;
9203 }
9204
9205 /*!
9206  * Modifies \a this one-dimensional array so that value of each element \a x
9207  * of \a this array (\a a) is computed as \f$ x_i = \sum_{j=0}^{i-1} a[ j ] \f$.
9208  * Or: for each i>0 new[i]=new[i-1]+old[i-1] for i==0 new[i]=0. Number of tuples
9209  * and components remains the same.<br>
9210  * This method is useful for allToAllV in MPI with contiguous policy. This method
9211  * differs from computeOffsets2() in that the number of tuples is \b not changed by
9212  * this one.
9213  *  \throw If \a this is not allocated.
9214  *  \throw If \a this->getNumberOfComponents() != 1.
9215  *
9216  *  \b Example: <br>
9217  *          - Before \a this contains [3,5,1,2,0,8]
9218  *          - After \a this contains  [0,3,8,9,11,11]<br>
9219  *          Note that the last element 19 = 11 + 8 is missing because size of \a this
9220  *          array is retained and thus there is no space to store the last element.
9221  */
9222 void DataArrayInt::computeOffsets() throw(INTERP_KERNEL::Exception)
9223 {
9224   checkAllocated();
9225   if(getNumberOfComponents()!=1)
9226      throw INTERP_KERNEL::Exception("DataArrayInt::computeOffsets : only single component allowed !");
9227   int nbOfTuples=getNumberOfTuples();
9228   if(nbOfTuples==0)
9229     return ;
9230   int *work=getPointer();
9231   int tmp=work[0];
9232   work[0]=0;
9233   for(int i=1;i<nbOfTuples;i++)
9234     {
9235       int tmp2=work[i];
9236       work[i]=work[i-1]+tmp;
9237       tmp=tmp2;
9238     }
9239   declareAsNew();
9240 }
9241
9242
9243 /*!
9244  * Modifies \a this one-dimensional array so that value of each element \a x
9245  * of \a this array (\a a) is computed as \f$ x_i = \sum_{j=0}^{i-1} a[ j ] \f$.
9246  * Or: for each i>0 new[i]=new[i-1]+old[i-1] for i==0 new[i]=0. Number
9247  * components remains the same and number of tuples is inceamented by one.<br>
9248  * This method is useful for allToAllV in MPI with contiguous policy. This method
9249  * differs from computeOffsets() in that the number of tuples is changed by this one.
9250  * This method preforms the reverse operation of DataArrayInt::deltaShiftIndex.
9251  *  \throw If \a this is not allocated.
9252  *  \throw If \a this->getNumberOfComponents() != 1.
9253  *
9254  *  \b Example: <br>
9255  *          - Before \a this contains [3,5,1,2,0,8]
9256  *          - After \a this contains  [0,3,8,9,11,11,19]<br>
9257  * \sa DataArrayInt::deltaShiftIndex
9258  */
9259 void DataArrayInt::computeOffsets2() throw(INTERP_KERNEL::Exception)
9260 {
9261   checkAllocated();
9262   if(getNumberOfComponents()!=1)
9263     throw INTERP_KERNEL::Exception("DataArrayInt::computeOffsets2 : only single component allowed !");
9264   int nbOfTuples=getNumberOfTuples();
9265   int *ret=(int *)malloc((nbOfTuples+1)*sizeof(int));
9266   if(nbOfTuples==0)
9267     return ;
9268   const int *work=getConstPointer();
9269   ret[0]=0;
9270   for(int i=0;i<nbOfTuples;i++)
9271     ret[i+1]=work[i]+ret[i];
9272   useArray(ret,true,C_DEALLOC,nbOfTuples+1,1);
9273   declareAsNew();
9274 }
9275
9276 /*!
9277  * Returns two new DataArrayInt instances whose contents is computed from that of \a this and \a listOfIds arrays as follows.
9278  * \a this is expected to be an offset format ( as returned by DataArrayInt::computeOffsets2 ) that is to say with one component
9279  * and ** sorted strictly increasingly **. \a listOfIds is expected to be sorted ascendingly (not strictly needed for \a listOfIds).
9280  * This methods searches in \a this, considered as a set of contiguous \c this->getNumberOfComponents() ranges, all ids in \a listOfIds
9281  * filling completely one of the ranges in \a this.
9282  *
9283  * \param [in] listOfIds a list of ids that has to be sorted ascendingly.
9284  * \param [out] rangeIdsFetched the range ids fetched
9285  * \param [out] idsInInputListThatFetch contains the list of ids in \a listOfIds that are \b fully included in a range in \a this. So
9286  *              \a idsInInputListThatFetch is a part of input \a listOfIds.
9287  *
9288  * \sa DataArrayInt::computeOffsets2
9289  *
9290  *  \b Example: <br>
9291  *          - \a this : [0,3,7,9,15,18]
9292  *          - \a listOfIds contains  [0,1,2,3,7,8,15,16,17]
9293  *          - \a rangeIdsFetched result array: [0,2,4]
9294  *          - \a idsInInputListThatFetch result array: [0,1,2,7,8,15,16,17]
9295  * In this example id 3 in input \a listOfIds is alone so it do not appear in output \a idsInInputListThatFetch.
9296  * <br>
9297  */
9298 void DataArrayInt::searchRangesInListOfIds(const DataArrayInt *listOfIds, DataArrayInt *& rangeIdsFetched, DataArrayInt *& idsInInputListThatFetch) const throw(INTERP_KERNEL::Exception)
9299 {
9300   if(!listOfIds)
9301     throw INTERP_KERNEL::Exception("DataArrayInt::searchRangesInListOfIds : input list of ids is null !");
9302   listOfIds->checkAllocated(); checkAllocated();
9303   if(listOfIds->getNumberOfComponents()!=1)
9304     throw INTERP_KERNEL::Exception("DataArrayInt::searchRangesInListOfIds : input list of ids must have exactly one component !");
9305   if(getNumberOfComponents()!=1)
9306     throw INTERP_KERNEL::Exception("DataArrayInt::searchRangesInListOfIds : this must have exactly one component !");
9307   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret0=DataArrayInt::New(); ret0->alloc(0,1);
9308   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret1=DataArrayInt::New(); ret1->alloc(0,1);
9309   const int *tupEnd(listOfIds->end()),*offBg(begin()),*offEnd(end()-1);
9310   const int *tupPtr(listOfIds->begin()),*offPtr(offBg);
9311   while(tupPtr!=tupEnd && offPtr!=offEnd)
9312     {
9313       if(*tupPtr==*offPtr)
9314         {
9315           int i=offPtr[0];
9316           while(i<offPtr[1] && *tupPtr==i && tupPtr!=tupEnd) { i++; tupPtr++; }
9317           if(i==offPtr[1])
9318             {
9319               ret0->pushBackSilent((int)std::distance(offBg,offPtr));
9320               ret1->pushBackValsSilent(tupPtr-(offPtr[1]-offPtr[0]),tupPtr);
9321               offPtr++;
9322             }
9323         }
9324       else
9325         { if(*tupPtr<*offPtr) tupPtr++; else offPtr++; }
9326     }
9327   rangeIdsFetched=ret0.retn();
9328   idsInInputListThatFetch=ret1.retn();
9329 }
9330
9331 /*!
9332  * Returns a new DataArrayInt whose contents is computed from that of \a this and \a
9333  * offsets arrays as follows. \a offsets is a one-dimensional array considered as an
9334  * "index" array of a "iota" array, thus, whose each element gives an index of a group
9335  * beginning within the "iota" array. And \a this is a one-dimensional array
9336  * considered as a selector of groups described by \a offsets to include into the result array.
9337  *  \throw If \a offsets is NULL.
9338  *  \throw If \a offsets is not allocated.
9339  *  \throw If \a offsets->getNumberOfComponents() != 1.
9340  *  \throw If \a offsets is not monotonically increasing.
9341  *  \throw If \a this is not allocated.
9342  *  \throw If \a this->getNumberOfComponents() != 1.
9343  *  \throw If any element of \a this is not a valid index for \a offsets array.
9344  *
9345  *  \b Example: <br>
9346  *          - \a this: [0,2,3]
9347  *          - \a offsets: [0,3,6,10,14,20]
9348  *          - result array: [0,1,2,6,7,8,9,10,11,12,13] == <br>
9349  *            \c range(0,3) + \c range(6,10) + \c range(10,14) ==<br>
9350  *            \c range( \a offsets[ \a this[0] ], offsets[ \a this[0]+1 ]) + 
9351  *            \c range( \a offsets[ \a this[1] ], offsets[ \a this[1]+1 ]) + 
9352  *            \c range( \a offsets[ \a this[2] ], offsets[ \a this[2]+1 ])
9353  */
9354 DataArrayInt *DataArrayInt::buildExplicitArrByRanges(const DataArrayInt *offsets) const throw(INTERP_KERNEL::Exception)
9355 {
9356   if(!offsets)
9357     throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrByRanges : DataArrayInt pointer in input is NULL !");
9358   checkAllocated();
9359   if(getNumberOfComponents()!=1)
9360      throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrByRanges : only single component allowed !");
9361   offsets->checkAllocated();
9362   if(offsets->getNumberOfComponents()!=1)
9363      throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrByRanges : input array should have only single component !");
9364   int othNbTuples=offsets->getNumberOfTuples()-1;
9365   int nbOfTuples=getNumberOfTuples();
9366   int retNbOftuples=0;
9367   const int *work=getConstPointer();
9368   const int *offPtr=offsets->getConstPointer();
9369   for(int i=0;i<nbOfTuples;i++)
9370     {
9371       int val=work[i];
9372       if(val>=0 && val<othNbTuples)
9373         {
9374           int delta=offPtr[val+1]-offPtr[val];
9375           if(delta>=0)
9376             retNbOftuples+=delta;
9377           else
9378             {
9379               std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrByRanges : Tuple #" << val << " of offset array has a delta < 0 !";
9380               throw INTERP_KERNEL::Exception(oss.str().c_str());
9381             }
9382         }
9383       else
9384         {
9385           std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrByRanges : Tuple #" << i << " in this contains " << val;
9386           oss << " whereas offsets array is of size " << othNbTuples+1 << " !";
9387           throw INTERP_KERNEL::Exception(oss.str().c_str());
9388         }
9389     }
9390   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
9391   ret->alloc(retNbOftuples,1);
9392   int *retPtr=ret->getPointer();
9393   for(int i=0;i<nbOfTuples;i++)
9394     {
9395       int val=work[i];
9396       int start=offPtr[val];
9397       int off=offPtr[val+1]-start;
9398       for(int j=0;j<off;j++,retPtr++)
9399         *retPtr=start+j;
9400     }
9401   return ret.retn();
9402 }
9403
9404 /*!
9405  * 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.
9406  * 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
9407  * in tuple **i** of returned DataArrayInt.
9408  * If ranges overlapped (in theory it should not) this method do not detect it and always returns the first range.
9409  *
9410  * 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)]
9411  * The return DataArrayInt will contain : **[0,4,1,2,2,3]**
9412  * 
9413  * \param [in] ranges typically come from output of MEDCouplingUMesh::ComputeRangesFromTypeDistribution. Each range is specified like this : 1st component is
9414  *             for lower value included and 2nd component is the upper value of corresponding range **excluded**.
9415  * \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
9416  *        is thrown if no ranges in \a ranges contains value in \a this.
9417  * 
9418  * \sa DataArrayInt::findIdInRangeForEachTuple
9419  */
9420 DataArrayInt *DataArrayInt::findRangeIdForEachTuple(const DataArrayInt *ranges) const throw(INTERP_KERNEL::Exception)
9421 {
9422   if(!ranges)
9423     throw INTERP_KERNEL::Exception("DataArrayInt::findRangeIdForEachTuple : null input pointer !");
9424   if(ranges->getNumberOfComponents()!=2)
9425     throw INTERP_KERNEL::Exception("DataArrayInt::findRangeIdForEachTuple : input DataArrayInt instance should have 2 components !");
9426   checkAllocated();
9427   if(getNumberOfComponents()!=1)
9428     throw INTERP_KERNEL::Exception("DataArrayInt::findRangeIdForEachTuple : this should have only one component !");
9429   int nbTuples=getNumberOfTuples();
9430   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbTuples,1);
9431   int nbOfRanges=ranges->getNumberOfTuples();
9432   const int *rangesPtr=ranges->getConstPointer();
9433   int *retPtr=ret->getPointer();
9434   const int *inPtr=getConstPointer();
9435   for(int i=0;i<nbTuples;i++,retPtr++)
9436     {
9437       int val=inPtr[i];
9438       bool found=false;
9439       for(int j=0;j<nbOfRanges && !found;j++)
9440         if(val>=rangesPtr[2*j] && val<rangesPtr[2*j+1])
9441           { *retPtr=j; found=true; }
9442       if(found)
9443         continue;
9444       else
9445         {
9446           std::ostringstream oss; oss << "DataArrayInt::findRangeIdForEachTuple : tuple #" << i << " not found by any ranges !";
9447           throw INTERP_KERNEL::Exception(oss.str().c_str());
9448         }
9449     }
9450   return ret.retn();
9451 }
9452
9453 /*!
9454  * 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.
9455  * 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
9456  * in tuple **i** of returned DataArrayInt.
9457  * If ranges overlapped (in theory it should not) this method do not detect it and always returns the sub position of the first range.
9458  *
9459  * 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)]
9460  * The return DataArrayInt will contain : **[1,2,4,0,2,2]**
9461  * This method is often called in pair with DataArrayInt::findRangeIdForEachTuple method.
9462  * 
9463  * \param [in] ranges typically come from output of MEDCouplingUMesh::ComputeRangesFromTypeDistribution. Each range is specified like this : 1st component is
9464  *             for lower value included and 2nd component is the upper value of corresponding range **excluded**.
9465  * \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
9466  *        is thrown if no ranges in \a ranges contains value in \a this.
9467  * \sa DataArrayInt::findRangeIdForEachTuple
9468  */
9469 DataArrayInt *DataArrayInt::findIdInRangeForEachTuple(const DataArrayInt *ranges) const throw(INTERP_KERNEL::Exception)
9470 {
9471   if(!ranges)
9472     throw INTERP_KERNEL::Exception("DataArrayInt::findIdInRangeForEachTuple : null input pointer !");
9473   if(ranges->getNumberOfComponents()!=2)
9474     throw INTERP_KERNEL::Exception("DataArrayInt::findIdInRangeForEachTuple : input DataArrayInt instance should have 2 components !");
9475   checkAllocated();
9476   if(getNumberOfComponents()!=1)
9477     throw INTERP_KERNEL::Exception("DataArrayInt::findIdInRangeForEachTuple : this should have only one component !");
9478   int nbTuples=getNumberOfTuples();
9479   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbTuples,1);
9480   int nbOfRanges=ranges->getNumberOfTuples();
9481   const int *rangesPtr=ranges->getConstPointer();
9482   int *retPtr=ret->getPointer();
9483   const int *inPtr=getConstPointer();
9484   for(int i=0;i<nbTuples;i++,retPtr++)
9485     {
9486       int val=inPtr[i];
9487       bool found=false;
9488       for(int j=0;j<nbOfRanges && !found;j++)
9489         if(val>=rangesPtr[2*j] && val<rangesPtr[2*j+1])
9490           { *retPtr=val-rangesPtr[2*j]; found=true; }
9491       if(found)
9492         continue;
9493       else
9494         {
9495           std::ostringstream oss; oss << "DataArrayInt::findIdInRangeForEachTuple : tuple #" << i << " not found by any ranges !";
9496           throw INTERP_KERNEL::Exception(oss.str().c_str());
9497         }
9498     }
9499   return ret.retn();
9500 }
9501
9502 /*!
9503  * 
9504  * \param [in] nbTimes specifies the nb of times each tuples in \a this will be duplicated contiguouly in returned DataArrayInt instance.
9505  *             \a nbTimes  should be at least equal to 1.
9506  * \return a newly allocated DataArrayInt having one component and number of tuples equal to \a nbTimes * \c this->getNumberOfTuples.
9507  * \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.
9508  */
9509 DataArrayInt *DataArrayInt::duplicateEachTupleNTimes(int nbTimes) const throw(INTERP_KERNEL::Exception)
9510 {
9511   checkAllocated();
9512   if(getNumberOfComponents()!=1)
9513     throw INTERP_KERNEL::Exception("DataArrayInt::duplicateEachTupleNTimes : this should have only one component !");
9514   if(nbTimes<1)
9515     throw INTERP_KERNEL::Exception("DataArrayInt::duplicateEachTupleNTimes : nb times should be >= 1 !");
9516   int nbTuples=getNumberOfTuples();
9517   const int *inPtr=getConstPointer();
9518   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbTimes*nbTuples,1);
9519   int *retPtr=ret->getPointer();
9520   for(int i=0;i<nbTuples;i++,inPtr++)
9521     {
9522       int val=*inPtr;
9523       for(int j=0;j<nbTimes;j++,retPtr++)
9524         *retPtr=val;
9525     }
9526   ret->copyStringInfoFrom(*this);
9527   return ret.retn();
9528 }
9529
9530 /*!
9531  * This method returns all different values found in \a this. This method throws if \a this has not been allocated.
9532  * But the number of components can be different from one.
9533  * \return a newly allocated array (that should be dealt by the caller) containing different values in \a this.
9534  */
9535 DataArrayInt *DataArrayInt::getDifferentValues() const throw(INTERP_KERNEL::Exception)
9536 {
9537   checkAllocated();
9538   std::set<int> ret;
9539   ret.insert(begin(),end());
9540   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret2=DataArrayInt::New(); ret2->alloc((int)ret.size(),1);
9541   std::copy(ret.begin(),ret.end(),ret2->getPointer());
9542   return ret2.retn();
9543 }
9544
9545 /*!
9546  * This method is a refinement of DataArrayInt::getDifferentValues because it returns not only different values in \a this but also, for each of
9547  * them it tells which tuple id have this id.
9548  * This method works only on arrays with one component (if it is not the case call DataArrayInt::rearrange(1) ).
9549  * This method returns two arrays having same size.
9550  * 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.
9551  * 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]]
9552  */
9553 std::vector<DataArrayInt *> DataArrayInt::partitionByDifferentValues(std::vector<int>& differentIds) const throw(INTERP_KERNEL::Exception)
9554 {
9555   checkAllocated();
9556   if(getNumberOfComponents()!=1)
9557     throw INTERP_KERNEL::Exception("DataArrayInt::partitionByDifferentValues : this should have only one component !");
9558   int id=0;
9559   std::map<int,int> m,m2,m3;
9560   for(const int *w=begin();w!=end();w++)
9561     m[*w]++;
9562   differentIds.resize(m.size());
9563   std::vector<DataArrayInt *> ret(m.size());
9564   std::vector<int *> retPtr(m.size());
9565   for(std::map<int,int>::const_iterator it=m.begin();it!=m.end();it++,id++)
9566     {
9567       m2[(*it).first]=id;
9568       ret[id]=DataArrayInt::New();
9569       ret[id]->alloc((*it).second,1);
9570       retPtr[id]=ret[id]->getPointer();
9571       differentIds[id]=(*it).first;
9572     }
9573   id=0;
9574   for(const int *w=begin();w!=end();w++,id++)
9575     {
9576       retPtr[m2[*w]][m3[*w]++]=id;
9577     }
9578   return ret;
9579 }
9580
9581 /*!
9582  * Returns a new DataArrayInt that is a sum of two given arrays. There are 3
9583  * valid cases.
9584  * 1.  The arrays have same number of tuples and components. Then each value of
9585  *   the result array (_a_) is a sum of the corresponding values of \a a1 and \a a2,
9586  *   i.e.: _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ i, j ].
9587  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
9588  *   component. Then
9589  *   _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ i, 0 ].
9590  * 3.  The arrays have same number of components and one array, say _a2_, has one
9591  *   tuple. Then
9592  *   _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ 0, j ].
9593  *
9594  * Info on components is copied either from the first array (in the first case) or from
9595  * the array with maximal number of elements (getNbOfElems()).
9596  *  \param [in] a1 - an array to sum up.
9597  *  \param [in] a2 - another array to sum up.
9598  *  \return DataArrayInt * - the new instance of DataArrayInt.
9599  *          The caller is to delete this result array using decrRef() as it is no more
9600  *          needed.
9601  *  \throw If either \a a1 or \a a2 is NULL.
9602  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
9603  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
9604  *         none of them has number of tuples or components equal to 1.
9605  */
9606 DataArrayInt *DataArrayInt::Add(const DataArrayInt *a1, const DataArrayInt *a2) throw(INTERP_KERNEL::Exception)
9607 {
9608   if(!a1 || !a2)
9609     throw INTERP_KERNEL::Exception("DataArrayInt::Add : input DataArrayInt instance is NULL !");
9610   int nbOfTuple=a1->getNumberOfTuples();
9611   int nbOfTuple2=a2->getNumberOfTuples();
9612   int nbOfComp=a1->getNumberOfComponents();
9613   int nbOfComp2=a2->getNumberOfComponents();
9614   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=0;
9615   if(nbOfTuple==nbOfTuple2)
9616     {
9617       if(nbOfComp==nbOfComp2)
9618         {
9619           ret=DataArrayInt::New();
9620           ret->alloc(nbOfTuple,nbOfComp);
9621           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::plus<int>());
9622           ret->copyStringInfoFrom(*a1);
9623         }
9624       else
9625         {
9626           int nbOfCompMin,nbOfCompMax;
9627           const DataArrayInt *aMin, *aMax;
9628           if(nbOfComp>nbOfComp2)
9629             {
9630               nbOfCompMin=nbOfComp2; nbOfCompMax=nbOfComp;
9631               aMin=a2; aMax=a1;
9632             }
9633           else
9634             {
9635               nbOfCompMin=nbOfComp; nbOfCompMax=nbOfComp2;
9636               aMin=a1; aMax=a2;
9637             }
9638           if(nbOfCompMin==1)
9639             {
9640               ret=DataArrayInt::New();
9641               ret->alloc(nbOfTuple,nbOfCompMax);
9642               const int *aMinPtr=aMin->getConstPointer();
9643               const int *aMaxPtr=aMax->getConstPointer();
9644               int *res=ret->getPointer();
9645               for(int i=0;i<nbOfTuple;i++)
9646                 res=std::transform(aMaxPtr+i*nbOfCompMax,aMaxPtr+(i+1)*nbOfCompMax,res,std::bind2nd(std::plus<int>(),aMinPtr[i]));
9647               ret->copyStringInfoFrom(*aMax);
9648             }
9649           else
9650             throw INTERP_KERNEL::Exception("Nb of components mismatch for array Add !");
9651         }
9652     }
9653   else if((nbOfTuple==1 && nbOfTuple2>1) || (nbOfTuple>1 && nbOfTuple2==1))
9654     {
9655       if(nbOfComp==nbOfComp2)
9656         {
9657           int nbOfTupleMax=std::max(nbOfTuple,nbOfTuple2);
9658           const DataArrayInt *aMin=nbOfTuple>nbOfTuple2?a2:a1;
9659           const DataArrayInt *aMax=nbOfTuple>nbOfTuple2?a1:a2;
9660           const int *aMinPtr=aMin->getConstPointer(),*aMaxPtr=aMax->getConstPointer();
9661           ret=DataArrayInt::New();
9662           ret->alloc(nbOfTupleMax,nbOfComp);
9663           int *res=ret->getPointer();
9664           for(int i=0;i<nbOfTupleMax;i++)
9665             res=std::transform(aMaxPtr+i*nbOfComp,aMaxPtr+(i+1)*nbOfComp,aMinPtr,res,std::plus<int>());
9666           ret->copyStringInfoFrom(*aMax);
9667         }
9668       else
9669         throw INTERP_KERNEL::Exception("Nb of components mismatch for array Add !");
9670     }
9671   else
9672     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Add !");
9673   return ret.retn();
9674 }
9675
9676 /*!
9677  * Adds values of another DataArrayInt to values of \a this one. There are 3
9678  * valid cases.
9679  * 1.  The arrays have same number of tuples and components. Then each value of
9680  *   \a other array is added to the corresponding value of \a this array, i.e.:
9681  *   _a_ [ i, j ] += _other_ [ i, j ].
9682  * 2.  The arrays have same number of tuples and \a other array has one component. Then
9683  *   _a_ [ i, j ] += _other_ [ i, 0 ].
9684  * 3.  The arrays have same number of components and \a other array has one tuple. Then
9685  *   _a_ [ i, j ] += _a2_ [ 0, j ].
9686  *
9687  *  \param [in] other - an array to add to \a this one.
9688  *  \throw If \a other is NULL.
9689  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
9690  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
9691  *         \a other has number of both tuples and components not equal to 1.
9692  */
9693 void DataArrayInt::addEqual(const DataArrayInt *other) throw(INTERP_KERNEL::Exception)
9694 {
9695   if(!other)
9696     throw INTERP_KERNEL::Exception("DataArrayInt::addEqual : input DataArrayInt instance is NULL !");
9697   const char *msg="Nb of tuples mismatch for DataArrayInt::addEqual  !";
9698   checkAllocated(); other->checkAllocated();
9699   int nbOfTuple=getNumberOfTuples();
9700   int nbOfTuple2=other->getNumberOfTuples();
9701   int nbOfComp=getNumberOfComponents();
9702   int nbOfComp2=other->getNumberOfComponents();
9703   if(nbOfTuple==nbOfTuple2)
9704     {
9705       if(nbOfComp==nbOfComp2)
9706         {
9707           std::transform(begin(),end(),other->begin(),getPointer(),std::plus<int>());
9708         }
9709       else if(nbOfComp2==1)
9710         {
9711           int *ptr=getPointer();
9712           const int *ptrc=other->getConstPointer();
9713           for(int i=0;i<nbOfTuple;i++)
9714             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::plus<int>(),*ptrc++));
9715         }
9716       else
9717         throw INTERP_KERNEL::Exception(msg);
9718     }
9719   else if(nbOfTuple2==1)
9720     {
9721       if(nbOfComp2==nbOfComp)
9722         {
9723           int *ptr=getPointer();
9724           const int *ptrc=other->getConstPointer();
9725           for(int i=0;i<nbOfTuple;i++)
9726             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::plus<int>());
9727         }
9728       else
9729         throw INTERP_KERNEL::Exception(msg);
9730     }
9731   else
9732     throw INTERP_KERNEL::Exception(msg);
9733   declareAsNew();
9734 }
9735
9736 /*!
9737  * Returns a new DataArrayInt that is a subtraction of two given arrays. There are 3
9738  * valid cases.
9739  * 1.  The arrays have same number of tuples and components. Then each value of
9740  *   the result array (_a_) is a subtraction of the corresponding values of \a a1 and
9741  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ i, j ].
9742  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
9743  *   component. Then
9744  *   _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ i, 0 ].
9745  * 3.  The arrays have same number of components and one array, say _a2_, has one
9746  *   tuple. Then
9747  *   _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ 0, j ].
9748  *
9749  * Info on components is copied either from the first array (in the first case) or from
9750  * the array with maximal number of elements (getNbOfElems()).
9751  *  \param [in] a1 - an array to subtract from.
9752  *  \param [in] a2 - an array to subtract.
9753  *  \return DataArrayInt * - the new instance of DataArrayInt.
9754  *          The caller is to delete this result array using decrRef() as it is no more
9755  *          needed.
9756  *  \throw If either \a a1 or \a a2 is NULL.
9757  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
9758  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
9759  *         none of them has number of tuples or components equal to 1.
9760  */
9761 DataArrayInt *DataArrayInt::Substract(const DataArrayInt *a1, const DataArrayInt *a2) throw(INTERP_KERNEL::Exception)
9762 {
9763   if(!a1 || !a2)
9764     throw INTERP_KERNEL::Exception("DataArrayInt::Substract : input DataArrayInt instance is NULL !");
9765   int nbOfTuple1=a1->getNumberOfTuples();
9766   int nbOfTuple2=a2->getNumberOfTuples();
9767   int nbOfComp1=a1->getNumberOfComponents();
9768   int nbOfComp2=a2->getNumberOfComponents();
9769   if(nbOfTuple2==nbOfTuple1)
9770     {
9771       if(nbOfComp1==nbOfComp2)
9772         {
9773           MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
9774           ret->alloc(nbOfTuple2,nbOfComp1);
9775           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::minus<int>());
9776           ret->copyStringInfoFrom(*a1);
9777           return ret.retn();
9778         }
9779       else if(nbOfComp2==1)
9780         {
9781           MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
9782           ret->alloc(nbOfTuple1,nbOfComp1);
9783           const int *a2Ptr=a2->getConstPointer();
9784           const int *a1Ptr=a1->getConstPointer();
9785           int *res=ret->getPointer();
9786           for(int i=0;i<nbOfTuple1;i++)
9787             res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::minus<int>(),a2Ptr[i]));
9788           ret->copyStringInfoFrom(*a1);
9789           return ret.retn();
9790         }
9791       else
9792         {
9793           a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Substract !");
9794           return 0;
9795         }
9796     }
9797   else if(nbOfTuple2==1)
9798     {
9799       a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Substract !");
9800       MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
9801       ret->alloc(nbOfTuple1,nbOfComp1);
9802       const int *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
9803       int *pt=ret->getPointer();
9804       for(int i=0;i<nbOfTuple1;i++)
9805         pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::minus<int>());
9806       ret->copyStringInfoFrom(*a1);
9807       return ret.retn();
9808     }
9809   else
9810     {
9811       a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Substract !");//will always throw an exception
9812       return 0;
9813     }
9814 }
9815
9816 /*!
9817  * Subtract values of another DataArrayInt from values of \a this one. There are 3
9818  * valid cases.
9819  * 1.  The arrays have same number of tuples and components. Then each value of
9820  *   \a other array is subtracted from the corresponding value of \a this array, i.e.:
9821  *   _a_ [ i, j ] -= _other_ [ i, j ].
9822  * 2.  The arrays have same number of tuples and \a other array has one component. Then
9823  *   _a_ [ i, j ] -= _other_ [ i, 0 ].
9824  * 3.  The arrays have same number of components and \a other array has one tuple. Then
9825  *   _a_ [ i, j ] -= _a2_ [ 0, j ].
9826  *
9827  *  \param [in] other - an array to subtract from \a this one.
9828  *  \throw If \a other is NULL.
9829  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
9830  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
9831  *         \a other has number of both tuples and components not equal to 1.
9832  */
9833 void DataArrayInt::substractEqual(const DataArrayInt *other) throw(INTERP_KERNEL::Exception)
9834 {
9835   if(!other)
9836     throw INTERP_KERNEL::Exception("DataArrayInt::substractEqual : input DataArrayInt instance is NULL !");
9837   const char *msg="Nb of tuples mismatch for DataArrayInt::substractEqual  !";
9838   checkAllocated(); other->checkAllocated();
9839   int nbOfTuple=getNumberOfTuples();
9840   int nbOfTuple2=other->getNumberOfTuples();
9841   int nbOfComp=getNumberOfComponents();
9842   int nbOfComp2=other->getNumberOfComponents();
9843   if(nbOfTuple==nbOfTuple2)
9844     {
9845       if(nbOfComp==nbOfComp2)
9846         {
9847           std::transform(begin(),end(),other->begin(),getPointer(),std::minus<int>());
9848         }
9849       else if(nbOfComp2==1)
9850         {
9851           int *ptr=getPointer();
9852           const int *ptrc=other->getConstPointer();
9853           for(int i=0;i<nbOfTuple;i++)
9854             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::minus<int>(),*ptrc++));
9855         }
9856       else
9857         throw INTERP_KERNEL::Exception(msg);
9858     }
9859   else if(nbOfTuple2==1)
9860     {
9861       int *ptr=getPointer();
9862       const int *ptrc=other->getConstPointer();
9863       for(int i=0;i<nbOfTuple;i++)
9864         std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::minus<int>());
9865     }
9866   else
9867     throw INTERP_KERNEL::Exception(msg);
9868   declareAsNew();
9869 }
9870
9871 /*!
9872  * Returns a new DataArrayInt that is a product of two given arrays. There are 3
9873  * valid cases.
9874  * 1.  The arrays have same number of tuples and components. Then each value of
9875  *   the result array (_a_) is a product of the corresponding values of \a a1 and
9876  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ i, j ].
9877  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
9878  *   component. Then
9879  *   _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ i, 0 ].
9880  * 3.  The arrays have same number of components and one array, say _a2_, has one
9881  *   tuple. Then
9882  *   _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ 0, j ].
9883  *
9884  * Info on components is copied either from the first array (in the first case) or from
9885  * the array with maximal number of elements (getNbOfElems()).
9886  *  \param [in] a1 - a factor array.
9887  *  \param [in] a2 - another factor array.
9888  *  \return DataArrayInt * - the new instance of DataArrayInt.
9889  *          The caller is to delete this result array using decrRef() as it is no more
9890  *          needed.
9891  *  \throw If either \a a1 or \a a2 is NULL.
9892  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
9893  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
9894  *         none of them has number of tuples or components equal to 1.
9895  */
9896 DataArrayInt *DataArrayInt::Multiply(const DataArrayInt *a1, const DataArrayInt *a2) throw(INTERP_KERNEL::Exception)
9897 {
9898   if(!a1 || !a2)
9899     throw INTERP_KERNEL::Exception("DataArrayInt::Multiply : input DataArrayInt instance is NULL !");
9900   int nbOfTuple=a1->getNumberOfTuples();
9901   int nbOfTuple2=a2->getNumberOfTuples();
9902   int nbOfComp=a1->getNumberOfComponents();
9903   int nbOfComp2=a2->getNumberOfComponents();
9904   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=0;
9905   if(nbOfTuple==nbOfTuple2)
9906     {
9907       if(nbOfComp==nbOfComp2)
9908         {
9909           ret=DataArrayInt::New();
9910           ret->alloc(nbOfTuple,nbOfComp);
9911           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::multiplies<int>());
9912           ret->copyStringInfoFrom(*a1);
9913         }
9914       else
9915         {
9916           int nbOfCompMin,nbOfCompMax;
9917           const DataArrayInt *aMin, *aMax;
9918           if(nbOfComp>nbOfComp2)
9919             {
9920               nbOfCompMin=nbOfComp2; nbOfCompMax=nbOfComp;
9921               aMin=a2; aMax=a1;
9922             }
9923           else
9924             {
9925               nbOfCompMin=nbOfComp; nbOfCompMax=nbOfComp2;
9926               aMin=a1; aMax=a2;
9927             }
9928           if(nbOfCompMin==1)
9929             {
9930               ret=DataArrayInt::New();
9931               ret->alloc(nbOfTuple,nbOfCompMax);
9932               const int *aMinPtr=aMin->getConstPointer();
9933               const int *aMaxPtr=aMax->getConstPointer();
9934               int *res=ret->getPointer();
9935               for(int i=0;i<nbOfTuple;i++)
9936                 res=std::transform(aMaxPtr+i*nbOfCompMax,aMaxPtr+(i+1)*nbOfCompMax,res,std::bind2nd(std::multiplies<int>(),aMinPtr[i]));
9937               ret->copyStringInfoFrom(*aMax);
9938             }
9939           else
9940             throw INTERP_KERNEL::Exception("Nb of components mismatch for array Multiply !");
9941         }
9942     }
9943   else if((nbOfTuple==1 && nbOfTuple2>1) || (nbOfTuple>1 && nbOfTuple2==1))
9944     {
9945       if(nbOfComp==nbOfComp2)
9946         {
9947           int nbOfTupleMax=std::max(nbOfTuple,nbOfTuple2);
9948           const DataArrayInt *aMin=nbOfTuple>nbOfTuple2?a2:a1;
9949           const DataArrayInt *aMax=nbOfTuple>nbOfTuple2?a1:a2;
9950           const int *aMinPtr=aMin->getConstPointer(),*aMaxPtr=aMax->getConstPointer();
9951           ret=DataArrayInt::New();
9952           ret->alloc(nbOfTupleMax,nbOfComp);
9953           int *res=ret->getPointer();
9954           for(int i=0;i<nbOfTupleMax;i++)
9955             res=std::transform(aMaxPtr+i*nbOfComp,aMaxPtr+(i+1)*nbOfComp,aMinPtr,res,std::multiplies<int>());
9956           ret->copyStringInfoFrom(*aMax);
9957         }
9958       else
9959         throw INTERP_KERNEL::Exception("Nb of components mismatch for array Multiply !");
9960     }
9961   else
9962     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Multiply !");
9963   return ret.retn();
9964 }
9965
9966
9967 /*!
9968  * Multiply values of another DataArrayInt to values of \a this one. There are 3
9969  * valid cases.
9970  * 1.  The arrays have same number of tuples and components. Then each value of
9971  *   \a other array is multiplied to the corresponding value of \a this array, i.e.:
9972  *   _a_ [ i, j ] *= _other_ [ i, j ].
9973  * 2.  The arrays have same number of tuples and \a other array has one component. Then
9974  *   _a_ [ i, j ] *= _other_ [ i, 0 ].
9975  * 3.  The arrays have same number of components and \a other array has one tuple. Then
9976  *   _a_ [ i, j ] *= _a2_ [ 0, j ].
9977  *
9978  *  \param [in] other - an array to multiply to \a this one.
9979  *  \throw If \a other is NULL.
9980  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
9981  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
9982  *         \a other has number of both tuples and components not equal to 1.
9983  */
9984 void DataArrayInt::multiplyEqual(const DataArrayInt *other) throw(INTERP_KERNEL::Exception)
9985 {
9986   if(!other)
9987     throw INTERP_KERNEL::Exception("DataArrayInt::multiplyEqual : input DataArrayInt instance is NULL !");
9988   const char *msg="Nb of tuples mismatch for DataArrayInt::multiplyEqual !";
9989   checkAllocated(); other->checkAllocated();
9990   int nbOfTuple=getNumberOfTuples();
9991   int nbOfTuple2=other->getNumberOfTuples();
9992   int nbOfComp=getNumberOfComponents();
9993   int nbOfComp2=other->getNumberOfComponents();
9994   if(nbOfTuple==nbOfTuple2)
9995     {
9996       if(nbOfComp==nbOfComp2)
9997         {
9998           std::transform(begin(),end(),other->begin(),getPointer(),std::multiplies<int>());
9999         }
10000       else if(nbOfComp2==1)
10001         {
10002           int *ptr=getPointer();
10003           const int *ptrc=other->getConstPointer();
10004           for(int i=0;i<nbOfTuple;i++)
10005             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::multiplies<int>(),*ptrc++));    
10006         }
10007       else
10008         throw INTERP_KERNEL::Exception(msg);
10009     }
10010   else if(nbOfTuple2==1)
10011     {
10012       if(nbOfComp2==nbOfComp)
10013         {
10014           int *ptr=getPointer();
10015           const int *ptrc=other->getConstPointer();
10016           for(int i=0;i<nbOfTuple;i++)
10017             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::multiplies<int>());
10018         }
10019       else
10020         throw INTERP_KERNEL::Exception(msg);
10021     }
10022   else
10023     throw INTERP_KERNEL::Exception(msg);
10024   declareAsNew();
10025 }
10026
10027
10028 /*!
10029  * Returns a new DataArrayInt that is a division of two given arrays. There are 3
10030  * valid cases.
10031  * 1.  The arrays have same number of tuples and components. Then each value of
10032  *   the result array (_a_) is a division of the corresponding values of \a a1 and
10033  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ i, j ].
10034  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
10035  *   component. Then
10036  *   _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ i, 0 ].
10037  * 3.  The arrays have same number of components and one array, say _a2_, has one
10038  *   tuple. Then
10039  *   _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ 0, j ].
10040  *
10041  * Info on components is copied either from the first array (in the first case) or from
10042  * the array with maximal number of elements (getNbOfElems()).
10043  *  \warning No check of division by zero is performed!
10044  *  \param [in] a1 - a numerator array.
10045  *  \param [in] a2 - a denominator array.
10046  *  \return DataArrayInt * - the new instance of DataArrayInt.
10047  *          The caller is to delete this result array using decrRef() as it is no more
10048  *          needed.
10049  *  \throw If either \a a1 or \a a2 is NULL.
10050  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
10051  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
10052  *         none of them has number of tuples or components equal to 1.
10053  */
10054 DataArrayInt *DataArrayInt::Divide(const DataArrayInt *a1, const DataArrayInt *a2) throw(INTERP_KERNEL::Exception)
10055 {
10056   if(!a1 || !a2)
10057     throw INTERP_KERNEL::Exception("DataArrayInt::Divide : input DataArrayInt instance is NULL !");
10058   int nbOfTuple1=a1->getNumberOfTuples();
10059   int nbOfTuple2=a2->getNumberOfTuples();
10060   int nbOfComp1=a1->getNumberOfComponents();
10061   int nbOfComp2=a2->getNumberOfComponents();
10062   if(nbOfTuple2==nbOfTuple1)
10063     {
10064       if(nbOfComp1==nbOfComp2)
10065         {
10066           MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
10067           ret->alloc(nbOfTuple2,nbOfComp1);
10068           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::divides<int>());
10069           ret->copyStringInfoFrom(*a1);
10070           return ret.retn();
10071         }
10072       else if(nbOfComp2==1)
10073         {
10074           MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
10075           ret->alloc(nbOfTuple1,nbOfComp1);
10076           const int *a2Ptr=a2->getConstPointer();
10077           const int *a1Ptr=a1->getConstPointer();
10078           int *res=ret->getPointer();
10079           for(int i=0;i<nbOfTuple1;i++)
10080             res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::divides<int>(),a2Ptr[i]));
10081           ret->copyStringInfoFrom(*a1);
10082           return ret.retn();
10083         }
10084       else
10085         {
10086           a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Divide !");
10087           return 0;
10088         }
10089     }
10090   else if(nbOfTuple2==1)
10091     {
10092       a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Divide !");
10093       MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
10094       ret->alloc(nbOfTuple1,nbOfComp1);
10095       const int *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
10096       int *pt=ret->getPointer();
10097       for(int i=0;i<nbOfTuple1;i++)
10098         pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::divides<int>());
10099       ret->copyStringInfoFrom(*a1);
10100       return ret.retn();
10101     }
10102   else
10103     {
10104       a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Divide !");//will always throw an exception
10105       return 0;
10106     }
10107 }
10108
10109 /*!
10110  * Divide values of \a this array by values of another DataArrayInt. There are 3
10111  * valid cases.
10112  * 1.  The arrays have same number of tuples and components. Then each value of
10113  *    \a this array is divided by the corresponding value of \a other one, i.e.:
10114  *   _a_ [ i, j ] /= _other_ [ i, j ].
10115  * 2.  The arrays have same number of tuples and \a other array has one component. Then
10116  *   _a_ [ i, j ] /= _other_ [ i, 0 ].
10117  * 3.  The arrays have same number of components and \a other array has one tuple. Then
10118  *   _a_ [ i, j ] /= _a2_ [ 0, j ].
10119  *
10120  *  \warning No check of division by zero is performed!
10121  *  \param [in] other - an array to divide \a this one by.
10122  *  \throw If \a other is NULL.
10123  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
10124  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
10125  *         \a other has number of both tuples and components not equal to 1.
10126  */
10127 void DataArrayInt::divideEqual(const DataArrayInt *other) throw(INTERP_KERNEL::Exception)
10128 {
10129   if(!other)
10130     throw INTERP_KERNEL::Exception("DataArrayInt::divideEqual : input DataArrayInt instance is NULL !");
10131   const char *msg="Nb of tuples mismatch for DataArrayInt::divideEqual !";
10132   checkAllocated(); other->checkAllocated();
10133   int nbOfTuple=getNumberOfTuples();
10134   int nbOfTuple2=other->getNumberOfTuples();
10135   int nbOfComp=getNumberOfComponents();
10136   int nbOfComp2=other->getNumberOfComponents();
10137   if(nbOfTuple==nbOfTuple2)
10138     {
10139       if(nbOfComp==nbOfComp2)
10140         {
10141           std::transform(begin(),end(),other->begin(),getPointer(),std::divides<int>());
10142         }
10143       else if(nbOfComp2==1)
10144         {
10145           int *ptr=getPointer();
10146           const int *ptrc=other->getConstPointer();
10147           for(int i=0;i<nbOfTuple;i++)
10148             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::divides<int>(),*ptrc++));
10149         }
10150       else
10151         throw INTERP_KERNEL::Exception(msg);
10152     }
10153   else if(nbOfTuple2==1)
10154     {
10155       if(nbOfComp2==nbOfComp)
10156         {
10157           int *ptr=getPointer();
10158           const int *ptrc=other->getConstPointer();
10159           for(int i=0;i<nbOfTuple;i++)
10160             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::divides<int>());
10161         }
10162       else
10163         throw INTERP_KERNEL::Exception(msg);
10164     }
10165   else
10166     throw INTERP_KERNEL::Exception(msg);
10167   declareAsNew();
10168 }
10169
10170
10171 /*!
10172  * Returns a new DataArrayInt that is a modulus of two given arrays. There are 3
10173  * valid cases.
10174  * 1.  The arrays have same number of tuples and components. Then each value of
10175  *   the result array (_a_) is a division of the corresponding values of \a a1 and
10176  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] % _a2_ [ i, j ].
10177  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
10178  *   component. Then
10179  *   _a_ [ i, j ] = _a1_ [ i, j ] % _a2_ [ i, 0 ].
10180  * 3.  The arrays have same number of components and one array, say _a2_, has one
10181  *   tuple. Then
10182  *   _a_ [ i, j ] = _a1_ [ i, j ] % _a2_ [ 0, j ].
10183  *
10184  * Info on components is copied either from the first array (in the first case) or from
10185  * the array with maximal number of elements (getNbOfElems()).
10186  *  \warning No check of division by zero is performed!
10187  *  \param [in] a1 - a dividend array.
10188  *  \param [in] a2 - a divisor array.
10189  *  \return DataArrayInt * - the new instance of DataArrayInt.
10190  *          The caller is to delete this result array using decrRef() as it is no more
10191  *          needed.
10192  *  \throw If either \a a1 or \a a2 is NULL.
10193  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
10194  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
10195  *         none of them has number of tuples or components equal to 1.
10196  */
10197 DataArrayInt *DataArrayInt::Modulus(const DataArrayInt *a1, const DataArrayInt *a2) throw(INTERP_KERNEL::Exception)
10198 {
10199     if(!a1 || !a2)
10200     throw INTERP_KERNEL::Exception("DataArrayInt::Modulus : input DataArrayInt instance is NULL !");
10201   int nbOfTuple1=a1->getNumberOfTuples();
10202   int nbOfTuple2=a2->getNumberOfTuples();
10203   int nbOfComp1=a1->getNumberOfComponents();
10204   int nbOfComp2=a2->getNumberOfComponents();
10205   if(nbOfTuple2==nbOfTuple1)
10206     {
10207       if(nbOfComp1==nbOfComp2)
10208         {
10209           MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
10210           ret->alloc(nbOfTuple2,nbOfComp1);
10211           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::modulus<int>());
10212           ret->copyStringInfoFrom(*a1);
10213           return ret.retn();
10214         }
10215       else if(nbOfComp2==1)
10216         {
10217           MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
10218           ret->alloc(nbOfTuple1,nbOfComp1);
10219           const int *a2Ptr=a2->getConstPointer();
10220           const int *a1Ptr=a1->getConstPointer();
10221           int *res=ret->getPointer();
10222           for(int i=0;i<nbOfTuple1;i++)
10223             res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::modulus<int>(),a2Ptr[i]));
10224           ret->copyStringInfoFrom(*a1);
10225           return ret.retn();
10226         }
10227       else
10228         {
10229           a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Modulus !");
10230           return 0;
10231         }
10232     }
10233   else if(nbOfTuple2==1)
10234     {
10235       a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Modulus !");
10236       MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
10237       ret->alloc(nbOfTuple1,nbOfComp1);
10238       const int *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
10239       int *pt=ret->getPointer();
10240       for(int i=0;i<nbOfTuple1;i++)
10241         pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::modulus<int>());
10242       ret->copyStringInfoFrom(*a1);
10243       return ret.retn();
10244     }
10245   else
10246     {
10247       a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Modulus !");//will always throw an exception
10248       return 0;
10249     }
10250 }
10251
10252 /*!
10253  * Modify \a this array so that each value becomes a modulus of division of this value by
10254  * a value of another DataArrayInt. There are 3 valid cases.
10255  * 1.  The arrays have same number of tuples and components. Then each value of
10256  *    \a this array is divided by the corresponding value of \a other one, i.e.:
10257  *   _a_ [ i, j ] %= _other_ [ i, j ].
10258  * 2.  The arrays have same number of tuples and \a other array has one component. Then
10259  *   _a_ [ i, j ] %= _other_ [ i, 0 ].
10260  * 3.  The arrays have same number of components and \a other array has one tuple. Then
10261  *   _a_ [ i, j ] %= _a2_ [ 0, j ].
10262  *
10263  *  \warning No check of division by zero is performed!
10264  *  \param [in] other - a divisor array.
10265  *  \throw If \a other is NULL.
10266  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
10267  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
10268  *         \a other has number of both tuples and components not equal to 1.
10269  */
10270 void DataArrayInt::modulusEqual(const DataArrayInt *other) throw(INTERP_KERNEL::Exception)
10271 {
10272   if(!other)
10273     throw INTERP_KERNEL::Exception("DataArrayInt::modulusEqual : input DataArrayInt instance is NULL !");
10274   const char *msg="Nb of tuples mismatch for DataArrayInt::modulusEqual !";
10275   checkAllocated(); other->checkAllocated();
10276   int nbOfTuple=getNumberOfTuples();
10277   int nbOfTuple2=other->getNumberOfTuples();
10278   int nbOfComp=getNumberOfComponents();
10279   int nbOfComp2=other->getNumberOfComponents();
10280   if(nbOfTuple==nbOfTuple2)
10281     {
10282       if(nbOfComp==nbOfComp2)
10283         {
10284           std::transform(begin(),end(),other->begin(),getPointer(),std::modulus<int>());
10285         }
10286       else if(nbOfComp2==1)
10287         {
10288           if(nbOfComp2==nbOfComp)
10289             {
10290               int *ptr=getPointer();
10291               const int *ptrc=other->getConstPointer();
10292               for(int i=0;i<nbOfTuple;i++)
10293                 std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::modulus<int>(),*ptrc++));
10294             }
10295           else
10296             throw INTERP_KERNEL::Exception(msg);
10297         }
10298       else
10299         throw INTERP_KERNEL::Exception(msg);
10300     }
10301   else if(nbOfTuple2==1)
10302     {
10303       int *ptr=getPointer();
10304       const int *ptrc=other->getConstPointer();
10305       for(int i=0;i<nbOfTuple;i++)
10306         std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::modulus<int>());
10307     }
10308   else
10309     throw INTERP_KERNEL::Exception(msg);
10310   declareAsNew();
10311 }
10312
10313 /*!
10314  * Returns a new DataArrayInt that is the result of pow of two given arrays. There are 3
10315  * valid cases.
10316  *
10317  *  \param [in] a1 - an array to pow up.
10318  *  \param [in] a2 - another array to sum up.
10319  *  \return DataArrayInt * - the new instance of DataArrayInt.
10320  *          The caller is to delete this result array using decrRef() as it is no more
10321  *          needed.
10322  *  \throw If either \a a1 or \a a2 is NULL.
10323  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
10324  *  \throw If \a a1->getNumberOfComponents() != 1 or \a a2->getNumberOfComponents() != 1.
10325  *  \throw If there is a negative value in \a a2.
10326  */
10327 DataArrayInt *DataArrayInt::Pow(const DataArrayInt *a1, const DataArrayInt *a2) throw(INTERP_KERNEL::Exception)
10328 {
10329   if(!a1 || !a2)
10330     throw INTERP_KERNEL::Exception("DataArrayInt::Pow : at least one of input instances is null !");
10331   int nbOfTuple=a1->getNumberOfTuples();
10332   int nbOfTuple2=a2->getNumberOfTuples();
10333   int nbOfComp=a1->getNumberOfComponents();
10334   int nbOfComp2=a2->getNumberOfComponents();
10335   if(nbOfTuple!=nbOfTuple2)
10336     throw INTERP_KERNEL::Exception("DataArrayInt::Pow : number of tuples mismatches !");
10337   if(nbOfComp!=1 || nbOfComp2!=1)
10338     throw INTERP_KERNEL::Exception("DataArrayInt::Pow : number of components of both arrays must be equal to 1 !");
10339   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbOfTuple,1);
10340   const int *ptr1(a1->begin()),*ptr2(a2->begin());
10341   int *ptr=ret->getPointer();
10342   for(int i=0;i<nbOfTuple;i++,ptr1++,ptr2++,ptr++)
10343     {
10344       if(*ptr2>=0)
10345         {
10346           int tmp=1;
10347           for(int j=0;j<*ptr2;j++)
10348             tmp*=*ptr1;
10349           *ptr=tmp;
10350         }
10351       else
10352         {
10353           std::ostringstream oss; oss << "DataArrayInt::Pow : on tuple #" << i << " of a2 value is < 0 (" << *ptr2 << ") !";
10354           throw INTERP_KERNEL::Exception(oss.str().c_str());
10355         }
10356     }
10357   return ret.retn();
10358 }
10359
10360 /*!
10361  * Apply pow on values of another DataArrayInt to values of \a this one.
10362  *
10363  *  \param [in] other - an array to pow to \a this one.
10364  *  \throw If \a other is NULL.
10365  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples()
10366  *  \throw If \a this->getNumberOfComponents() != 1 or \a other->getNumberOfComponents() != 1
10367  *  \throw If there is a negative value in \a other.
10368  */
10369 void DataArrayInt::powEqual(const DataArrayInt *other) throw(INTERP_KERNEL::Exception)
10370 {
10371   if(!other)
10372     throw INTERP_KERNEL::Exception("DataArrayInt::powEqual : input instance is null !");
10373   int nbOfTuple=getNumberOfTuples();
10374   int nbOfTuple2=other->getNumberOfTuples();
10375   int nbOfComp=getNumberOfComponents();
10376   int nbOfComp2=other->getNumberOfComponents();
10377   if(nbOfTuple!=nbOfTuple2)
10378     throw INTERP_KERNEL::Exception("DataArrayInt::powEqual : number of tuples mismatches !");
10379   if(nbOfComp!=1 || nbOfComp2!=1)
10380     throw INTERP_KERNEL::Exception("DataArrayInt::powEqual : number of components of both arrays must be equal to 1 !");
10381   int *ptr=getPointer();
10382   const int *ptrc=other->begin();
10383   for(int i=0;i<nbOfTuple;i++,ptrc++,ptr++)
10384     {
10385       if(*ptrc>=0)
10386         {
10387           int tmp=1;
10388           for(int j=0;j<*ptrc;j++)
10389             tmp*=*ptr;
10390           *ptr=tmp;
10391         }
10392       else
10393         {
10394           std::ostringstream oss; oss << "DataArrayInt::powEqual : on tuple #" << i << " of other value is < 0 (" << *ptrc << ") !";
10395           throw INTERP_KERNEL::Exception(oss.str().c_str());
10396         }
10397     }
10398   declareAsNew();
10399 }
10400
10401 /*!
10402  * Returns a C array which is a renumbering map in "Old to New" mode for the input array.
10403  * This map, if applied to \a start array, would make it sorted. For example, if
10404  * \a start array contents are [9,10,0,6,4,11,3,7] then the contents of the result array is
10405  * [5,6,0,3,2,7,1,4].
10406  *  \param [in] start - pointer to the first element of the array for which the
10407  *         permutation map is computed.
10408  *  \param [in] end - pointer specifying the end of the array \a start, so that
10409  *         the last value of \a start is \a end[ -1 ].
10410  *  \return int * - the result permutation array that the caller is to delete as it is no
10411  *         more needed.
10412  *  \throw If there are equal values in the input array.
10413  */
10414 int *DataArrayInt::CheckAndPreparePermutation(const int *start, const int *end)
10415 {
10416   std::size_t sz=std::distance(start,end);
10417   int *ret=(int *)malloc(sz*sizeof(int));
10418   int *work=new int[sz];
10419   std::copy(start,end,work);
10420   std::sort(work,work+sz);
10421   if(std::unique(work,work+sz)!=work+sz)
10422     {
10423       delete [] work;
10424       free(ret);
10425       throw INTERP_KERNEL::Exception("Some elements are equals in the specified array !");
10426     }
10427   std::map<int,int> m;
10428   for(int *workPt=work;workPt!=work+sz;workPt++)
10429     m[*workPt]=(int)std::distance(work,workPt);
10430   int *iter2=ret;
10431   for(const int *iter=start;iter!=end;iter++,iter2++)
10432     *iter2=m[*iter];
10433   delete [] work;
10434   return ret;
10435 }
10436
10437 /*!
10438  * Returns a new DataArrayInt containing an arithmetic progression
10439  * that is equal to the sequence returned by Python \c range(\a begin,\a  end,\a  step )
10440  * function.
10441  *  \param [in] begin - the start value of the result sequence.
10442  *  \param [in] end - limiting value, so that every value of the result array is less than
10443  *              \a end.
10444  *  \param [in] step - specifies the increment or decrement.
10445  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
10446  *          array using decrRef() as it is no more needed.
10447  *  \throw If \a step == 0.
10448  *  \throw If \a end < \a begin && \a step > 0.
10449  *  \throw If \a end > \a begin && \a step < 0.
10450  */
10451 DataArrayInt *DataArrayInt::Range(int begin, int end, int step) throw(INTERP_KERNEL::Exception)
10452 {
10453   int nbOfTuples=GetNumberOfItemGivenBESRelative(begin,end,step,"DataArrayInt::Range");
10454   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
10455   ret->alloc(nbOfTuples,1);
10456   int *ptr=ret->getPointer();
10457   if(step>0)
10458     {
10459       for(int i=begin;i<end;i+=step,ptr++)
10460         *ptr=i;
10461     }
10462   else
10463     {
10464       for(int i=begin;i>end;i+=step,ptr++)
10465         *ptr=i;
10466     }
10467   return ret.retn();
10468 }
10469
10470 /*!
10471  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
10472  * Server side.
10473  */
10474 void DataArrayInt::getTinySerializationIntInformation(std::vector<int>& tinyInfo) const
10475 {
10476   tinyInfo.resize(2);
10477   if(isAllocated())
10478     {
10479       tinyInfo[0]=getNumberOfTuples();
10480       tinyInfo[1]=getNumberOfComponents();
10481     }
10482   else
10483     {
10484       tinyInfo[0]=-1;
10485       tinyInfo[1]=-1;
10486     }
10487 }
10488
10489 /*!
10490  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
10491  * Server side.
10492  */
10493 void DataArrayInt::getTinySerializationStrInformation(std::vector<std::string>& tinyInfo) const
10494 {
10495   if(isAllocated())
10496     {
10497       int nbOfCompo=getNumberOfComponents();
10498       tinyInfo.resize(nbOfCompo+1);
10499       tinyInfo[0]=getName();
10500       for(int i=0;i<nbOfCompo;i++)
10501         tinyInfo[i+1]=getInfoOnComponent(i);
10502     }
10503   else
10504     {
10505       tinyInfo.resize(1);
10506       tinyInfo[0]=getName();
10507     }
10508 }
10509
10510 /*!
10511  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
10512  * This method returns if a feeding is needed.
10513  */
10514 bool DataArrayInt::resizeForUnserialization(const std::vector<int>& tinyInfoI)
10515 {
10516   int nbOfTuple=tinyInfoI[0];
10517   int nbOfComp=tinyInfoI[1];
10518   if(nbOfTuple!=-1 || nbOfComp!=-1)
10519     {
10520       alloc(nbOfTuple,nbOfComp);
10521       return true;
10522     }
10523   return false;
10524 }
10525
10526 /*!
10527  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
10528  * This method returns if a feeding is needed.
10529  */
10530 void DataArrayInt::finishUnserialization(const std::vector<int>& tinyInfoI, const std::vector<std::string>& tinyInfoS)
10531 {
10532   setName(tinyInfoS[0].c_str());
10533   if(isAllocated())
10534     {
10535       int nbOfCompo=getNumberOfComponents();
10536       for(int i=0;i<nbOfCompo;i++)
10537         setInfoOnComponent(i,tinyInfoS[i+1].c_str());
10538     }
10539 }
10540
10541 DataArrayIntIterator::DataArrayIntIterator(DataArrayInt *da):_da(da),_pt(0),_tuple_id(0),_nb_comp(0),_nb_tuple(0)
10542 {
10543   if(_da)
10544     {
10545       _da->incrRef();
10546       if(_da->isAllocated())
10547         {
10548           _nb_comp=da->getNumberOfComponents();
10549           _nb_tuple=da->getNumberOfTuples();
10550           _pt=da->getPointer();
10551         }
10552     }
10553 }
10554
10555 DataArrayIntIterator::~DataArrayIntIterator()
10556 {
10557   if(_da)
10558     _da->decrRef();
10559 }
10560
10561 DataArrayIntTuple *DataArrayIntIterator::nextt() throw(INTERP_KERNEL::Exception)
10562 {
10563   if(_tuple_id<_nb_tuple)
10564     {
10565       _tuple_id++;
10566       DataArrayIntTuple *ret=new DataArrayIntTuple(_pt,_nb_comp);
10567       _pt+=_nb_comp;
10568       return ret;
10569     }
10570   else
10571     return 0;
10572 }
10573
10574 DataArrayIntTuple::DataArrayIntTuple(int *pt, int nbOfComp):_pt(pt),_nb_of_compo(nbOfComp)
10575 {
10576 }
10577
10578 std::string DataArrayIntTuple::repr() const throw(INTERP_KERNEL::Exception)
10579 {
10580   std::ostringstream oss; oss << "(";
10581   for(int i=0;i<_nb_of_compo-1;i++)
10582     oss << _pt[i] << ", ";
10583   oss << _pt[_nb_of_compo-1] << ")";
10584   return oss.str();
10585 }
10586
10587 int DataArrayIntTuple::intValue() const throw(INTERP_KERNEL::Exception)
10588 {
10589   if(_nb_of_compo==1)
10590     return *_pt;
10591   throw INTERP_KERNEL::Exception("DataArrayIntTuple::intValue : DataArrayIntTuple instance has not exactly 1 component -> Not possible to convert it into an integer !");
10592 }
10593
10594 /*!
10595  * This method returns a newly allocated instance the caller should dealed with by a ParaMEDMEM::DataArrayInt::decrRef.
10596  * This method performs \b no copy of data. The content is only referenced using ParaMEDMEM::DataArrayInt::useArray with ownership set to \b false.
10597  * 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
10598  * \b nbOfCompo=1 and \bnbOfTuples==this->_nb_of_elem.
10599  */
10600 DataArrayInt *DataArrayIntTuple::buildDAInt(int nbOfTuples, int nbOfCompo) const throw(INTERP_KERNEL::Exception)
10601 {
10602   if((_nb_of_compo==nbOfCompo && nbOfTuples==1) || (_nb_of_compo==nbOfTuples && nbOfCompo==1))
10603     {
10604       DataArrayInt *ret=DataArrayInt::New();
10605       ret->useExternalArrayWithRWAccess(_pt,nbOfTuples,nbOfCompo);
10606       return ret;
10607     }
10608   else
10609     {
10610       std::ostringstream oss; oss << "DataArrayIntTuple::buildDAInt : unable to build a requested DataArrayInt instance with nbofTuple=" << nbOfTuples << " and nbOfCompo=" << nbOfCompo;
10611       oss << ".\nBecause the number of elements in this is " << _nb_of_compo << " !";
10612       throw INTERP_KERNEL::Exception(oss.str().c_str());
10613     }
10614 }