]> SALOME platform Git repositories - tools/medcoupling.git/blob - src/MEDCoupling/MEDCouplingMemArray.cxx
Salome HOME
nearly ready for the single geo type in MEDLoader
[tools/medcoupling.git] / src / MEDCoupling / MEDCouplingMemArray.cxx
1 // Copyright (C) 2007-2013  CEA/DEN, EDF R&D
2 //
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License.
7 //
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11 // Lesser General Public License for more details.
12 //
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
16 //
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
18 //
19 // Author : Anthony Geay (CEA/DEN)
20
21 #include "MEDCouplingMemArray.txx"
22 #include "MEDCouplingAutoRefCountObjectPtr.hxx"
23
24 #include "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  * Searches for tuples coincident within \a prec tolerance. Each tuple is considered
1791  * as coordinates of a point in getNumberOfComponents()-dimensional space. The
1792  * distance separating two points is computed with the infinite norm.
1793  *
1794  * Indices of coincident tuples are stored in output arrays.
1795  * A pair of arrays (\a comm, \a commIndex) is called "Surjective Format 2".
1796  *
1797  * This method is typically used by MEDCouplingPointSet::findCommonNodes() and
1798  * MEDCouplingUMesh::mergeNodes().
1799  *  \param [in] prec - minimal absolute distance between two tuples (infinite norm) at which they are
1800  *              considered not coincident.
1801  *  \param [in] limitTupleId - limit tuple id. If all tuples within a group of coincident
1802  *              tuples have id strictly lower than \a limitTupleId then they are not returned.
1803  *  \param [out] comm - the array holding ids (== indices) of coincident tuples. 
1804  *               \a comm->getNumberOfComponents() == 1. 
1805  *               \a comm->getNumberOfTuples() == \a commIndex->back().
1806  *  \param [out] commIndex - the array dividing all indices stored in \a comm into
1807  *               groups of (indices of) coincident tuples. Its every value is a tuple
1808  *               index where a next group of tuples begins. For example the second
1809  *               group of tuples in \a comm is described by following range of indices:
1810  *               [ \a commIndex[1], \a commIndex[2] ). \a commIndex->getNumberOfTuples()-1
1811  *               gives the number of groups of coincident tuples.
1812  *  \throw If \a this is not allocated.
1813  *  \throw If the number of components is not in [1,2,3].
1814  *
1815  *  \ref cpp_mcdataarraydouble_findcommontuples "Here is a C++ example".
1816  *
1817  *  \ref py_mcdataarraydouble_findcommontuples  "Here is a Python example".
1818  *  \sa DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2().
1819  */
1820 void DataArrayDouble::findCommonTuples(double prec, int limitTupleId, DataArrayInt *&comm, DataArrayInt *&commIndex) const throw(INTERP_KERNEL::Exception)
1821 {
1822   checkAllocated();
1823   int nbOfCompo=getNumberOfComponents();
1824   if ((nbOfCompo<1) || (nbOfCompo>3)) //test before work
1825     throw INTERP_KERNEL::Exception("DataArrayDouble::findCommonTuples : Unexpected spacedim of coords. Must be 1, 2 or 3.");
1826   
1827   int nbOfTuples=getNumberOfTuples();
1828   //
1829   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> c(DataArrayInt::New()),cI(DataArrayInt::New()); c->alloc(0,1); cI->pushBackSilent(0);
1830   switch(nbOfCompo)
1831     {
1832     case 3:
1833       findCommonTuplesAlg<3>(begin(),nbOfTuples,limitTupleId,prec,c,cI);
1834       break;
1835     case 2:
1836       findCommonTuplesAlg<2>(begin(),nbOfTuples,limitTupleId,prec,c,cI);
1837       break;
1838     case 1:
1839       findCommonTuplesAlg<1>(begin(),nbOfTuples,limitTupleId,prec,c,cI);
1840       break;
1841     default:
1842       throw INTERP_KERNEL::Exception("DataArrayDouble::findCommonTuples : nb of components managed are 1,2 and 3 ! not implemented for other number of components !");
1843     }
1844   comm=c.retn();
1845   commIndex=cI.retn();
1846 }
1847
1848 /*!
1849  * 
1850  * \param [in] nbTimes specifies the nb of times each tuples in \a this will be duplicated contiguouly in returned DataArrayDouble instance.
1851  *             \a nbTimes  should be at least equal to 1.
1852  * \return a newly allocated DataArrayDouble having one component and number of tuples equal to \a nbTimes * \c this->getNumberOfTuples.
1853  * \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.
1854  */
1855 DataArrayDouble *DataArrayDouble::duplicateEachTupleNTimes(int nbTimes) const throw(INTERP_KERNEL::Exception)
1856 {
1857   checkAllocated();
1858   if(getNumberOfComponents()!=1)
1859     throw INTERP_KERNEL::Exception("DataArrayDouble::duplicateEachTupleNTimes : this should have only one component !");
1860   if(nbTimes<1)
1861     throw INTERP_KERNEL::Exception("DataArrayDouble::duplicateEachTupleNTimes : nb times should be >= 1 !");
1862   int nbTuples=getNumberOfTuples();
1863   const double *inPtr=getConstPointer();
1864   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New(); ret->alloc(nbTimes*nbTuples,1);
1865   double *retPtr=ret->getPointer();
1866   for(int i=0;i<nbTuples;i++,inPtr++)
1867     {
1868       double val=*inPtr;
1869       for(int j=0;j<nbTimes;j++,retPtr++)
1870         *retPtr=val;
1871     }
1872   ret->copyStringInfoFrom(*this);
1873   return ret.retn();
1874 }
1875
1876 /*!
1877  * This methods returns the minimal distance between the two set of points \a this and \a other.
1878  * So \a this and \a other have to have the same number of components. If not an INTERP_KERNEL::Exception will be thrown.
1879  * This method works only if number of components of \a this (equal to those of \a other) is in 1, 2 or 3.
1880  *
1881  * \param [out] thisTupleId the tuple id in \a this corresponding to the returned minimal distance
1882  * \param [out] otherTupleId the tuple id in \a other corresponding to the returned minimal distance
1883  * \return the minimal distance between the two set of points \a this and \a other.
1884  * \sa DataArrayDouble::findClosestTupleId
1885  */
1886 double DataArrayDouble::minimalDistanceTo(const DataArrayDouble *other, int& thisTupleId, int& otherTupleId) const throw(INTERP_KERNEL::Exception)
1887 {
1888   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> part1=findClosestTupleId(other);
1889   int nbOfCompo(getNumberOfComponents());
1890   int otherNbTuples(other->getNumberOfTuples());
1891   const double *thisPt(begin()),*otherPt(other->begin());
1892   const int *part1Pt(part1->begin());
1893   double ret=std::numeric_limits<double>::max();
1894   for(int i=0;i<otherNbTuples;i++,part1Pt++,otherPt+=nbOfCompo)
1895     {
1896       double tmp(0.);
1897       for(int j=0;j<nbOfCompo;j++)
1898         tmp+=(otherPt[j]-thisPt[nbOfCompo*(*part1Pt)+j])*(otherPt[j]-thisPt[nbOfCompo*(*part1Pt)+j]);
1899       if(tmp<ret)
1900         { ret=tmp; thisTupleId=*part1Pt; otherTupleId=i; }
1901     }
1902   return sqrt(ret);
1903 }
1904
1905 /*!
1906  * This methods returns for each tuple in \a other which tuple in \a this is the closest.
1907  * So \a this and \a other have to have the same number of components. If not an INTERP_KERNEL::Exception will be thrown.
1908  * This method works only if number of components of \a this (equal to those of \a other) is in 1, 2 or 3.
1909  *
1910  * \return a newly allocated (new object to be dealt by the caller) DataArrayInt having \c other->getNumberOfTuples() tuples and one components.
1911  * \sa DataArrayDouble::minimalDistanceTo
1912  */
1913 DataArrayInt *DataArrayDouble::findClosestTupleId(const DataArrayDouble *other) const throw(INTERP_KERNEL::Exception)
1914 {
1915   if(!other)
1916     throw INTERP_KERNEL::Exception("DataArrayDouble::findClosestTupleId : other instance is NULL !");
1917   checkAllocated(); other->checkAllocated();
1918   int nbOfCompo=getNumberOfComponents();
1919   if(nbOfCompo!=other->getNumberOfComponents())
1920     {
1921       std::ostringstream oss; oss << "DataArrayDouble::findClosestTupleId : number of components in this is " << nbOfCompo;
1922       oss << ", whereas number of components in other is " << other->getNumberOfComponents() << "! Should be equal !";
1923       throw INTERP_KERNEL::Exception(oss.str().c_str());
1924     }
1925   int nbOfTuples=other->getNumberOfTuples();
1926   int thisNbOfTuples=getNumberOfTuples();
1927   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbOfTuples,1);
1928   double bounds[6];
1929   getMinMaxPerComponent(bounds);
1930   switch(nbOfCompo)
1931     {
1932     case 3:
1933       {
1934         double xDelta(fabs(bounds[1]-bounds[0])),yDelta(fabs(bounds[3]-bounds[2])),zDelta(fabs(bounds[5]-bounds[4]));
1935         double delta=std::max(xDelta,yDelta); delta=std::max(delta,zDelta);
1936         double characSize=pow((delta*delta*delta)/((double)thisNbOfTuples),1./3.);
1937         BBTreePts<3,int> myTree(begin(),0,0,getNumberOfTuples(),characSize*1e-12);
1938         FindClosestTupleIdAlg<3>(myTree,3.*characSize*characSize,other->begin(),nbOfTuples,begin(),thisNbOfTuples,ret->getPointer());
1939         break;
1940       }
1941     case 2:
1942       {
1943         double xDelta(fabs(bounds[1]-bounds[0])),yDelta(fabs(bounds[3]-bounds[2]));
1944         double delta=std::max(xDelta,yDelta);
1945         double characSize=sqrt(delta/(double)thisNbOfTuples);
1946         BBTreePts<2,int> myTree(begin(),0,0,getNumberOfTuples(),characSize*1e-12);
1947         FindClosestTupleIdAlg<2>(myTree,2.*characSize*characSize,other->begin(),nbOfTuples,begin(),thisNbOfTuples,ret->getPointer());
1948         break;
1949       }
1950     case 1:
1951       {
1952         double characSize=fabs(bounds[1]-bounds[0])/thisNbOfTuples;
1953         BBTreePts<1,int> myTree(begin(),0,0,getNumberOfTuples(),characSize*1e-12);
1954         FindClosestTupleIdAlg<1>(myTree,1.*characSize*characSize,other->begin(),nbOfTuples,begin(),thisNbOfTuples,ret->getPointer());
1955         break;
1956       }
1957     default:
1958       throw INTERP_KERNEL::Exception("Unexpected spacedim of coords for findClosestTupleId. Must be 1, 2 or 3.");
1959     }
1960   return ret.retn();
1961 }
1962
1963 /*!
1964  * Returns a copy of \a this array by excluding coincident tuples. Each tuple is
1965  * considered as coordinates of a point in getNumberOfComponents()-dimensional
1966  * space. The distance between tuples is computed using norm2. If several tuples are
1967  * not far each from other than \a prec, only one of them remains in the result
1968  * array. The order of tuples in the result array is same as in \a this one except
1969  * that coincident tuples are excluded.
1970  *  \param [in] prec - minimal absolute distance between two tuples at which they are
1971  *              considered not coincident.
1972  *  \param [in] limitTupleId - limit tuple id. If all tuples within a group of coincident
1973  *              tuples have id strictly lower than \a limitTupleId then they are not excluded.
1974  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1975  *          is to delete using decrRef() as it is no more needed.
1976  *  \throw If \a this is not allocated.
1977  *  \throw If the number of components is not in [1,2,3].
1978  *
1979  *  \ref py_mcdataarraydouble_getdifferentvalues "Here is a Python example".
1980  */
1981 DataArrayDouble *DataArrayDouble::getDifferentValues(double prec, int limitTupleId) const throw(INTERP_KERNEL::Exception)
1982 {
1983   checkAllocated();
1984   DataArrayInt *c0=0,*cI0=0;
1985   findCommonTuples(prec,limitTupleId,c0,cI0);
1986   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> c(c0),cI(cI0);
1987   int newNbOfTuples=-1;
1988   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> o2n=DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2(getNumberOfTuples(),c0->begin(),cI0->begin(),cI0->end(),newNbOfTuples);
1989   return renumberAndReduce(o2n->getConstPointer(),newNbOfTuples);
1990 }
1991
1992 /*!
1993  * Copy all components in a specified order from another DataArrayDouble.
1994  * Both numerical and textual data is copied. The number of tuples in \a this and
1995  * the other array can be different.
1996  *  \param [in] a - the array to copy data from.
1997  *  \param [in] compoIds - sequence of zero based indices of components, data of which is
1998  *              to be copied.
1999  *  \throw If \a a is NULL.
2000  *  \throw If \a compoIds.size() != \a a->getNumberOfComponents().
2001  *  \throw If \a compoIds[i] < 0 or \a compoIds[i] > \a this->getNumberOfComponents().
2002  *
2003  *  \ref py_mcdataarraydouble_setselectedcomponents "Here is a Python example".
2004  */
2005 void DataArrayDouble::setSelectedComponents(const DataArrayDouble *a, const std::vector<int>& compoIds) throw(INTERP_KERNEL::Exception)
2006 {
2007   if(!a)
2008     throw INTERP_KERNEL::Exception("DataArrayDouble::setSelectedComponents : input DataArrayDouble is NULL !");
2009   checkAllocated();
2010   copyPartOfStringInfoFrom2(compoIds,*a);
2011   std::size_t partOfCompoSz=compoIds.size();
2012   int nbOfCompo=getNumberOfComponents();
2013   int nbOfTuples=std::min(getNumberOfTuples(),a->getNumberOfTuples());
2014   const double *ac=a->getConstPointer();
2015   double *nc=getPointer();
2016   for(int i=0;i<nbOfTuples;i++)
2017     for(std::size_t j=0;j<partOfCompoSz;j++,ac++)
2018       nc[nbOfCompo*i+compoIds[j]]=*ac;
2019 }
2020
2021 /*!
2022  * Copy all values from another DataArrayDouble into specified tuples and components
2023  * of \a this array. Textual data is not copied.
2024  * The tree parameters defining set of indices of tuples and components are similar to
2025  * the tree parameters of the Python function \c range(\c start,\c stop,\c step).
2026  *  \param [in] a - the array to copy values from.
2027  *  \param [in] bgTuples - index of the first tuple of \a this array to assign values to.
2028  *  \param [in] endTuples - index of the tuple before which the tuples to assign to
2029  *              are located.
2030  *  \param [in] stepTuples - index increment to get index of the next tuple to assign to.
2031  *  \param [in] bgComp - index of the first component of \a this array to assign values to.
2032  *  \param [in] endComp - index of the component before which the components to assign
2033  *              to are located.
2034  *  \param [in] stepComp - index increment to get index of the next component to assign to.
2035  *  \param [in] strictCompoCompare - if \a true (by default), then \a a->getNumberOfComponents() 
2036  *              must be equal to the number of columns to assign to, else an
2037  *              exception is thrown; if \a false, then it is only required that \a
2038  *              a->getNbOfElems() equals to number of values to assign to (this condition
2039  *              must be respected even if \a strictCompoCompare is \a true). The number of 
2040  *              values to assign to is given by following Python expression:
2041  *              \a nbTargetValues = 
2042  *              \c len(\c range(\a bgTuples,\a endTuples,\a stepTuples)) *
2043  *              \c len(\c range(\a bgComp,\a endComp,\a stepComp)).
2044  *  \throw If \a a is NULL.
2045  *  \throw If \a a is not allocated.
2046  *  \throw If \a this is not allocated.
2047  *  \throw If parameters specifying tuples and components to assign to do not give a
2048  *            non-empty range of increasing indices.
2049  *  \throw If \a a->getNbOfElems() != \a nbTargetValues.
2050  *  \throw If \a strictCompoCompare == \a true && \a a->getNumberOfComponents() !=
2051  *            \c len(\c range(\a bgComp,\a endComp,\a stepComp)).
2052  *
2053  *  \ref py_mcdataarraydouble_setpartofvalues1 "Here is a Python example".
2054  */
2055 void DataArrayDouble::setPartOfValues1(const DataArrayDouble *a, int bgTuples, int endTuples, int stepTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare) throw(INTERP_KERNEL::Exception)
2056 {
2057   if(!a)
2058     throw INTERP_KERNEL::Exception("DataArrayDouble::setPartOfValues1 : input DataArrayDouble is NULL !");
2059   const char msg[]="DataArrayDouble::setPartOfValues1";
2060   checkAllocated();
2061   a->checkAllocated();
2062   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
2063   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
2064   int nbComp=getNumberOfComponents();
2065   int nbOfTuples=getNumberOfTuples();
2066   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
2067   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
2068   bool assignTech=true;
2069   if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
2070     {
2071       if(strictCompoCompare)
2072         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
2073     }
2074   else
2075     {
2076       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
2077       assignTech=false;
2078     }
2079   const double *srcPt=a->getConstPointer();
2080   double *pt=getPointer()+bgTuples*nbComp+bgComp;
2081   if(assignTech)
2082     {
2083       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
2084         for(int j=0;j<newNbOfComp;j++,srcPt++)
2085           pt[j*stepComp]=*srcPt;
2086     }
2087   else
2088     {
2089       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
2090         {
2091           const double *srcPt2=srcPt;
2092           for(int j=0;j<newNbOfComp;j++,srcPt2++)
2093             pt[j*stepComp]=*srcPt2;
2094         }
2095     }
2096 }
2097
2098 /*!
2099  * Assign a given value to values at specified tuples and components of \a this array.
2100  * The tree parameters defining set of indices of tuples and components are similar to
2101  * the tree parameters of the Python function \c range(\c start,\c stop,\c step)..
2102  *  \param [in] a - the value to assign.
2103  *  \param [in] bgTuples - index of the first tuple of \a this array to assign to.
2104  *  \param [in] endTuples - index of the tuple before which the tuples to assign to
2105  *              are located.
2106  *  \param [in] stepTuples - index increment to get index of the next tuple to assign to.
2107  *  \param [in] bgComp - index of the first component of \a this array to assign to.
2108  *  \param [in] endComp - index of the component before which the components to assign
2109  *              to are located.
2110  *  \param [in] stepComp - index increment to get index of the next component to assign to.
2111  *  \throw If \a this is not allocated.
2112  *  \throw If parameters specifying tuples and components to assign to, do not give a
2113  *            non-empty range of increasing indices or indices are out of a valid range
2114  *            for \this array.
2115  *
2116  *  \ref py_mcdataarraydouble_setpartofvaluessimple1 "Here is a Python example".
2117  */
2118 void DataArrayDouble::setPartOfValuesSimple1(double a, int bgTuples, int endTuples, int stepTuples, int bgComp, int endComp, int stepComp) throw(INTERP_KERNEL::Exception)
2119 {
2120   const char msg[]="DataArrayDouble::setPartOfValuesSimple1";
2121   checkAllocated();
2122   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
2123   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
2124   int nbComp=getNumberOfComponents();
2125   int nbOfTuples=getNumberOfTuples();
2126   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
2127   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
2128   double *pt=getPointer()+bgTuples*nbComp+bgComp;
2129   for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
2130     for(int j=0;j<newNbOfComp;j++)
2131       pt[j*stepComp]=a;
2132 }
2133
2134 /*!
2135  * Copy all values from another DataArrayDouble (\a a) into specified tuples and 
2136  * components of \a this array. Textual data is not copied.
2137  * The tuples and components to assign to are defined by C arrays of indices.
2138  * There are two *modes of usage*:
2139  * - If \a a->getNbOfElems() equals to number of values to assign to, then every value
2140  *   of \a a is assigned to its own location within \a this array. 
2141  * - If \a a includes one tuple, then all values of \a a are assigned to the specified
2142  *   components of every specified tuple of \a this array. In this mode it is required
2143  *   that \a a->getNumberOfComponents() equals to the number of specified components.
2144  *
2145  *  \param [in] a - the array to copy values from.
2146  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
2147  *              assign values of \a a to.
2148  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
2149  *              pointer to a tuple index <em>(pi)</em> varies as this: 
2150  *              \a bgTuples <= \a pi < \a endTuples.
2151  *  \param [in] bgComp - pointer to an array of component indices of \a this array to
2152  *              assign values of \a a to.
2153  *  \param [in] endComp - specifies the end of the array \a bgTuples, so that
2154  *              pointer to a component index <em>(pi)</em> varies as this: 
2155  *              \a bgComp <= \a pi < \a endComp.
2156  *  \param [in] strictCompoCompare - this parameter is checked only if the
2157  *               *mode of usage* is the first; if it is \a true (default), 
2158  *               then \a a->getNumberOfComponents() must be equal 
2159  *               to the number of specified columns, else this is not required.
2160  *  \throw If \a a is NULL.
2161  *  \throw If \a a is not allocated.
2162  *  \throw If \a this is not allocated.
2163  *  \throw If any index of tuple/component given by <em>bgTuples / bgComp</em> is
2164  *         out of a valid range for \a this array.
2165  *  \throw In the first *mode of usage*, if <em>strictCompoCompare == true </em> and
2166  *         if <em> a->getNumberOfComponents() != (endComp - bgComp) </em>.
2167  *  \throw In the second *mode of usage*, if \a a->getNumberOfTuples() != 1 or
2168  *         <em> a->getNumberOfComponents() != (endComp - bgComp)</em>.
2169  *
2170  *  \ref py_mcdataarraydouble_setpartofvalues2 "Here is a Python example".
2171  */
2172 void DataArrayDouble::setPartOfValues2(const DataArrayDouble *a, const int *bgTuples, const int *endTuples, const int *bgComp, const int *endComp, bool strictCompoCompare) throw(INTERP_KERNEL::Exception)
2173 {
2174   if(!a)
2175     throw INTERP_KERNEL::Exception("DataArrayDouble::setPartOfValues2 : input DataArrayDouble is NULL !");
2176   const char msg[]="DataArrayDouble::setPartOfValues2";
2177   checkAllocated();
2178   a->checkAllocated();
2179   int nbComp=getNumberOfComponents();
2180   int nbOfTuples=getNumberOfTuples();
2181   for(const int *z=bgComp;z!=endComp;z++)
2182     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
2183   int newNbOfTuples=(int)std::distance(bgTuples,endTuples);
2184   int newNbOfComp=(int)std::distance(bgComp,endComp);
2185   bool assignTech=true;
2186   if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
2187     {
2188       if(strictCompoCompare)
2189         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
2190     }
2191   else
2192     {
2193       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
2194       assignTech=false;
2195     }
2196   double *pt=getPointer();
2197   const double *srcPt=a->getConstPointer();
2198   if(assignTech)
2199     {    
2200       for(const int *w=bgTuples;w!=endTuples;w++)
2201         {
2202           DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
2203           for(const int *z=bgComp;z!=endComp;z++,srcPt++)
2204             {    
2205               pt[(std::size_t)(*w)*nbComp+(*z)]=*srcPt;
2206             }
2207         }
2208     }
2209   else
2210     {
2211       for(const int *w=bgTuples;w!=endTuples;w++)
2212         {
2213           const double *srcPt2=srcPt;
2214           DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
2215           for(const int *z=bgComp;z!=endComp;z++,srcPt2++)
2216             {    
2217               pt[(std::size_t)(*w)*nbComp+(*z)]=*srcPt2;
2218             }
2219         }
2220     }
2221 }
2222
2223 /*!
2224  * Assign a given value to values at specified tuples and components of \a this array.
2225  * The tuples and components to assign to are defined by C arrays of indices.
2226  *  \param [in] a - the value to assign.
2227  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
2228  *              assign \a a to.
2229  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
2230  *              pointer to a tuple index (\a pi) varies as this: 
2231  *              \a bgTuples <= \a pi < \a endTuples.
2232  *  \param [in] bgComp - pointer to an array of component indices of \a this array to
2233  *              assign \a a to.
2234  *  \param [in] endComp - specifies the end of the array \a bgTuples, so that
2235  *              pointer to a component index (\a pi) varies as this: 
2236  *              \a bgComp <= \a pi < \a endComp.
2237  *  \throw If \a this is not allocated.
2238  *  \throw If any index of tuple/component given by <em>bgTuples / bgComp</em> is
2239  *         out of a valid range for \a this array.
2240  *
2241  *  \ref py_mcdataarraydouble_setpartofvaluessimple2 "Here is a Python example".
2242  */
2243 void DataArrayDouble::setPartOfValuesSimple2(double a, const int *bgTuples, const int *endTuples, const int *bgComp, const int *endComp) throw(INTERP_KERNEL::Exception)
2244 {
2245   checkAllocated();
2246   int nbComp=getNumberOfComponents();
2247   int nbOfTuples=getNumberOfTuples();
2248   for(const int *z=bgComp;z!=endComp;z++)
2249     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
2250   double *pt=getPointer();
2251   for(const int *w=bgTuples;w!=endTuples;w++)
2252     for(const int *z=bgComp;z!=endComp;z++)
2253       {
2254         DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
2255         pt[(std::size_t)(*w)*nbComp+(*z)]=a;
2256       }
2257 }
2258
2259 /*!
2260  * Copy all values from another DataArrayDouble (\a a) into specified tuples and 
2261  * components of \a this array. Textual data is not copied.
2262  * The tuples to assign to are defined by a C array of indices.
2263  * The components to assign to are defined by three values similar to parameters of
2264  * the Python function \c range(\c start,\c stop,\c step).
2265  * There are two *modes of usage*:
2266  * - If \a a->getNbOfElems() equals to number of values to assign to, then every value
2267  *   of \a a is assigned to its own location within \a this array. 
2268  * - If \a a includes one tuple, then all values of \a a are assigned to the specified
2269  *   components of every specified tuple of \a this array. In this mode it is required
2270  *   that \a a->getNumberOfComponents() equals to the number of specified components.
2271  *
2272  *  \param [in] a - the array to copy values from.
2273  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
2274  *              assign values of \a a to.
2275  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
2276  *              pointer to a tuple index <em>(pi)</em> varies as this: 
2277  *              \a bgTuples <= \a pi < \a endTuples.
2278  *  \param [in] bgComp - index of the first component of \a this array to assign to.
2279  *  \param [in] endComp - index of the component before which the components to assign
2280  *              to are located.
2281  *  \param [in] stepComp - index increment to get index of the next component to assign to.
2282  *  \param [in] strictCompoCompare - this parameter is checked only in the first
2283  *               *mode of usage*; if \a strictCompoCompare is \a true (default), 
2284  *               then \a a->getNumberOfComponents() must be equal 
2285  *               to the number of specified columns, else this is not required.
2286  *  \throw If \a a is NULL.
2287  *  \throw If \a a is not allocated.
2288  *  \throw If \a this is not allocated.
2289  *  \throw If any index of tuple given by \a bgTuples is out of a valid range for 
2290  *         \a this array.
2291  *  \throw In the first *mode of usage*, if <em>strictCompoCompare == true </em> and
2292  *         if <em> a->getNumberOfComponents()</em> is unequal to the number of components
2293  *         defined by <em>(bgComp,endComp,stepComp)</em>.
2294  *  \throw In the second *mode of usage*, if \a a->getNumberOfTuples() != 1 or
2295  *         <em> a->getNumberOfComponents()</em> is unequal to the number of components
2296  *         defined by <em>(bgComp,endComp,stepComp)</em>.
2297  *  \throw If parameters specifying components to assign to, do not give a
2298  *            non-empty range of increasing indices or indices are out of a valid range
2299  *            for \this array.
2300  *
2301  *  \ref py_mcdataarraydouble_setpartofvalues3 "Here is a Python example".
2302  */
2303 void DataArrayDouble::setPartOfValues3(const DataArrayDouble *a, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare) throw(INTERP_KERNEL::Exception)
2304 {
2305   if(!a)
2306     throw INTERP_KERNEL::Exception("DataArrayDouble::setPartOfValues3 : input DataArrayDouble is NULL !");
2307   const char msg[]="DataArrayDouble::setPartOfValues3";
2308   checkAllocated();
2309   a->checkAllocated();
2310   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
2311   int nbComp=getNumberOfComponents();
2312   int nbOfTuples=getNumberOfTuples();
2313   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
2314   int newNbOfTuples=(int)std::distance(bgTuples,endTuples);
2315   bool assignTech=true;
2316   if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
2317     {
2318       if(strictCompoCompare)
2319         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
2320     }
2321   else
2322     {
2323       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
2324       assignTech=false;
2325     }
2326   double *pt=getPointer()+bgComp;
2327   const double *srcPt=a->getConstPointer();
2328   if(assignTech)
2329     {
2330       for(const int *w=bgTuples;w!=endTuples;w++)
2331         for(int j=0;j<newNbOfComp;j++,srcPt++)
2332           {
2333             DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
2334             pt[(std::size_t)(*w)*nbComp+j*stepComp]=*srcPt;
2335           }
2336     }
2337   else
2338     {
2339       for(const int *w=bgTuples;w!=endTuples;w++)
2340         {
2341           const double *srcPt2=srcPt;
2342           for(int j=0;j<newNbOfComp;j++,srcPt2++)
2343             {
2344               DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
2345               pt[(std::size_t)(*w)*nbComp+j*stepComp]=*srcPt2;
2346             }
2347         }
2348     }
2349 }
2350
2351 /*!
2352  * Assign a given value to values at specified tuples and components of \a this array.
2353  * The tuples to assign to are defined by a C array of indices.
2354  * The components to assign to are defined by three values similar to parameters of
2355  * the Python function \c range(\c start,\c stop,\c step).
2356  *  \param [in] a - the value to assign.
2357  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
2358  *              assign \a a to.
2359  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
2360  *              pointer to a tuple index <em>(pi)</em> varies as this: 
2361  *              \a bgTuples <= \a pi < \a endTuples.
2362  *  \param [in] bgComp - index of the first component of \a this array to assign to.
2363  *  \param [in] endComp - index of the component before which the components to assign
2364  *              to are located.
2365  *  \param [in] stepComp - index increment to get index of the next component to assign to.
2366  *  \throw If \a this is not allocated.
2367  *  \throw If any index of tuple given by \a bgTuples is out of a valid range for 
2368  *         \a this array.
2369  *  \throw If parameters specifying components to assign to, do not give a
2370  *            non-empty range of increasing indices or indices are out of a valid range
2371  *            for \this array.
2372  *
2373  *  \ref py_mcdataarraydouble_setpartofvaluessimple3 "Here is a Python example".
2374  */
2375 void DataArrayDouble::setPartOfValuesSimple3(double a, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp) throw(INTERP_KERNEL::Exception)
2376 {
2377   const char msg[]="DataArrayDouble::setPartOfValuesSimple3";
2378   checkAllocated();
2379   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
2380   int nbComp=getNumberOfComponents();
2381   int nbOfTuples=getNumberOfTuples();
2382   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
2383   double *pt=getPointer()+bgComp;
2384   for(const int *w=bgTuples;w!=endTuples;w++)
2385     for(int j=0;j<newNbOfComp;j++)
2386       {
2387         DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
2388         pt[(std::size_t)(*w)*nbComp+j*stepComp]=a;
2389       }
2390 }
2391
2392 /*!
2393  * Copy all values from another DataArrayDouble into specified tuples and components
2394  * of \a this array. Textual data is not copied.
2395  * The tree parameters defining set of indices of tuples and components are similar to
2396  * the tree parameters of the Python function \c range(\c start,\c stop,\c step).
2397  *  \param [in] a - the array to copy values from.
2398  *  \param [in] bgTuples - index of the first tuple of \a this array to assign values to.
2399  *  \param [in] endTuples - index of the tuple before which the tuples to assign to
2400  *              are located.
2401  *  \param [in] stepTuples - index increment to get index of the next tuple to assign to.
2402  *  \param [in] bgComp - pointer to an array of component indices of \a this array to
2403  *              assign \a a to.
2404  *  \param [in] endComp - specifies the end of the array \a bgTuples, so that
2405  *              pointer to a component index (\a pi) varies as this: 
2406  *              \a bgComp <= \a pi < \a endComp.
2407  *  \param [in] strictCompoCompare - if \a true (by default), then \a a->getNumberOfComponents() 
2408  *              must be equal to the number of columns to assign to, else an
2409  *              exception is thrown; if \a false, then it is only required that \a
2410  *              a->getNbOfElems() equals to number of values to assign to (this condition
2411  *              must be respected even if \a strictCompoCompare is \a true). The number of 
2412  *              values to assign to is given by following Python expression:
2413  *              \a nbTargetValues = 
2414  *              \c len(\c range(\a bgTuples,\a endTuples,\a stepTuples)) *
2415  *              \c len(\c range(\a bgComp,\a endComp,\a stepComp)).
2416  *  \throw If \a a is NULL.
2417  *  \throw If \a a is not allocated.
2418  *  \throw If \a this is not allocated.
2419  *  \throw If parameters specifying tuples and components to assign to do not give a
2420  *            non-empty range of increasing indices.
2421  *  \throw If \a a->getNbOfElems() != \a nbTargetValues.
2422  *  \throw If \a strictCompoCompare == \a true && \a a->getNumberOfComponents() !=
2423  *            \c len(\c range(\a bgComp,\a endComp,\a stepComp)).
2424  *
2425  */
2426 void DataArrayDouble::setPartOfValues4(const DataArrayDouble *a, int bgTuples, int endTuples, int stepTuples, const int *bgComp, const int *endComp, bool strictCompoCompare) throw(INTERP_KERNEL::Exception)
2427 {
2428   if(!a)
2429     throw INTERP_KERNEL::Exception("DataArrayDouble::setPartOfValues4 : input DataArrayDouble is NULL !");
2430   const char msg[]="DataArrayDouble::setPartOfValues4";
2431   checkAllocated();
2432   a->checkAllocated();
2433   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
2434   int newNbOfComp=(int)std::distance(bgComp,endComp);
2435   int nbComp=getNumberOfComponents();
2436   for(const int *z=bgComp;z!=endComp;z++)
2437     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
2438   int nbOfTuples=getNumberOfTuples();
2439   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
2440   bool assignTech=true;
2441   if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
2442     {
2443       if(strictCompoCompare)
2444         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
2445     }
2446   else
2447     {
2448       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
2449       assignTech=false;
2450     }
2451   const double *srcPt=a->getConstPointer();
2452   double *pt=getPointer()+bgTuples*nbComp;
2453   if(assignTech)
2454     {
2455       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
2456         for(const int *z=bgComp;z!=endComp;z++,srcPt++)
2457           pt[*z]=*srcPt;
2458     }
2459   else
2460     {
2461       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
2462         {
2463           const double *srcPt2=srcPt;
2464           for(const int *z=bgComp;z!=endComp;z++,srcPt2++)
2465             pt[*z]=*srcPt2;
2466         }
2467     }
2468 }
2469
2470 void DataArrayDouble::setPartOfValuesSimple4(double a, int bgTuples, int endTuples, int stepTuples, const int *bgComp, const int *endComp) throw(INTERP_KERNEL::Exception)
2471 {
2472   const char msg[]="DataArrayDouble::setPartOfValuesSimple4";
2473   checkAllocated();
2474   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
2475   int nbComp=getNumberOfComponents();
2476   for(const int *z=bgComp;z!=endComp;z++)
2477     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
2478   int nbOfTuples=getNumberOfTuples();
2479   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
2480   double *pt=getPointer()+bgTuples*nbComp;
2481   for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
2482     for(const int *z=bgComp;z!=endComp;z++)
2483       pt[*z]=a;
2484 }
2485
2486 /*!
2487  * Copy some tuples from another DataArrayDouble into specified tuples
2488  * of \a this array. Textual data is not copied. Both arrays must have equal number of
2489  * components.
2490  * Both the tuples to assign and the tuples to assign to are defined by a DataArrayInt.
2491  * All components of selected tuples are copied.
2492  *  \param [in] a - the array to copy values from.
2493  *  \param [in] tuplesSelec - the array specifying both source tuples of \a a and
2494  *              target tuples of \a this. \a tuplesSelec has two components, and the
2495  *              first component specifies index of the source tuple and the second
2496  *              one specifies index of the target tuple.
2497  *  \throw If \a this is not allocated.
2498  *  \throw If \a a is NULL.
2499  *  \throw If \a a is not allocated.
2500  *  \throw If \a tuplesSelec is NULL.
2501  *  \throw If \a tuplesSelec is not allocated.
2502  *  \throw If <em>this->getNumberOfComponents() != a->getNumberOfComponents()</em>.
2503  *  \throw If \a tuplesSelec->getNumberOfComponents() != 2.
2504  *  \throw If any tuple index given by \a tuplesSelec is out of a valid range for 
2505  *         the corresponding (\a this or \a a) array.
2506  */
2507 void DataArrayDouble::setPartOfValuesAdv(const DataArrayDouble *a, const DataArrayInt *tuplesSelec) throw(INTERP_KERNEL::Exception)
2508 {
2509   if(!a || !tuplesSelec)
2510     throw INTERP_KERNEL::Exception("DataArrayDouble::setPartOfValuesAdv : input DataArrayDouble is NULL !");
2511   checkAllocated();
2512   a->checkAllocated();
2513   tuplesSelec->checkAllocated();
2514   int nbOfComp=getNumberOfComponents();
2515   if(nbOfComp!=a->getNumberOfComponents())
2516     throw INTERP_KERNEL::Exception("DataArrayDouble::setPartOfValuesAdv : This and a do not have the same number of components !");
2517   if(tuplesSelec->getNumberOfComponents()!=2)
2518     throw INTERP_KERNEL::Exception("DataArrayDouble::setPartOfValuesAdv : Expecting to have a tuple selector DataArrayInt instance with exactly 2 components !");
2519   int thisNt=getNumberOfTuples();
2520   int aNt=a->getNumberOfTuples();
2521   double *valsToSet=getPointer();
2522   const double *valsSrc=a->getConstPointer();
2523   for(const int *tuple=tuplesSelec->begin();tuple!=tuplesSelec->end();tuple+=2)
2524     {
2525       if(tuple[1]>=0 && tuple[1]<aNt)
2526         {
2527           if(tuple[0]>=0 && tuple[0]<thisNt)
2528             std::copy(valsSrc+nbOfComp*tuple[1],valsSrc+nbOfComp*(tuple[1]+1),valsToSet+nbOfComp*tuple[0]);
2529           else
2530             {
2531               std::ostringstream oss; oss << "DataArrayDouble::setPartOfValuesAdv : Tuple #" << std::distance(tuplesSelec->begin(),tuple)/2;
2532               oss << " of 'tuplesSelec' request of tuple id #" << tuple[0] << " in 'this' ! It should be in [0," << thisNt << ") !";
2533               throw INTERP_KERNEL::Exception(oss.str().c_str());
2534             }
2535         }
2536       else
2537         {
2538           std::ostringstream oss; oss << "DataArrayDouble::setPartOfValuesAdv : Tuple #" << std::distance(tuplesSelec->begin(),tuple)/2;
2539           oss << " of 'tuplesSelec' request of tuple id #" << tuple[1] << " in 'a' ! It should be in [0," << aNt << ") !";
2540           throw INTERP_KERNEL::Exception(oss.str().c_str());
2541         }
2542     }
2543 }
2544
2545 /*!
2546  * Copy some tuples from another DataArrayDouble (\a a) into contiguous tuples
2547  * of \a this array. Textual data is not copied. Both arrays must have equal number of
2548  * components.
2549  * The tuples to assign to are defined by index of the first tuple, and
2550  * their number is defined by \a tuplesSelec->getNumberOfTuples().
2551  * The tuples to copy are defined by values of a DataArrayInt.
2552  * All components of selected tuples are copied.
2553  *  \param [in] tupleIdStart - index of the first tuple of \a this array to assign
2554  *              values to.
2555  *  \param [in] a - the array to copy values from.
2556  *  \param [in] tuplesSelec - the array specifying tuples of \a a to copy.
2557  *  \throw If \a this is not allocated.
2558  *  \throw If \a a is NULL.
2559  *  \throw If \a a is not allocated.
2560  *  \throw If \a tuplesSelec is NULL.
2561  *  \throw If \a tuplesSelec is not allocated.
2562  *  \throw If <em>this->getNumberOfComponents() != a->getNumberOfComponents()</em>.
2563  *  \throw If \a tuplesSelec->getNumberOfComponents() != 1.
2564  *  \throw If <em>tupleIdStart + tuplesSelec->getNumberOfTuples() > this->getNumberOfTuples().</em>
2565  *  \throw If any tuple index given by \a tuplesSelec is out of a valid range for 
2566  *         \a a array.
2567  */
2568 void DataArrayDouble::setContigPartOfSelectedValues(int tupleIdStart, const DataArray *aBase, const DataArrayInt *tuplesSelec) throw(INTERP_KERNEL::Exception)
2569 {
2570   if(!aBase || !tuplesSelec)
2571     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues : input DataArray is NULL !");
2572   const DataArrayDouble *a=dynamic_cast<const DataArrayDouble *>(aBase);
2573   if(!a)
2574     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues : input DataArray aBase is not a DataArrayDouble !");
2575   checkAllocated();
2576   a->checkAllocated();
2577   tuplesSelec->checkAllocated();
2578   int nbOfComp=getNumberOfComponents();
2579   if(nbOfComp!=a->getNumberOfComponents())
2580     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues : This and a do not have the same number of components !");
2581   if(tuplesSelec->getNumberOfComponents()!=1)
2582     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues : Expecting to have a tuple selector DataArrayInt instance with exactly 1 component !");
2583   int thisNt=getNumberOfTuples();
2584   int aNt=a->getNumberOfTuples();
2585   int nbOfTupleToWrite=tuplesSelec->getNumberOfTuples();
2586   double *valsToSet=getPointer()+tupleIdStart*nbOfComp;
2587   if(tupleIdStart+nbOfTupleToWrite>thisNt)
2588     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues : invalid number range of values to write !");
2589   const double *valsSrc=a->getConstPointer();
2590   for(const int *tuple=tuplesSelec->begin();tuple!=tuplesSelec->end();tuple++,valsToSet+=nbOfComp)
2591     {
2592       if(*tuple>=0 && *tuple<aNt)
2593         {
2594           std::copy(valsSrc+nbOfComp*(*tuple),valsSrc+nbOfComp*(*tuple+1),valsToSet);
2595         }
2596       else
2597         {
2598           std::ostringstream oss; oss << "DataArrayDouble::setContigPartOfSelectedValues : Tuple #" << std::distance(tuplesSelec->begin(),tuple);
2599           oss << " of 'tuplesSelec' request of tuple id #" << *tuple << " in 'a' ! It should be in [0," << aNt << ") !";
2600           throw INTERP_KERNEL::Exception(oss.str().c_str());
2601         }
2602     }
2603 }
2604
2605 /*!
2606  * Copy some tuples from another DataArrayDouble (\a a) into contiguous tuples
2607  * of \a this array. Textual data is not copied. Both arrays must have equal number of
2608  * components.
2609  * The tuples to copy are defined by three values similar to parameters of
2610  * the Python function \c range(\c start,\c stop,\c step).
2611  * The tuples to assign to are defined by index of the first tuple, and
2612  * their number is defined by number of tuples to copy.
2613  * All components of selected tuples are copied.
2614  *  \param [in] tupleIdStart - index of the first tuple of \a this array to assign
2615  *              values to.
2616  *  \param [in] a - the array to copy values from.
2617  *  \param [in] bg - index of the first tuple to copy of the array \a a.
2618  *  \param [in] end2 - index of the tuple of \a a before which the tuples to copy
2619  *              are located.
2620  *  \param [in] step - index increment to get index of the next tuple to copy.
2621  *  \throw If \a this is not allocated.
2622  *  \throw If \a a is NULL.
2623  *  \throw If \a a is not allocated.
2624  *  \throw If <em>this->getNumberOfComponents() != a->getNumberOfComponents()</em>.
2625  *  \throw If <em>tupleIdStart + len(range(bg,end2,step)) > this->getNumberOfTuples().</em>
2626  *  \throw If parameters specifying tuples to copy, do not give a
2627  *            non-empty range of increasing indices or indices are out of a valid range
2628  *            for the array \a a.
2629  */
2630 void DataArrayDouble::setContigPartOfSelectedValues2(int tupleIdStart, const DataArray *aBase, int bg, int end2, int step) throw(INTERP_KERNEL::Exception)
2631 {
2632   if(!aBase)
2633     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues2 : input DataArray is NULL !");
2634   const DataArrayDouble *a=dynamic_cast<const DataArrayDouble *>(aBase);
2635   if(!a)
2636     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues2 : input DataArray aBase is not a DataArrayDouble !");
2637   checkAllocated();
2638   a->checkAllocated();
2639   int nbOfComp=getNumberOfComponents();
2640   const char msg[]="DataArrayDouble::setContigPartOfSelectedValues2";
2641   int nbOfTupleToWrite=DataArray::GetNumberOfItemGivenBES(bg,end2,step,msg);
2642   if(nbOfComp!=a->getNumberOfComponents())
2643     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues2 : This and a do not have the same number of components !");
2644   int thisNt=getNumberOfTuples();
2645   int aNt=a->getNumberOfTuples();
2646   double *valsToSet=getPointer()+tupleIdStart*nbOfComp;
2647   if(tupleIdStart+nbOfTupleToWrite>thisNt)
2648     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues2 : invalid number range of values to write !");
2649   if(end2>aNt)
2650     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues2 : invalid range of values to read !");
2651   const double *valsSrc=a->getConstPointer()+bg*nbOfComp;
2652   for(int i=0;i<nbOfTupleToWrite;i++,valsToSet+=nbOfComp,valsSrc+=step*nbOfComp)
2653     {
2654       std::copy(valsSrc,valsSrc+nbOfComp,valsToSet);
2655     }
2656 }
2657
2658 /*!
2659  * Returns a value located at specified tuple and component.
2660  * This method is equivalent to DataArrayDouble::getIJ() except that validity of
2661  * parameters is checked. So this method is safe but expensive if used to go through
2662  * all values of \a this.
2663  *  \param [in] tupleId - index of tuple of interest.
2664  *  \param [in] compoId - index of component of interest.
2665  *  \return double - value located by \a tupleId and \a compoId.
2666  *  \throw If \a this is not allocated.
2667  *  \throw If condition <em>( 0 <= tupleId < this->getNumberOfTuples() )</em> is violated.
2668  *  \throw If condition <em>( 0 <= compoId < this->getNumberOfComponents() )</em> is violated.
2669  */
2670 double DataArrayDouble::getIJSafe(int tupleId, int compoId) const throw(INTERP_KERNEL::Exception)
2671 {
2672   checkAllocated();
2673   if(tupleId<0 || tupleId>=getNumberOfTuples())
2674     {
2675       std::ostringstream oss; oss << "DataArrayDouble::getIJSafe : request for tupleId " << tupleId << " should be in [0," << getNumberOfTuples() << ") !";
2676       throw INTERP_KERNEL::Exception(oss.str().c_str());
2677     }
2678   if(compoId<0 || compoId>=getNumberOfComponents())
2679     {
2680       std::ostringstream oss; oss << "DataArrayDouble::getIJSafe : request for compoId " << compoId << " should be in [0," << getNumberOfComponents() << ") !";
2681       throw INTERP_KERNEL::Exception(oss.str().c_str());
2682     }
2683   return _mem[tupleId*_info_on_compo.size()+compoId];
2684 }
2685
2686 /*!
2687  * Returns the first value of \a this. 
2688  *  \return double - the last value of \a this array.
2689  *  \throw If \a this is not allocated.
2690  *  \throw If \a this->getNumberOfComponents() != 1.
2691  *  \throw If \a this->getNumberOfTuples() < 1.
2692  */
2693 double DataArrayDouble::front() const throw(INTERP_KERNEL::Exception)
2694 {
2695   checkAllocated();
2696   if(getNumberOfComponents()!=1)
2697     throw INTERP_KERNEL::Exception("DataArrayDouble::front : number of components not equal to one !");
2698   int nbOfTuples=getNumberOfTuples();
2699   if(nbOfTuples<1)
2700     throw INTERP_KERNEL::Exception("DataArrayDouble::front : number of tuples must be >= 1 !");
2701   return *(getConstPointer());
2702 }
2703
2704 /*!
2705  * Returns the last value of \a this. 
2706  *  \return double - the last value of \a this array.
2707  *  \throw If \a this is not allocated.
2708  *  \throw If \a this->getNumberOfComponents() != 1.
2709  *  \throw If \a this->getNumberOfTuples() < 1.
2710  */
2711 double DataArrayDouble::back() const throw(INTERP_KERNEL::Exception)
2712 {
2713   checkAllocated();
2714   if(getNumberOfComponents()!=1)
2715     throw INTERP_KERNEL::Exception("DataArrayDouble::back : number of components not equal to one !");
2716   int nbOfTuples=getNumberOfTuples();
2717   if(nbOfTuples<1)
2718     throw INTERP_KERNEL::Exception("DataArrayDouble::back : number of tuples must be >= 1 !");
2719   return *(getConstPointer()+nbOfTuples-1);
2720 }
2721
2722 void DataArrayDouble::SetArrayIn(DataArrayDouble *newArray, DataArrayDouble* &arrayToSet)
2723 {
2724   if(newArray!=arrayToSet)
2725     {
2726       if(arrayToSet)
2727         arrayToSet->decrRef();
2728       arrayToSet=newArray;
2729       if(arrayToSet)
2730         arrayToSet->incrRef();
2731     }
2732 }
2733
2734 /*!
2735  * Sets a C array to be used as raw data of \a this. The previously set info
2736  *  of components is retained and re-sized. 
2737  * For more info see \ref MEDCouplingArraySteps1.
2738  *  \param [in] array - the C array to be used as raw data of \a this.
2739  *  \param [in] ownership - if \a true, \a array will be deallocated at destruction of \a this.
2740  *  \param [in] type - specifies how to deallocate \a array. If \a type == ParaMEDMEM::CPP_DEALLOC,
2741  *                     \c delete [] \c array; will be called. If \a type == ParaMEDMEM::C_DEALLOC,
2742  *                     \c free(\c array ) will be called.
2743  *  \param [in] nbOfTuple - new number of tuples in \a this.
2744  *  \param [in] nbOfCompo - new number of components in \a this.
2745  */
2746 void DataArrayDouble::useArray(const double *array, bool ownership, DeallocType type, int nbOfTuple, int nbOfCompo) throw(INTERP_KERNEL::Exception)
2747 {
2748   _info_on_compo.resize(nbOfCompo);
2749   _mem.useArray(array,ownership,type,(std::size_t)nbOfTuple*nbOfCompo);
2750   declareAsNew();
2751 }
2752
2753 void DataArrayDouble::useExternalArrayWithRWAccess(const double *array, int nbOfTuple, int nbOfCompo) throw(INTERP_KERNEL::Exception)
2754 {
2755   _info_on_compo.resize(nbOfCompo);
2756   _mem.useExternalArrayWithRWAccess(array,(std::size_t)nbOfTuple*nbOfCompo);
2757   declareAsNew();
2758 }
2759
2760 /*!
2761  * Checks if 0.0 value is present in \a this array. If it is the case, an exception
2762  * is thrown.
2763  * \throw If zero is found in \a this array.
2764  */
2765 void DataArrayDouble::checkNoNullValues() const throw(INTERP_KERNEL::Exception)
2766 {
2767   const double *tmp=getConstPointer();
2768   std::size_t nbOfElems=getNbOfElems();
2769   const double *where=std::find(tmp,tmp+nbOfElems,0.);
2770   if(where!=tmp+nbOfElems)
2771     throw INTERP_KERNEL::Exception("A value 0.0 have been detected !");
2772 }
2773
2774 /*!
2775  * Computes minimal and maximal value in each component. An output array is filled
2776  * with \c 2 * \a this->getNumberOfComponents() values, so the caller is to allocate
2777  * enough memory before calling this method.
2778  *  \param [out] bounds - array of size at least 2 *\a this->getNumberOfComponents().
2779  *               It is filled as follows:<br>
2780  *               \a bounds[0] = \c min_of_component_0 <br>
2781  *               \a bounds[1] = \c max_of_component_0 <br>
2782  *               \a bounds[2] = \c min_of_component_1 <br>
2783  *               \a bounds[3] = \c max_of_component_1 <br>
2784  *               ...
2785  */
2786 void DataArrayDouble::getMinMaxPerComponent(double *bounds) const throw(INTERP_KERNEL::Exception)
2787 {
2788   checkAllocated();
2789   int dim=getNumberOfComponents();
2790   for (int idim=0; idim<dim; idim++)
2791     {
2792       bounds[idim*2]=std::numeric_limits<double>::max();
2793       bounds[idim*2+1]=-std::numeric_limits<double>::max();
2794     } 
2795   const double *ptr=getConstPointer();
2796   int nbOfTuples=getNumberOfTuples();
2797   for(int i=0;i<nbOfTuples;i++)
2798     {
2799       for(int idim=0;idim<dim;idim++)
2800         {
2801           if(bounds[idim*2]>ptr[i*dim+idim])
2802             {
2803               bounds[idim*2]=ptr[i*dim+idim];
2804             }
2805           if(bounds[idim*2+1]<ptr[i*dim+idim])
2806             {
2807               bounds[idim*2+1]=ptr[i*dim+idim];
2808             }
2809         }
2810     }
2811 }
2812
2813 /*!
2814  * This method retrieves a newly allocated DataArrayDouble instance having same number of tuples than \a this and twice number of components than \a this
2815  * to store both the min and max per component of each tuples. 
2816  * \param [in] epsilon the width of the bbox (identical in each direction) - 0.0 by default
2817  *
2818  * \return a newly created DataArrayDouble instance having \c this->getNumberOfTuples() tuples and 2 * \c this->getNumberOfComponent() components
2819  *
2820  * \throw If \a this is not allocated yet.
2821  */
2822 DataArrayDouble *DataArrayDouble::computeBBoxPerTuple(double epsilon)const throw(INTERP_KERNEL::Exception)
2823 {
2824   checkAllocated();
2825   const double *dataPtr=getConstPointer();
2826   int nbOfCompo=getNumberOfComponents();
2827   int nbTuples=getNumberOfTuples();
2828   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> bbox=DataArrayDouble::New();
2829   bbox->alloc(nbTuples,2*nbOfCompo);
2830   double *bboxPtr=bbox->getPointer();
2831   for(int i=0;i<nbTuples;i++)
2832     {
2833       for(int j=0;j<nbOfCompo;j++)
2834         {
2835           bboxPtr[2*nbOfCompo*i+2*j]=dataPtr[nbOfCompo*i+j]-epsilon;
2836           bboxPtr[2*nbOfCompo*i+2*j+1]=dataPtr[nbOfCompo*i+j]+epsilon;
2837         }
2838     }
2839   return bbox.retn();
2840 }
2841
2842 /*!
2843  * For each tuples **t** in \a other, this method retrieves tuples in \a this that are equal to **t**.
2844  * Two tuples are considered equal if the euclidian distance between the two tuples is lower than \a eps.
2845  * 
2846  * \param [in] other a DataArrayDouble having same number of components than \a this.
2847  * \param [in] eps absolute precision representing distance (using infinite norm) between 2 tuples behind which 2 tuples are considered equal.
2848  * \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.
2849  *             \a cI allows to extract information in \a c.
2850  * \param [out] cI is an indirection array that allows to extract the data contained in \a c.
2851  *
2852  * \throw In case of:
2853  *  - \a this is not allocated
2854  *  - \a other is not allocated or null
2855  *  - \a this and \a other do not have the same number of components
2856  *  - if number of components of \a this is not in [1,2,3]
2857  *
2858  * \sa MEDCouplingPointSet::getNodeIdsNearPoints, DataArrayDouble::getDifferentValues
2859  */
2860 void DataArrayDouble::computeTupleIdsNearTuples(const DataArrayDouble *other, double eps, DataArrayInt *& c, DataArrayInt *& cI) const throw(INTERP_KERNEL::Exception)
2861 {
2862   if(!other)
2863     throw INTERP_KERNEL::Exception("DataArrayDouble::computeTupleIdsNearTuples : input pointer other is null !");
2864   checkAllocated();
2865   other->checkAllocated();
2866   int nbOfCompo=getNumberOfComponents();
2867   int otherNbOfCompo=other->getNumberOfComponents();
2868   if(nbOfCompo!=otherNbOfCompo)
2869     throw INTERP_KERNEL::Exception("DataArrayDouble::computeTupleIdsNearTuples : number of components should be equal between this and other !");
2870   int nbOfTuplesOther=other->getNumberOfTuples();
2871   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cArr(DataArrayInt::New()),cIArr(DataArrayInt::New()); cArr->alloc(0,1); cIArr->pushBackSilent(0);
2872   switch(nbOfCompo)
2873     {
2874     case 3:
2875       {
2876         BBTreePts<3,int> myTree(begin(),0,0,getNumberOfTuples(),eps);
2877         FindTupleIdsNearTuplesAlg<3>(myTree,other->getConstPointer(),nbOfTuplesOther,eps,cArr,cIArr);
2878         break;
2879       }
2880     case 2:
2881       {
2882         BBTreePts<2,int> myTree(begin(),0,0,getNumberOfTuples(),eps);
2883         FindTupleIdsNearTuplesAlg<2>(myTree,other->getConstPointer(),nbOfTuplesOther,eps,cArr,cIArr);
2884         break;
2885       }
2886     case 1:
2887       {
2888         BBTreePts<1,int> myTree(begin(),0,0,getNumberOfTuples(),eps);
2889         FindTupleIdsNearTuplesAlg<1>(myTree,other->getConstPointer(),nbOfTuplesOther,eps,cArr,cIArr);
2890         break;
2891       }
2892     default:
2893       throw INTERP_KERNEL::Exception("Unexpected spacedim of coords for computeTupleIdsNearTuples. Must be 1, 2 or 3.");
2894     }
2895   c=cArr.retn(); cI=cIArr.retn();
2896 }
2897
2898 /*!
2899  * 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
2900  * around origin of 'radius' 1.
2901  * 
2902  * \param [in] eps absolute epsilon. under that value of delta between max and min no scale is performed.
2903  */
2904 void DataArrayDouble::recenterForMaxPrecision(double eps) throw(INTERP_KERNEL::Exception)
2905 {
2906   checkAllocated();
2907   int dim=getNumberOfComponents();
2908   std::vector<double> bounds(2*dim);
2909   getMinMaxPerComponent(&bounds[0]);
2910   for(int i=0;i<dim;i++)
2911     {
2912       double delta=bounds[2*i+1]-bounds[2*i];
2913       double offset=(bounds[2*i]+bounds[2*i+1])/2.;
2914       if(delta>eps)
2915         applyLin(1./delta,-offset/delta,i);
2916       else
2917         applyLin(1.,-offset,i);
2918     }
2919 }
2920
2921 /*!
2922  * Returns the maximal value and its location within \a this one-dimensional array.
2923  *  \param [out] tupleId - index of the tuple holding the maximal value.
2924  *  \return double - the maximal value among all values of \a this array.
2925  *  \throw If \a this->getNumberOfComponents() != 1
2926  *  \throw If \a this->getNumberOfTuples() < 1
2927  */
2928 double DataArrayDouble::getMaxValue(int& tupleId) const throw(INTERP_KERNEL::Exception)
2929 {
2930   checkAllocated();
2931   if(getNumberOfComponents()!=1)
2932     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 !");
2933   int nbOfTuples=getNumberOfTuples();
2934   if(nbOfTuples<=0)
2935     throw INTERP_KERNEL::Exception("DataArrayDouble::getMaxValue : array exists but number of tuples must be > 0 !");
2936   const double *vals=getConstPointer();
2937   const double *loc=std::max_element(vals,vals+nbOfTuples);
2938   tupleId=(int)std::distance(vals,loc);
2939   return *loc;
2940 }
2941
2942 /*!
2943  * Returns the maximal value within \a this array that is allowed to have more than
2944  *  one component.
2945  *  \return double - the maximal value among all values of \a this array.
2946  *  \throw If \a this is not allocated.
2947  */
2948 double DataArrayDouble::getMaxValueInArray() const throw(INTERP_KERNEL::Exception)
2949 {
2950   checkAllocated();
2951   const double *loc=std::max_element(begin(),end());
2952   return *loc;
2953 }
2954
2955 /*!
2956  * Returns the maximal value and all its locations within \a this one-dimensional array.
2957  *  \param [out] tupleIds - a new instance of DataArrayInt containg indices of
2958  *               tuples holding the maximal value. The caller is to delete it using
2959  *               decrRef() as it is no more needed.
2960  *  \return double - the maximal value among all values of \a this array.
2961  *  \throw If \a this->getNumberOfComponents() != 1
2962  *  \throw If \a this->getNumberOfTuples() < 1
2963  */
2964 double DataArrayDouble::getMaxValue2(DataArrayInt*& tupleIds) const throw(INTERP_KERNEL::Exception)
2965 {
2966   int tmp;
2967   tupleIds=0;
2968   double ret=getMaxValue(tmp);
2969   tupleIds=getIdsInRange(ret,ret);
2970   return ret;
2971 }
2972
2973 /*!
2974  * Returns the minimal value and its location within \a this one-dimensional array.
2975  *  \param [out] tupleId - index of the tuple holding the minimal value.
2976  *  \return double - the minimal value among all values of \a this array.
2977  *  \throw If \a this->getNumberOfComponents() != 1
2978  *  \throw If \a this->getNumberOfTuples() < 1
2979  */
2980 double DataArrayDouble::getMinValue(int& tupleId) const throw(INTERP_KERNEL::Exception)
2981 {
2982   checkAllocated();
2983   if(getNumberOfComponents()!=1)
2984     throw INTERP_KERNEL::Exception("DataArrayDouble::getMinValue : must be applied on DataArrayDouble with only one component, you can call 'rearrange' method before call 'getMinValueInArray' method !");
2985   int nbOfTuples=getNumberOfTuples();
2986   if(nbOfTuples<=0)
2987     throw INTERP_KERNEL::Exception("DataArrayDouble::getMinValue : array exists but number of tuples must be > 0 !");
2988   const double *vals=getConstPointer();
2989   const double *loc=std::min_element(vals,vals+nbOfTuples);
2990   tupleId=(int)std::distance(vals,loc);
2991   return *loc;
2992 }
2993
2994 /*!
2995  * Returns the minimal value within \a this array that is allowed to have more than
2996  *  one component.
2997  *  \return double - the minimal value among all values of \a this array.
2998  *  \throw If \a this is not allocated.
2999  */
3000 double DataArrayDouble::getMinValueInArray() const throw(INTERP_KERNEL::Exception)
3001 {
3002   checkAllocated();
3003   const double *loc=std::min_element(begin(),end());
3004   return *loc;
3005 }
3006
3007 /*!
3008  * Returns the minimal value and all its locations within \a this one-dimensional array.
3009  *  \param [out] tupleIds - a new instance of DataArrayInt containg indices of
3010  *               tuples holding the minimal value. The caller is to delete it using
3011  *               decrRef() as it is no more needed.
3012  *  \return double - the minimal value among all values of \a this array.
3013  *  \throw If \a this->getNumberOfComponents() != 1
3014  *  \throw If \a this->getNumberOfTuples() < 1
3015  */
3016 double DataArrayDouble::getMinValue2(DataArrayInt*& tupleIds) const throw(INTERP_KERNEL::Exception)
3017 {
3018   int tmp;
3019   tupleIds=0;
3020   double ret=getMinValue(tmp);
3021   tupleIds=getIdsInRange(ret,ret);
3022   return ret;
3023 }
3024
3025 /*!
3026  * 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.
3027  * This method only works for single component array.
3028  *
3029  * \return a value in [ 0, \c this->getNumberOfTuples() )
3030  *
3031  * \throw If \a this is not allocated
3032  *
3033  */
3034 int DataArrayDouble::count(double value, double eps) const throw(INTERP_KERNEL::Exception)
3035 {
3036   int ret=0;
3037   checkAllocated();
3038   if(getNumberOfComponents()!=1)
3039     throw INTERP_KERNEL::Exception("DataArrayDouble::count : must be applied on DataArrayDouble with only one component, you can call 'rearrange' method before !");
3040   const double *vals=begin();
3041   int nbOfTuples=getNumberOfTuples();
3042   for(int i=0;i<nbOfTuples;i++,vals++)
3043     if(fabs(*vals-value)<=eps)
3044       ret++;
3045   return ret;
3046 }
3047
3048 /*!
3049  * Returns the average value of \a this one-dimensional array.
3050  *  \return double - the average value over all values of \a this array.
3051  *  \throw If \a this->getNumberOfComponents() != 1
3052  *  \throw If \a this->getNumberOfTuples() < 1
3053  */
3054 double DataArrayDouble::getAverageValue() const throw(INTERP_KERNEL::Exception)
3055 {
3056   if(getNumberOfComponents()!=1)
3057     throw INTERP_KERNEL::Exception("DataArrayDouble::getAverageValue : must be applied on DataArrayDouble with only one component, you can call 'rearrange' method before !");
3058   int nbOfTuples=getNumberOfTuples();
3059   if(nbOfTuples<=0)
3060     throw INTERP_KERNEL::Exception("DataArrayDouble::getAverageValue : array exists but number of tuples must be > 0 !");
3061   const double *vals=getConstPointer();
3062   double ret=std::accumulate(vals,vals+nbOfTuples,0.);
3063   return ret/nbOfTuples;
3064 }
3065
3066 /*!
3067  * Returns the Euclidean norm of the vector defined by \a this array.
3068  *  \return double - the value of the Euclidean norm, i.e.
3069  *          the square root of the inner product of vector.
3070  *  \throw If \a this is not allocated.
3071  */
3072 double DataArrayDouble::norm2() const throw(INTERP_KERNEL::Exception)
3073 {
3074   checkAllocated();
3075   double ret=0.;
3076   std::size_t nbOfElems=getNbOfElems();
3077   const double *pt=getConstPointer();
3078   for(std::size_t i=0;i<nbOfElems;i++,pt++)
3079     ret+=(*pt)*(*pt);
3080   return sqrt(ret);
3081 }
3082
3083 /*!
3084  * Returns the maximum norm of the vector defined by \a this array.
3085  *  \return double - the value of the maximum norm, i.e.
3086  *          the maximal absolute value among values of \a this array.
3087  *  \throw If \a this is not allocated.
3088  */
3089 double DataArrayDouble::normMax() const throw(INTERP_KERNEL::Exception)
3090 {
3091   checkAllocated();
3092   double ret=-1.;
3093   std::size_t nbOfElems=getNbOfElems();
3094   const double *pt=getConstPointer();
3095   for(std::size_t i=0;i<nbOfElems;i++,pt++)
3096     {
3097       double val=std::abs(*pt);
3098       if(val>ret)
3099         ret=val;
3100     }
3101   return ret;
3102 }
3103
3104 /*!
3105  * Accumulates values of each component of \a this array.
3106  *  \param [out] res - an array of length \a this->getNumberOfComponents(), allocated 
3107  *         by the caller, that is filled by this method with sum value for each
3108  *         component.
3109  *  \throw If \a this is not allocated.
3110  */
3111 void DataArrayDouble::accumulate(double *res) const throw(INTERP_KERNEL::Exception)
3112 {
3113   checkAllocated();
3114   const double *ptr=getConstPointer();
3115   int nbTuple=getNumberOfTuples();
3116   int nbComps=getNumberOfComponents();
3117   std::fill(res,res+nbComps,0.);
3118   for(int i=0;i<nbTuple;i++)
3119     std::transform(ptr+i*nbComps,ptr+(i+1)*nbComps,res,res,std::plus<double>());
3120 }
3121
3122 /*!
3123  * This method returns the min distance from an external tuple defined by [ \a tupleBg , \a tupleEnd ) to \a this and
3124  * the first tuple in \a this that matches the returned distance. If there is no tuples in \a this an exception will be thrown.
3125  *
3126  *
3127  * \a this is expected to be allocated and expected to have a number of components equal to the distance from \a tupleBg to
3128  * \a tupleEnd. If not an exception will be thrown.
3129  *
3130  * \param [in] tupleBg start pointer (included) of input external tuple
3131  * \param [in] tupleEnd end pointer (not included) of input external tuple
3132  * \param [out] tupleId the tuple id in \a this that matches the min of distance between \a this and input external tuple
3133  * \return the min distance.
3134  * \sa MEDCouplingUMesh::distanceToPoint
3135  */
3136 double DataArrayDouble::distanceToTuple(const double *tupleBg, const double *tupleEnd, int& tupleId) const throw(INTERP_KERNEL::Exception)
3137 {
3138   checkAllocated();
3139   int nbTuple=getNumberOfTuples();
3140   int nbComps=getNumberOfComponents();
3141   if(nbComps!=(int)std::distance(tupleBg,tupleEnd))
3142     { 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()); }
3143   if(nbTuple==0)
3144     throw INTERP_KERNEL::Exception("DataArrayDouble::distanceToTuple : no tuple in this ! No distance to compute !");
3145   double ret0=std::numeric_limits<double>::max();
3146   tupleId=-1;
3147   const double *work=getConstPointer();
3148   for(int i=0;i<nbTuple;i++)
3149     {
3150       double val=0.;
3151       for(int j=0;j<nbComps;j++,work++) 
3152         val+=(*work-tupleBg[j])*((*work-tupleBg[j]));
3153       if(val>=ret0)
3154         continue;
3155       else
3156         { ret0=val; tupleId=i; }
3157     }
3158   return sqrt(ret0);
3159 }
3160
3161 /*!
3162  * Accumulate values of the given component of \a this array.
3163  *  \param [in] compId - the index of the component of interest.
3164  *  \return double - a sum value of \a compId-th component.
3165  *  \throw If \a this is not allocated.
3166  *  \throw If \a the condition ( 0 <= \a compId < \a this->getNumberOfComponents() ) is
3167  *         not respected.
3168  */
3169 double DataArrayDouble::accumulate(int compId) const throw(INTERP_KERNEL::Exception)
3170 {
3171   checkAllocated();
3172   const double *ptr=getConstPointer();
3173   int nbTuple=getNumberOfTuples();
3174   int nbComps=getNumberOfComponents();
3175   if(compId<0 || compId>=nbComps)
3176     throw INTERP_KERNEL::Exception("DataArrayDouble::accumulate : Invalid compId specified : No such nb of components !");
3177   double ret=0.;
3178   for(int i=0;i<nbTuple;i++)
3179     ret+=ptr[i*nbComps+compId];
3180   return ret;
3181 }
3182
3183 /*!
3184  * This method accumulate using addition tuples in \a this using input index array [ \a bgOfIndex, \a endOfIndex ).
3185  * The returned array will have same number of components than \a this and number of tuples equal to
3186  * \c std::distance(bgOfIndex,endOfIndex) \b minus \b one.
3187  *
3188  * The input index array is expected to be ascendingly sorted in which the all referenced ids should be in [0, \c this->getNumberOfTuples).
3189  * 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.
3190  *
3191  * \param [in] bgOfIndex - begin (included) of the input index array.
3192  * \param [in] endOfIndex - end (excluded) of the input index array.
3193  * \return DataArrayDouble * - the new instance having the same number of components than \a this.
3194  * 
3195  * \throw If bgOfIndex or end is NULL.
3196  * \throw If input index array is not ascendingly sorted.
3197  * \throw If there is an id in [ \a bgOfIndex, \a endOfIndex ) not in [0, \c this->getNumberOfTuples).
3198  * \throw If std::distance(bgOfIndex,endOfIndex)==0.
3199  */
3200 DataArrayDouble *DataArrayDouble::accumulatePerChunck(const int *bgOfIndex, const int *endOfIndex) const throw(INTERP_KERNEL::Exception)
3201 {
3202   if(!bgOfIndex || !endOfIndex)
3203     throw INTERP_KERNEL::Exception("DataArrayDouble::accumulatePerChunck : input pointer NULL !");
3204   checkAllocated();
3205   int nbCompo=getNumberOfComponents();
3206   int nbOfTuples=getNumberOfTuples();
3207   int sz=(int)std::distance(bgOfIndex,endOfIndex);
3208   if(sz<1)
3209     throw INTERP_KERNEL::Exception("DataArrayDouble::accumulatePerChunck : invalid size of input index array !");
3210   sz--;
3211   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New(); ret->alloc(sz,nbCompo);
3212   const int *w=bgOfIndex;
3213   if(*w<0 || *w>=nbOfTuples)
3214     throw INTERP_KERNEL::Exception("DataArrayDouble::accumulatePerChunck : The first element of the input index not in [0,nbOfTuples) !");
3215   const double *srcPt=begin()+(*w)*nbCompo;
3216   double *tmp=ret->getPointer();
3217   for(int i=0;i<sz;i++,tmp+=nbCompo,w++)
3218     {
3219       std::fill(tmp,tmp+nbCompo,0.);
3220       if(w[1]>=w[0])
3221         {
3222           for(int j=w[0];j<w[1];j++,srcPt+=nbCompo)
3223             {
3224               if(j>=0 && j<nbOfTuples)
3225                 std::transform(srcPt,srcPt+nbCompo,tmp,tmp,std::plus<double>());
3226               else
3227                 {
3228                   std::ostringstream oss; oss << "DataArrayDouble::accumulatePerChunck : At rank #" << i << " the input index array points to id " << j << " should be in [0," << nbOfTuples << ") !";
3229                   throw INTERP_KERNEL::Exception(oss.str().c_str());
3230                 }
3231             }
3232         }
3233       else
3234         {
3235           std::ostringstream oss; oss << "DataArrayDouble::accumulatePerChunck : At rank #" << i << " the input index array is not in ascendingly sorted.";
3236           throw INTERP_KERNEL::Exception(oss.str().c_str());
3237         }
3238     }
3239   ret->copyStringInfoFrom(*this);
3240   return ret.retn();
3241 }
3242
3243 /*!
3244  * Converts each 2D point defined by the tuple of \a this array from the Polar to the
3245  * Cartesian coordinate system. The two components of the tuple of \a this array are 
3246  * considered to contain (1) radius and (2) angle of the point in the Polar CS.
3247  *  \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
3248  *          contains X and Y coordinates of the point in the Cartesian CS. The caller
3249  *          is to delete this array using decrRef() as it is no more needed. The array
3250  *          does not contain any textual info on components.
3251  *  \throw If \a this->getNumberOfComponents() != 2.
3252  */
3253 DataArrayDouble *DataArrayDouble::fromPolarToCart() const throw(INTERP_KERNEL::Exception)
3254 {
3255   checkAllocated();
3256   int nbOfComp=getNumberOfComponents();
3257   if(nbOfComp!=2)
3258     throw INTERP_KERNEL::Exception("DataArrayDouble::fromPolarToCart : must be an array with exactly 2 components !");
3259   int nbOfTuple=getNumberOfTuples();
3260   DataArrayDouble *ret=DataArrayDouble::New();
3261   ret->alloc(nbOfTuple,2);
3262   double *w=ret->getPointer();
3263   const double *wIn=getConstPointer();
3264   for(int i=0;i<nbOfTuple;i++,w+=2,wIn+=2)
3265     {
3266       w[0]=wIn[0]*cos(wIn[1]);
3267       w[1]=wIn[0]*sin(wIn[1]);
3268     }
3269   return ret;
3270 }
3271
3272 /*!
3273  * Converts each 3D point defined by the tuple of \a this array from the Cylindrical to
3274  * the Cartesian coordinate system. The three components of the tuple of \a this array 
3275  * are considered to contain (1) radius, (2) azimuth and (3) altitude of the point in
3276  * the Cylindrical CS.
3277  *  \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
3278  *          contains X, Y and Z coordinates of the point in the Cartesian CS. The info
3279  *          on the third component is copied from \a this array. The caller
3280  *          is to delete this array using decrRef() as it is no more needed. 
3281  *  \throw If \a this->getNumberOfComponents() != 3.
3282  */
3283 DataArrayDouble *DataArrayDouble::fromCylToCart() const throw(INTERP_KERNEL::Exception)
3284 {
3285   checkAllocated();
3286   int nbOfComp=getNumberOfComponents();
3287   if(nbOfComp!=3)
3288     throw INTERP_KERNEL::Exception("DataArrayDouble::fromCylToCart : must be an array with exactly 3 components !");
3289   int nbOfTuple=getNumberOfTuples();
3290   DataArrayDouble *ret=DataArrayDouble::New();
3291   ret->alloc(getNumberOfTuples(),3);
3292   double *w=ret->getPointer();
3293   const double *wIn=getConstPointer();
3294   for(int i=0;i<nbOfTuple;i++,w+=3,wIn+=3)
3295     {
3296       w[0]=wIn[0]*cos(wIn[1]);
3297       w[1]=wIn[0]*sin(wIn[1]);
3298       w[2]=wIn[2];
3299     }
3300   ret->setInfoOnComponent(2,getInfoOnComponent(2).c_str());
3301   return ret;
3302 }
3303
3304 /*!
3305  * Converts each 3D point defined by the tuple of \a this array from the Spherical to
3306  * the Cartesian coordinate system. The three components of the tuple of \a this array 
3307  * are considered to contain (1) radius, (2) polar angle and (3) azimuthal angle of the
3308  * point in the Cylindrical CS.
3309  *  \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
3310  *          contains X, Y and Z coordinates of the point in the Cartesian CS. The info
3311  *          on the third component is copied from \a this array. The caller
3312  *          is to delete this array using decrRef() as it is no more needed.
3313  *  \throw If \a this->getNumberOfComponents() != 3.
3314  */
3315 DataArrayDouble *DataArrayDouble::fromSpherToCart() const throw(INTERP_KERNEL::Exception)
3316 {
3317   checkAllocated();
3318   int nbOfComp=getNumberOfComponents();
3319   if(nbOfComp!=3)
3320     throw INTERP_KERNEL::Exception("DataArrayDouble::fromSpherToCart : must be an array with exactly 3 components !");
3321   int nbOfTuple=getNumberOfTuples();
3322   DataArrayDouble *ret=DataArrayDouble::New();
3323   ret->alloc(getNumberOfTuples(),3);
3324   double *w=ret->getPointer();
3325   const double *wIn=getConstPointer();
3326   for(int i=0;i<nbOfTuple;i++,w+=3,wIn+=3)
3327     {
3328       w[0]=wIn[0]*cos(wIn[2])*sin(wIn[1]);
3329       w[1]=wIn[0]*sin(wIn[2])*sin(wIn[1]);
3330       w[2]=wIn[0]*cos(wIn[1]);
3331     }
3332   return ret;
3333 }
3334
3335 /*!
3336  * Computes the doubly contracted product of every tensor defined by the tuple of \a this
3337  * array contating 6 components.
3338  *  \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
3339  *          is calculated from the tuple <em>(t)</em> of \a this array as follows:
3340  *          \f$ t[0]^2+t[1]^2+t[2]^2+2*t[3]^2+2*t[4]^2+2*t[5]^2\f$.
3341  *         The caller is to delete this result array using decrRef() as it is no more needed. 
3342  *  \throw If \a this->getNumberOfComponents() != 6.
3343  */
3344 DataArrayDouble *DataArrayDouble::doublyContractedProduct() const throw(INTERP_KERNEL::Exception)
3345 {
3346   checkAllocated();
3347   int nbOfComp=getNumberOfComponents();
3348   if(nbOfComp!=6)
3349     throw INTERP_KERNEL::Exception("DataArrayDouble::doublyContractedProduct : must be an array with exactly 6 components !");
3350   DataArrayDouble *ret=DataArrayDouble::New();
3351   int nbOfTuple=getNumberOfTuples();
3352   ret->alloc(nbOfTuple,1);
3353   const double *src=getConstPointer();
3354   double *dest=ret->getPointer();
3355   for(int i=0;i<nbOfTuple;i++,dest++,src+=6)
3356     *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];
3357   return ret;
3358 }
3359
3360 /*!
3361  * Computes the determinant of every square matrix defined by the tuple of \a this
3362  * array, which contains either 4, 6 or 9 components. The case of 6 components
3363  * corresponds to that of the upper triangular matrix.
3364  *  \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
3365  *          is the determinant of matrix of the corresponding tuple of \a this array.
3366  *          The caller is to delete this result array using decrRef() as it is no more
3367  *          needed. 
3368  *  \throw If \a this->getNumberOfComponents() is not in [4,6,9].
3369  */
3370 DataArrayDouble *DataArrayDouble::determinant() const throw(INTERP_KERNEL::Exception)
3371 {
3372   checkAllocated();
3373   DataArrayDouble *ret=DataArrayDouble::New();
3374   int nbOfTuple=getNumberOfTuples();
3375   ret->alloc(nbOfTuple,1);
3376   const double *src=getConstPointer();
3377   double *dest=ret->getPointer();
3378   switch(getNumberOfComponents())
3379     {
3380     case 6:
3381       for(int i=0;i<nbOfTuple;i++,dest++,src+=6)
3382         *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];
3383       return ret;
3384     case 4:
3385       for(int i=0;i<nbOfTuple;i++,dest++,src+=4)
3386         *dest=src[0]*src[3]-src[1]*src[2];
3387       return ret;
3388     case 9:
3389       for(int i=0;i<nbOfTuple;i++,dest++,src+=9)
3390         *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];
3391       return ret;
3392     default:
3393       ret->decrRef();
3394       throw INTERP_KERNEL::Exception("DataArrayDouble::determinant : Invalid number of components ! must be in 4,6,9 !");
3395     }
3396 }
3397
3398 /*!
3399  * Computes 3 eigenvalues of every upper triangular matrix defined by the tuple of
3400  * \a this array, which contains 6 components.
3401  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing 3
3402  *          components, whose each tuple contains the eigenvalues of the matrix of
3403  *          corresponding tuple of \a this array. 
3404  *          The caller is to delete this result array using decrRef() as it is no more
3405  *          needed. 
3406  *  \throw If \a this->getNumberOfComponents() != 6.
3407  */
3408 DataArrayDouble *DataArrayDouble::eigenValues() const throw(INTERP_KERNEL::Exception)
3409 {
3410   checkAllocated();
3411   int nbOfComp=getNumberOfComponents();
3412   if(nbOfComp!=6)
3413     throw INTERP_KERNEL::Exception("DataArrayDouble::eigenValues : must be an array with exactly 6 components !");
3414   DataArrayDouble *ret=DataArrayDouble::New();
3415   int nbOfTuple=getNumberOfTuples();
3416   ret->alloc(nbOfTuple,3);
3417   const double *src=getConstPointer();
3418   double *dest=ret->getPointer();
3419   for(int i=0;i<nbOfTuple;i++,dest+=3,src+=6)
3420     INTERP_KERNEL::computeEigenValues6(src,dest);
3421   return ret;
3422 }
3423
3424 /*!
3425  * Computes 3 eigenvectors of every upper triangular matrix defined by the tuple of
3426  * \a this array, which contains 6 components.
3427  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing 9
3428  *          components, whose each tuple contains 3 eigenvectors of the matrix of
3429  *          corresponding tuple of \a this array.
3430  *          The caller is to delete this result array using decrRef() as it is no more
3431  *          needed.
3432  *  \throw If \a this->getNumberOfComponents() != 6.
3433  */
3434 DataArrayDouble *DataArrayDouble::eigenVectors() const throw(INTERP_KERNEL::Exception)
3435 {
3436   checkAllocated();
3437   int nbOfComp=getNumberOfComponents();
3438   if(nbOfComp!=6)
3439     throw INTERP_KERNEL::Exception("DataArrayDouble::eigenVectors : must be an array with exactly 6 components !");
3440   DataArrayDouble *ret=DataArrayDouble::New();
3441   int nbOfTuple=getNumberOfTuples();
3442   ret->alloc(nbOfTuple,9);
3443   const double *src=getConstPointer();
3444   double *dest=ret->getPointer();
3445   for(int i=0;i<nbOfTuple;i++,src+=6)
3446     {
3447       double tmp[3];
3448       INTERP_KERNEL::computeEigenValues6(src,tmp);
3449       for(int j=0;j<3;j++,dest+=3)
3450         INTERP_KERNEL::computeEigenVectorForEigenValue6(src,tmp[j],1e-12,dest);
3451     }
3452   return ret;
3453 }
3454
3455 /*!
3456  * Computes the inverse matrix of every matrix defined by the tuple of \a this
3457  * array, which contains either 4, 6 or 9 components. The case of 6 components
3458  * corresponds to that of the upper triangular matrix.
3459  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
3460  *          same number of components as \a this one, whose each tuple is the inverse
3461  *          matrix of the matrix of corresponding tuple of \a this array. 
3462  *          The caller is to delete this result array using decrRef() as it is no more
3463  *          needed. 
3464  *  \throw If \a this->getNumberOfComponents() is not in [4,6,9].
3465  */
3466 DataArrayDouble *DataArrayDouble::inverse() const throw(INTERP_KERNEL::Exception)
3467 {
3468   checkAllocated();
3469   int nbOfComp=getNumberOfComponents();
3470   if(nbOfComp!=6 && nbOfComp!=9 && nbOfComp!=4)
3471     throw INTERP_KERNEL::Exception("DataArrayDouble::inversion : must be an array with 4,6 or 9 components !");
3472   DataArrayDouble *ret=DataArrayDouble::New();
3473   int nbOfTuple=getNumberOfTuples();
3474   ret->alloc(nbOfTuple,nbOfComp);
3475   const double *src=getConstPointer();
3476   double *dest=ret->getPointer();
3477 if(nbOfComp==6)
3478     for(int i=0;i<nbOfTuple;i++,dest+=6,src+=6)
3479       {
3480         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];
3481         dest[0]=(src[1]*src[2]-src[4]*src[4])/det;
3482         dest[1]=(src[0]*src[2]-src[5]*src[5])/det;
3483         dest[2]=(src[0]*src[1]-src[3]*src[3])/det;
3484         dest[3]=(src[5]*src[4]-src[3]*src[2])/det;
3485         dest[4]=(src[5]*src[3]-src[0]*src[4])/det;
3486         dest[5]=(src[3]*src[4]-src[1]*src[5])/det;
3487       }
3488   else if(nbOfComp==4)
3489     for(int i=0;i<nbOfTuple;i++,dest+=4,src+=4)
3490       {
3491         double det=src[0]*src[3]-src[1]*src[2];
3492         dest[0]=src[3]/det;
3493         dest[1]=-src[1]/det;
3494         dest[2]=-src[2]/det;
3495         dest[3]=src[0]/det;
3496       }
3497   else
3498     for(int i=0;i<nbOfTuple;i++,dest+=9,src+=9)
3499       {
3500         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];
3501         dest[0]=(src[4]*src[8]-src[7]*src[5])/det;
3502         dest[1]=(src[7]*src[2]-src[1]*src[8])/det;
3503         dest[2]=(src[1]*src[5]-src[4]*src[2])/det;
3504         dest[3]=(src[6]*src[5]-src[3]*src[8])/det;
3505         dest[4]=(src[0]*src[8]-src[6]*src[2])/det;
3506         dest[5]=(src[2]*src[3]-src[0]*src[5])/det;
3507         dest[6]=(src[3]*src[7]-src[6]*src[4])/det;
3508         dest[7]=(src[6]*src[1]-src[0]*src[7])/det;
3509         dest[8]=(src[0]*src[4]-src[1]*src[3])/det;
3510       }
3511   return ret;
3512 }
3513
3514 /*!
3515  * Computes the trace of every matrix defined by the tuple of \a this
3516  * array, which contains either 4, 6 or 9 components. The case of 6 components
3517  * corresponds to that of the upper triangular matrix.
3518  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing 
3519  *          1 component, whose each tuple is the trace of
3520  *          the matrix of corresponding tuple of \a this array. 
3521  *          The caller is to delete this result array using decrRef() as it is no more
3522  *          needed. 
3523  *  \throw If \a this->getNumberOfComponents() is not in [4,6,9].
3524  */
3525 DataArrayDouble *DataArrayDouble::trace() const throw(INTERP_KERNEL::Exception)
3526 {
3527   checkAllocated();
3528   int nbOfComp=getNumberOfComponents();
3529   if(nbOfComp!=6 && nbOfComp!=9 && nbOfComp!=4)
3530     throw INTERP_KERNEL::Exception("DataArrayDouble::trace : must be an array with 4,6 or 9 components !");
3531   DataArrayDouble *ret=DataArrayDouble::New();
3532   int nbOfTuple=getNumberOfTuples();
3533   ret->alloc(nbOfTuple,1);
3534   const double *src=getConstPointer();
3535   double *dest=ret->getPointer();
3536   if(nbOfComp==6)
3537     for(int i=0;i<nbOfTuple;i++,dest++,src+=6)
3538       *dest=src[0]+src[1]+src[2];
3539   else if(nbOfComp==4)
3540     for(int i=0;i<nbOfTuple;i++,dest++,src+=4)
3541       *dest=src[0]+src[3];
3542   else
3543     for(int i=0;i<nbOfTuple;i++,dest++,src+=9)
3544       *dest=src[0]+src[4]+src[8];
3545   return ret;
3546 }
3547
3548 /*!
3549  * Computes the stress deviator tensor of every stress tensor defined by the tuple of
3550  * \a this array, which contains 6 components.
3551  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
3552  *          same number of components and tuples as \a this array.
3553  *          The caller is to delete this result array using decrRef() as it is no more
3554  *          needed.
3555  *  \throw If \a this->getNumberOfComponents() != 6.
3556  */
3557 DataArrayDouble *DataArrayDouble::deviator() const throw(INTERP_KERNEL::Exception)
3558 {
3559   checkAllocated();
3560   int nbOfComp=getNumberOfComponents();
3561   if(nbOfComp!=6)
3562     throw INTERP_KERNEL::Exception("DataArrayDouble::deviator : must be an array with exactly 6 components !");
3563   DataArrayDouble *ret=DataArrayDouble::New();
3564   int nbOfTuple=getNumberOfTuples();
3565   ret->alloc(nbOfTuple,6);
3566   const double *src=getConstPointer();
3567   double *dest=ret->getPointer();
3568   for(int i=0;i<nbOfTuple;i++,dest+=6,src+=6)
3569     {
3570       double tr=(src[0]+src[1]+src[2])/3.;
3571       dest[0]=src[0]-tr;
3572       dest[1]=src[1]-tr;
3573       dest[2]=src[2]-tr;
3574       dest[3]=src[3];
3575       dest[4]=src[4];
3576       dest[5]=src[5];
3577     }
3578   return ret;
3579 }
3580
3581 /*!
3582  * Computes the magnitude of every vector defined by the tuple of
3583  * \a this array.
3584  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
3585  *          same number of tuples as \a this array and one component.
3586  *          The caller is to delete this result array using decrRef() as it is no more
3587  *          needed.
3588  *  \throw If \a this is not allocated.
3589  */
3590 DataArrayDouble *DataArrayDouble::magnitude() const throw(INTERP_KERNEL::Exception)
3591 {
3592   checkAllocated();
3593   int nbOfComp=getNumberOfComponents();
3594   DataArrayDouble *ret=DataArrayDouble::New();
3595   int nbOfTuple=getNumberOfTuples();
3596   ret->alloc(nbOfTuple,1);
3597   const double *src=getConstPointer();
3598   double *dest=ret->getPointer();
3599   for(int i=0;i<nbOfTuple;i++,dest++)
3600     {
3601       double sum=0.;
3602       for(int j=0;j<nbOfComp;j++,src++)
3603         sum+=(*src)*(*src);
3604       *dest=sqrt(sum);
3605     }
3606   return ret;
3607 }
3608
3609 /*!
3610  * Computes the maximal value within every tuple of \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  *  \sa DataArrayDouble::maxPerTupleWithCompoId
3617  */
3618 DataArrayDouble *DataArrayDouble::maxPerTuple() const throw(INTERP_KERNEL::Exception)
3619 {
3620   checkAllocated();
3621   int nbOfComp=getNumberOfComponents();
3622   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
3623   int nbOfTuple=getNumberOfTuples();
3624   ret->alloc(nbOfTuple,1);
3625   const double *src=getConstPointer();
3626   double *dest=ret->getPointer();
3627   for(int i=0;i<nbOfTuple;i++,dest++,src+=nbOfComp)
3628     *dest=*std::max_element(src,src+nbOfComp);
3629   return ret.retn();
3630 }
3631
3632 /*!
3633  * Computes the maximal value within every tuple of \a this array and it returns the first component
3634  * id for each tuple that corresponds to the maximal value within the tuple.
3635  * 
3636  *  \param [out] compoIdOfMaxPerTuple - the new new instance of DataArrayInt containing the
3637  *          same number of tuples and only one component.
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::maxPerTuple
3644  */
3645 DataArrayDouble *DataArrayDouble::maxPerTupleWithCompoId(DataArrayInt* &compoIdOfMaxPerTuple) const throw(INTERP_KERNEL::Exception)
3646 {
3647   checkAllocated();
3648   int nbOfComp=getNumberOfComponents();
3649   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret0=DataArrayDouble::New();
3650   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret1=DataArrayInt::New();
3651   int nbOfTuple=getNumberOfTuples();
3652   ret0->alloc(nbOfTuple,1); ret1->alloc(nbOfTuple,1);
3653   const double *src=getConstPointer();
3654   double *dest=ret0->getPointer(); int *dest1=ret1->getPointer();
3655   for(int i=0;i<nbOfTuple;i++,dest++,dest1++,src+=nbOfComp)
3656     {
3657       const double *loc=std::max_element(src,src+nbOfComp);
3658       *dest=*loc;
3659       *dest1=(int)std::distance(src,loc);
3660     }
3661   compoIdOfMaxPerTuple=ret1.retn();
3662   return ret0.retn();
3663 }
3664
3665 /*!
3666  * This method returns a newly allocated DataArrayDouble instance having one component and \c this->getNumberOfTuples() * \c this->getNumberOfTuples() tuples.
3667  * \n This returned array contains the euclidian distance for each tuple in \a this. 
3668  * \n So the returned array can be seen as a dense symmetrical matrix whose diagonal elements are equal to 0.
3669  * \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)
3670  *
3671  * \warning use this method with care because it can leads to big amount of consumed memory !
3672  * 
3673  * \return A newly allocated (huge) ParaMEDMEM::DataArrayDouble instance that the caller should deal with.
3674  *
3675  * \throw If \a this is not allocated.
3676  *
3677  * \sa DataArrayDouble::buildEuclidianDistanceDenseMatrixWith
3678  */
3679 DataArrayDouble *DataArrayDouble::buildEuclidianDistanceDenseMatrix() const throw(INTERP_KERNEL::Exception)
3680 {
3681   checkAllocated();
3682   int nbOfComp=getNumberOfComponents();
3683   int nbOfTuples=getNumberOfTuples();
3684   const double *inData=getConstPointer();
3685   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
3686   ret->alloc(nbOfTuples*nbOfTuples,1);
3687   double *outData=ret->getPointer();
3688   for(int i=0;i<nbOfTuples;i++)
3689     {
3690       outData[i*nbOfTuples+i]=0.;
3691       for(int j=i+1;j<nbOfTuples;j++)
3692         {
3693           double dist=0.;
3694           for(int k=0;k<nbOfComp;k++)
3695             { double delta=inData[i*nbOfComp+k]-inData[j*nbOfComp+k]; dist+=delta*delta; }
3696           dist=sqrt(dist);
3697           outData[i*nbOfTuples+j]=dist;
3698           outData[j*nbOfTuples+i]=dist;
3699         }
3700     }
3701   return ret.retn();
3702 }
3703
3704 /*!
3705  * This method returns a newly allocated DataArrayDouble instance having one component and \c this->getNumberOfTuples() * \c other->getNumberOfTuples() tuples.
3706  * \n This returned array contains the euclidian distance for each tuple in \a other with each tuple in \a this. 
3707  * \n So the returned array can be seen as a dense rectangular matrix with \c other->getNumberOfTuples() rows and \c this->getNumberOfTuples() columns.
3708  * \n Output rectangular matrix is sorted along rows.
3709  * \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)
3710  *
3711  * \warning use this method with care because it can leads to big amount of consumed memory !
3712  * 
3713  * \param [in] other DataArrayDouble instance having same number of components than \a this.
3714  * \return A newly allocated (huge) ParaMEDMEM::DataArrayDouble instance that the caller should deal with.
3715  *
3716  * \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.
3717  *
3718  * \sa DataArrayDouble::buildEuclidianDistanceDenseMatrix
3719  */
3720 DataArrayDouble *DataArrayDouble::buildEuclidianDistanceDenseMatrixWith(const DataArrayDouble *other) const throw(INTERP_KERNEL::Exception)
3721 {
3722   if(!other)
3723     throw INTERP_KERNEL::Exception("DataArrayDouble::buildEuclidianDistanceDenseMatrixWith : input parameter is null !");
3724   checkAllocated();
3725   other->checkAllocated();
3726   int nbOfComp=getNumberOfComponents();
3727   int otherNbOfComp=other->getNumberOfComponents();
3728   if(nbOfComp!=otherNbOfComp)
3729     {
3730       std::ostringstream oss; oss << "DataArrayDouble::buildEuclidianDistanceDenseMatrixWith : this nb of compo=" << nbOfComp << " and other nb of compo=" << otherNbOfComp << ". It should match !";
3731       throw INTERP_KERNEL::Exception(oss.str().c_str());
3732     }
3733   int nbOfTuples=getNumberOfTuples();
3734   int otherNbOfTuples=other->getNumberOfTuples();
3735   const double *inData=getConstPointer();
3736   const double *inDataOther=other->getConstPointer();
3737   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
3738   ret->alloc(otherNbOfTuples*nbOfTuples,1);
3739   double *outData=ret->getPointer();
3740   for(int i=0;i<otherNbOfTuples;i++,inDataOther+=nbOfComp)
3741     {
3742       for(int j=0;j<nbOfTuples;j++)
3743         {
3744           double dist=0.;
3745           for(int k=0;k<nbOfComp;k++)
3746             { double delta=inDataOther[k]-inData[j*nbOfComp+k]; dist+=delta*delta; }
3747           dist=sqrt(dist);
3748           outData[i*nbOfTuples+j]=dist;
3749         }
3750     }
3751   return ret.retn();
3752 }
3753
3754 /*!
3755  * Sorts value within every tuple of \a this array.
3756  *  \param [in] asc - if \a true, the values are sorted in ascending order, else,
3757  *              in descending order.
3758  *  \throw If \a this is not allocated.
3759  */
3760 void DataArrayDouble::sortPerTuple(bool asc) throw(INTERP_KERNEL::Exception)
3761 {
3762   checkAllocated();
3763   double *pt=getPointer();
3764   int nbOfTuple=getNumberOfTuples();
3765   int nbOfComp=getNumberOfComponents();
3766   if(asc)
3767     for(int i=0;i<nbOfTuple;i++,pt+=nbOfComp)
3768       std::sort(pt,pt+nbOfComp);
3769   else
3770     for(int i=0;i<nbOfTuple;i++,pt+=nbOfComp)
3771       std::sort(pt,pt+nbOfComp,std::greater<double>());
3772   declareAsNew();
3773 }
3774
3775 /*!
3776  * Converts every value of \a this array to its absolute value.
3777  *  \throw If \a this is not allocated.
3778  */
3779 void DataArrayDouble::abs() throw(INTERP_KERNEL::Exception)
3780 {
3781   checkAllocated();
3782   double *ptr=getPointer();
3783   std::size_t nbOfElems=getNbOfElems();
3784   std::transform(ptr,ptr+nbOfElems,ptr,std::ptr_fun<double,double>(fabs));
3785   declareAsNew();
3786 }
3787
3788 /*!
3789  * Apply a liner function to a given component of \a this array, so that
3790  * an array element <em>(x)</em> becomes \f$ a * x + b \f$.
3791  *  \param [in] a - the first coefficient of the function.
3792  *  \param [in] b - the second coefficient of the function.
3793  *  \param [in] compoId - the index of component to modify.
3794  *  \throw If \a this is not allocated.
3795  */
3796 void DataArrayDouble::applyLin(double a, double b, int compoId) throw(INTERP_KERNEL::Exception)
3797 {
3798   checkAllocated();
3799   double *ptr=getPointer()+compoId;
3800   int nbOfComp=getNumberOfComponents();
3801   int nbOfTuple=getNumberOfTuples();
3802   for(int i=0;i<nbOfTuple;i++,ptr+=nbOfComp)
3803     *ptr=a*(*ptr)+b;
3804   declareAsNew();
3805 }
3806
3807 /*!
3808  * Apply a liner function to all elements of \a this array, so that
3809  * an element _x_ becomes \f$ a * x + b \f$.
3810  *  \param [in] a - the first coefficient of the function.
3811  *  \param [in] b - the second coefficient of the function.
3812  *  \throw If \a this is not allocated.
3813  */
3814 void DataArrayDouble::applyLin(double a, double b) throw(INTERP_KERNEL::Exception)
3815 {
3816   checkAllocated();
3817   double *ptr=getPointer();
3818   std::size_t nbOfElems=getNbOfElems();
3819   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
3820     *ptr=a*(*ptr)+b;
3821   declareAsNew();
3822 }
3823
3824 /*!
3825  * Modify all elements of \a this array, so that
3826  * an element _x_ becomes \f$ numerator / x \f$.
3827  *  \warning If an exception is thrown because of presence of 0.0 element in \a this 
3828  *           array, all elements processed before detection of the zero element remain
3829  *           modified.
3830  *  \param [in] numerator - the numerator used to modify array elements.
3831  *  \throw If \a this is not allocated.
3832  *  \throw If there is an element equal to 0.0 in \a this array.
3833  */
3834 void DataArrayDouble::applyInv(double numerator) throw(INTERP_KERNEL::Exception)
3835 {
3836   checkAllocated();
3837   double *ptr=getPointer();
3838   std::size_t nbOfElems=getNbOfElems();
3839   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
3840     {
3841       if(std::abs(*ptr)>std::numeric_limits<double>::min())
3842         {
3843           *ptr=numerator/(*ptr);
3844         }
3845       else
3846         {
3847           std::ostringstream oss; oss << "DataArrayDouble::applyInv : presence of null value in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
3848           oss << " !";
3849           throw INTERP_KERNEL::Exception(oss.str().c_str());
3850         }
3851     }
3852   declareAsNew();
3853 }
3854
3855 /*!
3856  * Returns a full copy of \a this array except that sign of all elements is reversed.
3857  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
3858  *          same number of tuples and component as \a this array.
3859  *          The caller is to delete this result array using decrRef() as it is no more
3860  *          needed.
3861  *  \throw If \a this is not allocated.
3862  */
3863 DataArrayDouble *DataArrayDouble::negate() const throw(INTERP_KERNEL::Exception)
3864 {
3865   checkAllocated();
3866   DataArrayDouble *newArr=DataArrayDouble::New();
3867   int nbOfTuples=getNumberOfTuples();
3868   int nbOfComp=getNumberOfComponents();
3869   newArr->alloc(nbOfTuples,nbOfComp);
3870   const double *cptr=getConstPointer();
3871   std::transform(cptr,cptr+nbOfTuples*nbOfComp,newArr->getPointer(),std::negate<double>());
3872   newArr->copyStringInfoFrom(*this);
3873   return newArr;
3874 }
3875
3876 /*!
3877  * Modify all elements of \a this array, so that
3878  * an element _x_ becomes <em> val ^ x </em>. Contrary to DataArrayInt::applyPow
3879  * all values in \a this have to be >= 0 if val is \b not integer.
3880  *  \param [in] val - the value used to apply pow on all array elements.
3881  *  \throw If \a this is not allocated.
3882  *  \warning If an exception is thrown because of presence of 0 element in \a this 
3883  *           array and \a val is \b not integer, all elements processed before detection of the zero element remain
3884  *           modified.
3885  */
3886 void DataArrayDouble::applyPow(double val) throw(INTERP_KERNEL::Exception)
3887 {
3888   checkAllocated();
3889   double *ptr=getPointer();
3890   std::size_t nbOfElems=getNbOfElems();
3891   int val2=(int)val;
3892   bool isInt=((double)val2)==val;
3893   if(!isInt)
3894     {
3895       for(std::size_t i=0;i<nbOfElems;i++,ptr++)
3896         {
3897           if(*ptr>=0)
3898             *ptr=pow(*ptr,val);
3899           else
3900             {
3901               std::ostringstream oss; oss << "DataArrayDouble::applyPow (double) : At elem # " << i << " value is " << *ptr << " ! must be >=0. !";
3902               throw INTERP_KERNEL::Exception(oss.str().c_str());
3903             }
3904         }
3905     }
3906   else
3907     {
3908       for(std::size_t i=0;i<nbOfElems;i++,ptr++)
3909         *ptr=pow(*ptr,val2);
3910     }
3911   declareAsNew();
3912 }
3913
3914 /*!
3915  * Modify all elements of \a this array, so that
3916  * an element _x_ becomes \f$ val ^ x \f$.
3917  *  \param [in] val - the value used to apply pow on all array elements.
3918  *  \throw If \a this is not allocated.
3919  *  \throw If \a val < 0.
3920  *  \warning If an exception is thrown because of presence of 0 element in \a this 
3921  *           array, all elements processed before detection of the zero element remain
3922  *           modified.
3923  */
3924 void DataArrayDouble::applyRPow(double val) throw(INTERP_KERNEL::Exception)
3925 {
3926   checkAllocated();
3927   if(val<0.)
3928     throw INTERP_KERNEL::Exception("DataArrayDouble::applyRPow : the input value has to be >= 0 !");
3929   double *ptr=getPointer();
3930   std::size_t nbOfElems=getNbOfElems();
3931   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
3932     *ptr=pow(val,*ptr);
3933   declareAsNew();
3934 }
3935
3936 /*!
3937  * Returns a new DataArrayDouble created from \a this one by applying \a
3938  * FunctionToEvaluate to every tuple of \a this array. Textual data is not copied.
3939  * For more info see \ref MEDCouplingArrayApplyFunc
3940  *  \param [in] nbOfComp - number of components in the result array.
3941  *  \param [in] func - the \a FunctionToEvaluate declared as 
3942  *              \c bool (*\a func)(\c const \c double *\a pos, \c double *\a res), 
3943  *              where \a pos points to the first component of a tuple of \a this array
3944  *              and \a res points to the first component of a tuple of the result array.
3945  *              Note that length (number of components) of \a pos can differ from
3946  *              that of \a res.
3947  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
3948  *          same number of tuples as \a this array.
3949  *          The caller is to delete this result array using decrRef() as it is no more
3950  *          needed.
3951  *  \throw If \a this is not allocated.
3952  *  \throw If \a func returns \a false.
3953  */
3954 DataArrayDouble *DataArrayDouble::applyFunc(int nbOfComp, FunctionToEvaluate func) const throw(INTERP_KERNEL::Exception)
3955 {
3956   checkAllocated();
3957   DataArrayDouble *newArr=DataArrayDouble::New();
3958   int nbOfTuples=getNumberOfTuples();
3959   int oldNbOfComp=getNumberOfComponents();
3960   newArr->alloc(nbOfTuples,nbOfComp);
3961   const double *ptr=getConstPointer();
3962   double *ptrToFill=newArr->getPointer();
3963   for(int i=0;i<nbOfTuples;i++)
3964     {
3965       if(!func(ptr+i*oldNbOfComp,ptrToFill+i*nbOfComp))
3966         {
3967           std::ostringstream oss; oss << "For tuple # " << i << " with value (";
3968           std::copy(ptr+oldNbOfComp*i,ptr+oldNbOfComp*(i+1),std::ostream_iterator<double>(oss,", "));
3969           oss << ") : Evaluation of function failed !";
3970           newArr->decrRef();
3971           throw INTERP_KERNEL::Exception(oss.str().c_str());
3972         }
3973     }
3974   return newArr;
3975 }
3976
3977 /*!
3978  * Returns a new DataArrayDouble created from \a this one by applying a function to every
3979  * tuple of \a this array. Textual data is not copied.
3980  * For more info see \ref MEDCouplingArrayApplyFunc1.
3981  *  \param [in] nbOfComp - number of components in the result array.
3982  *  \param [in] func - the expression defining how to transform a tuple of \a this array.
3983  *              Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
3984  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
3985  *          same number of tuples as \a this array and \a nbOfComp components.
3986  *          The caller is to delete this result array using decrRef() as it is no more
3987  *          needed.
3988  *  \throw If \a this is not allocated.
3989  *  \throw If computing \a func fails.
3990  */
3991 DataArrayDouble *DataArrayDouble::applyFunc(int nbOfComp, const char *func) const throw(INTERP_KERNEL::Exception)
3992 {
3993   checkAllocated();
3994   INTERP_KERNEL::ExprParser expr(func);
3995   expr.parse();
3996   std::set<std::string> vars;
3997   expr.getTrueSetOfVars(vars);
3998   int oldNbOfComp=getNumberOfComponents();
3999   if((int)vars.size()>oldNbOfComp)
4000     {
4001       std::ostringstream oss; oss << "The field has " << oldNbOfComp << " components and there are ";
4002       oss << vars.size() << " variables : ";
4003       std::copy(vars.begin(),vars.end(),std::ostream_iterator<std::string>(oss," "));
4004       throw INTERP_KERNEL::Exception(oss.str().c_str());
4005     }
4006   std::vector<std::string> varsV(vars.begin(),vars.end());
4007   expr.prepareExprEvaluation(varsV,oldNbOfComp,nbOfComp);
4008   //
4009   DataArrayDouble *newArr=DataArrayDouble::New();
4010   int nbOfTuples=getNumberOfTuples();
4011   newArr->alloc(nbOfTuples,nbOfComp);
4012   const double *ptr=getConstPointer();
4013   double *ptrToFill=newArr->getPointer();
4014   for(int i=0;i<nbOfTuples;i++)
4015     {
4016       try
4017         {
4018           expr.evaluateExpr(nbOfComp,ptr+i*oldNbOfComp,ptrToFill+i*nbOfComp);
4019         }
4020       catch(INTERP_KERNEL::Exception& e)
4021         {
4022           std::ostringstream oss; oss << "For tuple # " << i << " with value (";
4023           std::copy(ptr+oldNbOfComp*i,ptr+oldNbOfComp*(i+1),std::ostream_iterator<double>(oss,", "));
4024           oss << ") : Evaluation of function failed !" << e.what();
4025           newArr->decrRef();
4026           throw INTERP_KERNEL::Exception(oss.str().c_str());
4027         }
4028     }
4029   return newArr;
4030 }
4031
4032 /*!
4033  * Returns a new DataArrayDouble created from \a this one by applying a function to every
4034  * tuple of \a this array. Textual data is not copied.
4035  * For more info see \ref MEDCouplingArrayApplyFunc0.
4036  *  \param [in] func - the expression defining how to transform a tuple of \a this array.
4037  *              Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
4038  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
4039  *          same number of tuples and components as \a this array.
4040  *          The caller is to delete this result array using decrRef() as it is no more
4041  *          needed.
4042  *  \throw If \a this is not allocated.
4043  *  \throw If computing \a func fails.
4044  */
4045 DataArrayDouble *DataArrayDouble::applyFunc(const char *func) const throw(INTERP_KERNEL::Exception)
4046 {
4047   checkAllocated();
4048   INTERP_KERNEL::ExprParser expr(func);
4049   expr.parse();
4050   expr.prepareExprEvaluationVec();
4051   //
4052   DataArrayDouble *newArr=DataArrayDouble::New();
4053   int nbOfTuples=getNumberOfTuples();
4054   int nbOfComp=getNumberOfComponents();
4055   newArr->alloc(nbOfTuples,nbOfComp);
4056   const double *ptr=getConstPointer();
4057   double *ptrToFill=newArr->getPointer();
4058   for(int i=0;i<nbOfTuples;i++)
4059     {
4060       try
4061         {
4062           expr.evaluateExpr(nbOfComp,ptr+i*nbOfComp,ptrToFill+i*nbOfComp);
4063         }
4064       catch(INTERP_KERNEL::Exception& e)
4065         {
4066           std::ostringstream oss; oss << "For tuple # " << i << " with value (";
4067           std::copy(ptr+nbOfComp*i,ptr+nbOfComp*(i+1),std::ostream_iterator<double>(oss,", "));
4068           oss << ") : Evaluation of function failed ! " << e.what();
4069           newArr->decrRef();
4070           throw INTERP_KERNEL::Exception(oss.str().c_str());
4071         }
4072     }
4073   return newArr;
4074 }
4075
4076 /*!
4077  * Returns a new DataArrayDouble created from \a this one by applying a function to every
4078  * tuple of \a this array. Textual data is not copied.
4079  * For more info see \ref MEDCouplingArrayApplyFunc2.
4080  *  \param [in] nbOfComp - number of components in the result array.
4081  *  \param [in] func - the expression defining how to transform a tuple of \a this array.
4082  *              Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
4083  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
4084  *          same number of tuples as \a this array.
4085  *          The caller is to delete this result array using decrRef() as it is no more
4086  *          needed.
4087  *  \throw If \a this is not allocated.
4088  *  \throw If \a func contains vars that are not in \a this->getInfoOnComponent().
4089  *  \throw If computing \a func fails.
4090  */
4091 DataArrayDouble *DataArrayDouble::applyFunc2(int nbOfComp, const char *func) const throw(INTERP_KERNEL::Exception)
4092 {
4093   checkAllocated();
4094   INTERP_KERNEL::ExprParser expr(func);
4095   expr.parse();
4096   std::set<std::string> vars;
4097   expr.getTrueSetOfVars(vars);
4098   int oldNbOfComp=getNumberOfComponents();
4099   if((int)vars.size()>oldNbOfComp)
4100     {
4101       std::ostringstream oss; oss << "The field has " << oldNbOfComp << " components and there are ";
4102       oss << vars.size() << " variables : ";
4103       std::copy(vars.begin(),vars.end(),std::ostream_iterator<std::string>(oss," "));
4104       throw INTERP_KERNEL::Exception(oss.str().c_str());
4105     }
4106   expr.prepareExprEvaluation(getVarsOnComponent(),oldNbOfComp,nbOfComp);
4107   //
4108   DataArrayDouble *newArr=DataArrayDouble::New();
4109   int nbOfTuples=getNumberOfTuples();
4110   newArr->alloc(nbOfTuples,nbOfComp);
4111   const double *ptr=getConstPointer();
4112   double *ptrToFill=newArr->getPointer();
4113   for(int i=0;i<nbOfTuples;i++)
4114     {
4115       try
4116         {
4117           expr.evaluateExpr(nbOfComp,ptr+i*oldNbOfComp,ptrToFill+i*nbOfComp);
4118         }
4119       catch(INTERP_KERNEL::Exception& e)
4120         {
4121           std::ostringstream oss; oss << "For tuple # " << i << " with value (";
4122           std::copy(ptr+oldNbOfComp*i,ptr+oldNbOfComp*(i+1),std::ostream_iterator<double>(oss,", "));
4123           oss << ") : Evaluation of function failed !" << e.what();
4124           newArr->decrRef();
4125           throw INTERP_KERNEL::Exception(oss.str().c_str());
4126         }
4127     }
4128   return newArr;
4129 }
4130
4131 /*!
4132  * Returns a new DataArrayDouble created from \a this one by applying a function to every
4133  * tuple of \a this array. Textual data is not copied.
4134  * For more info see \ref MEDCouplingArrayApplyFunc3.
4135  *  \param [in] nbOfComp - number of components in the result array.
4136  *  \param [in] varsOrder - sequence of vars defining their order.
4137  *  \param [in] func - the expression defining how to transform a tuple of \a this array.
4138  *              Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
4139  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
4140  *          same number of tuples as \a this array.
4141  *          The caller is to delete this result array using decrRef() as it is no more
4142  *          needed.
4143  *  \throw If \a this is not allocated.
4144  *  \throw If \a func contains vars not in \a varsOrder.
4145  *  \throw If computing \a func fails.
4146  */
4147 DataArrayDouble *DataArrayDouble::applyFunc3(int nbOfComp, const std::vector<std::string>& varsOrder, const char *func) const throw(INTERP_KERNEL::Exception)
4148 {
4149   checkAllocated();
4150   INTERP_KERNEL::ExprParser expr(func);
4151   expr.parse();
4152   std::set<std::string> vars;
4153   expr.getTrueSetOfVars(vars);
4154   int oldNbOfComp=getNumberOfComponents();
4155   if((int)vars.size()>oldNbOfComp)
4156     {
4157       std::ostringstream oss; oss << "The field has " << oldNbOfComp << " components and there are ";
4158       oss << vars.size() << " variables : ";
4159       std::copy(vars.begin(),vars.end(),std::ostream_iterator<std::string>(oss," "));
4160       throw INTERP_KERNEL::Exception(oss.str().c_str());
4161     }
4162   expr.prepareExprEvaluation(varsOrder,oldNbOfComp,nbOfComp);
4163   //
4164   DataArrayDouble *newArr=DataArrayDouble::New();
4165   int nbOfTuples=getNumberOfTuples();
4166   newArr->alloc(nbOfTuples,nbOfComp);
4167   const double *ptr=getConstPointer();
4168   double *ptrToFill=newArr->getPointer();
4169   for(int i=0;i<nbOfTuples;i++)
4170     {
4171       try
4172         {
4173           expr.evaluateExpr(nbOfComp,ptr+i*oldNbOfComp,ptrToFill+i*nbOfComp);
4174         }
4175       catch(INTERP_KERNEL::Exception& e)
4176         {
4177           std::ostringstream oss; oss << "For tuple # " << i << " with value (";
4178           std::copy(ptr+oldNbOfComp*i,ptr+oldNbOfComp*(i+1),std::ostream_iterator<double>(oss,", "));
4179           oss << ") : Evaluation of function failed !" << e.what();
4180           newArr->decrRef();
4181           throw INTERP_KERNEL::Exception(oss.str().c_str());
4182         }
4183     }
4184   return newArr;
4185 }
4186
4187 void DataArrayDouble::applyFuncFast32(const char *func) throw(INTERP_KERNEL::Exception)
4188 {
4189   checkAllocated();
4190   INTERP_KERNEL::ExprParser expr(func);
4191   expr.parse();
4192   char *funcStr=expr.compileX86();
4193   MYFUNCPTR funcPtr;
4194   *((void **)&funcPtr)=funcStr;//he he...
4195   //
4196   double *ptr=getPointer();
4197   int nbOfComp=getNumberOfComponents();
4198   int nbOfTuples=getNumberOfTuples();
4199   int nbOfElems=nbOfTuples*nbOfComp;
4200   for(int i=0;i<nbOfElems;i++,ptr++)
4201     *ptr=funcPtr(*ptr);
4202   declareAsNew();
4203 }
4204
4205 void DataArrayDouble::applyFuncFast64(const char *func) throw(INTERP_KERNEL::Exception)
4206 {
4207   checkAllocated();
4208   INTERP_KERNEL::ExprParser expr(func);
4209   expr.parse();
4210   char *funcStr=expr.compileX86_64();
4211   MYFUNCPTR funcPtr;
4212   *((void **)&funcPtr)=funcStr;//he he...
4213   //
4214   double *ptr=getPointer();
4215   int nbOfComp=getNumberOfComponents();
4216   int nbOfTuples=getNumberOfTuples();
4217   int nbOfElems=nbOfTuples*nbOfComp;
4218   for(int i=0;i<nbOfElems;i++,ptr++)
4219     *ptr=funcPtr(*ptr);
4220   declareAsNew();
4221 }
4222
4223 DataArrayDoubleIterator *DataArrayDouble::iterator() throw(INTERP_KERNEL::Exception)
4224 {
4225   return new DataArrayDoubleIterator(this);
4226 }
4227
4228 /*!
4229  * Returns a new DataArrayInt contating indices of tuples of \a this one-dimensional
4230  * array whose values are within a given range. Textual data is not copied.
4231  *  \param [in] vmin - a lowest acceptable value (included).
4232  *  \param [in] vmax - a greatest acceptable value (included).
4233  *  \return DataArrayInt * - the new instance of DataArrayInt.
4234  *          The caller is to delete this result array using decrRef() as it is no more
4235  *          needed.
4236  *  \throw If \a this->getNumberOfComponents() != 1.
4237  *
4238  *  \ref cpp_mcdataarraydouble_getidsinrange "Here is a C++ example".<br>
4239  *  \ref py_mcdataarraydouble_getidsinrange "Here is a Python example".
4240  */
4241 DataArrayInt *DataArrayDouble::getIdsInRange(double vmin, double vmax) const throw(INTERP_KERNEL::Exception)
4242 {
4243   checkAllocated();
4244   if(getNumberOfComponents()!=1)
4245     throw INTERP_KERNEL::Exception("DataArrayDouble::getIdsInRange : this must have exactly one component !");
4246   const double *cptr=getConstPointer();
4247   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(0,1);
4248   int nbOfTuples=getNumberOfTuples();
4249   for(int i=0;i<nbOfTuples;i++,cptr++)
4250     if(*cptr>=vmin && *cptr<=vmax)
4251       ret->pushBackSilent(i);
4252   return ret.retn();
4253 }
4254
4255 /*!
4256  * Returns a new DataArrayDouble by concatenating two given arrays, so that (1) the number
4257  * of tuples in the result array is a sum of the number of tuples of given arrays and (2)
4258  * the number of component in the result array is same as that of each of given arrays.
4259  * Info on components is copied from the first of the given arrays. Number of components
4260  * in the given arrays must be  the same.
4261  *  \param [in] a1 - an array to include in the result array.
4262  *  \param [in] a2 - another array to include in the result array.
4263  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4264  *          The caller is to delete this result array using decrRef() as it is no more
4265  *          needed.
4266  *  \throw If both \a a1 and \a a2 are NULL.
4267  *  \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents().
4268  */
4269 DataArrayDouble *DataArrayDouble::Aggregate(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception)
4270 {
4271   std::vector<const DataArrayDouble *> tmp(2);
4272   tmp[0]=a1; tmp[1]=a2;
4273   return Aggregate(tmp);
4274 }
4275
4276 /*!
4277  * Returns a new DataArrayDouble by concatenating all given arrays, so that (1) the number
4278  * of tuples in the result array is a sum of the number of tuples of given arrays and (2)
4279  * the number of component in the result array is same as that of each of given arrays.
4280  * Info on components is copied from the first of the given arrays. Number of components
4281  * in the given arrays must be  the same.
4282  *  \param [in] arr - a sequence of arrays to include in the result array.
4283  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4284  *          The caller is to delete this result array using decrRef() as it is no more
4285  *          needed.
4286  *  \throw If all arrays within \a arr are NULL.
4287  *  \throw If getNumberOfComponents() of arrays within \a arr.
4288  */
4289 DataArrayDouble *DataArrayDouble::Aggregate(const std::vector<const DataArrayDouble *>& arr) throw(INTERP_KERNEL::Exception)
4290 {
4291   std::vector<const DataArrayDouble *> a;
4292   for(std::vector<const DataArrayDouble *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
4293     if(*it4)
4294       a.push_back(*it4);
4295   if(a.empty())
4296     throw INTERP_KERNEL::Exception("DataArrayDouble::Aggregate : input list must contain at least one NON EMPTY DataArrayDouble !");
4297   std::vector<const DataArrayDouble *>::const_iterator it=a.begin();
4298   int nbOfComp=(*it)->getNumberOfComponents();
4299   int nbt=(*it++)->getNumberOfTuples();
4300   for(int i=1;it!=a.end();it++,i++)
4301     {
4302       if((*it)->getNumberOfComponents()!=nbOfComp)
4303         throw INTERP_KERNEL::Exception("DataArrayDouble::Aggregate : Nb of components mismatch for array aggregation !");
4304       nbt+=(*it)->getNumberOfTuples();
4305     }
4306   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
4307   ret->alloc(nbt,nbOfComp);
4308   double *pt=ret->getPointer();
4309   for(it=a.begin();it!=a.end();it++)
4310     pt=std::copy((*it)->getConstPointer(),(*it)->getConstPointer()+(*it)->getNbOfElems(),pt);
4311   ret->copyStringInfoFrom(*(a[0]));
4312   return ret.retn();
4313 }
4314
4315 /*!
4316  * Returns a new DataArrayDouble by aggregating two given arrays, so that (1) the number
4317  * of components in the result array is a sum of the number of components of given arrays
4318  * and (2) the number of tuples in the result array is same as that of each of given
4319  * arrays. In other words the i-th tuple of result array includes all components of
4320  * i-th tuples of all given arrays.
4321  * Number of tuples in the given arrays must be  the same.
4322  *  \param [in] a1 - an array to include in the result array.
4323  *  \param [in] a2 - another array to include in the result array.
4324  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4325  *          The caller is to delete this result array using decrRef() as it is no more
4326  *          needed.
4327  *  \throw If both \a a1 and \a a2 are NULL.
4328  *  \throw If any given array is not allocated.
4329  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
4330  */
4331 DataArrayDouble *DataArrayDouble::Meld(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception)
4332 {
4333   std::vector<const DataArrayDouble *> arr(2);
4334   arr[0]=a1; arr[1]=a2;
4335   return Meld(arr);
4336 }
4337
4338 /*!
4339  * Returns a new DataArrayDouble by aggregating all given arrays, so that (1) the number
4340  * of components in the result array is a sum of the number of components of given arrays
4341  * and (2) the number of tuples in the result array is same as that of each of given
4342  * arrays. In other words the i-th tuple of result array includes all components of
4343  * i-th tuples of all given arrays.
4344  * Number of tuples in the given arrays must be  the same.
4345  *  \param [in] arr - a sequence of arrays to include in the result array.
4346  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4347  *          The caller is to delete this result array using decrRef() as it is no more
4348  *          needed.
4349  *  \throw If all arrays within \a arr are NULL.
4350  *  \throw If any given array is not allocated.
4351  *  \throw If getNumberOfTuples() of arrays within \a arr is different.
4352  */
4353 DataArrayDouble *DataArrayDouble::Meld(const std::vector<const DataArrayDouble *>& arr) throw(INTERP_KERNEL::Exception)
4354 {
4355   std::vector<const DataArrayDouble *> a;
4356   for(std::vector<const DataArrayDouble *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
4357     if(*it4)
4358       a.push_back(*it4);
4359   if(a.empty())
4360     throw INTERP_KERNEL::Exception("DataArrayDouble::Meld : input list must contain at least one NON EMPTY DataArrayDouble !");
4361   std::vector<const DataArrayDouble *>::const_iterator it;
4362   for(it=a.begin();it!=a.end();it++)
4363     (*it)->checkAllocated();
4364   it=a.begin();
4365   int nbOfTuples=(*it)->getNumberOfTuples();
4366   std::vector<int> nbc(a.size());
4367   std::vector<const double *> pts(a.size());
4368   nbc[0]=(*it)->getNumberOfComponents();
4369   pts[0]=(*it++)->getConstPointer();
4370   for(int i=1;it!=a.end();it++,i++)
4371     {
4372       if(nbOfTuples!=(*it)->getNumberOfTuples())
4373         throw INTERP_KERNEL::Exception("DataArrayDouble::Meld : mismatch of number of tuples !");
4374       nbc[i]=(*it)->getNumberOfComponents();
4375       pts[i]=(*it)->getConstPointer();
4376     }
4377   int totalNbOfComp=std::accumulate(nbc.begin(),nbc.end(),0);
4378   DataArrayDouble *ret=DataArrayDouble::New();
4379   ret->alloc(nbOfTuples,totalNbOfComp);
4380   double *retPtr=ret->getPointer();
4381   for(int i=0;i<nbOfTuples;i++)
4382     for(int j=0;j<(int)a.size();j++)
4383       {
4384         retPtr=std::copy(pts[j],pts[j]+nbc[j],retPtr);
4385         pts[j]+=nbc[j];
4386       }
4387   int k=0;
4388   for(int i=0;i<(int)a.size();i++)
4389     for(int j=0;j<nbc[i];j++,k++)
4390       ret->setInfoOnComponent(k,a[i]->getInfoOnComponent(j).c_str());
4391   return ret;
4392 }
4393
4394 /*!
4395  * Returns a new DataArrayDouble containing a dot product of two given arrays, so that
4396  * the i-th tuple of the result array is a sum of products of j-th components of i-th
4397  * tuples of given arrays (\f$ a_i = \sum_{j=1}^n a1_j * a2_j \f$).
4398  * Info on components and name is copied from the first of the given arrays.
4399  * Number of tuples and components in the given arrays must be the same.
4400  *  \param [in] a1 - a given array.
4401  *  \param [in] a2 - another given array.
4402  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4403  *          The caller is to delete this result array using decrRef() as it is no more
4404  *          needed.
4405  *  \throw If either \a a1 or \a a2 is NULL.
4406  *  \throw If any given array is not allocated.
4407  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
4408  *  \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents()
4409  */
4410 DataArrayDouble *DataArrayDouble::Dot(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception)
4411 {
4412   if(!a1 || !a2)
4413     throw INTERP_KERNEL::Exception("DataArrayDouble::Dot : input DataArrayDouble instance is NULL !");
4414   a1->checkAllocated();
4415   a2->checkAllocated();
4416   int nbOfComp=a1->getNumberOfComponents();
4417   if(nbOfComp!=a2->getNumberOfComponents())
4418     throw INTERP_KERNEL::Exception("Nb of components mismatch for array Dot !");
4419   int nbOfTuple=a1->getNumberOfTuples();
4420   if(nbOfTuple!=a2->getNumberOfTuples())
4421     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Dot !");
4422   DataArrayDouble *ret=DataArrayDouble::New();
4423   ret->alloc(nbOfTuple,1);
4424   double *retPtr=ret->getPointer();
4425   const double *a1Ptr=a1->getConstPointer();
4426   const double *a2Ptr=a2->getConstPointer();
4427   for(int i=0;i<nbOfTuple;i++)
4428     {
4429       double sum=0.;
4430       for(int j=0;j<nbOfComp;j++)
4431         sum+=a1Ptr[i*nbOfComp+j]*a2Ptr[i*nbOfComp+j];
4432       retPtr[i]=sum;
4433     }
4434   ret->setInfoOnComponent(0,a1->getInfoOnComponent(0).c_str());
4435   ret->setName(a1->getName().c_str());
4436   return ret;
4437 }
4438
4439 /*!
4440  * Returns a new DataArrayDouble containing a cross product of two given arrays, so that
4441  * the i-th tuple of the result array contains 3 components of a vector which is a cross
4442  * product of two vectors defined by the i-th tuples of given arrays.
4443  * Info on components is copied from the first of the given arrays.
4444  * Number of tuples in the given arrays must be the same.
4445  * Number of components in the given arrays must be 3.
4446  *  \param [in] a1 - a given array.
4447  *  \param [in] a2 - another given array.
4448  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4449  *          The caller is to delete this result array using decrRef() as it is no more
4450  *          needed.
4451  *  \throw If either \a a1 or \a a2 is NULL.
4452  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
4453  *  \throw If \a a1->getNumberOfComponents() != 3
4454  *  \throw If \a a2->getNumberOfComponents() != 3
4455  */
4456 DataArrayDouble *DataArrayDouble::CrossProduct(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception)
4457 {
4458   if(!a1 || !a2)
4459     throw INTERP_KERNEL::Exception("DataArrayDouble::CrossProduct : input DataArrayDouble instance is NULL !");
4460   int nbOfComp=a1->getNumberOfComponents();
4461   if(nbOfComp!=a2->getNumberOfComponents())
4462     throw INTERP_KERNEL::Exception("Nb of components mismatch for array crossProduct !");
4463   if(nbOfComp!=3)
4464     throw INTERP_KERNEL::Exception("Nb of components must be equal to 3 for array crossProduct !");
4465   int nbOfTuple=a1->getNumberOfTuples();
4466   if(nbOfTuple!=a2->getNumberOfTuples())
4467     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array crossProduct !");
4468   DataArrayDouble *ret=DataArrayDouble::New();
4469   ret->alloc(nbOfTuple,3);
4470   double *retPtr=ret->getPointer();
4471   const double *a1Ptr=a1->getConstPointer();
4472   const double *a2Ptr=a2->getConstPointer();
4473   for(int i=0;i<nbOfTuple;i++)
4474     {
4475       retPtr[3*i]=a1Ptr[3*i+1]*a2Ptr[3*i+2]-a1Ptr[3*i+2]*a2Ptr[3*i+1];
4476       retPtr[3*i+1]=a1Ptr[3*i+2]*a2Ptr[3*i]-a1Ptr[3*i]*a2Ptr[3*i+2];
4477       retPtr[3*i+2]=a1Ptr[3*i]*a2Ptr[3*i+1]-a1Ptr[3*i+1]*a2Ptr[3*i];
4478     }
4479   ret->copyStringInfoFrom(*a1);
4480   return ret;
4481 }
4482
4483 /*!
4484  * Returns a new DataArrayDouble containing maximal values of two given arrays.
4485  * Info on components is copied from the first of the given arrays.
4486  * Number of tuples and components in the given arrays must be the same.
4487  *  \param [in] a1 - an array to compare values with another one.
4488  *  \param [in] a2 - another array to compare values with the first one.
4489  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4490  *          The caller is to delete this result array using decrRef() as it is no more
4491  *          needed.
4492  *  \throw If either \a a1 or \a a2 is NULL.
4493  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
4494  *  \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents()
4495  */
4496 DataArrayDouble *DataArrayDouble::Max(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception)
4497 {
4498   if(!a1 || !a2)
4499     throw INTERP_KERNEL::Exception("DataArrayDouble::Max : input DataArrayDouble instance is NULL !");
4500   int nbOfComp=a1->getNumberOfComponents();
4501   if(nbOfComp!=a2->getNumberOfComponents())
4502     throw INTERP_KERNEL::Exception("Nb of components mismatch for array Max !");
4503   int nbOfTuple=a1->getNumberOfTuples();
4504   if(nbOfTuple!=a2->getNumberOfTuples())
4505     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Max !");
4506   DataArrayDouble *ret=DataArrayDouble::New();
4507   ret->alloc(nbOfTuple,nbOfComp);
4508   double *retPtr=ret->getPointer();
4509   const double *a1Ptr=a1->getConstPointer();
4510   const double *a2Ptr=a2->getConstPointer();
4511   int nbElem=nbOfTuple*nbOfComp;
4512   for(int i=0;i<nbElem;i++)
4513     retPtr[i]=std::max(a1Ptr[i],a2Ptr[i]);
4514   ret->copyStringInfoFrom(*a1);
4515   return ret;
4516 }
4517
4518 /*!
4519  * Returns a new DataArrayDouble containing minimal values of two given arrays.
4520  * Info on components is copied from the first of the given arrays.
4521  * Number of tuples and components in the given arrays must be the same.
4522  *  \param [in] a1 - an array to compare values with another one.
4523  *  \param [in] a2 - another array to compare values with the first one.
4524  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4525  *          The caller is to delete this result array using decrRef() as it is no more
4526  *          needed.
4527  *  \throw If either \a a1 or \a a2 is NULL.
4528  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
4529  *  \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents()
4530  */
4531 DataArrayDouble *DataArrayDouble::Min(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception)
4532 {
4533   if(!a1 || !a2)
4534     throw INTERP_KERNEL::Exception("DataArrayDouble::Min : input DataArrayDouble instance is NULL !");
4535   int nbOfComp=a1->getNumberOfComponents();
4536   if(nbOfComp!=a2->getNumberOfComponents())
4537     throw INTERP_KERNEL::Exception("Nb of components mismatch for array min !");
4538   int nbOfTuple=a1->getNumberOfTuples();
4539   if(nbOfTuple!=a2->getNumberOfTuples())
4540     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array min !");
4541   DataArrayDouble *ret=DataArrayDouble::New();
4542   ret->alloc(nbOfTuple,nbOfComp);
4543   double *retPtr=ret->getPointer();
4544   const double *a1Ptr=a1->getConstPointer();
4545   const double *a2Ptr=a2->getConstPointer();
4546   int nbElem=nbOfTuple*nbOfComp;
4547   for(int i=0;i<nbElem;i++)
4548     retPtr[i]=std::min(a1Ptr[i],a2Ptr[i]);
4549   ret->copyStringInfoFrom(*a1);
4550   return ret;
4551 }
4552
4553 /*!
4554  * Returns a new DataArrayDouble that is a sum of two given arrays. There are 3
4555  * valid cases.
4556  * 1.  The arrays have same number of tuples and components. Then each value of
4557  *   the result array (_a_) is a sum of the corresponding values of \a a1 and \a a2,
4558  *   i.e.: _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ i, j ].
4559  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
4560  *   component. Then
4561  *   _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ i, 0 ].
4562  * 3.  The arrays have same number of components and one array, say _a2_, has one
4563  *   tuple. Then
4564  *   _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ 0, j ].
4565  *
4566  * Info on components is copied either from the first array (in the first case) or from
4567  * the array with maximal number of elements (getNbOfElems()).
4568  *  \param [in] a1 - an array to sum up.
4569  *  \param [in] a2 - another array to sum up.
4570  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4571  *          The caller is to delete this result array using decrRef() as it is no more
4572  *          needed.
4573  *  \throw If either \a a1 or \a a2 is NULL.
4574  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
4575  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
4576  *         none of them has number of tuples or components equal to 1.
4577  */
4578 DataArrayDouble *DataArrayDouble::Add(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception)
4579 {
4580   if(!a1 || !a2)
4581     throw INTERP_KERNEL::Exception("DataArrayDouble::Add : input DataArrayDouble instance is NULL !");
4582   int nbOfTuple=a1->getNumberOfTuples();
4583   int nbOfTuple2=a2->getNumberOfTuples();
4584   int nbOfComp=a1->getNumberOfComponents();
4585   int nbOfComp2=a2->getNumberOfComponents();
4586   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=0;
4587   if(nbOfTuple==nbOfTuple2)
4588     {
4589       if(nbOfComp==nbOfComp2)
4590         {
4591           ret=DataArrayDouble::New();
4592           ret->alloc(nbOfTuple,nbOfComp);
4593           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::plus<double>());
4594           ret->copyStringInfoFrom(*a1);
4595         }
4596       else
4597         {
4598           int nbOfCompMin,nbOfCompMax;
4599           const DataArrayDouble *aMin, *aMax;
4600           if(nbOfComp>nbOfComp2)
4601             {
4602               nbOfCompMin=nbOfComp2; nbOfCompMax=nbOfComp;
4603               aMin=a2; aMax=a1;
4604             }
4605           else
4606             {
4607               nbOfCompMin=nbOfComp; nbOfCompMax=nbOfComp2;
4608               aMin=a1; aMax=a2;
4609             }
4610           if(nbOfCompMin==1)
4611             {
4612               ret=DataArrayDouble::New();
4613               ret->alloc(nbOfTuple,nbOfCompMax);
4614               const double *aMinPtr=aMin->getConstPointer();
4615               const double *aMaxPtr=aMax->getConstPointer();
4616               double *res=ret->getPointer();
4617               for(int i=0;i<nbOfTuple;i++)
4618                 res=std::transform(aMaxPtr+i*nbOfCompMax,aMaxPtr+(i+1)*nbOfCompMax,res,std::bind2nd(std::plus<double>(),aMinPtr[i]));
4619               ret->copyStringInfoFrom(*aMax);
4620             }
4621           else
4622             throw INTERP_KERNEL::Exception("Nb of components mismatch for array Add !");
4623         }
4624     }
4625   else if((nbOfTuple==1 && nbOfTuple2>1) || (nbOfTuple>1 && nbOfTuple2==1))
4626     {
4627       if(nbOfComp==nbOfComp2)
4628         {
4629           int nbOfTupleMax=std::max(nbOfTuple,nbOfTuple2);
4630           const DataArrayDouble *aMin=nbOfTuple>nbOfTuple2?a2:a1;
4631           const DataArrayDouble *aMax=nbOfTuple>nbOfTuple2?a1:a2;
4632           const double *aMinPtr=aMin->getConstPointer(),*aMaxPtr=aMax->getConstPointer();
4633           ret=DataArrayDouble::New();
4634           ret->alloc(nbOfTupleMax,nbOfComp);
4635           double *res=ret->getPointer();
4636           for(int i=0;i<nbOfTupleMax;i++)
4637             res=std::transform(aMaxPtr+i*nbOfComp,aMaxPtr+(i+1)*nbOfComp,aMinPtr,res,std::plus<double>());
4638           ret->copyStringInfoFrom(*aMax);
4639         }
4640       else
4641         throw INTERP_KERNEL::Exception("Nb of components mismatch for array Add !");
4642     }
4643   else
4644     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Add !");
4645   return ret.retn();
4646 }
4647
4648 /*!
4649  * Adds values of another DataArrayDouble to values of \a this one. There are 3
4650  * valid cases.
4651  * 1.  The arrays have same number of tuples and components. Then each value of
4652  *   \a other array is added to the corresponding value of \a this array, i.e.:
4653  *   _a_ [ i, j ] += _other_ [ i, j ].
4654  * 2.  The arrays have same number of tuples and \a other array has one component. Then
4655  *   _a_ [ i, j ] += _other_ [ i, 0 ].
4656  * 3.  The arrays have same number of components and \a other array has one tuple. Then
4657  *   _a_ [ i, j ] += _a2_ [ 0, j ].
4658  *
4659  *  \param [in] other - an array to add to \a this one.
4660  *  \throw If \a other is NULL.
4661  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
4662  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
4663  *         \a other has number of both tuples and components not equal to 1.
4664  */
4665 void DataArrayDouble::addEqual(const DataArrayDouble *other) throw(INTERP_KERNEL::Exception)
4666 {
4667   if(!other)
4668     throw INTERP_KERNEL::Exception("DataArrayDouble::addEqual : input DataArrayDouble instance is NULL !");
4669   const char *msg="Nb of tuples mismatch for DataArrayDouble::addEqual  !";
4670   checkAllocated();
4671   other->checkAllocated();
4672   int nbOfTuple=getNumberOfTuples();
4673   int nbOfTuple2=other->getNumberOfTuples();
4674   int nbOfComp=getNumberOfComponents();
4675   int nbOfComp2=other->getNumberOfComponents();
4676   if(nbOfTuple==nbOfTuple2)
4677     {
4678       if(nbOfComp==nbOfComp2)
4679         {
4680           std::transform(begin(),end(),other->begin(),getPointer(),std::plus<double>());
4681         }
4682       else if(nbOfComp2==1)
4683         {
4684           double *ptr=getPointer();
4685           const double *ptrc=other->getConstPointer();
4686           for(int i=0;i<nbOfTuple;i++)
4687             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::plus<double>(),*ptrc++));
4688         }
4689       else
4690         throw INTERP_KERNEL::Exception(msg);
4691     }
4692   else if(nbOfTuple2==1)
4693     {
4694       if(nbOfComp2==nbOfComp)
4695         {
4696           double *ptr=getPointer();
4697           const double *ptrc=other->getConstPointer();
4698           for(int i=0;i<nbOfTuple;i++)
4699             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::plus<double>());
4700         }
4701       else
4702         throw INTERP_KERNEL::Exception(msg);
4703     }
4704   else
4705     throw INTERP_KERNEL::Exception(msg);
4706   declareAsNew();
4707 }
4708
4709 /*!
4710  * Returns a new DataArrayDouble that is a subtraction of two given arrays. There are 3
4711  * valid cases.
4712  * 1.  The arrays have same number of tuples and components. Then each value of
4713  *   the result array (_a_) is a subtraction of the corresponding values of \a a1 and
4714  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ i, j ].
4715  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
4716  *   component. Then
4717  *   _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ i, 0 ].
4718  * 3.  The arrays have same number of components and one array, say _a2_, has one
4719  *   tuple. Then
4720  *   _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ 0, j ].
4721  *
4722  * Info on components is copied either from the first array (in the first case) or from
4723  * the array with maximal number of elements (getNbOfElems()).
4724  *  \param [in] a1 - an array to subtract from.
4725  *  \param [in] a2 - an array to subtract.
4726  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4727  *          The caller is to delete this result array using decrRef() as it is no more
4728  *          needed.
4729  *  \throw If either \a a1 or \a a2 is NULL.
4730  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
4731  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
4732  *         none of them has number of tuples or components equal to 1.
4733  */
4734 DataArrayDouble *DataArrayDouble::Substract(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception)
4735 {
4736   if(!a1 || !a2)
4737     throw INTERP_KERNEL::Exception("DataArrayDouble::Substract : input DataArrayDouble instance is NULL !");
4738   int nbOfTuple1=a1->getNumberOfTuples();
4739   int nbOfTuple2=a2->getNumberOfTuples();
4740   int nbOfComp1=a1->getNumberOfComponents();
4741   int nbOfComp2=a2->getNumberOfComponents();
4742   if(nbOfTuple2==nbOfTuple1)
4743     {
4744       if(nbOfComp1==nbOfComp2)
4745         {
4746           MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
4747           ret->alloc(nbOfTuple2,nbOfComp1);
4748           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::minus<double>());
4749           ret->copyStringInfoFrom(*a1);
4750           return ret.retn();
4751         }
4752       else if(nbOfComp2==1)
4753         {
4754           MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
4755           ret->alloc(nbOfTuple1,nbOfComp1);
4756           const double *a2Ptr=a2->getConstPointer();
4757           const double *a1Ptr=a1->getConstPointer();
4758           double *res=ret->getPointer();
4759           for(int i=0;i<nbOfTuple1;i++)
4760             res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::minus<double>(),a2Ptr[i]));
4761           ret->copyStringInfoFrom(*a1);
4762           return ret.retn();
4763         }
4764       else
4765         {
4766           a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Substract !");
4767           return 0;
4768         }
4769     }
4770   else if(nbOfTuple2==1)
4771     {
4772       a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Substract !");
4773       MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
4774       ret->alloc(nbOfTuple1,nbOfComp1);
4775       const double *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
4776       double *pt=ret->getPointer();
4777       for(int i=0;i<nbOfTuple1;i++)
4778         pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::minus<double>());
4779       ret->copyStringInfoFrom(*a1);
4780       return ret.retn();
4781     }
4782   else
4783     {
4784       a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Substract !");//will always throw an exception
4785       return 0;
4786     }
4787 }
4788
4789 /*!
4790  * Subtract values of another DataArrayDouble from values of \a this one. There are 3
4791  * valid cases.
4792  * 1.  The arrays have same number of tuples and components. Then each value of
4793  *   \a other array is subtracted from the corresponding value of \a this array, i.e.:
4794  *   _a_ [ i, j ] -= _other_ [ i, j ].
4795  * 2.  The arrays have same number of tuples and \a other array has one component. Then
4796  *   _a_ [ i, j ] -= _other_ [ i, 0 ].
4797  * 3.  The arrays have same number of components and \a other array has one tuple. Then
4798  *   _a_ [ i, j ] -= _a2_ [ 0, j ].
4799  *
4800  *  \param [in] other - an array to subtract from \a this one.
4801  *  \throw If \a other is NULL.
4802  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
4803  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
4804  *         \a other has number of both tuples and components not equal to 1.
4805  */
4806 void DataArrayDouble::substractEqual(const DataArrayDouble *other) throw(INTERP_KERNEL::Exception)
4807 {
4808   if(!other)
4809     throw INTERP_KERNEL::Exception("DataArrayDouble::substractEqual : input DataArrayDouble instance is NULL !");
4810   const char *msg="Nb of tuples mismatch for DataArrayDouble::substractEqual  !";
4811   checkAllocated();
4812   other->checkAllocated();
4813   int nbOfTuple=getNumberOfTuples();
4814   int nbOfTuple2=other->getNumberOfTuples();
4815   int nbOfComp=getNumberOfComponents();
4816   int nbOfComp2=other->getNumberOfComponents();
4817   if(nbOfTuple==nbOfTuple2)
4818     {
4819       if(nbOfComp==nbOfComp2)
4820         {
4821           std::transform(begin(),end(),other->begin(),getPointer(),std::minus<double>());
4822         }
4823       else if(nbOfComp2==1)
4824         {
4825           double *ptr=getPointer();
4826           const double *ptrc=other->getConstPointer();
4827           for(int i=0;i<nbOfTuple;i++)
4828             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::minus<double>(),*ptrc++)); 
4829         }
4830       else
4831         throw INTERP_KERNEL::Exception(msg);
4832     }
4833   else if(nbOfTuple2==1)
4834     {
4835       if(nbOfComp2==nbOfComp)
4836         {
4837           double *ptr=getPointer();
4838           const double *ptrc=other->getConstPointer();
4839           for(int i=0;i<nbOfTuple;i++)
4840             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::minus<double>());
4841         }
4842       else
4843         throw INTERP_KERNEL::Exception(msg);
4844     }
4845   else
4846     throw INTERP_KERNEL::Exception(msg);
4847   declareAsNew();
4848 }
4849
4850 /*!
4851  * Returns a new DataArrayDouble that is a product of two given arrays. There are 3
4852  * valid cases.
4853  * 1.  The arrays have same number of tuples and components. Then each value of
4854  *   the result array (_a_) is a product of the corresponding values of \a a1 and
4855  *   \a a2, i.e. _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ i, j ].
4856  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
4857  *   component. Then
4858  *   _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ i, 0 ].
4859  * 3.  The arrays have same number of components and one array, say _a2_, has one
4860  *   tuple. Then
4861  *   _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ 0, j ].
4862  *
4863  * Info on components is copied either from the first array (in the first case) or from
4864  * the array with maximal number of elements (getNbOfElems()).
4865  *  \param [in] a1 - a factor array.
4866  *  \param [in] a2 - another factor array.
4867  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4868  *          The caller is to delete this result array using decrRef() as it is no more
4869  *          needed.
4870  *  \throw If either \a a1 or \a a2 is NULL.
4871  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
4872  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
4873  *         none of them has number of tuples or components equal to 1.
4874  */
4875 DataArrayDouble *DataArrayDouble::Multiply(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception)
4876 {
4877   if(!a1 || !a2)
4878     throw INTERP_KERNEL::Exception("DataArrayDouble::Multiply : input DataArrayDouble instance is NULL !");
4879   int nbOfTuple=a1->getNumberOfTuples();
4880   int nbOfTuple2=a2->getNumberOfTuples();
4881   int nbOfComp=a1->getNumberOfComponents();
4882   int nbOfComp2=a2->getNumberOfComponents();
4883   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=0;
4884   if(nbOfTuple==nbOfTuple2)
4885     {
4886       if(nbOfComp==nbOfComp2)
4887         {
4888           ret=DataArrayDouble::New();
4889           ret->alloc(nbOfTuple,nbOfComp);
4890           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::multiplies<double>());
4891           ret->copyStringInfoFrom(*a1);
4892         }
4893       else
4894         {
4895           int nbOfCompMin,nbOfCompMax;
4896           const DataArrayDouble *aMin, *aMax;
4897           if(nbOfComp>nbOfComp2)
4898             {
4899               nbOfCompMin=nbOfComp2; nbOfCompMax=nbOfComp;
4900               aMin=a2; aMax=a1;
4901             }
4902           else
4903             {
4904               nbOfCompMin=nbOfComp; nbOfCompMax=nbOfComp2;
4905               aMin=a1; aMax=a2;
4906             }
4907           if(nbOfCompMin==1)
4908             {
4909               ret=DataArrayDouble::New();
4910               ret->alloc(nbOfTuple,nbOfCompMax);
4911               const double *aMinPtr=aMin->getConstPointer();
4912               const double *aMaxPtr=aMax->getConstPointer();
4913               double *res=ret->getPointer();
4914               for(int i=0;i<nbOfTuple;i++)
4915                 res=std::transform(aMaxPtr+i*nbOfCompMax,aMaxPtr+(i+1)*nbOfCompMax,res,std::bind2nd(std::multiplies<double>(),aMinPtr[i]));
4916               ret->copyStringInfoFrom(*aMax);
4917             }
4918           else
4919             throw INTERP_KERNEL::Exception("Nb of components mismatch for array Multiply !");
4920         }
4921     }
4922   else if((nbOfTuple==1 && nbOfTuple2>1) || (nbOfTuple>1 && nbOfTuple2==1))
4923     {
4924       if(nbOfComp==nbOfComp2)
4925         {
4926           int nbOfTupleMax=std::max(nbOfTuple,nbOfTuple2);
4927           const DataArrayDouble *aMin=nbOfTuple>nbOfTuple2?a2:a1;
4928           const DataArrayDouble *aMax=nbOfTuple>nbOfTuple2?a1:a2;
4929           const double *aMinPtr=aMin->getConstPointer(),*aMaxPtr=aMax->getConstPointer();
4930           ret=DataArrayDouble::New();
4931           ret->alloc(nbOfTupleMax,nbOfComp);
4932           double *res=ret->getPointer();
4933           for(int i=0;i<nbOfTupleMax;i++)
4934             res=std::transform(aMaxPtr+i*nbOfComp,aMaxPtr+(i+1)*nbOfComp,aMinPtr,res,std::multiplies<double>());
4935           ret->copyStringInfoFrom(*aMax);
4936         }
4937       else
4938         throw INTERP_KERNEL::Exception("Nb of components mismatch for array Multiply !");
4939     }
4940   else
4941     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Multiply !");
4942   return ret.retn();
4943 }
4944
4945 /*!
4946  * Multiply values of another DataArrayDouble to values of \a this one. There are 3
4947  * valid cases.
4948  * 1.  The arrays have same number of tuples and components. Then each value of
4949  *   \a other array is multiplied to the corresponding value of \a this array, i.e.
4950  *   _this_ [ i, j ] *= _other_ [ i, j ].
4951  * 2.  The arrays have same number of tuples and \a other array has one component. Then
4952  *   _this_ [ i, j ] *= _other_ [ i, 0 ].
4953  * 3.  The arrays have same number of components and \a other array has one tuple. Then
4954  *   _this_ [ i, j ] *= _a2_ [ 0, j ].
4955  *
4956  *  \param [in] other - an array to multiply to \a this one.
4957  *  \throw If \a other is NULL.
4958  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
4959  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
4960  *         \a other has number of both tuples and components not equal to 1.
4961  */
4962 void DataArrayDouble::multiplyEqual(const DataArrayDouble *other) throw(INTERP_KERNEL::Exception)
4963 {
4964   if(!other)
4965     throw INTERP_KERNEL::Exception("DataArrayDouble::multiplyEqual : input DataArrayDouble instance is NULL !");
4966   const char *msg="Nb of tuples mismatch for DataArrayDouble::multiplyEqual !";
4967   checkAllocated();
4968   other->checkAllocated();
4969   int nbOfTuple=getNumberOfTuples();
4970   int nbOfTuple2=other->getNumberOfTuples();
4971   int nbOfComp=getNumberOfComponents();
4972   int nbOfComp2=other->getNumberOfComponents();
4973   if(nbOfTuple==nbOfTuple2)
4974     {
4975       if(nbOfComp==nbOfComp2)
4976         {
4977           std::transform(begin(),end(),other->begin(),getPointer(),std::multiplies<double>());
4978         }
4979       else if(nbOfComp2==1)
4980         {
4981           double *ptr=getPointer();
4982           const double *ptrc=other->getConstPointer();
4983           for(int i=0;i<nbOfTuple;i++)
4984             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::multiplies<double>(),*ptrc++));
4985         }
4986       else
4987         throw INTERP_KERNEL::Exception(msg);
4988     }
4989   else if(nbOfTuple2==1)
4990     {
4991       if(nbOfComp2==nbOfComp)
4992         {
4993           double *ptr=getPointer();
4994           const double *ptrc=other->getConstPointer();
4995           for(int i=0;i<nbOfTuple;i++)
4996             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::multiplies<double>());
4997         }
4998       else
4999         throw INTERP_KERNEL::Exception(msg);
5000     }
5001   else
5002     throw INTERP_KERNEL::Exception(msg);
5003   declareAsNew();
5004 }
5005
5006 /*!
5007  * Returns a new DataArrayDouble that is a division of two given arrays. There are 3
5008  * valid cases.
5009  * 1.  The arrays have same number of tuples and components. Then each value of
5010  *   the result array (_a_) is a division of the corresponding values of \a a1 and
5011  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ i, j ].
5012  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
5013  *   component. Then
5014  *   _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ i, 0 ].
5015  * 3.  The arrays have same number of components and one array, say _a2_, has one
5016  *   tuple. Then
5017  *   _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ 0, j ].
5018  *
5019  * Info on components is copied either from the first array (in the first case) or from
5020  * the array with maximal number of elements (getNbOfElems()).
5021  *  \warning No check of division by zero is performed!
5022  *  \param [in] a1 - a numerator array.
5023  *  \param [in] a2 - a denominator array.
5024  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
5025  *          The caller is to delete this result array using decrRef() as it is no more
5026  *          needed.
5027  *  \throw If either \a a1 or \a a2 is NULL.
5028  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
5029  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
5030  *         none of them has number of tuples or components equal to 1.
5031  */
5032 DataArrayDouble *DataArrayDouble::Divide(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception)
5033 {
5034   if(!a1 || !a2)
5035     throw INTERP_KERNEL::Exception("DataArrayDouble::Divide : input DataArrayDouble instance is NULL !");
5036   int nbOfTuple1=a1->getNumberOfTuples();
5037   int nbOfTuple2=a2->getNumberOfTuples();
5038   int nbOfComp1=a1->getNumberOfComponents();
5039   int nbOfComp2=a2->getNumberOfComponents();
5040   if(nbOfTuple2==nbOfTuple1)
5041     {
5042       if(nbOfComp1==nbOfComp2)
5043         {
5044           MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
5045           ret->alloc(nbOfTuple2,nbOfComp1);
5046           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::divides<double>());
5047           ret->copyStringInfoFrom(*a1);
5048           return ret.retn();
5049         }
5050       else if(nbOfComp2==1)
5051         {
5052           MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
5053           ret->alloc(nbOfTuple1,nbOfComp1);
5054           const double *a2Ptr=a2->getConstPointer();
5055           const double *a1Ptr=a1->getConstPointer();
5056           double *res=ret->getPointer();
5057           for(int i=0;i<nbOfTuple1;i++)
5058             res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::divides<double>(),a2Ptr[i]));
5059           ret->copyStringInfoFrom(*a1);
5060           return ret.retn();
5061         }
5062       else
5063         {
5064           a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Divide !");
5065           return 0;
5066         }
5067     }
5068   else if(nbOfTuple2==1)
5069     {
5070       a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Divide !");
5071       MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
5072       ret->alloc(nbOfTuple1,nbOfComp1);
5073       const double *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
5074       double *pt=ret->getPointer();
5075       for(int i=0;i<nbOfTuple1;i++)
5076         pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::divides<double>());
5077       ret->copyStringInfoFrom(*a1);
5078       return ret.retn();
5079     }
5080   else
5081     {
5082       a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Divide !");//will always throw an exception
5083       return 0;
5084     }
5085 }
5086
5087 /*!
5088  * Divide values of \a this array by values of another DataArrayDouble. There are 3
5089  * valid cases.
5090  * 1.  The arrays have same number of tuples and components. Then each value of
5091  *    \a this array is divided by the corresponding value of \a other one, i.e.:
5092  *   _a_ [ i, j ] /= _other_ [ i, j ].
5093  * 2.  The arrays have same number of tuples and \a other array has one component. Then
5094  *   _a_ [ i, j ] /= _other_ [ i, 0 ].
5095  * 3.  The arrays have same number of components and \a other array has one tuple. Then
5096  *   _a_ [ i, j ] /= _a2_ [ 0, j ].
5097  *
5098  *  \warning No check of division by zero is performed!
5099  *  \param [in] other - an array to divide \a this one by.
5100  *  \throw If \a other is NULL.
5101  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
5102  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
5103  *         \a other has number of both tuples and components not equal to 1.
5104  */
5105 void DataArrayDouble::divideEqual(const DataArrayDouble *other) throw(INTERP_KERNEL::Exception)
5106 {
5107   if(!other)
5108     throw INTERP_KERNEL::Exception("DataArrayDouble::divideEqual : input DataArrayDouble instance is NULL !");
5109   const char *msg="Nb of tuples mismatch for DataArrayDouble::divideEqual !";
5110   checkAllocated();
5111   other->checkAllocated();
5112   int nbOfTuple=getNumberOfTuples();
5113   int nbOfTuple2=other->getNumberOfTuples();
5114   int nbOfComp=getNumberOfComponents();
5115   int nbOfComp2=other->getNumberOfComponents();
5116   if(nbOfTuple==nbOfTuple2)
5117     {
5118       if(nbOfComp==nbOfComp2)
5119         {
5120           std::transform(begin(),end(),other->begin(),getPointer(),std::divides<double>());
5121         }
5122       else if(nbOfComp2==1)
5123         {
5124           double *ptr=getPointer();
5125           const double *ptrc=other->getConstPointer();
5126           for(int i=0;i<nbOfTuple;i++)
5127             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::divides<double>(),*ptrc++));
5128         }
5129       else
5130         throw INTERP_KERNEL::Exception(msg);
5131     }
5132   else if(nbOfTuple2==1)
5133     {
5134       if(nbOfComp2==nbOfComp)
5135         {
5136           double *ptr=getPointer();
5137           const double *ptrc=other->getConstPointer();
5138           for(int i=0;i<nbOfTuple;i++)
5139             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::divides<double>());
5140         }
5141       else
5142         throw INTERP_KERNEL::Exception(msg);
5143     }
5144   else
5145     throw INTERP_KERNEL::Exception(msg);
5146   declareAsNew();
5147 }
5148
5149 /*!
5150  * Returns a new DataArrayDouble that is the result of pow of two given arrays. There are 3
5151  * valid cases.
5152  *
5153  *  \param [in] a1 - an array to pow up.
5154  *  \param [in] a2 - another array to sum up.
5155  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
5156  *          The caller is to delete this result array using decrRef() as it is no more
5157  *          needed.
5158  *  \throw If either \a a1 or \a a2 is NULL.
5159  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
5160  *  \throw If \a a1->getNumberOfComponents() != 1 or \a a2->getNumberOfComponents() != 1.
5161  *  \throw If there is a negative value in \a a1.
5162  */
5163 DataArrayDouble *DataArrayDouble::Pow(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception)
5164 {
5165   if(!a1 || !a2)
5166     throw INTERP_KERNEL::Exception("DataArrayDouble::Pow : at least one of input instances is null !");
5167   int nbOfTuple=a1->getNumberOfTuples();
5168   int nbOfTuple2=a2->getNumberOfTuples();
5169   int nbOfComp=a1->getNumberOfComponents();
5170   int nbOfComp2=a2->getNumberOfComponents();
5171   if(nbOfTuple!=nbOfTuple2)
5172     throw INTERP_KERNEL::Exception("DataArrayDouble::Pow : number of tuples mismatches !");
5173   if(nbOfComp!=1 || nbOfComp2!=1)
5174     throw INTERP_KERNEL::Exception("DataArrayDouble::Pow : number of components of both arrays must be equal to 1 !");
5175   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New(); ret->alloc(nbOfTuple,1);
5176   const double *ptr1(a1->begin()),*ptr2(a2->begin());
5177   double *ptr=ret->getPointer();
5178   for(int i=0;i<nbOfTuple;i++,ptr1++,ptr2++,ptr++)
5179     {
5180       if(*ptr1>=0)
5181         {
5182           *ptr=pow(*ptr1,*ptr2);
5183         }
5184       else
5185         {
5186           std::ostringstream oss; oss << "DataArrayDouble::Pow : on tuple #" << i << " of a1 value is < 0 (" << *ptr1 << ") !";
5187           throw INTERP_KERNEL::Exception(oss.str().c_str());
5188         }
5189     }
5190   return ret.retn();
5191 }
5192
5193 /*!
5194  * Apply pow on values of another DataArrayDouble to values of \a this one.
5195  *
5196  *  \param [in] other - an array to pow to \a this one.
5197  *  \throw If \a other is NULL.
5198  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples()
5199  *  \throw If \a this->getNumberOfComponents() != 1 or \a other->getNumberOfComponents() != 1
5200  *  \throw If there is a negative value in \a this.
5201  */
5202 void DataArrayDouble::powEqual(const DataArrayDouble *other) throw(INTERP_KERNEL::Exception)
5203 {
5204   if(!other)
5205     throw INTERP_KERNEL::Exception("DataArrayDouble::powEqual : input instance is null !");
5206   int nbOfTuple=getNumberOfTuples();
5207   int nbOfTuple2=other->getNumberOfTuples();
5208   int nbOfComp=getNumberOfComponents();
5209   int nbOfComp2=other->getNumberOfComponents();
5210   if(nbOfTuple!=nbOfTuple2)
5211     throw INTERP_KERNEL::Exception("DataArrayDouble::powEqual : number of tuples mismatches !");
5212   if(nbOfComp!=1 || nbOfComp2!=1)
5213     throw INTERP_KERNEL::Exception("DataArrayDouble::powEqual : number of components of both arrays must be equal to 1 !");
5214   double *ptr=getPointer();
5215   const double *ptrc=other->begin();
5216   for(int i=0;i<nbOfTuple;i++,ptrc++,ptr++)
5217     {
5218       if(*ptr>=0)
5219         *ptr=pow(*ptr,*ptrc);
5220       else
5221         {
5222           std::ostringstream oss; oss << "DataArrayDouble::powEqual : on tuple #" << i << " of this value is < 0 (" << *ptr << ") !";
5223           throw INTERP_KERNEL::Exception(oss.str().c_str());
5224         }
5225     }
5226   declareAsNew();
5227 }
5228
5229 /*!
5230  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
5231  * Server side.
5232  */
5233 void DataArrayDouble::getTinySerializationIntInformation(std::vector<int>& tinyInfo) const
5234 {
5235   tinyInfo.resize(2);
5236   if(isAllocated())
5237     {
5238       tinyInfo[0]=getNumberOfTuples();
5239       tinyInfo[1]=getNumberOfComponents();
5240     }
5241   else
5242     {
5243       tinyInfo[0]=-1;
5244       tinyInfo[1]=-1;
5245     }
5246 }
5247
5248 /*!
5249  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
5250  * Server side.
5251  */
5252 void DataArrayDouble::getTinySerializationStrInformation(std::vector<std::string>& tinyInfo) const
5253 {
5254   if(isAllocated())
5255     {
5256       int nbOfCompo=getNumberOfComponents();
5257       tinyInfo.resize(nbOfCompo+1);
5258       tinyInfo[0]=getName();
5259       for(int i=0;i<nbOfCompo;i++)
5260         tinyInfo[i+1]=getInfoOnComponent(i);
5261     }
5262   else
5263     {
5264       tinyInfo.resize(1);
5265       tinyInfo[0]=getName();
5266     }
5267 }
5268
5269 /*!
5270  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
5271  * This method returns if a feeding is needed.
5272  */
5273 bool DataArrayDouble::resizeForUnserialization(const std::vector<int>& tinyInfoI)
5274 {
5275   int nbOfTuple=tinyInfoI[0];
5276   int nbOfComp=tinyInfoI[1];
5277   if(nbOfTuple!=-1 || nbOfComp!=-1)
5278     {
5279       alloc(nbOfTuple,nbOfComp);
5280       return true;
5281     }
5282   return false;
5283 }
5284
5285 /*!
5286  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
5287  */
5288 void DataArrayDouble::finishUnserialization(const std::vector<int>& tinyInfoI, const std::vector<std::string>& tinyInfoS)
5289 {
5290   setName(tinyInfoS[0].c_str());
5291   if(isAllocated())
5292     {
5293       int nbOfCompo=getNumberOfComponents();
5294       for(int i=0;i<nbOfCompo;i++)
5295         setInfoOnComponent(i,tinyInfoS[i+1].c_str());
5296     }
5297 }
5298
5299 DataArrayDoubleIterator::DataArrayDoubleIterator(DataArrayDouble *da):_da(da),_tuple_id(0),_nb_comp(0),_nb_tuple(0)
5300 {
5301   if(_da)
5302     {
5303       _da->incrRef();
5304       if(_da->isAllocated())
5305         {
5306           _nb_comp=da->getNumberOfComponents();
5307           _nb_tuple=da->getNumberOfTuples();
5308           _pt=da->getPointer();
5309         }
5310     }
5311 }
5312
5313 DataArrayDoubleIterator::~DataArrayDoubleIterator()
5314 {
5315   if(_da)
5316     _da->decrRef();
5317 }
5318
5319 DataArrayDoubleTuple *DataArrayDoubleIterator::nextt() throw(INTERP_KERNEL::Exception)
5320 {
5321   if(_tuple_id<_nb_tuple)
5322     {
5323       _tuple_id++;
5324       DataArrayDoubleTuple *ret=new DataArrayDoubleTuple(_pt,_nb_comp);
5325       _pt+=_nb_comp;
5326       return ret;
5327     }
5328   else
5329     return 0;
5330 }
5331
5332 DataArrayDoubleTuple::DataArrayDoubleTuple(double *pt, int nbOfComp):_pt(pt),_nb_of_compo(nbOfComp)
5333 {
5334 }
5335
5336
5337 std::string DataArrayDoubleTuple::repr() const throw(INTERP_KERNEL::Exception)
5338 {
5339   std::ostringstream oss; oss.precision(17); oss << "(";
5340   for(int i=0;i<_nb_of_compo-1;i++)
5341     oss << _pt[i] << ", ";
5342   oss << _pt[_nb_of_compo-1] << ")";
5343   return oss.str();
5344 }
5345
5346 double DataArrayDoubleTuple::doubleValue() const throw(INTERP_KERNEL::Exception)
5347 {
5348   if(_nb_of_compo==1)
5349     return *_pt;
5350   throw INTERP_KERNEL::Exception("DataArrayDoubleTuple::doubleValue : DataArrayDoubleTuple instance has not exactly 1 component -> Not possible to convert it into a double precision float !");
5351 }
5352
5353 /*!
5354  * This method returns a newly allocated instance the caller should dealed with by a ParaMEDMEM::DataArrayDouble::decrRef.
5355  * This method performs \b no copy of data. The content is only referenced using ParaMEDMEM::DataArrayDouble::useArray with ownership set to \b false.
5356  * 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
5357  * \b nbOfCompo=1 and \bnbOfTuples==this->_nb_of_elem.
5358  */
5359 DataArrayDouble *DataArrayDoubleTuple::buildDADouble(int nbOfTuples, int nbOfCompo) const throw(INTERP_KERNEL::Exception)
5360 {
5361   if((_nb_of_compo==nbOfCompo && nbOfTuples==1) || (_nb_of_compo==nbOfTuples && nbOfCompo==1))
5362     {
5363       DataArrayDouble *ret=DataArrayDouble::New();
5364       ret->useExternalArrayWithRWAccess(_pt,nbOfTuples,nbOfCompo);
5365       return ret;
5366     }
5367   else
5368     {
5369       std::ostringstream oss; oss << "DataArrayDoubleTuple::buildDADouble : unable to build a requested DataArrayDouble instance with nbofTuple=" << nbOfTuples << " and nbOfCompo=" << nbOfCompo;
5370       oss << ".\nBecause the number of elements in this is " << _nb_of_compo << " !";
5371       throw INTERP_KERNEL::Exception(oss.str().c_str());
5372     }
5373 }
5374
5375 /*!
5376  * Returns a new instance of DataArrayInt. The caller is to delete this array
5377  * using decrRef() as it is no more needed. 
5378  */
5379 DataArrayInt *DataArrayInt::New()
5380 {
5381   return new DataArrayInt;
5382 }
5383
5384 /*!
5385  * Checks if raw data is allocated. Read more on the raw data
5386  * in \ref MEDCouplingArrayBasicsTuplesAndCompo "DataArrays infos" for more information.
5387  *  \return bool - \a true if the raw data is allocated, \a false else.
5388  */
5389 bool DataArrayInt::isAllocated() const throw(INTERP_KERNEL::Exception)
5390 {
5391   return getConstPointer()!=0;
5392 }
5393
5394 /*!
5395  * Checks if raw data is allocated and throws an exception if it is not the case.
5396  *  \throw If the raw data is not allocated.
5397  */
5398 void DataArrayInt::checkAllocated() const throw(INTERP_KERNEL::Exception)
5399 {
5400   if(!isAllocated())
5401     throw INTERP_KERNEL::Exception("DataArrayInt::checkAllocated : Array is defined but not allocated ! Call alloc or setValues method first !");
5402 }
5403
5404 std::size_t DataArrayInt::getHeapMemorySize() const
5405 {
5406   std::size_t sz=_mem.getNbOfElemAllocated();
5407   sz*=sizeof(int);
5408   return DataArray::getHeapMemorySize()+sz;
5409 }
5410
5411 /*!
5412  * Returns the only one value in \a this, if and only if number of elements
5413  * (nb of tuples * nb of components) is equal to 1, and that \a this is allocated.
5414  *  \return double - the sole value stored in \a this array.
5415  *  \throw If at least one of conditions stated above is not fulfilled.
5416  */
5417 int DataArrayInt::intValue() const throw(INTERP_KERNEL::Exception)
5418 {
5419   if(isAllocated())
5420     {
5421       if(getNbOfElems()==1)
5422         {
5423           return *getConstPointer();
5424         }
5425       else
5426         throw INTERP_KERNEL::Exception("DataArrayInt::intValue : DataArrayInt instance is allocated but number of elements is not equal to 1 !");
5427     }
5428   else
5429     throw INTERP_KERNEL::Exception("DataArrayInt::intValue : DataArrayInt instance is not allocated !");
5430 }
5431
5432 /*!
5433  * Returns an integer value characterizing \a this array, which is useful for a quick
5434  * comparison of many instances of DataArrayInt.
5435  *  \return int - the hash value.
5436  *  \throw If \a this is not allocated.
5437  */
5438 int DataArrayInt::getHashCode() const throw(INTERP_KERNEL::Exception)
5439 {
5440   checkAllocated();
5441   std::size_t nbOfElems=getNbOfElems();
5442   int ret=nbOfElems*65536;
5443   int delta=3;
5444   if(nbOfElems>48)
5445     delta=nbOfElems/8;
5446   int ret0=0;
5447   const int *pt=begin();
5448   for(std::size_t i=0;i<nbOfElems;i+=delta)
5449     ret0+=pt[i] & 0x1FFF;
5450   return ret+ret0;
5451 }
5452
5453 /*!
5454  * Checks the number of tuples.
5455  *  \return bool - \a true if getNumberOfTuples() == 0, \a false else.
5456  *  \throw If \a this is not allocated.
5457  */
5458 bool DataArrayInt::empty() const throw(INTERP_KERNEL::Exception)
5459 {
5460   checkAllocated();
5461   return getNumberOfTuples()==0;
5462 }
5463
5464 /*!
5465  * Returns a full copy of \a this. For more info on copying data arrays see
5466  * \ref MEDCouplingArrayBasicsCopyDeep.
5467  *  \return DataArrayInt * - a new instance of DataArrayInt.
5468  */
5469 DataArrayInt *DataArrayInt::deepCpy() const throw(INTERP_KERNEL::Exception)
5470 {
5471   return new DataArrayInt(*this);
5472 }
5473
5474 /*!
5475  * Returns either a \a deep or \a shallow copy of this array. For more info see
5476  * \ref MEDCouplingArrayBasicsCopyDeep and \ref MEDCouplingArrayBasicsCopyShallow.
5477  *  \param [in] dCpy - if \a true, a deep copy is returned, else, a shallow one.
5478  *  \return DataArrayInt * - either a new instance of DataArrayInt (if \a dCpy
5479  *          == \a true) or \a this instance (if \a dCpy == \a false).
5480  */
5481 DataArrayInt *DataArrayInt::performCpy(bool dCpy) const throw(INTERP_KERNEL::Exception)
5482 {
5483   if(dCpy)
5484     return deepCpy();
5485   else
5486     {
5487       incrRef();
5488       return const_cast<DataArrayInt *>(this);
5489     }
5490 }
5491
5492 /*!
5493  * Copies all the data from another DataArrayInt. For more info see
5494  * \ref MEDCouplingArrayBasicsCopyDeepAssign.
5495  *  \param [in] other - another instance of DataArrayInt to copy data from.
5496  *  \throw If the \a other is not allocated.
5497  */
5498 void DataArrayInt::cpyFrom(const DataArrayInt& other) throw(INTERP_KERNEL::Exception)
5499 {
5500   other.checkAllocated();
5501   int nbOfTuples=other.getNumberOfTuples();
5502   int nbOfComp=other.getNumberOfComponents();
5503   allocIfNecessary(nbOfTuples,nbOfComp);
5504   std::size_t nbOfElems=(std::size_t)nbOfTuples*nbOfComp;
5505   int *pt=getPointer();
5506   const int *ptI=other.getConstPointer();
5507   for(std::size_t i=0;i<nbOfElems;i++)
5508     pt[i]=ptI[i];
5509   copyStringInfoFrom(other);
5510 }
5511
5512 /*!
5513  * This method reserve nbOfElems elements in memory ( nbOfElems*4 bytes ) \b without impacting the number of tuples in \a this.
5514  * 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.
5515  * If \a this has not already been allocated, number of components is set to one.
5516  * This method allows to reduce number of reallocations on invokation of DataArrayInt::pushBackSilent and DataArrayInt::pushBackValsSilent on \a this.
5517  * 
5518  * \sa DataArrayInt::pack, DataArrayInt::pushBackSilent, DataArrayInt::pushBackValsSilent
5519  */
5520 void DataArrayInt::reserve(std::size_t nbOfElems) throw(INTERP_KERNEL::Exception)
5521 {
5522   int nbCompo=getNumberOfComponents();
5523   if(nbCompo==1)
5524     {
5525       _mem.reserve(nbOfElems);
5526     }
5527   else if(nbCompo==0)
5528     {
5529       _mem.reserve(nbOfElems);
5530       _info_on_compo.resize(1);
5531     }
5532   else
5533     throw INTERP_KERNEL::Exception("DataArrayInt::reserve : not available for DataArrayInt with number of components different than 1 !");
5534 }
5535
5536 /*!
5537  * 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
5538  * of counter. So the caller is expected to call TimeLabel::declareAsNew on \a this at the end of the push session.
5539  *
5540  * \param [in] val the value to be added in \a this
5541  * \throw If \a this has already been allocated with number of components different from one.
5542  * \sa DataArrayInt::pushBackValsSilent
5543  */
5544 void DataArrayInt::pushBackSilent(int val) throw(INTERP_KERNEL::Exception)
5545 {
5546   int nbCompo=getNumberOfComponents();
5547   if(nbCompo==1)
5548     _mem.pushBack(val);
5549   else if(nbCompo==0)
5550     {
5551       _info_on_compo.resize(1);
5552       _mem.pushBack(val);
5553     }
5554   else
5555     throw INTERP_KERNEL::Exception("DataArrayInt::pushBackSilent : not available for DataArrayInt with number of components different than 1 !");
5556 }
5557
5558 /*!
5559  * 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
5560  * of counter. So the caller is expected to call TimeLabel::declareAsNew on \a this at the end of the push session.
5561  *
5562  *  \param [in] valsBg - an array of values to push at the end of \this.
5563  *  \param [in] valsEnd - specifies the end of the array \a valsBg, so that
5564  *              the last value of \a valsBg is \a valsEnd[ -1 ].
5565  * \throw If \a this has already been allocated with number of components different from one.
5566  * \sa DataArrayInt::pushBackSilent
5567  */
5568 void DataArrayInt::pushBackValsSilent(const int *valsBg, const int *valsEnd) throw(INTERP_KERNEL::Exception)
5569 {
5570   int nbCompo=getNumberOfComponents();
5571   if(nbCompo==1)
5572     _mem.insertAtTheEnd(valsBg,valsEnd);
5573   else if(nbCompo==0)
5574     {
5575       _info_on_compo.resize(1);
5576       _mem.insertAtTheEnd(valsBg,valsEnd);
5577     }
5578   else
5579     throw INTERP_KERNEL::Exception("DataArrayInt::pushBackValsSilent : not available for DataArrayInt with number of components different than 1 !");
5580 }
5581
5582 /*!
5583  * This method returns silently ( without updating time label in \a this ) the last value, if any and suppress it.
5584  * \throw If \a this is already empty.
5585  * \throw If \a this has number of components different from one.
5586  */
5587 int DataArrayInt::popBackSilent() throw(INTERP_KERNEL::Exception)
5588 {
5589   if(getNumberOfComponents()==1)
5590     return _mem.popBack();
5591   else
5592     throw INTERP_KERNEL::Exception("DataArrayInt::popBackSilent : not available for DataArrayInt with number of components different than 1 !");
5593 }
5594
5595 /*!
5596  * 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.
5597  *
5598  * \sa DataArrayInt::getHeapMemorySize, DataArrayInt::reserve
5599  */
5600 void DataArrayInt::pack() const throw(INTERP_KERNEL::Exception)
5601 {
5602   _mem.pack();
5603 }
5604
5605 /*!
5606  * Allocates the raw data in memory. If exactly as same memory as needed already
5607  * allocated, it is not re-allocated.
5608  *  \param [in] nbOfTuple - number of tuples of data to allocate.
5609  *  \param [in] nbOfCompo - number of components of data to allocate.
5610  *  \throw If \a nbOfTuple < 0 or \a nbOfCompo < 0.
5611  */
5612 void DataArrayInt::allocIfNecessary(int nbOfTuple, int nbOfCompo) throw(INTERP_KERNEL::Exception)
5613 {
5614   if(isAllocated())
5615     {
5616       if(nbOfTuple!=getNumberOfTuples() || nbOfCompo!=getNumberOfComponents())
5617         alloc(nbOfTuple,nbOfCompo);
5618     }
5619   else
5620     alloc(nbOfTuple,nbOfCompo);
5621 }
5622
5623 /*!
5624  * Allocates the raw data in memory. If the memory was already allocated, then it is
5625  * freed and re-allocated. See an example of this method use
5626  * \ref MEDCouplingArraySteps1WC "here".
5627  *  \param [in] nbOfTuple - number of tuples of data to allocate.
5628  *  \param [in] nbOfCompo - number of components of data to allocate.
5629  *  \throw If \a nbOfTuple < 0 or \a nbOfCompo < 0.
5630  */
5631 void DataArrayInt::alloc(int nbOfTuple, int nbOfCompo) throw(INTERP_KERNEL::Exception)
5632 {
5633   if(nbOfTuple<0 || nbOfCompo<0)
5634     throw INTERP_KERNEL::Exception("DataArrayInt::alloc : request for negative length of data !");
5635   _info_on_compo.resize(nbOfCompo);
5636   _mem.alloc(nbOfCompo*(std::size_t)nbOfTuple);
5637   declareAsNew();
5638 }
5639
5640 /*!
5641  * Assign zero to all values in \a this array. To know more on filling arrays see
5642  * \ref MEDCouplingArrayFill.
5643  * \throw If \a this is not allocated.
5644  */
5645 void DataArrayInt::fillWithZero() throw(INTERP_KERNEL::Exception)
5646 {
5647   checkAllocated();
5648   _mem.fillWithValue(0);
5649   declareAsNew();
5650 }
5651
5652 /*!
5653  * Assign \a val to all values in \a this array. To know more on filling arrays see
5654  * \ref MEDCouplingArrayFill.
5655  *  \param [in] val - the value to fill with.
5656  *  \throw If \a this is not allocated.
5657  */
5658 void DataArrayInt::fillWithValue(int val) throw(INTERP_KERNEL::Exception)
5659 {
5660   checkAllocated();
5661   _mem.fillWithValue(val);
5662   declareAsNew();
5663 }
5664
5665 /*!
5666  * Set all values in \a this array so that the i-th element equals to \a init + i
5667  * (i starts from zero). To know more on filling arrays see \ref MEDCouplingArrayFill.
5668  *  \param [in] init - value to assign to the first element of array.
5669  *  \throw If \a this->getNumberOfComponents() != 1
5670  *  \throw If \a this is not allocated.
5671  */
5672 void DataArrayInt::iota(int init) throw(INTERP_KERNEL::Exception)
5673 {
5674   checkAllocated();
5675   if(getNumberOfComponents()!=1)
5676     throw INTERP_KERNEL::Exception("DataArrayInt::iota : works only for arrays with only one component, you can call 'rearrange' method before !");
5677   int *ptr=getPointer();
5678   int ntuples=getNumberOfTuples();
5679   for(int i=0;i<ntuples;i++)
5680     ptr[i]=init+i;
5681   declareAsNew();
5682 }
5683
5684 /*!
5685  * Returns a textual and human readable representation of \a this instance of
5686  * DataArrayInt. This text is shown when a DataArrayInt is printed in Python.
5687  *  \return std::string - text describing \a this DataArrayInt.
5688  */
5689 std::string DataArrayInt::repr() const throw(INTERP_KERNEL::Exception)
5690 {
5691   std::ostringstream ret;
5692   reprStream(ret);
5693   return ret.str();
5694 }
5695
5696 std::string DataArrayInt::reprZip() const throw(INTERP_KERNEL::Exception)
5697 {
5698   std::ostringstream ret;
5699   reprZipStream(ret);
5700   return ret.str();
5701 }
5702
5703 void DataArrayInt::writeVTK(std::ostream& ofs, int indent, const char *type, const char *nameInFile) const throw(INTERP_KERNEL::Exception)
5704 {
5705   checkAllocated();
5706   std::string idt(indent,' ');
5707   ofs << idt << "<DataArray type=\"" << type << "\" Name=\"" << nameInFile << "\" NumberOfComponents=\"" << getNumberOfComponents() << "\"";
5708   ofs << " format=\"ascii\" RangeMin=\"" << getMinValueInArray() << "\" RangeMax=\"" << getMaxValueInArray() << "\">\n" << idt;
5709   std::copy(begin(),end(),std::ostream_iterator<int>(ofs," "));
5710   ofs << std::endl << idt << "</DataArray>\n";
5711 }
5712
5713 void DataArrayInt::reprStream(std::ostream& stream) const throw(INTERP_KERNEL::Exception)
5714 {
5715   stream << "Name of int array : \"" << _name << "\"\n";
5716   reprWithoutNameStream(stream);
5717 }
5718
5719 void DataArrayInt::reprZipStream(std::ostream& stream) const throw(INTERP_KERNEL::Exception)
5720 {
5721   stream << "Name of int array : \"" << _name << "\"\n";
5722   reprZipWithoutNameStream(stream);
5723 }
5724
5725 void DataArrayInt::reprWithoutNameStream(std::ostream& stream) const throw(INTERP_KERNEL::Exception)
5726 {
5727   DataArray::reprWithoutNameStream(stream);
5728   _mem.repr(getNumberOfComponents(),stream);
5729 }
5730
5731 void DataArrayInt::reprZipWithoutNameStream(std::ostream& stream) const throw(INTERP_KERNEL::Exception)
5732 {
5733   DataArray::reprWithoutNameStream(stream);
5734   _mem.reprZip(getNumberOfComponents(),stream);
5735 }
5736
5737 void DataArrayInt::reprCppStream(const char *varName, std::ostream& stream) const throw(INTERP_KERNEL::Exception)
5738 {
5739   int nbTuples=getNumberOfTuples(),nbComp=getNumberOfComponents();
5740   const int *data=getConstPointer();
5741   stream << "DataArrayInt *" << varName << "=DataArrayInt::New();" << std::endl;
5742   if(nbTuples*nbComp>=1)
5743     {
5744       stream << "const int " << varName << "Data[" << nbTuples*nbComp << "]={";
5745       std::copy(data,data+nbTuples*nbComp-1,std::ostream_iterator<int>(stream,","));
5746       stream << data[nbTuples*nbComp-1] << "};" << std::endl;
5747       stream << varName << "->useArray(" << varName << "Data,false,CPP_DEALLOC," << nbTuples << "," << nbComp << ");" << std::endl;
5748     }
5749   else
5750     stream << varName << "->alloc(" << nbTuples << "," << nbComp << ");" << std::endl;
5751   stream << varName << "->setName(\"" << getName() << "\");" << std::endl;
5752 }
5753
5754 /*!
5755  * Method that gives a quick overvien of \a this for python.
5756  */
5757 void DataArrayInt::reprQuickOverview(std::ostream& stream) const throw(INTERP_KERNEL::Exception)
5758 {
5759   static const std::size_t MAX_NB_OF_BYTE_IN_REPR=300;
5760   stream << "DataArrayInt C++ instance at " << this << ". ";
5761   if(isAllocated())
5762     {
5763       int nbOfCompo=(int)_info_on_compo.size();
5764       if(nbOfCompo>=1)
5765         {
5766           int nbOfTuples=getNumberOfTuples();
5767           stream << "Number of tuples : " << nbOfTuples << ". Number of components : " << nbOfCompo << "." << std::endl;
5768           reprQuickOverviewData(stream,MAX_NB_OF_BYTE_IN_REPR);
5769         }
5770       else
5771         stream << "Number of components : 0.";
5772     }
5773   else
5774     stream << "*** No data allocated ****";
5775 }
5776
5777 void DataArrayInt::reprQuickOverviewData(std::ostream& stream, std::size_t maxNbOfByteInRepr) const throw(INTERP_KERNEL::Exception)
5778 {
5779   const int *data=begin();
5780   int nbOfTuples=getNumberOfTuples();
5781   int nbOfCompo=(int)_info_on_compo.size();
5782   std::ostringstream oss2; oss2 << "[";
5783   std::string oss2Str(oss2.str());
5784   bool isFinished=true;
5785   for(int i=0;i<nbOfTuples && isFinished;i++)
5786     {
5787       if(nbOfCompo>1)
5788         {
5789           oss2 << "(";
5790           for(int j=0;j<nbOfCompo;j++,data++)
5791             {
5792               oss2 << *data;
5793               if(j!=nbOfCompo-1) oss2 << ", ";
5794             }
5795           oss2 << ")";
5796         }
5797       else
5798         oss2 << *data++;
5799       if(i!=nbOfTuples-1) oss2 << ", ";
5800       std::string oss3Str(oss2.str());
5801       if(oss3Str.length()<maxNbOfByteInRepr)
5802         oss2Str=oss3Str;
5803       else
5804         isFinished=false;
5805     }
5806   stream << oss2Str;
5807   if(!isFinished)
5808     stream << "... ";
5809   stream << "]";
5810 }
5811
5812 /*!
5813  * Modifies \a this one-dimensional array so that each value \a v = \a indArrBg[ \a v ],
5814  * i.e. a current value is used as in index to get a new value from \a indArrBg.
5815  *  \param [in] indArrBg - pointer to the first element of array of new values to assign
5816  *         to \a this array.
5817  *  \param [in] indArrEnd - specifies the end of the array \a indArrBg, so that
5818  *              the last value of \a indArrBg is \a indArrEnd[ -1 ].
5819  *  \throw If \a this->getNumberOfComponents() != 1
5820  *  \throw If any value of \a this can't be used as a valid index for 
5821  *         [\a indArrBg, \a indArrEnd).
5822  */
5823 void DataArrayInt::transformWithIndArr(const int *indArrBg, const int *indArrEnd) throw(INTERP_KERNEL::Exception)
5824 {
5825   checkAllocated();
5826   if(getNumberOfComponents()!=1)
5827     throw INTERP_KERNEL::Exception("Call transformWithIndArr method on DataArrayInt with only one component, you can call 'rearrange' method before !");
5828   int nbElemsIn=(int)std::distance(indArrBg,indArrEnd);
5829   int nbOfTuples=getNumberOfTuples();
5830   int *pt=getPointer();
5831   for(int i=0;i<nbOfTuples;i++,pt++)
5832     {
5833       if(*pt>=0 && *pt<nbElemsIn)
5834         *pt=indArrBg[*pt];
5835       else
5836         {
5837           std::ostringstream oss; oss << "DataArrayInt::transformWithIndArr : error on tuple #" << i << " of this value is " << *pt << ", should be in [0," << nbElemsIn << ") !";
5838           throw INTERP_KERNEL::Exception(oss.str().c_str());
5839         }
5840     }
5841   declareAsNew();
5842 }
5843
5844 /*!
5845  * Computes distribution of values of \a this one-dimensional array between given value
5846  * ranges (casts). This method is typically useful for entity number spliting by types,
5847  * for example. 
5848  *  \warning The values contained in \a arrBg should be sorted ascendently. No
5849  *           check of this is be done. If not, the result is not warranted. 
5850  *  \param [in] arrBg - the array of ascending values defining the value ranges. The i-th
5851  *         value of \a arrBg (\a arrBg[ i ]) gives the lowest value of the i-th range,
5852  *         and the greatest value of the i-th range equals to \a arrBg[ i+1 ] - 1. \a
5853  *         arrBg containing \a n values defines \a n-1 ranges. The last value of \a arrBg
5854  *         should be more than every value in \a this array.
5855  *  \param [in] arrEnd - specifies the end of the array \a arrBg, so that
5856  *              the last value of \a arrBg is \a arrEnd[ -1 ].
5857  *  \param [out] castArr - a new instance of DataArrayInt, of same size as \a this array
5858  *         (same number of tuples and components), the caller is to delete 
5859  *         using decrRef() as it is no more needed.
5860  *         This array contains indices of ranges for every value of \a this array. I.e.
5861  *         the i-th value of \a castArr gives the index of range the i-th value of \a this
5862  *         belongs to. Or, in other words, this parameter contains for each tuple in \a
5863  *         this in which cast it holds.
5864  *  \param [out] rankInsideCast - a new instance of DataArrayInt, of same size as \a this
5865  *         array, the caller is to delete using decrRef() as it is no more needed.
5866  *         This array contains ranks of values of \a this array within ranges
5867  *         they belongs to. I.e. the i-th value of \a rankInsideCast gives the rank of
5868  *         the i-th value of \a this array within the \a castArr[ i ]-th range, to which
5869  *         the i-th value of \a this belongs to. Or, in other words, this param contains 
5870  *         for each tuple its rank inside its cast. The rank is computed as difference
5871  *         between the value and the lowest value of range.
5872  *  \param [out] castsPresent - a new instance of DataArrayInt, containing indices of
5873  *         ranges (casts) to which at least one value of \a this array belongs.
5874  *         Or, in other words, this param contains the casts that \a this contains.
5875  *         The caller is to delete this array using decrRef() as it is no more needed.
5876  *
5877  * \b Example: If \a this contains [6,5,0,3,2,7,8,1,4] and \a arrBg contains [0,4,9] then
5878  *            the output of this method will be : 
5879  * - \a castArr       : [1,1,0,0,0,1,1,0,1]
5880  * - \a rankInsideCast: [2,1,0,3,2,3,4,1,0]
5881  * - \a castsPresent  : [0,1]
5882  *
5883  * I.e. values of \a this array belong to 2 ranges: #0 and #1. Value 6 belongs to the
5884  * range #1 and its rank within this range is 2; etc.
5885  *
5886  *  \throw If \a this->getNumberOfComponents() != 1.
5887  *  \throw If \a arrEnd - arrBg < 2.
5888  *  \throw If any value of \a this is not less than \a arrEnd[-1].
5889  */
5890 void DataArrayInt::splitByValueRange(const int *arrBg, const int *arrEnd,
5891                                      DataArrayInt *& castArr, DataArrayInt *& rankInsideCast, DataArrayInt *& castsPresent) const throw(INTERP_KERNEL::Exception)
5892 {
5893   checkAllocated();
5894   if(getNumberOfComponents()!=1)
5895     throw INTERP_KERNEL::Exception("Call splitByValueRange  method on DataArrayInt with only one component, you can call 'rearrange' method before !");
5896   int nbOfTuples=getNumberOfTuples();
5897   std::size_t nbOfCast=std::distance(arrBg,arrEnd);
5898   if(nbOfCast<2)
5899     throw INTERP_KERNEL::Exception("DataArrayInt::splitByValueRange : The input array giving the cast range values should be of size >=2 !");
5900   nbOfCast--;
5901   const int *work=getConstPointer();
5902   typedef std::reverse_iterator<const int *> rintstart;
5903   rintstart bg(arrEnd);//OK no problem because size of 'arr' is greater or equal 2
5904   rintstart end2(arrBg);
5905   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret1=DataArrayInt::New();
5906   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret2=DataArrayInt::New();
5907   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret3=DataArrayInt::New();
5908   ret1->alloc(nbOfTuples,1);
5909   ret2->alloc(nbOfTuples,1);
5910   int *ret1Ptr=ret1->getPointer();
5911   int *ret2Ptr=ret2->getPointer();
5912   std::set<std::size_t> castsDetected;
5913   for(int i=0;i<nbOfTuples;i++)
5914     {
5915       rintstart res=std::find_if(bg,end2,std::bind2nd(std::less_equal<int>(), work[i]));
5916       std::size_t pos=std::distance(bg,res);
5917       std::size_t pos2=nbOfCast-pos;
5918       if(pos2<nbOfCast)
5919         {
5920           ret1Ptr[i]=(int)pos2;
5921           ret2Ptr[i]=work[i]-arrBg[pos2];
5922           castsDetected.insert(pos2);
5923         }
5924       else
5925         {
5926           std::ostringstream oss; oss << "DataArrayInt::splitByValueRange : At rank #" << i << " the value is " << work[i] << " should be in [0," << *bg << ") !";
5927           throw INTERP_KERNEL::Exception(oss.str().c_str());
5928         }
5929     }
5930   ret3->alloc((int)castsDetected.size(),1);
5931   std::copy(castsDetected.begin(),castsDetected.end(),ret3->getPointer());
5932   castArr=ret1.retn();
5933   rankInsideCast=ret2.retn();
5934   castsPresent=ret3.retn();
5935 }
5936
5937 /*!
5938  * Creates a one-dimensional DataArrayInt (\a res) whose contents are computed from 
5939  * values of \a this (\a a) and the given (\a indArr) arrays as follows:
5940  * \a res[ \a indArr[ \a a[ i ]]] = i. I.e. for each value in place i \a v = \a a[ i ],
5941  * new value in place \a indArr[ \a v ] is i.
5942  *  \param [in] indArrBg - the array holding indices within the result array to assign
5943  *         indices of values of \a this array pointing to values of \a indArrBg.
5944  *  \param [in] indArrEnd - specifies the end of the array \a indArrBg, so that
5945  *              the last value of \a indArrBg is \a indArrEnd[ -1 ].
5946  *  \return DataArrayInt * - the new instance of DataArrayInt.
5947  *          The caller is to delete this result array using decrRef() as it is no more
5948  *          needed.
5949  *  \throw If \a this->getNumberOfComponents() != 1.
5950  *  \throw If any value of \a this array is not a valid index for \a indArrBg array.
5951  *  \throw If any value of \a indArrBg is not a valid index for \a this array.
5952  */
5953 DataArrayInt *DataArrayInt::transformWithIndArrR(const int *indArrBg, const int *indArrEnd) const throw(INTERP_KERNEL::Exception)
5954 {
5955   checkAllocated();
5956   if(getNumberOfComponents()!=1)
5957     throw INTERP_KERNEL::Exception("Call transformWithIndArrR method on DataArrayInt with only one component, you can call 'rearrange' method before !");
5958   int nbElemsIn=(int)std::distance(indArrBg,indArrEnd);
5959   int nbOfTuples=getNumberOfTuples();
5960   const int *pt=getConstPointer();
5961   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
5962   ret->alloc(nbOfTuples,1);
5963   ret->fillWithValue(-1);
5964   int *tmp=ret->getPointer();
5965   for(int i=0;i<nbOfTuples;i++,pt++)
5966     {
5967       if(*pt>=0 && *pt<nbElemsIn)
5968         {
5969           int pos=indArrBg[*pt];
5970           if(pos>=0 && pos<nbOfTuples)
5971             tmp[pos]=i;
5972           else
5973             {
5974               std::ostringstream oss; oss << "DataArrayInt::transformWithIndArrR : error on tuple #" << i << " value of new pos is " << pos << " ( indArrBg[" << *pt << "]) ! Should be in [0," << nbOfTuples << ") !";
5975               throw INTERP_KERNEL::Exception(oss.str().c_str());
5976             }
5977         }
5978       else
5979         {
5980           std::ostringstream oss; oss << "DataArrayInt::transformWithIndArrR : error on tuple #" << i << " value is " << *pt << " and indirectionnal array as a size equal to " << nbElemsIn << " !";
5981           throw INTERP_KERNEL::Exception(oss.str().c_str());
5982         }
5983     }
5984   return ret.retn();
5985 }
5986
5987 /*!
5988  * Creates a one-dimensional DataArrayInt of given length, whose contents are computed
5989  * from values of \a this array, which is supposed to contain a renumbering map in 
5990  * "Old to New" mode. The result array contains a renumbering map in "New to Old" mode.
5991  * To know how to use the renumbering maps see \ref MEDCouplingArrayRenumbering.
5992  *  \param [in] newNbOfElem - the number of tuples in the result array.
5993  *  \return DataArrayInt * - the new instance of DataArrayInt.
5994  *          The caller is to delete this result array using decrRef() as it is no more
5995  *          needed.
5996  * 
5997  *  \ref cpp_mcdataarrayint_invertarrayo2n2n2o "Here is a C++ example".<br>
5998  *  \ref py_mcdataarrayint_invertarrayo2n2n2o  "Here is a Python example".
5999  */
6000 DataArrayInt *DataArrayInt::invertArrayO2N2N2O(int newNbOfElem) const
6001 {
6002   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6003   ret->alloc(newNbOfElem,1);
6004   int nbOfOldNodes=getNumberOfTuples();
6005   const int *old2New=getConstPointer();
6006   int *pt=ret->getPointer();
6007   for(int i=0;i!=nbOfOldNodes;i++)
6008     if(old2New[i]!=-1)
6009       pt[old2New[i]]=i;
6010   return ret.retn();
6011 }
6012
6013 /*!
6014  * This method is similar to DataArrayInt::invertArrayO2N2N2O except that 
6015  * 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]
6016  */
6017 DataArrayInt *DataArrayInt::invertArrayO2N2N2OBis(int newNbOfElem) const throw(INTERP_KERNEL::Exception)
6018 {
6019   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6020   ret->alloc(newNbOfElem,1);
6021   int nbOfOldNodes=getNumberOfTuples();
6022   const int *old2New=getConstPointer();
6023   int *pt=ret->getPointer();
6024   for(int i=nbOfOldNodes-1;i>=0;i--)
6025     if(old2New[i]!=-1)
6026       pt[old2New[i]]=i;
6027   return ret.retn();
6028 }
6029
6030 /*!
6031  * Creates a one-dimensional DataArrayInt of given length, whose contents are computed
6032  * from values of \a this array, which is supposed to contain a renumbering map in 
6033  * "New to Old" mode. The result array contains a renumbering map in "Old to New" mode.
6034  * To know how to use the renumbering maps see \ref MEDCouplingArrayRenumbering.
6035  *  \param [in] newNbOfElem - the number of tuples in the result array.
6036  *  \return DataArrayInt * - the new instance of DataArrayInt.
6037  *          The caller is to delete this result array using decrRef() as it is no more
6038  *          needed.
6039  * 
6040  *  \ref cpp_mcdataarrayint_invertarrayn2o2o2n "Here is a C++ example".
6041  *
6042  *  \ref py_mcdataarrayint_invertarrayn2o2o2n "Here is a Python example".
6043  */
6044 DataArrayInt *DataArrayInt::invertArrayN2O2O2N(int oldNbOfElem) const
6045 {
6046   checkAllocated();
6047   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6048   ret->alloc(oldNbOfElem,1);
6049   const int *new2Old=getConstPointer();
6050   int *pt=ret->getPointer();
6051   std::fill(pt,pt+oldNbOfElem,-1);
6052   int nbOfNewElems=getNumberOfTuples();
6053   for(int i=0;i<nbOfNewElems;i++)
6054     pt[new2Old[i]]=i;
6055   return ret.retn();
6056 }
6057
6058 /*!
6059  * Equivalent to DataArrayInt::isEqual except that if false the reason of
6060  * mismatch is given.
6061  * 
6062  * \param [in] other the instance to be compared with \a this
6063  * \param [out] reason In case of inequality returns the reason.
6064  * \sa DataArrayInt::isEqual
6065  */
6066 bool DataArrayInt::isEqualIfNotWhy(const DataArrayInt& other, std::string& reason) const throw(INTERP_KERNEL::Exception)
6067 {
6068   if(!areInfoEqualsIfNotWhy(other,reason))
6069     return false;
6070   return _mem.isEqual(other._mem,0,reason);
6071 }
6072
6073 /*!
6074  * Checks if \a this and another DataArrayInt are fully equal. For more info see
6075  * \ref MEDCouplingArrayBasicsCompare.
6076  *  \param [in] other - an instance of DataArrayInt to compare with \a this one.
6077  *  \return bool - \a true if the two arrays are equal, \a false else.
6078  */
6079 bool DataArrayInt::isEqual(const DataArrayInt& other) const throw(INTERP_KERNEL::Exception)
6080 {
6081   std::string tmp;
6082   return isEqualIfNotWhy(other,tmp);
6083 }
6084
6085 /*!
6086  * Checks if values of \a this and another DataArrayInt are equal. For more info see
6087  * \ref MEDCouplingArrayBasicsCompare.
6088  *  \param [in] other - an instance of DataArrayInt to compare with \a this one.
6089  *  \return bool - \a true if the values of two arrays are equal, \a false else.
6090  */
6091 bool DataArrayInt::isEqualWithoutConsideringStr(const DataArrayInt& other) const throw(INTERP_KERNEL::Exception)
6092 {
6093   std::string tmp;
6094   return _mem.isEqual(other._mem,0,tmp);
6095 }
6096
6097 /*!
6098  * Checks if values of \a this and another DataArrayInt are equal. Comparison is
6099  * performed on sorted value sequences.
6100  * For more info see\ref MEDCouplingArrayBasicsCompare.
6101  *  \param [in] other - an instance of DataArrayInt to compare with \a this one.
6102  *  \return bool - \a true if the sorted values of two arrays are equal, \a false else.
6103  */
6104 bool DataArrayInt::isEqualWithoutConsideringStrAndOrder(const DataArrayInt& other) const throw(INTERP_KERNEL::Exception)
6105 {
6106   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> a=deepCpy();
6107   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> b=other.deepCpy();
6108   a->sort();
6109   b->sort();
6110   return a->isEqualWithoutConsideringStr(*b);
6111 }
6112
6113 /*!
6114  * Sorts values of the array.
6115  *  \param [in] asc - \a true means ascending order, \a false, descending.
6116  *  \throw If \a this is not allocated.
6117  *  \throw If \a this->getNumberOfComponents() != 1.
6118  */
6119 void DataArrayInt::sort(bool asc) throw(INTERP_KERNEL::Exception)
6120 {
6121   checkAllocated();
6122   if(getNumberOfComponents()!=1)
6123     throw INTERP_KERNEL::Exception("DataArrayInt::sort : only supported with 'this' array with ONE component !");
6124   _mem.sort(asc);
6125   declareAsNew();
6126 }
6127
6128 /*!
6129  * Reverse the array values.
6130  *  \throw If \a this->getNumberOfComponents() < 1.
6131  *  \throw If \a this is not allocated.
6132  */
6133 void DataArrayInt::reverse() throw(INTERP_KERNEL::Exception)
6134 {
6135   checkAllocated();
6136   _mem.reverse(getNumberOfComponents());
6137   declareAsNew();
6138 }
6139
6140 /*!
6141  * Checks that \a this array is consistently **increasing** or **decreasing** in value.
6142  * If not an exception is thrown.
6143  *  \param [in] increasing - if \a true, the array values should be increasing.
6144  *  \throw If sequence of values is not strictly monotonic in agreement with \a
6145  *         increasing arg.
6146  *  \throw If \a this->getNumberOfComponents() != 1.
6147  *  \throw If \a this is not allocated.
6148  */
6149 void DataArrayInt::checkMonotonic(bool increasing) const throw(INTERP_KERNEL::Exception)
6150 {
6151   if(!isMonotonic(increasing))
6152     {
6153       if (increasing)
6154         throw INTERP_KERNEL::Exception("DataArrayInt::checkMonotonic : 'this' is not INCREASING monotonic !");
6155       else
6156         throw INTERP_KERNEL::Exception("DataArrayInt::checkMonotonic : 'this' is not DECREASING monotonic !");
6157     }
6158 }
6159
6160 /*!
6161  * Checks that \a this array is consistently **increasing** or **decreasing** in value.
6162  *  \param [in] increasing - if \a true, array values should be increasing.
6163  *  \return bool - \a true if values change in accordance with \a increasing arg.
6164  *  \throw If \a this->getNumberOfComponents() != 1.
6165  *  \throw If \a this is not allocated.
6166  */
6167 bool DataArrayInt::isMonotonic(bool increasing) const throw(INTERP_KERNEL::Exception)
6168 {
6169   checkAllocated();
6170   if(getNumberOfComponents()!=1)
6171     throw INTERP_KERNEL::Exception("DataArrayInt::isMonotonic : only supported with 'this' array with ONE component !");
6172   int nbOfElements=getNumberOfTuples();
6173   const int *ptr=getConstPointer();
6174   if(nbOfElements==0)
6175     return true;
6176   int ref=ptr[0];
6177   if(increasing)
6178     {
6179       for(int i=1;i<nbOfElements;i++)
6180         {
6181           if(ptr[i]>=ref)
6182             ref=ptr[i];
6183           else
6184             return false;
6185         }
6186     }
6187   else
6188     {
6189       for(int i=1;i<nbOfElements;i++)
6190         {
6191           if(ptr[i]<=ref)
6192             ref=ptr[i];
6193           else
6194             return false;
6195         }
6196     }
6197   return true;
6198 }
6199
6200 /*!
6201  * This method check that array consistently INCREASING or DECREASING in value.
6202  */
6203 bool DataArrayInt::isStrictlyMonotonic(bool increasing) const throw(INTERP_KERNEL::Exception)
6204 {
6205   checkAllocated();
6206   if(getNumberOfComponents()!=1)
6207     throw INTERP_KERNEL::Exception("DataArrayInt::isStrictlyMonotonic : only supported with 'this' array with ONE component !");
6208   int nbOfElements=getNumberOfTuples();
6209   const int *ptr=getConstPointer();
6210   if(nbOfElements==0)
6211     return true;
6212   int ref=ptr[0];
6213   if(increasing)
6214     {
6215       for(int i=1;i<nbOfElements;i++)
6216         {
6217           if(ptr[i]>ref)
6218             ref=ptr[i];
6219           else
6220             return false;
6221         }
6222     }
6223   else
6224     {
6225       for(int i=1;i<nbOfElements;i++)
6226         {
6227           if(ptr[i]<ref)
6228             ref=ptr[i];
6229           else
6230             return false;
6231         }
6232     }
6233   return true;
6234 }
6235
6236 /*!
6237  * This method check that array consistently INCREASING or DECREASING in value.
6238  */
6239 void DataArrayInt::checkStrictlyMonotonic(bool increasing) const throw(INTERP_KERNEL::Exception)
6240 {
6241   if(!isStrictlyMonotonic(increasing))
6242     {
6243       if (increasing)
6244         throw INTERP_KERNEL::Exception("DataArrayInt::checkStrictlyMonotonic : 'this' is not strictly INCREASING monotonic !");
6245       else
6246         throw INTERP_KERNEL::Exception("DataArrayInt::checkStrictlyMonotonic : 'this' is not strictly DECREASING monotonic !");
6247     }
6248 }
6249
6250 /*!
6251  * Creates a new one-dimensional DataArrayInt of the same size as \a this and a given
6252  * one-dimensional arrays that must be of the same length. The result array describes
6253  * correspondence between \a this and \a other arrays, so that 
6254  * <em> other.getIJ(i,0) == this->getIJ(ret->getIJ(i),0)</em>. If such a permutation is
6255  * not possible because some element in \a other is not in \a this, an exception is thrown.
6256  *  \param [in] other - an array to compute permutation to.
6257  *  \return DataArrayInt * - a new instance of DataArrayInt, which is a permutation array
6258  * from \a this to \a other. The caller is to delete this array using decrRef() as it is
6259  * no more needed.
6260  *  \throw If \a this->getNumberOfComponents() != 1.
6261  *  \throw If \a other->getNumberOfComponents() != 1.
6262  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples().
6263  *  \throw If \a other includes a value which is not in \a this array.
6264  * 
6265  *  \ref cpp_mcdataarrayint_buildpermutationarr "Here is a C++ example".
6266  *
6267  *  \ref py_mcdataarrayint_buildpermutationarr "Here is a Python example".
6268  */
6269 DataArrayInt *DataArrayInt::buildPermutationArr(const DataArrayInt& other) const throw(INTERP_KERNEL::Exception)
6270 {
6271   checkAllocated();
6272   if(getNumberOfComponents()!=1 || other.getNumberOfComponents()!=1)
6273     throw INTERP_KERNEL::Exception("DataArrayInt::buildPermutationArr : 'this' and 'other' have to have exactly ONE component !");
6274   int nbTuple=getNumberOfTuples();
6275   other.checkAllocated();
6276   if(nbTuple!=other.getNumberOfTuples())
6277     throw INTERP_KERNEL::Exception("DataArrayInt::buildPermutationArr : 'this' and 'other' must have the same number of tuple !");
6278   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6279   ret->alloc(nbTuple,1);
6280   ret->fillWithValue(-1);
6281   const int *pt=getConstPointer();
6282   std::map<int,int> mm;
6283   for(int i=0;i<nbTuple;i++)
6284     mm[pt[i]]=i;
6285   pt=other.getConstPointer();
6286   int *retToFill=ret->getPointer();
6287   for(int i=0;i<nbTuple;i++)
6288     {
6289       std::map<int,int>::const_iterator it=mm.find(pt[i]);
6290       if(it==mm.end())
6291         {
6292           std::ostringstream oss; oss << "DataArrayInt::buildPermutationArr : Arrays mismatch : element (" << pt[i] << ") in 'other' not findable in 'this' !";
6293           throw INTERP_KERNEL::Exception(oss.str().c_str());
6294         }
6295       retToFill[i]=(*it).second;
6296     }
6297   return ret.retn();
6298 }
6299
6300 /*!
6301  * Sets a C array to be used as raw data of \a this. The previously set info
6302  *  of components is retained and re-sized. 
6303  * For more info see \ref MEDCouplingArraySteps1.
6304  *  \param [in] array - the C array to be used as raw data of \a this.
6305  *  \param [in] ownership - if \a true, \a array will be deallocated at destruction of \a this.
6306  *  \param [in] type - specifies how to deallocate \a array. If \a type == ParaMEDMEM::CPP_DEALLOC,
6307  *                     \c delete [] \c array; will be called. If \a type == ParaMEDMEM::C_DEALLOC,
6308  *                     \c free(\c array ) will be called.
6309  *  \param [in] nbOfTuple - new number of tuples in \a this.
6310  *  \param [in] nbOfCompo - new number of components in \a this.
6311  */
6312 void DataArrayInt::useArray(const int *array, bool ownership,  DeallocType type, int nbOfTuple, int nbOfCompo) throw(INTERP_KERNEL::Exception)
6313 {
6314   _info_on_compo.resize(nbOfCompo);
6315   _mem.useArray(array,ownership,type,nbOfTuple*nbOfCompo);
6316   declareAsNew();
6317 }
6318
6319 void DataArrayInt::useExternalArrayWithRWAccess(const int *array, int nbOfTuple, int nbOfCompo) throw(INTERP_KERNEL::Exception)
6320 {
6321   _info_on_compo.resize(nbOfCompo);
6322   _mem.useExternalArrayWithRWAccess(array,nbOfTuple*nbOfCompo);
6323   declareAsNew();
6324 }
6325
6326 /*!
6327  * Returns a new DataArrayInt holding the same values as \a this array but differently
6328  * arranged in memory. If \a this array holds 2 components of 3 values:
6329  * \f$ x_0,x_1,x_2,y_0,y_1,y_2 \f$, then the result array holds these values arranged
6330  * as follows: \f$ x_0,y_0,x_1,y_1,x_2,y_2 \f$.
6331  *  \warning Do not confuse this method with transpose()!
6332  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
6333  *          is to delete using decrRef() as it is no more needed.
6334  *  \throw If \a this is not allocated.
6335  */
6336 DataArrayInt *DataArrayInt::fromNoInterlace() const throw(INTERP_KERNEL::Exception)
6337 {
6338   checkAllocated();
6339   if(_mem.isNull())
6340     throw INTERP_KERNEL::Exception("DataArrayInt::fromNoInterlace : Not defined array !");
6341   int *tab=_mem.fromNoInterlace(getNumberOfComponents());
6342   DataArrayInt *ret=DataArrayInt::New();
6343   ret->useArray(tab,true,C_DEALLOC,getNumberOfTuples(),getNumberOfComponents());
6344   return ret;
6345 }
6346
6347 /*!
6348  * Returns a new DataArrayInt holding the same values as \a this array but differently
6349  * arranged in memory. If \a this array holds 2 components of 3 values:
6350  * \f$ x_0,y_0,x_1,y_1,x_2,y_2 \f$, then the result array holds these values arranged
6351  * as follows: \f$ x_0,x_1,x_2,y_0,y_1,y_2 \f$.
6352  *  \warning Do not confuse this method with transpose()!
6353  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
6354  *          is to delete using decrRef() as it is no more needed.
6355  *  \throw If \a this is not allocated.
6356  */
6357 DataArrayInt *DataArrayInt::toNoInterlace() const throw(INTERP_KERNEL::Exception)
6358 {
6359   checkAllocated();
6360   if(_mem.isNull())
6361     throw INTERP_KERNEL::Exception("DataArrayInt::toNoInterlace : Not defined array !");
6362   int *tab=_mem.toNoInterlace(getNumberOfComponents());
6363   DataArrayInt *ret=DataArrayInt::New();
6364   ret->useArray(tab,true,C_DEALLOC,getNumberOfTuples(),getNumberOfComponents());
6365   return ret;
6366 }
6367
6368 /*!
6369  * Permutes values of \a this array as required by \a old2New array. The values are
6370  * permuted so that \c new[ \a old2New[ i ]] = \c old[ i ]. Number of tuples remains
6371  * the same as in \this one.
6372  * If a permutation reduction is needed, substr() or selectByTupleId() should be used.
6373  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
6374  *  \param [in] old2New - C array of length equal to \a this->getNumberOfTuples()
6375  *     giving a new position for i-th old value.
6376  */
6377 void DataArrayInt::renumberInPlace(const int *old2New) throw(INTERP_KERNEL::Exception)
6378 {
6379   checkAllocated();
6380   int nbTuples=getNumberOfTuples();
6381   int nbOfCompo=getNumberOfComponents();
6382   int *tmp=new int[nbTuples*nbOfCompo];
6383   const int *iptr=getConstPointer();
6384   for(int i=0;i<nbTuples;i++)
6385     {
6386       int v=old2New[i];
6387       if(v>=0 && v<nbTuples)
6388         std::copy(iptr+nbOfCompo*i,iptr+nbOfCompo*(i+1),tmp+nbOfCompo*v);
6389       else
6390         {
6391           std::ostringstream oss; oss << "DataArrayInt::renumberInPlace : At place #" << i << " value is " << v << " ! Should be in [0," << nbTuples << ") !";
6392           throw INTERP_KERNEL::Exception(oss.str().c_str());
6393         }
6394     }
6395   std::copy(tmp,tmp+nbTuples*nbOfCompo,getPointer());
6396   delete [] tmp;
6397   declareAsNew();
6398 }
6399
6400 /*!
6401  * Permutes values of \a this array as required by \a new2Old array. The values are
6402  * permuted so that \c new[ i ] = \c old[ \a new2Old[ i ]]. Number of tuples remains
6403  * the same as in \this one.
6404  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
6405  *  \param [in] new2Old - C array of length equal to \a this->getNumberOfTuples()
6406  *     giving a previous position of i-th new value.
6407  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
6408  *          is to delete using decrRef() as it is no more needed.
6409  */
6410 void DataArrayInt::renumberInPlaceR(const int *new2Old) throw(INTERP_KERNEL::Exception)
6411 {
6412   checkAllocated();
6413   int nbTuples=getNumberOfTuples();
6414   int nbOfCompo=getNumberOfComponents();
6415   int *tmp=new int[nbTuples*nbOfCompo];
6416   const int *iptr=getConstPointer();
6417   for(int i=0;i<nbTuples;i++)
6418     {
6419       int v=new2Old[i];
6420       if(v>=0 && v<nbTuples)
6421         std::copy(iptr+nbOfCompo*v,iptr+nbOfCompo*(v+1),tmp+nbOfCompo*i);
6422       else
6423         {
6424           std::ostringstream oss; oss << "DataArrayInt::renumberInPlaceR : At place #" << i << " value is " << v << " ! Should be in [0," << nbTuples << ") !";
6425           throw INTERP_KERNEL::Exception(oss.str().c_str());
6426         }
6427     }
6428   std::copy(tmp,tmp+nbTuples*nbOfCompo,getPointer());
6429   delete [] tmp;
6430   declareAsNew();
6431 }
6432
6433 /*!
6434  * Returns a copy of \a this array with values permuted as required by \a old2New array.
6435  * The values are permuted so that  \c new[ \a old2New[ i ]] = \c old[ i ].
6436  * Number of tuples in the result array remains the same as in \this one.
6437  * If a permutation reduction is needed, renumberAndReduce() should be used.
6438  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
6439  *  \param [in] old2New - C array of length equal to \a this->getNumberOfTuples()
6440  *          giving a new position for i-th old value.
6441  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
6442  *          is to delete using decrRef() as it is no more needed.
6443  *  \throw If \a this is not allocated.
6444  */
6445 DataArrayInt *DataArrayInt::renumber(const int *old2New) const throw(INTERP_KERNEL::Exception)
6446 {
6447   checkAllocated();
6448   int nbTuples=getNumberOfTuples();
6449   int nbOfCompo=getNumberOfComponents();
6450   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6451   ret->alloc(nbTuples,nbOfCompo);
6452   ret->copyStringInfoFrom(*this);
6453   const int *iptr=getConstPointer();
6454   int *optr=ret->getPointer();
6455   for(int i=0;i<nbTuples;i++)
6456     std::copy(iptr+nbOfCompo*i,iptr+nbOfCompo*(i+1),optr+nbOfCompo*old2New[i]);
6457   ret->copyStringInfoFrom(*this);
6458   return ret.retn();
6459 }
6460
6461 /*!
6462  * Returns a copy of \a this array with values permuted as required by \a new2Old array.
6463  * The values are permuted so that  \c new[ i ] = \c old[ \a new2Old[ i ]]. Number of
6464  * tuples in the result array remains the same as in \this one.
6465  * If a permutation reduction is needed, substr() or selectByTupleId() should be used.
6466  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
6467  *  \param [in] new2Old - C array of length equal to \a this->getNumberOfTuples()
6468  *     giving a previous position of i-th new value.
6469  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
6470  *          is to delete using decrRef() as it is no more needed.
6471  */
6472 DataArrayInt *DataArrayInt::renumberR(const int *new2Old) 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*new2Old[i],iptr+nbOfCompo*(new2Old[i]+1),optr+nbOfCompo*i);
6484   ret->copyStringInfoFrom(*this);
6485   return ret.retn();
6486 }
6487
6488 /*!
6489  * Returns a shorten and permuted copy of \a this array. The new DataArrayInt is
6490  * of size \a newNbOfTuple and it's values are permuted as required by \a old2New array.
6491  * The values are permuted so that  \c new[ \a old2New[ i ]] = \c old[ i ] for all
6492  * \a old2New[ i ] >= 0. In other words every i-th tuple in \a this array, for which 
6493  * \a old2New[ i ] is negative, is missing from the result array.
6494  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
6495  *  \param [in] old2New - C array of length equal to \a this->getNumberOfTuples()
6496  *     giving a new position for i-th old tuple and giving negative position for
6497  *     for i-th old tuple that should be omitted.
6498  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
6499  *          is to delete using decrRef() as it is no more needed.
6500  */
6501 DataArrayInt *DataArrayInt::renumberAndReduce(const int *old2New, int newNbOfTuple) const throw(INTERP_KERNEL::Exception)
6502 {
6503   checkAllocated();
6504   int nbTuples=getNumberOfTuples();
6505   int nbOfCompo=getNumberOfComponents();
6506   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6507   ret->alloc(newNbOfTuple,nbOfCompo);
6508   const int *iptr=getConstPointer();
6509   int *optr=ret->getPointer();
6510   for(int i=0;i<nbTuples;i++)
6511     {
6512       int w=old2New[i];
6513       if(w>=0)
6514         std::copy(iptr+i*nbOfCompo,iptr+(i+1)*nbOfCompo,optr+w*nbOfCompo);
6515     }
6516   ret->copyStringInfoFrom(*this);
6517   return ret.retn();
6518 }
6519
6520 /*!
6521  * Returns a shorten and permuted copy of \a this array. The new DataArrayInt is
6522  * of size \a new2OldEnd - \a new2OldBg and it's values are permuted as required by
6523  * \a new2OldBg array.
6524  * The values are permuted so that  \c new[ i ] = \c old[ \a new2OldBg[ i ]].
6525  * This method is equivalent to renumberAndReduce() except that convention in input is
6526  * \c new2old and \b not \c old2new.
6527  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
6528  *  \param [in] new2OldBg - pointer to the beginning of a permutation array that gives a
6529  *              tuple index in \a this array to fill the i-th tuple in the new array.
6530  *  \param [in] new2OldEnd - specifies the end of the permutation array that starts at
6531  *              \a new2OldBg, so that pointer to a tuple index (\a pi) varies as this:
6532  *              \a new2OldBg <= \a pi < \a new2OldEnd.
6533  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
6534  *          is to delete using decrRef() as it is no more needed.
6535  */
6536 DataArrayInt *DataArrayInt::selectByTupleId(const int *new2OldBg, const int *new2OldEnd) const
6537 {
6538   checkAllocated();
6539   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6540   int nbComp=getNumberOfComponents();
6541   ret->alloc((int)std::distance(new2OldBg,new2OldEnd),nbComp);
6542   ret->copyStringInfoFrom(*this);
6543   int *pt=ret->getPointer();
6544   const int *srcPt=getConstPointer();
6545   int i=0;
6546   for(const int *w=new2OldBg;w!=new2OldEnd;w++,i++)
6547     std::copy(srcPt+(*w)*nbComp,srcPt+((*w)+1)*nbComp,pt+i*nbComp);
6548   ret->copyStringInfoFrom(*this);
6549   return ret.retn();
6550 }
6551
6552 /*!
6553  * Returns a shorten and permuted copy of \a this array. The new DataArrayInt is
6554  * of size \a new2OldEnd - \a new2OldBg and it's values are permuted as required by
6555  * \a new2OldBg array.
6556  * The values are permuted so that  \c new[ i ] = \c old[ \a new2OldBg[ i ]].
6557  * This method is equivalent to renumberAndReduce() except that convention in input is
6558  * \c new2old and \b not \c old2new.
6559  * This method is equivalent to selectByTupleId() except that it prevents coping data
6560  * from behind the end of \a this array.
6561  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
6562  *  \param [in] new2OldBg - pointer to the beginning of a permutation array that gives a
6563  *              tuple index in \a this array to fill the i-th tuple in the new array.
6564  *  \param [in] new2OldEnd - specifies the end of the permutation array that starts at
6565  *              \a new2OldBg, so that pointer to a tuple index (\a pi) varies as this:
6566  *              \a new2OldBg <= \a pi < \a new2OldEnd.
6567  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
6568  *          is to delete using decrRef() as it is no more needed.
6569  *  \throw If \a new2OldEnd - \a new2OldBg > \a this->getNumberOfTuples().
6570  */
6571 DataArrayInt *DataArrayInt::selectByTupleIdSafe(const int *new2OldBg, const int *new2OldEnd) const throw(INTERP_KERNEL::Exception)
6572 {
6573   checkAllocated();
6574   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6575   int nbComp=getNumberOfComponents();
6576   int oldNbOfTuples=getNumberOfTuples();
6577   ret->alloc((int)std::distance(new2OldBg,new2OldEnd),nbComp);
6578   ret->copyStringInfoFrom(*this);
6579   int *pt=ret->getPointer();
6580   const int *srcPt=getConstPointer();
6581   int i=0;
6582   for(const int *w=new2OldBg;w!=new2OldEnd;w++,i++)
6583     if(*w>=0 && *w<oldNbOfTuples)
6584       std::copy(srcPt+(*w)*nbComp,srcPt+((*w)+1)*nbComp,pt+i*nbComp);
6585     else
6586       throw INTERP_KERNEL::Exception("DataArrayInt::selectByTupleIdSafe : some ids has been detected to be out of [0,this->getNumberOfTuples) !");
6587   ret->copyStringInfoFrom(*this);
6588   return ret.retn();
6589 }
6590
6591 /*!
6592  * Returns a shorten copy of \a this array. The new DataArrayInt contains every
6593  * (\a bg + \c i * \a step)-th tuple of \a this array located before the \a end2-th
6594  * tuple. Indices of the selected tuples are the same as ones returned by the Python
6595  * command \c range( \a bg, \a end2, \a step ).
6596  * This method is equivalent to selectByTupleIdSafe() except that the input array is
6597  * not constructed explicitly.
6598  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
6599  *  \param [in] bg - index of the first tuple to copy from \a this array.
6600  *  \param [in] end2 - index of the tuple before which the tuples to copy are located.
6601  *  \param [in] step - index increment to get index of the next tuple to copy.
6602  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
6603  *          is to delete using decrRef() as it is no more needed.
6604  *  \sa DataArrayInt::substr.
6605  */
6606 DataArrayInt *DataArrayInt::selectByTupleId2(int bg, int end2, int step) const throw(INTERP_KERNEL::Exception)
6607 {
6608   checkAllocated();
6609   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6610   int nbComp=getNumberOfComponents();
6611   int newNbOfTuples=GetNumberOfItemGivenBESRelative(bg,end2,step,"DataArrayInt::selectByTupleId2 : ");
6612   ret->alloc(newNbOfTuples,nbComp);
6613   int *pt=ret->getPointer();
6614   const int *srcPt=getConstPointer()+bg*nbComp;
6615   for(int i=0;i<newNbOfTuples;i++,srcPt+=step*nbComp)
6616     std::copy(srcPt,srcPt+nbComp,pt+i*nbComp);
6617   ret->copyStringInfoFrom(*this);
6618   return ret.retn();
6619 }
6620
6621 /*!
6622  * Returns a shorten copy of \a this array. The new DataArrayInt contains ranges
6623  * of tuples specified by \a ranges parameter.
6624  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
6625  *  \param [in] ranges - std::vector of std::pair's each of which defines a range
6626  *              of tuples in [\c begin,\c end) format.
6627  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
6628  *          is to delete using decrRef() as it is no more needed.
6629  *  \throw If \a end < \a begin.
6630  *  \throw If \a end > \a this->getNumberOfTuples().
6631  *  \throw If \a this is not allocated.
6632  */
6633 DataArray *DataArrayInt::selectByTupleRanges(const std::vector<std::pair<int,int> >& ranges) const throw(INTERP_KERNEL::Exception)
6634 {
6635   checkAllocated();
6636   int nbOfComp=getNumberOfComponents();
6637   int nbOfTuplesThis=getNumberOfTuples();
6638   if(ranges.empty())
6639     {
6640       MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6641       ret->alloc(0,nbOfComp);
6642       ret->copyStringInfoFrom(*this);
6643       return ret.retn();
6644     }
6645   int ref=ranges.front().first;
6646   int nbOfTuples=0;
6647   bool isIncreasing=true;
6648   for(std::vector<std::pair<int,int> >::const_iterator it=ranges.begin();it!=ranges.end();it++)
6649     {
6650       if((*it).first<=(*it).second)
6651         {
6652           if((*it).first>=0 && (*it).second<=nbOfTuplesThis)
6653             {
6654               nbOfTuples+=(*it).second-(*it).first;
6655               if(isIncreasing)
6656                 isIncreasing=ref<=(*it).first;
6657               ref=(*it).second;
6658             }
6659           else
6660             {
6661               std::ostringstream oss; oss << "DataArrayInt::selectByTupleRanges : on range #" << std::distance(ranges.begin(),it);
6662               oss << " (" << (*it).first << "," << (*it).second << ") is greater than number of tuples of this :" << nbOfTuples << " !";
6663               throw INTERP_KERNEL::Exception(oss.str().c_str());
6664             }
6665         }
6666       else
6667         {
6668           std::ostringstream oss; oss << "DataArrayInt::selectByTupleRanges : on range #" << std::distance(ranges.begin(),it);
6669           oss << " (" << (*it).first << "," << (*it).second << ") end is before begin !";
6670           throw INTERP_KERNEL::Exception(oss.str().c_str());
6671         }
6672     }
6673   if(isIncreasing && nbOfTuplesThis==nbOfTuples)
6674     return deepCpy();
6675   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6676   ret->alloc(nbOfTuples,nbOfComp);
6677   ret->copyStringInfoFrom(*this);
6678   const int *src=getConstPointer();
6679   int *work=ret->getPointer();
6680   for(std::vector<std::pair<int,int> >::const_iterator it=ranges.begin();it!=ranges.end();it++)
6681     work=std::copy(src+(*it).first*nbOfComp,src+(*it).second*nbOfComp,work);
6682   return ret.retn();
6683 }
6684
6685 /*!
6686  * Returns a new DataArrayInt containing a renumbering map in "Old to New" mode.
6687  * This map, if applied to \a this array, would make it sorted. For example, if
6688  * \a this array contents are [9,10,0,6,4,11,3,7] then the contents of the result array
6689  * are [5,6,0,3,2,7,1,4]; if this result array (\a res) is used as an argument in call
6690  * \a this->renumber(\a res) then the returned array contains [0,3,4,6,7,9,10,11].
6691  * This method is useful for renumbering (in MED file for example). For more info
6692  * on renumbering see \ref MEDCouplingArrayRenumbering.
6693  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
6694  *          array using decrRef() as it is no more needed.
6695  *  \throw If \a this is not allocated.
6696  *  \throw If \a this->getNumberOfComponents() != 1.
6697  *  \throw If there are equal values in \a this array.
6698  */
6699 DataArrayInt *DataArrayInt::checkAndPreparePermutation() const throw(INTERP_KERNEL::Exception)
6700 {
6701   checkAllocated();
6702   if(getNumberOfComponents()!=1)
6703     throw INTERP_KERNEL::Exception("DataArrayInt::checkAndPreparePermutation : number of components must == 1 !");
6704   int nbTuples=getNumberOfTuples();
6705   const int *pt=getConstPointer();
6706   int *pt2=CheckAndPreparePermutation(pt,pt+nbTuples);
6707   DataArrayInt *ret=DataArrayInt::New();
6708   ret->useArray(pt2,true,C_DEALLOC,nbTuples,1);
6709   return ret;
6710 }
6711
6712 /*!
6713  * Returns two arrays describing a surjective mapping from \a this set of values (\a A)
6714  * onto a set of values of size \a targetNb (\a B). The surjective function is 
6715  * \a B[ \a A[ i ]] = i. That is to say that for each \a id in [0,\a targetNb), where \a
6716  * targetNb < \a this->getNumberOfTuples(), there exists at least one tupleId (\a tid) so
6717  * that <em> this->getIJ( tid, 0 ) == id</em>. <br>
6718  * The first of out arrays returns indices of elements of \a this array, grouped by their
6719  * place in the set \a B. The second out array is the index of the first one; it shows how
6720  * many elements of \a A are mapped into each element of \a B. <br>
6721  * For more info on
6722  * mapping and its usage in renumbering see \ref MEDCouplingArrayRenumbering. <br>
6723  * \b Example:
6724  * - \a this: [0,3,2,3,2,2,1,2]
6725  * - \a targetNb: 4
6726  * - \a arr:  [0,  6,  2,4,5,7,  1,3]
6727  * - \a arrI: [0,1,2,6,8]
6728  *
6729  * This result means: <br>
6730  * the element of \a B 0 encounters within \a A once (\a arrI[ 0+1 ] - \a arrI[ 0 ]) and
6731  * its index within \a A is 0 ( \a arr[ 0:1 ] == \a arr[ \a arrI[ 0 ] : \a arrI[ 0+1 ]]);<br>
6732  * the element of \a B 2 encounters within \a A 4 times (\a arrI[ 2+1 ] - \a arrI[ 2 ]) and
6733  * its indices within \a A are [2,4,5,7] ( \a arr[ 2:6 ] == \a arr[ \a arrI[ 2 ] : 
6734  * \a arrI[ 2+1 ]]); <br> etc.
6735  *  \param [in] targetNb - the size of the set \a B. \a targetNb must be equal or more
6736  *         than the maximal value of \a A.
6737  *  \param [out] arr - a new instance of DataArrayInt returning indices of
6738  *         elements of \a this, grouped by their place in the set \a B. The caller is to delete
6739  *         this array using decrRef() as it is no more needed.
6740  *  \param [out] arrI - a new instance of DataArrayInt returning size of groups of equal
6741  *         elements of \a this. The caller is to delete this array using decrRef() as it
6742  *         is no more needed.
6743  *  \throw If \a this is not allocated.
6744  *  \throw If \a this->getNumberOfComponents() != 1.
6745  *  \throw If any value in \a this is more or equal to \a targetNb.
6746  */
6747 void DataArrayInt::changeSurjectiveFormat(int targetNb, DataArrayInt *&arr, DataArrayInt *&arrI) const throw(INTERP_KERNEL::Exception)
6748 {
6749   checkAllocated();
6750   if(getNumberOfComponents()!=1)
6751     throw INTERP_KERNEL::Exception("DataArrayInt::changeSurjectiveFormat : number of components must == 1 !");
6752   int nbOfTuples=getNumberOfTuples();
6753   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New());
6754   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> retI(DataArrayInt::New());
6755   retI->alloc(targetNb+1,1);
6756   const int *input=getConstPointer();
6757   std::vector< std::vector<int> > tmp(targetNb);
6758   for(int i=0;i<nbOfTuples;i++)
6759     {
6760       int tmp2=input[i];
6761       if(tmp2>=0 && tmp2<targetNb)
6762         tmp[tmp2].push_back(i);
6763       else
6764         {
6765           std::ostringstream oss; oss << "DataArrayInt::changeSurjectiveFormat : At pos " << i << " presence of element " << tmp2 << " ! should be in [0," << targetNb << ") !";
6766           throw INTERP_KERNEL::Exception(oss.str().c_str());
6767         }
6768     }
6769   int *retIPtr=retI->getPointer();
6770   *retIPtr=0;
6771   for(std::vector< std::vector<int> >::const_iterator it1=tmp.begin();it1!=tmp.end();it1++,retIPtr++)
6772     retIPtr[1]=retIPtr[0]+(int)((*it1).size());
6773   if(nbOfTuples!=retI->getIJ(targetNb,0))
6774     throw INTERP_KERNEL::Exception("DataArrayInt::changeSurjectiveFormat : big problem should never happen !");
6775   ret->alloc(nbOfTuples,1);
6776   int *retPtr=ret->getPointer();
6777   for(std::vector< std::vector<int> >::const_iterator it1=tmp.begin();it1!=tmp.end();it1++)
6778     retPtr=std::copy((*it1).begin(),(*it1).end(),retPtr);
6779   arr=ret.retn();
6780   arrI=retI.retn();
6781 }
6782
6783
6784 /*!
6785  * Returns a new DataArrayInt containing a renumbering map in "Old to New" mode computed
6786  * from a zip representation of a surjective format (returned e.g. by
6787  * \ref ParaMEDMEM::DataArrayDouble::findCommonTuples() "DataArrayDouble::findCommonTuples()"
6788  * for example). The result array minimizes the permutation. <br>
6789  * For more info on renumbering see \ref MEDCouplingArrayRenumbering. <br>
6790  * \b Example: <br>
6791  * - \a nbOfOldTuples: 10 
6792  * - \a arr          : [0,3, 5,7,9]
6793  * - \a arrIBg       : [0,2,5]
6794  * - \a newNbOfTuples: 7
6795  * - result array    : [0,1,2,0,3,4,5,4,6,4]
6796  *
6797  *  \param [in] nbOfOldTuples - number of tuples in the initial array \a arr.
6798  *  \param [in] arr - the array of tuple indices grouped by \a arrIBg array.
6799  *  \param [in] arrIBg - the array dividing all indices stored in \a arr into groups of
6800  *         (indices of) equal values. Its every element (except the last one) points to
6801  *         the first element of a group of equal values.
6802  *  \param [in] arrIEnd - specifies the end of \a arrIBg, so that the last element of \a
6803  *          arrIBg is \a arrIEnd[ -1 ].
6804  *  \param [out] newNbOfTuples - number of tuples after surjection application.
6805  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
6806  *          array using decrRef() as it is no more needed.
6807  *  \throw If any value of \a arr breaks condition ( 0 <= \a arr[ i ] < \a nbOfOldTuples ).
6808  */
6809 DataArrayInt *DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2(int nbOfOldTuples, const int *arr, const int *arrIBg, const int *arrIEnd, int &newNbOfTuples) throw(INTERP_KERNEL::Exception)
6810 {
6811   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6812   ret->alloc(nbOfOldTuples,1);
6813   int *pt=ret->getPointer();
6814   std::fill(pt,pt+nbOfOldTuples,-1);
6815   int nbOfGrps=((int)std::distance(arrIBg,arrIEnd))-1;
6816   const int *cIPtr=arrIBg;
6817   for(int i=0;i<nbOfGrps;i++)
6818     pt[arr[cIPtr[i]]]=-(i+2);
6819   int newNb=0;
6820   for(int iNode=0;iNode<nbOfOldTuples;iNode++)
6821     {
6822       if(pt[iNode]<0)
6823         {
6824           if(pt[iNode]==-1)
6825             pt[iNode]=newNb++;
6826           else
6827             {
6828               int grpId=-(pt[iNode]+2);
6829               for(int j=cIPtr[grpId];j<cIPtr[grpId+1];j++)
6830                 {
6831                   if(arr[j]>=0 && arr[j]<nbOfOldTuples)
6832                     pt[arr[j]]=newNb;
6833                   else
6834                     {
6835                       std::ostringstream oss; oss << "DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2 : With element #" << j << " value is " << arr[j] << " should be in [0," << nbOfOldTuples << ") !";
6836                       throw INTERP_KERNEL::Exception(oss.str().c_str());
6837                     }
6838                 }
6839               newNb++;
6840             }
6841         }
6842     }
6843   newNbOfTuples=newNb;
6844   return ret.retn();
6845 }
6846
6847 /*!
6848  * Returns a new DataArrayInt containing a renumbering map in "New to Old" mode,
6849  * which if applied to \a this array would make it sorted ascendingly.
6850  * For more info on renumbering see \ref MEDCouplingArrayRenumbering. <br>
6851  * \b Example: <br>
6852  * - \a this: [2,0,1,1,0,1,2,0,1,1,0,0]
6853  * - result: [10,0,5,6,1,7,11,2,8,9,3,4]
6854  * - after applying result to \a this: [0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2] 
6855  *
6856  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
6857  *          array using decrRef() as it is no more needed.
6858  *  \throw If \a this is not allocated.
6859  *  \throw If \a this->getNumberOfComponents() != 1.
6860  */
6861 DataArrayInt *DataArrayInt::buildPermArrPerLevel() const throw(INTERP_KERNEL::Exception)
6862 {
6863   checkAllocated();
6864   if(getNumberOfComponents()!=1)
6865     throw INTERP_KERNEL::Exception("DataArrayInt::buildPermArrPerLevel : number of components must == 1 !");
6866   int nbOfTuples=getNumberOfTuples();
6867   const int *pt=getConstPointer();
6868   std::map<int,int> m;
6869   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6870   ret->alloc(nbOfTuples,1);
6871   int *opt=ret->getPointer();
6872   for(int i=0;i<nbOfTuples;i++,pt++,opt++)
6873     {
6874       int val=*pt;
6875       std::map<int,int>::iterator it=m.find(val);
6876       if(it!=m.end())
6877         {
6878           *opt=(*it).second;
6879           (*it).second++;
6880         }
6881       else
6882         {
6883           *opt=0;
6884           m.insert(std::pair<int,int>(val,1));
6885         }
6886     }
6887   int sum=0;
6888   for(std::map<int,int>::iterator it=m.begin();it!=m.end();it++)
6889     {
6890       int vt=(*it).second;
6891       (*it).second=sum;
6892       sum+=vt;
6893     }
6894   pt=getConstPointer();
6895   opt=ret->getPointer();
6896   for(int i=0;i<nbOfTuples;i++,pt++,opt++)
6897     *opt+=m[*pt];
6898   //
6899   return ret.retn();
6900 }
6901
6902 /*!
6903  * Checks if contents of \a this array are equal to that of an array filled with
6904  * iota(). This method is particularly useful for DataArrayInt instances that represent
6905  * a renumbering array to check the real need in renumbering. 
6906  *  \return bool - \a true if \a this array contents == \a range( \a this->getNumberOfTuples())
6907  *  \throw If \a this is not allocated.
6908  *  \throw If \a this->getNumberOfComponents() != 1.
6909  */
6910 bool DataArrayInt::isIdentity() const throw(INTERP_KERNEL::Exception)
6911 {
6912   checkAllocated();
6913   if(getNumberOfComponents()!=1)
6914     return false;
6915   int nbOfTuples=getNumberOfTuples();
6916   const int *pt=getConstPointer();
6917   for(int i=0;i<nbOfTuples;i++,pt++)
6918     if(*pt!=i)
6919       return false;
6920   return true;
6921 }
6922
6923 /*!
6924  * Checks if all values in \a this array are equal to \a val.
6925  *  \param [in] val - value to check equality of array values to.
6926  *  \return bool - \a true if all values are \a val.
6927  *  \throw If \a this is not allocated.
6928  *  \throw If \a this->getNumberOfComponents() != 1
6929  */
6930 bool DataArrayInt::isUniform(int val) const throw(INTERP_KERNEL::Exception)
6931 {
6932   checkAllocated();
6933   if(getNumberOfComponents()!=1)
6934     throw INTERP_KERNEL::Exception("DataArrayInt::isUniform : must be applied on DataArrayInt with only one component, you can call 'rearrange' method before !");
6935   int nbOfTuples=getNumberOfTuples();
6936   const int *w=getConstPointer();
6937   const int *end2=w+nbOfTuples;
6938   for(;w!=end2;w++)
6939     if(*w!=val)
6940       return false;
6941   return true;
6942 }
6943
6944 /*!
6945  * Creates a new DataArrayDouble and assigns all (textual and numerical) data of \a this
6946  * array to the new one.
6947  *  \return DataArrayDouble * - the new instance of DataArrayInt.
6948  */
6949 DataArrayDouble *DataArrayInt::convertToDblArr() const
6950 {
6951   checkAllocated();
6952   DataArrayDouble *ret=DataArrayDouble::New();
6953   ret->alloc(getNumberOfTuples(),getNumberOfComponents());
6954   std::size_t nbOfVals=getNbOfElems();
6955   const int *src=getConstPointer();
6956   double *dest=ret->getPointer();
6957   std::copy(src,src+nbOfVals,dest);
6958   ret->copyStringInfoFrom(*this);
6959   return ret;
6960 }
6961
6962 /*!
6963  * Returns a shorten copy of \a this array. The new DataArrayInt contains all
6964  * tuples starting from the \a tupleIdBg-th tuple and including all tuples located before
6965  * the \a tupleIdEnd-th one. This methods has a similar behavior as std::string::substr().
6966  * This method is a specialization of selectByTupleId2().
6967  *  \param [in] tupleIdBg - index of the first tuple to copy from \a this array.
6968  *  \param [in] tupleIdEnd - index of the tuple before which the tuples to copy are located.
6969  *          If \a tupleIdEnd == -1, all the tuples till the end of \a this array are copied.
6970  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
6971  *          is to delete using decrRef() as it is no more needed.
6972  *  \throw If \a tupleIdBg < 0.
6973  *  \throw If \a tupleIdBg > \a this->getNumberOfTuples().
6974     \throw If \a tupleIdEnd != -1 && \a tupleIdEnd < \a this->getNumberOfTuples().
6975  *  \sa DataArrayInt::selectByTupleId2
6976  */
6977 DataArrayInt *DataArrayInt::substr(int tupleIdBg, int tupleIdEnd) const throw(INTERP_KERNEL::Exception)
6978 {
6979   checkAllocated();
6980   int nbt=getNumberOfTuples();
6981   if(tupleIdBg<0)
6982     throw INTERP_KERNEL::Exception("DataArrayInt::substr : The tupleIdBg parameter must be greater than 0 !");
6983   if(tupleIdBg>nbt)
6984     throw INTERP_KERNEL::Exception("DataArrayInt::substr : The tupleIdBg parameter is greater than number of tuples !");
6985   int trueEnd=tupleIdEnd;
6986   if(tupleIdEnd!=-1)
6987     {
6988       if(tupleIdEnd>nbt)
6989         throw INTERP_KERNEL::Exception("DataArrayInt::substr : The tupleIdBg parameter is greater or equal than number of tuples !");
6990     }
6991   else
6992     trueEnd=nbt;
6993   int nbComp=getNumberOfComponents();
6994   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6995   ret->alloc(trueEnd-tupleIdBg,nbComp);
6996   ret->copyStringInfoFrom(*this);
6997   std::copy(getConstPointer()+tupleIdBg*nbComp,getConstPointer()+trueEnd*nbComp,ret->getPointer());
6998   return ret.retn();
6999 }
7000
7001 /*!
7002  * Changes the number of components within \a this array so that its raw data **does
7003  * not** change, instead splitting this data into tuples changes.
7004  *  \warning This method erases all (name and unit) component info set before!
7005  *  \param [in] newNbOfComp - number of components for \a this array to have.
7006  *  \throw If \a this is not allocated
7007  *  \throw If getNbOfElems() % \a newNbOfCompo != 0.
7008  *  \throw If \a newNbOfCompo is lower than 1.
7009  *  \throw If the rearrange method would lead to a number of tuples higher than 2147483647 (maximal capacity of int32 !).
7010  *  \warning This method erases all (name and unit) component info set before!
7011  */
7012 void DataArrayInt::rearrange(int newNbOfCompo) throw(INTERP_KERNEL::Exception)
7013 {
7014   checkAllocated();
7015   if(newNbOfCompo<1)
7016     throw INTERP_KERNEL::Exception("DataArrayInt::rearrange : input newNbOfCompo must be > 0 !");
7017   std::size_t nbOfElems=getNbOfElems();
7018   if(nbOfElems%newNbOfCompo!=0)
7019     throw INTERP_KERNEL::Exception("DataArrayInt::rearrange : nbOfElems%newNbOfCompo!=0 !");
7020   if(nbOfElems/newNbOfCompo>(std::size_t)std::numeric_limits<int>::max())
7021     throw INTERP_KERNEL::Exception("DataArrayInt::rearrange : the rearrangement leads to too high number of tuples (> 2147483647) !");
7022   _info_on_compo.clear();
7023   _info_on_compo.resize(newNbOfCompo);
7024   declareAsNew();
7025 }
7026
7027 /*!
7028  * Changes the number of components within \a this array to be equal to its number
7029  * of tuples, and inversely its number of tuples to become equal to its number of 
7030  * components. So that its raw data **does not** change, instead splitting this
7031  * data into tuples changes.
7032  *  \warning This method erases all (name and unit) component info set before!
7033  *  \warning Do not confuse this method with fromNoInterlace() and toNoInterlace()!
7034  *  \throw If \a this is not allocated.
7035  *  \sa rearrange()
7036  */
7037 void DataArrayInt::transpose() throw(INTERP_KERNEL::Exception)
7038 {
7039   checkAllocated();
7040   int nbOfTuples=getNumberOfTuples();
7041   rearrange(nbOfTuples);
7042 }
7043
7044 /*!
7045  * Returns a shorten or extended copy of \a this array. If \a newNbOfComp is less
7046  * than \a this->getNumberOfComponents() then the result array is shorten as each tuple
7047  * is truncated to have \a newNbOfComp components, keeping first components. If \a
7048  * newNbOfComp is more than \a this->getNumberOfComponents() then the result array is
7049  * expanded as each tuple is populated with \a dftValue to have \a newNbOfComp
7050  * components.  
7051  *  \param [in] newNbOfComp - number of components for the new array to have.
7052  *  \param [in] dftValue - value assigned to new values added to the new array.
7053  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
7054  *          is to delete using decrRef() as it is no more needed.
7055  *  \throw If \a this is not allocated.
7056  */
7057 DataArrayInt *DataArrayInt::changeNbOfComponents(int newNbOfComp, int dftValue) const throw(INTERP_KERNEL::Exception)
7058 {
7059   checkAllocated();
7060   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
7061   ret->alloc(getNumberOfTuples(),newNbOfComp);
7062   const int *oldc=getConstPointer();
7063   int *nc=ret->getPointer();
7064   int nbOfTuples=getNumberOfTuples();
7065   int oldNbOfComp=getNumberOfComponents();
7066   int dim=std::min(oldNbOfComp,newNbOfComp);
7067   for(int i=0;i<nbOfTuples;i++)
7068     {
7069       int j=0;
7070       for(;j<dim;j++)
7071         nc[newNbOfComp*i+j]=oldc[i*oldNbOfComp+j];
7072       for(;j<newNbOfComp;j++)
7073         nc[newNbOfComp*i+j]=dftValue;
7074     }
7075   ret->setName(getName().c_str());
7076   for(int i=0;i<dim;i++)
7077     ret->setInfoOnComponent(i,getInfoOnComponent(i).c_str());
7078   ret->setName(getName().c_str());
7079   return ret.retn();
7080 }
7081
7082 /*!
7083  * Changes number of tuples in the array. If the new number of tuples is smaller
7084  * than the current number the array is truncated, otherwise the array is extended.
7085  *  \param [in] nbOfTuples - new number of tuples. 
7086  *  \throw If \a this is not allocated.
7087  */
7088 void DataArrayInt::reAlloc(int nbOfTuples) throw(INTERP_KERNEL::Exception)
7089 {
7090   checkAllocated();
7091   _mem.reAlloc(getNumberOfComponents()*(std::size_t)nbOfTuples);
7092   declareAsNew();
7093 }
7094
7095
7096 /*!
7097  * Returns a copy of \a this array composed of selected components.
7098  * The new DataArrayInt has the same number of tuples but includes components
7099  * specified by \a compoIds parameter. So that getNbOfElems() of the result array
7100  * can be either less, same or more than \a this->getNbOfElems().
7101  *  \param [in] compoIds - sequence of zero based indices of components to include
7102  *              into the new array.
7103  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
7104  *          is to delete using decrRef() as it is no more needed.
7105  *  \throw If \a this is not allocated.
7106  *  \throw If a component index (\a i) is not valid: 
7107  *         \a i < 0 || \a i >= \a this->getNumberOfComponents().
7108  *
7109  *  \ref py_mcdataarrayint_keepselectedcomponents "Here is a Python example".
7110  */
7111 DataArray *DataArrayInt::keepSelectedComponents(const std::vector<int>& compoIds) const throw(INTERP_KERNEL::Exception)
7112 {
7113   checkAllocated();
7114   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New());
7115   int newNbOfCompo=(int)compoIds.size();
7116   int oldNbOfCompo=getNumberOfComponents();
7117   for(std::vector<int>::const_iterator it=compoIds.begin();it!=compoIds.end();it++)
7118     DataArray::CheckValueInRange(oldNbOfCompo,(*it),"keepSelectedComponents invalid requested component");
7119   int nbOfTuples=getNumberOfTuples();
7120   ret->alloc(nbOfTuples,newNbOfCompo);
7121   ret->copyPartOfStringInfoFrom(*this,compoIds);
7122   const int *oldc=getConstPointer();
7123   int *nc=ret->getPointer();
7124   for(int i=0;i<nbOfTuples;i++)
7125     for(int j=0;j<newNbOfCompo;j++,nc++)
7126       *nc=oldc[i*oldNbOfCompo+compoIds[j]];
7127   return ret.retn();
7128 }
7129
7130 /*!
7131  * Appends components of another array to components of \a this one, tuple by tuple.
7132  * So that the number of tuples of \a this array remains the same and the number of 
7133  * components increases.
7134  *  \param [in] other - the DataArrayInt to append to \a this one.
7135  *  \throw If \a this is not allocated.
7136  *  \throw If \a this and \a other arrays have different number of tuples.
7137  *
7138  *  \ref cpp_mcdataarrayint_meldwith "Here is a C++ example".
7139  *
7140  *  \ref py_mcdataarrayint_meldwith "Here is a Python example".
7141  */
7142 void DataArrayInt::meldWith(const DataArrayInt *other) throw(INTERP_KERNEL::Exception)
7143 {
7144   if(!other)
7145     throw INTERP_KERNEL::Exception("DataArrayInt::meldWith : DataArrayInt pointer in input is NULL !");
7146   checkAllocated();
7147   other->checkAllocated();
7148   int nbOfTuples=getNumberOfTuples();
7149   if(nbOfTuples!=other->getNumberOfTuples())
7150     throw INTERP_KERNEL::Exception("DataArrayInt::meldWith : mismatch of number of tuples !");
7151   int nbOfComp1=getNumberOfComponents();
7152   int nbOfComp2=other->getNumberOfComponents();
7153   int *newArr=(int *)malloc(nbOfTuples*(nbOfComp1+nbOfComp2)*sizeof(int));
7154   int *w=newArr;
7155   const int *inp1=getConstPointer();
7156   const int *inp2=other->getConstPointer();
7157   for(int i=0;i<nbOfTuples;i++,inp1+=nbOfComp1,inp2+=nbOfComp2)
7158     {
7159       w=std::copy(inp1,inp1+nbOfComp1,w);
7160       w=std::copy(inp2,inp2+nbOfComp2,w);
7161     }
7162   useArray(newArr,true,C_DEALLOC,nbOfTuples,nbOfComp1+nbOfComp2);
7163   std::vector<int> compIds(nbOfComp2);
7164   for(int i=0;i<nbOfComp2;i++)
7165     compIds[i]=nbOfComp1+i;
7166   copyPartOfStringInfoFrom2(compIds,*other);
7167 }
7168
7169 /*!
7170  * Copy all components in a specified order from another DataArrayInt.
7171  * The specified components become the first ones in \a this array.
7172  * Both numerical and textual data is copied. The number of tuples in \a this and
7173  * the other array can be different.
7174  *  \param [in] a - the array to copy data from.
7175  *  \param [in] compoIds - sequence of zero based indices of components, data of which is
7176  *              to be copied.
7177  *  \throw If \a a is NULL.
7178  *  \throw If \a compoIds.size() != \a a->getNumberOfComponents().
7179  *  \throw If \a compoIds[i] < 0 or \a compoIds[i] > \a this->getNumberOfComponents().
7180  *
7181  *  \ref py_mcdataarrayint_setselectedcomponents "Here is a Python example".
7182  */
7183 void DataArrayInt::setSelectedComponents(const DataArrayInt *a, const std::vector<int>& compoIds) throw(INTERP_KERNEL::Exception)
7184 {
7185   if(!a)
7186     throw INTERP_KERNEL::Exception("DataArrayInt::setSelectedComponents : input DataArrayInt is NULL !");
7187   checkAllocated();
7188   a->checkAllocated();
7189   copyPartOfStringInfoFrom2(compoIds,*a);
7190   std::size_t partOfCompoSz=compoIds.size();
7191   int nbOfCompo=getNumberOfComponents();
7192   int nbOfTuples=std::min(getNumberOfTuples(),a->getNumberOfTuples());
7193   const int *ac=a->getConstPointer();
7194   int *nc=getPointer();
7195   for(int i=0;i<nbOfTuples;i++)
7196     for(std::size_t j=0;j<partOfCompoSz;j++,ac++)
7197       nc[nbOfCompo*i+compoIds[j]]=*ac;
7198 }
7199
7200 /*!
7201  * Copy all values from another DataArrayInt into specified tuples and components
7202  * of \a this array. Textual data is not copied.
7203  * The tree parameters defining set of indices of tuples and components are similar to
7204  * the tree parameters of the Python function \c range(\c start,\c stop,\c step).
7205  *  \param [in] a - the array to copy values from.
7206  *  \param [in] bgTuples - index of the first tuple of \a this array to assign values to.
7207  *  \param [in] endTuples - index of the tuple before which the tuples to assign to
7208  *              are located.
7209  *  \param [in] stepTuples - index increment to get index of the next tuple to assign to.
7210  *  \param [in] bgComp - index of the first component of \a this array to assign values to.
7211  *  \param [in] endComp - index of the component before which the components to assign
7212  *              to are located.
7213  *  \param [in] stepComp - index increment to get index of the next component to assign to.
7214  *  \param [in] strictCompoCompare - if \a true (by default), then \a a->getNumberOfComponents() 
7215  *              must be equal to the number of columns to assign to, else an
7216  *              exception is thrown; if \a false, then it is only required that \a
7217  *              a->getNbOfElems() equals to number of values to assign to (this condition
7218  *              must be respected even if \a strictCompoCompare is \a true). The number of 
7219  *              values to assign to is given by following Python expression:
7220  *              \a nbTargetValues = 
7221  *              \c len(\c range(\a bgTuples,\a endTuples,\a stepTuples)) *
7222  *              \c len(\c range(\a bgComp,\a endComp,\a stepComp)).
7223  *  \throw If \a a is NULL.
7224  *  \throw If \a a is not allocated.
7225  *  \throw If \a this is not allocated.
7226  *  \throw If parameters specifying tuples and components to assign to do not give a
7227  *            non-empty range of increasing indices.
7228  *  \throw If \a a->getNbOfElems() != \a nbTargetValues.
7229  *  \throw If \a strictCompoCompare == \a true && \a a->getNumberOfComponents() !=
7230  *            \c len(\c range(\a bgComp,\a endComp,\a stepComp)).
7231  *
7232  *  \ref py_mcdataarrayint_setpartofvalues1 "Here is a Python example".
7233  */
7234 void DataArrayInt::setPartOfValues1(const DataArrayInt *a, int bgTuples, int endTuples, int stepTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare) throw(INTERP_KERNEL::Exception)
7235 {
7236   if(!a)
7237     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValues1 : DataArrayInt pointer in input is NULL !");
7238   const char msg[]="DataArrayInt::setPartOfValues1";
7239   checkAllocated();
7240   a->checkAllocated();
7241   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
7242   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
7243   int nbComp=getNumberOfComponents();
7244   int nbOfTuples=getNumberOfTuples();
7245   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
7246   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
7247   bool assignTech=true;
7248   if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
7249     {
7250       if(strictCompoCompare)
7251         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
7252     }
7253   else
7254     {
7255       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
7256       assignTech=false;
7257     }
7258   int *pt=getPointer()+bgTuples*nbComp+bgComp;
7259   const int *srcPt=a->getConstPointer();
7260   if(assignTech)
7261     {
7262       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
7263         for(int j=0;j<newNbOfComp;j++,srcPt++)
7264           pt[j*stepComp]=*srcPt;
7265     }
7266   else
7267     {
7268       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
7269         {
7270           const int *srcPt2=srcPt;
7271           for(int j=0;j<newNbOfComp;j++,srcPt2++)
7272             pt[j*stepComp]=*srcPt2;
7273         }
7274     }
7275 }
7276
7277 /*!
7278  * Assign a given value to values at specified tuples and components of \a this array.
7279  * The tree parameters defining set of indices of tuples and components are similar to
7280  * the tree parameters of the Python function \c range(\c start,\c stop,\c step)..
7281  *  \param [in] a - the value to assign.
7282  *  \param [in] bgTuples - index of the first tuple of \a this array to assign to.
7283  *  \param [in] endTuples - index of the tuple before which the tuples to assign to
7284  *              are located.
7285  *  \param [in] stepTuples - index increment to get index of the next tuple to assign to.
7286  *  \param [in] bgComp - index of the first component of \a this array to assign to.
7287  *  \param [in] endComp - index of the component before which the components to assign
7288  *              to are located.
7289  *  \param [in] stepComp - index increment to get index of the next component to assign to.
7290  *  \throw If \a this is not allocated.
7291  *  \throw If parameters specifying tuples and components to assign to, do not give a
7292  *            non-empty range of increasing indices or indices are out of a valid range
7293  *            for \this array.
7294  *
7295  *  \ref py_mcdataarrayint_setpartofvaluessimple1 "Here is a Python example".
7296  */
7297 void DataArrayInt::setPartOfValuesSimple1(int a, int bgTuples, int endTuples, int stepTuples, int bgComp, int endComp, int stepComp) throw(INTERP_KERNEL::Exception)
7298 {
7299   const char msg[]="DataArrayInt::setPartOfValuesSimple1";
7300   checkAllocated();
7301   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
7302   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
7303   int nbComp=getNumberOfComponents();
7304   int nbOfTuples=getNumberOfTuples();
7305   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
7306   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
7307   int *pt=getPointer()+bgTuples*nbComp+bgComp;
7308   for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
7309     for(int j=0;j<newNbOfComp;j++)
7310       pt[j*stepComp]=a;
7311 }
7312
7313
7314 /*!
7315  * Copy all values from another DataArrayInt (\a a) into specified tuples and 
7316  * components of \a this array. Textual data is not copied.
7317  * The tuples and components to assign to are defined by C arrays of indices.
7318  * There are two *modes of usage*:
7319  * - If \a a->getNbOfElems() equals to number of values to assign to, then every value
7320  *   of \a a is assigned to its own location within \a this array. 
7321  * - If \a a includes one tuple, then all values of \a a are assigned to the specified
7322  *   components of every specified tuple of \a this array. In this mode it is required
7323  *   that \a a->getNumberOfComponents() equals to the number of specified components.
7324  * 
7325  *  \param [in] a - the array to copy values from.
7326  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
7327  *              assign values of \a a to.
7328  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
7329  *              pointer to a tuple index <em>(pi)</em> varies as this: 
7330  *              \a bgTuples <= \a pi < \a endTuples.
7331  *  \param [in] bgComp - pointer to an array of component indices of \a this array to
7332  *              assign values of \a a to.
7333  *  \param [in] endComp - specifies the end of the array \a bgTuples, so that
7334  *              pointer to a component index <em>(pi)</em> varies as this: 
7335  *              \a bgComp <= \a pi < \a endComp.
7336  *  \param [in] strictCompoCompare - this parameter is checked only if the
7337  *               *mode of usage* is the first; if it is \a true (default), 
7338  *               then \a a->getNumberOfComponents() must be equal 
7339  *               to the number of specified columns, else this is not required.
7340  *  \throw If \a a is NULL.
7341  *  \throw If \a a is not allocated.
7342  *  \throw If \a this is not allocated.
7343  *  \throw If any index of tuple/component given by <em>bgTuples / bgComp</em> is
7344  *         out of a valid range for \a this array.
7345  *  \throw In the first *mode of usage*, if <em>strictCompoCompare == true </em> and
7346  *         if <em> a->getNumberOfComponents() != (endComp - bgComp) </em>.
7347  *  \throw In the second *mode of usage*, if \a a->getNumberOfTuples() != 1 or
7348  *         <em> a->getNumberOfComponents() != (endComp - bgComp)</em>.
7349  *
7350  *  \ref py_mcdataarrayint_setpartofvalues2 "Here is a Python example".
7351  */
7352 void DataArrayInt::setPartOfValues2(const DataArrayInt *a, const int *bgTuples, const int *endTuples, const int *bgComp, const int *endComp, bool strictCompoCompare) throw(INTERP_KERNEL::Exception)
7353 {
7354   if(!a)
7355     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValues2 : DataArrayInt pointer in input is NULL !");
7356   const char msg[]="DataArrayInt::setPartOfValues2";
7357   checkAllocated();
7358   a->checkAllocated();
7359   int nbComp=getNumberOfComponents();
7360   int nbOfTuples=getNumberOfTuples();
7361   for(const int *z=bgComp;z!=endComp;z++)
7362     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
7363   int newNbOfTuples=(int)std::distance(bgTuples,endTuples);
7364   int newNbOfComp=(int)std::distance(bgComp,endComp);
7365   bool assignTech=true;
7366   if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
7367     {
7368       if(strictCompoCompare)
7369         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
7370     }
7371   else
7372     {
7373       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
7374       assignTech=false;
7375     }
7376   int *pt=getPointer();
7377   const int *srcPt=a->getConstPointer();
7378   if(assignTech)
7379     {    
7380       for(const int *w=bgTuples;w!=endTuples;w++)
7381         {
7382           DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
7383           for(const int *z=bgComp;z!=endComp;z++,srcPt++)
7384             {    
7385               pt[(std::size_t)(*w)*nbComp+(*z)]=*srcPt;
7386             }
7387         }
7388     }
7389   else
7390     {
7391       for(const int *w=bgTuples;w!=endTuples;w++)
7392         {
7393           const int *srcPt2=srcPt;
7394           DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
7395           for(const int *z=bgComp;z!=endComp;z++,srcPt2++)
7396             {    
7397               pt[(std::size_t)(*w)*nbComp+(*z)]=*srcPt2;
7398             }
7399         }
7400     }
7401 }
7402
7403 /*!
7404  * Assign a given value to values at specified tuples and components of \a this array.
7405  * The tuples and components to assign to are defined by C arrays of indices.
7406  *  \param [in] a - the value to assign.
7407  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
7408  *              assign \a a to.
7409  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
7410  *              pointer to a tuple index (\a pi) varies as this: 
7411  *              \a bgTuples <= \a pi < \a endTuples.
7412  *  \param [in] bgComp - pointer to an array of component indices of \a this array to
7413  *              assign \a a to.
7414  *  \param [in] endComp - specifies the end of the array \a bgTuples, so that
7415  *              pointer to a component index (\a pi) varies as this: 
7416  *              \a bgComp <= \a pi < \a endComp.
7417  *  \throw If \a this is not allocated.
7418  *  \throw If any index of tuple/component given by <em>bgTuples / bgComp</em> is
7419  *         out of a valid range for \a this array.
7420  *
7421  *  \ref py_mcdataarrayint_setpartofvaluessimple2 "Here is a Python example".
7422  */
7423 void DataArrayInt::setPartOfValuesSimple2(int a, const int *bgTuples, const int *endTuples, const int *bgComp, const int *endComp) throw(INTERP_KERNEL::Exception)
7424 {
7425   checkAllocated();
7426   int nbComp=getNumberOfComponents();
7427   int nbOfTuples=getNumberOfTuples();
7428   for(const int *z=bgComp;z!=endComp;z++)
7429     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
7430   int *pt=getPointer();
7431   for(const int *w=bgTuples;w!=endTuples;w++)
7432     for(const int *z=bgComp;z!=endComp;z++)
7433       {
7434         DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
7435         pt[(std::size_t)(*w)*nbComp+(*z)]=a;
7436       }
7437 }
7438
7439 /*!
7440  * Copy all values from another DataArrayInt (\a a) into specified tuples and 
7441  * components of \a this array. Textual data is not copied.
7442  * The tuples to assign to are defined by a C array of indices.
7443  * The components to assign to are defined by three values similar to parameters of
7444  * the Python function \c range(\c start,\c stop,\c step).
7445  * There are two *modes of usage*:
7446  * - If \a a->getNbOfElems() equals to number of values to assign to, then every value
7447  *   of \a a is assigned to its own location within \a this array. 
7448  * - If \a a includes one tuple, then all values of \a a are assigned to the specified
7449  *   components of every specified tuple of \a this array. In this mode it is required
7450  *   that \a a->getNumberOfComponents() equals to the number of specified components.
7451  *
7452  *  \param [in] a - the array to copy values from.
7453  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
7454  *              assign values of \a a to.
7455  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
7456  *              pointer to a tuple index <em>(pi)</em> varies as this: 
7457  *              \a bgTuples <= \a pi < \a endTuples.
7458  *  \param [in] bgComp - index of the first component of \a this array to assign to.
7459  *  \param [in] endComp - index of the component before which the components to assign
7460  *              to are located.
7461  *  \param [in] stepComp - index increment to get index of the next component to assign to.
7462  *  \param [in] strictCompoCompare - this parameter is checked only in the first
7463  *               *mode of usage*; if \a strictCompoCompare is \a true (default), 
7464  *               then \a a->getNumberOfComponents() must be equal 
7465  *               to the number of specified columns, else this is not required.
7466  *  \throw If \a a is NULL.
7467  *  \throw If \a a is not allocated.
7468  *  \throw If \a this is not allocated.
7469  *  \throw If any index of tuple given by \a bgTuples is out of a valid range for 
7470  *         \a this array.
7471  *  \throw In the first *mode of usage*, if <em>strictCompoCompare == true </em> and
7472  *         if <em> a->getNumberOfComponents()</em> is unequal to the number of components
7473  *         defined by <em>(bgComp,endComp,stepComp)</em>.
7474  *  \throw In the second *mode of usage*, if \a a->getNumberOfTuples() != 1 or
7475  *         <em> a->getNumberOfComponents()</em> is unequal to the number of components
7476  *         defined by <em>(bgComp,endComp,stepComp)</em>.
7477  *  \throw If parameters specifying components to assign to, do not give a
7478  *            non-empty range of increasing indices or indices are out of a valid range
7479  *            for \this array.
7480  *
7481  *  \ref py_mcdataarrayint_setpartofvalues3 "Here is a Python example".
7482  */
7483 void DataArrayInt::setPartOfValues3(const DataArrayInt *a, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare) throw(INTERP_KERNEL::Exception)
7484 {
7485   if(!a)
7486     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValues3 : DataArrayInt pointer in input is NULL !");
7487   const char msg[]="DataArrayInt::setPartOfValues3";
7488   checkAllocated();
7489   a->checkAllocated();
7490   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
7491   int nbComp=getNumberOfComponents();
7492   int nbOfTuples=getNumberOfTuples();
7493   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
7494   int newNbOfTuples=(int)std::distance(bgTuples,endTuples);
7495   bool assignTech=true;
7496   if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
7497     {
7498       if(strictCompoCompare)
7499         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
7500     }
7501   else
7502     {
7503       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
7504       assignTech=false;
7505     }
7506   int *pt=getPointer()+bgComp;
7507   const int *srcPt=a->getConstPointer();
7508   if(assignTech)
7509     {
7510       for(const int *w=bgTuples;w!=endTuples;w++)
7511         for(int j=0;j<newNbOfComp;j++,srcPt++)
7512           {
7513             DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
7514             pt[(std::size_t)(*w)*nbComp+j*stepComp]=*srcPt;
7515           }
7516     }
7517   else
7518     {
7519       for(const int *w=bgTuples;w!=endTuples;w++)
7520         {
7521           const int *srcPt2=srcPt;
7522           for(int j=0;j<newNbOfComp;j++,srcPt2++)
7523             {
7524               DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
7525               pt[(std::size_t)(*w)*nbComp+j*stepComp]=*srcPt2;
7526             }
7527         }
7528     }
7529 }
7530
7531 /*!
7532  * Assign a given value to values at specified tuples and components of \a this array.
7533  * The tuples to assign to are defined by a C array of indices.
7534  * The components to assign to are defined by three values similar to parameters of
7535  * the Python function \c range(\c start,\c stop,\c step).
7536  *  \param [in] a - the value to assign.
7537  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
7538  *              assign \a a to.
7539  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
7540  *              pointer to a tuple index <em>(pi)</em> varies as this: 
7541  *              \a bgTuples <= \a pi < \a endTuples.
7542  *  \param [in] bgComp - index of the first component of \a this array to assign to.
7543  *  \param [in] endComp - index of the component before which the components to assign
7544  *              to are located.
7545  *  \param [in] stepComp - index increment to get index of the next component to assign to.
7546  *  \throw If \a this is not allocated.
7547  *  \throw If any index of tuple given by \a bgTuples is out of a valid range for 
7548  *         \a this array.
7549  *  \throw If parameters specifying components to assign to, do not give a
7550  *            non-empty range of increasing indices or indices are out of a valid range
7551  *            for \this array.
7552  *
7553  *  \ref py_mcdataarrayint_setpartofvaluessimple3 "Here is a Python example".
7554  */
7555 void DataArrayInt::setPartOfValuesSimple3(int a, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp) throw(INTERP_KERNEL::Exception)
7556 {
7557   const char msg[]="DataArrayInt::setPartOfValuesSimple3";
7558   checkAllocated();
7559   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
7560   int nbComp=getNumberOfComponents();
7561   int nbOfTuples=getNumberOfTuples();
7562   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
7563   int *pt=getPointer()+bgComp;
7564   for(const int *w=bgTuples;w!=endTuples;w++)
7565     for(int j=0;j<newNbOfComp;j++)
7566       {
7567         DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
7568         pt[(std::size_t)(*w)*nbComp+j*stepComp]=a;
7569       }
7570 }
7571
7572 void DataArrayInt::setPartOfValues4(const DataArrayInt *a, int bgTuples, int endTuples, int stepTuples, const int *bgComp, const int *endComp, bool strictCompoCompare) throw(INTERP_KERNEL::Exception)
7573 {
7574   if(!a)
7575     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValues4 : input DataArrayInt is NULL !");
7576   const char msg[]="DataArrayInt::setPartOfValues4";
7577   checkAllocated();
7578   a->checkAllocated();
7579   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
7580   int newNbOfComp=(int)std::distance(bgComp,endComp);
7581   int nbComp=getNumberOfComponents();
7582   for(const int *z=bgComp;z!=endComp;z++)
7583     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
7584   int nbOfTuples=getNumberOfTuples();
7585   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
7586   bool assignTech=true;
7587   if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
7588     {
7589       if(strictCompoCompare)
7590         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
7591     }
7592   else
7593     {
7594       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
7595       assignTech=false;
7596     }
7597   const int *srcPt=a->getConstPointer();
7598   int *pt=getPointer()+bgTuples*nbComp;
7599   if(assignTech)
7600     {
7601       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
7602         for(const int *z=bgComp;z!=endComp;z++,srcPt++)
7603           pt[*z]=*srcPt;
7604     }
7605   else
7606     {
7607       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
7608         {
7609           const int *srcPt2=srcPt;
7610           for(const int *z=bgComp;z!=endComp;z++,srcPt2++)
7611             pt[*z]=*srcPt2;
7612         }
7613     }
7614 }
7615
7616 void DataArrayInt::setPartOfValuesSimple4(int a, int bgTuples, int endTuples, int stepTuples, const int *bgComp, const int *endComp) throw(INTERP_KERNEL::Exception)
7617 {
7618   const char msg[]="DataArrayInt::setPartOfValuesSimple4";
7619   checkAllocated();
7620   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
7621   int nbComp=getNumberOfComponents();
7622   for(const int *z=bgComp;z!=endComp;z++)
7623     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
7624   int nbOfTuples=getNumberOfTuples();
7625   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
7626   int *pt=getPointer()+bgTuples*nbComp;
7627   for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
7628     for(const int *z=bgComp;z!=endComp;z++)
7629       pt[*z]=a;
7630 }
7631
7632 /*!
7633  * Copy some tuples from another DataArrayInt into specified tuples
7634  * of \a this array. Textual data is not copied. Both arrays must have equal number of
7635  * components.
7636  * Both the tuples to assign and the tuples to assign to are defined by a DataArrayInt.
7637  * All components of selected tuples are copied.
7638  *  \param [in] a - the array to copy values from.
7639  *  \param [in] tuplesSelec - the array specifying both source tuples of \a a and
7640  *              target tuples of \a this. \a tuplesSelec has two components, and the
7641  *              first component specifies index of the source tuple and the second
7642  *              one specifies index of the target tuple.
7643  *  \throw If \a this is not allocated.
7644  *  \throw If \a a is NULL.
7645  *  \throw If \a a is not allocated.
7646  *  \throw If \a tuplesSelec is NULL.
7647  *  \throw If \a tuplesSelec is not allocated.
7648  *  \throw If <em>this->getNumberOfComponents() != a->getNumberOfComponents()</em>.
7649  *  \throw If \a tuplesSelec->getNumberOfComponents() != 2.
7650  *  \throw If any tuple index given by \a tuplesSelec is out of a valid range for 
7651  *         the corresponding (\a this or \a a) array.
7652  */
7653 void DataArrayInt::setPartOfValuesAdv(const DataArrayInt *a, const DataArrayInt *tuplesSelec) throw(INTERP_KERNEL::Exception)
7654 {
7655   if(!a || !tuplesSelec)
7656     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValuesAdv : DataArrayInt pointer in input is NULL !");
7657   checkAllocated();
7658   a->checkAllocated();
7659   tuplesSelec->checkAllocated();
7660   int nbOfComp=getNumberOfComponents();
7661   if(nbOfComp!=a->getNumberOfComponents())
7662     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValuesAdv : This and a do not have the same number of components !");
7663   if(tuplesSelec->getNumberOfComponents()!=2)
7664     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValuesAdv : Expecting to have a tuple selector DataArrayInt instance with exactly 2 components !");
7665   int thisNt=getNumberOfTuples();
7666   int aNt=a->getNumberOfTuples();
7667   int *valsToSet=getPointer();
7668   const int *valsSrc=a->getConstPointer();
7669   for(const int *tuple=tuplesSelec->begin();tuple!=tuplesSelec->end();tuple+=2)
7670     {
7671       if(tuple[1]>=0 && tuple[1]<aNt)
7672         {
7673           if(tuple[0]>=0 && tuple[0]<thisNt)
7674             std::copy(valsSrc+nbOfComp*tuple[1],valsSrc+nbOfComp*(tuple[1]+1),valsToSet+nbOfComp*tuple[0]);
7675           else
7676             {
7677               std::ostringstream oss; oss << "DataArrayInt::setPartOfValuesAdv : Tuple #" << std::distance(tuplesSelec->begin(),tuple)/2;
7678               oss << " of 'tuplesSelec' request of tuple id #" << tuple[0] << " in 'this' ! It should be in [0," << thisNt << ") !";
7679               throw INTERP_KERNEL::Exception(oss.str().c_str());
7680             }
7681         }
7682       else
7683         {
7684           std::ostringstream oss; oss << "DataArrayInt::setPartOfValuesAdv : Tuple #" << std::distance(tuplesSelec->begin(),tuple)/2;
7685           oss << " of 'tuplesSelec' request of tuple id #" << tuple[1] << " in 'a' ! It should be in [0," << aNt << ") !";
7686           throw INTERP_KERNEL::Exception(oss.str().c_str());
7687         }
7688     }
7689 }
7690
7691 /*!
7692  * Copy some tuples from another DataArrayInt (\a a) into contiguous tuples
7693  * of \a this array. Textual data is not copied. Both arrays must have equal number of
7694  * components.
7695  * The tuples to assign to are defined by index of the first tuple, and
7696  * their number is defined by \a tuplesSelec->getNumberOfTuples().
7697  * The tuples to copy are defined by values of a DataArrayInt.
7698  * All components of selected tuples are copied.
7699  *  \param [in] tupleIdStart - index of the first tuple of \a this array to assign
7700  *              values to.
7701  *  \param [in] a - the array to copy values from.
7702  *  \param [in] tuplesSelec - the array specifying tuples of \a a to copy.
7703  *  \throw If \a this is not allocated.
7704  *  \throw If \a a is NULL.
7705  *  \throw If \a a is not allocated.
7706  *  \throw If \a tuplesSelec is NULL.
7707  *  \throw If \a tuplesSelec is not allocated.
7708  *  \throw If <em>this->getNumberOfComponents() != a->getNumberOfComponents()</em>.
7709  *  \throw If \a tuplesSelec->getNumberOfComponents() != 1.
7710  *  \throw If <em>tupleIdStart + tuplesSelec->getNumberOfTuples() > this->getNumberOfTuples().</em>
7711  *  \throw If any tuple index given by \a tuplesSelec is out of a valid range for 
7712  *         \a a array.
7713  */
7714 void DataArrayInt::setContigPartOfSelectedValues(int tupleIdStart, const DataArray *aBase, const DataArrayInt *tuplesSelec) throw(INTERP_KERNEL::Exception)
7715 {
7716   if(!aBase || !tuplesSelec)
7717     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues : input DataArray is NULL !");
7718   const DataArrayInt *a=dynamic_cast<const DataArrayInt *>(aBase);
7719   if(!a)
7720     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues : input DataArray aBase is not a DataArrayInt !");
7721   checkAllocated();
7722   a->checkAllocated();
7723   tuplesSelec->checkAllocated();
7724   int nbOfComp=getNumberOfComponents();
7725   if(nbOfComp!=a->getNumberOfComponents())
7726     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues : This and a do not have the same number of components !");
7727   if(tuplesSelec->getNumberOfComponents()!=1)
7728     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues : Expecting to have a tuple selector DataArrayInt instance with exactly 1 component !");
7729   int thisNt=getNumberOfTuples();
7730   int aNt=a->getNumberOfTuples();
7731   int nbOfTupleToWrite=tuplesSelec->getNumberOfTuples();
7732   int *valsToSet=getPointer()+tupleIdStart*nbOfComp;
7733   if(tupleIdStart+nbOfTupleToWrite>thisNt)
7734     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues : invalid number range of values to write !");
7735   const int *valsSrc=a->getConstPointer();
7736   for(const int *tuple=tuplesSelec->begin();tuple!=tuplesSelec->end();tuple++,valsToSet+=nbOfComp)
7737     {
7738       if(*tuple>=0 && *tuple<aNt)
7739         {
7740           std::copy(valsSrc+nbOfComp*(*tuple),valsSrc+nbOfComp*(*tuple+1),valsToSet);
7741         }
7742       else
7743         {
7744           std::ostringstream oss; oss << "DataArrayInt::setContigPartOfSelectedValues : Tuple #" << std::distance(tuplesSelec->begin(),tuple);
7745           oss << " of 'tuplesSelec' request of tuple id #" << *tuple << " in 'a' ! It should be in [0," << aNt << ") !";
7746           throw INTERP_KERNEL::Exception(oss.str().c_str());
7747         }
7748     }
7749 }
7750
7751 /*!
7752  * Copy some tuples from another DataArrayInt (\a a) into contiguous tuples
7753  * of \a this array. Textual data is not copied. Both arrays must have equal number of
7754  * components.
7755  * The tuples to copy are defined by three values similar to parameters of
7756  * the Python function \c range(\c start,\c stop,\c step).
7757  * The tuples to assign to are defined by index of the first tuple, and
7758  * their number is defined by number of tuples to copy.
7759  * All components of selected tuples are copied.
7760  *  \param [in] tupleIdStart - index of the first tuple of \a this array to assign
7761  *              values to.
7762  *  \param [in] a - the array to copy values from.
7763  *  \param [in] bg - index of the first tuple to copy of the array \a a.
7764  *  \param [in] end2 - index of the tuple of \a a before which the tuples to copy
7765  *              are located.
7766  *  \param [in] step - index increment to get index of the next tuple to copy.
7767  *  \throw If \a this is not allocated.
7768  *  \throw If \a a is NULL.
7769  *  \throw If \a a is not allocated.
7770  *  \throw If <em>this->getNumberOfComponents() != a->getNumberOfComponents()</em>.
7771  *  \throw If <em>tupleIdStart + len(range(bg,end2,step)) > this->getNumberOfTuples().</em>
7772  *  \throw If parameters specifying tuples to copy, do not give a
7773  *            non-empty range of increasing indices or indices are out of a valid range
7774  *            for the array \a a.
7775  */
7776 void DataArrayInt::setContigPartOfSelectedValues2(int tupleIdStart, const DataArray *aBase, int bg, int end2, int step) throw(INTERP_KERNEL::Exception)
7777 {
7778   if(!aBase)
7779     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues2 : input DataArray is NULL !");
7780   const DataArrayInt *a=dynamic_cast<const DataArrayInt *>(aBase);
7781   if(!a)
7782     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues2 : input DataArray aBase is not a DataArrayInt !");
7783   checkAllocated();
7784   a->checkAllocated();
7785   int nbOfComp=getNumberOfComponents();
7786   const char msg[]="DataArrayInt::setContigPartOfSelectedValues2";
7787   int nbOfTupleToWrite=DataArray::GetNumberOfItemGivenBES(bg,end2,step,msg);
7788   if(nbOfComp!=a->getNumberOfComponents())
7789     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues2 : This and a do not have the same number of components !");
7790   int thisNt=getNumberOfTuples();
7791   int aNt=a->getNumberOfTuples();
7792   int *valsToSet=getPointer()+tupleIdStart*nbOfComp;
7793   if(tupleIdStart+nbOfTupleToWrite>thisNt)
7794     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues2 : invalid number range of values to write !");
7795   if(end2>aNt)
7796     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues2 : invalid range of values to read !");
7797   const int *valsSrc=a->getConstPointer()+bg*nbOfComp;
7798   for(int i=0;i<nbOfTupleToWrite;i++,valsToSet+=nbOfComp,valsSrc+=step*nbOfComp)
7799     {
7800       std::copy(valsSrc,valsSrc+nbOfComp,valsToSet);
7801     }
7802 }
7803
7804 /*!
7805  * Returns a value located at specified tuple and component.
7806  * This method is equivalent to DataArrayInt::getIJ() except that validity of
7807  * parameters is checked. So this method is safe but expensive if used to go through
7808  * all values of \a this.
7809  *  \param [in] tupleId - index of tuple of interest.
7810  *  \param [in] compoId - index of component of interest.
7811  *  \return double - value located by \a tupleId and \a compoId.
7812  *  \throw If \a this is not allocated.
7813  *  \throw If condition <em>( 0 <= tupleId < this->getNumberOfTuples() )</em> is violated.
7814  *  \throw If condition <em>( 0 <= compoId < this->getNumberOfComponents() )</em> is violated.
7815  */
7816 int DataArrayInt::getIJSafe(int tupleId, int compoId) const throw(INTERP_KERNEL::Exception)
7817 {
7818   checkAllocated();
7819   if(tupleId<0 || tupleId>=getNumberOfTuples())
7820     {
7821       std::ostringstream oss; oss << "DataArrayInt::getIJSafe : request for tupleId " << tupleId << " should be in [0," << getNumberOfTuples() << ") !";
7822       throw INTERP_KERNEL::Exception(oss.str().c_str());
7823     }
7824   if(compoId<0 || compoId>=getNumberOfComponents())
7825     {
7826       std::ostringstream oss; oss << "DataArrayInt::getIJSafe : request for compoId " << compoId << " should be in [0," << getNumberOfComponents() << ") !";
7827       throw INTERP_KERNEL::Exception(oss.str().c_str());
7828     }
7829   return _mem[tupleId*_info_on_compo.size()+compoId];
7830 }
7831
7832 /*!
7833  * Returns the first value of \a this. 
7834  *  \return int - the last value of \a this array.
7835  *  \throw If \a this is not allocated.
7836  *  \throw If \a this->getNumberOfComponents() != 1.
7837  *  \throw If \a this->getNumberOfTuples() < 1.
7838  */
7839 int DataArrayInt::front() const throw(INTERP_KERNEL::Exception)
7840 {
7841   checkAllocated();
7842   if(getNumberOfComponents()!=1)
7843     throw INTERP_KERNEL::Exception("DataArrayInt::front : number of components not equal to one !");
7844   int nbOfTuples=getNumberOfTuples();
7845   if(nbOfTuples<1)
7846     throw INTERP_KERNEL::Exception("DataArrayInt::front : number of tuples must be >= 1 !");
7847   return *(getConstPointer());
7848 }
7849
7850 /*!
7851  * Returns the last value of \a this. 
7852  *  \return int - the last value of \a this array.
7853  *  \throw If \a this is not allocated.
7854  *  \throw If \a this->getNumberOfComponents() != 1.
7855  *  \throw If \a this->getNumberOfTuples() < 1.
7856  */
7857 int DataArrayInt::back() const throw(INTERP_KERNEL::Exception)
7858 {
7859   checkAllocated();
7860   if(getNumberOfComponents()!=1)
7861     throw INTERP_KERNEL::Exception("DataArrayInt::back : number of components not equal to one !");
7862   int nbOfTuples=getNumberOfTuples();
7863   if(nbOfTuples<1)
7864     throw INTERP_KERNEL::Exception("DataArrayInt::back : number of tuples must be >= 1 !");
7865   return *(getConstPointer()+nbOfTuples-1);
7866 }
7867
7868 /*!
7869  * Assign pointer to one array to a pointer to another appay. Reference counter of
7870  * \a arrayToSet is incremented / decremented.
7871  *  \param [in] newArray - the pointer to array to assign to \a arrayToSet.
7872  *  \param [in,out] arrayToSet - the pointer to array to assign to.
7873  */
7874 void DataArrayInt::SetArrayIn(DataArrayInt *newArray, DataArrayInt* &arrayToSet)
7875 {
7876   if(newArray!=arrayToSet)
7877     {
7878       if(arrayToSet)
7879         arrayToSet->decrRef();
7880       arrayToSet=newArray;
7881       if(arrayToSet)
7882         arrayToSet->incrRef();
7883     }
7884 }
7885
7886 DataArrayIntIterator *DataArrayInt::iterator() throw(INTERP_KERNEL::Exception)
7887 {
7888   return new DataArrayIntIterator(this);
7889 }
7890
7891 /*!
7892  * Creates a new DataArrayInt containing IDs (indices) of tuples holding value equal to a
7893  * given one.
7894  *  \param [in] val - the value to find within \a this.
7895  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
7896  *          array using decrRef() as it is no more needed.
7897  *  \throw If \a this is not allocated.
7898  *  \throw If \a this->getNumberOfComponents() != 1.
7899  */
7900 DataArrayInt *DataArrayInt::getIdsEqual(int val) const throw(INTERP_KERNEL::Exception)
7901 {
7902   checkAllocated();
7903   if(getNumberOfComponents()!=1)
7904     throw INTERP_KERNEL::Exception("DataArrayInt::getIdsEqual : the array must have only one component, you can call 'rearrange' method before !");
7905   const int *cptr=getConstPointer();
7906   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
7907   int nbOfTuples=getNumberOfTuples();
7908   for(int i=0;i<nbOfTuples;i++,cptr++)
7909     if(*cptr==val)
7910       ret->pushBackSilent(i);
7911   return ret.retn();
7912 }
7913
7914 /*!
7915  * Creates a new DataArrayInt containing IDs (indices) of tuples holding value \b not
7916  * equal to a given one. 
7917  *  \param [in] val - the value to ignore within \a this.
7918  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
7919  *          array using decrRef() as it is no more needed.
7920  *  \throw If \a this is not allocated.
7921  *  \throw If \a this->getNumberOfComponents() != 1.
7922  */
7923 DataArrayInt *DataArrayInt::getIdsNotEqual(int val) const throw(INTERP_KERNEL::Exception)
7924 {
7925   checkAllocated();
7926   if(getNumberOfComponents()!=1)
7927     throw INTERP_KERNEL::Exception("DataArrayInt::getIdsNotEqual : the array must have only one component, you can call 'rearrange' method before !");
7928   const int *cptr=getConstPointer();
7929   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
7930   int nbOfTuples=getNumberOfTuples();
7931   for(int i=0;i<nbOfTuples;i++,cptr++)
7932     if(*cptr!=val)
7933       ret->pushBackSilent(i);
7934   return ret.retn();
7935 }
7936
7937
7938 /*!
7939  * Assigns \a newValue to all elements holding \a oldValue within \a this
7940  * one-dimensional array.
7941  *  \param [in] oldValue - the value to replace.
7942  *  \param [in] newValue - the value to assign.
7943  *  \return int - number of replacements performed.
7944  *  \throw If \a this is not allocated.
7945  *  \throw If \a this->getNumberOfComponents() != 1.
7946  */
7947 int DataArrayInt::changeValue(int oldValue, int newValue) throw(INTERP_KERNEL::Exception)
7948 {
7949   checkAllocated();
7950   if(getNumberOfComponents()!=1)
7951     throw INTERP_KERNEL::Exception("DataArrayInt::changeValue : the array must have only one component, you can call 'rearrange' method before !");
7952   int *start=getPointer();
7953   int *end2=start+getNbOfElems();
7954   int ret=0;
7955   for(int *val=start;val!=end2;val++)
7956     {
7957       if(*val==oldValue)
7958         {
7959           *val=newValue;
7960           ret++;
7961         }
7962     }
7963   return ret;
7964 }
7965
7966 /*!
7967  * Creates a new DataArrayInt containing IDs (indices) of tuples holding value equal to
7968  * one of given values.
7969  *  \param [in] valsBg - an array of values to find within \a this array.
7970  *  \param [in] valsEnd - specifies the end of the array \a valsBg, so that
7971  *              the last value of \a valsBg is \a valsEnd[ -1 ].
7972  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
7973  *          array using decrRef() as it is no more needed.
7974  *  \throw If \a this->getNumberOfComponents() != 1.
7975  */
7976 DataArrayInt *DataArrayInt::getIdsEqualList(const int *valsBg, const int *valsEnd) const throw(INTERP_KERNEL::Exception)
7977 {
7978   if(getNumberOfComponents()!=1)
7979     throw INTERP_KERNEL::Exception("DataArrayInt::getIdsEqualList : the array must have only one component, you can call 'rearrange' method before !");
7980   std::set<int> vals2(valsBg,valsEnd);
7981   const int *cptr=getConstPointer();
7982   std::vector<int> res;
7983   int nbOfTuples=getNumberOfTuples();
7984   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
7985   for(int i=0;i<nbOfTuples;i++,cptr++)
7986     if(vals2.find(*cptr)!=vals2.end())
7987       ret->pushBackSilent(i);
7988   return ret.retn();
7989 }
7990
7991 /*!
7992  * Creates a new DataArrayInt containing IDs (indices) of tuples holding values \b not
7993  * equal to any of given values.
7994  *  \param [in] valsBg - an array of values to ignore within \a this array.
7995  *  \param [in] valsEnd - specifies the end of the array \a valsBg, so that
7996  *              the last value of \a valsBg is \a valsEnd[ -1 ].
7997  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
7998  *          array using decrRef() as it is no more needed.
7999  *  \throw If \a this->getNumberOfComponents() != 1.
8000  */
8001 DataArrayInt *DataArrayInt::getIdsNotEqualList(const int *valsBg, const int *valsEnd) const throw(INTERP_KERNEL::Exception)
8002 {
8003   if(getNumberOfComponents()!=1)
8004     throw INTERP_KERNEL::Exception("DataArrayInt::getIdsNotEqualList : the array must have only one component, you can call 'rearrange' method before !");
8005   std::set<int> vals2(valsBg,valsEnd);
8006   const int *cptr=getConstPointer();
8007   std::vector<int> res;
8008   int nbOfTuples=getNumberOfTuples();
8009   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
8010   for(int i=0;i<nbOfTuples;i++,cptr++)
8011     if(vals2.find(*cptr)==vals2.end())
8012       ret->pushBackSilent(i);
8013   return ret.retn();
8014 }
8015
8016 /*!
8017  * This method is an extension of DataArrayInt::locateValue method because this method works for DataArrayInt with
8018  * any number of components excepted 0 (an INTERP_KERNEL::Exception is thrown in this case).
8019  * This method searches in \b this is there is a tuple that matched the input parameter \b tupl.
8020  * If any the tuple id is returned. If not -1 is returned.
8021  * 
8022  * This method throws an INTERP_KERNEL::Exception if the number of components in \b this mismatches with the size of
8023  * the input vector. An INTERP_KERNEL::Exception is thrown too if \b this is not allocated.
8024  *
8025  * \return tuple id where \b tupl is. -1 if no such tuple exists in \b this.
8026  * \sa DataArrayInt::search, DataArrayInt::presenceOfTuple.
8027  */
8028 int DataArrayInt::locateTuple(const std::vector<int>& tupl) const throw(INTERP_KERNEL::Exception)
8029 {
8030   checkAllocated();
8031   int nbOfCompo=getNumberOfComponents();
8032   if(nbOfCompo==0)
8033     throw INTERP_KERNEL::Exception("DataArrayInt::locateTuple : 0 components in 'this' !");
8034   if(nbOfCompo!=(int)tupl.size())
8035     {
8036       std::ostringstream oss; oss << "DataArrayInt::locateTuple : 'this' contains " << nbOfCompo << " components and searching for a tuple of length " << tupl.size() << " !";
8037       throw INTERP_KERNEL::Exception(oss.str().c_str());
8038     }
8039   const int *cptr=getConstPointer();
8040   std::size_t nbOfVals=getNbOfElems();
8041   for(const int *work=cptr;work!=cptr+nbOfVals;)
8042     {
8043       work=std::search(work,cptr+nbOfVals,tupl.begin(),tupl.end());
8044       if(work!=cptr+nbOfVals)
8045         {
8046           if(std::distance(cptr,work)%nbOfCompo!=0)
8047             work++;
8048           else
8049             return std::distance(cptr,work)/nbOfCompo;
8050         }
8051     }
8052   return -1;
8053 }
8054
8055 /*!
8056  * This method searches the sequence specified in input parameter \b vals in \b this.
8057  * This works only for DataArrayInt having number of components equal to one (if not an INTERP_KERNEL::Exception will be thrown).
8058  * This method differs from DataArrayInt::locateTuple in that the position is internal raw data is not considered here contrary to DataArrayInt::locateTuple.
8059  * \sa DataArrayInt::locateTuple
8060  */
8061 int DataArrayInt::search(const std::vector<int>& vals) const throw(INTERP_KERNEL::Exception)
8062 {
8063   checkAllocated();
8064   int nbOfCompo=getNumberOfComponents();
8065   if(nbOfCompo!=1)
8066     throw INTERP_KERNEL::Exception("DataArrayInt::search : works only for DataArrayInt instance with one component !");
8067   const int *cptr=getConstPointer();
8068   std::size_t nbOfVals=getNbOfElems();
8069   const int *loc=std::search(cptr,cptr+nbOfVals,vals.begin(),vals.end());
8070   if(loc!=cptr+nbOfVals)
8071     return std::distance(cptr,loc);
8072   return -1;
8073 }
8074
8075 /*!
8076  * This method expects to be called when number of components of this is equal to one.
8077  * This method returns the tuple id, if it exists, of the first tuple equal to \b value.
8078  * If not any tuple contains \b value -1 is returned.
8079  * \sa DataArrayInt::presenceOfValue
8080  */
8081 int DataArrayInt::locateValue(int value) const throw(INTERP_KERNEL::Exception)
8082 {
8083   checkAllocated();
8084   if(getNumberOfComponents()!=1)
8085     throw INTERP_KERNEL::Exception("DataArrayInt::presenceOfValue : the array must have only one component, you can call 'rearrange' method before !");
8086   const int *cptr=getConstPointer();
8087   int nbOfTuples=getNumberOfTuples();
8088   const int *ret=std::find(cptr,cptr+nbOfTuples,value);
8089   if(ret!=cptr+nbOfTuples)
8090     return std::distance(cptr,ret);
8091   return -1;
8092 }
8093
8094 /*!
8095  * This method expects to be called when number of components of this is equal to one.
8096  * This method returns the tuple id, if it exists, of the first tuple so that the value is contained in \b vals.
8097  * If not any tuple contains one of the values contained in 'vals' false is returned.
8098  * \sa DataArrayInt::presenceOfValue
8099  */
8100 int DataArrayInt::locateValue(const std::vector<int>& vals) const throw(INTERP_KERNEL::Exception)
8101 {
8102   checkAllocated();
8103   if(getNumberOfComponents()!=1)
8104     throw INTERP_KERNEL::Exception("DataArrayInt::presenceOfValue : the array must have only one component, you can call 'rearrange' method before !");
8105   std::set<int> vals2(vals.begin(),vals.end());
8106   const int *cptr=getConstPointer();
8107   int nbOfTuples=getNumberOfTuples();
8108   for(const int *w=cptr;w!=cptr+nbOfTuples;w++)
8109     if(vals2.find(*w)!=vals2.end())
8110       return std::distance(cptr,w);
8111   return -1;
8112 }
8113
8114 /*!
8115  * This method returns the number of values in \a this that are equals to input parameter \a value.
8116  * This method only works for single component array.
8117  *
8118  * \return a value in [ 0, \c this->getNumberOfTuples() )
8119  *
8120  * \throw If \a this is not allocated
8121  *
8122  */
8123 int DataArrayInt::count(int value) const throw(INTERP_KERNEL::Exception)
8124 {
8125   int ret=0;
8126   checkAllocated();
8127   if(getNumberOfComponents()!=1)
8128     throw INTERP_KERNEL::Exception("DataArrayInt::count : must be applied on DataArrayInt with only one component, you can call 'rearrange' method before !");
8129   const int *vals=begin();
8130   int nbOfTuples=getNumberOfTuples();
8131   for(int i=0;i<nbOfTuples;i++,vals++)
8132     if(*vals==value)
8133       ret++;
8134   return ret;
8135 }
8136
8137 /*!
8138  * This method is an extension of DataArrayInt::presenceOfValue method because this method works for DataArrayInt with
8139  * any number of components excepted 0 (an INTERP_KERNEL::Exception is thrown in this case).
8140  * This method searches in \b this is there is a tuple that matched the input parameter \b tupl.
8141  * This method throws an INTERP_KERNEL::Exception if the number of components in \b this mismatches with the size of
8142  * the input vector. An INTERP_KERNEL::Exception is thrown too if \b this is not allocated.
8143  * \sa DataArrayInt::locateTuple
8144  */
8145 bool DataArrayInt::presenceOfTuple(const std::vector<int>& tupl) const throw(INTERP_KERNEL::Exception)
8146 {
8147   return locateTuple(tupl)!=-1;
8148 }
8149
8150
8151 /*!
8152  * Returns \a true if a given value is present within \a this one-dimensional array.
8153  *  \param [in] value - the value to find within \a this array.
8154  *  \return bool - \a true in case if \a value is present within \a this array.
8155  *  \throw If \a this is not allocated.
8156  *  \throw If \a this->getNumberOfComponents() != 1.
8157  *  \sa locateValue()
8158  */
8159 bool DataArrayInt::presenceOfValue(int value) const throw(INTERP_KERNEL::Exception)
8160 {
8161   return locateValue(value)!=-1;
8162 }
8163
8164 /*!
8165  * This method expects to be called when number of components of this is equal to one.
8166  * This method returns true if it exists a tuple so that the value is contained in \b vals.
8167  * If not any tuple contains one of the values contained in 'vals' false is returned.
8168  * \sa DataArrayInt::locateValue
8169  */
8170 bool DataArrayInt::presenceOfValue(const std::vector<int>& vals) const throw(INTERP_KERNEL::Exception)
8171 {
8172   return locateValue(vals)!=-1;
8173 }
8174
8175 /*!
8176  * Accumulates values of each component of \a this array.
8177  *  \param [out] res - an array of length \a this->getNumberOfComponents(), allocated 
8178  *         by the caller, that is filled by this method with sum value for each
8179  *         component.
8180  *  \throw If \a this is not allocated.
8181  */
8182 void DataArrayInt::accumulate(int *res) const throw(INTERP_KERNEL::Exception)
8183 {
8184   checkAllocated();
8185   const int *ptr=getConstPointer();
8186   int nbTuple=getNumberOfTuples();
8187   int nbComps=getNumberOfComponents();
8188   std::fill(res,res+nbComps,0);
8189   for(int i=0;i<nbTuple;i++)
8190     std::transform(ptr+i*nbComps,ptr+(i+1)*nbComps,res,res,std::plus<int>());
8191 }
8192
8193 int DataArrayInt::accumulate(int compId) const throw(INTERP_KERNEL::Exception)
8194 {
8195   checkAllocated();
8196   const int *ptr=getConstPointer();
8197   int nbTuple=getNumberOfTuples();
8198   int nbComps=getNumberOfComponents();
8199   if(compId<0 || compId>=nbComps)
8200     throw INTERP_KERNEL::Exception("DataArrayInt::accumulate : Invalid compId specified : No such nb of components !");
8201   int ret=0;
8202   for(int i=0;i<nbTuple;i++)
8203     ret+=ptr[i*nbComps+compId];
8204   return ret;
8205 }
8206
8207 /*!
8208  * This method accumulate using addition tuples in \a this using input index array [ \a bgOfIndex, \a endOfIndex ).
8209  * The returned array will have same number of components than \a this and number of tuples equal to
8210  * \c std::distance(bgOfIndex,endOfIndex) \b minus \b one.
8211  *
8212  * The input index array is expected to be ascendingly sorted in which the all referenced ids should be in [0, \c this->getNumberOfTuples).
8213  *
8214  * \param [in] bgOfIndex - begin (included) of the input index array.
8215  * \param [in] endOfIndex - end (excluded) of the input index array.
8216  * \return DataArrayInt * - the new instance having the same number of components than \a this.
8217  * 
8218  * \throw If bgOfIndex or end is NULL.
8219  * \throw If input index array is not ascendingly sorted.
8220  * \throw If there is an id in [ \a bgOfIndex, \a endOfIndex ) not in [0, \c this->getNumberOfTuples).
8221  * \throw If std::distance(bgOfIndex,endOfIndex)==0.
8222  */
8223 DataArrayInt *DataArrayInt::accumulatePerChunck(const int *bgOfIndex, const int *endOfIndex) const throw(INTERP_KERNEL::Exception)
8224 {
8225   if(!bgOfIndex || !endOfIndex)
8226     throw INTERP_KERNEL::Exception("DataArrayInt::accumulatePerChunck : input pointer NULL !");
8227   checkAllocated();
8228   int nbCompo=getNumberOfComponents();
8229   int nbOfTuples=getNumberOfTuples();
8230   int sz=(int)std::distance(bgOfIndex,endOfIndex);
8231   if(sz<1)
8232     throw INTERP_KERNEL::Exception("DataArrayInt::accumulatePerChunck : invalid size of input index array !");
8233   sz--;
8234   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(sz,nbCompo);
8235   const int *w=bgOfIndex;
8236   if(*w<0 || *w>=nbOfTuples)
8237     throw INTERP_KERNEL::Exception("DataArrayInt::accumulatePerChunck : The first element of the input index not in [0,nbOfTuples) !");
8238   const int *srcPt=begin()+(*w)*nbCompo;
8239   int *tmp=ret->getPointer();
8240   for(int i=0;i<sz;i++,tmp+=nbCompo,w++)
8241     {
8242       std::fill(tmp,tmp+nbCompo,0.);
8243       if(w[1]>=w[0])
8244         {
8245           for(int j=w[0];j<w[1];j++,srcPt+=nbCompo)
8246             {
8247               if(j>=0 && j<nbOfTuples)
8248                 std::transform(srcPt,srcPt+nbCompo,tmp,tmp,std::plus<int>());
8249               else
8250                 {
8251                   std::ostringstream oss; oss << "DataArrayInt::accumulatePerChunck : At rank #" << i << " the input index array points to id " << j << " should be in [0," << nbOfTuples << ") !";
8252                   throw INTERP_KERNEL::Exception(oss.str().c_str());
8253                 }
8254             }
8255         }
8256       else
8257         {
8258           std::ostringstream oss; oss << "DataArrayInt::accumulatePerChunck : At rank #" << i << " the input index array is not in ascendingly sorted.";
8259           throw INTERP_KERNEL::Exception(oss.str().c_str());
8260         }
8261     }
8262   ret->copyStringInfoFrom(*this);
8263   return ret.retn();
8264 }
8265
8266 /*!
8267  * Returns a new DataArrayInt by concatenating two given arrays, so that (1) the number
8268  * of tuples in the result array is <em> a1->getNumberOfTuples() + a2->getNumberOfTuples() -
8269  * offsetA2</em> and (2)
8270  * the number of component in the result array is same as that of each of given arrays.
8271  * First \a offsetA2 tuples of \a a2 are skipped and thus are missing from the result array.
8272  * Info on components is copied from the first of the given arrays. Number of components
8273  * in the given arrays must be the same.
8274  *  \param [in] a1 - an array to include in the result array.
8275  *  \param [in] a2 - another array to include in the result array.
8276  *  \param [in] offsetA2 - number of tuples of \a a2 to skip.
8277  *  \return DataArrayInt * - the new instance of DataArrayInt.
8278  *          The caller is to delete this result array using decrRef() as it is no more
8279  *          needed.
8280  *  \throw If either \a a1 or \a a2 is NULL.
8281  *  \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents().
8282  */
8283 DataArrayInt *DataArrayInt::Aggregate(const DataArrayInt *a1, const DataArrayInt *a2, int offsetA2)
8284 {
8285   if(!a1 || !a2)
8286     throw INTERP_KERNEL::Exception("DataArrayInt::Aggregate : input DataArrayInt instance is NULL !");
8287   int nbOfComp=a1->getNumberOfComponents();
8288   if(nbOfComp!=a2->getNumberOfComponents())
8289     throw INTERP_KERNEL::Exception("Nb of components mismatch for array Aggregation !");
8290   int nbOfTuple1=a1->getNumberOfTuples();
8291   int nbOfTuple2=a2->getNumberOfTuples();
8292   DataArrayInt *ret=DataArrayInt::New();
8293   ret->alloc(nbOfTuple1+nbOfTuple2-offsetA2,nbOfComp);
8294   int *pt=std::copy(a1->getConstPointer(),a1->getConstPointer()+nbOfTuple1*nbOfComp,ret->getPointer());
8295   std::copy(a2->getConstPointer()+offsetA2*nbOfComp,a2->getConstPointer()+nbOfTuple2*nbOfComp,pt);
8296   ret->copyStringInfoFrom(*a1);
8297   return ret;
8298 }
8299
8300 /*!
8301  * Returns a new DataArrayInt by concatenating all given arrays, so that (1) the number
8302  * of tuples in the result array is a sum of the number of tuples of given arrays and (2)
8303  * the number of component in the result array is same as that of each of given arrays.
8304  * Info on components is copied from the first of the given arrays. Number of components
8305  * in the given arrays must be  the same.
8306  *  \param [in] arr - a sequence of arrays to include in the result array.
8307  *  \return DataArrayInt * - the new instance of DataArrayInt.
8308  *          The caller is to delete this result array using decrRef() as it is no more
8309  *          needed.
8310  *  \throw If all arrays within \a arr are NULL.
8311  *  \throw If getNumberOfComponents() of arrays within \a arr.
8312  */
8313 DataArrayInt *DataArrayInt::Aggregate(const std::vector<const DataArrayInt *>& arr) throw(INTERP_KERNEL::Exception)
8314 {
8315   std::vector<const DataArrayInt *> a;
8316   for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
8317     if(*it4)
8318       a.push_back(*it4);
8319   if(a.empty())
8320     throw INTERP_KERNEL::Exception("DataArrayInt::Aggregate : input list must be NON EMPTY !");
8321   std::vector<const DataArrayInt *>::const_iterator it=a.begin();
8322   int nbOfComp=(*it)->getNumberOfComponents();
8323   int nbt=(*it++)->getNumberOfTuples();
8324   for(int i=1;it!=a.end();it++,i++)
8325     {
8326       if((*it)->getNumberOfComponents()!=nbOfComp)
8327         throw INTERP_KERNEL::Exception("DataArrayInt::Aggregate : Nb of components mismatch for array aggregation !");
8328       nbt+=(*it)->getNumberOfTuples();
8329     }
8330   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
8331   ret->alloc(nbt,nbOfComp);
8332   int *pt=ret->getPointer();
8333   for(it=a.begin();it!=a.end();it++)
8334     pt=std::copy((*it)->getConstPointer(),(*it)->getConstPointer()+(*it)->getNbOfElems(),pt);
8335   ret->copyStringInfoFrom(*(a[0]));
8336   return ret.retn();
8337 }
8338
8339 /*!
8340  * This method takes as input a list of DataArrayInt instances \a arrs that represent each a packed index arrays.
8341  * A packed index array is an allocated array with one component, and at least one tuple. The first element
8342  * of each array in \a arrs must be 0. Each array in \a arrs is expected to be increasingly monotonic.
8343  * 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.
8344  * 
8345  * \return DataArrayInt * - a new object to be managed by the caller.
8346  */
8347 DataArrayInt *DataArrayInt::AggregateIndexes(const std::vector<const DataArrayInt *>& arrs) throw(INTERP_KERNEL::Exception)
8348 {
8349   int retSz=1;
8350   for(std::vector<const DataArrayInt *>::const_iterator it4=arrs.begin();it4!=arrs.end();it4++)
8351     {
8352       if(*it4)
8353         {
8354           (*it4)->checkAllocated();
8355           if((*it4)->getNumberOfComponents()!=1)
8356             {
8357               std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a DataArrayInt instance with nb of compo != 1 at pos " << std::distance(arrs.begin(),it4) << " !";
8358               throw INTERP_KERNEL::Exception(oss.str().c_str());
8359             }
8360           int nbTupl=(*it4)->getNumberOfTuples();
8361           if(nbTupl<1)
8362             {
8363               std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a DataArrayInt instance with nb of tuples < 1 at pos " << std::distance(arrs.begin(),it4) << " !";
8364               throw INTERP_KERNEL::Exception(oss.str().c_str());
8365             }
8366           if((*it4)->front()!=0)
8367             {
8368               std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a DataArrayInt instance with front value != 0 at pos " << std::distance(arrs.begin(),it4) << " !";
8369               throw INTERP_KERNEL::Exception(oss.str().c_str());
8370             }
8371           retSz+=nbTupl-1;
8372         }
8373       else
8374         {
8375           std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a null instance at pos " << std::distance(arrs.begin(),it4) << " !";
8376           throw INTERP_KERNEL::Exception(oss.str().c_str());
8377         }
8378     }
8379   if(arrs.empty())
8380     throw INTERP_KERNEL::Exception("DataArrayInt::AggregateIndexes : input list must be NON EMPTY !");
8381   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
8382   ret->alloc(retSz,1);
8383   int *pt=ret->getPointer(); *pt++=0;
8384   for(std::vector<const DataArrayInt *>::const_iterator it=arrs.begin();it!=arrs.end();it++)
8385     pt=std::transform((*it)->begin()+1,(*it)->end(),pt,std::bind2nd(std::plus<int>(),pt[-1]));
8386   ret->copyStringInfoFrom(*(arrs[0]));
8387   return ret.retn();
8388 }
8389
8390 /*!
8391  * Returns the maximal value and its location within \a this one-dimensional array.
8392  *  \param [out] tupleId - index of the tuple holding the maximal value.
8393  *  \return int - the maximal value among all values of \a this array.
8394  *  \throw If \a this->getNumberOfComponents() != 1
8395  *  \throw If \a this->getNumberOfTuples() < 1
8396  */
8397 int DataArrayInt::getMaxValue(int& tupleId) const throw(INTERP_KERNEL::Exception)
8398 {
8399   checkAllocated();
8400   if(getNumberOfComponents()!=1)
8401     throw INTERP_KERNEL::Exception("DataArrayInt::getMaxValue : must be applied on DataArrayInt with only one component !");
8402   int nbOfTuples=getNumberOfTuples();
8403   if(nbOfTuples<=0)
8404     throw INTERP_KERNEL::Exception("DataArrayInt::getMaxValue : array exists but number of tuples must be > 0 !");
8405   const int *vals=getConstPointer();
8406   const int *loc=std::max_element(vals,vals+nbOfTuples);
8407   tupleId=(int)std::distance(vals,loc);
8408   return *loc;
8409 }
8410
8411 /*!
8412  * Returns the maximal value within \a this array that is allowed to have more than
8413  *  one component.
8414  *  \return int - the maximal value among all values of \a this array.
8415  *  \throw If \a this is not allocated.
8416  */
8417 int DataArrayInt::getMaxValueInArray() const throw(INTERP_KERNEL::Exception)
8418 {
8419   checkAllocated();
8420   const int *loc=std::max_element(begin(),end());
8421   return *loc;
8422 }
8423
8424 /*!
8425  * Returns the minimal value and its location within \a this one-dimensional array.
8426  *  \param [out] tupleId - index of the tuple holding the minimal value.
8427  *  \return int - the minimal value among all values of \a this array.
8428  *  \throw If \a this->getNumberOfComponents() != 1
8429  *  \throw If \a this->getNumberOfTuples() < 1
8430  */
8431 int DataArrayInt::getMinValue(int& tupleId) const throw(INTERP_KERNEL::Exception)
8432 {
8433   checkAllocated();
8434   if(getNumberOfComponents()!=1)
8435     throw INTERP_KERNEL::Exception("DataArrayInt::getMaxValue : must be applied on DataArrayInt with only one component !");
8436   int nbOfTuples=getNumberOfTuples();
8437   if(nbOfTuples<=0)
8438     throw INTERP_KERNEL::Exception("DataArrayInt::getMaxValue : array exists but number of tuples must be > 0 !");
8439   const int *vals=getConstPointer();
8440   const int *loc=std::min_element(vals,vals+nbOfTuples);
8441   tupleId=(int)std::distance(vals,loc);
8442   return *loc;
8443 }
8444
8445 /*!
8446  * Returns the minimal value within \a this array that is allowed to have more than
8447  *  one component.
8448  *  \return int - the minimal value among all values of \a this array.
8449  *  \throw If \a this is not allocated.
8450  */
8451 int DataArrayInt::getMinValueInArray() const throw(INTERP_KERNEL::Exception)
8452 {
8453   checkAllocated();
8454   const int *loc=std::min_element(begin(),end());
8455   return *loc;
8456 }
8457
8458 /*!
8459  * Converts every value of \a this array to its absolute value.
8460  *  \throw If \a this is not allocated.
8461  */
8462 void DataArrayInt::abs() throw(INTERP_KERNEL::Exception)
8463 {
8464   checkAllocated();
8465   int *ptr=getPointer();
8466   std::size_t nbOfElems=getNbOfElems();
8467   std::transform(ptr,ptr+nbOfElems,ptr,std::ptr_fun<int,int>(std::abs));
8468   declareAsNew();
8469 }
8470
8471 /*!
8472  * Apply a liner function to a given component of \a this array, so that
8473  * an array element <em>(x)</em> becomes \f$ a * x + b \f$.
8474  *  \param [in] a - the first coefficient of the function.
8475  *  \param [in] b - the second coefficient of the function.
8476  *  \param [in] compoId - the index of component to modify.
8477  *  \throw If \a this is not allocated.
8478  */
8479 void DataArrayInt::applyLin(int a, int b, int compoId) throw(INTERP_KERNEL::Exception)
8480 {
8481   checkAllocated();
8482   int *ptr=getPointer()+compoId;
8483   int nbOfComp=getNumberOfComponents();
8484   int nbOfTuple=getNumberOfTuples();
8485   for(int i=0;i<nbOfTuple;i++,ptr+=nbOfComp)
8486     *ptr=a*(*ptr)+b;
8487   declareAsNew();
8488 }
8489
8490 /*!
8491  * Apply a liner function to all elements of \a this array, so that
8492  * an element _x_ becomes \f$ a * x + b \f$.
8493  *  \param [in] a - the first coefficient of the function.
8494  *  \param [in] b - the second coefficient of the function.
8495  *  \throw If \a this is not allocated.
8496  */
8497 void DataArrayInt::applyLin(int a, int b) throw(INTERP_KERNEL::Exception)
8498 {
8499   checkAllocated();
8500   int *ptr=getPointer();
8501   std::size_t nbOfElems=getNbOfElems();
8502   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
8503     *ptr=a*(*ptr)+b;
8504   declareAsNew();
8505 }
8506
8507 /*!
8508  * Returns a full copy of \a this array except that sign of all elements is reversed.
8509  *  \return DataArrayInt * - the new instance of DataArrayInt containing the
8510  *          same number of tuples and component as \a this array.
8511  *          The caller is to delete this result array using decrRef() as it is no more
8512  *          needed.
8513  *  \throw If \a this is not allocated.
8514  */
8515 DataArrayInt *DataArrayInt::negate() const throw(INTERP_KERNEL::Exception)
8516 {
8517   checkAllocated();
8518   DataArrayInt *newArr=DataArrayInt::New();
8519   int nbOfTuples=getNumberOfTuples();
8520   int nbOfComp=getNumberOfComponents();
8521   newArr->alloc(nbOfTuples,nbOfComp);
8522   const int *cptr=getConstPointer();
8523   std::transform(cptr,cptr+nbOfTuples*nbOfComp,newArr->getPointer(),std::negate<int>());
8524   newArr->copyStringInfoFrom(*this);
8525   return newArr;
8526 }
8527
8528 /*!
8529  * Modify all elements of \a this array, so that
8530  * an element _x_ becomes \f$ numerator / x \f$.
8531  *  \warning If an exception is thrown because of presence of 0 element in \a this 
8532  *           array, all elements processed before detection of the zero element remain
8533  *           modified.
8534  *  \param [in] numerator - the numerator used to modify array elements.
8535  *  \throw If \a this is not allocated.
8536  *  \throw If there is an element equal to 0 in \a this array.
8537  */
8538 void DataArrayInt::applyInv(int numerator) throw(INTERP_KERNEL::Exception)
8539 {
8540   checkAllocated();
8541   int *ptr=getPointer();
8542   std::size_t nbOfElems=getNbOfElems();
8543   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
8544     {
8545       if(*ptr!=0)
8546         {
8547           *ptr=numerator/(*ptr);
8548         }
8549       else
8550         {
8551           std::ostringstream oss; oss << "DataArrayInt::applyInv : presence of null value in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
8552           oss << " !";
8553           throw INTERP_KERNEL::Exception(oss.str().c_str());
8554         }
8555     }
8556   declareAsNew();
8557 }
8558
8559 /*!
8560  * Modify all elements of \a this array, so that
8561  * an element _x_ becomes \f$ x / val \f$.
8562  *  \param [in] val - the denominator used to modify array elements.
8563  *  \throw If \a this is not allocated.
8564  *  \throw If \a val == 0.
8565  */
8566 void DataArrayInt::applyDivideBy(int val) throw(INTERP_KERNEL::Exception)
8567 {
8568   if(val==0)
8569     throw INTERP_KERNEL::Exception("DataArrayInt::applyDivideBy : Trying to divide by 0 !");
8570   checkAllocated();
8571   int *ptr=getPointer();
8572   std::size_t nbOfElems=getNbOfElems();
8573   std::transform(ptr,ptr+nbOfElems,ptr,std::bind2nd(std::divides<int>(),val));
8574   declareAsNew();
8575 }
8576
8577 /*!
8578  * Modify all elements of \a this array, so that
8579  * an element _x_ becomes  <em> x % val </em>.
8580  *  \param [in] val - the divisor used to modify array elements.
8581  *  \throw If \a this is not allocated.
8582  *  \throw If \a val <= 0.
8583  */
8584 void DataArrayInt::applyModulus(int val) throw(INTERP_KERNEL::Exception)
8585 {
8586   if(val<=0)
8587     throw INTERP_KERNEL::Exception("DataArrayInt::applyDivideBy : Trying to operate modulus on value <= 0 !");
8588   checkAllocated();
8589   int *ptr=getPointer();
8590   std::size_t nbOfElems=getNbOfElems();
8591   std::transform(ptr,ptr+nbOfElems,ptr,std::bind2nd(std::modulus<int>(),val));
8592   declareAsNew();
8593 }
8594
8595 /*!
8596  * This method works only on data array with one component.
8597  * This method returns a newly allocated array storing stored ascendantly tuple ids in \b this so that
8598  * this[*id] in [\b vmin,\b vmax)
8599  * 
8600  * \param [in] vmin begin of range. This value is included in range (included).
8601  * \param [in] vmax end of range. This value is \b not included in range (excluded).
8602  * \return a newly allocated data array that the caller should deal with.
8603  */
8604 DataArrayInt *DataArrayInt::getIdsInRange(int vmin, int vmax) const throw(INTERP_KERNEL::Exception)
8605 {
8606   checkAllocated();
8607   if(getNumberOfComponents()!=1)
8608     throw INTERP_KERNEL::Exception("DataArrayInt::getIdsInRange : this must have exactly one component !");
8609   const int *cptr=getConstPointer();
8610   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(0,1);
8611   int nbOfTuples=getNumberOfTuples();
8612   for(int i=0;i<nbOfTuples;i++,cptr++)
8613     if(*cptr>=vmin && *cptr<vmax)
8614       ret->pushBackSilent(i);
8615   return ret.retn();
8616 }
8617
8618 /*!
8619  * This method works only on data array with one component.
8620  * 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.
8621  * 
8622  * \param [in] vmin begin of range. This value is included in range (included).
8623  * \param [in] vmax end of range. This value is \b not included in range (excluded).
8624  * \return if all ids in \a this are so that (*this)[i]==i for all i in [ 0, \c this->getNumberOfTuples() ).
8625  */
8626 bool DataArrayInt::checkAllIdsInRange(int vmin, int vmax) const throw(INTERP_KERNEL::Exception)
8627 {
8628   checkAllocated();
8629   if(getNumberOfComponents()!=1)
8630     throw INTERP_KERNEL::Exception("DataArrayInt::checkAllIdsInRange : this must have exactly one component !");
8631   int nbOfTuples=getNumberOfTuples();
8632   bool ret=true;
8633   const int *cptr=getConstPointer();
8634   for(int i=0;i<nbOfTuples;i++,cptr++)
8635     {
8636       if(*cptr>=vmin && *cptr<vmax)
8637         { ret=ret && *cptr==i; }
8638       else
8639         {
8640           std::ostringstream oss; oss << "DataArrayInt::checkAllIdsInRange : tuple #" << i << " has value " << *cptr << " should be in [" << vmin << "," << vmax << ") !";
8641           throw INTERP_KERNEL::Exception(oss.str().c_str());
8642         }
8643     }
8644   return ret;
8645 }
8646
8647 /*!
8648  * Modify all elements of \a this array, so that
8649  * an element _x_ becomes <em> val % x </em>.
8650  *  \warning If an exception is thrown because of presence of an element <= 0 in \a this 
8651  *           array, all elements processed before detection of the zero element remain
8652  *           modified.
8653  *  \param [in] val - the divident used to modify array elements.
8654  *  \throw If \a this is not allocated.
8655  *  \throw If there is an element equal to or less than 0 in \a this array.
8656  */
8657 void DataArrayInt::applyRModulus(int val) throw(INTERP_KERNEL::Exception)
8658 {
8659   checkAllocated();
8660   int *ptr=getPointer();
8661   std::size_t nbOfElems=getNbOfElems();
8662   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
8663     {
8664       if(*ptr>0)
8665         {
8666           *ptr=val%(*ptr);
8667         }
8668       else
8669         {
8670           std::ostringstream oss; oss << "DataArrayInt::applyRModulus : presence of value <=0 in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
8671           oss << " !";
8672           throw INTERP_KERNEL::Exception(oss.str().c_str());
8673         }
8674     }
8675   declareAsNew();
8676 }
8677
8678 /*!
8679  * Modify all elements of \a this array, so that
8680  * an element _x_ becomes <em> val ^ x </em>.
8681  *  \param [in] val - the value used to apply pow on all array elements.
8682  *  \throw If \a this is not allocated.
8683  *  \throw If \a val < 0.
8684  */
8685 void DataArrayInt::applyPow(int val) throw(INTERP_KERNEL::Exception)
8686 {
8687   checkAllocated();
8688   if(val<0)
8689     throw INTERP_KERNEL::Exception("DataArrayInt::applyPow : input pow in < 0 !");
8690   int *ptr=getPointer();
8691   std::size_t nbOfElems=getNbOfElems();
8692   if(val==0)
8693     {
8694       std::fill(ptr,ptr+nbOfElems,1.);
8695       return ;
8696     }
8697   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
8698     {
8699       int tmp=1;
8700       for(int j=0;j<val;j++)
8701         tmp*=*ptr;
8702       *ptr=tmp;
8703     }
8704   declareAsNew();
8705 }
8706
8707 /*!
8708  * Modify all elements of \a this array, so that
8709  * an element _x_ becomes \f$ val ^ x \f$.
8710  *  \param [in] val - the value used to apply pow on all array elements.
8711  *  \throw If \a this is not allocated.
8712  *  \throw If there is an element < 0 in \a this array.
8713  *  \warning If an exception is thrown because of presence of 0 element in \a this 
8714  *           array, all elements processed before detection of the zero element remain
8715  *           modified.
8716  */
8717 void DataArrayInt::applyRPow(int val) throw(INTERP_KERNEL::Exception)
8718 {
8719   checkAllocated();
8720   int *ptr=getPointer();
8721   std::size_t nbOfElems=getNbOfElems();
8722   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
8723     {
8724       if(*ptr>=0)
8725         {
8726           int tmp=1;
8727           for(int j=0;j<*ptr;j++)
8728             tmp*=val;
8729           *ptr=tmp;
8730         }
8731       else
8732         {
8733           std::ostringstream oss; oss << "DataArrayInt::applyRPow : presence of negative value in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
8734           oss << " !";
8735           throw INTERP_KERNEL::Exception(oss.str().c_str());
8736         }
8737     }
8738   declareAsNew();
8739 }
8740
8741 /*!
8742  * Returns a new DataArrayInt by aggregating two given arrays, so that (1) the number
8743  * of components in the result array is a sum of the number of components of given arrays
8744  * and (2) the number of tuples in the result array is same as that of each of given
8745  * arrays. In other words the i-th tuple of result array includes all components of
8746  * i-th tuples of all given arrays.
8747  * Number of tuples in the given arrays must be the same.
8748  *  \param [in] a1 - an array to include in the result array.
8749  *  \param [in] a2 - another array to include in the result array.
8750  *  \return DataArrayInt * - the new instance of DataArrayInt.
8751  *          The caller is to delete this result array using decrRef() as it is no more
8752  *          needed.
8753  *  \throw If both \a a1 and \a a2 are NULL.
8754  *  \throw If any given array is not allocated.
8755  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
8756  */
8757 DataArrayInt *DataArrayInt::Meld(const DataArrayInt *a1, const DataArrayInt *a2) throw(INTERP_KERNEL::Exception)
8758 {
8759   std::vector<const DataArrayInt *> arr(2);
8760   arr[0]=a1; arr[1]=a2;
8761   return Meld(arr);
8762 }
8763
8764 /*!
8765  * Returns a new DataArrayInt by aggregating all given arrays, so that (1) the number
8766  * of components in the result array is a sum of the number of components of given arrays
8767  * and (2) the number of tuples in the result array is same as that of each of given
8768  * arrays. In other words the i-th tuple of result array includes all components of
8769  * i-th tuples of all given arrays.
8770  * Number of tuples in the given arrays must be  the same.
8771  *  \param [in] arr - a sequence of arrays to include in the result array.
8772  *  \return DataArrayInt * - the new instance of DataArrayInt.
8773  *          The caller is to delete this result array using decrRef() as it is no more
8774  *          needed.
8775  *  \throw If all arrays within \a arr are NULL.
8776  *  \throw If any given array is not allocated.
8777  *  \throw If getNumberOfTuples() of arrays within \a arr is different.
8778  */
8779 DataArrayInt *DataArrayInt::Meld(const std::vector<const DataArrayInt *>& arr) throw(INTERP_KERNEL::Exception)
8780 {
8781   std::vector<const DataArrayInt *> a;
8782   for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
8783     if(*it4)
8784       a.push_back(*it4);
8785   if(a.empty())
8786     throw INTERP_KERNEL::Exception("DataArrayInt::Meld : array must be NON empty !");
8787   std::vector<const DataArrayInt *>::const_iterator it;
8788   for(it=a.begin();it!=a.end();it++)
8789     (*it)->checkAllocated();
8790   it=a.begin();
8791   int nbOfTuples=(*it)->getNumberOfTuples();
8792   std::vector<int> nbc(a.size());
8793   std::vector<const int *> pts(a.size());
8794   nbc[0]=(*it)->getNumberOfComponents();
8795   pts[0]=(*it++)->getConstPointer();
8796   for(int i=1;it!=a.end();it++,i++)
8797     {
8798       if(nbOfTuples!=(*it)->getNumberOfTuples())
8799         throw INTERP_KERNEL::Exception("DataArrayInt::meld : mismatch of number of tuples !");
8800       nbc[i]=(*it)->getNumberOfComponents();
8801       pts[i]=(*it)->getConstPointer();
8802     }
8803   int totalNbOfComp=std::accumulate(nbc.begin(),nbc.end(),0);
8804   DataArrayInt *ret=DataArrayInt::New();
8805   ret->alloc(nbOfTuples,totalNbOfComp);
8806   int *retPtr=ret->getPointer();
8807   for(int i=0;i<nbOfTuples;i++)
8808     for(int j=0;j<(int)a.size();j++)
8809       {
8810         retPtr=std::copy(pts[j],pts[j]+nbc[j],retPtr);
8811         pts[j]+=nbc[j];
8812       }
8813   int k=0;
8814   for(int i=0;i<(int)a.size();i++)
8815     for(int j=0;j<nbc[i];j++,k++)
8816       ret->setInfoOnComponent(k,a[i]->getInfoOnComponent(j).c_str());
8817   return ret;
8818 }
8819
8820 /*!
8821  * Returns a new DataArrayInt which is a minimal partition of elements of \a groups.
8822  * The i-th item of the result array is an ID of a set of elements belonging to a
8823  * unique set of groups, which the i-th element is a part of. This set of elements
8824  * belonging to a unique set of groups is called \a family, so the result array contains
8825  * IDs of families each element belongs to.
8826  *
8827  * \b Example: if we have two groups of elements: \a group1 [0,4] and \a group2 [ 0,1,2 ],
8828  * then there are 3 families:
8829  * - \a family1 (with ID 1) contains element [0] belonging to ( \a group1 + \a group2 ),
8830  * - \a family2 (with ID 2) contains elements [4] belonging to ( \a group1 ),
8831  * - \a family3 (with ID 3) contains element [1,2] belonging to ( \a group2 ), <br>
8832  * and the result array contains IDs of families [ 1,3,3,0,2 ]. <br> Note a family ID 0 which
8833  * stands for the element #3 which is in none of groups.
8834  *
8835  *  \param [in] groups - sequence of groups of element IDs.
8836  *  \param [in] newNb - total number of elements; it must be more than max ID of element
8837  *         in \a groups.
8838  *  \param [out] fidsOfGroups - IDs of families the elements of each group belong to.
8839  *  \return DataArrayInt * - a new instance of DataArrayInt containing IDs of families
8840  *         each element with ID from range [0, \a newNb ) belongs to. The caller is to
8841  *         delete this array using decrRef() as it is no more needed.
8842  *  \throw If any element ID in \a groups violates condition ( 0 <= ID < \a newNb ).
8843  */
8844 DataArrayInt *DataArrayInt::MakePartition(const std::vector<const DataArrayInt *>& groups, int newNb, std::vector< std::vector<int> >& fidsOfGroups) throw(INTERP_KERNEL::Exception)
8845 {
8846   std::vector<const DataArrayInt *> groups2;
8847   for(std::vector<const DataArrayInt *>::const_iterator it4=groups.begin();it4!=groups.end();it4++)
8848     if(*it4)
8849       groups2.push_back(*it4);
8850   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
8851   ret->alloc(newNb,1);
8852   int *retPtr=ret->getPointer();
8853   std::fill(retPtr,retPtr+newNb,0);
8854   int fid=1;
8855   for(std::vector<const DataArrayInt *>::const_iterator iter=groups2.begin();iter!=groups2.end();iter++)
8856     {
8857       const int *ptr=(*iter)->getConstPointer();
8858       std::size_t nbOfElem=(*iter)->getNbOfElems();
8859       int sfid=fid;
8860       for(int j=0;j<sfid;j++)
8861         {
8862           bool found=false;
8863           for(std::size_t i=0;i<nbOfElem;i++)
8864             {
8865               if(ptr[i]>=0 && ptr[i]<newNb)
8866                 {
8867                   if(retPtr[ptr[i]]==j)
8868                     {
8869                       retPtr[ptr[i]]=fid;
8870                       found=true;
8871                     }
8872                 }
8873               else
8874                 {
8875                   std::ostringstream oss; oss << "DataArrayInt::MakePartition : In group \"" << (*iter)->getName() << "\" in tuple #" << i << " value = " << ptr[i] << " ! Should be in [0," << newNb;
8876                   oss << ") !";
8877                   throw INTERP_KERNEL::Exception(oss.str().c_str());
8878                 }
8879             }
8880           if(found)
8881             fid++;
8882         }
8883     }
8884   fidsOfGroups.clear();
8885   fidsOfGroups.resize(groups2.size());
8886   int grId=0;
8887   for(std::vector<const DataArrayInt *>::const_iterator iter=groups2.begin();iter!=groups2.end();iter++,grId++)
8888     {
8889       std::set<int> tmp;
8890       const int *ptr=(*iter)->getConstPointer();
8891       std::size_t nbOfElem=(*iter)->getNbOfElems();
8892       for(const int *p=ptr;p!=ptr+nbOfElem;p++)
8893         tmp.insert(retPtr[*p]);
8894       fidsOfGroups[grId].insert(fidsOfGroups[grId].end(),tmp.begin(),tmp.end());
8895     }
8896   return ret.retn();
8897 }
8898
8899 /*!
8900  * Returns a new DataArrayInt which contains all elements of given one-dimensional
8901  * arrays. The result array does not contain any duplicates and its values
8902  * are sorted in ascending order.
8903  *  \param [in] arr - sequence of DataArrayInt's to unite.
8904  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
8905  *         array using decrRef() as it is no more needed.
8906  *  \throw If any \a arr[i] is not allocated.
8907  *  \throw If \a arr[i]->getNumberOfComponents() != 1.
8908  */
8909 DataArrayInt *DataArrayInt::BuildUnion(const std::vector<const DataArrayInt *>& arr) throw(INTERP_KERNEL::Exception)
8910 {
8911   std::vector<const DataArrayInt *> a;
8912   for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
8913     if(*it4)
8914       a.push_back(*it4);
8915   for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
8916     {
8917       (*it)->checkAllocated();
8918       if((*it)->getNumberOfComponents()!=1)
8919         throw INTERP_KERNEL::Exception("DataArrayInt::BuildUnion : only single component allowed !");
8920     }
8921   //
8922   std::set<int> r;
8923   for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
8924     {
8925       const int *pt=(*it)->getConstPointer();
8926       int nbOfTuples=(*it)->getNumberOfTuples();
8927       r.insert(pt,pt+nbOfTuples);
8928     }
8929   DataArrayInt *ret=DataArrayInt::New();
8930   ret->alloc((int)r.size(),1);
8931   std::copy(r.begin(),r.end(),ret->getPointer());
8932   return ret;
8933 }
8934
8935 /*!
8936  * Returns a new DataArrayInt which contains elements present in each of given one-dimensional
8937  * arrays. The result array does not contain any duplicates and its values
8938  * are sorted in ascending order.
8939  *  \param [in] arr - sequence of DataArrayInt's to intersect.
8940  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
8941  *         array using decrRef() as it is no more needed.
8942  *  \throw If any \a arr[i] is not allocated.
8943  *  \throw If \a arr[i]->getNumberOfComponents() != 1.
8944  */
8945 DataArrayInt *DataArrayInt::BuildIntersection(const std::vector<const DataArrayInt *>& arr) throw(INTERP_KERNEL::Exception)
8946 {
8947   std::vector<const DataArrayInt *> a;
8948   for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
8949     if(*it4)
8950       a.push_back(*it4);
8951   for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
8952     {
8953       (*it)->checkAllocated();
8954       if((*it)->getNumberOfComponents()!=1)
8955         throw INTERP_KERNEL::Exception("DataArrayInt::BuildIntersection : only single component allowed !");
8956     }
8957   //
8958   std::set<int> r;
8959   for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
8960     {
8961       const int *pt=(*it)->getConstPointer();
8962       int nbOfTuples=(*it)->getNumberOfTuples();
8963       std::set<int> s1(pt,pt+nbOfTuples);
8964       if(it!=a.begin())
8965         {
8966           std::set<int> r2;
8967           std::set_intersection(r.begin(),r.end(),s1.begin(),s1.end(),inserter(r2,r2.end()));
8968           r=r2;
8969         }
8970       else
8971         r=s1;
8972     }
8973   DataArrayInt *ret=DataArrayInt::New();
8974   ret->alloc((int)r.size(),1);
8975   std::copy(r.begin(),r.end(),ret->getPointer());
8976   return ret;
8977 }
8978
8979 /*!
8980  * Returns a new DataArrayInt which contains a complement of elements of \a this
8981  * one-dimensional array. I.e. the result array contains all elements from the range [0,
8982  * \a nbOfElement) not present in \a this array.
8983  *  \param [in] nbOfElement - maximal size of the result array.
8984  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
8985  *         array using decrRef() as it is no more needed.
8986  *  \throw If \a this is not allocated.
8987  *  \throw If \a this->getNumberOfComponents() != 1.
8988  *  \throw If any element \a x of \a this array violates condition ( 0 <= \a x < \a
8989  *         nbOfElement ).
8990  */
8991 DataArrayInt *DataArrayInt::buildComplement(int nbOfElement) const throw(INTERP_KERNEL::Exception)
8992 {
8993    checkAllocated();
8994    if(getNumberOfComponents()!=1)
8995      throw INTERP_KERNEL::Exception("DataArrayInt::buildComplement : only single component allowed !");
8996    std::vector<bool> tmp(nbOfElement);
8997    const int *pt=getConstPointer();
8998    int nbOfTuples=getNumberOfTuples();
8999    for(const int *w=pt;w!=pt+nbOfTuples;w++)
9000      if(*w>=0 && *w<nbOfElement)
9001        tmp[*w]=true;
9002      else
9003        throw INTERP_KERNEL::Exception("DataArrayInt::buildComplement : an element is not in valid range : [0,nbOfElement) !");
9004    int nbOfRetVal=(int)std::count(tmp.begin(),tmp.end(),false);
9005    DataArrayInt *ret=DataArrayInt::New();
9006    ret->alloc(nbOfRetVal,1);
9007    int j=0;
9008    int *retPtr=ret->getPointer();
9009    for(int i=0;i<nbOfElement;i++)
9010      if(!tmp[i])
9011        retPtr[j++]=i;
9012    return ret;
9013 }
9014
9015 /*!
9016  * Returns a new DataArrayInt containing elements of \a this one-dimensional missing
9017  * from an \a other one-dimensional array.
9018  *  \param [in] other - a DataArrayInt containing elements not to include in the result array.
9019  *  \return DataArrayInt * - a new instance of DataArrayInt with one component. The
9020  *         caller is to delete this array using decrRef() as it is no more needed.
9021  *  \throw If \a other is NULL.
9022  *  \throw If \a other is not allocated.
9023  *  \throw If \a other->getNumberOfComponents() != 1.
9024  *  \throw If \a this is not allocated.
9025  *  \throw If \a this->getNumberOfComponents() != 1.
9026  *  \sa DataArrayInt::buildSubstractionOptimized()
9027  */
9028 DataArrayInt *DataArrayInt::buildSubstraction(const DataArrayInt *other) const throw(INTERP_KERNEL::Exception)
9029 {
9030   if(!other)
9031     throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstraction : DataArrayInt pointer in input is NULL !");
9032   checkAllocated();
9033   other->checkAllocated();
9034   if(getNumberOfComponents()!=1)
9035      throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstraction : only single component allowed !");
9036   if(other->getNumberOfComponents()!=1)
9037      throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstraction : only single component allowed for other type !");
9038   const int *pt=getConstPointer();
9039   int nbOfTuples=getNumberOfTuples();
9040   std::set<int> s1(pt,pt+nbOfTuples);
9041   pt=other->getConstPointer();
9042   nbOfTuples=other->getNumberOfTuples();
9043   std::set<int> s2(pt,pt+nbOfTuples);
9044   std::vector<int> r;
9045   std::set_difference(s1.begin(),s1.end(),s2.begin(),s2.end(),std::back_insert_iterator< std::vector<int> >(r));
9046   DataArrayInt *ret=DataArrayInt::New();
9047   ret->alloc((int)r.size(),1);
9048   std::copy(r.begin(),r.end(),ret->getPointer());
9049   return ret;
9050 }
9051
9052 /*!
9053  * \a this is expected to have one component and to be sorted ascendingly (as for \a other).
9054  * \a other is expected to be a part of \a this. If not DataArrayInt::buildSubstraction should be called instead.
9055  * 
9056  * \param [in] other an array with one component and expected to be sorted ascendingly.
9057  * \ret list of ids in \a this but not in \a other.
9058  * \sa DataArrayInt::buildSubstraction
9059  */
9060 DataArrayInt *DataArrayInt::buildSubstractionOptimized(const DataArrayInt *other) const throw(INTERP_KERNEL::Exception)
9061 {
9062   static const char *MSG="DataArrayInt::buildSubstractionOptimized : only single component allowed !";
9063   if(!other) throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstractionOptimized : NULL input array !");
9064   checkAllocated(); other->checkAllocated();
9065   if(getNumberOfComponents()!=1) throw INTERP_KERNEL::Exception(MSG);
9066   if(other->getNumberOfComponents()!=1) throw INTERP_KERNEL::Exception(MSG);
9067   const int *pt1Bg(begin()),*pt1End(end()),*pt2Bg(other->begin()),*pt2End(other->end()),*work1(pt1Bg),*work2(pt2Bg);
9068   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
9069   for(;work1!=pt1End;work1++)
9070     {
9071       if(work2!=pt2End && *work1==*work2)
9072         work2++;
9073       else
9074         ret->pushBackSilent(*work1);
9075     }
9076   return ret.retn();
9077 }
9078
9079
9080 /*!
9081  * Returns a new DataArrayInt which contains all elements of \a this and a given
9082  * one-dimensional arrays. The result array does not contain any duplicates
9083  * and its values are sorted in ascending order.
9084  *  \param [in] other - an array to unite with \a this one.
9085  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
9086  *         array using decrRef() as it is no more needed.
9087  *  \throw If \a this or \a other is not allocated.
9088  *  \throw If \a this->getNumberOfComponents() != 1.
9089  *  \throw If \a other->getNumberOfComponents() != 1.
9090  */
9091 DataArrayInt *DataArrayInt::buildUnion(const DataArrayInt *other) const throw(INTERP_KERNEL::Exception)
9092 {
9093   std::vector<const DataArrayInt *>arrs(2);
9094   arrs[0]=this; arrs[1]=other;
9095   return BuildUnion(arrs);
9096 }
9097
9098
9099 /*!
9100  * Returns a new DataArrayInt which contains elements present in both \a this and a given
9101  * one-dimensional arrays. The result array does not contain any duplicates
9102  * and its values are sorted in ascending order.
9103  *  \param [in] other - an array to intersect with \a this one.
9104  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
9105  *         array using decrRef() as it is no more needed.
9106  *  \throw If \a this or \a other is not allocated.
9107  *  \throw If \a this->getNumberOfComponents() != 1.
9108  *  \throw If \a other->getNumberOfComponents() != 1.
9109  */
9110 DataArrayInt *DataArrayInt::buildIntersection(const DataArrayInt *other) const throw(INTERP_KERNEL::Exception)
9111 {
9112   std::vector<const DataArrayInt *>arrs(2);
9113   arrs[0]=this; arrs[1]=other;
9114   return BuildIntersection(arrs);
9115 }
9116
9117 /*!
9118  * This method can be applied on allocated with one component DataArrayInt instance.
9119  * This method is typically relevant for sorted arrays. All consecutive duplicated items in \a this will appear only once in returned DataArrayInt instance.
9120  * 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]
9121  * 
9122  * \return a newly allocated array that contain the result of the unique operation applied on \a this.
9123  * \throw if \a this is not allocated or if \a this has not exactly one component.
9124  */
9125 DataArrayInt *DataArrayInt::buildUnique() const throw(INTERP_KERNEL::Exception)
9126 {
9127   checkAllocated();
9128   if(getNumberOfComponents()!=1)
9129      throw INTERP_KERNEL::Exception("DataArrayInt::buildUnique : only single component allowed !");
9130   int nbOfTuples=getNumberOfTuples();
9131   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp=deepCpy();
9132   int *data=tmp->getPointer();
9133   int *last=std::unique(data,data+nbOfTuples);
9134   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
9135   ret->alloc(std::distance(data,last),1);
9136   std::copy(data,last,ret->getPointer());
9137   return ret.retn();
9138 }
9139
9140 /*!
9141  * Returns a new DataArrayInt which contains size of every of groups described by \a this
9142  * "index" array. Such "index" array is returned for example by 
9143  * \ref ParaMEDMEM::MEDCouplingUMesh::buildDescendingConnectivity
9144  * "MEDCouplingUMesh::buildDescendingConnectivity" and
9145  * \ref ParaMEDMEM::MEDCouplingUMesh::getNodalConnectivityIndex
9146  * "MEDCouplingUMesh::getNodalConnectivityIndex" etc.
9147  * This method preforms the reverse operation of DataArrayInt::computeOffsets2.
9148  *  \return DataArrayInt * - a new instance of DataArrayInt, whose number of tuples
9149  *          equals to \a this->getNumberOfComponents() - 1, and number of components is 1.
9150  *          The caller is to delete this array using decrRef() as it is no more needed. 
9151  *  \throw If \a this is not allocated.
9152  *  \throw If \a this->getNumberOfComponents() != 1.
9153  *  \throw If \a this->getNumberOfTuples() < 2.
9154  *
9155  *  \b Example: <br> 
9156  *         - this contains [1,3,6,7,7,9,15]
9157  *         - result array contains [2,3,1,0,2,6],
9158  *          where 2 = 3 - 1, 3 = 6 - 3, 1 = 7 - 6 etc.
9159  *
9160  * \sa DataArrayInt::computeOffsets2
9161  */
9162 DataArrayInt *DataArrayInt::deltaShiftIndex() const throw(INTERP_KERNEL::Exception)
9163 {
9164   checkAllocated();
9165   if(getNumberOfComponents()!=1)
9166      throw INTERP_KERNEL::Exception("DataArrayInt::deltaShiftIndex : only single component allowed !");
9167   int nbOfTuples=getNumberOfTuples();
9168   if(nbOfTuples<2)
9169     throw INTERP_KERNEL::Exception("DataArrayInt::deltaShiftIndex : 1 tuple at least must be present in 'this' !");
9170   const int *ptr=getConstPointer();
9171   DataArrayInt *ret=DataArrayInt::New();
9172   ret->alloc(nbOfTuples-1,1);
9173   int *out=ret->getPointer();
9174   std::transform(ptr+1,ptr+nbOfTuples,ptr,out,std::minus<int>());
9175   return ret;
9176 }
9177
9178 /*!
9179  * Modifies \a this one-dimensional array so that value of each element \a x
9180  * of \a this array (\a a) is computed as \f$ x_i = \sum_{j=0}^{i-1} a[ j ] \f$.
9181  * Or: for each i>0 new[i]=new[i-1]+old[i-1] for i==0 new[i]=0. Number of tuples
9182  * and components remains the same.<br>
9183  * This method is useful for allToAllV in MPI with contiguous policy. This method
9184  * differs from computeOffsets2() in that the number of tuples is \b not changed by
9185  * this one.
9186  *  \throw If \a this is not allocated.
9187  *  \throw If \a this->getNumberOfComponents() != 1.
9188  *
9189  *  \b Example: <br>
9190  *          - Before \a this contains [3,5,1,2,0,8]
9191  *          - After \a this contains  [0,3,8,9,11,11]<br>
9192  *          Note that the last element 19 = 11 + 8 is missing because size of \a this
9193  *          array is retained and thus there is no space to store the last element.
9194  */
9195 void DataArrayInt::computeOffsets() throw(INTERP_KERNEL::Exception)
9196 {
9197   checkAllocated();
9198   if(getNumberOfComponents()!=1)
9199      throw INTERP_KERNEL::Exception("DataArrayInt::computeOffsets : only single component allowed !");
9200   int nbOfTuples=getNumberOfTuples();
9201   if(nbOfTuples==0)
9202     return ;
9203   int *work=getPointer();
9204   int tmp=work[0];
9205   work[0]=0;
9206   for(int i=1;i<nbOfTuples;i++)
9207     {
9208       int tmp2=work[i];
9209       work[i]=work[i-1]+tmp;
9210       tmp=tmp2;
9211     }
9212   declareAsNew();
9213 }
9214
9215
9216 /*!
9217  * Modifies \a this one-dimensional array so that value of each element \a x
9218  * of \a this array (\a a) is computed as \f$ x_i = \sum_{j=0}^{i-1} a[ j ] \f$.
9219  * Or: for each i>0 new[i]=new[i-1]+old[i-1] for i==0 new[i]=0. Number
9220  * components remains the same and number of tuples is inceamented by one.<br>
9221  * This method is useful for allToAllV in MPI with contiguous policy. This method
9222  * differs from computeOffsets() in that the number of tuples is changed by this one.
9223  * This method preforms the reverse operation of DataArrayInt::deltaShiftIndex.
9224  *  \throw If \a this is not allocated.
9225  *  \throw If \a this->getNumberOfComponents() != 1.
9226  *
9227  *  \b Example: <br>
9228  *          - Before \a this contains [3,5,1,2,0,8]
9229  *          - After \a this contains  [0,3,8,9,11,11,19]<br>
9230  * \sa DataArrayInt::deltaShiftIndex
9231  */
9232 void DataArrayInt::computeOffsets2() throw(INTERP_KERNEL::Exception)
9233 {
9234   checkAllocated();
9235   if(getNumberOfComponents()!=1)
9236     throw INTERP_KERNEL::Exception("DataArrayInt::computeOffsets2 : only single component allowed !");
9237   int nbOfTuples=getNumberOfTuples();
9238   int *ret=(int *)malloc((nbOfTuples+1)*sizeof(int));
9239   if(nbOfTuples==0)
9240     return ;
9241   const int *work=getConstPointer();
9242   ret[0]=0;
9243   for(int i=0;i<nbOfTuples;i++)
9244     ret[i+1]=work[i]+ret[i];
9245   useArray(ret,true,C_DEALLOC,nbOfTuples+1,1);
9246   declareAsNew();
9247 }
9248
9249 /*!
9250  * Returns two new DataArrayInt instances whose contents is computed from that of \a this and \a listOfIds arrays as follows.
9251  * \a this is expected to be an offset format ( as returned by DataArrayInt::computeOffsets2 ) that is to say with one component
9252  * and ** sorted strictly increasingly **. \a listOfIds is expected to be sorted ascendingly (not strictly needed for \a listOfIds).
9253  * This methods searches in \a this, considered as a set of contiguous \c this->getNumberOfComponents() ranges, all ids in \a listOfIds
9254  * filling completely one of the ranges in \a this.
9255  *
9256  * \param [in] listOfIds a list of ids that has to be sorted ascendingly.
9257  * \param [out] rangeIdsFetched the range ids fetched
9258  * \param [out] idsInInputListThatFetch contains the list of ids in \a listOfIds that are \b fully included in a range in \a this. So
9259  *              \a idsInInputListThatFetch is a part of input \a listOfIds.
9260  *
9261  * \sa DataArrayInt::computeOffsets2
9262  *
9263  *  \b Example: <br>
9264  *          - \a this : [0,3,7,9,15,18]
9265  *          - \a listOfIds contains  [0,1,2,3,7,8,15,16,17]
9266  *          - \a rangeIdsFetched result array: [0,2,4]
9267  *          - \a idsInInputListThatFetch result array: [0,1,2,7,8,15,16,17]
9268  * In this example id 3 in input \a listOfIds is alone so it do not appear in output \a idsInInputListThatFetch.
9269  * <br>
9270  */
9271 void DataArrayInt::searchRangesInListOfIds(const DataArrayInt *listOfIds, DataArrayInt *& rangeIdsFetched, DataArrayInt *& idsInInputListThatFetch) const throw(INTERP_KERNEL::Exception)
9272 {
9273   if(!listOfIds)
9274     throw INTERP_KERNEL::Exception("DataArrayInt::searchRangesInListOfIds : input list of ids is null !");
9275   listOfIds->checkAllocated(); checkAllocated();
9276   if(listOfIds->getNumberOfComponents()!=1)
9277     throw INTERP_KERNEL::Exception("DataArrayInt::searchRangesInListOfIds : input list of ids must have exactly one component !");
9278   if(getNumberOfComponents()!=1)
9279     throw INTERP_KERNEL::Exception("DataArrayInt::searchRangesInListOfIds : this must have exactly one component !");
9280   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret0=DataArrayInt::New(); ret0->alloc(0,1);
9281   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret1=DataArrayInt::New(); ret1->alloc(0,1);
9282   const int *tupEnd(listOfIds->end()),*offBg(begin()),*offEnd(end()-1);
9283   const int *tupPtr(listOfIds->begin()),*offPtr(offBg);
9284   while(tupPtr!=tupEnd && offPtr!=offEnd)
9285     {
9286       if(*tupPtr==*offPtr)
9287         {
9288           int i=offPtr[0];
9289           while(i<offPtr[1] && *tupPtr==i && tupPtr!=tupEnd) { i++; tupPtr++; }
9290           if(i==offPtr[1])
9291             {
9292               ret0->pushBackSilent((int)std::distance(offBg,offPtr));
9293               ret1->pushBackValsSilent(tupPtr-(offPtr[1]-offPtr[0]),tupPtr);
9294               offPtr++;
9295             }
9296         }
9297       else
9298         { if(*tupPtr<*offPtr) tupPtr++; else offPtr++; }
9299     }
9300   rangeIdsFetched=ret0.retn();
9301   idsInInputListThatFetch=ret1.retn();
9302 }
9303
9304 /*!
9305  * Returns a new DataArrayInt whose contents is computed from that of \a this and \a
9306  * offsets arrays as follows. \a offsets is a one-dimensional array considered as an
9307  * "index" array of a "iota" array, thus, whose each element gives an index of a group
9308  * beginning within the "iota" array. And \a this is a one-dimensional array
9309  * considered as a selector of groups described by \a offsets to include into the result array.
9310  *  \throw If \a offsets is NULL.
9311  *  \throw If \a offsets is not allocated.
9312  *  \throw If \a offsets->getNumberOfComponents() != 1.
9313  *  \throw If \a offsets is not monotonically increasing.
9314  *  \throw If \a this is not allocated.
9315  *  \throw If \a this->getNumberOfComponents() != 1.
9316  *  \throw If any element of \a this is not a valid index for \a offsets array.
9317  *
9318  *  \b Example: <br>
9319  *          - \a this: [0,2,3]
9320  *          - \a offsets: [0,3,6,10,14,20]
9321  *          - result array: [0,1,2,6,7,8,9,10,11,12,13] == <br>
9322  *            \c range(0,3) + \c range(6,10) + \c range(10,14) ==<br>
9323  *            \c range( \a offsets[ \a this[0] ], offsets[ \a this[0]+1 ]) + 
9324  *            \c range( \a offsets[ \a this[1] ], offsets[ \a this[1]+1 ]) + 
9325  *            \c range( \a offsets[ \a this[2] ], offsets[ \a this[2]+1 ])
9326  */
9327 DataArrayInt *DataArrayInt::buildExplicitArrByRanges(const DataArrayInt *offsets) const throw(INTERP_KERNEL::Exception)
9328 {
9329   if(!offsets)
9330     throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrByRanges : DataArrayInt pointer in input is NULL !");
9331   checkAllocated();
9332   if(getNumberOfComponents()!=1)
9333      throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrByRanges : only single component allowed !");
9334   offsets->checkAllocated();
9335   if(offsets->getNumberOfComponents()!=1)
9336      throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrByRanges : input array should have only single component !");
9337   int othNbTuples=offsets->getNumberOfTuples()-1;
9338   int nbOfTuples=getNumberOfTuples();
9339   int retNbOftuples=0;
9340   const int *work=getConstPointer();
9341   const int *offPtr=offsets->getConstPointer();
9342   for(int i=0;i<nbOfTuples;i++)
9343     {
9344       int val=work[i];
9345       if(val>=0 && val<othNbTuples)
9346         {
9347           int delta=offPtr[val+1]-offPtr[val];
9348           if(delta>=0)
9349             retNbOftuples+=delta;
9350           else
9351             {
9352               std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrByRanges : Tuple #" << val << " of offset array has a delta < 0 !";
9353               throw INTERP_KERNEL::Exception(oss.str().c_str());
9354             }
9355         }
9356       else
9357         {
9358           std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrByRanges : Tuple #" << i << " in this contains " << val;
9359           oss << " whereas offsets array is of size " << othNbTuples+1 << " !";
9360           throw INTERP_KERNEL::Exception(oss.str().c_str());
9361         }
9362     }
9363   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
9364   ret->alloc(retNbOftuples,1);
9365   int *retPtr=ret->getPointer();
9366   for(int i=0;i<nbOfTuples;i++)
9367     {
9368       int val=work[i];
9369       int start=offPtr[val];
9370       int off=offPtr[val+1]-start;
9371       for(int j=0;j<off;j++,retPtr++)
9372         *retPtr=start+j;
9373     }
9374   return ret.retn();
9375 }
9376
9377 /*!
9378  * 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.
9379  * 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
9380  * in tuple **i** of returned DataArrayInt.
9381  * If ranges overlapped (in theory it should not) this method do not detect it and always returns the first range.
9382  *
9383  * 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)]
9384  * The return DataArrayInt will contain : **[0,4,1,2,2,3]**
9385  * 
9386  * \param [in] ranges typically come from output of MEDCouplingUMesh::ComputeRangesFromTypeDistribution. Each range is specified like this : 1st component is
9387  *             for lower value included and 2nd component is the upper value of corresponding range **excluded**.
9388  * \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
9389  *        is thrown if no ranges in \a ranges contains value in \a this.
9390  * 
9391  * \sa DataArrayInt::findIdInRangeForEachTuple
9392  */
9393 DataArrayInt *DataArrayInt::findRangeIdForEachTuple(const DataArrayInt *ranges) const throw(INTERP_KERNEL::Exception)
9394 {
9395   if(!ranges)
9396     throw INTERP_KERNEL::Exception("DataArrayInt::findRangeIdForEachTuple : null input pointer !");
9397   if(ranges->getNumberOfComponents()!=2)
9398     throw INTERP_KERNEL::Exception("DataArrayInt::findRangeIdForEachTuple : input DataArrayInt instance should have 2 components !");
9399   checkAllocated();
9400   if(getNumberOfComponents()!=1)
9401     throw INTERP_KERNEL::Exception("DataArrayInt::findRangeIdForEachTuple : this should have only one component !");
9402   int nbTuples=getNumberOfTuples();
9403   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbTuples,1);
9404   int nbOfRanges=ranges->getNumberOfTuples();
9405   const int *rangesPtr=ranges->getConstPointer();
9406   int *retPtr=ret->getPointer();
9407   const int *inPtr=getConstPointer();
9408   for(int i=0;i<nbTuples;i++,retPtr++)
9409     {
9410       int val=inPtr[i];
9411       bool found=false;
9412       for(int j=0;j<nbOfRanges && !found;j++)
9413         if(val>=rangesPtr[2*j] && val<rangesPtr[2*j+1])
9414           { *retPtr=j; found=true; }
9415       if(found)
9416         continue;
9417       else
9418         {
9419           std::ostringstream oss; oss << "DataArrayInt::findRangeIdForEachTuple : tuple #" << i << " not found by any ranges !";
9420           throw INTERP_KERNEL::Exception(oss.str().c_str());
9421         }
9422     }
9423   return ret.retn();
9424 }
9425
9426 /*!
9427  * 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.
9428  * 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
9429  * in tuple **i** of returned DataArrayInt.
9430  * If ranges overlapped (in theory it should not) this method do not detect it and always returns the sub position of the first range.
9431  *
9432  * 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)]
9433  * The return DataArrayInt will contain : **[1,2,4,0,2,2]**
9434  * This method is often called in pair with DataArrayInt::findRangeIdForEachTuple method.
9435  * 
9436  * \param [in] ranges typically come from output of MEDCouplingUMesh::ComputeRangesFromTypeDistribution. Each range is specified like this : 1st component is
9437  *             for lower value included and 2nd component is the upper value of corresponding range **excluded**.
9438  * \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
9439  *        is thrown if no ranges in \a ranges contains value in \a this.
9440  * \sa DataArrayInt::findRangeIdForEachTuple
9441  */
9442 DataArrayInt *DataArrayInt::findIdInRangeForEachTuple(const DataArrayInt *ranges) const throw(INTERP_KERNEL::Exception)
9443 {
9444   if(!ranges)
9445     throw INTERP_KERNEL::Exception("DataArrayInt::findIdInRangeForEachTuple : null input pointer !");
9446   if(ranges->getNumberOfComponents()!=2)
9447     throw INTERP_KERNEL::Exception("DataArrayInt::findIdInRangeForEachTuple : input DataArrayInt instance should have 2 components !");
9448   checkAllocated();
9449   if(getNumberOfComponents()!=1)
9450     throw INTERP_KERNEL::Exception("DataArrayInt::findIdInRangeForEachTuple : this should have only one component !");
9451   int nbTuples=getNumberOfTuples();
9452   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbTuples,1);
9453   int nbOfRanges=ranges->getNumberOfTuples();
9454   const int *rangesPtr=ranges->getConstPointer();
9455   int *retPtr=ret->getPointer();
9456   const int *inPtr=getConstPointer();
9457   for(int i=0;i<nbTuples;i++,retPtr++)
9458     {
9459       int val=inPtr[i];
9460       bool found=false;
9461       for(int j=0;j<nbOfRanges && !found;j++)
9462         if(val>=rangesPtr[2*j] && val<rangesPtr[2*j+1])
9463           { *retPtr=val-rangesPtr[2*j]; found=true; }
9464       if(found)
9465         continue;
9466       else
9467         {
9468           std::ostringstream oss; oss << "DataArrayInt::findIdInRangeForEachTuple : tuple #" << i << " not found by any ranges !";
9469           throw INTERP_KERNEL::Exception(oss.str().c_str());
9470         }
9471     }
9472   return ret.retn();
9473 }
9474
9475 /*!
9476  * 
9477  * \param [in] nbTimes specifies the nb of times each tuples in \a this will be duplicated contiguouly in returned DataArrayInt instance.
9478  *             \a nbTimes  should be at least equal to 1.
9479  * \return a newly allocated DataArrayInt having one component and number of tuples equal to \a nbTimes * \c this->getNumberOfTuples.
9480  * \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.
9481  */
9482 DataArrayInt *DataArrayInt::duplicateEachTupleNTimes(int nbTimes) const throw(INTERP_KERNEL::Exception)
9483 {
9484   checkAllocated();
9485   if(getNumberOfComponents()!=1)
9486     throw INTERP_KERNEL::Exception("DataArrayInt::duplicateEachTupleNTimes : this should have only one component !");
9487   if(nbTimes<1)
9488     throw INTERP_KERNEL::Exception("DataArrayInt::duplicateEachTupleNTimes : nb times should be >= 1 !");
9489   int nbTuples=getNumberOfTuples();
9490   const int *inPtr=getConstPointer();
9491   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbTimes*nbTuples,1);
9492   int *retPtr=ret->getPointer();
9493   for(int i=0;i<nbTuples;i++,inPtr++)
9494     {
9495       int val=*inPtr;
9496       for(int j=0;j<nbTimes;j++,retPtr++)
9497         *retPtr=val;
9498     }
9499   ret->copyStringInfoFrom(*this);
9500   return ret.retn();
9501 }
9502
9503 /*!
9504  * This method returns all different values found in \a this. This method throws if \a this has not been allocated.
9505  * But the number of components can be different from one.
9506  * \return a newly allocated array (that should be dealt by the caller) containing different values in \a this.
9507  */
9508 DataArrayInt *DataArrayInt::getDifferentValues() const throw(INTERP_KERNEL::Exception)
9509 {
9510   checkAllocated();
9511   std::set<int> ret;
9512   ret.insert(begin(),end());
9513   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret2=DataArrayInt::New(); ret2->alloc((int)ret.size(),1);
9514   std::copy(ret.begin(),ret.end(),ret2->getPointer());
9515   return ret2.retn();
9516 }
9517
9518 /*!
9519  * This method is a refinement of DataArrayInt::getDifferentValues because it returns not only different values in \a this but also, for each of
9520  * them it tells which tuple id have this id.
9521  * This method works only on arrays with one component (if it is not the case call DataArrayInt::rearrange(1) ).
9522  * This method returns two arrays having same size.
9523  * 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.
9524  * 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]]
9525  */
9526 std::vector<DataArrayInt *> DataArrayInt::partitionByDifferentValues(std::vector<int>& differentIds) const throw(INTERP_KERNEL::Exception)
9527 {
9528   checkAllocated();
9529   if(getNumberOfComponents()!=1)
9530     throw INTERP_KERNEL::Exception("DataArrayInt::partitionByDifferentValues : this should have only one component !");
9531   int id=0;
9532   std::map<int,int> m,m2,m3;
9533   for(const int *w=begin();w!=end();w++)
9534     m[*w]++;
9535   differentIds.resize(m.size());
9536   std::vector<DataArrayInt *> ret(m.size());
9537   std::vector<int *> retPtr(m.size());
9538   for(std::map<int,int>::const_iterator it=m.begin();it!=m.end();it++,id++)
9539     {
9540       m2[(*it).first]=id;
9541       ret[id]=DataArrayInt::New();
9542       ret[id]->alloc((*it).second,1);
9543       retPtr[id]=ret[id]->getPointer();
9544       differentIds[id]=(*it).first;
9545     }
9546   id=0;
9547   for(const int *w=begin();w!=end();w++,id++)
9548     {
9549       retPtr[m2[*w]][m3[*w]++]=id;
9550     }
9551   return ret;
9552 }
9553
9554 /*!
9555  * Returns a new DataArrayInt that is a sum of two given arrays. There are 3
9556  * valid cases.
9557  * 1.  The arrays have same number of tuples and components. Then each value of
9558  *   the result array (_a_) is a sum of the corresponding values of \a a1 and \a a2,
9559  *   i.e.: _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ i, j ].
9560  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
9561  *   component. Then
9562  *   _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ i, 0 ].
9563  * 3.  The arrays have same number of components and one array, say _a2_, has one
9564  *   tuple. Then
9565  *   _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ 0, j ].
9566  *
9567  * Info on components is copied either from the first array (in the first case) or from
9568  * the array with maximal number of elements (getNbOfElems()).
9569  *  \param [in] a1 - an array to sum up.
9570  *  \param [in] a2 - another array to sum up.
9571  *  \return DataArrayInt * - the new instance of DataArrayInt.
9572  *          The caller is to delete this result array using decrRef() as it is no more
9573  *          needed.
9574  *  \throw If either \a a1 or \a a2 is NULL.
9575  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
9576  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
9577  *         none of them has number of tuples or components equal to 1.
9578  */
9579 DataArrayInt *DataArrayInt::Add(const DataArrayInt *a1, const DataArrayInt *a2) throw(INTERP_KERNEL::Exception)
9580 {
9581   if(!a1 || !a2)
9582     throw INTERP_KERNEL::Exception("DataArrayInt::Add : input DataArrayInt instance is NULL !");
9583   int nbOfTuple=a1->getNumberOfTuples();
9584   int nbOfTuple2=a2->getNumberOfTuples();
9585   int nbOfComp=a1->getNumberOfComponents();
9586   int nbOfComp2=a2->getNumberOfComponents();
9587   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=0;
9588   if(nbOfTuple==nbOfTuple2)
9589     {
9590       if(nbOfComp==nbOfComp2)
9591         {
9592           ret=DataArrayInt::New();
9593           ret->alloc(nbOfTuple,nbOfComp);
9594           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::plus<int>());
9595           ret->copyStringInfoFrom(*a1);
9596         }
9597       else
9598         {
9599           int nbOfCompMin,nbOfCompMax;
9600           const DataArrayInt *aMin, *aMax;
9601           if(nbOfComp>nbOfComp2)
9602             {
9603               nbOfCompMin=nbOfComp2; nbOfCompMax=nbOfComp;
9604               aMin=a2; aMax=a1;
9605             }
9606           else
9607             {
9608               nbOfCompMin=nbOfComp; nbOfCompMax=nbOfComp2;
9609               aMin=a1; aMax=a2;
9610             }
9611           if(nbOfCompMin==1)
9612             {
9613               ret=DataArrayInt::New();
9614               ret->alloc(nbOfTuple,nbOfCompMax);
9615               const int *aMinPtr=aMin->getConstPointer();
9616               const int *aMaxPtr=aMax->getConstPointer();
9617               int *res=ret->getPointer();
9618               for(int i=0;i<nbOfTuple;i++)
9619                 res=std::transform(aMaxPtr+i*nbOfCompMax,aMaxPtr+(i+1)*nbOfCompMax,res,std::bind2nd(std::plus<int>(),aMinPtr[i]));
9620               ret->copyStringInfoFrom(*aMax);
9621             }
9622           else
9623             throw INTERP_KERNEL::Exception("Nb of components mismatch for array Add !");
9624         }
9625     }
9626   else if((nbOfTuple==1 && nbOfTuple2>1) || (nbOfTuple>1 && nbOfTuple2==1))
9627     {
9628       if(nbOfComp==nbOfComp2)
9629         {
9630           int nbOfTupleMax=std::max(nbOfTuple,nbOfTuple2);
9631           const DataArrayInt *aMin=nbOfTuple>nbOfTuple2?a2:a1;
9632           const DataArrayInt *aMax=nbOfTuple>nbOfTuple2?a1:a2;
9633           const int *aMinPtr=aMin->getConstPointer(),*aMaxPtr=aMax->getConstPointer();
9634           ret=DataArrayInt::New();
9635           ret->alloc(nbOfTupleMax,nbOfComp);
9636           int *res=ret->getPointer();
9637           for(int i=0;i<nbOfTupleMax;i++)
9638             res=std::transform(aMaxPtr+i*nbOfComp,aMaxPtr+(i+1)*nbOfComp,aMinPtr,res,std::plus<int>());
9639           ret->copyStringInfoFrom(*aMax);
9640         }
9641       else
9642         throw INTERP_KERNEL::Exception("Nb of components mismatch for array Add !");
9643     }
9644   else
9645     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Add !");
9646   return ret.retn();
9647 }
9648
9649 /*!
9650  * Adds values of another DataArrayInt to values of \a this one. There are 3
9651  * valid cases.
9652  * 1.  The arrays have same number of tuples and components. Then each value of
9653  *   \a other array is added to the corresponding value of \a this array, i.e.:
9654  *   _a_ [ i, j ] += _other_ [ i, j ].
9655  * 2.  The arrays have same number of tuples and \a other array has one component. Then
9656  *   _a_ [ i, j ] += _other_ [ i, 0 ].
9657  * 3.  The arrays have same number of components and \a other array has one tuple. Then
9658  *   _a_ [ i, j ] += _a2_ [ 0, j ].
9659  *
9660  *  \param [in] other - an array to add to \a this one.
9661  *  \throw If \a other is NULL.
9662  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
9663  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
9664  *         \a other has number of both tuples and components not equal to 1.
9665  */
9666 void DataArrayInt::addEqual(const DataArrayInt *other) throw(INTERP_KERNEL::Exception)
9667 {
9668   if(!other)
9669     throw INTERP_KERNEL::Exception("DataArrayInt::addEqual : input DataArrayInt instance is NULL !");
9670   const char *msg="Nb of tuples mismatch for DataArrayInt::addEqual  !";
9671   checkAllocated(); other->checkAllocated();
9672   int nbOfTuple=getNumberOfTuples();
9673   int nbOfTuple2=other->getNumberOfTuples();
9674   int nbOfComp=getNumberOfComponents();
9675   int nbOfComp2=other->getNumberOfComponents();
9676   if(nbOfTuple==nbOfTuple2)
9677     {
9678       if(nbOfComp==nbOfComp2)
9679         {
9680           std::transform(begin(),end(),other->begin(),getPointer(),std::plus<int>());
9681         }
9682       else if(nbOfComp2==1)
9683         {
9684           int *ptr=getPointer();
9685           const int *ptrc=other->getConstPointer();
9686           for(int i=0;i<nbOfTuple;i++)
9687             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::plus<int>(),*ptrc++));
9688         }
9689       else
9690         throw INTERP_KERNEL::Exception(msg);
9691     }
9692   else if(nbOfTuple2==1)
9693     {
9694       if(nbOfComp2==nbOfComp)
9695         {
9696           int *ptr=getPointer();
9697           const int *ptrc=other->getConstPointer();
9698           for(int i=0;i<nbOfTuple;i++)
9699             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::plus<int>());
9700         }
9701       else
9702         throw INTERP_KERNEL::Exception(msg);
9703     }
9704   else
9705     throw INTERP_KERNEL::Exception(msg);
9706   declareAsNew();
9707 }
9708
9709 /*!
9710  * Returns a new DataArrayInt that is a subtraction of two given arrays. There are 3
9711  * valid cases.
9712  * 1.  The arrays have same number of tuples and components. Then each value of
9713  *   the result array (_a_) is a subtraction of the corresponding values of \a a1 and
9714  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ i, j ].
9715  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
9716  *   component. Then
9717  *   _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ i, 0 ].
9718  * 3.  The arrays have same number of components and one array, say _a2_, has one
9719  *   tuple. Then
9720  *   _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ 0, j ].
9721  *
9722  * Info on components is copied either from the first array (in the first case) or from
9723  * the array with maximal number of elements (getNbOfElems()).
9724  *  \param [in] a1 - an array to subtract from.
9725  *  \param [in] a2 - an array to subtract.
9726  *  \return DataArrayInt * - the new instance of DataArrayInt.
9727  *          The caller is to delete this result array using decrRef() as it is no more
9728  *          needed.
9729  *  \throw If either \a a1 or \a a2 is NULL.
9730  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
9731  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
9732  *         none of them has number of tuples or components equal to 1.
9733  */
9734 DataArrayInt *DataArrayInt::Substract(const DataArrayInt *a1, const DataArrayInt *a2) throw(INTERP_KERNEL::Exception)
9735 {
9736   if(!a1 || !a2)
9737     throw INTERP_KERNEL::Exception("DataArrayInt::Substract : input DataArrayInt instance is NULL !");
9738   int nbOfTuple1=a1->getNumberOfTuples();
9739   int nbOfTuple2=a2->getNumberOfTuples();
9740   int nbOfComp1=a1->getNumberOfComponents();
9741   int nbOfComp2=a2->getNumberOfComponents();
9742   if(nbOfTuple2==nbOfTuple1)
9743     {
9744       if(nbOfComp1==nbOfComp2)
9745         {
9746           MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
9747           ret->alloc(nbOfTuple2,nbOfComp1);
9748           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::minus<int>());
9749           ret->copyStringInfoFrom(*a1);
9750           return ret.retn();
9751         }
9752       else if(nbOfComp2==1)
9753         {
9754           MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
9755           ret->alloc(nbOfTuple1,nbOfComp1);
9756           const int *a2Ptr=a2->getConstPointer();
9757           const int *a1Ptr=a1->getConstPointer();
9758           int *res=ret->getPointer();
9759           for(int i=0;i<nbOfTuple1;i++)
9760             res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::minus<int>(),a2Ptr[i]));
9761           ret->copyStringInfoFrom(*a1);
9762           return ret.retn();
9763         }
9764       else
9765         {
9766           a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Substract !");
9767           return 0;
9768         }
9769     }
9770   else if(nbOfTuple2==1)
9771     {
9772       a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Substract !");
9773       MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
9774       ret->alloc(nbOfTuple1,nbOfComp1);
9775       const int *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
9776       int *pt=ret->getPointer();
9777       for(int i=0;i<nbOfTuple1;i++)
9778         pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::minus<int>());
9779       ret->copyStringInfoFrom(*a1);
9780       return ret.retn();
9781     }
9782   else
9783     {
9784       a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Substract !");//will always throw an exception
9785       return 0;
9786     }
9787 }
9788
9789 /*!
9790  * Subtract values of another DataArrayInt from values of \a this one. There are 3
9791  * valid cases.
9792  * 1.  The arrays have same number of tuples and components. Then each value of
9793  *   \a other array is subtracted from the corresponding value of \a this array, i.e.:
9794  *   _a_ [ i, j ] -= _other_ [ i, j ].
9795  * 2.  The arrays have same number of tuples and \a other array has one component. Then
9796  *   _a_ [ i, j ] -= _other_ [ i, 0 ].
9797  * 3.  The arrays have same number of components and \a other array has one tuple. Then
9798  *   _a_ [ i, j ] -= _a2_ [ 0, j ].
9799  *
9800  *  \param [in] other - an array to subtract from \a this one.
9801  *  \throw If \a other is NULL.
9802  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
9803  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
9804  *         \a other has number of both tuples and components not equal to 1.
9805  */
9806 void DataArrayInt::substractEqual(const DataArrayInt *other) throw(INTERP_KERNEL::Exception)
9807 {
9808   if(!other)
9809     throw INTERP_KERNEL::Exception("DataArrayInt::substractEqual : input DataArrayInt instance is NULL !");
9810   const char *msg="Nb of tuples mismatch for DataArrayInt::substractEqual  !";
9811   checkAllocated(); other->checkAllocated();
9812   int nbOfTuple=getNumberOfTuples();
9813   int nbOfTuple2=other->getNumberOfTuples();
9814   int nbOfComp=getNumberOfComponents();
9815   int nbOfComp2=other->getNumberOfComponents();
9816   if(nbOfTuple==nbOfTuple2)
9817     {
9818       if(nbOfComp==nbOfComp2)
9819         {
9820           std::transform(begin(),end(),other->begin(),getPointer(),std::minus<int>());
9821         }
9822       else if(nbOfComp2==1)
9823         {
9824           int *ptr=getPointer();
9825           const int *ptrc=other->getConstPointer();
9826           for(int i=0;i<nbOfTuple;i++)
9827             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::minus<int>(),*ptrc++));
9828         }
9829       else
9830         throw INTERP_KERNEL::Exception(msg);
9831     }
9832   else if(nbOfTuple2==1)
9833     {
9834       int *ptr=getPointer();
9835       const int *ptrc=other->getConstPointer();
9836       for(int i=0;i<nbOfTuple;i++)
9837         std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::minus<int>());
9838     }
9839   else
9840     throw INTERP_KERNEL::Exception(msg);
9841   declareAsNew();
9842 }
9843
9844 /*!
9845  * Returns a new DataArrayInt that is a product of two given arrays. There are 3
9846  * valid cases.
9847  * 1.  The arrays have same number of tuples and components. Then each value of
9848  *   the result array (_a_) is a product of the corresponding values of \a a1 and
9849  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ i, j ].
9850  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
9851  *   component. Then
9852  *   _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ i, 0 ].
9853  * 3.  The arrays have same number of components and one array, say _a2_, has one
9854  *   tuple. Then
9855  *   _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ 0, j ].
9856  *
9857  * Info on components is copied either from the first array (in the first case) or from
9858  * the array with maximal number of elements (getNbOfElems()).
9859  *  \param [in] a1 - a factor array.
9860  *  \param [in] a2 - another factor array.
9861  *  \return DataArrayInt * - the new instance of DataArrayInt.
9862  *          The caller is to delete this result array using decrRef() as it is no more
9863  *          needed.
9864  *  \throw If either \a a1 or \a a2 is NULL.
9865  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
9866  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
9867  *         none of them has number of tuples or components equal to 1.
9868  */
9869 DataArrayInt *DataArrayInt::Multiply(const DataArrayInt *a1, const DataArrayInt *a2) throw(INTERP_KERNEL::Exception)
9870 {
9871   if(!a1 || !a2)
9872     throw INTERP_KERNEL::Exception("DataArrayInt::Multiply : input DataArrayInt instance is NULL !");
9873   int nbOfTuple=a1->getNumberOfTuples();
9874   int nbOfTuple2=a2->getNumberOfTuples();
9875   int nbOfComp=a1->getNumberOfComponents();
9876   int nbOfComp2=a2->getNumberOfComponents();
9877   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=0;
9878   if(nbOfTuple==nbOfTuple2)
9879     {
9880       if(nbOfComp==nbOfComp2)
9881         {
9882           ret=DataArrayInt::New();
9883           ret->alloc(nbOfTuple,nbOfComp);
9884           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::multiplies<int>());
9885           ret->copyStringInfoFrom(*a1);
9886         }
9887       else
9888         {
9889           int nbOfCompMin,nbOfCompMax;
9890           const DataArrayInt *aMin, *aMax;
9891           if(nbOfComp>nbOfComp2)
9892             {
9893               nbOfCompMin=nbOfComp2; nbOfCompMax=nbOfComp;
9894               aMin=a2; aMax=a1;
9895             }
9896           else
9897             {
9898               nbOfCompMin=nbOfComp; nbOfCompMax=nbOfComp2;
9899               aMin=a1; aMax=a2;
9900             }
9901           if(nbOfCompMin==1)
9902             {
9903               ret=DataArrayInt::New();
9904               ret->alloc(nbOfTuple,nbOfCompMax);
9905               const int *aMinPtr=aMin->getConstPointer();
9906               const int *aMaxPtr=aMax->getConstPointer();
9907               int *res=ret->getPointer();
9908               for(int i=0;i<nbOfTuple;i++)
9909                 res=std::transform(aMaxPtr+i*nbOfCompMax,aMaxPtr+(i+1)*nbOfCompMax,res,std::bind2nd(std::multiplies<int>(),aMinPtr[i]));
9910               ret->copyStringInfoFrom(*aMax);
9911             }
9912           else
9913             throw INTERP_KERNEL::Exception("Nb of components mismatch for array Multiply !");
9914         }
9915     }
9916   else if((nbOfTuple==1 && nbOfTuple2>1) || (nbOfTuple>1 && nbOfTuple2==1))
9917     {
9918       if(nbOfComp==nbOfComp2)
9919         {
9920           int nbOfTupleMax=std::max(nbOfTuple,nbOfTuple2);
9921           const DataArrayInt *aMin=nbOfTuple>nbOfTuple2?a2:a1;
9922           const DataArrayInt *aMax=nbOfTuple>nbOfTuple2?a1:a2;
9923           const int *aMinPtr=aMin->getConstPointer(),*aMaxPtr=aMax->getConstPointer();
9924           ret=DataArrayInt::New();
9925           ret->alloc(nbOfTupleMax,nbOfComp);
9926           int *res=ret->getPointer();
9927           for(int i=0;i<nbOfTupleMax;i++)
9928             res=std::transform(aMaxPtr+i*nbOfComp,aMaxPtr+(i+1)*nbOfComp,aMinPtr,res,std::multiplies<int>());
9929           ret->copyStringInfoFrom(*aMax);
9930         }
9931       else
9932         throw INTERP_KERNEL::Exception("Nb of components mismatch for array Multiply !");
9933     }
9934   else
9935     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Multiply !");
9936   return ret.retn();
9937 }
9938
9939
9940 /*!
9941  * Multiply values of another DataArrayInt to values of \a this one. There are 3
9942  * valid cases.
9943  * 1.  The arrays have same number of tuples and components. Then each value of
9944  *   \a other array is multiplied to the corresponding value of \a this array, i.e.:
9945  *   _a_ [ i, j ] *= _other_ [ i, j ].
9946  * 2.  The arrays have same number of tuples and \a other array has one component. Then
9947  *   _a_ [ i, j ] *= _other_ [ i, 0 ].
9948  * 3.  The arrays have same number of components and \a other array has one tuple. Then
9949  *   _a_ [ i, j ] *= _a2_ [ 0, j ].
9950  *
9951  *  \param [in] other - an array to multiply to \a this one.
9952  *  \throw If \a other is NULL.
9953  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
9954  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
9955  *         \a other has number of both tuples and components not equal to 1.
9956  */
9957 void DataArrayInt::multiplyEqual(const DataArrayInt *other) throw(INTERP_KERNEL::Exception)
9958 {
9959   if(!other)
9960     throw INTERP_KERNEL::Exception("DataArrayInt::multiplyEqual : input DataArrayInt instance is NULL !");
9961   const char *msg="Nb of tuples mismatch for DataArrayInt::multiplyEqual !";
9962   checkAllocated(); other->checkAllocated();
9963   int nbOfTuple=getNumberOfTuples();
9964   int nbOfTuple2=other->getNumberOfTuples();
9965   int nbOfComp=getNumberOfComponents();
9966   int nbOfComp2=other->getNumberOfComponents();
9967   if(nbOfTuple==nbOfTuple2)
9968     {
9969       if(nbOfComp==nbOfComp2)
9970         {
9971           std::transform(begin(),end(),other->begin(),getPointer(),std::multiplies<int>());
9972         }
9973       else if(nbOfComp2==1)
9974         {
9975           int *ptr=getPointer();
9976           const int *ptrc=other->getConstPointer();
9977           for(int i=0;i<nbOfTuple;i++)
9978             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::multiplies<int>(),*ptrc++));    
9979         }
9980       else
9981         throw INTERP_KERNEL::Exception(msg);
9982     }
9983   else if(nbOfTuple2==1)
9984     {
9985       if(nbOfComp2==nbOfComp)
9986         {
9987           int *ptr=getPointer();
9988           const int *ptrc=other->getConstPointer();
9989           for(int i=0;i<nbOfTuple;i++)
9990             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::multiplies<int>());
9991         }
9992       else
9993         throw INTERP_KERNEL::Exception(msg);
9994     }
9995   else
9996     throw INTERP_KERNEL::Exception(msg);
9997   declareAsNew();
9998 }
9999
10000
10001 /*!
10002  * Returns a new DataArrayInt that is a division of two given arrays. There are 3
10003  * valid cases.
10004  * 1.  The arrays have same number of tuples and components. Then each value of
10005  *   the result array (_a_) is a division of the corresponding values of \a a1 and
10006  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ i, j ].
10007  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
10008  *   component. Then
10009  *   _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ i, 0 ].
10010  * 3.  The arrays have same number of components and one array, say _a2_, has one
10011  *   tuple. Then
10012  *   _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ 0, j ].
10013  *
10014  * Info on components is copied either from the first array (in the first case) or from
10015  * the array with maximal number of elements (getNbOfElems()).
10016  *  \warning No check of division by zero is performed!
10017  *  \param [in] a1 - a numerator array.
10018  *  \param [in] a2 - a denominator array.
10019  *  \return DataArrayInt * - the new instance of DataArrayInt.
10020  *          The caller is to delete this result array using decrRef() as it is no more
10021  *          needed.
10022  *  \throw If either \a a1 or \a a2 is NULL.
10023  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
10024  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
10025  *         none of them has number of tuples or components equal to 1.
10026  */
10027 DataArrayInt *DataArrayInt::Divide(const DataArrayInt *a1, const DataArrayInt *a2) throw(INTERP_KERNEL::Exception)
10028 {
10029   if(!a1 || !a2)
10030     throw INTERP_KERNEL::Exception("DataArrayInt::Divide : input DataArrayInt instance is NULL !");
10031   int nbOfTuple1=a1->getNumberOfTuples();
10032   int nbOfTuple2=a2->getNumberOfTuples();
10033   int nbOfComp1=a1->getNumberOfComponents();
10034   int nbOfComp2=a2->getNumberOfComponents();
10035   if(nbOfTuple2==nbOfTuple1)
10036     {
10037       if(nbOfComp1==nbOfComp2)
10038         {
10039           MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
10040           ret->alloc(nbOfTuple2,nbOfComp1);
10041           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::divides<int>());
10042           ret->copyStringInfoFrom(*a1);
10043           return ret.retn();
10044         }
10045       else if(nbOfComp2==1)
10046         {
10047           MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
10048           ret->alloc(nbOfTuple1,nbOfComp1);
10049           const int *a2Ptr=a2->getConstPointer();
10050           const int *a1Ptr=a1->getConstPointer();
10051           int *res=ret->getPointer();
10052           for(int i=0;i<nbOfTuple1;i++)
10053             res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::divides<int>(),a2Ptr[i]));
10054           ret->copyStringInfoFrom(*a1);
10055           return ret.retn();
10056         }
10057       else
10058         {
10059           a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Divide !");
10060           return 0;
10061         }
10062     }
10063   else if(nbOfTuple2==1)
10064     {
10065       a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Divide !");
10066       MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
10067       ret->alloc(nbOfTuple1,nbOfComp1);
10068       const int *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
10069       int *pt=ret->getPointer();
10070       for(int i=0;i<nbOfTuple1;i++)
10071         pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::divides<int>());
10072       ret->copyStringInfoFrom(*a1);
10073       return ret.retn();
10074     }
10075   else
10076     {
10077       a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Divide !");//will always throw an exception
10078       return 0;
10079     }
10080 }
10081
10082 /*!
10083  * Divide values of \a this array by values of another DataArrayInt. There are 3
10084  * valid cases.
10085  * 1.  The arrays have same number of tuples and components. Then each value of
10086  *    \a this array is divided by the corresponding value of \a other one, i.e.:
10087  *   _a_ [ i, j ] /= _other_ [ i, j ].
10088  * 2.  The arrays have same number of tuples and \a other array has one component. Then
10089  *   _a_ [ i, j ] /= _other_ [ i, 0 ].
10090  * 3.  The arrays have same number of components and \a other array has one tuple. Then
10091  *   _a_ [ i, j ] /= _a2_ [ 0, j ].
10092  *
10093  *  \warning No check of division by zero is performed!
10094  *  \param [in] other - an array to divide \a this one by.
10095  *  \throw If \a other is NULL.
10096  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
10097  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
10098  *         \a other has number of both tuples and components not equal to 1.
10099  */
10100 void DataArrayInt::divideEqual(const DataArrayInt *other) throw(INTERP_KERNEL::Exception)
10101 {
10102   if(!other)
10103     throw INTERP_KERNEL::Exception("DataArrayInt::divideEqual : input DataArrayInt instance is NULL !");
10104   const char *msg="Nb of tuples mismatch for DataArrayInt::divideEqual !";
10105   checkAllocated(); other->checkAllocated();
10106   int nbOfTuple=getNumberOfTuples();
10107   int nbOfTuple2=other->getNumberOfTuples();
10108   int nbOfComp=getNumberOfComponents();
10109   int nbOfComp2=other->getNumberOfComponents();
10110   if(nbOfTuple==nbOfTuple2)
10111     {
10112       if(nbOfComp==nbOfComp2)
10113         {
10114           std::transform(begin(),end(),other->begin(),getPointer(),std::divides<int>());
10115         }
10116       else if(nbOfComp2==1)
10117         {
10118           int *ptr=getPointer();
10119           const int *ptrc=other->getConstPointer();
10120           for(int i=0;i<nbOfTuple;i++)
10121             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::divides<int>(),*ptrc++));
10122         }
10123       else
10124         throw INTERP_KERNEL::Exception(msg);
10125     }
10126   else if(nbOfTuple2==1)
10127     {
10128       if(nbOfComp2==nbOfComp)
10129         {
10130           int *ptr=getPointer();
10131           const int *ptrc=other->getConstPointer();
10132           for(int i=0;i<nbOfTuple;i++)
10133             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::divides<int>());
10134         }
10135       else
10136         throw INTERP_KERNEL::Exception(msg);
10137     }
10138   else
10139     throw INTERP_KERNEL::Exception(msg);
10140   declareAsNew();
10141 }
10142
10143
10144 /*!
10145  * Returns a new DataArrayInt that is a modulus of two given arrays. There are 3
10146  * valid cases.
10147  * 1.  The arrays have same number of tuples and components. Then each value of
10148  *   the result array (_a_) is a division of the corresponding values of \a a1 and
10149  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] % _a2_ [ i, j ].
10150  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
10151  *   component. Then
10152  *   _a_ [ i, j ] = _a1_ [ i, j ] % _a2_ [ i, 0 ].
10153  * 3.  The arrays have same number of components and one array, say _a2_, has one
10154  *   tuple. Then
10155  *   _a_ [ i, j ] = _a1_ [ i, j ] % _a2_ [ 0, j ].
10156  *
10157  * Info on components is copied either from the first array (in the first case) or from
10158  * the array with maximal number of elements (getNbOfElems()).
10159  *  \warning No check of division by zero is performed!
10160  *  \param [in] a1 - a dividend array.
10161  *  \param [in] a2 - a divisor array.
10162  *  \return DataArrayInt * - the new instance of DataArrayInt.
10163  *          The caller is to delete this result array using decrRef() as it is no more
10164  *          needed.
10165  *  \throw If either \a a1 or \a a2 is NULL.
10166  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
10167  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
10168  *         none of them has number of tuples or components equal to 1.
10169  */
10170 DataArrayInt *DataArrayInt::Modulus(const DataArrayInt *a1, const DataArrayInt *a2) throw(INTERP_KERNEL::Exception)
10171 {
10172     if(!a1 || !a2)
10173     throw INTERP_KERNEL::Exception("DataArrayInt::Modulus : input DataArrayInt instance is NULL !");
10174   int nbOfTuple1=a1->getNumberOfTuples();
10175   int nbOfTuple2=a2->getNumberOfTuples();
10176   int nbOfComp1=a1->getNumberOfComponents();
10177   int nbOfComp2=a2->getNumberOfComponents();
10178   if(nbOfTuple2==nbOfTuple1)
10179     {
10180       if(nbOfComp1==nbOfComp2)
10181         {
10182           MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
10183           ret->alloc(nbOfTuple2,nbOfComp1);
10184           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::modulus<int>());
10185           ret->copyStringInfoFrom(*a1);
10186           return ret.retn();
10187         }
10188       else if(nbOfComp2==1)
10189         {
10190           MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
10191           ret->alloc(nbOfTuple1,nbOfComp1);
10192           const int *a2Ptr=a2->getConstPointer();
10193           const int *a1Ptr=a1->getConstPointer();
10194           int *res=ret->getPointer();
10195           for(int i=0;i<nbOfTuple1;i++)
10196             res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::modulus<int>(),a2Ptr[i]));
10197           ret->copyStringInfoFrom(*a1);
10198           return ret.retn();
10199         }
10200       else
10201         {
10202           a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Modulus !");
10203           return 0;
10204         }
10205     }
10206   else if(nbOfTuple2==1)
10207     {
10208       a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Modulus !");
10209       MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
10210       ret->alloc(nbOfTuple1,nbOfComp1);
10211       const int *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
10212       int *pt=ret->getPointer();
10213       for(int i=0;i<nbOfTuple1;i++)
10214         pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::modulus<int>());
10215       ret->copyStringInfoFrom(*a1);
10216       return ret.retn();
10217     }
10218   else
10219     {
10220       a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Modulus !");//will always throw an exception
10221       return 0;
10222     }
10223 }
10224
10225 /*!
10226  * Modify \a this array so that each value becomes a modulus of division of this value by
10227  * a value of another DataArrayInt. There are 3 valid cases.
10228  * 1.  The arrays have same number of tuples and components. Then each value of
10229  *    \a this array is divided by the corresponding value of \a other one, i.e.:
10230  *   _a_ [ i, j ] %= _other_ [ i, j ].
10231  * 2.  The arrays have same number of tuples and \a other array has one component. Then
10232  *   _a_ [ i, j ] %= _other_ [ i, 0 ].
10233  * 3.  The arrays have same number of components and \a other array has one tuple. Then
10234  *   _a_ [ i, j ] %= _a2_ [ 0, j ].
10235  *
10236  *  \warning No check of division by zero is performed!
10237  *  \param [in] other - a divisor array.
10238  *  \throw If \a other is NULL.
10239  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
10240  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
10241  *         \a other has number of both tuples and components not equal to 1.
10242  */
10243 void DataArrayInt::modulusEqual(const DataArrayInt *other) throw(INTERP_KERNEL::Exception)
10244 {
10245   if(!other)
10246     throw INTERP_KERNEL::Exception("DataArrayInt::modulusEqual : input DataArrayInt instance is NULL !");
10247   const char *msg="Nb of tuples mismatch for DataArrayInt::modulusEqual !";
10248   checkAllocated(); other->checkAllocated();
10249   int nbOfTuple=getNumberOfTuples();
10250   int nbOfTuple2=other->getNumberOfTuples();
10251   int nbOfComp=getNumberOfComponents();
10252   int nbOfComp2=other->getNumberOfComponents();
10253   if(nbOfTuple==nbOfTuple2)
10254     {
10255       if(nbOfComp==nbOfComp2)
10256         {
10257           std::transform(begin(),end(),other->begin(),getPointer(),std::modulus<int>());
10258         }
10259       else if(nbOfComp2==1)
10260         {
10261           if(nbOfComp2==nbOfComp)
10262             {
10263               int *ptr=getPointer();
10264               const int *ptrc=other->getConstPointer();
10265               for(int i=0;i<nbOfTuple;i++)
10266                 std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::modulus<int>(),*ptrc++));
10267             }
10268           else
10269             throw INTERP_KERNEL::Exception(msg);
10270         }
10271       else
10272         throw INTERP_KERNEL::Exception(msg);
10273     }
10274   else if(nbOfTuple2==1)
10275     {
10276       int *ptr=getPointer();
10277       const int *ptrc=other->getConstPointer();
10278       for(int i=0;i<nbOfTuple;i++)
10279         std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::modulus<int>());
10280     }
10281   else
10282     throw INTERP_KERNEL::Exception(msg);
10283   declareAsNew();
10284 }
10285
10286 /*!
10287  * Returns a new DataArrayInt that is the result of pow of two given arrays. There are 3
10288  * valid cases.
10289  *
10290  *  \param [in] a1 - an array to pow up.
10291  *  \param [in] a2 - another array to sum up.
10292  *  \return DataArrayInt * - the new instance of DataArrayInt.
10293  *          The caller is to delete this result array using decrRef() as it is no more
10294  *          needed.
10295  *  \throw If either \a a1 or \a a2 is NULL.
10296  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
10297  *  \throw If \a a1->getNumberOfComponents() != 1 or \a a2->getNumberOfComponents() != 1.
10298  *  \throw If there is a negative value in \a a2.
10299  */
10300 DataArrayInt *DataArrayInt::Pow(const DataArrayInt *a1, const DataArrayInt *a2) throw(INTERP_KERNEL::Exception)
10301 {
10302   if(!a1 || !a2)
10303     throw INTERP_KERNEL::Exception("DataArrayInt::Pow : at least one of input instances is null !");
10304   int nbOfTuple=a1->getNumberOfTuples();
10305   int nbOfTuple2=a2->getNumberOfTuples();
10306   int nbOfComp=a1->getNumberOfComponents();
10307   int nbOfComp2=a2->getNumberOfComponents();
10308   if(nbOfTuple!=nbOfTuple2)
10309     throw INTERP_KERNEL::Exception("DataArrayInt::Pow : number of tuples mismatches !");
10310   if(nbOfComp!=1 || nbOfComp2!=1)
10311     throw INTERP_KERNEL::Exception("DataArrayInt::Pow : number of components of both arrays must be equal to 1 !");
10312   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbOfTuple,1);
10313   const int *ptr1(a1->begin()),*ptr2(a2->begin());
10314   int *ptr=ret->getPointer();
10315   for(int i=0;i<nbOfTuple;i++,ptr1++,ptr2++,ptr++)
10316     {
10317       if(*ptr2>=0)
10318         {
10319           int tmp=1;
10320           for(int j=0;j<*ptr2;j++)
10321             tmp*=*ptr1;
10322           *ptr=tmp;
10323         }
10324       else
10325         {
10326           std::ostringstream oss; oss << "DataArrayInt::Pow : on tuple #" << i << " of a2 value is < 0 (" << *ptr2 << ") !";
10327           throw INTERP_KERNEL::Exception(oss.str().c_str());
10328         }
10329     }
10330   return ret.retn();
10331 }
10332
10333 /*!
10334  * Apply pow on values of another DataArrayInt to values of \a this one.
10335  *
10336  *  \param [in] other - an array to pow to \a this one.
10337  *  \throw If \a other is NULL.
10338  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples()
10339  *  \throw If \a this->getNumberOfComponents() != 1 or \a other->getNumberOfComponents() != 1
10340  *  \throw If there is a negative value in \a other.
10341  */
10342 void DataArrayInt::powEqual(const DataArrayInt *other) throw(INTERP_KERNEL::Exception)
10343 {
10344   if(!other)
10345     throw INTERP_KERNEL::Exception("DataArrayInt::powEqual : input instance is null !");
10346   int nbOfTuple=getNumberOfTuples();
10347   int nbOfTuple2=other->getNumberOfTuples();
10348   int nbOfComp=getNumberOfComponents();
10349   int nbOfComp2=other->getNumberOfComponents();
10350   if(nbOfTuple!=nbOfTuple2)
10351     throw INTERP_KERNEL::Exception("DataArrayInt::powEqual : number of tuples mismatches !");
10352   if(nbOfComp!=1 || nbOfComp2!=1)
10353     throw INTERP_KERNEL::Exception("DataArrayInt::powEqual : number of components of both arrays must be equal to 1 !");
10354   int *ptr=getPointer();
10355   const int *ptrc=other->begin();
10356   for(int i=0;i<nbOfTuple;i++,ptrc++,ptr++)
10357     {
10358       if(*ptrc>=0)
10359         {
10360           int tmp=1;
10361           for(int j=0;j<*ptrc;j++)
10362             tmp*=*ptr;
10363           *ptr=tmp;
10364         }
10365       else
10366         {
10367           std::ostringstream oss; oss << "DataArrayInt::powEqual : on tuple #" << i << " of other value is < 0 (" << *ptrc << ") !";
10368           throw INTERP_KERNEL::Exception(oss.str().c_str());
10369         }
10370     }
10371   declareAsNew();
10372 }
10373
10374 /*!
10375  * Returns a C array which is a renumbering map in "Old to New" mode for the input array.
10376  * This map, if applied to \a start array, would make it sorted. For example, if
10377  * \a start array contents are [9,10,0,6,4,11,3,7] then the contents of the result array is
10378  * [5,6,0,3,2,7,1,4].
10379  *  \param [in] start - pointer to the first element of the array for which the
10380  *         permutation map is computed.
10381  *  \param [in] end - pointer specifying the end of the array \a start, so that
10382  *         the last value of \a start is \a end[ -1 ].
10383  *  \return int * - the result permutation array that the caller is to delete as it is no
10384  *         more needed.
10385  *  \throw If there are equal values in the input array.
10386  */
10387 int *DataArrayInt::CheckAndPreparePermutation(const int *start, const int *end)
10388 {
10389   std::size_t sz=std::distance(start,end);
10390   int *ret=(int *)malloc(sz*sizeof(int));
10391   int *work=new int[sz];
10392   std::copy(start,end,work);
10393   std::sort(work,work+sz);
10394   if(std::unique(work,work+sz)!=work+sz)
10395     {
10396       delete [] work;
10397       free(ret);
10398       throw INTERP_KERNEL::Exception("Some elements are equals in the specified array !");
10399     }
10400   std::map<int,int> m;
10401   for(int *workPt=work;workPt!=work+sz;workPt++)
10402     m[*workPt]=(int)std::distance(work,workPt);
10403   int *iter2=ret;
10404   for(const int *iter=start;iter!=end;iter++,iter2++)
10405     *iter2=m[*iter];
10406   delete [] work;
10407   return ret;
10408 }
10409
10410 /*!
10411  * Returns a new DataArrayInt containing an arithmetic progression
10412  * that is equal to the sequence returned by Python \c range(\a begin,\a  end,\a  step )
10413  * function.
10414  *  \param [in] begin - the start value of the result sequence.
10415  *  \param [in] end - limiting value, so that every value of the result array is less than
10416  *              \a end.
10417  *  \param [in] step - specifies the increment or decrement.
10418  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
10419  *          array using decrRef() as it is no more needed.
10420  *  \throw If \a step == 0.
10421  *  \throw If \a end < \a begin && \a step > 0.
10422  *  \throw If \a end > \a begin && \a step < 0.
10423  */
10424 DataArrayInt *DataArrayInt::Range(int begin, int end, int step) throw(INTERP_KERNEL::Exception)
10425 {
10426   int nbOfTuples=GetNumberOfItemGivenBESRelative(begin,end,step,"DataArrayInt::Range");
10427   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
10428   ret->alloc(nbOfTuples,1);
10429   int *ptr=ret->getPointer();
10430   if(step>0)
10431     {
10432       for(int i=begin;i<end;i+=step,ptr++)
10433         *ptr=i;
10434     }
10435   else
10436     {
10437       for(int i=begin;i>end;i+=step,ptr++)
10438         *ptr=i;
10439     }
10440   return ret.retn();
10441 }
10442
10443 /*!
10444  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
10445  * Server side.
10446  */
10447 void DataArrayInt::getTinySerializationIntInformation(std::vector<int>& tinyInfo) const
10448 {
10449   tinyInfo.resize(2);
10450   if(isAllocated())
10451     {
10452       tinyInfo[0]=getNumberOfTuples();
10453       tinyInfo[1]=getNumberOfComponents();
10454     }
10455   else
10456     {
10457       tinyInfo[0]=-1;
10458       tinyInfo[1]=-1;
10459     }
10460 }
10461
10462 /*!
10463  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
10464  * Server side.
10465  */
10466 void DataArrayInt::getTinySerializationStrInformation(std::vector<std::string>& tinyInfo) const
10467 {
10468   if(isAllocated())
10469     {
10470       int nbOfCompo=getNumberOfComponents();
10471       tinyInfo.resize(nbOfCompo+1);
10472       tinyInfo[0]=getName();
10473       for(int i=0;i<nbOfCompo;i++)
10474         tinyInfo[i+1]=getInfoOnComponent(i);
10475     }
10476   else
10477     {
10478       tinyInfo.resize(1);
10479       tinyInfo[0]=getName();
10480     }
10481 }
10482
10483 /*!
10484  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
10485  * This method returns if a feeding is needed.
10486  */
10487 bool DataArrayInt::resizeForUnserialization(const std::vector<int>& tinyInfoI)
10488 {
10489   int nbOfTuple=tinyInfoI[0];
10490   int nbOfComp=tinyInfoI[1];
10491   if(nbOfTuple!=-1 || nbOfComp!=-1)
10492     {
10493       alloc(nbOfTuple,nbOfComp);
10494       return true;
10495     }
10496   return false;
10497 }
10498
10499 /*!
10500  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
10501  * This method returns if a feeding is needed.
10502  */
10503 void DataArrayInt::finishUnserialization(const std::vector<int>& tinyInfoI, const std::vector<std::string>& tinyInfoS)
10504 {
10505   setName(tinyInfoS[0].c_str());
10506   if(isAllocated())
10507     {
10508       int nbOfCompo=getNumberOfComponents();
10509       for(int i=0;i<nbOfCompo;i++)
10510         setInfoOnComponent(i,tinyInfoS[i+1].c_str());
10511     }
10512 }
10513
10514 DataArrayIntIterator::DataArrayIntIterator(DataArrayInt *da):_da(da),_pt(0),_tuple_id(0),_nb_comp(0),_nb_tuple(0)
10515 {
10516   if(_da)
10517     {
10518       _da->incrRef();
10519       if(_da->isAllocated())
10520         {
10521           _nb_comp=da->getNumberOfComponents();
10522           _nb_tuple=da->getNumberOfTuples();
10523           _pt=da->getPointer();
10524         }
10525     }
10526 }
10527
10528 DataArrayIntIterator::~DataArrayIntIterator()
10529 {
10530   if(_da)
10531     _da->decrRef();
10532 }
10533
10534 DataArrayIntTuple *DataArrayIntIterator::nextt() throw(INTERP_KERNEL::Exception)
10535 {
10536   if(_tuple_id<_nb_tuple)
10537     {
10538       _tuple_id++;
10539       DataArrayIntTuple *ret=new DataArrayIntTuple(_pt,_nb_comp);
10540       _pt+=_nb_comp;
10541       return ret;
10542     }
10543   else
10544     return 0;
10545 }
10546
10547 DataArrayIntTuple::DataArrayIntTuple(int *pt, int nbOfComp):_pt(pt),_nb_of_compo(nbOfComp)
10548 {
10549 }
10550
10551 std::string DataArrayIntTuple::repr() const throw(INTERP_KERNEL::Exception)
10552 {
10553   std::ostringstream oss; oss << "(";
10554   for(int i=0;i<_nb_of_compo-1;i++)
10555     oss << _pt[i] << ", ";
10556   oss << _pt[_nb_of_compo-1] << ")";
10557   return oss.str();
10558 }
10559
10560 int DataArrayIntTuple::intValue() const throw(INTERP_KERNEL::Exception)
10561 {
10562   if(_nb_of_compo==1)
10563     return *_pt;
10564   throw INTERP_KERNEL::Exception("DataArrayIntTuple::intValue : DataArrayIntTuple instance has not exactly 1 component -> Not possible to convert it into an integer !");
10565 }
10566
10567 /*!
10568  * This method returns a newly allocated instance the caller should dealed with by a ParaMEDMEM::DataArrayInt::decrRef.
10569  * This method performs \b no copy of data. The content is only referenced using ParaMEDMEM::DataArrayInt::useArray with ownership set to \b false.
10570  * 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
10571  * \b nbOfCompo=1 and \bnbOfTuples==this->_nb_of_elem.
10572  */
10573 DataArrayInt *DataArrayIntTuple::buildDAInt(int nbOfTuples, int nbOfCompo) const throw(INTERP_KERNEL::Exception)
10574 {
10575   if((_nb_of_compo==nbOfCompo && nbOfTuples==1) || (_nb_of_compo==nbOfTuples && nbOfCompo==1))
10576     {
10577       DataArrayInt *ret=DataArrayInt::New();
10578       ret->useExternalArrayWithRWAccess(_pt,nbOfTuples,nbOfCompo);
10579       return ret;
10580     }
10581   else
10582     {
10583       std::ostringstream oss; oss << "DataArrayIntTuple::buildDAInt : unable to build a requested DataArrayInt instance with nbofTuple=" << nbOfTuples << " and nbOfCompo=" << nbOfCompo;
10584       oss << ".\nBecause the number of elements in this is " << _nb_of_compo << " !";
10585       throw INTERP_KERNEL::Exception(oss.str().c_str());
10586     }
10587 }