Salome HOME
bbeeaf46acc2c7035d55eb08002d8c1cfd015fec
[modules/med.git] / src / MEDCoupling / MEDCouplingMemArray.cxx
1 // Copyright (C) 2007-2013  CEA/DEN, EDF R&D
2 //
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License.
7 //
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11 // Lesser General Public License for more details.
12 //
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
16 //
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
18 //
19 // Author : Anthony Geay (CEA/DEN)
20
21 #include "MEDCouplingMemArray.txx"
22 #include "MEDCouplingAutoRefCountObjectPtr.hxx"
23
24 #include "GenMathFormulae.hxx"
25 #include "InterpKernelExprParser.hxx"
26
27 #include <set>
28 #include <cmath>
29 #include <limits>
30 #include <numeric>
31 #include <algorithm>
32 #include <functional>
33
34 typedef double (*MYFUNCPTR)(double);
35
36 using namespace ParaMEDMEM;
37
38 template<int SPACEDIM>
39 void DataArrayDouble::findCommonTuplesAlg(const double *bbox, int nbNodes, int limitNodeId, double prec, DataArrayInt *c, DataArrayInt *cI) const
40 {
41   const double *coordsPtr=getConstPointer();
42   BBTreePts<SPACEDIM,int> myTree(bbox,0,0,nbNodes,prec);
43   std::vector<bool> isDone(nbNodes);
44   for(int i=0;i<nbNodes;i++)
45     {
46       if(!isDone[i])
47         {
48           std::vector<int> intersectingElems;
49           myTree.getElementsAroundPoint(coordsPtr+i*SPACEDIM,intersectingElems);
50           if(intersectingElems.size()>1)
51             {
52               std::vector<int> commonNodes;
53               for(std::vector<int>::const_iterator it=intersectingElems.begin();it!=intersectingElems.end();it++)
54                 if(*it!=i)
55                   if(*it>=limitNodeId)
56                     {
57                       commonNodes.push_back(*it);
58                       isDone[*it]=true;
59                     }
60               if(!commonNodes.empty())
61                 {
62                   cI->pushBackSilent(cI->back()+(int)commonNodes.size()+1);
63                   c->pushBackSilent(i);
64                   c->insertAtTheEnd(commonNodes.begin(),commonNodes.end());
65                 }
66             }
67         }
68     }
69 }
70
71 template<int SPACEDIM>
72 void DataArrayDouble::FindTupleIdsNearTuplesAlg(const BBTreePts<SPACEDIM,int>& myTree, const double *pos, int nbOfTuples, double eps,
73                                                 DataArrayInt *c, DataArrayInt *cI)
74 {
75   for(int i=0;i<nbOfTuples;i++)
76     {
77       std::vector<int> intersectingElems;
78       myTree.getElementsAroundPoint(pos+i*SPACEDIM,intersectingElems);
79       std::vector<int> commonNodes;
80       for(std::vector<int>::const_iterator it=intersectingElems.begin();it!=intersectingElems.end();it++)
81         commonNodes.push_back(*it);
82       cI->pushBackSilent(cI->back()+(int)commonNodes.size());
83       c->insertAtTheEnd(commonNodes.begin(),commonNodes.end());
84     }
85 }
86
87 template<int SPACEDIM>
88 void DataArrayDouble::FindClosestTupleIdAlg(const BBTreePts<SPACEDIM,int>& myTree, double dist, const double *pos, int nbOfTuples, const double *thisPt, int thisNbOfTuples, int *res)
89 {
90   double distOpt(dist);
91   const double *p(pos);
92   int *r(res);
93   for(int i=0;i<nbOfTuples;i++,p+=SPACEDIM,r++)
94     {
95       while(true)
96         {
97           int elem=-1;
98           double ret=myTree.getElementsAroundPoint2(p,distOpt,elem);
99           if(ret!=std::numeric_limits<double>::max())
100             {
101               distOpt=std::max(ret,1e-4);
102               *r=elem;
103               break;
104             }
105           else
106             { distOpt=2*distOpt; continue; }
107         }
108     }
109 }
110
111 std::size_t DataArray::getHeapMemorySize() const
112 {
113   std::size_t sz1=_name.capacity();
114   std::size_t sz2=_info_on_compo.capacity();
115   std::size_t sz3=0;
116   for(std::vector<std::string>::const_iterator it=_info_on_compo.begin();it!=_info_on_compo.end();it++)
117     sz3+=(*it).capacity();
118   return sz1+sz2+sz3;
119 }
120
121 /*!
122  * Sets the attribute \a _name of \a this array.
123  * See \ref MEDCouplingArrayBasicsName "DataArrays infos" for more information.
124  *  \param [in] name - new array name
125  */
126 void DataArray::setName(const char *name)
127 {
128   _name=name;
129 }
130
131 /*!
132  * Copies textual data from an \a other DataArray. The copied data are
133  * - the name attribute,
134  * - the information of components.
135  *
136  * For more information on these data see \ref MEDCouplingArrayBasicsName "DataArrays infos".
137  *
138  *  \param [in] other - another instance of DataArray to copy the textual data from.
139  *  \throw If number of components of \a this array differs from that of the \a other.
140  */
141 void DataArray::copyStringInfoFrom(const DataArray& other) throw(INTERP_KERNEL::Exception)
142 {
143   if(_info_on_compo.size()!=other._info_on_compo.size())
144     throw INTERP_KERNEL::Exception("Size of arrays mismatches on copyStringInfoFrom !");
145   _name=other._name;
146   _info_on_compo=other._info_on_compo;
147 }
148
149 void DataArray::copyPartOfStringInfoFrom(const DataArray& other, const std::vector<int>& compoIds) throw(INTERP_KERNEL::Exception)
150 {
151   int nbOfCompoOth=other.getNumberOfComponents();
152   std::size_t newNbOfCompo=compoIds.size();
153   for(std::size_t i=0;i<newNbOfCompo;i++)
154     if(compoIds[i]>=nbOfCompoOth || compoIds[i]<0)
155       {
156         std::ostringstream oss; oss << "Specified component id is out of range (" << compoIds[i] << ") compared with nb of actual components (" << nbOfCompoOth << ")";
157         throw INTERP_KERNEL::Exception(oss.str().c_str());
158       }
159   for(std::size_t i=0;i<newNbOfCompo;i++)
160     setInfoOnComponent((int)i,other.getInfoOnComponent(compoIds[i]).c_str());
161 }
162
163 void DataArray::copyPartOfStringInfoFrom2(const std::vector<int>& compoIds, const DataArray& other) throw(INTERP_KERNEL::Exception)
164 {
165   int nbOfCompo=getNumberOfComponents();
166   std::size_t partOfCompoToSet=compoIds.size();
167   if((int)partOfCompoToSet!=other.getNumberOfComponents())
168     throw INTERP_KERNEL::Exception("Given compoIds has not the same size as number of components of given array !");
169   for(std::size_t i=0;i<partOfCompoToSet;i++)
170     if(compoIds[i]>=nbOfCompo || compoIds[i]<0)
171       {
172         std::ostringstream oss; oss << "Specified component id is out of range (" << compoIds[i] << ") compared with nb of actual components (" << nbOfCompo << ")";
173         throw INTERP_KERNEL::Exception(oss.str().c_str());
174       }
175   for(std::size_t i=0;i<partOfCompoToSet;i++)
176     setInfoOnComponent(compoIds[i],other.getInfoOnComponent((int)i).c_str());
177 }
178
179 bool DataArray::areInfoEqualsIfNotWhy(const DataArray& other, std::string& reason) const throw(INTERP_KERNEL::Exception)
180 {
181   std::ostringstream oss;
182   if(_name!=other._name)
183     {
184       oss << "Names DataArray mismatch : this name=\"" << _name << " other name=\"" << other._name << "\" !";
185       reason=oss.str();
186       return false;
187     }
188   if(_info_on_compo!=other._info_on_compo)
189     {
190       oss << "Components DataArray mismatch : \nThis components=";
191       for(std::vector<std::string>::const_iterator it=_info_on_compo.begin();it!=_info_on_compo.end();it++)
192         oss << "\"" << *it << "\",";
193       oss << "\nOther components=";
194       for(std::vector<std::string>::const_iterator it=other._info_on_compo.begin();it!=other._info_on_compo.end();it++)
195         oss << "\"" << *it << "\",";
196       reason=oss.str();
197       return false;
198     }
199   return true;
200 }
201
202 /*!
203  * Compares textual information of \a this DataArray with that of an \a other one.
204  * The compared data are
205  * - the name attribute,
206  * - the information of components.
207  *
208  * For more information on these data see \ref MEDCouplingArrayBasicsName "DataArrays infos".
209  *  \param [in] other - another instance of DataArray to compare the textual data of.
210  *  \return bool - \a true if the textual information is same, \a false else.
211  */
212 bool DataArray::areInfoEquals(const DataArray& other) const throw(INTERP_KERNEL::Exception)
213 {
214   std::string tmp;
215   return areInfoEqualsIfNotWhy(other,tmp);
216 }
217
218 void DataArray::reprWithoutNameStream(std::ostream& stream) const throw(INTERP_KERNEL::Exception)
219 {
220   stream << "Number of components : "<< getNumberOfComponents() << "\n";
221   stream << "Info of these components : ";
222   for(std::vector<std::string>::const_iterator iter=_info_on_compo.begin();iter!=_info_on_compo.end();iter++)
223     stream << "\"" << *iter << "\"   ";
224   stream << "\n";
225 }
226
227 std::string DataArray::cppRepr(const char *varName) const throw(INTERP_KERNEL::Exception)
228 {
229   std::ostringstream ret;
230   reprCppStream(varName,ret);
231   return ret.str();
232 }
233
234 /*!
235  * Sets information on all components. To know more on format of this information
236  * see \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
237  *  \param [in] info - a vector of strings.
238  *  \throw If size of \a info differs from the number of components of \a this.
239  */
240 void DataArray::setInfoOnComponents(const std::vector<std::string>& info) throw(INTERP_KERNEL::Exception)
241 {
242   if(getNumberOfComponents()!=(int)info.size())
243     {
244       std::ostringstream oss; oss << "DataArray::setInfoOnComponents : input is of size " << info.size() << " whereas number of components is equal to " << getNumberOfComponents() << " !";
245       throw INTERP_KERNEL::Exception(oss.str().c_str());
246     }
247   _info_on_compo=info;
248 }
249
250 std::vector<std::string> DataArray::getVarsOnComponent() const throw(INTERP_KERNEL::Exception)
251 {
252   int nbOfCompo=(int)_info_on_compo.size();
253   std::vector<std::string> ret(nbOfCompo);
254   for(int i=0;i<nbOfCompo;i++)
255     ret[i]=getVarOnComponent(i);
256   return ret;
257 }
258
259 std::vector<std::string> DataArray::getUnitsOnComponent() const throw(INTERP_KERNEL::Exception)
260 {
261   int nbOfCompo=(int)_info_on_compo.size();
262   std::vector<std::string> ret(nbOfCompo);
263   for(int i=0;i<nbOfCompo;i++)
264     ret[i]=getUnitOnComponent(i);
265   return ret;
266 }
267
268 /*!
269  * Returns information on a component specified by an index.
270  * To know more on format of this information
271  * see \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
272  *  \param [in] i - the index (zero based) of the component of interest.
273  *  \return std::string - a string containing the information on \a i-th component.
274  *  \throw If \a i is not a valid component index.
275  */
276 std::string DataArray::getInfoOnComponent(int i) const throw(INTERP_KERNEL::Exception)
277 {
278   if(i<(int)_info_on_compo.size() && i>=0)
279     return _info_on_compo[i];
280   else
281     {
282       std::ostringstream oss; oss << "DataArray::getInfoOnComponent : Specified component id is out of range (" << i << ") compared with nb of actual components (" << (int) _info_on_compo.size();
283       throw INTERP_KERNEL::Exception(oss.str().c_str());
284     }
285 }
286
287 /*!
288  * Returns the var part of the full information of the \a i-th component.
289  * For example, if \c getInfoOnComponent(0) returns "SIGXY [N/m^2]", then
290  * \c getVarOnComponent(0) returns "SIGXY".
291  * If a unit part of information is not detected by presence of
292  * two square brackets, then the full information is returned.
293  * To read more about the component information format, see
294  * \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
295  *  \param [in] i - the index (zero based) of the component of interest.
296  *  \return std::string - a string containing the var information, or the full info.
297  *  \throw If \a i is not a valid component index.
298  */
299 std::string DataArray::getVarOnComponent(int i) const throw(INTERP_KERNEL::Exception)
300 {
301   if(i<(int)_info_on_compo.size() && i>=0)
302     {
303       return GetVarNameFromInfo(_info_on_compo[i]);
304     }
305   else
306     {
307       std::ostringstream oss; oss << "DataArray::getVarOnComponent : Specified component id is out of range  (" << i << ") compared with nb of actual components (" << (int) _info_on_compo.size();
308       throw INTERP_KERNEL::Exception(oss.str().c_str());
309     }
310 }
311
312 /*!
313  * Returns the unit part of the full information of the \a i-th component.
314  * For example, if \c getInfoOnComponent(0) returns "SIGXY [ N/m^2]", then
315  * \c getUnitOnComponent(0) returns " N/m^2".
316  * If a unit part of information is not detected by presence of
317  * two square brackets, then an empty string is returned.
318  * To read more about the component information format, see
319  * \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
320  *  \param [in] i - the index (zero based) of the component of interest.
321  *  \return std::string - a string containing the unit information, if any, or "".
322  *  \throw If \a i is not a valid component index.
323  */
324 std::string DataArray::getUnitOnComponent(int i) const throw(INTERP_KERNEL::Exception)
325 {
326   if(i<(int)_info_on_compo.size() && i>=0)
327     {
328       return GetUnitFromInfo(_info_on_compo[i]);
329     }
330   else
331     {
332       std::ostringstream oss; oss << "DataArray::getUnitOnComponent : Specified component id is out of range  (" << i << ") compared with nb of actual components (" << (int) _info_on_compo.size();
333       throw INTERP_KERNEL::Exception(oss.str().c_str());
334     }
335 }
336
337 /*!
338  * Returns the var part of the full component information.
339  * For example, if \a info == "SIGXY [N/m^2]", then this method returns "SIGXY".
340  * If a unit part of information is not detected by presence of
341  * two square brackets, then the whole \a info is returned.
342  * To read more about the component information format, see
343  * \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
344  *  \param [in] info - the full component information.
345  *  \return std::string - a string containing only var information, or the \a info.
346  */
347 std::string DataArray::GetVarNameFromInfo(const std::string& info) throw(INTERP_KERNEL::Exception)
348 {
349   std::size_t p1=info.find_last_of('[');
350   std::size_t p2=info.find_last_of(']');
351   if(p1==std::string::npos || p2==std::string::npos)
352     return info;
353   if(p1>p2)
354     return info;
355   if(p1==0)
356     return std::string();
357   std::size_t p3=info.find_last_not_of(' ',p1-1);
358   return info.substr(0,p3+1);
359 }
360
361 /*!
362  * Returns the unit part of the full component information.
363  * For example, if \a info == "SIGXY [ N/m^2]", then this method returns " N/m^2".
364  * If a unit part of information is not detected by presence of
365  * two square brackets, then an empty string is returned.
366  * To read more about the component information format, see
367  * \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
368  *  \param [in] info - the full component information.
369  *  \return std::string - a string containing only unit information, if any, or "".
370  */
371 std::string DataArray::GetUnitFromInfo(const std::string& info) throw(INTERP_KERNEL::Exception)
372 {
373   std::size_t p1=info.find_last_of('[');
374   std::size_t p2=info.find_last_of(']');
375   if(p1==std::string::npos || p2==std::string::npos)
376     return std::string();
377   if(p1>p2)
378     return std::string();
379   return info.substr(p1+1,p2-p1-1);
380 }
381
382 /*!
383  * Sets information on a component specified by an index.
384  * To know more on format of this information
385  * see \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
386  *  \warning Don't pass NULL as \a info!
387  *  \param [in] i - the index (zero based) of the component of interest.
388  *  \param [in] info - the string containing the information.
389  *  \throw If \a i is not a valid component index.
390  */
391 void DataArray::setInfoOnComponent(int i, const char *info) throw(INTERP_KERNEL::Exception)
392 {
393   if(i<(int)_info_on_compo.size() && i>=0)
394     _info_on_compo[i]=info;
395   else
396     {
397       std::ostringstream oss; oss << "DataArray::setInfoOnComponent : Specified component id is out of range  (" << i << ") compared with nb of actual components (" << (int) _info_on_compo.size();
398       throw INTERP_KERNEL::Exception(oss.str().c_str());
399     }
400 }
401
402 /*!
403  * Sets information on all components. This method can change number of components
404  * at certain conditions; if the conditions are not respected, an exception is thrown.
405  * The number of components can be changed in \a this only if \a this is not allocated.
406  * The condition of number of components must not be changed.
407  *
408  * To know more on format of the component information see
409  * \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
410  *  \param [in] info - a vector of component infos.
411  *  \throw If \a this->getNumberOfComponents() != \a info.size() && \a this->isAllocated()
412  */
413 void DataArray::setInfoAndChangeNbOfCompo(const std::vector<std::string>& info) throw(INTERP_KERNEL::Exception)
414 {
415   if(getNumberOfComponents()!=(int)info.size())
416     {
417       if(!isAllocated())
418         _info_on_compo=info;
419       else
420         {
421           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 !";
422           throw INTERP_KERNEL::Exception(oss.str().c_str());
423         }
424     }
425   else
426     _info_on_compo=info;
427 }
428
429 void DataArray::checkNbOfTuples(int nbOfTuples, const char *msg) const throw(INTERP_KERNEL::Exception)
430 {
431   if(getNumberOfTuples()!=nbOfTuples)
432     {
433       std::ostringstream oss; oss << msg << " : mismatch number of tuples : expected " <<  nbOfTuples << " having " << getNumberOfTuples() << " !";
434       throw INTERP_KERNEL::Exception(oss.str().c_str());
435     }
436 }
437
438 void DataArray::checkNbOfComps(int nbOfCompo, const char *msg) const throw(INTERP_KERNEL::Exception)
439 {
440   if(getNumberOfComponents()!=nbOfCompo)
441     {
442       std::ostringstream oss; oss << msg << " : mismatch number of components : expected " << nbOfCompo << " having " << getNumberOfComponents() << " !";
443       throw INTERP_KERNEL::Exception(oss.str().c_str());
444     }
445 }
446
447 void DataArray::checkNbOfElems(std::size_t nbOfElems, const char *msg) const throw(INTERP_KERNEL::Exception)
448 {
449   if(getNbOfElems()!=nbOfElems)
450     {
451       std::ostringstream oss; oss << msg << " : mismatch number of elems : Expected " << nbOfElems << " having " << getNbOfElems() << " !";
452       throw INTERP_KERNEL::Exception(oss.str().c_str());
453     }
454 }
455
456 void DataArray::checkNbOfTuplesAndComp(const DataArray& other, const char *msg) const throw(INTERP_KERNEL::Exception)
457 {
458    if(getNumberOfTuples()!=other.getNumberOfTuples())
459     {
460       std::ostringstream oss; oss << msg << " : mismatch number of tuples : expected " <<  other.getNumberOfTuples() << " having " << getNumberOfTuples() << " !";
461       throw INTERP_KERNEL::Exception(oss.str().c_str());
462     }
463   if(getNumberOfComponents()!=other.getNumberOfComponents())
464     {
465       std::ostringstream oss; oss << msg << " : mismatch number of components : expected " << other.getNumberOfComponents() << " having " << getNumberOfComponents() << " !";
466       throw INTERP_KERNEL::Exception(oss.str().c_str());
467     }
468 }
469
470 void DataArray::checkNbOfTuplesAndComp(int nbOfTuples, int nbOfCompo, const char *msg) const throw(INTERP_KERNEL::Exception)
471 {
472   checkNbOfTuples(nbOfTuples,msg);
473   checkNbOfComps(nbOfCompo,msg);
474 }
475
476 /*!
477  * Simply this method checks that \b value is in [0,\b ref).
478  */
479 void DataArray::CheckValueInRange(int ref, int value, const char *msg) throw(INTERP_KERNEL::Exception)
480 {
481   if(value<0 || value>=ref)
482     {
483       std::ostringstream oss; oss << "DataArray::CheckValueInRange : " << msg  << " ! Expected in range [0," << ref << "[ having " << value << " !";
484       throw INTERP_KERNEL::Exception(oss.str().c_str());
485     }
486 }
487
488 /*!
489  * This method checks that [\b start, \b end) is compliant with ref length \b value.
490  * typicaly start in [0,\b value) and end in [0,\b value). If value==start and start==end, it is supported.
491  */
492 void DataArray::CheckValueInRangeEx(int value, int start, int end, const char *msg) throw(INTERP_KERNEL::Exception)
493 {
494   if(start<0 || start>=value)
495     {
496       if(value!=start || end!=start)
497         {
498           std::ostringstream oss; oss << "DataArray::CheckValueInRangeEx : " << msg  << " ! Expected start " << start << " of input range, in [0," << value << "[ !";
499           throw INTERP_KERNEL::Exception(oss.str().c_str());
500         }
501     }
502   if(end<0 || end>value)
503     {
504       std::ostringstream oss; oss << "DataArray::CheckValueInRangeEx : " << msg  << " ! Expected end " << end << " of input range, in [0," << value << "] !";
505       throw INTERP_KERNEL::Exception(oss.str().c_str());
506     }
507 }
508
509 void DataArray::CheckClosingParInRange(int ref, int value, const char *msg) throw(INTERP_KERNEL::Exception)
510 {
511   if(value<0 || value>ref)
512     {
513       std::ostringstream oss; oss << "DataArray::CheckClosingParInRange : " << msg  << " ! Expected input range in [0," << ref << "] having closing open parenthesis " << value << " !";
514       throw INTERP_KERNEL::Exception(oss.str().c_str());
515     }
516 }
517
518 /*!
519  * 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, 
520  * typically it is a whole slice of tuples of DataArray or cells, nodes of a mesh...
521  *
522  * The input \a sliceId should be an id in [0, \a nbOfSlices) that specifies the slice of work.
523  *
524  * \param [in] start - the start of the input slice of the whole work to perform splitted into slices.
525  * \param [in] stop - the stop of the input slice of the whole work to perform splitted into slices.
526  * \param [in] step - the step (that can be <0) of the input slice of the whole work to perform splitted into slices.
527  * \param [in] sliceId - the slice id considered
528  * \param [in] nbOfSlices - the number of slices (typically the number of cores on which the work is expected to be sliced)
529  * \param [out] startSlice - the start of the slice considered
530  * \param [out] stopSlice - the stop of the slice consided
531  * 
532  * \throw If \a step == 0
533  * \throw If \a nbOfSlices not > 0
534  * \throw If \a sliceId not in [0,nbOfSlices)
535  */
536 void DataArray::GetSlice(int start, int stop, int step, int sliceId, int nbOfSlices, int& startSlice, int& stopSlice) throw(INTERP_KERNEL::Exception)
537 {
538   if(nbOfSlices<=0)
539     {
540       std::ostringstream oss; oss << "DataArray::GetSlice : nbOfSlices (" << nbOfSlices << ") must be > 0 !";
541       throw INTERP_KERNEL::Exception(oss.str().c_str());
542     }
543   if(sliceId<0 || sliceId>=nbOfSlices)
544     {
545       std::ostringstream oss; oss << "DataArray::GetSlice : sliceId (" << nbOfSlices << ") must be in [0 , nbOfSlices (" << nbOfSlices << ") ) !";
546       throw INTERP_KERNEL::Exception(oss.str().c_str());
547     }
548   int nbElems=GetNumberOfItemGivenBESRelative(start,stop,step,"DataArray::GetSlice");
549   int minNbOfElemsPerSlice=nbElems/nbOfSlices;
550   startSlice=start+minNbOfElemsPerSlice*step*sliceId;
551   if(sliceId<nbOfSlices-1)
552     stopSlice=start+minNbOfElemsPerSlice*step*(sliceId+1);
553   else
554     stopSlice=stop;
555 }
556
557 int DataArray::GetNumberOfItemGivenBES(int begin, int end, int step, const char *msg) throw(INTERP_KERNEL::Exception)
558 {
559   if(end<begin)
560     {
561       std::ostringstream oss; oss << msg << " : end before begin !";
562       throw INTERP_KERNEL::Exception(oss.str().c_str());
563     }
564   if(end==begin)
565     return 0;
566   if(step<=0)
567     {
568       std::ostringstream oss; oss << msg << " : invalid step should be > 0 !";
569       throw INTERP_KERNEL::Exception(oss.str().c_str());
570     }
571   return (end-1-begin)/step+1;
572 }
573
574 int DataArray::GetNumberOfItemGivenBESRelative(int begin, int end, int step, const char *msg) throw(INTERP_KERNEL::Exception)
575 {
576   if(step==0)
577     throw INTERP_KERNEL::Exception("DataArray::GetNumberOfItemGivenBES : step=0 is not allowed !");
578   if(end<begin && step>0)
579     {
580       std::ostringstream oss; oss << msg << " : end before begin whereas step is positive !";
581       throw INTERP_KERNEL::Exception(oss.str().c_str());
582     }
583   if(begin<end && step<0)
584     {
585       std::ostringstream oss; oss << msg << " : invalid step should be > 0 !";
586       throw INTERP_KERNEL::Exception(oss.str().c_str());
587     }
588   if(begin!=end)
589     return (std::max(begin,end)-1-std::min(begin,end))/std::abs(step)+1;
590   else
591     return 0;
592 }
593
594 int DataArray::GetPosOfItemGivenBESRelativeNoThrow(int value, int begin, int end, int step) throw(INTERP_KERNEL::Exception)
595 {
596   if(step!=0)
597     {
598       if(step>0)
599         {
600           if(begin<=value && value<end)
601             {
602               if((value-begin)%step==0)
603                 return (value-begin)/step;
604               else
605                 return -1;
606             }
607           else
608             return -1;
609         }
610       else
611         {
612           if(begin>=value && value>end)
613             {
614               if((begin-value)%(-step)==0)
615                 return (begin-value)/(-step);
616               else
617                 return -1;
618             }
619           else
620             return -1;
621         }
622     }
623   else
624     return -1;
625 }
626
627 /*!
628  * Returns a new instance of DataArrayDouble. The caller is to delete this array
629  * using decrRef() as it is no more needed. 
630  */
631 DataArrayDouble *DataArrayDouble::New()
632 {
633   return new DataArrayDouble;
634 }
635
636 /*!
637  * Checks if raw data is allocated. Read more on the raw data
638  * in \ref MEDCouplingArrayBasicsTuplesAndCompo "DataArrays infos" for more information.
639  *  \return bool - \a true if the raw data is allocated, \a false else.
640  */
641 bool DataArrayDouble::isAllocated() const throw(INTERP_KERNEL::Exception)
642 {
643   return getConstPointer()!=0;
644 }
645
646 /*!
647  * Checks if raw data is allocated and throws an exception if it is not the case.
648  *  \throw If the raw data is not allocated.
649  */
650 void DataArrayDouble::checkAllocated() const throw(INTERP_KERNEL::Exception)
651 {
652   if(!isAllocated())
653     throw INTERP_KERNEL::Exception("DataArrayDouble::checkAllocated : Array is defined but not allocated ! Call alloc or setValues method first !");
654 }
655
656 /*!
657  * This method desallocated \a this without modification of informations relative to the components.
658  * After call of this method, DataArrayDouble::isAllocated will return false.
659  * If \a this is already not allocated, \a this is let unchanged.
660  */
661 void DataArrayDouble::desallocate() throw(INTERP_KERNEL::Exception)
662 {
663   _mem.destroy();
664 }
665
666 std::size_t DataArrayDouble::getHeapMemorySize() const
667 {
668   std::size_t sz=_mem.getNbOfElemAllocated();
669   sz*=sizeof(double);
670   return DataArray::getHeapMemorySize()+sz;
671 }
672
673 /*!
674  * Returns the only one value in \a this, if and only if number of elements
675  * (nb of tuples * nb of components) is equal to 1, and that \a this is allocated.
676  *  \return double - the sole value stored in \a this array.
677  *  \throw If at least one of conditions stated above is not fulfilled.
678  */
679 double DataArrayDouble::doubleValue() const throw(INTERP_KERNEL::Exception)
680 {
681   if(isAllocated())
682     {
683       if(getNbOfElems()==1)
684         {
685           return *getConstPointer();
686         }
687       else
688         throw INTERP_KERNEL::Exception("DataArrayDouble::doubleValue : DataArrayDouble instance is allocated but number of elements is not equal to 1 !");
689     }
690   else
691     throw INTERP_KERNEL::Exception("DataArrayDouble::doubleValue : DataArrayDouble instance is not allocated !");
692 }
693
694 /*!
695  * Checks the number of tuples.
696  *  \return bool - \a true if getNumberOfTuples() == 0, \a false else.
697  *  \throw If \a this is not allocated.
698  */
699 bool DataArrayDouble::empty() const throw(INTERP_KERNEL::Exception)
700 {
701   checkAllocated();
702   return getNumberOfTuples()==0;
703 }
704
705 /*!
706  * Returns a full copy of \a this. For more info on copying data arrays see
707  * \ref MEDCouplingArrayBasicsCopyDeep.
708  *  \return DataArrayDouble * - a new instance of DataArrayDouble. The caller is to
709  *          delete this array using decrRef() as it is no more needed. 
710  */
711 DataArrayDouble *DataArrayDouble::deepCpy() const throw(INTERP_KERNEL::Exception)
712 {
713   return new DataArrayDouble(*this);
714 }
715
716 /*!
717  * Returns either a \a deep or \a shallow copy of this array. For more info see
718  * \ref MEDCouplingArrayBasicsCopyDeep and \ref MEDCouplingArrayBasicsCopyShallow.
719  *  \param [in] dCpy - if \a true, a deep copy is returned, else, a shallow one.
720  *  \return DataArrayDouble * - either a new instance of DataArrayDouble (if \a dCpy
721  *          == \a true) or \a this instance (if \a dCpy == \a false).
722  */
723 DataArrayDouble *DataArrayDouble::performCpy(bool dCpy) const throw(INTERP_KERNEL::Exception)
724 {
725   if(dCpy)
726     return deepCpy();
727   else
728     {
729       incrRef();
730       return const_cast<DataArrayDouble *>(this);
731     }
732 }
733
734 /*!
735  * Copies all the data from another DataArrayDouble. For more info see
736  * \ref MEDCouplingArrayBasicsCopyDeepAssign.
737  *  \param [in] other - another instance of DataArrayDouble to copy data from.
738  *  \throw If the \a other is not allocated.
739  */
740 void DataArrayDouble::cpyFrom(const DataArrayDouble& other) throw(INTERP_KERNEL::Exception)
741 {
742   other.checkAllocated();
743   int nbOfTuples=other.getNumberOfTuples();
744   int nbOfComp=other.getNumberOfComponents();
745   allocIfNecessary(nbOfTuples,nbOfComp);
746   std::size_t nbOfElems=(std::size_t)nbOfTuples*nbOfComp;
747   double *pt=getPointer();
748   const double *ptI=other.getConstPointer();
749   for(std::size_t i=0;i<nbOfElems;i++)
750     pt[i]=ptI[i];
751   copyStringInfoFrom(other);
752 }
753
754 /*!
755  * This method reserve nbOfElems elements in memory ( nbOfElems*8 bytes ) \b without impacting the number of tuples in \a this.
756  * 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.
757  * If \a this has not already been allocated, number of components is set to one.
758  * This method allows to reduce number of reallocations on invokation of DataArrayDouble::pushBackSilent and DataArrayDouble::pushBackValsSilent on \a this.
759  * 
760  * \sa DataArrayDouble::pack, DataArrayDouble::pushBackSilent, DataArrayDouble::pushBackValsSilent
761  */
762 void DataArrayDouble::reserve(std::size_t nbOfElems) throw(INTERP_KERNEL::Exception)
763 {
764   int nbCompo=getNumberOfComponents();
765   if(nbCompo==1)
766     {
767       _mem.reserve(nbOfElems);
768     }
769   else if(nbCompo==0)
770     {
771       _mem.reserve(nbOfElems);
772       _info_on_compo.resize(1);
773     }
774   else
775     throw INTERP_KERNEL::Exception("DataArrayDouble::reserve : not available for DataArrayDouble with number of components different than 1 !");
776 }
777
778 /*!
779  * 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
780  * of counter. So the caller is expected to call TimeLabel::declareAsNew on \a this at the end of the push session.
781  *
782  * \param [in] val the value to be added in \a this
783  * \throw If \a this has already been allocated with number of components different from one.
784  * \sa DataArrayDouble::pushBackValsSilent
785  */
786 void DataArrayDouble::pushBackSilent(double val) throw(INTERP_KERNEL::Exception)
787 {
788   int nbCompo=getNumberOfComponents();
789   if(nbCompo==1)
790     _mem.pushBack(val);
791   else if(nbCompo==0)
792     {
793       _info_on_compo.resize(1);
794       _mem.pushBack(val);
795     }
796   else
797     throw INTERP_KERNEL::Exception("DataArrayDouble::pushBackSilent : not available for DataArrayDouble with number of components different than 1 !");
798 }
799
800 /*!
801  * 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
802  * of counter. So the caller is expected to call TimeLabel::declareAsNew on \a this at the end of the push session.
803  *
804  *  \param [in] valsBg - an array of values to push at the end of \this.
805  *  \param [in] valsEnd - specifies the end of the array \a valsBg, so that
806  *              the last value of \a valsBg is \a valsEnd[ -1 ].
807  * \throw If \a this has already been allocated with number of components different from one.
808  * \sa DataArrayDouble::pushBackSilent
809  */
810 void DataArrayDouble::pushBackValsSilent(const double *valsBg, const double *valsEnd) throw(INTERP_KERNEL::Exception)
811 {
812   int nbCompo=getNumberOfComponents();
813   if(nbCompo==1)
814     _mem.insertAtTheEnd(valsBg,valsEnd);
815   else if(nbCompo==0)
816     {
817       _info_on_compo.resize(1);
818       _mem.insertAtTheEnd(valsBg,valsEnd);
819     }
820   else
821     throw INTERP_KERNEL::Exception("DataArrayDouble::pushBackValsSilent : not available for DataArrayDouble with number of components different than 1 !");
822 }
823
824 /*!
825  * This method returns silently ( without updating time label in \a this ) the last value, if any and suppress it.
826  * \throw If \a this is already empty.
827  * \throw If \a this has number of components different from one.
828  */
829 double DataArrayDouble::popBackSilent() throw(INTERP_KERNEL::Exception)
830 {
831   if(getNumberOfComponents()==1)
832     return _mem.popBack();
833   else
834     throw INTERP_KERNEL::Exception("DataArrayDouble::popBackSilent : not available for DataArrayDouble with number of components different than 1 !");
835 }
836
837 /*!
838  * 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.
839  *
840  * \sa DataArrayDouble::getHeapMemorySize, DataArrayDouble::reserve
841  */
842 void DataArrayDouble::pack() const throw(INTERP_KERNEL::Exception)
843 {
844   _mem.pack();
845 }
846
847 /*!
848  * Allocates the raw data in memory. If exactly same memory as needed already
849  * allocated, it is not re-allocated.
850  *  \param [in] nbOfTuple - number of tuples of data to allocate.
851  *  \param [in] nbOfCompo - number of components of data to allocate.
852  *  \throw If \a nbOfTuple < 0 or \a nbOfCompo < 0.
853  */
854 void DataArrayDouble::allocIfNecessary(int nbOfTuple, int nbOfCompo) throw(INTERP_KERNEL::Exception)
855 {
856   if(isAllocated())
857     {
858       if(nbOfTuple!=getNumberOfTuples() || nbOfCompo!=getNumberOfComponents())
859         alloc(nbOfTuple,nbOfCompo);
860     }
861   else
862     alloc(nbOfTuple,nbOfCompo);
863 }
864
865 /*!
866  * Allocates the raw data in memory. If the memory was already allocated, then it is
867  * freed and re-allocated. See an example of this method use
868  * \ref MEDCouplingArraySteps1WC "here".
869  *  \param [in] nbOfTuple - number of tuples of data to allocate.
870  *  \param [in] nbOfCompo - number of components of data to allocate.
871  *  \throw If \a nbOfTuple < 0 or \a nbOfCompo < 0.
872  */
873 void DataArrayDouble::alloc(int nbOfTuple, int nbOfCompo) throw(INTERP_KERNEL::Exception)
874 {
875   if(nbOfTuple<0 || nbOfCompo<0)
876     throw INTERP_KERNEL::Exception("DataArrayDouble::alloc : request for negative length of data !");
877   _info_on_compo.resize(nbOfCompo);
878   _mem.alloc(nbOfCompo*(std::size_t)nbOfTuple);
879   declareAsNew();
880 }
881
882 /*!
883  * Assign zero to all values in \a this array. To know more on filling arrays see
884  * \ref MEDCouplingArrayFill.
885  * \throw If \a this is not allocated.
886  */
887 void DataArrayDouble::fillWithZero() throw(INTERP_KERNEL::Exception)
888 {
889   checkAllocated();
890   _mem.fillWithValue(0.);
891   declareAsNew();
892 }
893
894 /*!
895  * Assign \a val to all values in \a this array. To know more on filling arrays see
896  * \ref MEDCouplingArrayFill.
897  *  \param [in] val - the value to fill with.
898  *  \throw If \a this is not allocated.
899  */
900 void DataArrayDouble::fillWithValue(double val) throw(INTERP_KERNEL::Exception)
901 {
902   checkAllocated();
903   _mem.fillWithValue(val);
904   declareAsNew();
905 }
906
907 /*!
908  * Set all values in \a this array so that the i-th element equals to \a init + i
909  * (i starts from zero). To know more on filling arrays see \ref MEDCouplingArrayFill.
910  *  \param [in] init - value to assign to the first element of array.
911  *  \throw If \a this->getNumberOfComponents() != 1
912  *  \throw If \a this is not allocated.
913  */
914 void DataArrayDouble::iota(double init) throw(INTERP_KERNEL::Exception)
915 {
916   checkAllocated();
917   if(getNumberOfComponents()!=1)
918     throw INTERP_KERNEL::Exception("DataArrayDouble::iota : works only for arrays with only one component, you can call 'rearrange' method before !");
919   double *ptr=getPointer();
920   int ntuples=getNumberOfTuples();
921   for(int i=0;i<ntuples;i++)
922     ptr[i]=init+double(i);
923   declareAsNew();
924 }
925
926 /*!
927  * Checks if all values in \a this array are equal to \a val at precision \a eps.
928  *  \param [in] val - value to check equality of array values to.
929  *  \param [in] eps - precision to check the equality.
930  *  \return bool - \a true if all values are in range (_val_ - _eps_; _val_ + _eps_),
931  *                 \a false else.
932  *  \throw If \a this->getNumberOfComponents() != 1
933  *  \throw If \a this is not allocated.
934  */
935 bool DataArrayDouble::isUniform(double val, double eps) const throw(INTERP_KERNEL::Exception)
936 {
937   checkAllocated();
938   if(getNumberOfComponents()!=1)
939     throw INTERP_KERNEL::Exception("DataArrayDouble::isUniform : must be applied on DataArrayDouble with only one component, you can call 'rearrange' method before !");
940   int nbOfTuples=getNumberOfTuples();
941   const double *w=getConstPointer();
942   const double *end2=w+nbOfTuples;
943   const double vmin=val-eps;
944   const double vmax=val+eps;
945   for(;w!=end2;w++)
946     if(*w<vmin || *w>vmax)
947       return false;
948   return true;
949 }
950
951 /*!
952  * Sorts values of the array.
953  *  \param [in] asc - \a true means ascending order, \a false, descending.
954  *  \throw If \a this is not allocated.
955  *  \throw If \a this->getNumberOfComponents() != 1.
956  */
957 void DataArrayDouble::sort(bool asc) throw(INTERP_KERNEL::Exception)
958 {
959   checkAllocated();
960   if(getNumberOfComponents()!=1)
961     throw INTERP_KERNEL::Exception("DataArrayDouble::sort : only supported with 'this' array with ONE component !");
962   _mem.sort(asc);
963   declareAsNew();
964 }
965
966 /*!
967  * Reverse the array values.
968  *  \throw If \a this->getNumberOfComponents() < 1.
969  *  \throw If \a this is not allocated.
970  */
971 void DataArrayDouble::reverse() throw(INTERP_KERNEL::Exception)
972 {
973   checkAllocated();
974   _mem.reverse(getNumberOfComponents());
975   declareAsNew();
976 }
977
978 /*!
979  * Checks that \a this array is consistently **increasing** or **decreasing** in value,
980  * with at least absolute difference value of |\a eps| at each step.
981  * If not an exception is thrown.
982  *  \param [in] increasing - if \a true, the array values should be increasing.
983  *  \param [in] eps - minimal absolute difference between the neighbor values at which 
984  *                    the values are considered different.
985  *  \throw If sequence of values is not strictly monotonic in agreement with \a
986  *         increasing arg.
987  *  \throw If \a this->getNumberOfComponents() != 1.
988  *  \throw If \a this is not allocated.
989  */
990 void DataArrayDouble::checkMonotonic(bool increasing, double eps) const throw(INTERP_KERNEL::Exception)
991 {
992   if(!isMonotonic(increasing,eps))
993     {
994       if (increasing)
995         throw INTERP_KERNEL::Exception("DataArrayDouble::checkMonotonic : 'this' is not INCREASING monotonic !");
996       else
997         throw INTERP_KERNEL::Exception("DataArrayDouble::checkMonotonic : 'this' is not DECREASING monotonic !");
998     }
999 }
1000
1001 /*!
1002  * Checks that \a this array is consistently **increasing** or **decreasing** in value,
1003  * with at least absolute difference value of |\a eps| at each step.
1004  *  \param [in] increasing - if \a true, array values should be increasing.
1005  *  \param [in] eps - minimal absolute difference between the neighbor values at which 
1006  *                    the values are considered different.
1007  *  \return bool - \a true if values change in accordance with \a increasing arg.
1008  *  \throw If \a this->getNumberOfComponents() != 1.
1009  *  \throw If \a this is not allocated.
1010  */
1011 bool DataArrayDouble::isMonotonic(bool increasing, double eps) const throw(INTERP_KERNEL::Exception)
1012 {
1013   checkAllocated();
1014   if(getNumberOfComponents()!=1)
1015     throw INTERP_KERNEL::Exception("DataArrayDouble::isMonotonic : only supported with 'this' array with ONE component !");
1016   int nbOfElements=getNumberOfTuples();
1017   const double *ptr=getConstPointer();
1018   if(nbOfElements==0)
1019     return true;
1020   double ref=ptr[0];
1021   double absEps=fabs(eps);
1022   if(increasing)
1023     {
1024       for(int i=1;i<nbOfElements;i++)
1025         {
1026           if(ptr[i]<(ref+absEps))
1027             return false;
1028           ref=ptr[i];
1029         }
1030       return true;
1031     }
1032   else
1033     {
1034       for(int i=1;i<nbOfElements;i++)
1035         {
1036           if(ptr[i]>(ref-absEps))
1037             return false;
1038           ref=ptr[i];
1039         }
1040       return true;
1041     }
1042 }
1043
1044 /*!
1045  * Returns a textual and human readable representation of \a this instance of
1046  * DataArrayDouble. This text is shown when a DataArrayDouble is printed in Python.
1047  *  \return std::string - text describing \a this DataArrayDouble.
1048  */
1049 std::string DataArrayDouble::repr() const throw(INTERP_KERNEL::Exception)
1050 {
1051   std::ostringstream ret;
1052   reprStream(ret);
1053   return ret.str();
1054 }
1055
1056 std::string DataArrayDouble::reprZip() const throw(INTERP_KERNEL::Exception)
1057 {
1058   std::ostringstream ret;
1059   reprZipStream(ret);
1060   return ret.str();
1061 }
1062
1063 void DataArrayDouble::writeVTK(std::ostream& ofs, int indent, const char *nameInFile) const throw(INTERP_KERNEL::Exception)
1064 {
1065   std::string idt(indent,' ');
1066   ofs.precision(17);
1067   ofs << idt << "<DataArray type=\"Float32\" Name=\"" << nameInFile << "\" NumberOfComponents=\"" << getNumberOfComponents() << "\"";
1068   ofs << " format=\"ascii\" RangeMin=\"" << getMinValueInArray() << "\" RangeMax=\"" << getMaxValueInArray() << "\">\n" << idt;
1069   std::copy(begin(),end(),std::ostream_iterator<double>(ofs," "));
1070   ofs << std::endl << idt << "</DataArray>\n";
1071 }
1072
1073 void DataArrayDouble::reprStream(std::ostream& stream) const throw(INTERP_KERNEL::Exception)
1074 {
1075   stream << "Name of double array : \"" << _name << "\"\n";
1076   reprWithoutNameStream(stream);
1077 }
1078
1079 void DataArrayDouble::reprZipStream(std::ostream& stream) const throw(INTERP_KERNEL::Exception)
1080 {
1081   stream << "Name of double array : \"" << _name << "\"\n";
1082   reprZipWithoutNameStream(stream);
1083 }
1084
1085 void DataArrayDouble::reprWithoutNameStream(std::ostream& stream) const throw(INTERP_KERNEL::Exception)
1086 {
1087   DataArray::reprWithoutNameStream(stream);
1088   stream.precision(17);
1089   _mem.repr(getNumberOfComponents(),stream);
1090 }
1091
1092 void DataArrayDouble::reprZipWithoutNameStream(std::ostream& stream) const throw(INTERP_KERNEL::Exception)
1093 {
1094   DataArray::reprWithoutNameStream(stream);
1095   stream.precision(17);
1096   _mem.reprZip(getNumberOfComponents(),stream);
1097 }
1098
1099 void DataArrayDouble::reprCppStream(const char *varName, std::ostream& stream) const throw(INTERP_KERNEL::Exception)
1100 {
1101   int nbTuples=getNumberOfTuples(),nbComp=getNumberOfComponents();
1102   const double *data=getConstPointer();
1103   stream.precision(17);
1104   stream << "DataArrayDouble *" << varName << "=DataArrayDouble::New();" << std::endl;
1105   if(nbTuples*nbComp>=1)
1106     {
1107       stream << "const double " << varName << "Data[" << nbTuples*nbComp << "]={";
1108       std::copy(data,data+nbTuples*nbComp-1,std::ostream_iterator<double>(stream,","));
1109       stream << data[nbTuples*nbComp-1] << "};" << std::endl;
1110       stream << varName << "->useArray(" << varName << "Data,false,CPP_DEALLOC," << nbTuples << "," << nbComp << ");" << std::endl;
1111     }
1112   else
1113     stream << varName << "->alloc(" << nbTuples << "," << nbComp << ");" << std::endl;
1114   stream << varName << "->setName(\"" << getName() << "\");" << std::endl;
1115 }
1116
1117 /*!
1118  * Method that gives a quick overvien of \a this for python.
1119  */
1120 void DataArrayDouble::reprQuickOverview(std::ostream& stream) const throw(INTERP_KERNEL::Exception)
1121 {
1122   static const std::size_t MAX_NB_OF_BYTE_IN_REPR=300;
1123   stream << "DataArrayDouble C++ instance at " << this << ". ";
1124   if(isAllocated())
1125     {
1126       int nbOfCompo=(int)_info_on_compo.size();
1127       if(nbOfCompo>=1)
1128         {
1129           int nbOfTuples=getNumberOfTuples();
1130           stream << "Number of tuples : " << nbOfTuples << ". Number of components : " << nbOfCompo << "." << std::endl;
1131           reprQuickOverviewData(stream,MAX_NB_OF_BYTE_IN_REPR);
1132         }
1133       else
1134         stream << "Number of components : 0.";
1135     }
1136   else
1137     stream << "*** No data allocated ****";
1138 }
1139
1140 void DataArrayDouble::reprQuickOverviewData(std::ostream& stream, std::size_t maxNbOfByteInRepr) const throw(INTERP_KERNEL::Exception)
1141 {
1142   const double *data=begin();
1143   int nbOfTuples=getNumberOfTuples();
1144   int nbOfCompo=(int)_info_on_compo.size();
1145   std::ostringstream oss2; oss2 << "[";
1146   oss2.precision(17);
1147   std::string oss2Str(oss2.str());
1148   bool isFinished=true;
1149   for(int i=0;i<nbOfTuples && isFinished;i++)
1150     {
1151       if(nbOfCompo>1)
1152         {
1153           oss2 << "(";
1154           for(int j=0;j<nbOfCompo;j++,data++)
1155             {
1156               oss2 << *data;
1157               if(j!=nbOfCompo-1) oss2 << ", ";
1158             }
1159           oss2 << ")";
1160         }
1161       else
1162         oss2 << *data++;
1163       if(i!=nbOfTuples-1) oss2 << ", ";
1164       std::string oss3Str(oss2.str());
1165       if(oss3Str.length()<maxNbOfByteInRepr)
1166         oss2Str=oss3Str;
1167       else
1168         isFinished=false;
1169     }
1170   stream << oss2Str;
1171   if(!isFinished)
1172     stream << "... ";
1173   stream << "]";
1174 }
1175
1176 /*!
1177  * Equivalent to DataArrayDouble::isEqual except that if false the reason of
1178  * mismatch is given.
1179  * 
1180  * \param [in] other the instance to be compared with \a this
1181  * \param [in] prec the precision to compare numeric data of the arrays.
1182  * \param [out] reason In case of inequality returns the reason.
1183  * \sa DataArrayDouble::isEqual
1184  */
1185 bool DataArrayDouble::isEqualIfNotWhy(const DataArrayDouble& other, double prec, std::string& reason) const throw(INTERP_KERNEL::Exception)
1186 {
1187   if(!areInfoEqualsIfNotWhy(other,reason))
1188     return false;
1189   return _mem.isEqual(other._mem,prec,reason);
1190 }
1191
1192 /*!
1193  * Checks if \a this and another DataArrayDouble are fully equal. For more info see
1194  * \ref MEDCouplingArrayBasicsCompare.
1195  *  \param [in] other - an instance of DataArrayDouble to compare with \a this one.
1196  *  \param [in] prec - precision value to compare numeric data of the arrays.
1197  *  \return bool - \a true if the two arrays are equal, \a false else.
1198  */
1199 bool DataArrayDouble::isEqual(const DataArrayDouble& other, double prec) const throw(INTERP_KERNEL::Exception)
1200 {
1201   std::string tmp;
1202   return isEqualIfNotWhy(other,prec,tmp);
1203 }
1204
1205 /*!
1206  * Checks if values of \a this and another DataArrayDouble are equal. For more info see
1207  * \ref MEDCouplingArrayBasicsCompare.
1208  *  \param [in] other - an instance of DataArrayDouble to compare with \a this one.
1209  *  \param [in] prec - precision value to compare numeric data of the arrays.
1210  *  \return bool - \a true if the values of two arrays are equal, \a false else.
1211  */
1212 bool DataArrayDouble::isEqualWithoutConsideringStr(const DataArrayDouble& other, double prec) const throw(INTERP_KERNEL::Exception)
1213 {
1214   std::string tmp;
1215   return _mem.isEqual(other._mem,prec,tmp);
1216 }
1217
1218 /*!
1219  * Changes number of tuples in the array. If the new number of tuples is smaller
1220  * than the current number the array is truncated, otherwise the array is extended.
1221  *  \param [in] nbOfTuples - new number of tuples. 
1222  *  \throw If \a this is not allocated.
1223  *  \throw If \a nbOfTuples is negative.
1224  */
1225 void DataArrayDouble::reAlloc(int nbOfTuples) throw(INTERP_KERNEL::Exception)
1226 {
1227   if(nbOfTuples<0)
1228     throw INTERP_KERNEL::Exception("DataArrayDouble::reAlloc : input new number of tuples should be >=0 !");
1229   checkAllocated();
1230   _mem.reAlloc(getNumberOfComponents()*(std::size_t)nbOfTuples);
1231   declareAsNew();
1232 }
1233
1234 /*!
1235  * Creates a new DataArrayInt and assigns all (textual and numerical) data of \a this
1236  * array to the new one.
1237  *  \return DataArrayInt * - the new instance of DataArrayInt.
1238  */
1239 DataArrayInt *DataArrayDouble::convertToIntArr() const
1240 {
1241   DataArrayInt *ret=DataArrayInt::New();
1242   ret->alloc(getNumberOfTuples(),getNumberOfComponents());
1243   std::size_t nbOfVals=getNbOfElems();
1244   const double *src=getConstPointer();
1245   int *dest=ret->getPointer();
1246   std::copy(src,src+nbOfVals,dest);
1247   ret->copyStringInfoFrom(*this);
1248   return ret;
1249 }
1250
1251 /*!
1252  * Returns a new DataArrayDouble holding the same values as \a this array but differently
1253  * arranged in memory. If \a this array holds 2 components of 3 values:
1254  * \f$ x_0,x_1,x_2,y_0,y_1,y_2 \f$, then the result array holds these values arranged
1255  * as follows: \f$ x_0,y_0,x_1,y_1,x_2,y_2 \f$.
1256  *  \warning Do not confuse this method with transpose()!
1257  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1258  *          is to delete using decrRef() as it is no more needed.
1259  *  \throw If \a this is not allocated.
1260  */
1261 DataArrayDouble *DataArrayDouble::fromNoInterlace() const throw(INTERP_KERNEL::Exception)
1262 {
1263   if(_mem.isNull())
1264     throw INTERP_KERNEL::Exception("DataArrayDouble::fromNoInterlace : Not defined array !");
1265   double *tab=_mem.fromNoInterlace(getNumberOfComponents());
1266   DataArrayDouble *ret=DataArrayDouble::New();
1267   ret->useArray(tab,true,C_DEALLOC,getNumberOfTuples(),getNumberOfComponents());
1268   return ret;
1269 }
1270
1271 /*!
1272  * Returns a new DataArrayDouble holding the same values as \a this array but differently
1273  * arranged in memory. If \a this array holds 2 components of 3 values:
1274  * \f$ x_0,y_0,x_1,y_1,x_2,y_2 \f$, then the result array holds these values arranged
1275  * as follows: \f$ x_0,x_1,x_2,y_0,y_1,y_2 \f$.
1276  *  \warning Do not confuse this method with transpose()!
1277  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1278  *          is to delete using decrRef() as it is no more needed.
1279  *  \throw If \a this is not allocated.
1280  */
1281 DataArrayDouble *DataArrayDouble::toNoInterlace() const throw(INTERP_KERNEL::Exception)
1282 {
1283   if(_mem.isNull())
1284     throw INTERP_KERNEL::Exception("DataArrayDouble::toNoInterlace : Not defined array !");
1285   double *tab=_mem.toNoInterlace(getNumberOfComponents());
1286   DataArrayDouble *ret=DataArrayDouble::New();
1287   ret->useArray(tab,true,C_DEALLOC,getNumberOfTuples(),getNumberOfComponents());
1288   return ret;
1289 }
1290
1291 /*!
1292  * Permutes values of \a this array as required by \a old2New array. The values are
1293  * permuted so that \c new[ \a old2New[ i ]] = \c old[ i ]. Number of tuples remains
1294  * the same as in \this one.
1295  * If a permutation reduction is needed, substr() or selectByTupleId() should be used.
1296  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
1297  *  \param [in] old2New - C array of length equal to \a this->getNumberOfTuples()
1298  *     giving a new position for i-th old value.
1299  */
1300 void DataArrayDouble::renumberInPlace(const int *old2New) throw(INTERP_KERNEL::Exception)
1301 {
1302   checkAllocated();
1303   int nbTuples=getNumberOfTuples();
1304   int nbOfCompo=getNumberOfComponents();
1305   double *tmp=new double[nbTuples*nbOfCompo];
1306   const double *iptr=getConstPointer();
1307   for(int i=0;i<nbTuples;i++)
1308     {
1309       int v=old2New[i];
1310       if(v>=0 && v<nbTuples)
1311         std::copy(iptr+nbOfCompo*i,iptr+nbOfCompo*(i+1),tmp+nbOfCompo*v);
1312       else
1313         {
1314           std::ostringstream oss; oss << "DataArrayDouble::renumberInPlace : At place #" << i << " value is " << v << " ! Should be in [0," << nbTuples << ") !";
1315           throw INTERP_KERNEL::Exception(oss.str().c_str());
1316         }
1317     }
1318   std::copy(tmp,tmp+nbTuples*nbOfCompo,getPointer());
1319   delete [] tmp;
1320   declareAsNew();
1321 }
1322
1323 /*!
1324  * Permutes values of \a this array as required by \a new2Old array. The values are
1325  * permuted so that \c new[ i ] = \c old[ \a new2Old[ i ]]. Number of tuples remains
1326  * the same as in \this one.
1327  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
1328  *  \param [in] new2Old - C array of length equal to \a this->getNumberOfTuples()
1329  *     giving a previous position of i-th new value.
1330  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1331  *          is to delete using decrRef() as it is no more needed.
1332  */
1333 void DataArrayDouble::renumberInPlaceR(const int *new2Old) throw(INTERP_KERNEL::Exception)
1334 {
1335   checkAllocated();
1336   int nbTuples=getNumberOfTuples();
1337   int nbOfCompo=getNumberOfComponents();
1338   double *tmp=new double[nbTuples*nbOfCompo];
1339   const double *iptr=getConstPointer();
1340   for(int i=0;i<nbTuples;i++)
1341     {
1342       int v=new2Old[i];
1343       if(v>=0 && v<nbTuples)
1344         std::copy(iptr+nbOfCompo*v,iptr+nbOfCompo*(v+1),tmp+nbOfCompo*i);
1345       else
1346         {
1347           std::ostringstream oss; oss << "DataArrayDouble::renumberInPlaceR : At place #" << i << " value is " << v << " ! Should be in [0," << nbTuples << ") !";
1348           throw INTERP_KERNEL::Exception(oss.str().c_str());
1349         }
1350     }
1351   std::copy(tmp,tmp+nbTuples*nbOfCompo,getPointer());
1352   delete [] tmp;
1353   declareAsNew();
1354 }
1355
1356 /*!
1357  * Returns a copy of \a this array with values permuted as required by \a old2New array.
1358  * The values are permuted so that  \c new[ \a old2New[ i ]] = \c old[ i ].
1359  * Number of tuples in the result array remains the same as in \this one.
1360  * If a permutation reduction is needed, renumberAndReduce() should be used.
1361  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
1362  *  \param [in] old2New - C array of length equal to \a this->getNumberOfTuples()
1363  *          giving a new position for i-th old value.
1364  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1365  *          is to delete using decrRef() as it is no more needed.
1366  *  \throw If \a this is not allocated.
1367  */
1368 DataArrayDouble *DataArrayDouble::renumber(const int *old2New) const throw(INTERP_KERNEL::Exception)
1369 {
1370   checkAllocated();
1371   int nbTuples=getNumberOfTuples();
1372   int nbOfCompo=getNumberOfComponents();
1373   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
1374   ret->alloc(nbTuples,nbOfCompo);
1375   ret->copyStringInfoFrom(*this);
1376   const double *iptr=getConstPointer();
1377   double *optr=ret->getPointer();
1378   for(int i=0;i<nbTuples;i++)
1379     std::copy(iptr+nbOfCompo*i,iptr+nbOfCompo*(i+1),optr+nbOfCompo*old2New[i]);
1380   ret->copyStringInfoFrom(*this);
1381   return ret.retn();
1382 }
1383
1384 /*!
1385  * Returns a copy of \a this array with values permuted as required by \a new2Old array.
1386  * The values are permuted so that  \c new[ i ] = \c old[ \a new2Old[ i ]]. Number of
1387  * tuples in the result array remains the same as in \this one.
1388  * If a permutation reduction is needed, substr() or selectByTupleId() should be used.
1389  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
1390  *  \param [in] new2Old - C array of length equal to \a this->getNumberOfTuples()
1391  *     giving a previous position of i-th new value.
1392  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1393  *          is to delete using decrRef() as it is no more needed.
1394  */
1395 DataArrayDouble *DataArrayDouble::renumberR(const int *new2Old) const throw(INTERP_KERNEL::Exception)
1396 {
1397   checkAllocated();
1398   int nbTuples=getNumberOfTuples();
1399   int nbOfCompo=getNumberOfComponents();
1400   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
1401   ret->alloc(nbTuples,nbOfCompo);
1402   ret->copyStringInfoFrom(*this);
1403   const double *iptr=getConstPointer();
1404   double *optr=ret->getPointer();
1405   for(int i=0;i<nbTuples;i++)
1406     std::copy(iptr+nbOfCompo*new2Old[i],iptr+nbOfCompo*(new2Old[i]+1),optr+i*nbOfCompo);
1407   ret->copyStringInfoFrom(*this);
1408   return ret.retn();
1409 }
1410
1411 /*!
1412  * Returns a shorten and permuted copy of \a this array. The new DataArrayDouble is
1413  * of size \a newNbOfTuple and it's values are permuted as required by \a old2New array.
1414  * The values are permuted so that  \c new[ \a old2New[ i ]] = \c old[ i ] for all
1415  * \a old2New[ i ] >= 0. In other words every i-th tuple in \a this array, for which 
1416  * \a old2New[ i ] is negative, is missing from the result array.
1417  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
1418  *  \param [in] old2New - C array of length equal to \a this->getNumberOfTuples()
1419  *     giving a new position for i-th old tuple and giving negative position for
1420  *     for i-th old tuple that should be omitted.
1421  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1422  *          is to delete using decrRef() as it is no more needed.
1423  */
1424 DataArrayDouble *DataArrayDouble::renumberAndReduce(const int *old2New, int newNbOfTuple) const throw(INTERP_KERNEL::Exception)
1425 {
1426   checkAllocated();
1427   int nbTuples=getNumberOfTuples();
1428   int nbOfCompo=getNumberOfComponents();
1429   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
1430   ret->alloc(newNbOfTuple,nbOfCompo);
1431   const double *iptr=getConstPointer();
1432   double *optr=ret->getPointer();
1433   for(int i=0;i<nbTuples;i++)
1434     {
1435       int w=old2New[i];
1436       if(w>=0)
1437         std::copy(iptr+i*nbOfCompo,iptr+(i+1)*nbOfCompo,optr+w*nbOfCompo);
1438     }
1439   ret->copyStringInfoFrom(*this);
1440   return ret.retn();
1441 }
1442
1443 /*!
1444  * Returns a shorten and permuted copy of \a this array. The new DataArrayDouble is
1445  * of size \a new2OldEnd - \a new2OldBg and it's values are permuted as required by
1446  * \a new2OldBg array.
1447  * The values are permuted so that  \c new[ i ] = \c old[ \a new2OldBg[ i ]].
1448  * This method is equivalent to renumberAndReduce() except that convention in input is
1449  * \c new2old and \b not \c old2new.
1450  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
1451  *  \param [in] new2OldBg - pointer to the beginning of a permutation array that gives a
1452  *              tuple index in \a this array to fill the i-th tuple in the new array.
1453  *  \param [in] new2OldEnd - specifies the end of the permutation array that starts at
1454  *              \a new2OldBg, so that pointer to a tuple index (\a pi) varies as this:
1455  *              \a new2OldBg <= \a pi < \a new2OldEnd.
1456  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1457  *          is to delete using decrRef() as it is no more needed.
1458  */
1459 DataArrayDouble *DataArrayDouble::selectByTupleId(const int *new2OldBg, const int *new2OldEnd) const
1460 {
1461   checkAllocated();
1462   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
1463   int nbComp=getNumberOfComponents();
1464   ret->alloc((int)std::distance(new2OldBg,new2OldEnd),nbComp);
1465   ret->copyStringInfoFrom(*this);
1466   double *pt=ret->getPointer();
1467   const double *srcPt=getConstPointer();
1468   int i=0;
1469   for(const int *w=new2OldBg;w!=new2OldEnd;w++,i++)
1470     std::copy(srcPt+(*w)*nbComp,srcPt+((*w)+1)*nbComp,pt+i*nbComp);
1471   ret->copyStringInfoFrom(*this);
1472   return ret.retn();
1473 }
1474
1475 /*!
1476  * Returns a shorten and permuted copy of \a this array. The new DataArrayDouble is
1477  * of size \a new2OldEnd - \a new2OldBg and it's values are permuted as required by
1478  * \a new2OldBg array.
1479  * The values are permuted so that  \c new[ i ] = \c old[ \a new2OldBg[ i ]].
1480  * This method is equivalent to renumberAndReduce() except that convention in input is
1481  * \c new2old and \b not \c old2new.
1482  * This method is equivalent to selectByTupleId() except that it prevents coping data
1483  * from behind the end of \a this array.
1484  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
1485  *  \param [in] new2OldBg - pointer to the beginning of a permutation array that gives a
1486  *              tuple index in \a this array to fill the i-th tuple in the new array.
1487  *  \param [in] new2OldEnd - specifies the end of the permutation array that starts at
1488  *              \a new2OldBg, so that pointer to a tuple index (\a pi) varies as this:
1489  *              \a new2OldBg <= \a pi < \a new2OldEnd.
1490  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1491  *          is to delete using decrRef() as it is no more needed.
1492  *  \throw If \a new2OldEnd - \a new2OldBg > \a this->getNumberOfTuples().
1493  */
1494 DataArrayDouble *DataArrayDouble::selectByTupleIdSafe(const int *new2OldBg, const int *new2OldEnd) const throw(INTERP_KERNEL::Exception)
1495 {
1496   checkAllocated();
1497   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
1498   int nbComp=getNumberOfComponents();
1499   int oldNbOfTuples=getNumberOfTuples();
1500   ret->alloc((int)std::distance(new2OldBg,new2OldEnd),nbComp);
1501   ret->copyStringInfoFrom(*this);
1502   double *pt=ret->getPointer();
1503   const double *srcPt=getConstPointer();
1504   int i=0;
1505   for(const int *w=new2OldBg;w!=new2OldEnd;w++,i++)
1506     if(*w>=0 && *w<oldNbOfTuples)
1507       std::copy(srcPt+(*w)*nbComp,srcPt+((*w)+1)*nbComp,pt+i*nbComp);
1508     else
1509       throw INTERP_KERNEL::Exception("DataArrayDouble::selectByTupleIdSafe : some ids has been detected to be out of [0,this->getNumberOfTuples) !");
1510   ret->copyStringInfoFrom(*this);
1511   return ret.retn();
1512 }
1513
1514 /*!
1515  * Returns a shorten copy of \a this array. The new DataArrayDouble contains every
1516  * (\a bg + \c i * \a step)-th tuple of \a this array located before the \a end2-th
1517  * tuple. Indices of the selected tuples are the same as ones returned by the Python
1518  * command \c range( \a bg, \a end2, \a step ).
1519  * This method is equivalent to selectByTupleIdSafe() except that the input array is
1520  * not constructed explicitly.
1521  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
1522  *  \param [in] bg - index of the first tuple to copy from \a this array.
1523  *  \param [in] end2 - index of the tuple before which the tuples to copy are located.
1524  *  \param [in] step - index increment to get index of the next tuple to copy.
1525  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1526  *          is to delete using decrRef() as it is no more needed.
1527  *  \sa DataArrayDouble::substr.
1528  */
1529 DataArrayDouble *DataArrayDouble::selectByTupleId2(int bg, int end2, int step) const throw(INTERP_KERNEL::Exception)
1530 {
1531   checkAllocated();
1532   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
1533   int nbComp=getNumberOfComponents();
1534   int newNbOfTuples=GetNumberOfItemGivenBESRelative(bg,end2,step,"DataArrayDouble::selectByTupleId2 : ");
1535   ret->alloc(newNbOfTuples,nbComp);
1536   double *pt=ret->getPointer();
1537   const double *srcPt=getConstPointer()+bg*nbComp;
1538   for(int i=0;i<newNbOfTuples;i++,srcPt+=step*nbComp)
1539     std::copy(srcPt,srcPt+nbComp,pt+i*nbComp);
1540   ret->copyStringInfoFrom(*this);
1541   return ret.retn();
1542 }
1543
1544 /*!
1545  * Returns a shorten copy of \a this array. The new DataArrayDouble contains ranges
1546  * of tuples specified by \a ranges parameter.
1547  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
1548  *  \param [in] ranges - std::vector of std::pair's each of which defines a range
1549  *              of tuples in [\c begin,\c end) format.
1550  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1551  *          is to delete using decrRef() as it is no more needed.
1552  *  \throw If \a end < \a begin.
1553  *  \throw If \a end > \a this->getNumberOfTuples().
1554  *  \throw If \a this is not allocated.
1555  */
1556 DataArray *DataArrayDouble::selectByTupleRanges(const std::vector<std::pair<int,int> >& ranges) const throw(INTERP_KERNEL::Exception)
1557 {
1558   checkAllocated();
1559   int nbOfComp=getNumberOfComponents();
1560   int nbOfTuplesThis=getNumberOfTuples();
1561   if(ranges.empty())
1562     {
1563       DataArrayDouble *ret=DataArrayDouble::New();
1564       ret->alloc(0,nbOfComp);
1565       ret->copyStringInfoFrom(*this);
1566       return ret;
1567     }
1568   int ref=ranges.front().first;
1569   int nbOfTuples=0;
1570   bool isIncreasing=true;
1571   for(std::vector<std::pair<int,int> >::const_iterator it=ranges.begin();it!=ranges.end();it++)
1572     {
1573       if((*it).first<=(*it).second)
1574         {
1575           if((*it).first>=0 && (*it).second<=nbOfTuplesThis)
1576             {
1577               nbOfTuples+=(*it).second-(*it).first;
1578               if(isIncreasing)
1579                 isIncreasing=ref<=(*it).first;
1580               ref=(*it).second;
1581             }
1582           else
1583             {
1584               std::ostringstream oss; oss << "DataArrayDouble::selectByTupleRanges : on range #" << std::distance(ranges.begin(),it);
1585               oss << " (" << (*it).first << "," << (*it).second << ") is greater than number of tuples of this :" << nbOfTuples << " !";
1586               throw INTERP_KERNEL::Exception(oss.str().c_str());
1587             }
1588         }
1589       else
1590         {
1591           std::ostringstream oss; oss << "DataArrayDouble::selectByTupleRanges : on range #" << std::distance(ranges.begin(),it);
1592           oss << " (" << (*it).first << "," << (*it).second << ") end is before begin !";
1593           throw INTERP_KERNEL::Exception(oss.str().c_str());
1594         }
1595     }
1596   if(isIncreasing && nbOfTuplesThis==nbOfTuples)
1597     return deepCpy();
1598   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
1599   ret->alloc(nbOfTuples,nbOfComp);
1600   ret->copyStringInfoFrom(*this);
1601   const double *src=getConstPointer();
1602   double *work=ret->getPointer();
1603   for(std::vector<std::pair<int,int> >::const_iterator it=ranges.begin();it!=ranges.end();it++)
1604     work=std::copy(src+(*it).first*nbOfComp,src+(*it).second*nbOfComp,work);
1605   return ret.retn();
1606 }
1607
1608 /*!
1609  * Returns a shorten copy of \a this array. The new DataArrayDouble contains all
1610  * tuples starting from the \a tupleIdBg-th tuple and including all tuples located before
1611  * the \a tupleIdEnd-th one. This methods has a similar behavior as std::string::substr().
1612  * This method is a specialization of selectByTupleId2().
1613  *  \param [in] tupleIdBg - index of the first tuple to copy from \a this array.
1614  *  \param [in] tupleIdEnd - index of the tuple before which the tuples to copy are located.
1615  *          If \a tupleIdEnd == -1, all the tuples till the end of \a this array are copied.
1616  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1617  *          is to delete using decrRef() as it is no more needed.
1618  *  \throw If \a tupleIdBg < 0.
1619  *  \throw If \a tupleIdBg > \a this->getNumberOfTuples().
1620     \throw If \a tupleIdEnd != -1 && \a tupleIdEnd < \a this->getNumberOfTuples().
1621  *  \sa DataArrayDouble::selectByTupleId2
1622  */
1623 DataArrayDouble *DataArrayDouble::substr(int tupleIdBg, int tupleIdEnd) const throw(INTERP_KERNEL::Exception)
1624 {
1625   checkAllocated();
1626   int nbt=getNumberOfTuples();
1627   if(tupleIdBg<0)
1628     throw INTERP_KERNEL::Exception("DataArrayDouble::substr : The tupleIdBg parameter must be greater than 0 !");
1629   if(tupleIdBg>nbt)
1630     throw INTERP_KERNEL::Exception("DataArrayDouble::substr : The tupleIdBg parameter is greater than number of tuples !");
1631   int trueEnd=tupleIdEnd;
1632   if(tupleIdEnd!=-1)
1633     {
1634       if(tupleIdEnd>nbt)
1635         throw INTERP_KERNEL::Exception("DataArrayDouble::substr : The tupleIdBg parameter is greater or equal than number of tuples !");
1636     }
1637   else
1638     trueEnd=nbt;
1639   int nbComp=getNumberOfComponents();
1640   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
1641   ret->alloc(trueEnd-tupleIdBg,nbComp);
1642   ret->copyStringInfoFrom(*this);
1643   std::copy(getConstPointer()+tupleIdBg*nbComp,getConstPointer()+trueEnd*nbComp,ret->getPointer());
1644   return ret.retn();
1645 }
1646
1647 /*!
1648  * Returns a shorten or extended copy of \a this array. If \a newNbOfComp is less
1649  * than \a this->getNumberOfComponents() then the result array is shorten as each tuple
1650  * is truncated to have \a newNbOfComp components, keeping first components. If \a
1651  * newNbOfComp is more than \a this->getNumberOfComponents() then the result array is
1652  * expanded as each tuple is populated with \a dftValue to have \a newNbOfComp
1653  * components.  
1654  *  \param [in] newNbOfComp - number of components for the new array to have.
1655  *  \param [in] dftValue - value assigned to new values added to the new array.
1656  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1657  *          is to delete using decrRef() as it is no more needed.
1658  *  \throw If \a this is not allocated.
1659  */
1660 DataArrayDouble *DataArrayDouble::changeNbOfComponents(int newNbOfComp, double dftValue) const throw(INTERP_KERNEL::Exception)
1661 {
1662   checkAllocated();
1663   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
1664   ret->alloc(getNumberOfTuples(),newNbOfComp);
1665   const double *oldc=getConstPointer();
1666   double *nc=ret->getPointer();
1667   int nbOfTuples=getNumberOfTuples();
1668   int oldNbOfComp=getNumberOfComponents();
1669   int dim=std::min(oldNbOfComp,newNbOfComp);
1670   for(int i=0;i<nbOfTuples;i++)
1671     {
1672       int j=0;
1673       for(;j<dim;j++)
1674         nc[newNbOfComp*i+j]=oldc[i*oldNbOfComp+j];
1675       for(;j<newNbOfComp;j++)
1676         nc[newNbOfComp*i+j]=dftValue;
1677     }
1678   ret->setName(getName().c_str());
1679   for(int i=0;i<dim;i++)
1680     ret->setInfoOnComponent(i,getInfoOnComponent(i).c_str());
1681   ret->setName(getName().c_str());
1682   return ret.retn();
1683 }
1684
1685 /*!
1686  * Changes the number of components within \a this array so that its raw data **does
1687  * not** change, instead splitting this data into tuples changes.
1688  *  \warning This method erases all (name and unit) component info set before!
1689  *  \param [in] newNbOfComp - number of components for \a this array to have.
1690  *  \throw If \a this is not allocated
1691  *  \throw If getNbOfElems() % \a newNbOfCompo != 0.
1692  *  \throw If \a newNbOfCompo is lower than 1.
1693  *  \throw If the rearrange method would lead to a number of tuples higher than 2147483647 (maximal capacity of int32 !).
1694  *  \warning This method erases all (name and unit) component info set before!
1695  */
1696 void DataArrayDouble::rearrange(int newNbOfCompo) throw(INTERP_KERNEL::Exception)
1697 {
1698   checkAllocated();
1699   if(newNbOfCompo<1)
1700     throw INTERP_KERNEL::Exception("DataArrayDouble::rearrange : input newNbOfCompo must be > 0 !");
1701   std::size_t nbOfElems=getNbOfElems();
1702   if(nbOfElems%newNbOfCompo!=0)
1703     throw INTERP_KERNEL::Exception("DataArrayDouble::rearrange : nbOfElems%newNbOfCompo!=0 !");
1704   if(nbOfElems/newNbOfCompo>(std::size_t)std::numeric_limits<int>::max())
1705     throw INTERP_KERNEL::Exception("DataArrayDouble::rearrange : the rearrangement leads to too high number of tuples (> 2147483647) !");
1706   _info_on_compo.clear();
1707   _info_on_compo.resize(newNbOfCompo);
1708   declareAsNew();
1709 }
1710
1711 /*!
1712  * Changes the number of components within \a this array to be equal to its number
1713  * of tuples, and inversely its number of tuples to become equal to its number of 
1714  * components. So that its raw data **does not** change, instead splitting this
1715  * data into tuples changes.
1716  *  \warning This method erases all (name and unit) component info set before!
1717  *  \warning Do not confuse this method with fromNoInterlace() and toNoInterlace()!
1718  *  \throw If \a this is not allocated.
1719  *  \sa rearrange()
1720  */
1721 void DataArrayDouble::transpose() throw(INTERP_KERNEL::Exception)
1722 {
1723   checkAllocated();
1724   int nbOfTuples=getNumberOfTuples();
1725   rearrange(nbOfTuples);
1726 }
1727
1728 /*!
1729  * Returns a copy of \a this array composed of selected components.
1730  * The new DataArrayDouble has the same number of tuples but includes components
1731  * specified by \a compoIds parameter. So that getNbOfElems() of the result array
1732  * can be either less, same or more than \a this->getNbOfElems().
1733  *  \param [in] compoIds - sequence of zero based indices of components to include
1734  *              into the new array.
1735  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1736  *          is to delete using decrRef() as it is no more needed.
1737  *  \throw If \a this is not allocated.
1738  *  \throw If a component index (\a i) is not valid: 
1739  *         \a i < 0 || \a i >= \a this->getNumberOfComponents().
1740  *
1741  *  \ref py_mcdataarraydouble_KeepSelectedComponents "Here is a Python example".
1742  */
1743 DataArray *DataArrayDouble::keepSelectedComponents(const std::vector<int>& compoIds) const throw(INTERP_KERNEL::Exception)
1744 {
1745   checkAllocated();
1746   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret(DataArrayDouble::New());
1747   std::size_t newNbOfCompo=compoIds.size();
1748   int oldNbOfCompo=getNumberOfComponents();
1749   for(std::vector<int>::const_iterator it=compoIds.begin();it!=compoIds.end();it++)
1750     if((*it)<0 || (*it)>=oldNbOfCompo)
1751       {
1752         std::ostringstream oss; oss << "DataArrayDouble::keepSelectedComponents : invalid requested component : " << *it << " whereas it should be in [0," << oldNbOfCompo << ") !";
1753         throw INTERP_KERNEL::Exception(oss.str().c_str());
1754       }
1755   int nbOfTuples=getNumberOfTuples();
1756   ret->alloc(nbOfTuples,(int)newNbOfCompo);
1757   ret->copyPartOfStringInfoFrom(*this,compoIds);
1758   const double *oldc=getConstPointer();
1759   double *nc=ret->getPointer();
1760   for(int i=0;i<nbOfTuples;i++)
1761     for(std::size_t j=0;j<newNbOfCompo;j++,nc++)
1762       *nc=oldc[i*oldNbOfCompo+compoIds[j]];
1763   return ret.retn();
1764 }
1765
1766 /*!
1767  * Appends components of another array to components of \a this one, tuple by tuple.
1768  * So that the number of tuples of \a this array remains the same and the number of 
1769  * components increases.
1770  *  \param [in] other - the DataArrayDouble to append to \a this one.
1771  *  \throw If \a this is not allocated.
1772  *  \throw If \a this and \a other arrays have different number of tuples.
1773  *
1774  *  \ref cpp_mcdataarraydouble_meldwith "Here is a C++ example".
1775  *
1776  *  \ref py_mcdataarraydouble_meldwith "Here is a Python example".
1777  */
1778 void DataArrayDouble::meldWith(const DataArrayDouble *other) throw(INTERP_KERNEL::Exception)
1779 {
1780   checkAllocated();
1781   other->checkAllocated();
1782   int nbOfTuples=getNumberOfTuples();
1783   if(nbOfTuples!=other->getNumberOfTuples())
1784     throw INTERP_KERNEL::Exception("DataArrayDouble::meldWith : mismatch of number of tuples !");
1785   int nbOfComp1=getNumberOfComponents();
1786   int nbOfComp2=other->getNumberOfComponents();
1787   double *newArr=(double *)malloc((nbOfTuples*(nbOfComp1+nbOfComp2))*sizeof(double));
1788   double *w=newArr;
1789   const double *inp1=getConstPointer();
1790   const double *inp2=other->getConstPointer();
1791   for(int i=0;i<nbOfTuples;i++,inp1+=nbOfComp1,inp2+=nbOfComp2)
1792     {
1793       w=std::copy(inp1,inp1+nbOfComp1,w);
1794       w=std::copy(inp2,inp2+nbOfComp2,w);
1795     }
1796   useArray(newArr,true,C_DEALLOC,nbOfTuples,nbOfComp1+nbOfComp2);
1797   std::vector<int> compIds(nbOfComp2);
1798   for(int i=0;i<nbOfComp2;i++)
1799     compIds[i]=nbOfComp1+i;
1800   copyPartOfStringInfoFrom2(compIds,*other);
1801 }
1802
1803 /*!
1804  * This method checks that all tuples in \a other are in \a this.
1805  * If true, the output param \a tupleIds contains the tuples ids of \a this that correspond to tupes in \a this.
1806  * For each i in [ 0 , other->getNumberOfTuples() ) tuple #i in \a other is equal ( regarding input precision \a prec ) to tuple tupleIds[i] in \a this.
1807  *
1808  * \param [in] other - the array having the same number of components than \a this.
1809  * \param [out] tupleIds - the tuple ids containing the same number of tuples than \a other has.
1810  * \sa DataArrayDouble::findCommonTuples
1811  */
1812 bool DataArrayDouble::areIncludedInMe(const DataArrayDouble *other, double prec, DataArrayInt *&tupleIds) const throw(INTERP_KERNEL::Exception)
1813 {
1814   if(!other)
1815     throw INTERP_KERNEL::Exception("DataArrayDouble::areIncludedInMe : input array is NULL !");
1816   checkAllocated(); other->checkAllocated();
1817   if(getNumberOfComponents()!=other->getNumberOfComponents())
1818     throw INTERP_KERNEL::Exception("DataArrayDouble::areIncludedInMe : the number of components does not match !");
1819   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> a=DataArrayDouble::Aggregate(this,other);
1820   DataArrayInt *c=0,*ci=0;
1821   a->findCommonTuples(prec,getNumberOfTuples(),c,ci);
1822   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cSafe(c),ciSafe(ci);
1823   int newNbOfTuples=-1;
1824   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ids=DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2(a->getNumberOfTuples(),c->begin(),ci->begin(),ci->end(),newNbOfTuples);
1825   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret1=ids->selectByTupleId2(getNumberOfTuples(),a->getNumberOfTuples(),1);
1826   tupleIds=ret1.retn();
1827   return newNbOfTuples==getNumberOfTuples();
1828 }
1829
1830 /*!
1831  * Searches for tuples coincident within \a prec tolerance. Each tuple is considered
1832  * as coordinates of a point in getNumberOfComponents()-dimensional space. The
1833  * distance separating two points is computed with the infinite norm.
1834  *
1835  * Indices of coincident tuples are stored in output arrays.
1836  * A pair of arrays (\a comm, \a commIndex) is called "Surjective Format 2".
1837  *
1838  * This method is typically used by MEDCouplingPointSet::findCommonNodes() and
1839  * MEDCouplingUMesh::mergeNodes().
1840  *  \param [in] prec - minimal absolute distance between two tuples (infinite norm) at which they are
1841  *              considered not coincident.
1842  *  \param [in] limitTupleId - limit tuple id. If all tuples within a group of coincident
1843  *              tuples have id strictly lower than \a limitTupleId then they are not returned.
1844  *  \param [out] comm - the array holding ids (== indices) of coincident tuples. 
1845  *               \a comm->getNumberOfComponents() == 1. 
1846  *               \a comm->getNumberOfTuples() == \a commIndex->back().
1847  *  \param [out] commIndex - the array dividing all indices stored in \a comm into
1848  *               groups of (indices of) coincident tuples. Its every value is a tuple
1849  *               index where a next group of tuples begins. For example the second
1850  *               group of tuples in \a comm is described by following range of indices:
1851  *               [ \a commIndex[1], \a commIndex[2] ). \a commIndex->getNumberOfTuples()-1
1852  *               gives the number of groups of coincident tuples.
1853  *  \throw If \a this is not allocated.
1854  *  \throw If the number of components is not in [1,2,3].
1855  *
1856  *  \ref cpp_mcdataarraydouble_findcommontuples "Here is a C++ example".
1857  *
1858  *  \ref py_mcdataarraydouble_findcommontuples  "Here is a Python example".
1859  *  \sa DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2(), DataArrayDouble::areIncludedInMe
1860  */
1861 void DataArrayDouble::findCommonTuples(double prec, int limitTupleId, DataArrayInt *&comm, DataArrayInt *&commIndex) const throw(INTERP_KERNEL::Exception)
1862 {
1863   checkAllocated();
1864   int nbOfCompo=getNumberOfComponents();
1865   if ((nbOfCompo<1) || (nbOfCompo>3)) //test before work
1866     throw INTERP_KERNEL::Exception("DataArrayDouble::findCommonTuples : Unexpected spacedim of coords. Must be 1, 2 or 3.");
1867   
1868   int nbOfTuples=getNumberOfTuples();
1869   //
1870   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> c(DataArrayInt::New()),cI(DataArrayInt::New()); c->alloc(0,1); cI->pushBackSilent(0);
1871   switch(nbOfCompo)
1872     {
1873     case 3:
1874       findCommonTuplesAlg<3>(begin(),nbOfTuples,limitTupleId,prec,c,cI);
1875       break;
1876     case 2:
1877       findCommonTuplesAlg<2>(begin(),nbOfTuples,limitTupleId,prec,c,cI);
1878       break;
1879     case 1:
1880       findCommonTuplesAlg<1>(begin(),nbOfTuples,limitTupleId,prec,c,cI);
1881       break;
1882     default:
1883       throw INTERP_KERNEL::Exception("DataArrayDouble::findCommonTuples : nb of components managed are 1,2 and 3 ! not implemented for other number of components !");
1884     }
1885   comm=c.retn();
1886   commIndex=cI.retn();
1887 }
1888
1889 /*!
1890  * 
1891  * \param [in] nbTimes specifies the nb of times each tuples in \a this will be duplicated contiguouly in returned DataArrayDouble instance.
1892  *             \a nbTimes  should be at least equal to 1.
1893  * \return a newly allocated DataArrayDouble having one component and number of tuples equal to \a nbTimes * \c this->getNumberOfTuples.
1894  * \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.
1895  */
1896 DataArrayDouble *DataArrayDouble::duplicateEachTupleNTimes(int nbTimes) const throw(INTERP_KERNEL::Exception)
1897 {
1898   checkAllocated();
1899   if(getNumberOfComponents()!=1)
1900     throw INTERP_KERNEL::Exception("DataArrayDouble::duplicateEachTupleNTimes : this should have only one component !");
1901   if(nbTimes<1)
1902     throw INTERP_KERNEL::Exception("DataArrayDouble::duplicateEachTupleNTimes : nb times should be >= 1 !");
1903   int nbTuples=getNumberOfTuples();
1904   const double *inPtr=getConstPointer();
1905   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New(); ret->alloc(nbTimes*nbTuples,1);
1906   double *retPtr=ret->getPointer();
1907   for(int i=0;i<nbTuples;i++,inPtr++)
1908     {
1909       double val=*inPtr;
1910       for(int j=0;j<nbTimes;j++,retPtr++)
1911         *retPtr=val;
1912     }
1913   ret->copyStringInfoFrom(*this);
1914   return ret.retn();
1915 }
1916
1917 /*!
1918  * This methods returns the minimal distance between the two set of points \a this and \a other.
1919  * So \a this and \a other have to have the same number of components. If not an INTERP_KERNEL::Exception will be thrown.
1920  * This method works only if number of components of \a this (equal to those of \a other) is in 1, 2 or 3.
1921  *
1922  * \param [out] thisTupleId the tuple id in \a this corresponding to the returned minimal distance
1923  * \param [out] otherTupleId the tuple id in \a other corresponding to the returned minimal distance
1924  * \return the minimal distance between the two set of points \a this and \a other.
1925  * \sa DataArrayDouble::findClosestTupleId
1926  */
1927 double DataArrayDouble::minimalDistanceTo(const DataArrayDouble *other, int& thisTupleId, int& otherTupleId) const throw(INTERP_KERNEL::Exception)
1928 {
1929   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> part1=findClosestTupleId(other);
1930   int nbOfCompo(getNumberOfComponents());
1931   int otherNbTuples(other->getNumberOfTuples());
1932   const double *thisPt(begin()),*otherPt(other->begin());
1933   const int *part1Pt(part1->begin());
1934   double ret=std::numeric_limits<double>::max();
1935   for(int i=0;i<otherNbTuples;i++,part1Pt++,otherPt+=nbOfCompo)
1936     {
1937       double tmp(0.);
1938       for(int j=0;j<nbOfCompo;j++)
1939         tmp+=(otherPt[j]-thisPt[nbOfCompo*(*part1Pt)+j])*(otherPt[j]-thisPt[nbOfCompo*(*part1Pt)+j]);
1940       if(tmp<ret)
1941         { ret=tmp; thisTupleId=*part1Pt; otherTupleId=i; }
1942     }
1943   return sqrt(ret);
1944 }
1945
1946 /*!
1947  * This methods returns for each tuple in \a other which tuple in \a this is the closest.
1948  * So \a this and \a other have to have the same number of components. If not an INTERP_KERNEL::Exception will be thrown.
1949  * This method works only if number of components of \a this (equal to those of \a other) is in 1, 2 or 3.
1950  *
1951  * \return a newly allocated (new object to be dealt by the caller) DataArrayInt having \c other->getNumberOfTuples() tuples and one components.
1952  * \sa DataArrayDouble::minimalDistanceTo
1953  */
1954 DataArrayInt *DataArrayDouble::findClosestTupleId(const DataArrayDouble *other) const throw(INTERP_KERNEL::Exception)
1955 {
1956   if(!other)
1957     throw INTERP_KERNEL::Exception("DataArrayDouble::findClosestTupleId : other instance is NULL !");
1958   checkAllocated(); other->checkAllocated();
1959   int nbOfCompo=getNumberOfComponents();
1960   if(nbOfCompo!=other->getNumberOfComponents())
1961     {
1962       std::ostringstream oss; oss << "DataArrayDouble::findClosestTupleId : number of components in this is " << nbOfCompo;
1963       oss << ", whereas number of components in other is " << other->getNumberOfComponents() << "! Should be equal !";
1964       throw INTERP_KERNEL::Exception(oss.str().c_str());
1965     }
1966   int nbOfTuples=other->getNumberOfTuples();
1967   int thisNbOfTuples=getNumberOfTuples();
1968   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbOfTuples,1);
1969   double bounds[6];
1970   getMinMaxPerComponent(bounds);
1971   switch(nbOfCompo)
1972     {
1973     case 3:
1974       {
1975         double xDelta(fabs(bounds[1]-bounds[0])),yDelta(fabs(bounds[3]-bounds[2])),zDelta(fabs(bounds[5]-bounds[4]));
1976         double delta=std::max(xDelta,yDelta); delta=std::max(delta,zDelta);
1977         double characSize=pow((delta*delta*delta)/((double)thisNbOfTuples),1./3.);
1978         BBTreePts<3,int> myTree(begin(),0,0,getNumberOfTuples(),characSize*1e-12);
1979         FindClosestTupleIdAlg<3>(myTree,3.*characSize*characSize,other->begin(),nbOfTuples,begin(),thisNbOfTuples,ret->getPointer());
1980         break;
1981       }
1982     case 2:
1983       {
1984         double xDelta(fabs(bounds[1]-bounds[0])),yDelta(fabs(bounds[3]-bounds[2]));
1985         double delta=std::max(xDelta,yDelta);
1986         double characSize=sqrt(delta/(double)thisNbOfTuples);
1987         BBTreePts<2,int> myTree(begin(),0,0,getNumberOfTuples(),characSize*1e-12);
1988         FindClosestTupleIdAlg<2>(myTree,2.*characSize*characSize,other->begin(),nbOfTuples,begin(),thisNbOfTuples,ret->getPointer());
1989         break;
1990       }
1991     case 1:
1992       {
1993         double characSize=fabs(bounds[1]-bounds[0])/thisNbOfTuples;
1994         BBTreePts<1,int> myTree(begin(),0,0,getNumberOfTuples(),characSize*1e-12);
1995         FindClosestTupleIdAlg<1>(myTree,1.*characSize*characSize,other->begin(),nbOfTuples,begin(),thisNbOfTuples,ret->getPointer());
1996         break;
1997       }
1998     default:
1999       throw INTERP_KERNEL::Exception("Unexpected spacedim of coords for findClosestTupleId. Must be 1, 2 or 3.");
2000     }
2001   return ret.retn();
2002 }
2003
2004 /*!
2005  * Returns a copy of \a this array by excluding coincident tuples. Each tuple is
2006  * considered as coordinates of a point in getNumberOfComponents()-dimensional
2007  * space. The distance between tuples is computed using norm2. If several tuples are
2008  * not far each from other than \a prec, only one of them remains in the result
2009  * array. The order of tuples in the result array is same as in \a this one except
2010  * that coincident tuples are excluded.
2011  *  \param [in] prec - minimal absolute distance between two tuples at which they are
2012  *              considered not coincident.
2013  *  \param [in] limitTupleId - limit tuple id. If all tuples within a group of coincident
2014  *              tuples have id strictly lower than \a limitTupleId then they are not excluded.
2015  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
2016  *          is to delete using decrRef() as it is no more needed.
2017  *  \throw If \a this is not allocated.
2018  *  \throw If the number of components is not in [1,2,3].
2019  *
2020  *  \ref py_mcdataarraydouble_getdifferentvalues "Here is a Python example".
2021  */
2022 DataArrayDouble *DataArrayDouble::getDifferentValues(double prec, int limitTupleId) const throw(INTERP_KERNEL::Exception)
2023 {
2024   checkAllocated();
2025   DataArrayInt *c0=0,*cI0=0;
2026   findCommonTuples(prec,limitTupleId,c0,cI0);
2027   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> c(c0),cI(cI0);
2028   int newNbOfTuples=-1;
2029   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> o2n=DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2(getNumberOfTuples(),c0->begin(),cI0->begin(),cI0->end(),newNbOfTuples);
2030   return renumberAndReduce(o2n->getConstPointer(),newNbOfTuples);
2031 }
2032
2033 /*!
2034  * Copy all components in a specified order from another DataArrayDouble.
2035  * Both numerical and textual data is copied. The number of tuples in \a this and
2036  * the other array can be different.
2037  *  \param [in] a - the array to copy data from.
2038  *  \param [in] compoIds - sequence of zero based indices of components, data of which is
2039  *              to be copied.
2040  *  \throw If \a a is NULL.
2041  *  \throw If \a compoIds.size() != \a a->getNumberOfComponents().
2042  *  \throw If \a compoIds[i] < 0 or \a compoIds[i] > \a this->getNumberOfComponents().
2043  *
2044  *  \ref py_mcdataarraydouble_setselectedcomponents "Here is a Python example".
2045  */
2046 void DataArrayDouble::setSelectedComponents(const DataArrayDouble *a, const std::vector<int>& compoIds) throw(INTERP_KERNEL::Exception)
2047 {
2048   if(!a)
2049     throw INTERP_KERNEL::Exception("DataArrayDouble::setSelectedComponents : input DataArrayDouble is NULL !");
2050   checkAllocated();
2051   copyPartOfStringInfoFrom2(compoIds,*a);
2052   std::size_t partOfCompoSz=compoIds.size();
2053   int nbOfCompo=getNumberOfComponents();
2054   int nbOfTuples=std::min(getNumberOfTuples(),a->getNumberOfTuples());
2055   const double *ac=a->getConstPointer();
2056   double *nc=getPointer();
2057   for(int i=0;i<nbOfTuples;i++)
2058     for(std::size_t j=0;j<partOfCompoSz;j++,ac++)
2059       nc[nbOfCompo*i+compoIds[j]]=*ac;
2060 }
2061
2062 /*!
2063  * Copy all values from another DataArrayDouble into specified tuples and components
2064  * of \a this array. Textual data is not copied.
2065  * The tree parameters defining set of indices of tuples and components are similar to
2066  * the tree parameters of the Python function \c range(\c start,\c stop,\c step).
2067  *  \param [in] a - the array to copy values from.
2068  *  \param [in] bgTuples - index of the first tuple of \a this array to assign values to.
2069  *  \param [in] endTuples - index of the tuple before which the tuples to assign to
2070  *              are located.
2071  *  \param [in] stepTuples - index increment to get index of the next tuple to assign to.
2072  *  \param [in] bgComp - index of the first component of \a this array to assign values to.
2073  *  \param [in] endComp - index of the component before which the components to assign
2074  *              to are located.
2075  *  \param [in] stepComp - index increment to get index of the next component to assign to.
2076  *  \param [in] strictCompoCompare - if \a true (by default), then \a a->getNumberOfComponents() 
2077  *              must be equal to the number of columns to assign to, else an
2078  *              exception is thrown; if \a false, then it is only required that \a
2079  *              a->getNbOfElems() equals to number of values to assign to (this condition
2080  *              must be respected even if \a strictCompoCompare is \a true). The number of 
2081  *              values to assign to is given by following Python expression:
2082  *              \a nbTargetValues = 
2083  *              \c len(\c range(\a bgTuples,\a endTuples,\a stepTuples)) *
2084  *              \c len(\c range(\a bgComp,\a endComp,\a stepComp)).
2085  *  \throw If \a a is NULL.
2086  *  \throw If \a a is not allocated.
2087  *  \throw If \a this is not allocated.
2088  *  \throw If parameters specifying tuples and components to assign to do not give a
2089  *            non-empty range of increasing indices.
2090  *  \throw If \a a->getNbOfElems() != \a nbTargetValues.
2091  *  \throw If \a strictCompoCompare == \a true && \a a->getNumberOfComponents() !=
2092  *            \c len(\c range(\a bgComp,\a endComp,\a stepComp)).
2093  *
2094  *  \ref py_mcdataarraydouble_setpartofvalues1 "Here is a Python example".
2095  */
2096 void DataArrayDouble::setPartOfValues1(const DataArrayDouble *a, int bgTuples, int endTuples, int stepTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare) throw(INTERP_KERNEL::Exception)
2097 {
2098   if(!a)
2099     throw INTERP_KERNEL::Exception("DataArrayDouble::setPartOfValues1 : input DataArrayDouble is NULL !");
2100   const char msg[]="DataArrayDouble::setPartOfValues1";
2101   checkAllocated();
2102   a->checkAllocated();
2103   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
2104   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
2105   int nbComp=getNumberOfComponents();
2106   int nbOfTuples=getNumberOfTuples();
2107   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
2108   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
2109   bool assignTech=true;
2110   if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
2111     {
2112       if(strictCompoCompare)
2113         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
2114     }
2115   else
2116     {
2117       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
2118       assignTech=false;
2119     }
2120   const double *srcPt=a->getConstPointer();
2121   double *pt=getPointer()+bgTuples*nbComp+bgComp;
2122   if(assignTech)
2123     {
2124       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
2125         for(int j=0;j<newNbOfComp;j++,srcPt++)
2126           pt[j*stepComp]=*srcPt;
2127     }
2128   else
2129     {
2130       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
2131         {
2132           const double *srcPt2=srcPt;
2133           for(int j=0;j<newNbOfComp;j++,srcPt2++)
2134             pt[j*stepComp]=*srcPt2;
2135         }
2136     }
2137 }
2138
2139 /*!
2140  * Assign a given value to values at specified tuples and components of \a this array.
2141  * The tree parameters defining set of indices of tuples and components are similar to
2142  * the tree parameters of the Python function \c range(\c start,\c stop,\c step)..
2143  *  \param [in] a - the value to assign.
2144  *  \param [in] bgTuples - index of the first tuple of \a this array to assign to.
2145  *  \param [in] endTuples - index of the tuple before which the tuples to assign to
2146  *              are located.
2147  *  \param [in] stepTuples - index increment to get index of the next tuple to assign to.
2148  *  \param [in] bgComp - index of the first component of \a this array to assign to.
2149  *  \param [in] endComp - index of the component before which the components to assign
2150  *              to are located.
2151  *  \param [in] stepComp - index increment to get index of the next component to assign to.
2152  *  \throw If \a this is not allocated.
2153  *  \throw If parameters specifying tuples and components to assign to, do not give a
2154  *            non-empty range of increasing indices or indices are out of a valid range
2155  *            for \this array.
2156  *
2157  *  \ref py_mcdataarraydouble_setpartofvaluessimple1 "Here is a Python example".
2158  */
2159 void DataArrayDouble::setPartOfValuesSimple1(double a, int bgTuples, int endTuples, int stepTuples, int bgComp, int endComp, int stepComp) throw(INTERP_KERNEL::Exception)
2160 {
2161   const char msg[]="DataArrayDouble::setPartOfValuesSimple1";
2162   checkAllocated();
2163   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
2164   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
2165   int nbComp=getNumberOfComponents();
2166   int nbOfTuples=getNumberOfTuples();
2167   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
2168   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
2169   double *pt=getPointer()+bgTuples*nbComp+bgComp;
2170   for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
2171     for(int j=0;j<newNbOfComp;j++)
2172       pt[j*stepComp]=a;
2173 }
2174
2175 /*!
2176  * Copy all values from another DataArrayDouble (\a a) into specified tuples and 
2177  * components of \a this array. Textual data is not copied.
2178  * The tuples and components to assign to are defined by C arrays of indices.
2179  * There are two *modes of usage*:
2180  * - If \a a->getNbOfElems() equals to number of values to assign to, then every value
2181  *   of \a a is assigned to its own location within \a this array. 
2182  * - If \a a includes one tuple, then all values of \a a are assigned to the specified
2183  *   components of every specified tuple of \a this array. In this mode it is required
2184  *   that \a a->getNumberOfComponents() equals to the number of specified components.
2185  *
2186  *  \param [in] a - the array to copy values from.
2187  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
2188  *              assign values of \a a to.
2189  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
2190  *              pointer to a tuple index <em>(pi)</em> varies as this: 
2191  *              \a bgTuples <= \a pi < \a endTuples.
2192  *  \param [in] bgComp - pointer to an array of component indices of \a this array to
2193  *              assign values of \a a to.
2194  *  \param [in] endComp - specifies the end of the array \a bgTuples, so that
2195  *              pointer to a component index <em>(pi)</em> varies as this: 
2196  *              \a bgComp <= \a pi < \a endComp.
2197  *  \param [in] strictCompoCompare - this parameter is checked only if the
2198  *               *mode of usage* is the first; if it is \a true (default), 
2199  *               then \a a->getNumberOfComponents() must be equal 
2200  *               to the number of specified columns, else this is not required.
2201  *  \throw If \a a is NULL.
2202  *  \throw If \a a is not allocated.
2203  *  \throw If \a this is not allocated.
2204  *  \throw If any index of tuple/component given by <em>bgTuples / bgComp</em> is
2205  *         out of a valid range for \a this array.
2206  *  \throw In the first *mode of usage*, if <em>strictCompoCompare == true </em> and
2207  *         if <em> a->getNumberOfComponents() != (endComp - bgComp) </em>.
2208  *  \throw In the second *mode of usage*, if \a a->getNumberOfTuples() != 1 or
2209  *         <em> a->getNumberOfComponents() != (endComp - bgComp)</em>.
2210  *
2211  *  \ref py_mcdataarraydouble_setpartofvalues2 "Here is a Python example".
2212  */
2213 void DataArrayDouble::setPartOfValues2(const DataArrayDouble *a, const int *bgTuples, const int *endTuples, const int *bgComp, const int *endComp, bool strictCompoCompare) throw(INTERP_KERNEL::Exception)
2214 {
2215   if(!a)
2216     throw INTERP_KERNEL::Exception("DataArrayDouble::setPartOfValues2 : input DataArrayDouble is NULL !");
2217   const char msg[]="DataArrayDouble::setPartOfValues2";
2218   checkAllocated();
2219   a->checkAllocated();
2220   int nbComp=getNumberOfComponents();
2221   int nbOfTuples=getNumberOfTuples();
2222   for(const int *z=bgComp;z!=endComp;z++)
2223     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
2224   int newNbOfTuples=(int)std::distance(bgTuples,endTuples);
2225   int newNbOfComp=(int)std::distance(bgComp,endComp);
2226   bool assignTech=true;
2227   if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
2228     {
2229       if(strictCompoCompare)
2230         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
2231     }
2232   else
2233     {
2234       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
2235       assignTech=false;
2236     }
2237   double *pt=getPointer();
2238   const double *srcPt=a->getConstPointer();
2239   if(assignTech)
2240     {    
2241       for(const int *w=bgTuples;w!=endTuples;w++)
2242         {
2243           DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
2244           for(const int *z=bgComp;z!=endComp;z++,srcPt++)
2245             {    
2246               pt[(std::size_t)(*w)*nbComp+(*z)]=*srcPt;
2247             }
2248         }
2249     }
2250   else
2251     {
2252       for(const int *w=bgTuples;w!=endTuples;w++)
2253         {
2254           const double *srcPt2=srcPt;
2255           DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
2256           for(const int *z=bgComp;z!=endComp;z++,srcPt2++)
2257             {    
2258               pt[(std::size_t)(*w)*nbComp+(*z)]=*srcPt2;
2259             }
2260         }
2261     }
2262 }
2263
2264 /*!
2265  * Assign a given value to values at specified tuples and components of \a this array.
2266  * The tuples and components to assign to are defined by C arrays of indices.
2267  *  \param [in] a - the value to assign.
2268  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
2269  *              assign \a a to.
2270  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
2271  *              pointer to a tuple index (\a pi) varies as this: 
2272  *              \a bgTuples <= \a pi < \a endTuples.
2273  *  \param [in] bgComp - pointer to an array of component indices of \a this array to
2274  *              assign \a a to.
2275  *  \param [in] endComp - specifies the end of the array \a bgTuples, so that
2276  *              pointer to a component index (\a pi) varies as this: 
2277  *              \a bgComp <= \a pi < \a endComp.
2278  *  \throw If \a this is not allocated.
2279  *  \throw If any index of tuple/component given by <em>bgTuples / bgComp</em> is
2280  *         out of a valid range for \a this array.
2281  *
2282  *  \ref py_mcdataarraydouble_setpartofvaluessimple2 "Here is a Python example".
2283  */
2284 void DataArrayDouble::setPartOfValuesSimple2(double a, const int *bgTuples, const int *endTuples, const int *bgComp, const int *endComp) throw(INTERP_KERNEL::Exception)
2285 {
2286   checkAllocated();
2287   int nbComp=getNumberOfComponents();
2288   int nbOfTuples=getNumberOfTuples();
2289   for(const int *z=bgComp;z!=endComp;z++)
2290     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
2291   double *pt=getPointer();
2292   for(const int *w=bgTuples;w!=endTuples;w++)
2293     for(const int *z=bgComp;z!=endComp;z++)
2294       {
2295         DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
2296         pt[(std::size_t)(*w)*nbComp+(*z)]=a;
2297       }
2298 }
2299
2300 /*!
2301  * Copy all values from another DataArrayDouble (\a a) into specified tuples and 
2302  * components of \a this array. Textual data is not copied.
2303  * The tuples to assign to are defined by a C array of indices.
2304  * The components to assign to are defined by three values similar to parameters of
2305  * the Python function \c range(\c start,\c stop,\c step).
2306  * There are two *modes of usage*:
2307  * - If \a a->getNbOfElems() equals to number of values to assign to, then every value
2308  *   of \a a is assigned to its own location within \a this array. 
2309  * - If \a a includes one tuple, then all values of \a a are assigned to the specified
2310  *   components of every specified tuple of \a this array. In this mode it is required
2311  *   that \a a->getNumberOfComponents() equals to the number of specified components.
2312  *
2313  *  \param [in] a - the array to copy values from.
2314  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
2315  *              assign values of \a a to.
2316  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
2317  *              pointer to a tuple index <em>(pi)</em> varies as this: 
2318  *              \a bgTuples <= \a pi < \a endTuples.
2319  *  \param [in] bgComp - index of the first component of \a this array to assign to.
2320  *  \param [in] endComp - index of the component before which the components to assign
2321  *              to are located.
2322  *  \param [in] stepComp - index increment to get index of the next component to assign to.
2323  *  \param [in] strictCompoCompare - this parameter is checked only in the first
2324  *               *mode of usage*; if \a strictCompoCompare is \a true (default), 
2325  *               then \a a->getNumberOfComponents() must be equal 
2326  *               to the number of specified columns, else this is not required.
2327  *  \throw If \a a is NULL.
2328  *  \throw If \a a is not allocated.
2329  *  \throw If \a this is not allocated.
2330  *  \throw If any index of tuple given by \a bgTuples is out of a valid range for 
2331  *         \a this array.
2332  *  \throw In the first *mode of usage*, if <em>strictCompoCompare == true </em> and
2333  *         if <em> a->getNumberOfComponents()</em> is unequal to the number of components
2334  *         defined by <em>(bgComp,endComp,stepComp)</em>.
2335  *  \throw In the second *mode of usage*, if \a a->getNumberOfTuples() != 1 or
2336  *         <em> a->getNumberOfComponents()</em> is unequal to the number of components
2337  *         defined by <em>(bgComp,endComp,stepComp)</em>.
2338  *  \throw If parameters specifying components to assign to, do not give a
2339  *            non-empty range of increasing indices or indices are out of a valid range
2340  *            for \this array.
2341  *
2342  *  \ref py_mcdataarraydouble_setpartofvalues3 "Here is a Python example".
2343  */
2344 void DataArrayDouble::setPartOfValues3(const DataArrayDouble *a, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare) throw(INTERP_KERNEL::Exception)
2345 {
2346   if(!a)
2347     throw INTERP_KERNEL::Exception("DataArrayDouble::setPartOfValues3 : input DataArrayDouble is NULL !");
2348   const char msg[]="DataArrayDouble::setPartOfValues3";
2349   checkAllocated();
2350   a->checkAllocated();
2351   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
2352   int nbComp=getNumberOfComponents();
2353   int nbOfTuples=getNumberOfTuples();
2354   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
2355   int newNbOfTuples=(int)std::distance(bgTuples,endTuples);
2356   bool assignTech=true;
2357   if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
2358     {
2359       if(strictCompoCompare)
2360         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
2361     }
2362   else
2363     {
2364       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
2365       assignTech=false;
2366     }
2367   double *pt=getPointer()+bgComp;
2368   const double *srcPt=a->getConstPointer();
2369   if(assignTech)
2370     {
2371       for(const int *w=bgTuples;w!=endTuples;w++)
2372         for(int j=0;j<newNbOfComp;j++,srcPt++)
2373           {
2374             DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
2375             pt[(std::size_t)(*w)*nbComp+j*stepComp]=*srcPt;
2376           }
2377     }
2378   else
2379     {
2380       for(const int *w=bgTuples;w!=endTuples;w++)
2381         {
2382           const double *srcPt2=srcPt;
2383           for(int j=0;j<newNbOfComp;j++,srcPt2++)
2384             {
2385               DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
2386               pt[(std::size_t)(*w)*nbComp+j*stepComp]=*srcPt2;
2387             }
2388         }
2389     }
2390 }
2391
2392 /*!
2393  * Assign a given value to values at specified tuples and components of \a this array.
2394  * The tuples to assign to are defined by a C array of indices.
2395  * The components to assign to are defined by three values similar to parameters of
2396  * the Python function \c range(\c start,\c stop,\c step).
2397  *  \param [in] a - the value to assign.
2398  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
2399  *              assign \a a to.
2400  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
2401  *              pointer to a tuple index <em>(pi)</em> varies as this: 
2402  *              \a bgTuples <= \a pi < \a endTuples.
2403  *  \param [in] bgComp - index of the first component of \a this array to assign to.
2404  *  \param [in] endComp - index of the component before which the components to assign
2405  *              to are located.
2406  *  \param [in] stepComp - index increment to get index of the next component to assign to.
2407  *  \throw If \a this is not allocated.
2408  *  \throw If any index of tuple given by \a bgTuples is out of a valid range for 
2409  *         \a this array.
2410  *  \throw If parameters specifying components to assign to, do not give a
2411  *            non-empty range of increasing indices or indices are out of a valid range
2412  *            for \this array.
2413  *
2414  *  \ref py_mcdataarraydouble_setpartofvaluessimple3 "Here is a Python example".
2415  */
2416 void DataArrayDouble::setPartOfValuesSimple3(double a, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp) throw(INTERP_KERNEL::Exception)
2417 {
2418   const char msg[]="DataArrayDouble::setPartOfValuesSimple3";
2419   checkAllocated();
2420   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
2421   int nbComp=getNumberOfComponents();
2422   int nbOfTuples=getNumberOfTuples();
2423   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
2424   double *pt=getPointer()+bgComp;
2425   for(const int *w=bgTuples;w!=endTuples;w++)
2426     for(int j=0;j<newNbOfComp;j++)
2427       {
2428         DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
2429         pt[(std::size_t)(*w)*nbComp+j*stepComp]=a;
2430       }
2431 }
2432
2433 /*!
2434  * Copy all values from another DataArrayDouble into specified tuples and components
2435  * of \a this array. Textual data is not copied.
2436  * The tree parameters defining set of indices of tuples and components are similar to
2437  * the tree parameters of the Python function \c range(\c start,\c stop,\c step).
2438  *  \param [in] a - the array to copy values from.
2439  *  \param [in] bgTuples - index of the first tuple of \a this array to assign values to.
2440  *  \param [in] endTuples - index of the tuple before which the tuples to assign to
2441  *              are located.
2442  *  \param [in] stepTuples - index increment to get index of the next tuple to assign to.
2443  *  \param [in] bgComp - pointer to an array of component indices of \a this array to
2444  *              assign \a a to.
2445  *  \param [in] endComp - specifies the end of the array \a bgTuples, so that
2446  *              pointer to a component index (\a pi) varies as this: 
2447  *              \a bgComp <= \a pi < \a endComp.
2448  *  \param [in] strictCompoCompare - if \a true (by default), then \a a->getNumberOfComponents() 
2449  *              must be equal to the number of columns to assign to, else an
2450  *              exception is thrown; if \a false, then it is only required that \a
2451  *              a->getNbOfElems() equals to number of values to assign to (this condition
2452  *              must be respected even if \a strictCompoCompare is \a true). The number of 
2453  *              values to assign to is given by following Python expression:
2454  *              \a nbTargetValues = 
2455  *              \c len(\c range(\a bgTuples,\a endTuples,\a stepTuples)) *
2456  *              \c len(\c range(\a bgComp,\a endComp,\a stepComp)).
2457  *  \throw If \a a is NULL.
2458  *  \throw If \a a is not allocated.
2459  *  \throw If \a this is not allocated.
2460  *  \throw If parameters specifying tuples and components to assign to do not give a
2461  *            non-empty range of increasing indices.
2462  *  \throw If \a a->getNbOfElems() != \a nbTargetValues.
2463  *  \throw If \a strictCompoCompare == \a true && \a a->getNumberOfComponents() !=
2464  *            \c len(\c range(\a bgComp,\a endComp,\a stepComp)).
2465  *
2466  */
2467 void DataArrayDouble::setPartOfValues4(const DataArrayDouble *a, int bgTuples, int endTuples, int stepTuples, const int *bgComp, const int *endComp, bool strictCompoCompare) throw(INTERP_KERNEL::Exception)
2468 {
2469   if(!a)
2470     throw INTERP_KERNEL::Exception("DataArrayDouble::setPartOfValues4 : input DataArrayDouble is NULL !");
2471   const char msg[]="DataArrayDouble::setPartOfValues4";
2472   checkAllocated();
2473   a->checkAllocated();
2474   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
2475   int newNbOfComp=(int)std::distance(bgComp,endComp);
2476   int nbComp=getNumberOfComponents();
2477   for(const int *z=bgComp;z!=endComp;z++)
2478     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
2479   int nbOfTuples=getNumberOfTuples();
2480   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
2481   bool assignTech=true;
2482   if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
2483     {
2484       if(strictCompoCompare)
2485         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
2486     }
2487   else
2488     {
2489       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
2490       assignTech=false;
2491     }
2492   const double *srcPt=a->getConstPointer();
2493   double *pt=getPointer()+bgTuples*nbComp;
2494   if(assignTech)
2495     {
2496       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
2497         for(const int *z=bgComp;z!=endComp;z++,srcPt++)
2498           pt[*z]=*srcPt;
2499     }
2500   else
2501     {
2502       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
2503         {
2504           const double *srcPt2=srcPt;
2505           for(const int *z=bgComp;z!=endComp;z++,srcPt2++)
2506             pt[*z]=*srcPt2;
2507         }
2508     }
2509 }
2510
2511 void DataArrayDouble::setPartOfValuesSimple4(double a, int bgTuples, int endTuples, int stepTuples, const int *bgComp, const int *endComp) throw(INTERP_KERNEL::Exception)
2512 {
2513   const char msg[]="DataArrayDouble::setPartOfValuesSimple4";
2514   checkAllocated();
2515   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
2516   int nbComp=getNumberOfComponents();
2517   for(const int *z=bgComp;z!=endComp;z++)
2518     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
2519   int nbOfTuples=getNumberOfTuples();
2520   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
2521   double *pt=getPointer()+bgTuples*nbComp;
2522   for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
2523     for(const int *z=bgComp;z!=endComp;z++)
2524       pt[*z]=a;
2525 }
2526
2527 /*!
2528  * Copy some tuples from another DataArrayDouble into specified tuples
2529  * of \a this array. Textual data is not copied. Both arrays must have equal number of
2530  * components.
2531  * Both the tuples to assign and the tuples to assign to are defined by a DataArrayInt.
2532  * All components of selected tuples are copied.
2533  *  \param [in] a - the array to copy values from.
2534  *  \param [in] tuplesSelec - the array specifying both source tuples of \a a and
2535  *              target tuples of \a this. \a tuplesSelec has two components, and the
2536  *              first component specifies index of the source tuple and the second
2537  *              one specifies index of the target tuple.
2538  *  \throw If \a this is not allocated.
2539  *  \throw If \a a is NULL.
2540  *  \throw If \a a is not allocated.
2541  *  \throw If \a tuplesSelec is NULL.
2542  *  \throw If \a tuplesSelec is not allocated.
2543  *  \throw If <em>this->getNumberOfComponents() != a->getNumberOfComponents()</em>.
2544  *  \throw If \a tuplesSelec->getNumberOfComponents() != 2.
2545  *  \throw If any tuple index given by \a tuplesSelec is out of a valid range for 
2546  *         the corresponding (\a this or \a a) array.
2547  */
2548 void DataArrayDouble::setPartOfValuesAdv(const DataArrayDouble *a, const DataArrayInt *tuplesSelec) throw(INTERP_KERNEL::Exception)
2549 {
2550   if(!a || !tuplesSelec)
2551     throw INTERP_KERNEL::Exception("DataArrayDouble::setPartOfValuesAdv : input DataArrayDouble is NULL !");
2552   checkAllocated();
2553   a->checkAllocated();
2554   tuplesSelec->checkAllocated();
2555   int nbOfComp=getNumberOfComponents();
2556   if(nbOfComp!=a->getNumberOfComponents())
2557     throw INTERP_KERNEL::Exception("DataArrayDouble::setPartOfValuesAdv : This and a do not have the same number of components !");
2558   if(tuplesSelec->getNumberOfComponents()!=2)
2559     throw INTERP_KERNEL::Exception("DataArrayDouble::setPartOfValuesAdv : Expecting to have a tuple selector DataArrayInt instance with exactly 2 components !");
2560   int thisNt=getNumberOfTuples();
2561   int aNt=a->getNumberOfTuples();
2562   double *valsToSet=getPointer();
2563   const double *valsSrc=a->getConstPointer();
2564   for(const int *tuple=tuplesSelec->begin();tuple!=tuplesSelec->end();tuple+=2)
2565     {
2566       if(tuple[1]>=0 && tuple[1]<aNt)
2567         {
2568           if(tuple[0]>=0 && tuple[0]<thisNt)
2569             std::copy(valsSrc+nbOfComp*tuple[1],valsSrc+nbOfComp*(tuple[1]+1),valsToSet+nbOfComp*tuple[0]);
2570           else
2571             {
2572               std::ostringstream oss; oss << "DataArrayDouble::setPartOfValuesAdv : Tuple #" << std::distance(tuplesSelec->begin(),tuple)/2;
2573               oss << " of 'tuplesSelec' request of tuple id #" << tuple[0] << " in 'this' ! It should be in [0," << thisNt << ") !";
2574               throw INTERP_KERNEL::Exception(oss.str().c_str());
2575             }
2576         }
2577       else
2578         {
2579           std::ostringstream oss; oss << "DataArrayDouble::setPartOfValuesAdv : Tuple #" << std::distance(tuplesSelec->begin(),tuple)/2;
2580           oss << " of 'tuplesSelec' request of tuple id #" << tuple[1] << " in 'a' ! It should be in [0," << aNt << ") !";
2581           throw INTERP_KERNEL::Exception(oss.str().c_str());
2582         }
2583     }
2584 }
2585
2586 /*!
2587  * Copy some tuples from another DataArrayDouble (\a a) into contiguous tuples
2588  * of \a this array. Textual data is not copied. Both arrays must have equal number of
2589  * components.
2590  * The tuples to assign to are defined by index of the first tuple, and
2591  * their number is defined by \a tuplesSelec->getNumberOfTuples().
2592  * The tuples to copy are defined by values of a DataArrayInt.
2593  * All components of selected tuples are copied.
2594  *  \param [in] tupleIdStart - index of the first tuple of \a this array to assign
2595  *              values to.
2596  *  \param [in] a - the array to copy values from.
2597  *  \param [in] tuplesSelec - the array specifying tuples of \a a to copy.
2598  *  \throw If \a this is not allocated.
2599  *  \throw If \a a is NULL.
2600  *  \throw If \a a is not allocated.
2601  *  \throw If \a tuplesSelec is NULL.
2602  *  \throw If \a tuplesSelec is not allocated.
2603  *  \throw If <em>this->getNumberOfComponents() != a->getNumberOfComponents()</em>.
2604  *  \throw If \a tuplesSelec->getNumberOfComponents() != 1.
2605  *  \throw If <em>tupleIdStart + tuplesSelec->getNumberOfTuples() > this->getNumberOfTuples().</em>
2606  *  \throw If any tuple index given by \a tuplesSelec is out of a valid range for 
2607  *         \a a array.
2608  */
2609 void DataArrayDouble::setContigPartOfSelectedValues(int tupleIdStart, const DataArray *aBase, const DataArrayInt *tuplesSelec) throw(INTERP_KERNEL::Exception)
2610 {
2611   if(!aBase || !tuplesSelec)
2612     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues : input DataArray is NULL !");
2613   const DataArrayDouble *a=dynamic_cast<const DataArrayDouble *>(aBase);
2614   if(!a)
2615     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues : input DataArray aBase is not a DataArrayDouble !");
2616   checkAllocated();
2617   a->checkAllocated();
2618   tuplesSelec->checkAllocated();
2619   int nbOfComp=getNumberOfComponents();
2620   if(nbOfComp!=a->getNumberOfComponents())
2621     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues : This and a do not have the same number of components !");
2622   if(tuplesSelec->getNumberOfComponents()!=1)
2623     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues : Expecting to have a tuple selector DataArrayInt instance with exactly 1 component !");
2624   int thisNt=getNumberOfTuples();
2625   int aNt=a->getNumberOfTuples();
2626   int nbOfTupleToWrite=tuplesSelec->getNumberOfTuples();
2627   double *valsToSet=getPointer()+tupleIdStart*nbOfComp;
2628   if(tupleIdStart+nbOfTupleToWrite>thisNt)
2629     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues : invalid number range of values to write !");
2630   const double *valsSrc=a->getConstPointer();
2631   for(const int *tuple=tuplesSelec->begin();tuple!=tuplesSelec->end();tuple++,valsToSet+=nbOfComp)
2632     {
2633       if(*tuple>=0 && *tuple<aNt)
2634         {
2635           std::copy(valsSrc+nbOfComp*(*tuple),valsSrc+nbOfComp*(*tuple+1),valsToSet);
2636         }
2637       else
2638         {
2639           std::ostringstream oss; oss << "DataArrayDouble::setContigPartOfSelectedValues : Tuple #" << std::distance(tuplesSelec->begin(),tuple);
2640           oss << " of 'tuplesSelec' request of tuple id #" << *tuple << " in 'a' ! It should be in [0," << aNt << ") !";
2641           throw INTERP_KERNEL::Exception(oss.str().c_str());
2642         }
2643     }
2644 }
2645
2646 /*!
2647  * Copy some tuples from another DataArrayDouble (\a a) into contiguous tuples
2648  * of \a this array. Textual data is not copied. Both arrays must have equal number of
2649  * components.
2650  * The tuples to copy are defined by three values similar to parameters of
2651  * the Python function \c range(\c start,\c stop,\c step).
2652  * The tuples to assign to are defined by index of the first tuple, and
2653  * their number is defined by number of tuples to copy.
2654  * All components of selected tuples are copied.
2655  *  \param [in] tupleIdStart - index of the first tuple of \a this array to assign
2656  *              values to.
2657  *  \param [in] a - the array to copy values from.
2658  *  \param [in] bg - index of the first tuple to copy of the array \a a.
2659  *  \param [in] end2 - index of the tuple of \a a before which the tuples to copy
2660  *              are located.
2661  *  \param [in] step - index increment to get index of the next tuple to copy.
2662  *  \throw If \a this is not allocated.
2663  *  \throw If \a a is NULL.
2664  *  \throw If \a a is not allocated.
2665  *  \throw If <em>this->getNumberOfComponents() != a->getNumberOfComponents()</em>.
2666  *  \throw If <em>tupleIdStart + len(range(bg,end2,step)) > this->getNumberOfTuples().</em>
2667  *  \throw If parameters specifying tuples to copy, do not give a
2668  *            non-empty range of increasing indices or indices are out of a valid range
2669  *            for the array \a a.
2670  */
2671 void DataArrayDouble::setContigPartOfSelectedValues2(int tupleIdStart, const DataArray *aBase, int bg, int end2, int step) throw(INTERP_KERNEL::Exception)
2672 {
2673   if(!aBase)
2674     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues2 : input DataArray is NULL !");
2675   const DataArrayDouble *a=dynamic_cast<const DataArrayDouble *>(aBase);
2676   if(!a)
2677     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues2 : input DataArray aBase is not a DataArrayDouble !");
2678   checkAllocated();
2679   a->checkAllocated();
2680   int nbOfComp=getNumberOfComponents();
2681   const char msg[]="DataArrayDouble::setContigPartOfSelectedValues2";
2682   int nbOfTupleToWrite=DataArray::GetNumberOfItemGivenBES(bg,end2,step,msg);
2683   if(nbOfComp!=a->getNumberOfComponents())
2684     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues2 : This and a do not have the same number of components !");
2685   int thisNt=getNumberOfTuples();
2686   int aNt=a->getNumberOfTuples();
2687   double *valsToSet=getPointer()+tupleIdStart*nbOfComp;
2688   if(tupleIdStart+nbOfTupleToWrite>thisNt)
2689     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues2 : invalid number range of values to write !");
2690   if(end2>aNt)
2691     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues2 : invalid range of values to read !");
2692   const double *valsSrc=a->getConstPointer()+bg*nbOfComp;
2693   for(int i=0;i<nbOfTupleToWrite;i++,valsToSet+=nbOfComp,valsSrc+=step*nbOfComp)
2694     {
2695       std::copy(valsSrc,valsSrc+nbOfComp,valsToSet);
2696     }
2697 }
2698
2699 /*!
2700  * Returns a value located at specified tuple and component.
2701  * This method is equivalent to DataArrayDouble::getIJ() except that validity of
2702  * parameters is checked. So this method is safe but expensive if used to go through
2703  * all values of \a this.
2704  *  \param [in] tupleId - index of tuple of interest.
2705  *  \param [in] compoId - index of component of interest.
2706  *  \return double - value located by \a tupleId and \a compoId.
2707  *  \throw If \a this is not allocated.
2708  *  \throw If condition <em>( 0 <= tupleId < this->getNumberOfTuples() )</em> is violated.
2709  *  \throw If condition <em>( 0 <= compoId < this->getNumberOfComponents() )</em> is violated.
2710  */
2711 double DataArrayDouble::getIJSafe(int tupleId, int compoId) const throw(INTERP_KERNEL::Exception)
2712 {
2713   checkAllocated();
2714   if(tupleId<0 || tupleId>=getNumberOfTuples())
2715     {
2716       std::ostringstream oss; oss << "DataArrayDouble::getIJSafe : request for tupleId " << tupleId << " should be in [0," << getNumberOfTuples() << ") !";
2717       throw INTERP_KERNEL::Exception(oss.str().c_str());
2718     }
2719   if(compoId<0 || compoId>=getNumberOfComponents())
2720     {
2721       std::ostringstream oss; oss << "DataArrayDouble::getIJSafe : request for compoId " << compoId << " should be in [0," << getNumberOfComponents() << ") !";
2722       throw INTERP_KERNEL::Exception(oss.str().c_str());
2723     }
2724   return _mem[tupleId*_info_on_compo.size()+compoId];
2725 }
2726
2727 /*!
2728  * Returns the first value of \a this. 
2729  *  \return double - the last value of \a this array.
2730  *  \throw If \a this is not allocated.
2731  *  \throw If \a this->getNumberOfComponents() != 1.
2732  *  \throw If \a this->getNumberOfTuples() < 1.
2733  */
2734 double DataArrayDouble::front() const throw(INTERP_KERNEL::Exception)
2735 {
2736   checkAllocated();
2737   if(getNumberOfComponents()!=1)
2738     throw INTERP_KERNEL::Exception("DataArrayDouble::front : number of components not equal to one !");
2739   int nbOfTuples=getNumberOfTuples();
2740   if(nbOfTuples<1)
2741     throw INTERP_KERNEL::Exception("DataArrayDouble::front : number of tuples must be >= 1 !");
2742   return *(getConstPointer());
2743 }
2744
2745 /*!
2746  * Returns the last value of \a this. 
2747  *  \return double - the last value of \a this array.
2748  *  \throw If \a this is not allocated.
2749  *  \throw If \a this->getNumberOfComponents() != 1.
2750  *  \throw If \a this->getNumberOfTuples() < 1.
2751  */
2752 double DataArrayDouble::back() const throw(INTERP_KERNEL::Exception)
2753 {
2754   checkAllocated();
2755   if(getNumberOfComponents()!=1)
2756     throw INTERP_KERNEL::Exception("DataArrayDouble::back : number of components not equal to one !");
2757   int nbOfTuples=getNumberOfTuples();
2758   if(nbOfTuples<1)
2759     throw INTERP_KERNEL::Exception("DataArrayDouble::back : number of tuples must be >= 1 !");
2760   return *(getConstPointer()+nbOfTuples-1);
2761 }
2762
2763 void DataArrayDouble::SetArrayIn(DataArrayDouble *newArray, DataArrayDouble* &arrayToSet)
2764 {
2765   if(newArray!=arrayToSet)
2766     {
2767       if(arrayToSet)
2768         arrayToSet->decrRef();
2769       arrayToSet=newArray;
2770       if(arrayToSet)
2771         arrayToSet->incrRef();
2772     }
2773 }
2774
2775 /*!
2776  * Sets a C array to be used as raw data of \a this. The previously set info
2777  *  of components is retained and re-sized. 
2778  * For more info see \ref MEDCouplingArraySteps1.
2779  *  \param [in] array - the C array to be used as raw data of \a this.
2780  *  \param [in] ownership - if \a true, \a array will be deallocated at destruction of \a this.
2781  *  \param [in] type - specifies how to deallocate \a array. If \a type == ParaMEDMEM::CPP_DEALLOC,
2782  *                     \c delete [] \c array; will be called. If \a type == ParaMEDMEM::C_DEALLOC,
2783  *                     \c free(\c array ) will be called.
2784  *  \param [in] nbOfTuple - new number of tuples in \a this.
2785  *  \param [in] nbOfCompo - new number of components in \a this.
2786  */
2787 void DataArrayDouble::useArray(const double *array, bool ownership, DeallocType type, int nbOfTuple, int nbOfCompo) throw(INTERP_KERNEL::Exception)
2788 {
2789   _info_on_compo.resize(nbOfCompo);
2790   _mem.useArray(array,ownership,type,(std::size_t)nbOfTuple*nbOfCompo);
2791   declareAsNew();
2792 }
2793
2794 void DataArrayDouble::useExternalArrayWithRWAccess(const double *array, int nbOfTuple, int nbOfCompo) throw(INTERP_KERNEL::Exception)
2795 {
2796   _info_on_compo.resize(nbOfCompo);
2797   _mem.useExternalArrayWithRWAccess(array,(std::size_t)nbOfTuple*nbOfCompo);
2798   declareAsNew();
2799 }
2800
2801 /*!
2802  * Checks if 0.0 value is present in \a this array. If it is the case, an exception
2803  * is thrown.
2804  * \throw If zero is found in \a this array.
2805  */
2806 void DataArrayDouble::checkNoNullValues() const throw(INTERP_KERNEL::Exception)
2807 {
2808   const double *tmp=getConstPointer();
2809   std::size_t nbOfElems=getNbOfElems();
2810   const double *where=std::find(tmp,tmp+nbOfElems,0.);
2811   if(where!=tmp+nbOfElems)
2812     throw INTERP_KERNEL::Exception("A value 0.0 have been detected !");
2813 }
2814
2815 /*!
2816  * Computes minimal and maximal value in each component. An output array is filled
2817  * with \c 2 * \a this->getNumberOfComponents() values, so the caller is to allocate
2818  * enough memory before calling this method.
2819  *  \param [out] bounds - array of size at least 2 *\a this->getNumberOfComponents().
2820  *               It is filled as follows:<br>
2821  *               \a bounds[0] = \c min_of_component_0 <br>
2822  *               \a bounds[1] = \c max_of_component_0 <br>
2823  *               \a bounds[2] = \c min_of_component_1 <br>
2824  *               \a bounds[3] = \c max_of_component_1 <br>
2825  *               ...
2826  */
2827 void DataArrayDouble::getMinMaxPerComponent(double *bounds) const throw(INTERP_KERNEL::Exception)
2828 {
2829   checkAllocated();
2830   int dim=getNumberOfComponents();
2831   for (int idim=0; idim<dim; idim++)
2832     {
2833       bounds[idim*2]=std::numeric_limits<double>::max();
2834       bounds[idim*2+1]=-std::numeric_limits<double>::max();
2835     } 
2836   const double *ptr=getConstPointer();
2837   int nbOfTuples=getNumberOfTuples();
2838   for(int i=0;i<nbOfTuples;i++)
2839     {
2840       for(int idim=0;idim<dim;idim++)
2841         {
2842           if(bounds[idim*2]>ptr[i*dim+idim])
2843             {
2844               bounds[idim*2]=ptr[i*dim+idim];
2845             }
2846           if(bounds[idim*2+1]<ptr[i*dim+idim])
2847             {
2848               bounds[idim*2+1]=ptr[i*dim+idim];
2849             }
2850         }
2851     }
2852 }
2853
2854 /*!
2855  * This method retrieves a newly allocated DataArrayDouble instance having same number of tuples than \a this and twice number of components than \a this
2856  * to store both the min and max per component of each tuples. 
2857  * \param [in] epsilon the width of the bbox (identical in each direction) - 0.0 by default
2858  *
2859  * \return a newly created DataArrayDouble instance having \c this->getNumberOfTuples() tuples and 2 * \c this->getNumberOfComponent() components
2860  *
2861  * \throw If \a this is not allocated yet.
2862  */
2863 DataArrayDouble *DataArrayDouble::computeBBoxPerTuple(double epsilon)const throw(INTERP_KERNEL::Exception)
2864 {
2865   checkAllocated();
2866   const double *dataPtr=getConstPointer();
2867   int nbOfCompo=getNumberOfComponents();
2868   int nbTuples=getNumberOfTuples();
2869   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> bbox=DataArrayDouble::New();
2870   bbox->alloc(nbTuples,2*nbOfCompo);
2871   double *bboxPtr=bbox->getPointer();
2872   for(int i=0;i<nbTuples;i++)
2873     {
2874       for(int j=0;j<nbOfCompo;j++)
2875         {
2876           bboxPtr[2*nbOfCompo*i+2*j]=dataPtr[nbOfCompo*i+j]-epsilon;
2877           bboxPtr[2*nbOfCompo*i+2*j+1]=dataPtr[nbOfCompo*i+j]+epsilon;
2878         }
2879     }
2880   return bbox.retn();
2881 }
2882
2883 /*!
2884  * For each tuples **t** in \a other, this method retrieves tuples in \a this that are equal to **t**.
2885  * Two tuples are considered equal if the euclidian distance between the two tuples is lower than \a eps.
2886  * 
2887  * \param [in] other a DataArrayDouble having same number of components than \a this.
2888  * \param [in] eps absolute precision representing distance (using infinite norm) between 2 tuples behind which 2 tuples are considered equal.
2889  * \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.
2890  *             \a cI allows to extract information in \a c.
2891  * \param [out] cI is an indirection array that allows to extract the data contained in \a c.
2892  *
2893  * \throw In case of:
2894  *  - \a this is not allocated
2895  *  - \a other is not allocated or null
2896  *  - \a this and \a other do not have the same number of components
2897  *  - if number of components of \a this is not in [1,2,3]
2898  *
2899  * \sa MEDCouplingPointSet::getNodeIdsNearPoints, DataArrayDouble::getDifferentValues
2900  */
2901 void DataArrayDouble::computeTupleIdsNearTuples(const DataArrayDouble *other, double eps, DataArrayInt *& c, DataArrayInt *& cI) const throw(INTERP_KERNEL::Exception)
2902 {
2903   if(!other)
2904     throw INTERP_KERNEL::Exception("DataArrayDouble::computeTupleIdsNearTuples : input pointer other is null !");
2905   checkAllocated();
2906   other->checkAllocated();
2907   int nbOfCompo=getNumberOfComponents();
2908   int otherNbOfCompo=other->getNumberOfComponents();
2909   if(nbOfCompo!=otherNbOfCompo)
2910     throw INTERP_KERNEL::Exception("DataArrayDouble::computeTupleIdsNearTuples : number of components should be equal between this and other !");
2911   int nbOfTuplesOther=other->getNumberOfTuples();
2912   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cArr(DataArrayInt::New()),cIArr(DataArrayInt::New()); cArr->alloc(0,1); cIArr->pushBackSilent(0);
2913   switch(nbOfCompo)
2914     {
2915     case 3:
2916       {
2917         BBTreePts<3,int> myTree(begin(),0,0,getNumberOfTuples(),eps);
2918         FindTupleIdsNearTuplesAlg<3>(myTree,other->getConstPointer(),nbOfTuplesOther,eps,cArr,cIArr);
2919         break;
2920       }
2921     case 2:
2922       {
2923         BBTreePts<2,int> myTree(begin(),0,0,getNumberOfTuples(),eps);
2924         FindTupleIdsNearTuplesAlg<2>(myTree,other->getConstPointer(),nbOfTuplesOther,eps,cArr,cIArr);
2925         break;
2926       }
2927     case 1:
2928       {
2929         BBTreePts<1,int> myTree(begin(),0,0,getNumberOfTuples(),eps);
2930         FindTupleIdsNearTuplesAlg<1>(myTree,other->getConstPointer(),nbOfTuplesOther,eps,cArr,cIArr);
2931         break;
2932       }
2933     default:
2934       throw INTERP_KERNEL::Exception("Unexpected spacedim of coords for computeTupleIdsNearTuples. Must be 1, 2 or 3.");
2935     }
2936   c=cArr.retn(); cI=cIArr.retn();
2937 }
2938
2939 /*!
2940  * 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
2941  * around origin of 'radius' 1.
2942  * 
2943  * \param [in] eps absolute epsilon. under that value of delta between max and min no scale is performed.
2944  */
2945 void DataArrayDouble::recenterForMaxPrecision(double eps) throw(INTERP_KERNEL::Exception)
2946 {
2947   checkAllocated();
2948   int dim=getNumberOfComponents();
2949   std::vector<double> bounds(2*dim);
2950   getMinMaxPerComponent(&bounds[0]);
2951   for(int i=0;i<dim;i++)
2952     {
2953       double delta=bounds[2*i+1]-bounds[2*i];
2954       double offset=(bounds[2*i]+bounds[2*i+1])/2.;
2955       if(delta>eps)
2956         applyLin(1./delta,-offset/delta,i);
2957       else
2958         applyLin(1.,-offset,i);
2959     }
2960 }
2961
2962 /*!
2963  * Returns the maximal value and its location within \a this one-dimensional array.
2964  *  \param [out] tupleId - index of the tuple holding the maximal value.
2965  *  \return double - the maximal value among all values of \a this array.
2966  *  \throw If \a this->getNumberOfComponents() != 1
2967  *  \throw If \a this->getNumberOfTuples() < 1
2968  */
2969 double DataArrayDouble::getMaxValue(int& tupleId) const throw(INTERP_KERNEL::Exception)
2970 {
2971   checkAllocated();
2972   if(getNumberOfComponents()!=1)
2973     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 !");
2974   int nbOfTuples=getNumberOfTuples();
2975   if(nbOfTuples<=0)
2976     throw INTERP_KERNEL::Exception("DataArrayDouble::getMaxValue : array exists but number of tuples must be > 0 !");
2977   const double *vals=getConstPointer();
2978   const double *loc=std::max_element(vals,vals+nbOfTuples);
2979   tupleId=(int)std::distance(vals,loc);
2980   return *loc;
2981 }
2982
2983 /*!
2984  * Returns the maximal value within \a this array that is allowed to have more than
2985  *  one component.
2986  *  \return double - the maximal value among all values of \a this array.
2987  *  \throw If \a this is not allocated.
2988  */
2989 double DataArrayDouble::getMaxValueInArray() const throw(INTERP_KERNEL::Exception)
2990 {
2991   checkAllocated();
2992   const double *loc=std::max_element(begin(),end());
2993   return *loc;
2994 }
2995
2996 /*!
2997  * Returns the maximal value and all its locations within \a this one-dimensional array.
2998  *  \param [out] tupleIds - a new instance of DataArrayInt containg indices of
2999  *               tuples holding the maximal value. The caller is to delete it using
3000  *               decrRef() as it is no more needed.
3001  *  \return double - the maximal value among all values of \a this array.
3002  *  \throw If \a this->getNumberOfComponents() != 1
3003  *  \throw If \a this->getNumberOfTuples() < 1
3004  */
3005 double DataArrayDouble::getMaxValue2(DataArrayInt*& tupleIds) const throw(INTERP_KERNEL::Exception)
3006 {
3007   int tmp;
3008   tupleIds=0;
3009   double ret=getMaxValue(tmp);
3010   tupleIds=getIdsInRange(ret,ret);
3011   return ret;
3012 }
3013
3014 /*!
3015  * Returns the minimal value and its location within \a this one-dimensional array.
3016  *  \param [out] tupleId - index of the tuple holding the minimal value.
3017  *  \return double - the minimal value among all values of \a this array.
3018  *  \throw If \a this->getNumberOfComponents() != 1
3019  *  \throw If \a this->getNumberOfTuples() < 1
3020  */
3021 double DataArrayDouble::getMinValue(int& tupleId) const throw(INTERP_KERNEL::Exception)
3022 {
3023   checkAllocated();
3024   if(getNumberOfComponents()!=1)
3025     throw INTERP_KERNEL::Exception("DataArrayDouble::getMinValue : must be applied on DataArrayDouble with only one component, you can call 'rearrange' method before call 'getMinValueInArray' method !");
3026   int nbOfTuples=getNumberOfTuples();
3027   if(nbOfTuples<=0)
3028     throw INTERP_KERNEL::Exception("DataArrayDouble::getMinValue : array exists but number of tuples must be > 0 !");
3029   const double *vals=getConstPointer();
3030   const double *loc=std::min_element(vals,vals+nbOfTuples);
3031   tupleId=(int)std::distance(vals,loc);
3032   return *loc;
3033 }
3034
3035 /*!
3036  * Returns the minimal value within \a this array that is allowed to have more than
3037  *  one component.
3038  *  \return double - the minimal value among all values of \a this array.
3039  *  \throw If \a this is not allocated.
3040  */
3041 double DataArrayDouble::getMinValueInArray() const throw(INTERP_KERNEL::Exception)
3042 {
3043   checkAllocated();
3044   const double *loc=std::min_element(begin(),end());
3045   return *loc;
3046 }
3047
3048 /*!
3049  * Returns the minimal value and all its locations within \a this one-dimensional array.
3050  *  \param [out] tupleIds - a new instance of DataArrayInt containg indices of
3051  *               tuples holding the minimal value. The caller is to delete it using
3052  *               decrRef() as it is no more needed.
3053  *  \return double - the minimal value among all values of \a this array.
3054  *  \throw If \a this->getNumberOfComponents() != 1
3055  *  \throw If \a this->getNumberOfTuples() < 1
3056  */
3057 double DataArrayDouble::getMinValue2(DataArrayInt*& tupleIds) const throw(INTERP_KERNEL::Exception)
3058 {
3059   int tmp;
3060   tupleIds=0;
3061   double ret=getMinValue(tmp);
3062   tupleIds=getIdsInRange(ret,ret);
3063   return ret;
3064 }
3065
3066 /*!
3067  * 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.
3068  * This method only works for single component array.
3069  *
3070  * \return a value in [ 0, \c this->getNumberOfTuples() )
3071  *
3072  * \throw If \a this is not allocated
3073  *
3074  */
3075 int DataArrayDouble::count(double value, double eps) const throw(INTERP_KERNEL::Exception)
3076 {
3077   int ret=0;
3078   checkAllocated();
3079   if(getNumberOfComponents()!=1)
3080     throw INTERP_KERNEL::Exception("DataArrayDouble::count : must be applied on DataArrayDouble with only one component, you can call 'rearrange' method before !");
3081   const double *vals=begin();
3082   int nbOfTuples=getNumberOfTuples();
3083   for(int i=0;i<nbOfTuples;i++,vals++)
3084     if(fabs(*vals-value)<=eps)
3085       ret++;
3086   return ret;
3087 }
3088
3089 /*!
3090  * Returns the average value of \a this one-dimensional array.
3091  *  \return double - the average value over all values of \a this array.
3092  *  \throw If \a this->getNumberOfComponents() != 1
3093  *  \throw If \a this->getNumberOfTuples() < 1
3094  */
3095 double DataArrayDouble::getAverageValue() const throw(INTERP_KERNEL::Exception)
3096 {
3097   if(getNumberOfComponents()!=1)
3098     throw INTERP_KERNEL::Exception("DataArrayDouble::getAverageValue : must be applied on DataArrayDouble with only one component, you can call 'rearrange' method before !");
3099   int nbOfTuples=getNumberOfTuples();
3100   if(nbOfTuples<=0)
3101     throw INTERP_KERNEL::Exception("DataArrayDouble::getAverageValue : array exists but number of tuples must be > 0 !");
3102   const double *vals=getConstPointer();
3103   double ret=std::accumulate(vals,vals+nbOfTuples,0.);
3104   return ret/nbOfTuples;
3105 }
3106
3107 /*!
3108  * Returns the Euclidean norm of the vector defined by \a this array.
3109  *  \return double - the value of the Euclidean norm, i.e.
3110  *          the square root of the inner product of vector.
3111  *  \throw If \a this is not allocated.
3112  */
3113 double DataArrayDouble::norm2() const throw(INTERP_KERNEL::Exception)
3114 {
3115   checkAllocated();
3116   double ret=0.;
3117   std::size_t nbOfElems=getNbOfElems();
3118   const double *pt=getConstPointer();
3119   for(std::size_t i=0;i<nbOfElems;i++,pt++)
3120     ret+=(*pt)*(*pt);
3121   return sqrt(ret);
3122 }
3123
3124 /*!
3125  * Returns the maximum norm of the vector defined by \a this array.
3126  *  \return double - the value of the maximum norm, i.e.
3127  *          the maximal absolute value among values of \a this array.
3128  *  \throw If \a this is not allocated.
3129  */
3130 double DataArrayDouble::normMax() const throw(INTERP_KERNEL::Exception)
3131 {
3132   checkAllocated();
3133   double ret=-1.;
3134   std::size_t nbOfElems=getNbOfElems();
3135   const double *pt=getConstPointer();
3136   for(std::size_t i=0;i<nbOfElems;i++,pt++)
3137     {
3138       double val=std::abs(*pt);
3139       if(val>ret)
3140         ret=val;
3141     }
3142   return ret;
3143 }
3144
3145 /*!
3146  * Accumulates values of each component of \a this array.
3147  *  \param [out] res - an array of length \a this->getNumberOfComponents(), allocated 
3148  *         by the caller, that is filled by this method with sum value for each
3149  *         component.
3150  *  \throw If \a this is not allocated.
3151  */
3152 void DataArrayDouble::accumulate(double *res) const throw(INTERP_KERNEL::Exception)
3153 {
3154   checkAllocated();
3155   const double *ptr=getConstPointer();
3156   int nbTuple=getNumberOfTuples();
3157   int nbComps=getNumberOfComponents();
3158   std::fill(res,res+nbComps,0.);
3159   for(int i=0;i<nbTuple;i++)
3160     std::transform(ptr+i*nbComps,ptr+(i+1)*nbComps,res,res,std::plus<double>());
3161 }
3162
3163 /*!
3164  * This method returns the min distance from an external tuple defined by [ \a tupleBg , \a tupleEnd ) to \a this and
3165  * the first tuple in \a this that matches the returned distance. If there is no tuples in \a this an exception will be thrown.
3166  *
3167  *
3168  * \a this is expected to be allocated and expected to have a number of components equal to the distance from \a tupleBg to
3169  * \a tupleEnd. If not an exception will be thrown.
3170  *
3171  * \param [in] tupleBg start pointer (included) of input external tuple
3172  * \param [in] tupleEnd end pointer (not included) of input external tuple
3173  * \param [out] tupleId the tuple id in \a this that matches the min of distance between \a this and input external tuple
3174  * \return the min distance.
3175  * \sa MEDCouplingUMesh::distanceToPoint
3176  */
3177 double DataArrayDouble::distanceToTuple(const double *tupleBg, const double *tupleEnd, int& tupleId) const throw(INTERP_KERNEL::Exception)
3178 {
3179   checkAllocated();
3180   int nbTuple=getNumberOfTuples();
3181   int nbComps=getNumberOfComponents();
3182   if(nbComps!=(int)std::distance(tupleBg,tupleEnd))
3183     { 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()); }
3184   if(nbTuple==0)
3185     throw INTERP_KERNEL::Exception("DataArrayDouble::distanceToTuple : no tuple in this ! No distance to compute !");
3186   double ret0=std::numeric_limits<double>::max();
3187   tupleId=-1;
3188   const double *work=getConstPointer();
3189   for(int i=0;i<nbTuple;i++)
3190     {
3191       double val=0.;
3192       for(int j=0;j<nbComps;j++,work++) 
3193         val+=(*work-tupleBg[j])*((*work-tupleBg[j]));
3194       if(val>=ret0)
3195         continue;
3196       else
3197         { ret0=val; tupleId=i; }
3198     }
3199   return sqrt(ret0);
3200 }
3201
3202 /*!
3203  * Accumulate values of the given component of \a this array.
3204  *  \param [in] compId - the index of the component of interest.
3205  *  \return double - a sum value of \a compId-th component.
3206  *  \throw If \a this is not allocated.
3207  *  \throw If \a the condition ( 0 <= \a compId < \a this->getNumberOfComponents() ) is
3208  *         not respected.
3209  */
3210 double DataArrayDouble::accumulate(int compId) const throw(INTERP_KERNEL::Exception)
3211 {
3212   checkAllocated();
3213   const double *ptr=getConstPointer();
3214   int nbTuple=getNumberOfTuples();
3215   int nbComps=getNumberOfComponents();
3216   if(compId<0 || compId>=nbComps)
3217     throw INTERP_KERNEL::Exception("DataArrayDouble::accumulate : Invalid compId specified : No such nb of components !");
3218   double ret=0.;
3219   for(int i=0;i<nbTuple;i++)
3220     ret+=ptr[i*nbComps+compId];
3221   return ret;
3222 }
3223
3224 /*!
3225  * This method accumulate using addition tuples in \a this using input index array [ \a bgOfIndex, \a endOfIndex ).
3226  * The returned array will have same number of components than \a this and number of tuples equal to
3227  * \c std::distance(bgOfIndex,endOfIndex) \b minus \b one.
3228  *
3229  * The input index array is expected to be ascendingly sorted in which the all referenced ids should be in [0, \c this->getNumberOfTuples).
3230  * 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.
3231  *
3232  * \param [in] bgOfIndex - begin (included) of the input index array.
3233  * \param [in] endOfIndex - end (excluded) of the input index array.
3234  * \return DataArrayDouble * - the new instance having the same number of components than \a this.
3235  * 
3236  * \throw If bgOfIndex or end is NULL.
3237  * \throw If input index array is not ascendingly sorted.
3238  * \throw If there is an id in [ \a bgOfIndex, \a endOfIndex ) not in [0, \c this->getNumberOfTuples).
3239  * \throw If std::distance(bgOfIndex,endOfIndex)==0.
3240  */
3241 DataArrayDouble *DataArrayDouble::accumulatePerChunck(const int *bgOfIndex, const int *endOfIndex) const throw(INTERP_KERNEL::Exception)
3242 {
3243   if(!bgOfIndex || !endOfIndex)
3244     throw INTERP_KERNEL::Exception("DataArrayDouble::accumulatePerChunck : input pointer NULL !");
3245   checkAllocated();
3246   int nbCompo=getNumberOfComponents();
3247   int nbOfTuples=getNumberOfTuples();
3248   int sz=(int)std::distance(bgOfIndex,endOfIndex);
3249   if(sz<1)
3250     throw INTERP_KERNEL::Exception("DataArrayDouble::accumulatePerChunck : invalid size of input index array !");
3251   sz--;
3252   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New(); ret->alloc(sz,nbCompo);
3253   const int *w=bgOfIndex;
3254   if(*w<0 || *w>=nbOfTuples)
3255     throw INTERP_KERNEL::Exception("DataArrayDouble::accumulatePerChunck : The first element of the input index not in [0,nbOfTuples) !");
3256   const double *srcPt=begin()+(*w)*nbCompo;
3257   double *tmp=ret->getPointer();
3258   for(int i=0;i<sz;i++,tmp+=nbCompo,w++)
3259     {
3260       std::fill(tmp,tmp+nbCompo,0.);
3261       if(w[1]>=w[0])
3262         {
3263           for(int j=w[0];j<w[1];j++,srcPt+=nbCompo)
3264             {
3265               if(j>=0 && j<nbOfTuples)
3266                 std::transform(srcPt,srcPt+nbCompo,tmp,tmp,std::plus<double>());
3267               else
3268                 {
3269                   std::ostringstream oss; oss << "DataArrayDouble::accumulatePerChunck : At rank #" << i << " the input index array points to id " << j << " should be in [0," << nbOfTuples << ") !";
3270                   throw INTERP_KERNEL::Exception(oss.str().c_str());
3271                 }
3272             }
3273         }
3274       else
3275         {
3276           std::ostringstream oss; oss << "DataArrayDouble::accumulatePerChunck : At rank #" << i << " the input index array is not in ascendingly sorted.";
3277           throw INTERP_KERNEL::Exception(oss.str().c_str());
3278         }
3279     }
3280   ret->copyStringInfoFrom(*this);
3281   return ret.retn();
3282 }
3283
3284 /*!
3285  * Converts each 2D point defined by the tuple of \a this array from the Polar to the
3286  * Cartesian coordinate system. The two components of the tuple of \a this array are 
3287  * considered to contain (1) radius and (2) angle of the point in the Polar CS.
3288  *  \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
3289  *          contains X and Y coordinates of the point in the Cartesian CS. The caller
3290  *          is to delete this array using decrRef() as it is no more needed. The array
3291  *          does not contain any textual info on components.
3292  *  \throw If \a this->getNumberOfComponents() != 2.
3293  */
3294 DataArrayDouble *DataArrayDouble::fromPolarToCart() const throw(INTERP_KERNEL::Exception)
3295 {
3296   checkAllocated();
3297   int nbOfComp=getNumberOfComponents();
3298   if(nbOfComp!=2)
3299     throw INTERP_KERNEL::Exception("DataArrayDouble::fromPolarToCart : must be an array with exactly 2 components !");
3300   int nbOfTuple=getNumberOfTuples();
3301   DataArrayDouble *ret=DataArrayDouble::New();
3302   ret->alloc(nbOfTuple,2);
3303   double *w=ret->getPointer();
3304   const double *wIn=getConstPointer();
3305   for(int i=0;i<nbOfTuple;i++,w+=2,wIn+=2)
3306     {
3307       w[0]=wIn[0]*cos(wIn[1]);
3308       w[1]=wIn[0]*sin(wIn[1]);
3309     }
3310   return ret;
3311 }
3312
3313 /*!
3314  * Converts each 3D point defined by the tuple of \a this array from the Cylindrical to
3315  * the Cartesian coordinate system. The three components of the tuple of \a this array 
3316  * are considered to contain (1) radius, (2) azimuth and (3) altitude of the point in
3317  * the Cylindrical CS.
3318  *  \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
3319  *          contains X, Y and Z coordinates of the point in the Cartesian CS. The info
3320  *          on the third component is copied from \a this array. The caller
3321  *          is to delete this array using decrRef() as it is no more needed. 
3322  *  \throw If \a this->getNumberOfComponents() != 3.
3323  */
3324 DataArrayDouble *DataArrayDouble::fromCylToCart() const throw(INTERP_KERNEL::Exception)
3325 {
3326   checkAllocated();
3327   int nbOfComp=getNumberOfComponents();
3328   if(nbOfComp!=3)
3329     throw INTERP_KERNEL::Exception("DataArrayDouble::fromCylToCart : must be an array with exactly 3 components !");
3330   int nbOfTuple=getNumberOfTuples();
3331   DataArrayDouble *ret=DataArrayDouble::New();
3332   ret->alloc(getNumberOfTuples(),3);
3333   double *w=ret->getPointer();
3334   const double *wIn=getConstPointer();
3335   for(int i=0;i<nbOfTuple;i++,w+=3,wIn+=3)
3336     {
3337       w[0]=wIn[0]*cos(wIn[1]);
3338       w[1]=wIn[0]*sin(wIn[1]);
3339       w[2]=wIn[2];
3340     }
3341   ret->setInfoOnComponent(2,getInfoOnComponent(2).c_str());
3342   return ret;
3343 }
3344
3345 /*!
3346  * Converts each 3D point defined by the tuple of \a this array from the Spherical to
3347  * the Cartesian coordinate system. The three components of the tuple of \a this array 
3348  * are considered to contain (1) radius, (2) polar angle and (3) azimuthal angle of the
3349  * point in the Cylindrical CS.
3350  *  \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
3351  *          contains X, Y and Z coordinates of the point in the Cartesian CS. The info
3352  *          on the third component is copied from \a this array. The caller
3353  *          is to delete this array using decrRef() as it is no more needed.
3354  *  \throw If \a this->getNumberOfComponents() != 3.
3355  */
3356 DataArrayDouble *DataArrayDouble::fromSpherToCart() const throw(INTERP_KERNEL::Exception)
3357 {
3358   checkAllocated();
3359   int nbOfComp=getNumberOfComponents();
3360   if(nbOfComp!=3)
3361     throw INTERP_KERNEL::Exception("DataArrayDouble::fromSpherToCart : must be an array with exactly 3 components !");
3362   int nbOfTuple=getNumberOfTuples();
3363   DataArrayDouble *ret=DataArrayDouble::New();
3364   ret->alloc(getNumberOfTuples(),3);
3365   double *w=ret->getPointer();
3366   const double *wIn=getConstPointer();
3367   for(int i=0;i<nbOfTuple;i++,w+=3,wIn+=3)
3368     {
3369       w[0]=wIn[0]*cos(wIn[2])*sin(wIn[1]);
3370       w[1]=wIn[0]*sin(wIn[2])*sin(wIn[1]);
3371       w[2]=wIn[0]*cos(wIn[1]);
3372     }
3373   return ret;
3374 }
3375
3376 /*!
3377  * Computes the doubly contracted product of every tensor defined by the tuple of \a this
3378  * array contating 6 components.
3379  *  \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
3380  *          is calculated from the tuple <em>(t)</em> of \a this array as follows:
3381  *          \f$ t[0]^2+t[1]^2+t[2]^2+2*t[3]^2+2*t[4]^2+2*t[5]^2\f$.
3382  *         The caller is to delete this result array using decrRef() as it is no more needed. 
3383  *  \throw If \a this->getNumberOfComponents() != 6.
3384  */
3385 DataArrayDouble *DataArrayDouble::doublyContractedProduct() const throw(INTERP_KERNEL::Exception)
3386 {
3387   checkAllocated();
3388   int nbOfComp=getNumberOfComponents();
3389   if(nbOfComp!=6)
3390     throw INTERP_KERNEL::Exception("DataArrayDouble::doublyContractedProduct : must be an array with exactly 6 components !");
3391   DataArrayDouble *ret=DataArrayDouble::New();
3392   int nbOfTuple=getNumberOfTuples();
3393   ret->alloc(nbOfTuple,1);
3394   const double *src=getConstPointer();
3395   double *dest=ret->getPointer();
3396   for(int i=0;i<nbOfTuple;i++,dest++,src+=6)
3397     *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];
3398   return ret;
3399 }
3400
3401 /*!
3402  * Computes the determinant of every square matrix defined by the tuple of \a this
3403  * array, which contains either 4, 6 or 9 components. The case of 6 components
3404  * corresponds to that of the upper triangular matrix.
3405  *  \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
3406  *          is the determinant of matrix of the corresponding tuple of \a this array.
3407  *          The caller is to delete this result array using decrRef() as it is no more
3408  *          needed. 
3409  *  \throw If \a this->getNumberOfComponents() is not in [4,6,9].
3410  */
3411 DataArrayDouble *DataArrayDouble::determinant() const throw(INTERP_KERNEL::Exception)
3412 {
3413   checkAllocated();
3414   DataArrayDouble *ret=DataArrayDouble::New();
3415   int nbOfTuple=getNumberOfTuples();
3416   ret->alloc(nbOfTuple,1);
3417   const double *src=getConstPointer();
3418   double *dest=ret->getPointer();
3419   switch(getNumberOfComponents())
3420     {
3421     case 6:
3422       for(int i=0;i<nbOfTuple;i++,dest++,src+=6)
3423         *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];
3424       return ret;
3425     case 4:
3426       for(int i=0;i<nbOfTuple;i++,dest++,src+=4)
3427         *dest=src[0]*src[3]-src[1]*src[2];
3428       return ret;
3429     case 9:
3430       for(int i=0;i<nbOfTuple;i++,dest++,src+=9)
3431         *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];
3432       return ret;
3433     default:
3434       ret->decrRef();
3435       throw INTERP_KERNEL::Exception("DataArrayDouble::determinant : Invalid number of components ! must be in 4,6,9 !");
3436     }
3437 }
3438
3439 /*!
3440  * Computes 3 eigenvalues of every upper triangular matrix defined by the tuple of
3441  * \a this array, which contains 6 components.
3442  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing 3
3443  *          components, whose each tuple contains the eigenvalues of the matrix of
3444  *          corresponding tuple of \a this array. 
3445  *          The caller is to delete this result array using decrRef() as it is no more
3446  *          needed. 
3447  *  \throw If \a this->getNumberOfComponents() != 6.
3448  */
3449 DataArrayDouble *DataArrayDouble::eigenValues() const throw(INTERP_KERNEL::Exception)
3450 {
3451   checkAllocated();
3452   int nbOfComp=getNumberOfComponents();
3453   if(nbOfComp!=6)
3454     throw INTERP_KERNEL::Exception("DataArrayDouble::eigenValues : must be an array with exactly 6 components !");
3455   DataArrayDouble *ret=DataArrayDouble::New();
3456   int nbOfTuple=getNumberOfTuples();
3457   ret->alloc(nbOfTuple,3);
3458   const double *src=getConstPointer();
3459   double *dest=ret->getPointer();
3460   for(int i=0;i<nbOfTuple;i++,dest+=3,src+=6)
3461     INTERP_KERNEL::computeEigenValues6(src,dest);
3462   return ret;
3463 }
3464
3465 /*!
3466  * Computes 3 eigenvectors of every upper triangular matrix defined by the tuple of
3467  * \a this array, which contains 6 components.
3468  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing 9
3469  *          components, whose each tuple contains 3 eigenvectors of the matrix of
3470  *          corresponding tuple of \a this array.
3471  *          The caller is to delete this result array using decrRef() as it is no more
3472  *          needed.
3473  *  \throw If \a this->getNumberOfComponents() != 6.
3474  */
3475 DataArrayDouble *DataArrayDouble::eigenVectors() const throw(INTERP_KERNEL::Exception)
3476 {
3477   checkAllocated();
3478   int nbOfComp=getNumberOfComponents();
3479   if(nbOfComp!=6)
3480     throw INTERP_KERNEL::Exception("DataArrayDouble::eigenVectors : must be an array with exactly 6 components !");
3481   DataArrayDouble *ret=DataArrayDouble::New();
3482   int nbOfTuple=getNumberOfTuples();
3483   ret->alloc(nbOfTuple,9);
3484   const double *src=getConstPointer();
3485   double *dest=ret->getPointer();
3486   for(int i=0;i<nbOfTuple;i++,src+=6)
3487     {
3488       double tmp[3];
3489       INTERP_KERNEL::computeEigenValues6(src,tmp);
3490       for(int j=0;j<3;j++,dest+=3)
3491         INTERP_KERNEL::computeEigenVectorForEigenValue6(src,tmp[j],1e-12,dest);
3492     }
3493   return ret;
3494 }
3495
3496 /*!
3497  * Computes the inverse matrix of every matrix defined by the tuple of \a this
3498  * array, which contains either 4, 6 or 9 components. The case of 6 components
3499  * corresponds to that of the upper triangular matrix.
3500  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
3501  *          same number of components as \a this one, whose each tuple is the inverse
3502  *          matrix of the matrix of corresponding tuple of \a this array. 
3503  *          The caller is to delete this result array using decrRef() as it is no more
3504  *          needed. 
3505  *  \throw If \a this->getNumberOfComponents() is not in [4,6,9].
3506  */
3507 DataArrayDouble *DataArrayDouble::inverse() const throw(INTERP_KERNEL::Exception)
3508 {
3509   checkAllocated();
3510   int nbOfComp=getNumberOfComponents();
3511   if(nbOfComp!=6 && nbOfComp!=9 && nbOfComp!=4)
3512     throw INTERP_KERNEL::Exception("DataArrayDouble::inversion : must be an array with 4,6 or 9 components !");
3513   DataArrayDouble *ret=DataArrayDouble::New();
3514   int nbOfTuple=getNumberOfTuples();
3515   ret->alloc(nbOfTuple,nbOfComp);
3516   const double *src=getConstPointer();
3517   double *dest=ret->getPointer();
3518 if(nbOfComp==6)
3519     for(int i=0;i<nbOfTuple;i++,dest+=6,src+=6)
3520       {
3521         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];
3522         dest[0]=(src[1]*src[2]-src[4]*src[4])/det;
3523         dest[1]=(src[0]*src[2]-src[5]*src[5])/det;
3524         dest[2]=(src[0]*src[1]-src[3]*src[3])/det;
3525         dest[3]=(src[5]*src[4]-src[3]*src[2])/det;
3526         dest[4]=(src[5]*src[3]-src[0]*src[4])/det;
3527         dest[5]=(src[3]*src[4]-src[1]*src[5])/det;
3528       }
3529   else if(nbOfComp==4)
3530     for(int i=0;i<nbOfTuple;i++,dest+=4,src+=4)
3531       {
3532         double det=src[0]*src[3]-src[1]*src[2];
3533         dest[0]=src[3]/det;
3534         dest[1]=-src[1]/det;
3535         dest[2]=-src[2]/det;
3536         dest[3]=src[0]/det;
3537       }
3538   else
3539     for(int i=0;i<nbOfTuple;i++,dest+=9,src+=9)
3540       {
3541         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];
3542         dest[0]=(src[4]*src[8]-src[7]*src[5])/det;
3543         dest[1]=(src[7]*src[2]-src[1]*src[8])/det;
3544         dest[2]=(src[1]*src[5]-src[4]*src[2])/det;
3545         dest[3]=(src[6]*src[5]-src[3]*src[8])/det;
3546         dest[4]=(src[0]*src[8]-src[6]*src[2])/det;
3547         dest[5]=(src[2]*src[3]-src[0]*src[5])/det;
3548         dest[6]=(src[3]*src[7]-src[6]*src[4])/det;
3549         dest[7]=(src[6]*src[1]-src[0]*src[7])/det;
3550         dest[8]=(src[0]*src[4]-src[1]*src[3])/det;
3551       }
3552   return ret;
3553 }
3554
3555 /*!
3556  * Computes the trace of every matrix defined by the tuple of \a this
3557  * array, which contains either 4, 6 or 9 components. The case of 6 components
3558  * corresponds to that of the upper triangular matrix.
3559  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing 
3560  *          1 component, whose each tuple is the trace of
3561  *          the matrix of corresponding tuple of \a this array. 
3562  *          The caller is to delete this result array using decrRef() as it is no more
3563  *          needed. 
3564  *  \throw If \a this->getNumberOfComponents() is not in [4,6,9].
3565  */
3566 DataArrayDouble *DataArrayDouble::trace() const throw(INTERP_KERNEL::Exception)
3567 {
3568   checkAllocated();
3569   int nbOfComp=getNumberOfComponents();
3570   if(nbOfComp!=6 && nbOfComp!=9 && nbOfComp!=4)
3571     throw INTERP_KERNEL::Exception("DataArrayDouble::trace : must be an array with 4,6 or 9 components !");
3572   DataArrayDouble *ret=DataArrayDouble::New();
3573   int nbOfTuple=getNumberOfTuples();
3574   ret->alloc(nbOfTuple,1);
3575   const double *src=getConstPointer();
3576   double *dest=ret->getPointer();
3577   if(nbOfComp==6)
3578     for(int i=0;i<nbOfTuple;i++,dest++,src+=6)
3579       *dest=src[0]+src[1]+src[2];
3580   else if(nbOfComp==4)
3581     for(int i=0;i<nbOfTuple;i++,dest++,src+=4)
3582       *dest=src[0]+src[3];
3583   else
3584     for(int i=0;i<nbOfTuple;i++,dest++,src+=9)
3585       *dest=src[0]+src[4]+src[8];
3586   return ret;
3587 }
3588
3589 /*!
3590  * Computes the stress deviator tensor of every stress tensor defined by the tuple of
3591  * \a this array, which contains 6 components.
3592  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
3593  *          same number of components and tuples as \a this array.
3594  *          The caller is to delete this result array using decrRef() as it is no more
3595  *          needed.
3596  *  \throw If \a this->getNumberOfComponents() != 6.
3597  */
3598 DataArrayDouble *DataArrayDouble::deviator() const throw(INTERP_KERNEL::Exception)
3599 {
3600   checkAllocated();
3601   int nbOfComp=getNumberOfComponents();
3602   if(nbOfComp!=6)
3603     throw INTERP_KERNEL::Exception("DataArrayDouble::deviator : must be an array with exactly 6 components !");
3604   DataArrayDouble *ret=DataArrayDouble::New();
3605   int nbOfTuple=getNumberOfTuples();
3606   ret->alloc(nbOfTuple,6);
3607   const double *src=getConstPointer();
3608   double *dest=ret->getPointer();
3609   for(int i=0;i<nbOfTuple;i++,dest+=6,src+=6)
3610     {
3611       double tr=(src[0]+src[1]+src[2])/3.;
3612       dest[0]=src[0]-tr;
3613       dest[1]=src[1]-tr;
3614       dest[2]=src[2]-tr;
3615       dest[3]=src[3];
3616       dest[4]=src[4];
3617       dest[5]=src[5];
3618     }
3619   return ret;
3620 }
3621
3622 /*!
3623  * Computes the magnitude of every vector defined by the tuple of
3624  * \a this array.
3625  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
3626  *          same number of tuples as \a this array and one component.
3627  *          The caller is to delete this result array using decrRef() as it is no more
3628  *          needed.
3629  *  \throw If \a this is not allocated.
3630  */
3631 DataArrayDouble *DataArrayDouble::magnitude() const throw(INTERP_KERNEL::Exception)
3632 {
3633   checkAllocated();
3634   int nbOfComp=getNumberOfComponents();
3635   DataArrayDouble *ret=DataArrayDouble::New();
3636   int nbOfTuple=getNumberOfTuples();
3637   ret->alloc(nbOfTuple,1);
3638   const double *src=getConstPointer();
3639   double *dest=ret->getPointer();
3640   for(int i=0;i<nbOfTuple;i++,dest++)
3641     {
3642       double sum=0.;
3643       for(int j=0;j<nbOfComp;j++,src++)
3644         sum+=(*src)*(*src);
3645       *dest=sqrt(sum);
3646     }
3647   return ret;
3648 }
3649
3650 /*!
3651  * Computes the maximal value within every tuple of \a this array.
3652  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
3653  *          same number of tuples as \a this array and one component.
3654  *          The caller is to delete this result array using decrRef() as it is no more
3655  *          needed.
3656  *  \throw If \a this is not allocated.
3657  *  \sa DataArrayDouble::maxPerTupleWithCompoId
3658  */
3659 DataArrayDouble *DataArrayDouble::maxPerTuple() const throw(INTERP_KERNEL::Exception)
3660 {
3661   checkAllocated();
3662   int nbOfComp=getNumberOfComponents();
3663   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
3664   int nbOfTuple=getNumberOfTuples();
3665   ret->alloc(nbOfTuple,1);
3666   const double *src=getConstPointer();
3667   double *dest=ret->getPointer();
3668   for(int i=0;i<nbOfTuple;i++,dest++,src+=nbOfComp)
3669     *dest=*std::max_element(src,src+nbOfComp);
3670   return ret.retn();
3671 }
3672
3673 /*!
3674  * Computes the maximal value within every tuple of \a this array and it returns the first component
3675  * id for each tuple that corresponds to the maximal value within the tuple.
3676  * 
3677  *  \param [out] compoIdOfMaxPerTuple - the new new instance of DataArrayInt containing the
3678  *          same number of tuples and only one component.
3679  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
3680  *          same number of tuples as \a this array and one component.
3681  *          The caller is to delete this result array using decrRef() as it is no more
3682  *          needed.
3683  *  \throw If \a this is not allocated.
3684  *  \sa DataArrayDouble::maxPerTuple
3685  */
3686 DataArrayDouble *DataArrayDouble::maxPerTupleWithCompoId(DataArrayInt* &compoIdOfMaxPerTuple) const throw(INTERP_KERNEL::Exception)
3687 {
3688   checkAllocated();
3689   int nbOfComp=getNumberOfComponents();
3690   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret0=DataArrayDouble::New();
3691   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret1=DataArrayInt::New();
3692   int nbOfTuple=getNumberOfTuples();
3693   ret0->alloc(nbOfTuple,1); ret1->alloc(nbOfTuple,1);
3694   const double *src=getConstPointer();
3695   double *dest=ret0->getPointer(); int *dest1=ret1->getPointer();
3696   for(int i=0;i<nbOfTuple;i++,dest++,dest1++,src+=nbOfComp)
3697     {
3698       const double *loc=std::max_element(src,src+nbOfComp);
3699       *dest=*loc;
3700       *dest1=(int)std::distance(src,loc);
3701     }
3702   compoIdOfMaxPerTuple=ret1.retn();
3703   return ret0.retn();
3704 }
3705
3706 /*!
3707  * This method returns a newly allocated DataArrayDouble instance having one component and \c this->getNumberOfTuples() * \c this->getNumberOfTuples() tuples.
3708  * \n This returned array contains the euclidian distance for each tuple in \a this. 
3709  * \n So the returned array can be seen as a dense symmetrical matrix whose diagonal elements are equal to 0.
3710  * \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)
3711  *
3712  * \warning use this method with care because it can leads to big amount of consumed memory !
3713  * 
3714  * \return A newly allocated (huge) ParaMEDMEM::DataArrayDouble instance that the caller should deal with.
3715  *
3716  * \throw If \a this is not allocated.
3717  *
3718  * \sa DataArrayDouble::buildEuclidianDistanceDenseMatrixWith
3719  */
3720 DataArrayDouble *DataArrayDouble::buildEuclidianDistanceDenseMatrix() const throw(INTERP_KERNEL::Exception)
3721 {
3722   checkAllocated();
3723   int nbOfComp=getNumberOfComponents();
3724   int nbOfTuples=getNumberOfTuples();
3725   const double *inData=getConstPointer();
3726   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
3727   ret->alloc(nbOfTuples*nbOfTuples,1);
3728   double *outData=ret->getPointer();
3729   for(int i=0;i<nbOfTuples;i++)
3730     {
3731       outData[i*nbOfTuples+i]=0.;
3732       for(int j=i+1;j<nbOfTuples;j++)
3733         {
3734           double dist=0.;
3735           for(int k=0;k<nbOfComp;k++)
3736             { double delta=inData[i*nbOfComp+k]-inData[j*nbOfComp+k]; dist+=delta*delta; }
3737           dist=sqrt(dist);
3738           outData[i*nbOfTuples+j]=dist;
3739           outData[j*nbOfTuples+i]=dist;
3740         }
3741     }
3742   return ret.retn();
3743 }
3744
3745 /*!
3746  * This method returns a newly allocated DataArrayDouble instance having one component and \c this->getNumberOfTuples() * \c other->getNumberOfTuples() tuples.
3747  * \n This returned array contains the euclidian distance for each tuple in \a other with each tuple in \a this. 
3748  * \n So the returned array can be seen as a dense rectangular matrix with \c other->getNumberOfTuples() rows and \c this->getNumberOfTuples() columns.
3749  * \n Output rectangular matrix is sorted along rows.
3750  * \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)
3751  *
3752  * \warning use this method with care because it can leads to big amount of consumed memory !
3753  * 
3754  * \param [in] other DataArrayDouble instance having same number of components than \a this.
3755  * \return A newly allocated (huge) ParaMEDMEM::DataArrayDouble instance that the caller should deal with.
3756  *
3757  * \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.
3758  *
3759  * \sa DataArrayDouble::buildEuclidianDistanceDenseMatrix
3760  */
3761 DataArrayDouble *DataArrayDouble::buildEuclidianDistanceDenseMatrixWith(const DataArrayDouble *other) const throw(INTERP_KERNEL::Exception)
3762 {
3763   if(!other)
3764     throw INTERP_KERNEL::Exception("DataArrayDouble::buildEuclidianDistanceDenseMatrixWith : input parameter is null !");
3765   checkAllocated();
3766   other->checkAllocated();
3767   int nbOfComp=getNumberOfComponents();
3768   int otherNbOfComp=other->getNumberOfComponents();
3769   if(nbOfComp!=otherNbOfComp)
3770     {
3771       std::ostringstream oss; oss << "DataArrayDouble::buildEuclidianDistanceDenseMatrixWith : this nb of compo=" << nbOfComp << " and other nb of compo=" << otherNbOfComp << ". It should match !";
3772       throw INTERP_KERNEL::Exception(oss.str().c_str());
3773     }
3774   int nbOfTuples=getNumberOfTuples();
3775   int otherNbOfTuples=other->getNumberOfTuples();
3776   const double *inData=getConstPointer();
3777   const double *inDataOther=other->getConstPointer();
3778   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
3779   ret->alloc(otherNbOfTuples*nbOfTuples,1);
3780   double *outData=ret->getPointer();
3781   for(int i=0;i<otherNbOfTuples;i++,inDataOther+=nbOfComp)
3782     {
3783       for(int j=0;j<nbOfTuples;j++)
3784         {
3785           double dist=0.;
3786           for(int k=0;k<nbOfComp;k++)
3787             { double delta=inDataOther[k]-inData[j*nbOfComp+k]; dist+=delta*delta; }
3788           dist=sqrt(dist);
3789           outData[i*nbOfTuples+j]=dist;
3790         }
3791     }
3792   return ret.retn();
3793 }
3794
3795 /*!
3796  * Sorts value within every tuple of \a this array.
3797  *  \param [in] asc - if \a true, the values are sorted in ascending order, else,
3798  *              in descending order.
3799  *  \throw If \a this is not allocated.
3800  */
3801 void DataArrayDouble::sortPerTuple(bool asc) throw(INTERP_KERNEL::Exception)
3802 {
3803   checkAllocated();
3804   double *pt=getPointer();
3805   int nbOfTuple=getNumberOfTuples();
3806   int nbOfComp=getNumberOfComponents();
3807   if(asc)
3808     for(int i=0;i<nbOfTuple;i++,pt+=nbOfComp)
3809       std::sort(pt,pt+nbOfComp);
3810   else
3811     for(int i=0;i<nbOfTuple;i++,pt+=nbOfComp)
3812       std::sort(pt,pt+nbOfComp,std::greater<double>());
3813   declareAsNew();
3814 }
3815
3816 /*!
3817  * Converts every value of \a this array to its absolute value.
3818  *  \throw If \a this is not allocated.
3819  */
3820 void DataArrayDouble::abs() throw(INTERP_KERNEL::Exception)
3821 {
3822   checkAllocated();
3823   double *ptr=getPointer();
3824   std::size_t nbOfElems=getNbOfElems();
3825   std::transform(ptr,ptr+nbOfElems,ptr,std::ptr_fun<double,double>(fabs));
3826   declareAsNew();
3827 }
3828
3829 /*!
3830  * Apply a liner function to a given component of \a this array, so that
3831  * an array element <em>(x)</em> becomes \f$ a * x + b \f$.
3832  *  \param [in] a - the first coefficient of the function.
3833  *  \param [in] b - the second coefficient of the function.
3834  *  \param [in] compoId - the index of component to modify.
3835  *  \throw If \a this is not allocated.
3836  */
3837 void DataArrayDouble::applyLin(double a, double b, int compoId) throw(INTERP_KERNEL::Exception)
3838 {
3839   checkAllocated();
3840   double *ptr=getPointer()+compoId;
3841   int nbOfComp=getNumberOfComponents();
3842   int nbOfTuple=getNumberOfTuples();
3843   for(int i=0;i<nbOfTuple;i++,ptr+=nbOfComp)
3844     *ptr=a*(*ptr)+b;
3845   declareAsNew();
3846 }
3847
3848 /*!
3849  * Apply a liner function to all elements of \a this array, so that
3850  * an element _x_ becomes \f$ a * x + b \f$.
3851  *  \param [in] a - the first coefficient of the function.
3852  *  \param [in] b - the second coefficient of the function.
3853  *  \throw If \a this is not allocated.
3854  */
3855 void DataArrayDouble::applyLin(double a, double b) throw(INTERP_KERNEL::Exception)
3856 {
3857   checkAllocated();
3858   double *ptr=getPointer();
3859   std::size_t nbOfElems=getNbOfElems();
3860   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
3861     *ptr=a*(*ptr)+b;
3862   declareAsNew();
3863 }
3864
3865 /*!
3866  * Modify all elements of \a this array, so that
3867  * an element _x_ becomes \f$ numerator / x \f$.
3868  *  \warning If an exception is thrown because of presence of 0.0 element in \a this 
3869  *           array, all elements processed before detection of the zero element remain
3870  *           modified.
3871  *  \param [in] numerator - the numerator used to modify array elements.
3872  *  \throw If \a this is not allocated.
3873  *  \throw If there is an element equal to 0.0 in \a this array.
3874  */
3875 void DataArrayDouble::applyInv(double numerator) throw(INTERP_KERNEL::Exception)
3876 {
3877   checkAllocated();
3878   double *ptr=getPointer();
3879   std::size_t nbOfElems=getNbOfElems();
3880   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
3881     {
3882       if(std::abs(*ptr)>std::numeric_limits<double>::min())
3883         {
3884           *ptr=numerator/(*ptr);
3885         }
3886       else
3887         {
3888           std::ostringstream oss; oss << "DataArrayDouble::applyInv : presence of null value in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
3889           oss << " !";
3890           throw INTERP_KERNEL::Exception(oss.str().c_str());
3891         }
3892     }
3893   declareAsNew();
3894 }
3895
3896 /*!
3897  * Returns a full copy of \a this array except that sign of all elements is reversed.
3898  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
3899  *          same number of tuples and component as \a this array.
3900  *          The caller is to delete this result array using decrRef() as it is no more
3901  *          needed.
3902  *  \throw If \a this is not allocated.
3903  */
3904 DataArrayDouble *DataArrayDouble::negate() const throw(INTERP_KERNEL::Exception)
3905 {
3906   checkAllocated();
3907   DataArrayDouble *newArr=DataArrayDouble::New();
3908   int nbOfTuples=getNumberOfTuples();
3909   int nbOfComp=getNumberOfComponents();
3910   newArr->alloc(nbOfTuples,nbOfComp);
3911   const double *cptr=getConstPointer();
3912   std::transform(cptr,cptr+nbOfTuples*nbOfComp,newArr->getPointer(),std::negate<double>());
3913   newArr->copyStringInfoFrom(*this);
3914   return newArr;
3915 }
3916
3917 /*!
3918  * Modify all elements of \a this array, so that
3919  * an element _x_ becomes <em> val ^ x </em>. Contrary to DataArrayInt::applyPow
3920  * all values in \a this have to be >= 0 if val is \b not integer.
3921  *  \param [in] val - the value used to apply pow on all array elements.
3922  *  \throw If \a this is not allocated.
3923  *  \warning If an exception is thrown because of presence of 0 element in \a this 
3924  *           array and \a val is \b not integer, all elements processed before detection of the zero element remain
3925  *           modified.
3926  */
3927 void DataArrayDouble::applyPow(double val) throw(INTERP_KERNEL::Exception)
3928 {
3929   checkAllocated();
3930   double *ptr=getPointer();
3931   std::size_t nbOfElems=getNbOfElems();
3932   int val2=(int)val;
3933   bool isInt=((double)val2)==val;
3934   if(!isInt)
3935     {
3936       for(std::size_t i=0;i<nbOfElems;i++,ptr++)
3937         {
3938           if(*ptr>=0)
3939             *ptr=pow(*ptr,val);
3940           else
3941             {
3942               std::ostringstream oss; oss << "DataArrayDouble::applyPow (double) : At elem # " << i << " value is " << *ptr << " ! must be >=0. !";
3943               throw INTERP_KERNEL::Exception(oss.str().c_str());
3944             }
3945         }
3946     }
3947   else
3948     {
3949       for(std::size_t i=0;i<nbOfElems;i++,ptr++)
3950         *ptr=pow(*ptr,val2);
3951     }
3952   declareAsNew();
3953 }
3954
3955 /*!
3956  * Modify all elements of \a this array, so that
3957  * an element _x_ becomes \f$ val ^ x \f$.
3958  *  \param [in] val - the value used to apply pow on all array elements.
3959  *  \throw If \a this is not allocated.
3960  *  \throw If \a val < 0.
3961  *  \warning If an exception is thrown because of presence of 0 element in \a this 
3962  *           array, all elements processed before detection of the zero element remain
3963  *           modified.
3964  */
3965 void DataArrayDouble::applyRPow(double val) throw(INTERP_KERNEL::Exception)
3966 {
3967   checkAllocated();
3968   if(val<0.)
3969     throw INTERP_KERNEL::Exception("DataArrayDouble::applyRPow : the input value has to be >= 0 !");
3970   double *ptr=getPointer();
3971   std::size_t nbOfElems=getNbOfElems();
3972   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
3973     *ptr=pow(val,*ptr);
3974   declareAsNew();
3975 }
3976
3977 /*!
3978  * Returns a new DataArrayDouble created from \a this one by applying \a
3979  * FunctionToEvaluate to every tuple of \a this array. Textual data is not copied.
3980  * For more info see \ref MEDCouplingArrayApplyFunc
3981  *  \param [in] nbOfComp - number of components in the result array.
3982  *  \param [in] func - the \a FunctionToEvaluate declared as 
3983  *              \c bool (*\a func)(\c const \c double *\a pos, \c double *\a res), 
3984  *              where \a pos points to the first component of a tuple of \a this array
3985  *              and \a res points to the first component of a tuple of the result array.
3986  *              Note that length (number of components) of \a pos can differ from
3987  *              that of \a res.
3988  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
3989  *          same number of tuples as \a this array.
3990  *          The caller is to delete this result array using decrRef() as it is no more
3991  *          needed.
3992  *  \throw If \a this is not allocated.
3993  *  \throw If \a func returns \a false.
3994  */
3995 DataArrayDouble *DataArrayDouble::applyFunc(int nbOfComp, FunctionToEvaluate func) const throw(INTERP_KERNEL::Exception)
3996 {
3997   checkAllocated();
3998   DataArrayDouble *newArr=DataArrayDouble::New();
3999   int nbOfTuples=getNumberOfTuples();
4000   int oldNbOfComp=getNumberOfComponents();
4001   newArr->alloc(nbOfTuples,nbOfComp);
4002   const double *ptr=getConstPointer();
4003   double *ptrToFill=newArr->getPointer();
4004   for(int i=0;i<nbOfTuples;i++)
4005     {
4006       if(!func(ptr+i*oldNbOfComp,ptrToFill+i*nbOfComp))
4007         {
4008           std::ostringstream oss; oss << "For tuple # " << i << " with value (";
4009           std::copy(ptr+oldNbOfComp*i,ptr+oldNbOfComp*(i+1),std::ostream_iterator<double>(oss,", "));
4010           oss << ") : Evaluation of function failed !";
4011           newArr->decrRef();
4012           throw INTERP_KERNEL::Exception(oss.str().c_str());
4013         }
4014     }
4015   return newArr;
4016 }
4017
4018 /*!
4019  * Returns a new DataArrayDouble created from \a this one by applying a function to every
4020  * tuple of \a this array. Textual data is not copied.
4021  * For more info see \ref MEDCouplingArrayApplyFunc1.
4022  *  \param [in] nbOfComp - number of components in the result array.
4023  *  \param [in] func - the expression defining how to transform a tuple of \a this array.
4024  *              Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
4025  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
4026  *          same number of tuples as \a this array and \a nbOfComp components.
4027  *          The caller is to delete this result array using decrRef() as it is no more
4028  *          needed.
4029  *  \throw If \a this is not allocated.
4030  *  \throw If computing \a func fails.
4031  */
4032 DataArrayDouble *DataArrayDouble::applyFunc(int nbOfComp, const char *func) const throw(INTERP_KERNEL::Exception)
4033 {
4034   checkAllocated();
4035   INTERP_KERNEL::ExprParser expr(func);
4036   expr.parse();
4037   std::set<std::string> vars;
4038   expr.getTrueSetOfVars(vars);
4039   int oldNbOfComp=getNumberOfComponents();
4040   if((int)vars.size()>oldNbOfComp)
4041     {
4042       std::ostringstream oss; oss << "The field has " << oldNbOfComp << " components and there are ";
4043       oss << vars.size() << " variables : ";
4044       std::copy(vars.begin(),vars.end(),std::ostream_iterator<std::string>(oss," "));
4045       throw INTERP_KERNEL::Exception(oss.str().c_str());
4046     }
4047   std::vector<std::string> varsV(vars.begin(),vars.end());
4048   expr.prepareExprEvaluation(varsV,oldNbOfComp,nbOfComp);
4049   //
4050   DataArrayDouble *newArr=DataArrayDouble::New();
4051   int nbOfTuples=getNumberOfTuples();
4052   newArr->alloc(nbOfTuples,nbOfComp);
4053   const double *ptr=getConstPointer();
4054   double *ptrToFill=newArr->getPointer();
4055   for(int i=0;i<nbOfTuples;i++)
4056     {
4057       try
4058         {
4059           expr.evaluateExpr(nbOfComp,ptr+i*oldNbOfComp,ptrToFill+i*nbOfComp);
4060         }
4061       catch(INTERP_KERNEL::Exception& e)
4062         {
4063           std::ostringstream oss; oss << "For tuple # " << i << " with value (";
4064           std::copy(ptr+oldNbOfComp*i,ptr+oldNbOfComp*(i+1),std::ostream_iterator<double>(oss,", "));
4065           oss << ") : Evaluation of function failed !" << e.what();
4066           newArr->decrRef();
4067           throw INTERP_KERNEL::Exception(oss.str().c_str());
4068         }
4069     }
4070   return newArr;
4071 }
4072
4073 /*!
4074  * Returns a new DataArrayDouble created from \a this one by applying a function to every
4075  * tuple of \a this array. Textual data is not copied.
4076  * For more info see \ref MEDCouplingArrayApplyFunc0.
4077  *  \param [in] func - the expression defining how to transform a tuple of \a this array.
4078  *              Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
4079  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
4080  *          same number of tuples and components as \a this array.
4081  *          The caller is to delete this result array using decrRef() as it is no more
4082  *          needed.
4083  *  \throw If \a this is not allocated.
4084  *  \throw If computing \a func fails.
4085  */
4086 DataArrayDouble *DataArrayDouble::applyFunc(const char *func) const throw(INTERP_KERNEL::Exception)
4087 {
4088   checkAllocated();
4089   INTERP_KERNEL::ExprParser expr(func);
4090   expr.parse();
4091   expr.prepareExprEvaluationVec();
4092   //
4093   DataArrayDouble *newArr=DataArrayDouble::New();
4094   int nbOfTuples=getNumberOfTuples();
4095   int nbOfComp=getNumberOfComponents();
4096   newArr->alloc(nbOfTuples,nbOfComp);
4097   const double *ptr=getConstPointer();
4098   double *ptrToFill=newArr->getPointer();
4099   for(int i=0;i<nbOfTuples;i++)
4100     {
4101       try
4102         {
4103           expr.evaluateExpr(nbOfComp,ptr+i*nbOfComp,ptrToFill+i*nbOfComp);
4104         }
4105       catch(INTERP_KERNEL::Exception& e)
4106         {
4107           std::ostringstream oss; oss << "For tuple # " << i << " with value (";
4108           std::copy(ptr+nbOfComp*i,ptr+nbOfComp*(i+1),std::ostream_iterator<double>(oss,", "));
4109           oss << ") : Evaluation of function failed ! " << e.what();
4110           newArr->decrRef();
4111           throw INTERP_KERNEL::Exception(oss.str().c_str());
4112         }
4113     }
4114   return newArr;
4115 }
4116
4117 /*!
4118  * Returns a new DataArrayDouble created from \a this one by applying a function to every
4119  * tuple of \a this array. Textual data is not copied.
4120  * For more info see \ref MEDCouplingArrayApplyFunc2.
4121  *  \param [in] nbOfComp - number of components in the result array.
4122  *  \param [in] func - the expression defining how to transform a tuple of \a this array.
4123  *              Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
4124  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
4125  *          same number of tuples as \a this array.
4126  *          The caller is to delete this result array using decrRef() as it is no more
4127  *          needed.
4128  *  \throw If \a this is not allocated.
4129  *  \throw If \a func contains vars that are not in \a this->getInfoOnComponent().
4130  *  \throw If computing \a func fails.
4131  */
4132 DataArrayDouble *DataArrayDouble::applyFunc2(int nbOfComp, const char *func) const throw(INTERP_KERNEL::Exception)
4133 {
4134   checkAllocated();
4135   INTERP_KERNEL::ExprParser expr(func);
4136   expr.parse();
4137   std::set<std::string> vars;
4138   expr.getTrueSetOfVars(vars);
4139   int oldNbOfComp=getNumberOfComponents();
4140   if((int)vars.size()>oldNbOfComp)
4141     {
4142       std::ostringstream oss; oss << "The field has " << oldNbOfComp << " components and there are ";
4143       oss << vars.size() << " variables : ";
4144       std::copy(vars.begin(),vars.end(),std::ostream_iterator<std::string>(oss," "));
4145       throw INTERP_KERNEL::Exception(oss.str().c_str());
4146     }
4147   expr.prepareExprEvaluation(getVarsOnComponent(),oldNbOfComp,nbOfComp);
4148   //
4149   DataArrayDouble *newArr=DataArrayDouble::New();
4150   int nbOfTuples=getNumberOfTuples();
4151   newArr->alloc(nbOfTuples,nbOfComp);
4152   const double *ptr=getConstPointer();
4153   double *ptrToFill=newArr->getPointer();
4154   for(int i=0;i<nbOfTuples;i++)
4155     {
4156       try
4157         {
4158           expr.evaluateExpr(nbOfComp,ptr+i*oldNbOfComp,ptrToFill+i*nbOfComp);
4159         }
4160       catch(INTERP_KERNEL::Exception& e)
4161         {
4162           std::ostringstream oss; oss << "For tuple # " << i << " with value (";
4163           std::copy(ptr+oldNbOfComp*i,ptr+oldNbOfComp*(i+1),std::ostream_iterator<double>(oss,", "));
4164           oss << ") : Evaluation of function failed !" << e.what();
4165           newArr->decrRef();
4166           throw INTERP_KERNEL::Exception(oss.str().c_str());
4167         }
4168     }
4169   return newArr;
4170 }
4171
4172 /*!
4173  * Returns a new DataArrayDouble created from \a this one by applying a function to every
4174  * tuple of \a this array. Textual data is not copied.
4175  * For more info see \ref MEDCouplingArrayApplyFunc3.
4176  *  \param [in] nbOfComp - number of components in the result array.
4177  *  \param [in] varsOrder - sequence of vars defining their order.
4178  *  \param [in] func - the expression defining how to transform a tuple of \a this array.
4179  *              Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
4180  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
4181  *          same number of tuples as \a this array.
4182  *          The caller is to delete this result array using decrRef() as it is no more
4183  *          needed.
4184  *  \throw If \a this is not allocated.
4185  *  \throw If \a func contains vars not in \a varsOrder.
4186  *  \throw If computing \a func fails.
4187  */
4188 DataArrayDouble *DataArrayDouble::applyFunc3(int nbOfComp, const std::vector<std::string>& varsOrder, const char *func) const throw(INTERP_KERNEL::Exception)
4189 {
4190   checkAllocated();
4191   INTERP_KERNEL::ExprParser expr(func);
4192   expr.parse();
4193   std::set<std::string> vars;
4194   expr.getTrueSetOfVars(vars);
4195   int oldNbOfComp=getNumberOfComponents();
4196   if((int)vars.size()>oldNbOfComp)
4197     {
4198       std::ostringstream oss; oss << "The field has " << oldNbOfComp << " components and there are ";
4199       oss << vars.size() << " variables : ";
4200       std::copy(vars.begin(),vars.end(),std::ostream_iterator<std::string>(oss," "));
4201       throw INTERP_KERNEL::Exception(oss.str().c_str());
4202     }
4203   expr.prepareExprEvaluation(varsOrder,oldNbOfComp,nbOfComp);
4204   //
4205   DataArrayDouble *newArr=DataArrayDouble::New();
4206   int nbOfTuples=getNumberOfTuples();
4207   newArr->alloc(nbOfTuples,nbOfComp);
4208   const double *ptr=getConstPointer();
4209   double *ptrToFill=newArr->getPointer();
4210   for(int i=0;i<nbOfTuples;i++)
4211     {
4212       try
4213         {
4214           expr.evaluateExpr(nbOfComp,ptr+i*oldNbOfComp,ptrToFill+i*nbOfComp);
4215         }
4216       catch(INTERP_KERNEL::Exception& e)
4217         {
4218           std::ostringstream oss; oss << "For tuple # " << i << " with value (";
4219           std::copy(ptr+oldNbOfComp*i,ptr+oldNbOfComp*(i+1),std::ostream_iterator<double>(oss,", "));
4220           oss << ") : Evaluation of function failed !" << e.what();
4221           newArr->decrRef();
4222           throw INTERP_KERNEL::Exception(oss.str().c_str());
4223         }
4224     }
4225   return newArr;
4226 }
4227
4228 void DataArrayDouble::applyFuncFast32(const char *func) throw(INTERP_KERNEL::Exception)
4229 {
4230   checkAllocated();
4231   INTERP_KERNEL::ExprParser expr(func);
4232   expr.parse();
4233   char *funcStr=expr.compileX86();
4234   MYFUNCPTR funcPtr;
4235   *((void **)&funcPtr)=funcStr;//he he...
4236   //
4237   double *ptr=getPointer();
4238   int nbOfComp=getNumberOfComponents();
4239   int nbOfTuples=getNumberOfTuples();
4240   int nbOfElems=nbOfTuples*nbOfComp;
4241   for(int i=0;i<nbOfElems;i++,ptr++)
4242     *ptr=funcPtr(*ptr);
4243   declareAsNew();
4244 }
4245
4246 void DataArrayDouble::applyFuncFast64(const char *func) throw(INTERP_KERNEL::Exception)
4247 {
4248   checkAllocated();
4249   INTERP_KERNEL::ExprParser expr(func);
4250   expr.parse();
4251   char *funcStr=expr.compileX86_64();
4252   MYFUNCPTR funcPtr;
4253   *((void **)&funcPtr)=funcStr;//he he...
4254   //
4255   double *ptr=getPointer();
4256   int nbOfComp=getNumberOfComponents();
4257   int nbOfTuples=getNumberOfTuples();
4258   int nbOfElems=nbOfTuples*nbOfComp;
4259   for(int i=0;i<nbOfElems;i++,ptr++)
4260     *ptr=funcPtr(*ptr);
4261   declareAsNew();
4262 }
4263
4264 DataArrayDoubleIterator *DataArrayDouble::iterator() throw(INTERP_KERNEL::Exception)
4265 {
4266   return new DataArrayDoubleIterator(this);
4267 }
4268
4269 /*!
4270  * Returns a new DataArrayInt contating indices of tuples of \a this one-dimensional
4271  * array whose values are within a given range. Textual data is not copied.
4272  *  \param [in] vmin - a lowest acceptable value (included).
4273  *  \param [in] vmax - a greatest acceptable value (included).
4274  *  \return DataArrayInt * - the new instance of DataArrayInt.
4275  *          The caller is to delete this result array using decrRef() as it is no more
4276  *          needed.
4277  *  \throw If \a this->getNumberOfComponents() != 1.
4278  *
4279  *  \ref cpp_mcdataarraydouble_getidsinrange "Here is a C++ example".<br>
4280  *  \ref py_mcdataarraydouble_getidsinrange "Here is a Python example".
4281  */
4282 DataArrayInt *DataArrayDouble::getIdsInRange(double vmin, double vmax) const throw(INTERP_KERNEL::Exception)
4283 {
4284   checkAllocated();
4285   if(getNumberOfComponents()!=1)
4286     throw INTERP_KERNEL::Exception("DataArrayDouble::getIdsInRange : this must have exactly one component !");
4287   const double *cptr=getConstPointer();
4288   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(0,1);
4289   int nbOfTuples=getNumberOfTuples();
4290   for(int i=0;i<nbOfTuples;i++,cptr++)
4291     if(*cptr>=vmin && *cptr<=vmax)
4292       ret->pushBackSilent(i);
4293   return ret.retn();
4294 }
4295
4296 /*!
4297  * Returns a new DataArrayDouble by concatenating two given arrays, so that (1) the number
4298  * of tuples in the result array is a sum of the number of tuples of given arrays and (2)
4299  * the number of component in the result array is same as that of each of given arrays.
4300  * Info on components is copied from the first of the given arrays. Number of components
4301  * in the given arrays must be  the same.
4302  *  \param [in] a1 - an array to include in the result array.
4303  *  \param [in] a2 - another array to include in the result array.
4304  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4305  *          The caller is to delete this result array using decrRef() as it is no more
4306  *          needed.
4307  *  \throw If both \a a1 and \a a2 are NULL.
4308  *  \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents().
4309  */
4310 DataArrayDouble *DataArrayDouble::Aggregate(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception)
4311 {
4312   std::vector<const DataArrayDouble *> tmp(2);
4313   tmp[0]=a1; tmp[1]=a2;
4314   return Aggregate(tmp);
4315 }
4316
4317 /*!
4318  * Returns a new DataArrayDouble by concatenating all given arrays, so that (1) the number
4319  * of tuples in the result array is a sum of the number of tuples of given arrays and (2)
4320  * the number of component in the result array is same as that of each of given arrays.
4321  * Info on components is copied from the first of the given arrays. Number of components
4322  * in the given arrays must be  the same.
4323  *  \param [in] arr - a sequence of arrays 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 all arrays within \a arr are NULL.
4328  *  \throw If getNumberOfComponents() of arrays within \a arr.
4329  */
4330 DataArrayDouble *DataArrayDouble::Aggregate(const std::vector<const DataArrayDouble *>& arr) throw(INTERP_KERNEL::Exception)
4331 {
4332   std::vector<const DataArrayDouble *> a;
4333   for(std::vector<const DataArrayDouble *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
4334     if(*it4)
4335       a.push_back(*it4);
4336   if(a.empty())
4337     throw INTERP_KERNEL::Exception("DataArrayDouble::Aggregate : input list must contain at least one NON EMPTY DataArrayDouble !");
4338   std::vector<const DataArrayDouble *>::const_iterator it=a.begin();
4339   int nbOfComp=(*it)->getNumberOfComponents();
4340   int nbt=(*it++)->getNumberOfTuples();
4341   for(int i=1;it!=a.end();it++,i++)
4342     {
4343       if((*it)->getNumberOfComponents()!=nbOfComp)
4344         throw INTERP_KERNEL::Exception("DataArrayDouble::Aggregate : Nb of components mismatch for array aggregation !");
4345       nbt+=(*it)->getNumberOfTuples();
4346     }
4347   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
4348   ret->alloc(nbt,nbOfComp);
4349   double *pt=ret->getPointer();
4350   for(it=a.begin();it!=a.end();it++)
4351     pt=std::copy((*it)->getConstPointer(),(*it)->getConstPointer()+(*it)->getNbOfElems(),pt);
4352   ret->copyStringInfoFrom(*(a[0]));
4353   return ret.retn();
4354 }
4355
4356 /*!
4357  * Returns a new DataArrayDouble by aggregating two given arrays, so that (1) the number
4358  * of components in the result array is a sum of the number of components of given arrays
4359  * and (2) the number of tuples in the result array is same as that of each of given
4360  * arrays. In other words the i-th tuple of result array includes all components of
4361  * i-th tuples of all given arrays.
4362  * Number of tuples in the given arrays must be  the same.
4363  *  \param [in] a1 - an array to include in the result array.
4364  *  \param [in] a2 - another array to include in the result array.
4365  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4366  *          The caller is to delete this result array using decrRef() as it is no more
4367  *          needed.
4368  *  \throw If both \a a1 and \a a2 are NULL.
4369  *  \throw If any given array is not allocated.
4370  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
4371  */
4372 DataArrayDouble *DataArrayDouble::Meld(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception)
4373 {
4374   std::vector<const DataArrayDouble *> arr(2);
4375   arr[0]=a1; arr[1]=a2;
4376   return Meld(arr);
4377 }
4378
4379 /*!
4380  * Returns a new DataArrayDouble by aggregating all given arrays, so that (1) the number
4381  * of components in the result array is a sum of the number of components of given arrays
4382  * and (2) the number of tuples in the result array is same as that of each of given
4383  * arrays. In other words the i-th tuple of result array includes all components of
4384  * i-th tuples of all given arrays.
4385  * Number of tuples in the given arrays must be  the same.
4386  *  \param [in] arr - a sequence of arrays to include in the result array.
4387  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4388  *          The caller is to delete this result array using decrRef() as it is no more
4389  *          needed.
4390  *  \throw If all arrays within \a arr are NULL.
4391  *  \throw If any given array is not allocated.
4392  *  \throw If getNumberOfTuples() of arrays within \a arr is different.
4393  */
4394 DataArrayDouble *DataArrayDouble::Meld(const std::vector<const DataArrayDouble *>& arr) throw(INTERP_KERNEL::Exception)
4395 {
4396   std::vector<const DataArrayDouble *> a;
4397   for(std::vector<const DataArrayDouble *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
4398     if(*it4)
4399       a.push_back(*it4);
4400   if(a.empty())
4401     throw INTERP_KERNEL::Exception("DataArrayDouble::Meld : input list must contain at least one NON EMPTY DataArrayDouble !");
4402   std::vector<const DataArrayDouble *>::const_iterator it;
4403   for(it=a.begin();it!=a.end();it++)
4404     (*it)->checkAllocated();
4405   it=a.begin();
4406   int nbOfTuples=(*it)->getNumberOfTuples();
4407   std::vector<int> nbc(a.size());
4408   std::vector<const double *> pts(a.size());
4409   nbc[0]=(*it)->getNumberOfComponents();
4410   pts[0]=(*it++)->getConstPointer();
4411   for(int i=1;it!=a.end();it++,i++)
4412     {
4413       if(nbOfTuples!=(*it)->getNumberOfTuples())
4414         throw INTERP_KERNEL::Exception("DataArrayDouble::Meld : mismatch of number of tuples !");
4415       nbc[i]=(*it)->getNumberOfComponents();
4416       pts[i]=(*it)->getConstPointer();
4417     }
4418   int totalNbOfComp=std::accumulate(nbc.begin(),nbc.end(),0);
4419   DataArrayDouble *ret=DataArrayDouble::New();
4420   ret->alloc(nbOfTuples,totalNbOfComp);
4421   double *retPtr=ret->getPointer();
4422   for(int i=0;i<nbOfTuples;i++)
4423     for(int j=0;j<(int)a.size();j++)
4424       {
4425         retPtr=std::copy(pts[j],pts[j]+nbc[j],retPtr);
4426         pts[j]+=nbc[j];
4427       }
4428   int k=0;
4429   for(int i=0;i<(int)a.size();i++)
4430     for(int j=0;j<nbc[i];j++,k++)
4431       ret->setInfoOnComponent(k,a[i]->getInfoOnComponent(j).c_str());
4432   return ret;
4433 }
4434
4435 /*!
4436  * Returns a new DataArrayDouble containing a dot product of two given arrays, so that
4437  * the i-th tuple of the result array is a sum of products of j-th components of i-th
4438  * tuples of given arrays (\f$ a_i = \sum_{j=1}^n a1_j * a2_j \f$).
4439  * Info on components and name is copied from the first of the given arrays.
4440  * Number of tuples and components in the given arrays must be the same.
4441  *  \param [in] a1 - a given array.
4442  *  \param [in] a2 - another given array.
4443  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4444  *          The caller is to delete this result array using decrRef() as it is no more
4445  *          needed.
4446  *  \throw If either \a a1 or \a a2 is NULL.
4447  *  \throw If any given array is not allocated.
4448  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
4449  *  \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents()
4450  */
4451 DataArrayDouble *DataArrayDouble::Dot(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception)
4452 {
4453   if(!a1 || !a2)
4454     throw INTERP_KERNEL::Exception("DataArrayDouble::Dot : input DataArrayDouble instance is NULL !");
4455   a1->checkAllocated();
4456   a2->checkAllocated();
4457   int nbOfComp=a1->getNumberOfComponents();
4458   if(nbOfComp!=a2->getNumberOfComponents())
4459     throw INTERP_KERNEL::Exception("Nb of components mismatch for array Dot !");
4460   int nbOfTuple=a1->getNumberOfTuples();
4461   if(nbOfTuple!=a2->getNumberOfTuples())
4462     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Dot !");
4463   DataArrayDouble *ret=DataArrayDouble::New();
4464   ret->alloc(nbOfTuple,1);
4465   double *retPtr=ret->getPointer();
4466   const double *a1Ptr=a1->getConstPointer();
4467   const double *a2Ptr=a2->getConstPointer();
4468   for(int i=0;i<nbOfTuple;i++)
4469     {
4470       double sum=0.;
4471       for(int j=0;j<nbOfComp;j++)
4472         sum+=a1Ptr[i*nbOfComp+j]*a2Ptr[i*nbOfComp+j];
4473       retPtr[i]=sum;
4474     }
4475   ret->setInfoOnComponent(0,a1->getInfoOnComponent(0).c_str());
4476   ret->setName(a1->getName().c_str());
4477   return ret;
4478 }
4479
4480 /*!
4481  * Returns a new DataArrayDouble containing a cross product of two given arrays, so that
4482  * the i-th tuple of the result array contains 3 components of a vector which is a cross
4483  * product of two vectors defined by the i-th tuples of given arrays.
4484  * Info on components is copied from the first of the given arrays.
4485  * Number of tuples in the given arrays must be the same.
4486  * Number of components in the given arrays must be 3.
4487  *  \param [in] a1 - a given array.
4488  *  \param [in] a2 - another given array.
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() != 3
4495  *  \throw If \a a2->getNumberOfComponents() != 3
4496  */
4497 DataArrayDouble *DataArrayDouble::CrossProduct(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception)
4498 {
4499   if(!a1 || !a2)
4500     throw INTERP_KERNEL::Exception("DataArrayDouble::CrossProduct : input DataArrayDouble instance is NULL !");
4501   int nbOfComp=a1->getNumberOfComponents();
4502   if(nbOfComp!=a2->getNumberOfComponents())
4503     throw INTERP_KERNEL::Exception("Nb of components mismatch for array crossProduct !");
4504   if(nbOfComp!=3)
4505     throw INTERP_KERNEL::Exception("Nb of components must be equal to 3 for array crossProduct !");
4506   int nbOfTuple=a1->getNumberOfTuples();
4507   if(nbOfTuple!=a2->getNumberOfTuples())
4508     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array crossProduct !");
4509   DataArrayDouble *ret=DataArrayDouble::New();
4510   ret->alloc(nbOfTuple,3);
4511   double *retPtr=ret->getPointer();
4512   const double *a1Ptr=a1->getConstPointer();
4513   const double *a2Ptr=a2->getConstPointer();
4514   for(int i=0;i<nbOfTuple;i++)
4515     {
4516       retPtr[3*i]=a1Ptr[3*i+1]*a2Ptr[3*i+2]-a1Ptr[3*i+2]*a2Ptr[3*i+1];
4517       retPtr[3*i+1]=a1Ptr[3*i+2]*a2Ptr[3*i]-a1Ptr[3*i]*a2Ptr[3*i+2];
4518       retPtr[3*i+2]=a1Ptr[3*i]*a2Ptr[3*i+1]-a1Ptr[3*i+1]*a2Ptr[3*i];
4519     }
4520   ret->copyStringInfoFrom(*a1);
4521   return ret;
4522 }
4523
4524 /*!
4525  * Returns a new DataArrayDouble containing maximal values of two given arrays.
4526  * Info on components is copied from the first of the given arrays.
4527  * Number of tuples and components in the given arrays must be the same.
4528  *  \param [in] a1 - an array to compare values with another one.
4529  *  \param [in] a2 - another array to compare values with the first one.
4530  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4531  *          The caller is to delete this result array using decrRef() as it is no more
4532  *          needed.
4533  *  \throw If either \a a1 or \a a2 is NULL.
4534  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
4535  *  \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents()
4536  */
4537 DataArrayDouble *DataArrayDouble::Max(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception)
4538 {
4539   if(!a1 || !a2)
4540     throw INTERP_KERNEL::Exception("DataArrayDouble::Max : input DataArrayDouble instance is NULL !");
4541   int nbOfComp=a1->getNumberOfComponents();
4542   if(nbOfComp!=a2->getNumberOfComponents())
4543     throw INTERP_KERNEL::Exception("Nb of components mismatch for array Max !");
4544   int nbOfTuple=a1->getNumberOfTuples();
4545   if(nbOfTuple!=a2->getNumberOfTuples())
4546     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Max !");
4547   DataArrayDouble *ret=DataArrayDouble::New();
4548   ret->alloc(nbOfTuple,nbOfComp);
4549   double *retPtr=ret->getPointer();
4550   const double *a1Ptr=a1->getConstPointer();
4551   const double *a2Ptr=a2->getConstPointer();
4552   int nbElem=nbOfTuple*nbOfComp;
4553   for(int i=0;i<nbElem;i++)
4554     retPtr[i]=std::max(a1Ptr[i],a2Ptr[i]);
4555   ret->copyStringInfoFrom(*a1);
4556   return ret;
4557 }
4558
4559 /*!
4560  * Returns a new DataArrayDouble containing minimal values of two given arrays.
4561  * Info on components is copied from the first of the given arrays.
4562  * Number of tuples and components in the given arrays must be the same.
4563  *  \param [in] a1 - an array to compare values with another one.
4564  *  \param [in] a2 - another array to compare values with the first one.
4565  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4566  *          The caller is to delete this result array using decrRef() as it is no more
4567  *          needed.
4568  *  \throw If either \a a1 or \a a2 is NULL.
4569  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
4570  *  \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents()
4571  */
4572 DataArrayDouble *DataArrayDouble::Min(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception)
4573 {
4574   if(!a1 || !a2)
4575     throw INTERP_KERNEL::Exception("DataArrayDouble::Min : input DataArrayDouble instance is NULL !");
4576   int nbOfComp=a1->getNumberOfComponents();
4577   if(nbOfComp!=a2->getNumberOfComponents())
4578     throw INTERP_KERNEL::Exception("Nb of components mismatch for array min !");
4579   int nbOfTuple=a1->getNumberOfTuples();
4580   if(nbOfTuple!=a2->getNumberOfTuples())
4581     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array min !");
4582   DataArrayDouble *ret=DataArrayDouble::New();
4583   ret->alloc(nbOfTuple,nbOfComp);
4584   double *retPtr=ret->getPointer();
4585   const double *a1Ptr=a1->getConstPointer();
4586   const double *a2Ptr=a2->getConstPointer();
4587   int nbElem=nbOfTuple*nbOfComp;
4588   for(int i=0;i<nbElem;i++)
4589     retPtr[i]=std::min(a1Ptr[i],a2Ptr[i]);
4590   ret->copyStringInfoFrom(*a1);
4591   return ret;
4592 }
4593
4594 /*!
4595  * Returns a new DataArrayDouble that is a sum of two given arrays. There are 3
4596  * valid cases.
4597  * 1.  The arrays have same number of tuples and components. Then each value of
4598  *   the result array (_a_) is a sum of the corresponding values of \a a1 and \a a2,
4599  *   i.e.: _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ i, j ].
4600  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
4601  *   component. Then
4602  *   _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ i, 0 ].
4603  * 3.  The arrays have same number of components and one array, say _a2_, has one
4604  *   tuple. Then
4605  *   _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ 0, j ].
4606  *
4607  * Info on components is copied either from the first array (in the first case) or from
4608  * the array with maximal number of elements (getNbOfElems()).
4609  *  \param [in] a1 - an array to sum up.
4610  *  \param [in] a2 - another array to sum up.
4611  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4612  *          The caller is to delete this result array using decrRef() as it is no more
4613  *          needed.
4614  *  \throw If either \a a1 or \a a2 is NULL.
4615  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
4616  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
4617  *         none of them has number of tuples or components equal to 1.
4618  */
4619 DataArrayDouble *DataArrayDouble::Add(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception)
4620 {
4621   if(!a1 || !a2)
4622     throw INTERP_KERNEL::Exception("DataArrayDouble::Add : input DataArrayDouble instance is NULL !");
4623   int nbOfTuple=a1->getNumberOfTuples();
4624   int nbOfTuple2=a2->getNumberOfTuples();
4625   int nbOfComp=a1->getNumberOfComponents();
4626   int nbOfComp2=a2->getNumberOfComponents();
4627   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=0;
4628   if(nbOfTuple==nbOfTuple2)
4629     {
4630       if(nbOfComp==nbOfComp2)
4631         {
4632           ret=DataArrayDouble::New();
4633           ret->alloc(nbOfTuple,nbOfComp);
4634           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::plus<double>());
4635           ret->copyStringInfoFrom(*a1);
4636         }
4637       else
4638         {
4639           int nbOfCompMin,nbOfCompMax;
4640           const DataArrayDouble *aMin, *aMax;
4641           if(nbOfComp>nbOfComp2)
4642             {
4643               nbOfCompMin=nbOfComp2; nbOfCompMax=nbOfComp;
4644               aMin=a2; aMax=a1;
4645             }
4646           else
4647             {
4648               nbOfCompMin=nbOfComp; nbOfCompMax=nbOfComp2;
4649               aMin=a1; aMax=a2;
4650             }
4651           if(nbOfCompMin==1)
4652             {
4653               ret=DataArrayDouble::New();
4654               ret->alloc(nbOfTuple,nbOfCompMax);
4655               const double *aMinPtr=aMin->getConstPointer();
4656               const double *aMaxPtr=aMax->getConstPointer();
4657               double *res=ret->getPointer();
4658               for(int i=0;i<nbOfTuple;i++)
4659                 res=std::transform(aMaxPtr+i*nbOfCompMax,aMaxPtr+(i+1)*nbOfCompMax,res,std::bind2nd(std::plus<double>(),aMinPtr[i]));
4660               ret->copyStringInfoFrom(*aMax);
4661             }
4662           else
4663             throw INTERP_KERNEL::Exception("Nb of components mismatch for array Add !");
4664         }
4665     }
4666   else if((nbOfTuple==1 && nbOfTuple2>1) || (nbOfTuple>1 && nbOfTuple2==1))
4667     {
4668       if(nbOfComp==nbOfComp2)
4669         {
4670           int nbOfTupleMax=std::max(nbOfTuple,nbOfTuple2);
4671           const DataArrayDouble *aMin=nbOfTuple>nbOfTuple2?a2:a1;
4672           const DataArrayDouble *aMax=nbOfTuple>nbOfTuple2?a1:a2;
4673           const double *aMinPtr=aMin->getConstPointer(),*aMaxPtr=aMax->getConstPointer();
4674           ret=DataArrayDouble::New();
4675           ret->alloc(nbOfTupleMax,nbOfComp);
4676           double *res=ret->getPointer();
4677           for(int i=0;i<nbOfTupleMax;i++)
4678             res=std::transform(aMaxPtr+i*nbOfComp,aMaxPtr+(i+1)*nbOfComp,aMinPtr,res,std::plus<double>());
4679           ret->copyStringInfoFrom(*aMax);
4680         }
4681       else
4682         throw INTERP_KERNEL::Exception("Nb of components mismatch for array Add !");
4683     }
4684   else
4685     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Add !");
4686   return ret.retn();
4687 }
4688
4689 /*!
4690  * Adds values of another DataArrayDouble to values of \a this one. There are 3
4691  * valid cases.
4692  * 1.  The arrays have same number of tuples and components. Then each value of
4693  *   \a other array is added to the corresponding value of \a this array, i.e.:
4694  *   _a_ [ i, j ] += _other_ [ i, j ].
4695  * 2.  The arrays have same number of tuples and \a other array has one component. Then
4696  *   _a_ [ i, j ] += _other_ [ i, 0 ].
4697  * 3.  The arrays have same number of components and \a other array has one tuple. Then
4698  *   _a_ [ i, j ] += _a2_ [ 0, j ].
4699  *
4700  *  \param [in] other - an array to add to \a this one.
4701  *  \throw If \a other is NULL.
4702  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
4703  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
4704  *         \a other has number of both tuples and components not equal to 1.
4705  */
4706 void DataArrayDouble::addEqual(const DataArrayDouble *other) throw(INTERP_KERNEL::Exception)
4707 {
4708   if(!other)
4709     throw INTERP_KERNEL::Exception("DataArrayDouble::addEqual : input DataArrayDouble instance is NULL !");
4710   const char *msg="Nb of tuples mismatch for DataArrayDouble::addEqual  !";
4711   checkAllocated();
4712   other->checkAllocated();
4713   int nbOfTuple=getNumberOfTuples();
4714   int nbOfTuple2=other->getNumberOfTuples();
4715   int nbOfComp=getNumberOfComponents();
4716   int nbOfComp2=other->getNumberOfComponents();
4717   if(nbOfTuple==nbOfTuple2)
4718     {
4719       if(nbOfComp==nbOfComp2)
4720         {
4721           std::transform(begin(),end(),other->begin(),getPointer(),std::plus<double>());
4722         }
4723       else if(nbOfComp2==1)
4724         {
4725           double *ptr=getPointer();
4726           const double *ptrc=other->getConstPointer();
4727           for(int i=0;i<nbOfTuple;i++)
4728             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::plus<double>(),*ptrc++));
4729         }
4730       else
4731         throw INTERP_KERNEL::Exception(msg);
4732     }
4733   else if(nbOfTuple2==1)
4734     {
4735       if(nbOfComp2==nbOfComp)
4736         {
4737           double *ptr=getPointer();
4738           const double *ptrc=other->getConstPointer();
4739           for(int i=0;i<nbOfTuple;i++)
4740             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::plus<double>());
4741         }
4742       else
4743         throw INTERP_KERNEL::Exception(msg);
4744     }
4745   else
4746     throw INTERP_KERNEL::Exception(msg);
4747   declareAsNew();
4748 }
4749
4750 /*!
4751  * Returns a new DataArrayDouble that is a subtraction of two given arrays. There are 3
4752  * valid cases.
4753  * 1.  The arrays have same number of tuples and components. Then each value of
4754  *   the result array (_a_) is a subtraction of the corresponding values of \a a1 and
4755  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ i, j ].
4756  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
4757  *   component. Then
4758  *   _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ i, 0 ].
4759  * 3.  The arrays have same number of components and one array, say _a2_, has one
4760  *   tuple. Then
4761  *   _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ 0, j ].
4762  *
4763  * Info on components is copied either from the first array (in the first case) or from
4764  * the array with maximal number of elements (getNbOfElems()).
4765  *  \param [in] a1 - an array to subtract from.
4766  *  \param [in] a2 - an array to subtract.
4767  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4768  *          The caller is to delete this result array using decrRef() as it is no more
4769  *          needed.
4770  *  \throw If either \a a1 or \a a2 is NULL.
4771  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
4772  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
4773  *         none of them has number of tuples or components equal to 1.
4774  */
4775 DataArrayDouble *DataArrayDouble::Substract(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception)
4776 {
4777   if(!a1 || !a2)
4778     throw INTERP_KERNEL::Exception("DataArrayDouble::Substract : input DataArrayDouble instance is NULL !");
4779   int nbOfTuple1=a1->getNumberOfTuples();
4780   int nbOfTuple2=a2->getNumberOfTuples();
4781   int nbOfComp1=a1->getNumberOfComponents();
4782   int nbOfComp2=a2->getNumberOfComponents();
4783   if(nbOfTuple2==nbOfTuple1)
4784     {
4785       if(nbOfComp1==nbOfComp2)
4786         {
4787           MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
4788           ret->alloc(nbOfTuple2,nbOfComp1);
4789           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::minus<double>());
4790           ret->copyStringInfoFrom(*a1);
4791           return ret.retn();
4792         }
4793       else if(nbOfComp2==1)
4794         {
4795           MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
4796           ret->alloc(nbOfTuple1,nbOfComp1);
4797           const double *a2Ptr=a2->getConstPointer();
4798           const double *a1Ptr=a1->getConstPointer();
4799           double *res=ret->getPointer();
4800           for(int i=0;i<nbOfTuple1;i++)
4801             res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::minus<double>(),a2Ptr[i]));
4802           ret->copyStringInfoFrom(*a1);
4803           return ret.retn();
4804         }
4805       else
4806         {
4807           a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Substract !");
4808           return 0;
4809         }
4810     }
4811   else if(nbOfTuple2==1)
4812     {
4813       a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Substract !");
4814       MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
4815       ret->alloc(nbOfTuple1,nbOfComp1);
4816       const double *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
4817       double *pt=ret->getPointer();
4818       for(int i=0;i<nbOfTuple1;i++)
4819         pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::minus<double>());
4820       ret->copyStringInfoFrom(*a1);
4821       return ret.retn();
4822     }
4823   else
4824     {
4825       a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Substract !");//will always throw an exception
4826       return 0;
4827     }
4828 }
4829
4830 /*!
4831  * Subtract values of another DataArrayDouble from values of \a this one. There are 3
4832  * valid cases.
4833  * 1.  The arrays have same number of tuples and components. Then each value of
4834  *   \a other array is subtracted from the corresponding value of \a this array, i.e.:
4835  *   _a_ [ i, j ] -= _other_ [ i, j ].
4836  * 2.  The arrays have same number of tuples and \a other array has one component. Then
4837  *   _a_ [ i, j ] -= _other_ [ i, 0 ].
4838  * 3.  The arrays have same number of components and \a other array has one tuple. Then
4839  *   _a_ [ i, j ] -= _a2_ [ 0, j ].
4840  *
4841  *  \param [in] other - an array to subtract from \a this one.
4842  *  \throw If \a other is NULL.
4843  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
4844  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
4845  *         \a other has number of both tuples and components not equal to 1.
4846  */
4847 void DataArrayDouble::substractEqual(const DataArrayDouble *other) throw(INTERP_KERNEL::Exception)
4848 {
4849   if(!other)
4850     throw INTERP_KERNEL::Exception("DataArrayDouble::substractEqual : input DataArrayDouble instance is NULL !");
4851   const char *msg="Nb of tuples mismatch for DataArrayDouble::substractEqual  !";
4852   checkAllocated();
4853   other->checkAllocated();
4854   int nbOfTuple=getNumberOfTuples();
4855   int nbOfTuple2=other->getNumberOfTuples();
4856   int nbOfComp=getNumberOfComponents();
4857   int nbOfComp2=other->getNumberOfComponents();
4858   if(nbOfTuple==nbOfTuple2)
4859     {
4860       if(nbOfComp==nbOfComp2)
4861         {
4862           std::transform(begin(),end(),other->begin(),getPointer(),std::minus<double>());
4863         }
4864       else if(nbOfComp2==1)
4865         {
4866           double *ptr=getPointer();
4867           const double *ptrc=other->getConstPointer();
4868           for(int i=0;i<nbOfTuple;i++)
4869             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::minus<double>(),*ptrc++)); 
4870         }
4871       else
4872         throw INTERP_KERNEL::Exception(msg);
4873     }
4874   else if(nbOfTuple2==1)
4875     {
4876       if(nbOfComp2==nbOfComp)
4877         {
4878           double *ptr=getPointer();
4879           const double *ptrc=other->getConstPointer();
4880           for(int i=0;i<nbOfTuple;i++)
4881             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::minus<double>());
4882         }
4883       else
4884         throw INTERP_KERNEL::Exception(msg);
4885     }
4886   else
4887     throw INTERP_KERNEL::Exception(msg);
4888   declareAsNew();
4889 }
4890
4891 /*!
4892  * Returns a new DataArrayDouble that is a product of two given arrays. There are 3
4893  * valid cases.
4894  * 1.  The arrays have same number of tuples and components. Then each value of
4895  *   the result array (_a_) is a product of the corresponding values of \a a1 and
4896  *   \a a2, i.e. _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ i, j ].
4897  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
4898  *   component. Then
4899  *   _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ i, 0 ].
4900  * 3.  The arrays have same number of components and one array, say _a2_, has one
4901  *   tuple. Then
4902  *   _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ 0, j ].
4903  *
4904  * Info on components is copied either from the first array (in the first case) or from
4905  * the array with maximal number of elements (getNbOfElems()).
4906  *  \param [in] a1 - a factor array.
4907  *  \param [in] a2 - another factor array.
4908  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4909  *          The caller is to delete this result array using decrRef() as it is no more
4910  *          needed.
4911  *  \throw If either \a a1 or \a a2 is NULL.
4912  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
4913  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
4914  *         none of them has number of tuples or components equal to 1.
4915  */
4916 DataArrayDouble *DataArrayDouble::Multiply(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception)
4917 {
4918   if(!a1 || !a2)
4919     throw INTERP_KERNEL::Exception("DataArrayDouble::Multiply : input DataArrayDouble instance is NULL !");
4920   int nbOfTuple=a1->getNumberOfTuples();
4921   int nbOfTuple2=a2->getNumberOfTuples();
4922   int nbOfComp=a1->getNumberOfComponents();
4923   int nbOfComp2=a2->getNumberOfComponents();
4924   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=0;
4925   if(nbOfTuple==nbOfTuple2)
4926     {
4927       if(nbOfComp==nbOfComp2)
4928         {
4929           ret=DataArrayDouble::New();
4930           ret->alloc(nbOfTuple,nbOfComp);
4931           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::multiplies<double>());
4932           ret->copyStringInfoFrom(*a1);
4933         }
4934       else
4935         {
4936           int nbOfCompMin,nbOfCompMax;
4937           const DataArrayDouble *aMin, *aMax;
4938           if(nbOfComp>nbOfComp2)
4939             {
4940               nbOfCompMin=nbOfComp2; nbOfCompMax=nbOfComp;
4941               aMin=a2; aMax=a1;
4942             }
4943           else
4944             {
4945               nbOfCompMin=nbOfComp; nbOfCompMax=nbOfComp2;
4946               aMin=a1; aMax=a2;
4947             }
4948           if(nbOfCompMin==1)
4949             {
4950               ret=DataArrayDouble::New();
4951               ret->alloc(nbOfTuple,nbOfCompMax);
4952               const double *aMinPtr=aMin->getConstPointer();
4953               const double *aMaxPtr=aMax->getConstPointer();
4954               double *res=ret->getPointer();
4955               for(int i=0;i<nbOfTuple;i++)
4956                 res=std::transform(aMaxPtr+i*nbOfCompMax,aMaxPtr+(i+1)*nbOfCompMax,res,std::bind2nd(std::multiplies<double>(),aMinPtr[i]));
4957               ret->copyStringInfoFrom(*aMax);
4958             }
4959           else
4960             throw INTERP_KERNEL::Exception("Nb of components mismatch for array Multiply !");
4961         }
4962     }
4963   else if((nbOfTuple==1 && nbOfTuple2>1) || (nbOfTuple>1 && nbOfTuple2==1))
4964     {
4965       if(nbOfComp==nbOfComp2)
4966         {
4967           int nbOfTupleMax=std::max(nbOfTuple,nbOfTuple2);
4968           const DataArrayDouble *aMin=nbOfTuple>nbOfTuple2?a2:a1;
4969           const DataArrayDouble *aMax=nbOfTuple>nbOfTuple2?a1:a2;
4970           const double *aMinPtr=aMin->getConstPointer(),*aMaxPtr=aMax->getConstPointer();
4971           ret=DataArrayDouble::New();
4972           ret->alloc(nbOfTupleMax,nbOfComp);
4973           double *res=ret->getPointer();
4974           for(int i=0;i<nbOfTupleMax;i++)
4975             res=std::transform(aMaxPtr+i*nbOfComp,aMaxPtr+(i+1)*nbOfComp,aMinPtr,res,std::multiplies<double>());
4976           ret->copyStringInfoFrom(*aMax);
4977         }
4978       else
4979         throw INTERP_KERNEL::Exception("Nb of components mismatch for array Multiply !");
4980     }
4981   else
4982     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Multiply !");
4983   return ret.retn();
4984 }
4985
4986 /*!
4987  * Multiply values of another DataArrayDouble to values of \a this one. There are 3
4988  * valid cases.
4989  * 1.  The arrays have same number of tuples and components. Then each value of
4990  *   \a other array is multiplied to the corresponding value of \a this array, i.e.
4991  *   _this_ [ i, j ] *= _other_ [ i, j ].
4992  * 2.  The arrays have same number of tuples and \a other array has one component. Then
4993  *   _this_ [ i, j ] *= _other_ [ i, 0 ].
4994  * 3.  The arrays have same number of components and \a other array has one tuple. Then
4995  *   _this_ [ i, j ] *= _a2_ [ 0, j ].
4996  *
4997  *  \param [in] other - an array to multiply to \a this one.
4998  *  \throw If \a other is NULL.
4999  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
5000  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
5001  *         \a other has number of both tuples and components not equal to 1.
5002  */
5003 void DataArrayDouble::multiplyEqual(const DataArrayDouble *other) throw(INTERP_KERNEL::Exception)
5004 {
5005   if(!other)
5006     throw INTERP_KERNEL::Exception("DataArrayDouble::multiplyEqual : input DataArrayDouble instance is NULL !");
5007   const char *msg="Nb of tuples mismatch for DataArrayDouble::multiplyEqual !";
5008   checkAllocated();
5009   other->checkAllocated();
5010   int nbOfTuple=getNumberOfTuples();
5011   int nbOfTuple2=other->getNumberOfTuples();
5012   int nbOfComp=getNumberOfComponents();
5013   int nbOfComp2=other->getNumberOfComponents();
5014   if(nbOfTuple==nbOfTuple2)
5015     {
5016       if(nbOfComp==nbOfComp2)
5017         {
5018           std::transform(begin(),end(),other->begin(),getPointer(),std::multiplies<double>());
5019         }
5020       else if(nbOfComp2==1)
5021         {
5022           double *ptr=getPointer();
5023           const double *ptrc=other->getConstPointer();
5024           for(int i=0;i<nbOfTuple;i++)
5025             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::multiplies<double>(),*ptrc++));
5026         }
5027       else
5028         throw INTERP_KERNEL::Exception(msg);
5029     }
5030   else if(nbOfTuple2==1)
5031     {
5032       if(nbOfComp2==nbOfComp)
5033         {
5034           double *ptr=getPointer();
5035           const double *ptrc=other->getConstPointer();
5036           for(int i=0;i<nbOfTuple;i++)
5037             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::multiplies<double>());
5038         }
5039       else
5040         throw INTERP_KERNEL::Exception(msg);
5041     }
5042   else
5043     throw INTERP_KERNEL::Exception(msg);
5044   declareAsNew();
5045 }
5046
5047 /*!
5048  * Returns a new DataArrayDouble that is a division of two given arrays. There are 3
5049  * valid cases.
5050  * 1.  The arrays have same number of tuples and components. Then each value of
5051  *   the result array (_a_) is a division of the corresponding values of \a a1 and
5052  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ i, j ].
5053  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
5054  *   component. Then
5055  *   _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ i, 0 ].
5056  * 3.  The arrays have same number of components and one array, say _a2_, has one
5057  *   tuple. Then
5058  *   _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ 0, j ].
5059  *
5060  * Info on components is copied either from the first array (in the first case) or from
5061  * the array with maximal number of elements (getNbOfElems()).
5062  *  \warning No check of division by zero is performed!
5063  *  \param [in] a1 - a numerator array.
5064  *  \param [in] a2 - a denominator array.
5065  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
5066  *          The caller is to delete this result array using decrRef() as it is no more
5067  *          needed.
5068  *  \throw If either \a a1 or \a a2 is NULL.
5069  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
5070  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
5071  *         none of them has number of tuples or components equal to 1.
5072  */
5073 DataArrayDouble *DataArrayDouble::Divide(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception)
5074 {
5075   if(!a1 || !a2)
5076     throw INTERP_KERNEL::Exception("DataArrayDouble::Divide : input DataArrayDouble instance is NULL !");
5077   int nbOfTuple1=a1->getNumberOfTuples();
5078   int nbOfTuple2=a2->getNumberOfTuples();
5079   int nbOfComp1=a1->getNumberOfComponents();
5080   int nbOfComp2=a2->getNumberOfComponents();
5081   if(nbOfTuple2==nbOfTuple1)
5082     {
5083       if(nbOfComp1==nbOfComp2)
5084         {
5085           MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
5086           ret->alloc(nbOfTuple2,nbOfComp1);
5087           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::divides<double>());
5088           ret->copyStringInfoFrom(*a1);
5089           return ret.retn();
5090         }
5091       else if(nbOfComp2==1)
5092         {
5093           MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
5094           ret->alloc(nbOfTuple1,nbOfComp1);
5095           const double *a2Ptr=a2->getConstPointer();
5096           const double *a1Ptr=a1->getConstPointer();
5097           double *res=ret->getPointer();
5098           for(int i=0;i<nbOfTuple1;i++)
5099             res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::divides<double>(),a2Ptr[i]));
5100           ret->copyStringInfoFrom(*a1);
5101           return ret.retn();
5102         }
5103       else
5104         {
5105           a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Divide !");
5106           return 0;
5107         }
5108     }
5109   else if(nbOfTuple2==1)
5110     {
5111       a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Divide !");
5112       MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
5113       ret->alloc(nbOfTuple1,nbOfComp1);
5114       const double *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
5115       double *pt=ret->getPointer();
5116       for(int i=0;i<nbOfTuple1;i++)
5117         pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::divides<double>());
5118       ret->copyStringInfoFrom(*a1);
5119       return ret.retn();
5120     }
5121   else
5122     {
5123       a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Divide !");//will always throw an exception
5124       return 0;
5125     }
5126 }
5127
5128 /*!
5129  * Divide values of \a this array by values of another DataArrayDouble. There are 3
5130  * valid cases.
5131  * 1.  The arrays have same number of tuples and components. Then each value of
5132  *    \a this array is divided by the corresponding value of \a other one, i.e.:
5133  *   _a_ [ i, j ] /= _other_ [ i, j ].
5134  * 2.  The arrays have same number of tuples and \a other array has one component. Then
5135  *   _a_ [ i, j ] /= _other_ [ i, 0 ].
5136  * 3.  The arrays have same number of components and \a other array has one tuple. Then
5137  *   _a_ [ i, j ] /= _a2_ [ 0, j ].
5138  *
5139  *  \warning No check of division by zero is performed!
5140  *  \param [in] other - an array to divide \a this one by.
5141  *  \throw If \a other is NULL.
5142  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
5143  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
5144  *         \a other has number of both tuples and components not equal to 1.
5145  */
5146 void DataArrayDouble::divideEqual(const DataArrayDouble *other) throw(INTERP_KERNEL::Exception)
5147 {
5148   if(!other)
5149     throw INTERP_KERNEL::Exception("DataArrayDouble::divideEqual : input DataArrayDouble instance is NULL !");
5150   const char *msg="Nb of tuples mismatch for DataArrayDouble::divideEqual !";
5151   checkAllocated();
5152   other->checkAllocated();
5153   int nbOfTuple=getNumberOfTuples();
5154   int nbOfTuple2=other->getNumberOfTuples();
5155   int nbOfComp=getNumberOfComponents();
5156   int nbOfComp2=other->getNumberOfComponents();
5157   if(nbOfTuple==nbOfTuple2)
5158     {
5159       if(nbOfComp==nbOfComp2)
5160         {
5161           std::transform(begin(),end(),other->begin(),getPointer(),std::divides<double>());
5162         }
5163       else if(nbOfComp2==1)
5164         {
5165           double *ptr=getPointer();
5166           const double *ptrc=other->getConstPointer();
5167           for(int i=0;i<nbOfTuple;i++)
5168             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::divides<double>(),*ptrc++));
5169         }
5170       else
5171         throw INTERP_KERNEL::Exception(msg);
5172     }
5173   else if(nbOfTuple2==1)
5174     {
5175       if(nbOfComp2==nbOfComp)
5176         {
5177           double *ptr=getPointer();
5178           const double *ptrc=other->getConstPointer();
5179           for(int i=0;i<nbOfTuple;i++)
5180             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::divides<double>());
5181         }
5182       else
5183         throw INTERP_KERNEL::Exception(msg);
5184     }
5185   else
5186     throw INTERP_KERNEL::Exception(msg);
5187   declareAsNew();
5188 }
5189
5190 /*!
5191  * Returns a new DataArrayDouble that is the result of pow of two given arrays. There are 3
5192  * valid cases.
5193  *
5194  *  \param [in] a1 - an array to pow up.
5195  *  \param [in] a2 - another array to sum up.
5196  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
5197  *          The caller is to delete this result array using decrRef() as it is no more
5198  *          needed.
5199  *  \throw If either \a a1 or \a a2 is NULL.
5200  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
5201  *  \throw If \a a1->getNumberOfComponents() != 1 or \a a2->getNumberOfComponents() != 1.
5202  *  \throw If there is a negative value in \a a1.
5203  */
5204 DataArrayDouble *DataArrayDouble::Pow(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception)
5205 {
5206   if(!a1 || !a2)
5207     throw INTERP_KERNEL::Exception("DataArrayDouble::Pow : at least one of input instances is null !");
5208   int nbOfTuple=a1->getNumberOfTuples();
5209   int nbOfTuple2=a2->getNumberOfTuples();
5210   int nbOfComp=a1->getNumberOfComponents();
5211   int nbOfComp2=a2->getNumberOfComponents();
5212   if(nbOfTuple!=nbOfTuple2)
5213     throw INTERP_KERNEL::Exception("DataArrayDouble::Pow : number of tuples mismatches !");
5214   if(nbOfComp!=1 || nbOfComp2!=1)
5215     throw INTERP_KERNEL::Exception("DataArrayDouble::Pow : number of components of both arrays must be equal to 1 !");
5216   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New(); ret->alloc(nbOfTuple,1);
5217   const double *ptr1(a1->begin()),*ptr2(a2->begin());
5218   double *ptr=ret->getPointer();
5219   for(int i=0;i<nbOfTuple;i++,ptr1++,ptr2++,ptr++)
5220     {
5221       if(*ptr1>=0)
5222         {
5223           *ptr=pow(*ptr1,*ptr2);
5224         }
5225       else
5226         {
5227           std::ostringstream oss; oss << "DataArrayDouble::Pow : on tuple #" << i << " of a1 value is < 0 (" << *ptr1 << ") !";
5228           throw INTERP_KERNEL::Exception(oss.str().c_str());
5229         }
5230     }
5231   return ret.retn();
5232 }
5233
5234 /*!
5235  * Apply pow on values of another DataArrayDouble to values of \a this one.
5236  *
5237  *  \param [in] other - an array to pow to \a this one.
5238  *  \throw If \a other is NULL.
5239  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples()
5240  *  \throw If \a this->getNumberOfComponents() != 1 or \a other->getNumberOfComponents() != 1
5241  *  \throw If there is a negative value in \a this.
5242  */
5243 void DataArrayDouble::powEqual(const DataArrayDouble *other) throw(INTERP_KERNEL::Exception)
5244 {
5245   if(!other)
5246     throw INTERP_KERNEL::Exception("DataArrayDouble::powEqual : input instance is null !");
5247   int nbOfTuple=getNumberOfTuples();
5248   int nbOfTuple2=other->getNumberOfTuples();
5249   int nbOfComp=getNumberOfComponents();
5250   int nbOfComp2=other->getNumberOfComponents();
5251   if(nbOfTuple!=nbOfTuple2)
5252     throw INTERP_KERNEL::Exception("DataArrayDouble::powEqual : number of tuples mismatches !");
5253   if(nbOfComp!=1 || nbOfComp2!=1)
5254     throw INTERP_KERNEL::Exception("DataArrayDouble::powEqual : number of components of both arrays must be equal to 1 !");
5255   double *ptr=getPointer();
5256   const double *ptrc=other->begin();
5257   for(int i=0;i<nbOfTuple;i++,ptrc++,ptr++)
5258     {
5259       if(*ptr>=0)
5260         *ptr=pow(*ptr,*ptrc);
5261       else
5262         {
5263           std::ostringstream oss; oss << "DataArrayDouble::powEqual : on tuple #" << i << " of this value is < 0 (" << *ptr << ") !";
5264           throw INTERP_KERNEL::Exception(oss.str().c_str());
5265         }
5266     }
5267   declareAsNew();
5268 }
5269
5270 /*!
5271  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
5272  * Server side.
5273  */
5274 void DataArrayDouble::getTinySerializationIntInformation(std::vector<int>& tinyInfo) const
5275 {
5276   tinyInfo.resize(2);
5277   if(isAllocated())
5278     {
5279       tinyInfo[0]=getNumberOfTuples();
5280       tinyInfo[1]=getNumberOfComponents();
5281     }
5282   else
5283     {
5284       tinyInfo[0]=-1;
5285       tinyInfo[1]=-1;
5286     }
5287 }
5288
5289 /*!
5290  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
5291  * Server side.
5292  */
5293 void DataArrayDouble::getTinySerializationStrInformation(std::vector<std::string>& tinyInfo) const
5294 {
5295   if(isAllocated())
5296     {
5297       int nbOfCompo=getNumberOfComponents();
5298       tinyInfo.resize(nbOfCompo+1);
5299       tinyInfo[0]=getName();
5300       for(int i=0;i<nbOfCompo;i++)
5301         tinyInfo[i+1]=getInfoOnComponent(i);
5302     }
5303   else
5304     {
5305       tinyInfo.resize(1);
5306       tinyInfo[0]=getName();
5307     }
5308 }
5309
5310 /*!
5311  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
5312  * This method returns if a feeding is needed.
5313  */
5314 bool DataArrayDouble::resizeForUnserialization(const std::vector<int>& tinyInfoI)
5315 {
5316   int nbOfTuple=tinyInfoI[0];
5317   int nbOfComp=tinyInfoI[1];
5318   if(nbOfTuple!=-1 || nbOfComp!=-1)
5319     {
5320       alloc(nbOfTuple,nbOfComp);
5321       return true;
5322     }
5323   return false;
5324 }
5325
5326 /*!
5327  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
5328  */
5329 void DataArrayDouble::finishUnserialization(const std::vector<int>& tinyInfoI, const std::vector<std::string>& tinyInfoS)
5330 {
5331   setName(tinyInfoS[0].c_str());
5332   if(isAllocated())
5333     {
5334       int nbOfCompo=getNumberOfComponents();
5335       for(int i=0;i<nbOfCompo;i++)
5336         setInfoOnComponent(i,tinyInfoS[i+1].c_str());
5337     }
5338 }
5339
5340 DataArrayDoubleIterator::DataArrayDoubleIterator(DataArrayDouble *da):_da(da),_tuple_id(0),_nb_comp(0),_nb_tuple(0)
5341 {
5342   if(_da)
5343     {
5344       _da->incrRef();
5345       if(_da->isAllocated())
5346         {
5347           _nb_comp=da->getNumberOfComponents();
5348           _nb_tuple=da->getNumberOfTuples();
5349           _pt=da->getPointer();
5350         }
5351     }
5352 }
5353
5354 DataArrayDoubleIterator::~DataArrayDoubleIterator()
5355 {
5356   if(_da)
5357     _da->decrRef();
5358 }
5359
5360 DataArrayDoubleTuple *DataArrayDoubleIterator::nextt() throw(INTERP_KERNEL::Exception)
5361 {
5362   if(_tuple_id<_nb_tuple)
5363     {
5364       _tuple_id++;
5365       DataArrayDoubleTuple *ret=new DataArrayDoubleTuple(_pt,_nb_comp);
5366       _pt+=_nb_comp;
5367       return ret;
5368     }
5369   else
5370     return 0;
5371 }
5372
5373 DataArrayDoubleTuple::DataArrayDoubleTuple(double *pt, int nbOfComp):_pt(pt),_nb_of_compo(nbOfComp)
5374 {
5375 }
5376
5377
5378 std::string DataArrayDoubleTuple::repr() const throw(INTERP_KERNEL::Exception)
5379 {
5380   std::ostringstream oss; oss.precision(17); oss << "(";
5381   for(int i=0;i<_nb_of_compo-1;i++)
5382     oss << _pt[i] << ", ";
5383   oss << _pt[_nb_of_compo-1] << ")";
5384   return oss.str();
5385 }
5386
5387 double DataArrayDoubleTuple::doubleValue() const throw(INTERP_KERNEL::Exception)
5388 {
5389   if(_nb_of_compo==1)
5390     return *_pt;
5391   throw INTERP_KERNEL::Exception("DataArrayDoubleTuple::doubleValue : DataArrayDoubleTuple instance has not exactly 1 component -> Not possible to convert it into a double precision float !");
5392 }
5393
5394 /*!
5395  * This method returns a newly allocated instance the caller should dealed with by a ParaMEDMEM::DataArrayDouble::decrRef.
5396  * This method performs \b no copy of data. The content is only referenced using ParaMEDMEM::DataArrayDouble::useArray with ownership set to \b false.
5397  * 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
5398  * \b nbOfCompo=1 and \bnbOfTuples==this->_nb_of_elem.
5399  */
5400 DataArrayDouble *DataArrayDoubleTuple::buildDADouble(int nbOfTuples, int nbOfCompo) const throw(INTERP_KERNEL::Exception)
5401 {
5402   if((_nb_of_compo==nbOfCompo && nbOfTuples==1) || (_nb_of_compo==nbOfTuples && nbOfCompo==1))
5403     {
5404       DataArrayDouble *ret=DataArrayDouble::New();
5405       ret->useExternalArrayWithRWAccess(_pt,nbOfTuples,nbOfCompo);
5406       return ret;
5407     }
5408   else
5409     {
5410       std::ostringstream oss; oss << "DataArrayDoubleTuple::buildDADouble : unable to build a requested DataArrayDouble instance with nbofTuple=" << nbOfTuples << " and nbOfCompo=" << nbOfCompo;
5411       oss << ".\nBecause the number of elements in this is " << _nb_of_compo << " !";
5412       throw INTERP_KERNEL::Exception(oss.str().c_str());
5413     }
5414 }
5415
5416 /*!
5417  * Returns a new instance of DataArrayInt. The caller is to delete this array
5418  * using decrRef() as it is no more needed. 
5419  */
5420 DataArrayInt *DataArrayInt::New()
5421 {
5422   return new DataArrayInt;
5423 }
5424
5425 /*!
5426  * Checks if raw data is allocated. Read more on the raw data
5427  * in \ref MEDCouplingArrayBasicsTuplesAndCompo "DataArrays infos" for more information.
5428  *  \return bool - \a true if the raw data is allocated, \a false else.
5429  */
5430 bool DataArrayInt::isAllocated() const throw(INTERP_KERNEL::Exception)
5431 {
5432   return getConstPointer()!=0;
5433 }
5434
5435 /*!
5436  * Checks if raw data is allocated and throws an exception if it is not the case.
5437  *  \throw If the raw data is not allocated.
5438  */
5439 void DataArrayInt::checkAllocated() const throw(INTERP_KERNEL::Exception)
5440 {
5441   if(!isAllocated())
5442     throw INTERP_KERNEL::Exception("DataArrayInt::checkAllocated : Array is defined but not allocated ! Call alloc or setValues method first !");
5443 }
5444
5445 /*!
5446  * This method desallocated \a this without modification of informations relative to the components.
5447  * After call of this method, DataArrayInt::isAllocated will return false.
5448  * If \a this is already not allocated, \a this is let unchanged.
5449  */
5450 void DataArrayInt::desallocate() throw(INTERP_KERNEL::Exception)
5451 {
5452   _mem.destroy();
5453 }
5454
5455 std::size_t DataArrayInt::getHeapMemorySize() const
5456 {
5457   std::size_t sz=_mem.getNbOfElemAllocated();
5458   sz*=sizeof(int);
5459   return DataArray::getHeapMemorySize()+sz;
5460 }
5461
5462 /*!
5463  * Returns the only one value in \a this, if and only if number of elements
5464  * (nb of tuples * nb of components) is equal to 1, and that \a this is allocated.
5465  *  \return double - the sole value stored in \a this array.
5466  *  \throw If at least one of conditions stated above is not fulfilled.
5467  */
5468 int DataArrayInt::intValue() const throw(INTERP_KERNEL::Exception)
5469 {
5470   if(isAllocated())
5471     {
5472       if(getNbOfElems()==1)
5473         {
5474           return *getConstPointer();
5475         }
5476       else
5477         throw INTERP_KERNEL::Exception("DataArrayInt::intValue : DataArrayInt instance is allocated but number of elements is not equal to 1 !");
5478     }
5479   else
5480     throw INTERP_KERNEL::Exception("DataArrayInt::intValue : DataArrayInt instance is not allocated !");
5481 }
5482
5483 /*!
5484  * Returns an integer value characterizing \a this array, which is useful for a quick
5485  * comparison of many instances of DataArrayInt.
5486  *  \return int - the hash value.
5487  *  \throw If \a this is not allocated.
5488  */
5489 int DataArrayInt::getHashCode() const throw(INTERP_KERNEL::Exception)
5490 {
5491   checkAllocated();
5492   std::size_t nbOfElems=getNbOfElems();
5493   int ret=nbOfElems*65536;
5494   int delta=3;
5495   if(nbOfElems>48)
5496     delta=nbOfElems/8;
5497   int ret0=0;
5498   const int *pt=begin();
5499   for(std::size_t i=0;i<nbOfElems;i+=delta)
5500     ret0+=pt[i] & 0x1FFF;
5501   return ret+ret0;
5502 }
5503
5504 /*!
5505  * Checks the number of tuples.
5506  *  \return bool - \a true if getNumberOfTuples() == 0, \a false else.
5507  *  \throw If \a this is not allocated.
5508  */
5509 bool DataArrayInt::empty() const throw(INTERP_KERNEL::Exception)
5510 {
5511   checkAllocated();
5512   return getNumberOfTuples()==0;
5513 }
5514
5515 /*!
5516  * Returns a full copy of \a this. For more info on copying data arrays see
5517  * \ref MEDCouplingArrayBasicsCopyDeep.
5518  *  \return DataArrayInt * - a new instance of DataArrayInt.
5519  */
5520 DataArrayInt *DataArrayInt::deepCpy() const throw(INTERP_KERNEL::Exception)
5521 {
5522   return new DataArrayInt(*this);
5523 }
5524
5525 /*!
5526  * Returns either a \a deep or \a shallow copy of this array. For more info see
5527  * \ref MEDCouplingArrayBasicsCopyDeep and \ref MEDCouplingArrayBasicsCopyShallow.
5528  *  \param [in] dCpy - if \a true, a deep copy is returned, else, a shallow one.
5529  *  \return DataArrayInt * - either a new instance of DataArrayInt (if \a dCpy
5530  *          == \a true) or \a this instance (if \a dCpy == \a false).
5531  */
5532 DataArrayInt *DataArrayInt::performCpy(bool dCpy) const throw(INTERP_KERNEL::Exception)
5533 {
5534   if(dCpy)
5535     return deepCpy();
5536   else
5537     {
5538       incrRef();
5539       return const_cast<DataArrayInt *>(this);
5540     }
5541 }
5542
5543 /*!
5544  * Copies all the data from another DataArrayInt. For more info see
5545  * \ref MEDCouplingArrayBasicsCopyDeepAssign.
5546  *  \param [in] other - another instance of DataArrayInt to copy data from.
5547  *  \throw If the \a other is not allocated.
5548  */
5549 void DataArrayInt::cpyFrom(const DataArrayInt& other) throw(INTERP_KERNEL::Exception)
5550 {
5551   other.checkAllocated();
5552   int nbOfTuples=other.getNumberOfTuples();
5553   int nbOfComp=other.getNumberOfComponents();
5554   allocIfNecessary(nbOfTuples,nbOfComp);
5555   std::size_t nbOfElems=(std::size_t)nbOfTuples*nbOfComp;
5556   int *pt=getPointer();
5557   const int *ptI=other.getConstPointer();
5558   for(std::size_t i=0;i<nbOfElems;i++)
5559     pt[i]=ptI[i];
5560   copyStringInfoFrom(other);
5561 }
5562
5563 /*!
5564  * This method reserve nbOfElems elements in memory ( nbOfElems*4 bytes ) \b without impacting the number of tuples in \a this.
5565  * 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.
5566  * If \a this has not already been allocated, number of components is set to one.
5567  * This method allows to reduce number of reallocations on invokation of DataArrayInt::pushBackSilent and DataArrayInt::pushBackValsSilent on \a this.
5568  * 
5569  * \sa DataArrayInt::pack, DataArrayInt::pushBackSilent, DataArrayInt::pushBackValsSilent
5570  */
5571 void DataArrayInt::reserve(std::size_t nbOfElems) throw(INTERP_KERNEL::Exception)
5572 {
5573   int nbCompo=getNumberOfComponents();
5574   if(nbCompo==1)
5575     {
5576       _mem.reserve(nbOfElems);
5577     }
5578   else if(nbCompo==0)
5579     {
5580       _mem.reserve(nbOfElems);
5581       _info_on_compo.resize(1);
5582     }
5583   else
5584     throw INTERP_KERNEL::Exception("DataArrayInt::reserve : not available for DataArrayInt with number of components different than 1 !");
5585 }
5586
5587 /*!
5588  * 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
5589  * of counter. So the caller is expected to call TimeLabel::declareAsNew on \a this at the end of the push session.
5590  *
5591  * \param [in] val the value to be added in \a this
5592  * \throw If \a this has already been allocated with number of components different from one.
5593  * \sa DataArrayInt::pushBackValsSilent
5594  */
5595 void DataArrayInt::pushBackSilent(int val) throw(INTERP_KERNEL::Exception)
5596 {
5597   int nbCompo=getNumberOfComponents();
5598   if(nbCompo==1)
5599     _mem.pushBack(val);
5600   else if(nbCompo==0)
5601     {
5602       _info_on_compo.resize(1);
5603       _mem.pushBack(val);
5604     }
5605   else
5606     throw INTERP_KERNEL::Exception("DataArrayInt::pushBackSilent : not available for DataArrayInt with number of components different than 1 !");
5607 }
5608
5609 /*!
5610  * 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
5611  * of counter. So the caller is expected to call TimeLabel::declareAsNew on \a this at the end of the push session.
5612  *
5613  *  \param [in] valsBg - an array of values to push at the end of \this.
5614  *  \param [in] valsEnd - specifies the end of the array \a valsBg, so that
5615  *              the last value of \a valsBg is \a valsEnd[ -1 ].
5616  * \throw If \a this has already been allocated with number of components different from one.
5617  * \sa DataArrayInt::pushBackSilent
5618  */
5619 void DataArrayInt::pushBackValsSilent(const int *valsBg, const int *valsEnd) throw(INTERP_KERNEL::Exception)
5620 {
5621   int nbCompo=getNumberOfComponents();
5622   if(nbCompo==1)
5623     _mem.insertAtTheEnd(valsBg,valsEnd);
5624   else if(nbCompo==0)
5625     {
5626       _info_on_compo.resize(1);
5627       _mem.insertAtTheEnd(valsBg,valsEnd);
5628     }
5629   else
5630     throw INTERP_KERNEL::Exception("DataArrayInt::pushBackValsSilent : not available for DataArrayInt with number of components different than 1 !");
5631 }
5632
5633 /*!
5634  * This method returns silently ( without updating time label in \a this ) the last value, if any and suppress it.
5635  * \throw If \a this is already empty.
5636  * \throw If \a this has number of components different from one.
5637  */
5638 int DataArrayInt::popBackSilent() throw(INTERP_KERNEL::Exception)
5639 {
5640   if(getNumberOfComponents()==1)
5641     return _mem.popBack();
5642   else
5643     throw INTERP_KERNEL::Exception("DataArrayInt::popBackSilent : not available for DataArrayInt with number of components different than 1 !");
5644 }
5645
5646 /*!
5647  * 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.
5648  *
5649  * \sa DataArrayInt::getHeapMemorySize, DataArrayInt::reserve
5650  */
5651 void DataArrayInt::pack() const throw(INTERP_KERNEL::Exception)
5652 {
5653   _mem.pack();
5654 }
5655
5656 /*!
5657  * Allocates the raw data in memory. If exactly as same memory as needed already
5658  * allocated, it is not re-allocated.
5659  *  \param [in] nbOfTuple - number of tuples of data to allocate.
5660  *  \param [in] nbOfCompo - number of components of data to allocate.
5661  *  \throw If \a nbOfTuple < 0 or \a nbOfCompo < 0.
5662  */
5663 void DataArrayInt::allocIfNecessary(int nbOfTuple, int nbOfCompo) throw(INTERP_KERNEL::Exception)
5664 {
5665   if(isAllocated())
5666     {
5667       if(nbOfTuple!=getNumberOfTuples() || nbOfCompo!=getNumberOfComponents())
5668         alloc(nbOfTuple,nbOfCompo);
5669     }
5670   else
5671     alloc(nbOfTuple,nbOfCompo);
5672 }
5673
5674 /*!
5675  * Allocates the raw data in memory. If the memory was already allocated, then it is
5676  * freed and re-allocated. See an example of this method use
5677  * \ref MEDCouplingArraySteps1WC "here".
5678  *  \param [in] nbOfTuple - number of tuples of data to allocate.
5679  *  \param [in] nbOfCompo - number of components of data to allocate.
5680  *  \throw If \a nbOfTuple < 0 or \a nbOfCompo < 0.
5681  */
5682 void DataArrayInt::alloc(int nbOfTuple, int nbOfCompo) throw(INTERP_KERNEL::Exception)
5683 {
5684   if(nbOfTuple<0 || nbOfCompo<0)
5685     throw INTERP_KERNEL::Exception("DataArrayInt::alloc : request for negative length of data !");
5686   _info_on_compo.resize(nbOfCompo);
5687   _mem.alloc(nbOfCompo*(std::size_t)nbOfTuple);
5688   declareAsNew();
5689 }
5690
5691 /*!
5692  * Assign zero to all values in \a this array. To know more on filling arrays see
5693  * \ref MEDCouplingArrayFill.
5694  * \throw If \a this is not allocated.
5695  */
5696 void DataArrayInt::fillWithZero() throw(INTERP_KERNEL::Exception)
5697 {
5698   checkAllocated();
5699   _mem.fillWithValue(0);
5700   declareAsNew();
5701 }
5702
5703 /*!
5704  * Assign \a val to all values in \a this array. To know more on filling arrays see
5705  * \ref MEDCouplingArrayFill.
5706  *  \param [in] val - the value to fill with.
5707  *  \throw If \a this is not allocated.
5708  */
5709 void DataArrayInt::fillWithValue(int val) throw(INTERP_KERNEL::Exception)
5710 {
5711   checkAllocated();
5712   _mem.fillWithValue(val);
5713   declareAsNew();
5714 }
5715
5716 /*!
5717  * Set all values in \a this array so that the i-th element equals to \a init + i
5718  * (i starts from zero). To know more on filling arrays see \ref MEDCouplingArrayFill.
5719  *  \param [in] init - value to assign to the first element of array.
5720  *  \throw If \a this->getNumberOfComponents() != 1
5721  *  \throw If \a this is not allocated.
5722  */
5723 void DataArrayInt::iota(int init) throw(INTERP_KERNEL::Exception)
5724 {
5725   checkAllocated();
5726   if(getNumberOfComponents()!=1)
5727     throw INTERP_KERNEL::Exception("DataArrayInt::iota : works only for arrays with only one component, you can call 'rearrange' method before !");
5728   int *ptr=getPointer();
5729   int ntuples=getNumberOfTuples();
5730   for(int i=0;i<ntuples;i++)
5731     ptr[i]=init+i;
5732   declareAsNew();
5733 }
5734
5735 /*!
5736  * Returns a textual and human readable representation of \a this instance of
5737  * DataArrayInt. This text is shown when a DataArrayInt is printed in Python.
5738  *  \return std::string - text describing \a this DataArrayInt.
5739  */
5740 std::string DataArrayInt::repr() const throw(INTERP_KERNEL::Exception)
5741 {
5742   std::ostringstream ret;
5743   reprStream(ret);
5744   return ret.str();
5745 }
5746
5747 std::string DataArrayInt::reprZip() const throw(INTERP_KERNEL::Exception)
5748 {
5749   std::ostringstream ret;
5750   reprZipStream(ret);
5751   return ret.str();
5752 }
5753
5754 void DataArrayInt::writeVTK(std::ostream& ofs, int indent, const char *type, const char *nameInFile) const throw(INTERP_KERNEL::Exception)
5755 {
5756   checkAllocated();
5757   std::string idt(indent,' ');
5758   ofs << idt << "<DataArray type=\"" << type << "\" Name=\"" << nameInFile << "\" NumberOfComponents=\"" << getNumberOfComponents() << "\"";
5759   ofs << " format=\"ascii\" RangeMin=\"" << getMinValueInArray() << "\" RangeMax=\"" << getMaxValueInArray() << "\">\n" << idt;
5760   std::copy(begin(),end(),std::ostream_iterator<int>(ofs," "));
5761   ofs << std::endl << idt << "</DataArray>\n";
5762 }
5763
5764 void DataArrayInt::reprStream(std::ostream& stream) const throw(INTERP_KERNEL::Exception)
5765 {
5766   stream << "Name of int array : \"" << _name << "\"\n";
5767   reprWithoutNameStream(stream);
5768 }
5769
5770 void DataArrayInt::reprZipStream(std::ostream& stream) const throw(INTERP_KERNEL::Exception)
5771 {
5772   stream << "Name of int array : \"" << _name << "\"\n";
5773   reprZipWithoutNameStream(stream);
5774 }
5775
5776 void DataArrayInt::reprWithoutNameStream(std::ostream& stream) const throw(INTERP_KERNEL::Exception)
5777 {
5778   DataArray::reprWithoutNameStream(stream);
5779   _mem.repr(getNumberOfComponents(),stream);
5780 }
5781
5782 void DataArrayInt::reprZipWithoutNameStream(std::ostream& stream) const throw(INTERP_KERNEL::Exception)
5783 {
5784   DataArray::reprWithoutNameStream(stream);
5785   _mem.reprZip(getNumberOfComponents(),stream);
5786 }
5787
5788 void DataArrayInt::reprCppStream(const char *varName, std::ostream& stream) const throw(INTERP_KERNEL::Exception)
5789 {
5790   int nbTuples=getNumberOfTuples(),nbComp=getNumberOfComponents();
5791   const int *data=getConstPointer();
5792   stream << "DataArrayInt *" << varName << "=DataArrayInt::New();" << std::endl;
5793   if(nbTuples*nbComp>=1)
5794     {
5795       stream << "const int " << varName << "Data[" << nbTuples*nbComp << "]={";
5796       std::copy(data,data+nbTuples*nbComp-1,std::ostream_iterator<int>(stream,","));
5797       stream << data[nbTuples*nbComp-1] << "};" << std::endl;
5798       stream << varName << "->useArray(" << varName << "Data,false,CPP_DEALLOC," << nbTuples << "," << nbComp << ");" << std::endl;
5799     }
5800   else
5801     stream << varName << "->alloc(" << nbTuples << "," << nbComp << ");" << std::endl;
5802   stream << varName << "->setName(\"" << getName() << "\");" << std::endl;
5803 }
5804
5805 /*!
5806  * Method that gives a quick overvien of \a this for python.
5807  */
5808 void DataArrayInt::reprQuickOverview(std::ostream& stream) const throw(INTERP_KERNEL::Exception)
5809 {
5810   static const std::size_t MAX_NB_OF_BYTE_IN_REPR=300;
5811   stream << "DataArrayInt C++ instance at " << this << ". ";
5812   if(isAllocated())
5813     {
5814       int nbOfCompo=(int)_info_on_compo.size();
5815       if(nbOfCompo>=1)
5816         {
5817           int nbOfTuples=getNumberOfTuples();
5818           stream << "Number of tuples : " << nbOfTuples << ". Number of components : " << nbOfCompo << "." << std::endl;
5819           reprQuickOverviewData(stream,MAX_NB_OF_BYTE_IN_REPR);
5820         }
5821       else
5822         stream << "Number of components : 0.";
5823     }
5824   else
5825     stream << "*** No data allocated ****";
5826 }
5827
5828 void DataArrayInt::reprQuickOverviewData(std::ostream& stream, std::size_t maxNbOfByteInRepr) const throw(INTERP_KERNEL::Exception)
5829 {
5830   const int *data=begin();
5831   int nbOfTuples=getNumberOfTuples();
5832   int nbOfCompo=(int)_info_on_compo.size();
5833   std::ostringstream oss2; oss2 << "[";
5834   std::string oss2Str(oss2.str());
5835   bool isFinished=true;
5836   for(int i=0;i<nbOfTuples && isFinished;i++)
5837     {
5838       if(nbOfCompo>1)
5839         {
5840           oss2 << "(";
5841           for(int j=0;j<nbOfCompo;j++,data++)
5842             {
5843               oss2 << *data;
5844               if(j!=nbOfCompo-1) oss2 << ", ";
5845             }
5846           oss2 << ")";
5847         }
5848       else
5849         oss2 << *data++;
5850       if(i!=nbOfTuples-1) oss2 << ", ";
5851       std::string oss3Str(oss2.str());
5852       if(oss3Str.length()<maxNbOfByteInRepr)
5853         oss2Str=oss3Str;
5854       else
5855         isFinished=false;
5856     }
5857   stream << oss2Str;
5858   if(!isFinished)
5859     stream << "... ";
5860   stream << "]";
5861 }
5862
5863 /*!
5864  * Modifies \a this one-dimensional array so that each value \a v = \a indArrBg[ \a v ],
5865  * i.e. a current value is used as in index to get a new value from \a indArrBg.
5866  *  \param [in] indArrBg - pointer to the first element of array of new values to assign
5867  *         to \a this array.
5868  *  \param [in] indArrEnd - specifies the end of the array \a indArrBg, so that
5869  *              the last value of \a indArrBg is \a indArrEnd[ -1 ].
5870  *  \throw If \a this->getNumberOfComponents() != 1
5871  *  \throw If any value of \a this can't be used as a valid index for 
5872  *         [\a indArrBg, \a indArrEnd).
5873  */
5874 void DataArrayInt::transformWithIndArr(const int *indArrBg, const int *indArrEnd) throw(INTERP_KERNEL::Exception)
5875 {
5876   checkAllocated();
5877   if(getNumberOfComponents()!=1)
5878     throw INTERP_KERNEL::Exception("Call transformWithIndArr method on DataArrayInt with only one component, you can call 'rearrange' method before !");
5879   int nbElemsIn=(int)std::distance(indArrBg,indArrEnd);
5880   int nbOfTuples=getNumberOfTuples();
5881   int *pt=getPointer();
5882   for(int i=0;i<nbOfTuples;i++,pt++)
5883     {
5884       if(*pt>=0 && *pt<nbElemsIn)
5885         *pt=indArrBg[*pt];
5886       else
5887         {
5888           std::ostringstream oss; oss << "DataArrayInt::transformWithIndArr : error on tuple #" << i << " of this value is " << *pt << ", should be in [0," << nbElemsIn << ") !";
5889           throw INTERP_KERNEL::Exception(oss.str().c_str());
5890         }
5891     }
5892   declareAsNew();
5893 }
5894
5895 /*!
5896  * Computes distribution of values of \a this one-dimensional array between given value
5897  * ranges (casts). This method is typically useful for entity number spliting by types,
5898  * for example. 
5899  *  \warning The values contained in \a arrBg should be sorted ascendently. No
5900  *           check of this is be done. If not, the result is not warranted. 
5901  *  \param [in] arrBg - the array of ascending values defining the value ranges. The i-th
5902  *         value of \a arrBg (\a arrBg[ i ]) gives the lowest value of the i-th range,
5903  *         and the greatest value of the i-th range equals to \a arrBg[ i+1 ] - 1. \a
5904  *         arrBg containing \a n values defines \a n-1 ranges. The last value of \a arrBg
5905  *         should be more than every value in \a this array.
5906  *  \param [in] arrEnd - specifies the end of the array \a arrBg, so that
5907  *              the last value of \a arrBg is \a arrEnd[ -1 ].
5908  *  \param [out] castArr - a new instance of DataArrayInt, of same size as \a this array
5909  *         (same number of tuples and components), the caller is to delete 
5910  *         using decrRef() as it is no more needed.
5911  *         This array contains indices of ranges for every value of \a this array. I.e.
5912  *         the i-th value of \a castArr gives the index of range the i-th value of \a this
5913  *         belongs to. Or, in other words, this parameter contains for each tuple in \a
5914  *         this in which cast it holds.
5915  *  \param [out] rankInsideCast - a new instance of DataArrayInt, of same size as \a this
5916  *         array, the caller is to delete using decrRef() as it is no more needed.
5917  *         This array contains ranks of values of \a this array within ranges
5918  *         they belongs to. I.e. the i-th value of \a rankInsideCast gives the rank of
5919  *         the i-th value of \a this array within the \a castArr[ i ]-th range, to which
5920  *         the i-th value of \a this belongs to. Or, in other words, this param contains 
5921  *         for each tuple its rank inside its cast. The rank is computed as difference
5922  *         between the value and the lowest value of range.
5923  *  \param [out] castsPresent - a new instance of DataArrayInt, containing indices of
5924  *         ranges (casts) to which at least one value of \a this array belongs.
5925  *         Or, in other words, this param contains the casts that \a this contains.
5926  *         The caller is to delete this array using decrRef() as it is no more needed.
5927  *
5928  * \b Example: If \a this contains [6,5,0,3,2,7,8,1,4] and \a arrBg contains [0,4,9] then
5929  *            the output of this method will be : 
5930  * - \a castArr       : [1,1,0,0,0,1,1,0,1]
5931  * - \a rankInsideCast: [2,1,0,3,2,3,4,1,0]
5932  * - \a castsPresent  : [0,1]
5933  *
5934  * I.e. values of \a this array belong to 2 ranges: #0 and #1. Value 6 belongs to the
5935  * range #1 and its rank within this range is 2; etc.
5936  *
5937  *  \throw If \a this->getNumberOfComponents() != 1.
5938  *  \throw If \a arrEnd - arrBg < 2.
5939  *  \throw If any value of \a this is not less than \a arrEnd[-1].
5940  */
5941 void DataArrayInt::splitByValueRange(const int *arrBg, const int *arrEnd,
5942                                      DataArrayInt *& castArr, DataArrayInt *& rankInsideCast, DataArrayInt *& castsPresent) const throw(INTERP_KERNEL::Exception)
5943 {
5944   checkAllocated();
5945   if(getNumberOfComponents()!=1)
5946     throw INTERP_KERNEL::Exception("Call splitByValueRange  method on DataArrayInt with only one component, you can call 'rearrange' method before !");
5947   int nbOfTuples=getNumberOfTuples();
5948   std::size_t nbOfCast=std::distance(arrBg,arrEnd);
5949   if(nbOfCast<2)
5950     throw INTERP_KERNEL::Exception("DataArrayInt::splitByValueRange : The input array giving the cast range values should be of size >=2 !");
5951   nbOfCast--;
5952   const int *work=getConstPointer();
5953   typedef std::reverse_iterator<const int *> rintstart;
5954   rintstart bg(arrEnd);//OK no problem because size of 'arr' is greater or equal 2
5955   rintstart end2(arrBg);
5956   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret1=DataArrayInt::New();
5957   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret2=DataArrayInt::New();
5958   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret3=DataArrayInt::New();
5959   ret1->alloc(nbOfTuples,1);
5960   ret2->alloc(nbOfTuples,1);
5961   int *ret1Ptr=ret1->getPointer();
5962   int *ret2Ptr=ret2->getPointer();
5963   std::set<std::size_t> castsDetected;
5964   for(int i=0;i<nbOfTuples;i++)
5965     {
5966       rintstart res=std::find_if(bg,end2,std::bind2nd(std::less_equal<int>(), work[i]));
5967       std::size_t pos=std::distance(bg,res);
5968       std::size_t pos2=nbOfCast-pos;
5969       if(pos2<nbOfCast)
5970         {
5971           ret1Ptr[i]=(int)pos2;
5972           ret2Ptr[i]=work[i]-arrBg[pos2];
5973           castsDetected.insert(pos2);
5974         }
5975       else
5976         {
5977           std::ostringstream oss; oss << "DataArrayInt::splitByValueRange : At rank #" << i << " the value is " << work[i] << " should be in [0," << *bg << ") !";
5978           throw INTERP_KERNEL::Exception(oss.str().c_str());
5979         }
5980     }
5981   ret3->alloc((int)castsDetected.size(),1);
5982   std::copy(castsDetected.begin(),castsDetected.end(),ret3->getPointer());
5983   castArr=ret1.retn();
5984   rankInsideCast=ret2.retn();
5985   castsPresent=ret3.retn();
5986 }
5987
5988 /*!
5989  * Creates a one-dimensional DataArrayInt (\a res) whose contents are computed from 
5990  * values of \a this (\a a) and the given (\a indArr) arrays as follows:
5991  * \a res[ \a indArr[ \a a[ i ]]] = i. I.e. for each value in place i \a v = \a a[ i ],
5992  * new value in place \a indArr[ \a v ] is i.
5993  *  \param [in] indArrBg - the array holding indices within the result array to assign
5994  *         indices of values of \a this array pointing to values of \a indArrBg.
5995  *  \param [in] indArrEnd - specifies the end of the array \a indArrBg, so that
5996  *              the last value of \a indArrBg is \a indArrEnd[ -1 ].
5997  *  \return DataArrayInt * - the new instance of DataArrayInt.
5998  *          The caller is to delete this result array using decrRef() as it is no more
5999  *          needed.
6000  *  \throw If \a this->getNumberOfComponents() != 1.
6001  *  \throw If any value of \a this array is not a valid index for \a indArrBg array.
6002  *  \throw If any value of \a indArrBg is not a valid index for \a this array.
6003  */
6004 DataArrayInt *DataArrayInt::transformWithIndArrR(const int *indArrBg, const int *indArrEnd) const throw(INTERP_KERNEL::Exception)
6005 {
6006   checkAllocated();
6007   if(getNumberOfComponents()!=1)
6008     throw INTERP_KERNEL::Exception("Call transformWithIndArrR method on DataArrayInt with only one component, you can call 'rearrange' method before !");
6009   int nbElemsIn=(int)std::distance(indArrBg,indArrEnd);
6010   int nbOfTuples=getNumberOfTuples();
6011   const int *pt=getConstPointer();
6012   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6013   ret->alloc(nbOfTuples,1);
6014   ret->fillWithValue(-1);
6015   int *tmp=ret->getPointer();
6016   for(int i=0;i<nbOfTuples;i++,pt++)
6017     {
6018       if(*pt>=0 && *pt<nbElemsIn)
6019         {
6020           int pos=indArrBg[*pt];
6021           if(pos>=0 && pos<nbOfTuples)
6022             tmp[pos]=i;
6023           else
6024             {
6025               std::ostringstream oss; oss << "DataArrayInt::transformWithIndArrR : error on tuple #" << i << " value of new pos is " << pos << " ( indArrBg[" << *pt << "]) ! Should be in [0," << nbOfTuples << ") !";
6026               throw INTERP_KERNEL::Exception(oss.str().c_str());
6027             }
6028         }
6029       else
6030         {
6031           std::ostringstream oss; oss << "DataArrayInt::transformWithIndArrR : error on tuple #" << i << " value is " << *pt << " and indirectionnal array as a size equal to " << nbElemsIn << " !";
6032           throw INTERP_KERNEL::Exception(oss.str().c_str());
6033         }
6034     }
6035   return ret.retn();
6036 }
6037
6038 /*!
6039  * Creates a one-dimensional DataArrayInt of given length, whose contents are computed
6040  * from values of \a this array, which is supposed to contain a renumbering map in 
6041  * "Old to New" mode. The result array contains a renumbering map in "New to Old" mode.
6042  * To know how to use the renumbering maps see \ref MEDCouplingArrayRenumbering.
6043  *  \param [in] newNbOfElem - the number of tuples in the result array.
6044  *  \return DataArrayInt * - the new instance of DataArrayInt.
6045  *          The caller is to delete this result array using decrRef() as it is no more
6046  *          needed.
6047  * 
6048  *  \ref cpp_mcdataarrayint_invertarrayo2n2n2o "Here is a C++ example".<br>
6049  *  \ref py_mcdataarrayint_invertarrayo2n2n2o  "Here is a Python example".
6050  */
6051 DataArrayInt *DataArrayInt::invertArrayO2N2N2O(int newNbOfElem) const
6052 {
6053   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6054   ret->alloc(newNbOfElem,1);
6055   int nbOfOldNodes=getNumberOfTuples();
6056   const int *old2New=getConstPointer();
6057   int *pt=ret->getPointer();
6058   for(int i=0;i!=nbOfOldNodes;i++)
6059     if(old2New[i]!=-1)
6060       pt[old2New[i]]=i;
6061   return ret.retn();
6062 }
6063
6064 /*!
6065  * This method is similar to DataArrayInt::invertArrayO2N2N2O except that 
6066  * 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]
6067  */
6068 DataArrayInt *DataArrayInt::invertArrayO2N2N2OBis(int newNbOfElem) const throw(INTERP_KERNEL::Exception)
6069 {
6070   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6071   ret->alloc(newNbOfElem,1);
6072   int nbOfOldNodes=getNumberOfTuples();
6073   const int *old2New=getConstPointer();
6074   int *pt=ret->getPointer();
6075   for(int i=nbOfOldNodes-1;i>=0;i--)
6076     if(old2New[i]!=-1)
6077       pt[old2New[i]]=i;
6078   return ret.retn();
6079 }
6080
6081 /*!
6082  * Creates a one-dimensional DataArrayInt of given length, whose contents are computed
6083  * from values of \a this array, which is supposed to contain a renumbering map in 
6084  * "New to Old" mode. The result array contains a renumbering map in "Old to New" mode.
6085  * To know how to use the renumbering maps see \ref MEDCouplingArrayRenumbering.
6086  *  \param [in] newNbOfElem - the number of tuples in the result array.
6087  *  \return DataArrayInt * - the new instance of DataArrayInt.
6088  *          The caller is to delete this result array using decrRef() as it is no more
6089  *          needed.
6090  * 
6091  *  \ref cpp_mcdataarrayint_invertarrayn2o2o2n "Here is a C++ example".
6092  *
6093  *  \ref py_mcdataarrayint_invertarrayn2o2o2n "Here is a Python example".
6094  */
6095 DataArrayInt *DataArrayInt::invertArrayN2O2O2N(int oldNbOfElem) const
6096 {
6097   checkAllocated();
6098   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6099   ret->alloc(oldNbOfElem,1);
6100   const int *new2Old=getConstPointer();
6101   int *pt=ret->getPointer();
6102   std::fill(pt,pt+oldNbOfElem,-1);
6103   int nbOfNewElems=getNumberOfTuples();
6104   for(int i=0;i<nbOfNewElems;i++)
6105     pt[new2Old[i]]=i;
6106   return ret.retn();
6107 }
6108
6109 /*!
6110  * Equivalent to DataArrayInt::isEqual except that if false the reason of
6111  * mismatch is given.
6112  * 
6113  * \param [in] other the instance to be compared with \a this
6114  * \param [out] reason In case of inequality returns the reason.
6115  * \sa DataArrayInt::isEqual
6116  */
6117 bool DataArrayInt::isEqualIfNotWhy(const DataArrayInt& other, std::string& reason) const throw(INTERP_KERNEL::Exception)
6118 {
6119   if(!areInfoEqualsIfNotWhy(other,reason))
6120     return false;
6121   return _mem.isEqual(other._mem,0,reason);
6122 }
6123
6124 /*!
6125  * Checks if \a this and another DataArrayInt are fully equal. For more info see
6126  * \ref MEDCouplingArrayBasicsCompare.
6127  *  \param [in] other - an instance of DataArrayInt to compare with \a this one.
6128  *  \return bool - \a true if the two arrays are equal, \a false else.
6129  */
6130 bool DataArrayInt::isEqual(const DataArrayInt& other) const throw(INTERP_KERNEL::Exception)
6131 {
6132   std::string tmp;
6133   return isEqualIfNotWhy(other,tmp);
6134 }
6135
6136 /*!
6137  * Checks if values of \a this and another DataArrayInt are equal. For more info see
6138  * \ref MEDCouplingArrayBasicsCompare.
6139  *  \param [in] other - an instance of DataArrayInt to compare with \a this one.
6140  *  \return bool - \a true if the values of two arrays are equal, \a false else.
6141  */
6142 bool DataArrayInt::isEqualWithoutConsideringStr(const DataArrayInt& other) const throw(INTERP_KERNEL::Exception)
6143 {
6144   std::string tmp;
6145   return _mem.isEqual(other._mem,0,tmp);
6146 }
6147
6148 /*!
6149  * Checks if values of \a this and another DataArrayInt are equal. Comparison is
6150  * performed on sorted value sequences.
6151  * For more info see\ref MEDCouplingArrayBasicsCompare.
6152  *  \param [in] other - an instance of DataArrayInt to compare with \a this one.
6153  *  \return bool - \a true if the sorted values of two arrays are equal, \a false else.
6154  */
6155 bool DataArrayInt::isEqualWithoutConsideringStrAndOrder(const DataArrayInt& other) const throw(INTERP_KERNEL::Exception)
6156 {
6157   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> a=deepCpy();
6158   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> b=other.deepCpy();
6159   a->sort();
6160   b->sort();
6161   return a->isEqualWithoutConsideringStr(*b);
6162 }
6163
6164 /*!
6165  * This method compares content of input vector \a v and \a this.
6166  * If for each id in \a this v[id]==True and for all other ids id2 not in \a this v[id2]==False, true is returned.
6167  * For performance reasons \a this is expected to be sorted ascendingly. If not an exception will be thrown.
6168  *
6169  * \param [in] v - the vector of 'flags' to be compared with \a this.
6170  *
6171  * \throw If \a this is not sorted ascendingly.
6172  * \throw If \a this has not exactly one component.
6173  * \throw If \a this is not allocated.
6174  */
6175 bool DataArrayInt::isFittingWith(const std::vector<bool>& v) const throw(INTERP_KERNEL::Exception)
6176 {
6177   checkAllocated();
6178   if(getNumberOfComponents()!=1)
6179     throw INTERP_KERNEL::Exception("DataArrayInt::isFittingWith : number of components of this should be equal to one !");
6180   int nbOfTuples(getNumberOfTuples());
6181   const int *w(begin()),*end2(end());
6182   int refVal=-std::numeric_limits<int>::max();
6183   int i=0;
6184   std::vector<bool>::const_iterator it(v.begin());
6185   for(;it!=v.end();it++,i++)
6186     {
6187       if(*it)
6188         {
6189           if(w!=end2)
6190             {
6191               if(*w++==i)
6192                 {
6193                   if(i>refVal)
6194                     refVal=i;
6195                   else
6196                     {
6197                       std::ostringstream oss; oss << "DataArrayInt::isFittingWith : At pos #" << std::distance(begin(),w-1) << " this is not sorted ascendingly !";
6198                       throw INTERP_KERNEL::Exception(oss.str().c_str());
6199                     }
6200                 }
6201               return false;
6202             }
6203           else
6204             return false;
6205         }
6206     }
6207   return w==end2;
6208 }
6209
6210 /*!
6211  * Sorts values of the array.
6212  *  \param [in] asc - \a true means ascending order, \a false, descending.
6213  *  \throw If \a this is not allocated.
6214  *  \throw If \a this->getNumberOfComponents() != 1.
6215  */
6216 void DataArrayInt::sort(bool asc) throw(INTERP_KERNEL::Exception)
6217 {
6218   checkAllocated();
6219   if(getNumberOfComponents()!=1)
6220     throw INTERP_KERNEL::Exception("DataArrayInt::sort : only supported with 'this' array with ONE component !");
6221   _mem.sort(asc);
6222   declareAsNew();
6223 }
6224
6225 /*!
6226  * Reverse the array values.
6227  *  \throw If \a this->getNumberOfComponents() < 1.
6228  *  \throw If \a this is not allocated.
6229  */
6230 void DataArrayInt::reverse() throw(INTERP_KERNEL::Exception)
6231 {
6232   checkAllocated();
6233   _mem.reverse(getNumberOfComponents());
6234   declareAsNew();
6235 }
6236
6237 /*!
6238  * Checks that \a this array is consistently **increasing** or **decreasing** in value.
6239  * If not an exception is thrown.
6240  *  \param [in] increasing - if \a true, the array values should be increasing.
6241  *  \throw If sequence of values is not strictly monotonic in agreement with \a
6242  *         increasing arg.
6243  *  \throw If \a this->getNumberOfComponents() != 1.
6244  *  \throw If \a this is not allocated.
6245  */
6246 void DataArrayInt::checkMonotonic(bool increasing) const throw(INTERP_KERNEL::Exception)
6247 {
6248   if(!isMonotonic(increasing))
6249     {
6250       if (increasing)
6251         throw INTERP_KERNEL::Exception("DataArrayInt::checkMonotonic : 'this' is not INCREASING monotonic !");
6252       else
6253         throw INTERP_KERNEL::Exception("DataArrayInt::checkMonotonic : 'this' is not DECREASING monotonic !");
6254     }
6255 }
6256
6257 /*!
6258  * Checks that \a this array is consistently **increasing** or **decreasing** in value.
6259  *  \param [in] increasing - if \a true, array values should be increasing.
6260  *  \return bool - \a true if values change in accordance with \a increasing arg.
6261  *  \throw If \a this->getNumberOfComponents() != 1.
6262  *  \throw If \a this is not allocated.
6263  */
6264 bool DataArrayInt::isMonotonic(bool increasing) const throw(INTERP_KERNEL::Exception)
6265 {
6266   checkAllocated();
6267   if(getNumberOfComponents()!=1)
6268     throw INTERP_KERNEL::Exception("DataArrayInt::isMonotonic : only supported with 'this' array with ONE component !");
6269   int nbOfElements=getNumberOfTuples();
6270   const int *ptr=getConstPointer();
6271   if(nbOfElements==0)
6272     return true;
6273   int ref=ptr[0];
6274   if(increasing)
6275     {
6276       for(int i=1;i<nbOfElements;i++)
6277         {
6278           if(ptr[i]>=ref)
6279             ref=ptr[i];
6280           else
6281             return false;
6282         }
6283     }
6284   else
6285     {
6286       for(int i=1;i<nbOfElements;i++)
6287         {
6288           if(ptr[i]<=ref)
6289             ref=ptr[i];
6290           else
6291             return false;
6292         }
6293     }
6294   return true;
6295 }
6296
6297 /*!
6298  * This method check that array consistently INCREASING or DECREASING in value.
6299  */
6300 bool DataArrayInt::isStrictlyMonotonic(bool increasing) const throw(INTERP_KERNEL::Exception)
6301 {
6302   checkAllocated();
6303   if(getNumberOfComponents()!=1)
6304     throw INTERP_KERNEL::Exception("DataArrayInt::isStrictlyMonotonic : only supported with 'this' array with ONE component !");
6305   int nbOfElements=getNumberOfTuples();
6306   const int *ptr=getConstPointer();
6307   if(nbOfElements==0)
6308     return true;
6309   int ref=ptr[0];
6310   if(increasing)
6311     {
6312       for(int i=1;i<nbOfElements;i++)
6313         {
6314           if(ptr[i]>ref)
6315             ref=ptr[i];
6316           else
6317             return false;
6318         }
6319     }
6320   else
6321     {
6322       for(int i=1;i<nbOfElements;i++)
6323         {
6324           if(ptr[i]<ref)
6325             ref=ptr[i];
6326           else
6327             return false;
6328         }
6329     }
6330   return true;
6331 }
6332
6333 /*!
6334  * This method check that array consistently INCREASING or DECREASING in value.
6335  */
6336 void DataArrayInt::checkStrictlyMonotonic(bool increasing) const throw(INTERP_KERNEL::Exception)
6337 {
6338   if(!isStrictlyMonotonic(increasing))
6339     {
6340       if (increasing)
6341         throw INTERP_KERNEL::Exception("DataArrayInt::checkStrictlyMonotonic : 'this' is not strictly INCREASING monotonic !");
6342       else
6343         throw INTERP_KERNEL::Exception("DataArrayInt::checkStrictlyMonotonic : 'this' is not strictly DECREASING monotonic !");
6344     }
6345 }
6346
6347 /*!
6348  * Creates a new one-dimensional DataArrayInt of the same size as \a this and a given
6349  * one-dimensional arrays that must be of the same length. The result array describes
6350  * correspondence between \a this and \a other arrays, so that 
6351  * <em> other.getIJ(i,0) == this->getIJ(ret->getIJ(i),0)</em>. If such a permutation is
6352  * not possible because some element in \a other is not in \a this, an exception is thrown.
6353  *  \param [in] other - an array to compute permutation to.
6354  *  \return DataArrayInt * - a new instance of DataArrayInt, which is a permutation array
6355  * from \a this to \a other. The caller is to delete this array using decrRef() as it is
6356  * no more needed.
6357  *  \throw If \a this->getNumberOfComponents() != 1.
6358  *  \throw If \a other->getNumberOfComponents() != 1.
6359  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples().
6360  *  \throw If \a other includes a value which is not in \a this array.
6361  * 
6362  *  \ref cpp_mcdataarrayint_buildpermutationarr "Here is a C++ example".
6363  *
6364  *  \ref py_mcdataarrayint_buildpermutationarr "Here is a Python example".
6365  */
6366 DataArrayInt *DataArrayInt::buildPermutationArr(const DataArrayInt& other) const throw(INTERP_KERNEL::Exception)
6367 {
6368   checkAllocated();
6369   if(getNumberOfComponents()!=1 || other.getNumberOfComponents()!=1)
6370     throw INTERP_KERNEL::Exception("DataArrayInt::buildPermutationArr : 'this' and 'other' have to have exactly ONE component !");
6371   int nbTuple=getNumberOfTuples();
6372   other.checkAllocated();
6373   if(nbTuple!=other.getNumberOfTuples())
6374     throw INTERP_KERNEL::Exception("DataArrayInt::buildPermutationArr : 'this' and 'other' must have the same number of tuple !");
6375   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6376   ret->alloc(nbTuple,1);
6377   ret->fillWithValue(-1);
6378   const int *pt=getConstPointer();
6379   std::map<int,int> mm;
6380   for(int i=0;i<nbTuple;i++)
6381     mm[pt[i]]=i;
6382   pt=other.getConstPointer();
6383   int *retToFill=ret->getPointer();
6384   for(int i=0;i<nbTuple;i++)
6385     {
6386       std::map<int,int>::const_iterator it=mm.find(pt[i]);
6387       if(it==mm.end())
6388         {
6389           std::ostringstream oss; oss << "DataArrayInt::buildPermutationArr : Arrays mismatch : element (" << pt[i] << ") in 'other' not findable in 'this' !";
6390           throw INTERP_KERNEL::Exception(oss.str().c_str());
6391         }
6392       retToFill[i]=(*it).second;
6393     }
6394   return ret.retn();
6395 }
6396
6397 /*!
6398  * Sets a C array to be used as raw data of \a this. The previously set info
6399  *  of components is retained and re-sized. 
6400  * For more info see \ref MEDCouplingArraySteps1.
6401  *  \param [in] array - the C array to be used as raw data of \a this.
6402  *  \param [in] ownership - if \a true, \a array will be deallocated at destruction of \a this.
6403  *  \param [in] type - specifies how to deallocate \a array. If \a type == ParaMEDMEM::CPP_DEALLOC,
6404  *                     \c delete [] \c array; will be called. If \a type == ParaMEDMEM::C_DEALLOC,
6405  *                     \c free(\c array ) will be called.
6406  *  \param [in] nbOfTuple - new number of tuples in \a this.
6407  *  \param [in] nbOfCompo - new number of components in \a this.
6408  */
6409 void DataArrayInt::useArray(const int *array, bool ownership,  DeallocType type, int nbOfTuple, int nbOfCompo) throw(INTERP_KERNEL::Exception)
6410 {
6411   _info_on_compo.resize(nbOfCompo);
6412   _mem.useArray(array,ownership,type,nbOfTuple*nbOfCompo);
6413   declareAsNew();
6414 }
6415
6416 void DataArrayInt::useExternalArrayWithRWAccess(const int *array, int nbOfTuple, int nbOfCompo) throw(INTERP_KERNEL::Exception)
6417 {
6418   _info_on_compo.resize(nbOfCompo);
6419   _mem.useExternalArrayWithRWAccess(array,nbOfTuple*nbOfCompo);
6420   declareAsNew();
6421 }
6422
6423 /*!
6424  * Returns a new DataArrayInt holding the same values as \a this array but differently
6425  * arranged in memory. If \a this array holds 2 components of 3 values:
6426  * \f$ x_0,x_1,x_2,y_0,y_1,y_2 \f$, then the result array holds these values arranged
6427  * as follows: \f$ x_0,y_0,x_1,y_1,x_2,y_2 \f$.
6428  *  \warning Do not confuse this method with transpose()!
6429  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
6430  *          is to delete using decrRef() as it is no more needed.
6431  *  \throw If \a this is not allocated.
6432  */
6433 DataArrayInt *DataArrayInt::fromNoInterlace() const throw(INTERP_KERNEL::Exception)
6434 {
6435   checkAllocated();
6436   if(_mem.isNull())
6437     throw INTERP_KERNEL::Exception("DataArrayInt::fromNoInterlace : Not defined array !");
6438   int *tab=_mem.fromNoInterlace(getNumberOfComponents());
6439   DataArrayInt *ret=DataArrayInt::New();
6440   ret->useArray(tab,true,C_DEALLOC,getNumberOfTuples(),getNumberOfComponents());
6441   return ret;
6442 }
6443
6444 /*!
6445  * Returns a new DataArrayInt holding the same values as \a this array but differently
6446  * arranged in memory. If \a this array holds 2 components of 3 values:
6447  * \f$ x_0,y_0,x_1,y_1,x_2,y_2 \f$, then the result array holds these values arranged
6448  * as follows: \f$ x_0,x_1,x_2,y_0,y_1,y_2 \f$.
6449  *  \warning Do not confuse this method with transpose()!
6450  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
6451  *          is to delete using decrRef() as it is no more needed.
6452  *  \throw If \a this is not allocated.
6453  */
6454 DataArrayInt *DataArrayInt::toNoInterlace() const throw(INTERP_KERNEL::Exception)
6455 {
6456   checkAllocated();
6457   if(_mem.isNull())
6458     throw INTERP_KERNEL::Exception("DataArrayInt::toNoInterlace : Not defined array !");
6459   int *tab=_mem.toNoInterlace(getNumberOfComponents());
6460   DataArrayInt *ret=DataArrayInt::New();
6461   ret->useArray(tab,true,C_DEALLOC,getNumberOfTuples(),getNumberOfComponents());
6462   return ret;
6463 }
6464
6465 /*!
6466  * Permutes values of \a this array as required by \a old2New array. The values are
6467  * permuted so that \c new[ \a old2New[ i ]] = \c old[ i ]. Number of tuples remains
6468  * the same as in \this one.
6469  * If a permutation reduction is needed, substr() or selectByTupleId() should be used.
6470  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
6471  *  \param [in] old2New - C array of length equal to \a this->getNumberOfTuples()
6472  *     giving a new position for i-th old value.
6473  */
6474 void DataArrayInt::renumberInPlace(const int *old2New) throw(INTERP_KERNEL::Exception)
6475 {
6476   checkAllocated();
6477   int nbTuples=getNumberOfTuples();
6478   int nbOfCompo=getNumberOfComponents();
6479   int *tmp=new int[nbTuples*nbOfCompo];
6480   const int *iptr=getConstPointer();
6481   for(int i=0;i<nbTuples;i++)
6482     {
6483       int v=old2New[i];
6484       if(v>=0 && v<nbTuples)
6485         std::copy(iptr+nbOfCompo*i,iptr+nbOfCompo*(i+1),tmp+nbOfCompo*v);
6486       else
6487         {
6488           std::ostringstream oss; oss << "DataArrayInt::renumberInPlace : At place #" << i << " value is " << v << " ! Should be in [0," << nbTuples << ") !";
6489           throw INTERP_KERNEL::Exception(oss.str().c_str());
6490         }
6491     }
6492   std::copy(tmp,tmp+nbTuples*nbOfCompo,getPointer());
6493   delete [] tmp;
6494   declareAsNew();
6495 }
6496
6497 /*!
6498  * Permutes values of \a this array as required by \a new2Old array. The values are
6499  * permuted so that \c new[ i ] = \c old[ \a new2Old[ i ]]. Number of tuples remains
6500  * the same as in \this one.
6501  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
6502  *  \param [in] new2Old - C array of length equal to \a this->getNumberOfTuples()
6503  *     giving a previous position of i-th new value.
6504  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
6505  *          is to delete using decrRef() as it is no more needed.
6506  */
6507 void DataArrayInt::renumberInPlaceR(const int *new2Old) throw(INTERP_KERNEL::Exception)
6508 {
6509   checkAllocated();
6510   int nbTuples=getNumberOfTuples();
6511   int nbOfCompo=getNumberOfComponents();
6512   int *tmp=new int[nbTuples*nbOfCompo];
6513   const int *iptr=getConstPointer();
6514   for(int i=0;i<nbTuples;i++)
6515     {
6516       int v=new2Old[i];
6517       if(v>=0 && v<nbTuples)
6518         std::copy(iptr+nbOfCompo*v,iptr+nbOfCompo*(v+1),tmp+nbOfCompo*i);
6519       else
6520         {
6521           std::ostringstream oss; oss << "DataArrayInt::renumberInPlaceR : At place #" << i << " value is " << v << " ! Should be in [0," << nbTuples << ") !";
6522           throw INTERP_KERNEL::Exception(oss.str().c_str());
6523         }
6524     }
6525   std::copy(tmp,tmp+nbTuples*nbOfCompo,getPointer());
6526   delete [] tmp;
6527   declareAsNew();
6528 }
6529
6530 /*!
6531  * Returns a copy of \a this array with values permuted as required by \a old2New array.
6532  * The values are permuted so that  \c new[ \a old2New[ i ]] = \c old[ i ].
6533  * Number of tuples in the result array remains the same as in \this one.
6534  * If a permutation reduction is needed, renumberAndReduce() should be used.
6535  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
6536  *  \param [in] old2New - C array of length equal to \a this->getNumberOfTuples()
6537  *          giving a new position for i-th old value.
6538  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
6539  *          is to delete using decrRef() as it is no more needed.
6540  *  \throw If \a this is not allocated.
6541  */
6542 DataArrayInt *DataArrayInt::renumber(const int *old2New) const throw(INTERP_KERNEL::Exception)
6543 {
6544   checkAllocated();
6545   int nbTuples=getNumberOfTuples();
6546   int nbOfCompo=getNumberOfComponents();
6547   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6548   ret->alloc(nbTuples,nbOfCompo);
6549   ret->copyStringInfoFrom(*this);
6550   const int *iptr=getConstPointer();
6551   int *optr=ret->getPointer();
6552   for(int i=0;i<nbTuples;i++)
6553     std::copy(iptr+nbOfCompo*i,iptr+nbOfCompo*(i+1),optr+nbOfCompo*old2New[i]);
6554   ret->copyStringInfoFrom(*this);
6555   return ret.retn();
6556 }
6557
6558 /*!
6559  * Returns a copy of \a this array with values permuted as required by \a new2Old array.
6560  * The values are permuted so that  \c new[ i ] = \c old[ \a new2Old[ i ]]. Number of
6561  * tuples in the result array remains the same as in \this one.
6562  * If a permutation reduction is needed, substr() or selectByTupleId() should be used.
6563  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
6564  *  \param [in] new2Old - C array of length equal to \a this->getNumberOfTuples()
6565  *     giving a previous position of i-th new value.
6566  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
6567  *          is to delete using decrRef() as it is no more needed.
6568  */
6569 DataArrayInt *DataArrayInt::renumberR(const int *new2Old) const throw(INTERP_KERNEL::Exception)
6570 {
6571   checkAllocated();
6572   int nbTuples=getNumberOfTuples();
6573   int nbOfCompo=getNumberOfComponents();
6574   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6575   ret->alloc(nbTuples,nbOfCompo);
6576   ret->copyStringInfoFrom(*this);
6577   const int *iptr=getConstPointer();
6578   int *optr=ret->getPointer();
6579   for(int i=0;i<nbTuples;i++)
6580     std::copy(iptr+nbOfCompo*new2Old[i],iptr+nbOfCompo*(new2Old[i]+1),optr+nbOfCompo*i);
6581   ret->copyStringInfoFrom(*this);
6582   return ret.retn();
6583 }
6584
6585 /*!
6586  * Returns a shorten and permuted copy of \a this array. The new DataArrayInt is
6587  * of size \a newNbOfTuple and it's values are permuted as required by \a old2New array.
6588  * The values are permuted so that  \c new[ \a old2New[ i ]] = \c old[ i ] for all
6589  * \a old2New[ i ] >= 0. In other words every i-th tuple in \a this array, for which 
6590  * \a old2New[ i ] is negative, is missing from the result array.
6591  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
6592  *  \param [in] old2New - C array of length equal to \a this->getNumberOfTuples()
6593  *     giving a new position for i-th old tuple and giving negative position for
6594  *     for i-th old tuple that should be omitted.
6595  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
6596  *          is to delete using decrRef() as it is no more needed.
6597  */
6598 DataArrayInt *DataArrayInt::renumberAndReduce(const int *old2New, int newNbOfTuple) const throw(INTERP_KERNEL::Exception)
6599 {
6600   checkAllocated();
6601   int nbTuples=getNumberOfTuples();
6602   int nbOfCompo=getNumberOfComponents();
6603   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6604   ret->alloc(newNbOfTuple,nbOfCompo);
6605   const int *iptr=getConstPointer();
6606   int *optr=ret->getPointer();
6607   for(int i=0;i<nbTuples;i++)
6608     {
6609       int w=old2New[i];
6610       if(w>=0)
6611         std::copy(iptr+i*nbOfCompo,iptr+(i+1)*nbOfCompo,optr+w*nbOfCompo);
6612     }
6613   ret->copyStringInfoFrom(*this);
6614   return ret.retn();
6615 }
6616
6617 /*!
6618  * Returns a shorten and permuted copy of \a this array. The new DataArrayInt is
6619  * of size \a new2OldEnd - \a new2OldBg and it's values are permuted as required by
6620  * \a new2OldBg array.
6621  * The values are permuted so that  \c new[ i ] = \c old[ \a new2OldBg[ i ]].
6622  * This method is equivalent to renumberAndReduce() except that convention in input is
6623  * \c new2old and \b not \c old2new.
6624  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
6625  *  \param [in] new2OldBg - pointer to the beginning of a permutation array that gives a
6626  *              tuple index in \a this array to fill the i-th tuple in the new array.
6627  *  \param [in] new2OldEnd - specifies the end of the permutation array that starts at
6628  *              \a new2OldBg, so that pointer to a tuple index (\a pi) varies as this:
6629  *              \a new2OldBg <= \a pi < \a new2OldEnd.
6630  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
6631  *          is to delete using decrRef() as it is no more needed.
6632  */
6633 DataArrayInt *DataArrayInt::selectByTupleId(const int *new2OldBg, const int *new2OldEnd) const
6634 {
6635   checkAllocated();
6636   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6637   int nbComp=getNumberOfComponents();
6638   ret->alloc((int)std::distance(new2OldBg,new2OldEnd),nbComp);
6639   ret->copyStringInfoFrom(*this);
6640   int *pt=ret->getPointer();
6641   const int *srcPt=getConstPointer();
6642   int i=0;
6643   for(const int *w=new2OldBg;w!=new2OldEnd;w++,i++)
6644     std::copy(srcPt+(*w)*nbComp,srcPt+((*w)+1)*nbComp,pt+i*nbComp);
6645   ret->copyStringInfoFrom(*this);
6646   return ret.retn();
6647 }
6648
6649 /*!
6650  * Returns a shorten and permuted copy of \a this array. The new DataArrayInt is
6651  * of size \a new2OldEnd - \a new2OldBg and it's values are permuted as required by
6652  * \a new2OldBg array.
6653  * The values are permuted so that  \c new[ i ] = \c old[ \a new2OldBg[ i ]].
6654  * This method is equivalent to renumberAndReduce() except that convention in input is
6655  * \c new2old and \b not \c old2new.
6656  * This method is equivalent to selectByTupleId() except that it prevents coping data
6657  * from behind the end of \a this array.
6658  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
6659  *  \param [in] new2OldBg - pointer to the beginning of a permutation array that gives a
6660  *              tuple index in \a this array to fill the i-th tuple in the new array.
6661  *  \param [in] new2OldEnd - specifies the end of the permutation array that starts at
6662  *              \a new2OldBg, so that pointer to a tuple index (\a pi) varies as this:
6663  *              \a new2OldBg <= \a pi < \a new2OldEnd.
6664  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
6665  *          is to delete using decrRef() as it is no more needed.
6666  *  \throw If \a new2OldEnd - \a new2OldBg > \a this->getNumberOfTuples().
6667  */
6668 DataArrayInt *DataArrayInt::selectByTupleIdSafe(const int *new2OldBg, const int *new2OldEnd) const throw(INTERP_KERNEL::Exception)
6669 {
6670   checkAllocated();
6671   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6672   int nbComp=getNumberOfComponents();
6673   int oldNbOfTuples=getNumberOfTuples();
6674   ret->alloc((int)std::distance(new2OldBg,new2OldEnd),nbComp);
6675   ret->copyStringInfoFrom(*this);
6676   int *pt=ret->getPointer();
6677   const int *srcPt=getConstPointer();
6678   int i=0;
6679   for(const int *w=new2OldBg;w!=new2OldEnd;w++,i++)
6680     if(*w>=0 && *w<oldNbOfTuples)
6681       std::copy(srcPt+(*w)*nbComp,srcPt+((*w)+1)*nbComp,pt+i*nbComp);
6682     else
6683       throw INTERP_KERNEL::Exception("DataArrayInt::selectByTupleIdSafe : some ids has been detected to be out of [0,this->getNumberOfTuples) !");
6684   ret->copyStringInfoFrom(*this);
6685   return ret.retn();
6686 }
6687
6688 /*!
6689  * Returns a shorten copy of \a this array. The new DataArrayInt contains every
6690  * (\a bg + \c i * \a step)-th tuple of \a this array located before the \a end2-th
6691  * tuple. Indices of the selected tuples are the same as ones returned by the Python
6692  * command \c range( \a bg, \a end2, \a step ).
6693  * This method is equivalent to selectByTupleIdSafe() except that the input array is
6694  * not constructed explicitly.
6695  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
6696  *  \param [in] bg - index of the first tuple to copy from \a this array.
6697  *  \param [in] end2 - index of the tuple before which the tuples to copy are located.
6698  *  \param [in] step - index increment to get index of the next tuple to copy.
6699  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
6700  *          is to delete using decrRef() as it is no more needed.
6701  *  \sa DataArrayInt::substr.
6702  */
6703 DataArrayInt *DataArrayInt::selectByTupleId2(int bg, int end2, int step) const throw(INTERP_KERNEL::Exception)
6704 {
6705   checkAllocated();
6706   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6707   int nbComp=getNumberOfComponents();
6708   int newNbOfTuples=GetNumberOfItemGivenBESRelative(bg,end2,step,"DataArrayInt::selectByTupleId2 : ");
6709   ret->alloc(newNbOfTuples,nbComp);
6710   int *pt=ret->getPointer();
6711   const int *srcPt=getConstPointer()+bg*nbComp;
6712   for(int i=0;i<newNbOfTuples;i++,srcPt+=step*nbComp)
6713     std::copy(srcPt,srcPt+nbComp,pt+i*nbComp);
6714   ret->copyStringInfoFrom(*this);
6715   return ret.retn();
6716 }
6717
6718 /*!
6719  * Returns a shorten copy of \a this array. The new DataArrayInt contains ranges
6720  * of tuples specified by \a ranges parameter.
6721  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
6722  *  \param [in] ranges - std::vector of std::pair's each of which defines a range
6723  *              of tuples in [\c begin,\c end) format.
6724  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
6725  *          is to delete using decrRef() as it is no more needed.
6726  *  \throw If \a end < \a begin.
6727  *  \throw If \a end > \a this->getNumberOfTuples().
6728  *  \throw If \a this is not allocated.
6729  */
6730 DataArray *DataArrayInt::selectByTupleRanges(const std::vector<std::pair<int,int> >& ranges) const throw(INTERP_KERNEL::Exception)
6731 {
6732   checkAllocated();
6733   int nbOfComp=getNumberOfComponents();
6734   int nbOfTuplesThis=getNumberOfTuples();
6735   if(ranges.empty())
6736     {
6737       MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6738       ret->alloc(0,nbOfComp);
6739       ret->copyStringInfoFrom(*this);
6740       return ret.retn();
6741     }
6742   int ref=ranges.front().first;
6743   int nbOfTuples=0;
6744   bool isIncreasing=true;
6745   for(std::vector<std::pair<int,int> >::const_iterator it=ranges.begin();it!=ranges.end();it++)
6746     {
6747       if((*it).first<=(*it).second)
6748         {
6749           if((*it).first>=0 && (*it).second<=nbOfTuplesThis)
6750             {
6751               nbOfTuples+=(*it).second-(*it).first;
6752               if(isIncreasing)
6753                 isIncreasing=ref<=(*it).first;
6754               ref=(*it).second;
6755             }
6756           else
6757             {
6758               std::ostringstream oss; oss << "DataArrayInt::selectByTupleRanges : on range #" << std::distance(ranges.begin(),it);
6759               oss << " (" << (*it).first << "," << (*it).second << ") is greater than number of tuples of this :" << nbOfTuples << " !";
6760               throw INTERP_KERNEL::Exception(oss.str().c_str());
6761             }
6762         }
6763       else
6764         {
6765           std::ostringstream oss; oss << "DataArrayInt::selectByTupleRanges : on range #" << std::distance(ranges.begin(),it);
6766           oss << " (" << (*it).first << "," << (*it).second << ") end is before begin !";
6767           throw INTERP_KERNEL::Exception(oss.str().c_str());
6768         }
6769     }
6770   if(isIncreasing && nbOfTuplesThis==nbOfTuples)
6771     return deepCpy();
6772   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6773   ret->alloc(nbOfTuples,nbOfComp);
6774   ret->copyStringInfoFrom(*this);
6775   const int *src=getConstPointer();
6776   int *work=ret->getPointer();
6777   for(std::vector<std::pair<int,int> >::const_iterator it=ranges.begin();it!=ranges.end();it++)
6778     work=std::copy(src+(*it).first*nbOfComp,src+(*it).second*nbOfComp,work);
6779   return ret.retn();
6780 }
6781
6782 /*!
6783  * Returns a new DataArrayInt containing a renumbering map in "Old to New" mode.
6784  * This map, if applied to \a this array, would make it sorted. For example, if
6785  * \a this array contents are [9,10,0,6,4,11,3,7] then the contents of the result array
6786  * are [5,6,0,3,2,7,1,4]; if this result array (\a res) is used as an argument in call
6787  * \a this->renumber(\a res) then the returned array contains [0,3,4,6,7,9,10,11].
6788  * This method is useful for renumbering (in MED file for example). For more info
6789  * on renumbering see \ref MEDCouplingArrayRenumbering.
6790  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
6791  *          array using decrRef() as it is no more needed.
6792  *  \throw If \a this is not allocated.
6793  *  \throw If \a this->getNumberOfComponents() != 1.
6794  *  \throw If there are equal values in \a this array.
6795  */
6796 DataArrayInt *DataArrayInt::checkAndPreparePermutation() const throw(INTERP_KERNEL::Exception)
6797 {
6798   checkAllocated();
6799   if(getNumberOfComponents()!=1)
6800     throw INTERP_KERNEL::Exception("DataArrayInt::checkAndPreparePermutation : number of components must == 1 !");
6801   int nbTuples=getNumberOfTuples();
6802   const int *pt=getConstPointer();
6803   int *pt2=CheckAndPreparePermutation(pt,pt+nbTuples);
6804   DataArrayInt *ret=DataArrayInt::New();
6805   ret->useArray(pt2,true,C_DEALLOC,nbTuples,1);
6806   return ret;
6807 }
6808
6809 /*!
6810  * Returns two arrays describing a surjective mapping from \a this set of values (\a A)
6811  * onto a set of values of size \a targetNb (\a B). The surjective function is 
6812  * \a B[ \a A[ i ]] = i. That is to say that for each \a id in [0,\a targetNb), where \a
6813  * targetNb < \a this->getNumberOfTuples(), there exists at least one tupleId (\a tid) so
6814  * that <em> this->getIJ( tid, 0 ) == id</em>. <br>
6815  * The first of out arrays returns indices of elements of \a this array, grouped by their
6816  * place in the set \a B. The second out array is the index of the first one; it shows how
6817  * many elements of \a A are mapped into each element of \a B. <br>
6818  * For more info on
6819  * mapping and its usage in renumbering see \ref MEDCouplingArrayRenumbering. <br>
6820  * \b Example:
6821  * - \a this: [0,3,2,3,2,2,1,2]
6822  * - \a targetNb: 4
6823  * - \a arr:  [0,  6,  2,4,5,7,  1,3]
6824  * - \a arrI: [0,1,2,6,8]
6825  *
6826  * This result means: <br>
6827  * the element of \a B 0 encounters within \a A once (\a arrI[ 0+1 ] - \a arrI[ 0 ]) and
6828  * its index within \a A is 0 ( \a arr[ 0:1 ] == \a arr[ \a arrI[ 0 ] : \a arrI[ 0+1 ]]);<br>
6829  * the element of \a B 2 encounters within \a A 4 times (\a arrI[ 2+1 ] - \a arrI[ 2 ]) and
6830  * its indices within \a A are [2,4,5,7] ( \a arr[ 2:6 ] == \a arr[ \a arrI[ 2 ] : 
6831  * \a arrI[ 2+1 ]]); <br> etc.
6832  *  \param [in] targetNb - the size of the set \a B. \a targetNb must be equal or more
6833  *         than the maximal value of \a A.
6834  *  \param [out] arr - a new instance of DataArrayInt returning indices of
6835  *         elements of \a this, grouped by their place in the set \a B. The caller is to delete
6836  *         this array using decrRef() as it is no more needed.
6837  *  \param [out] arrI - a new instance of DataArrayInt returning size of groups of equal
6838  *         elements of \a this. The caller is to delete this array using decrRef() as it
6839  *         is no more needed.
6840  *  \throw If \a this is not allocated.
6841  *  \throw If \a this->getNumberOfComponents() != 1.
6842  *  \throw If any value in \a this is more or equal to \a targetNb.
6843  */
6844 void DataArrayInt::changeSurjectiveFormat(int targetNb, DataArrayInt *&arr, DataArrayInt *&arrI) const throw(INTERP_KERNEL::Exception)
6845 {
6846   checkAllocated();
6847   if(getNumberOfComponents()!=1)
6848     throw INTERP_KERNEL::Exception("DataArrayInt::changeSurjectiveFormat : number of components must == 1 !");
6849   int nbOfTuples=getNumberOfTuples();
6850   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New());
6851   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> retI(DataArrayInt::New());
6852   retI->alloc(targetNb+1,1);
6853   const int *input=getConstPointer();
6854   std::vector< std::vector<int> > tmp(targetNb);
6855   for(int i=0;i<nbOfTuples;i++)
6856     {
6857       int tmp2=input[i];
6858       if(tmp2>=0 && tmp2<targetNb)
6859         tmp[tmp2].push_back(i);
6860       else
6861         {
6862           std::ostringstream oss; oss << "DataArrayInt::changeSurjectiveFormat : At pos " << i << " presence of element " << tmp2 << " ! should be in [0," << targetNb << ") !";
6863           throw INTERP_KERNEL::Exception(oss.str().c_str());
6864         }
6865     }
6866   int *retIPtr=retI->getPointer();
6867   *retIPtr=0;
6868   for(std::vector< std::vector<int> >::const_iterator it1=tmp.begin();it1!=tmp.end();it1++,retIPtr++)
6869     retIPtr[1]=retIPtr[0]+(int)((*it1).size());
6870   if(nbOfTuples!=retI->getIJ(targetNb,0))
6871     throw INTERP_KERNEL::Exception("DataArrayInt::changeSurjectiveFormat : big problem should never happen !");
6872   ret->alloc(nbOfTuples,1);
6873   int *retPtr=ret->getPointer();
6874   for(std::vector< std::vector<int> >::const_iterator it1=tmp.begin();it1!=tmp.end();it1++)
6875     retPtr=std::copy((*it1).begin(),(*it1).end(),retPtr);
6876   arr=ret.retn();
6877   arrI=retI.retn();
6878 }
6879
6880
6881 /*!
6882  * Returns a new DataArrayInt containing a renumbering map in "Old to New" mode computed
6883  * from a zip representation of a surjective format (returned e.g. by
6884  * \ref ParaMEDMEM::DataArrayDouble::findCommonTuples() "DataArrayDouble::findCommonTuples()"
6885  * for example). The result array minimizes the permutation. <br>
6886  * For more info on renumbering see \ref MEDCouplingArrayRenumbering. <br>
6887  * \b Example: <br>
6888  * - \a nbOfOldTuples: 10 
6889  * - \a arr          : [0,3, 5,7,9]
6890  * - \a arrIBg       : [0,2,5]
6891  * - \a newNbOfTuples: 7
6892  * - result array    : [0,1,2,0,3,4,5,4,6,4]
6893  *
6894  *  \param [in] nbOfOldTuples - number of tuples in the initial array \a arr.
6895  *  \param [in] arr - the array of tuple indices grouped by \a arrIBg array.
6896  *  \param [in] arrIBg - the array dividing all indices stored in \a arr into groups of
6897  *         (indices of) equal values. Its every element (except the last one) points to
6898  *         the first element of a group of equal values.
6899  *  \param [in] arrIEnd - specifies the end of \a arrIBg, so that the last element of \a
6900  *          arrIBg is \a arrIEnd[ -1 ].
6901  *  \param [out] newNbOfTuples - number of tuples after surjection application.
6902  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
6903  *          array using decrRef() as it is no more needed.
6904  *  \throw If any value of \a arr breaks condition ( 0 <= \a arr[ i ] < \a nbOfOldTuples ).
6905  */
6906 DataArrayInt *DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2(int nbOfOldTuples, const int *arr, const int *arrIBg, const int *arrIEnd, int &newNbOfTuples) throw(INTERP_KERNEL::Exception)
6907 {
6908   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6909   ret->alloc(nbOfOldTuples,1);
6910   int *pt=ret->getPointer();
6911   std::fill(pt,pt+nbOfOldTuples,-1);
6912   int nbOfGrps=((int)std::distance(arrIBg,arrIEnd))-1;
6913   const int *cIPtr=arrIBg;
6914   for(int i=0;i<nbOfGrps;i++)
6915     pt[arr[cIPtr[i]]]=-(i+2);
6916   int newNb=0;
6917   for(int iNode=0;iNode<nbOfOldTuples;iNode++)
6918     {
6919       if(pt[iNode]<0)
6920         {
6921           if(pt[iNode]==-1)
6922             pt[iNode]=newNb++;
6923           else
6924             {
6925               int grpId=-(pt[iNode]+2);
6926               for(int j=cIPtr[grpId];j<cIPtr[grpId+1];j++)
6927                 {
6928                   if(arr[j]>=0 && arr[j]<nbOfOldTuples)
6929                     pt[arr[j]]=newNb;
6930                   else
6931                     {
6932                       std::ostringstream oss; oss << "DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2 : With element #" << j << " value is " << arr[j] << " should be in [0," << nbOfOldTuples << ") !";
6933                       throw INTERP_KERNEL::Exception(oss.str().c_str());
6934                     }
6935                 }
6936               newNb++;
6937             }
6938         }
6939     }
6940   newNbOfTuples=newNb;
6941   return ret.retn();
6942 }
6943
6944 /*!
6945  * Returns a new DataArrayInt containing a renumbering map in "New to Old" mode,
6946  * which if applied to \a this array would make it sorted ascendingly.
6947  * For more info on renumbering see \ref MEDCouplingArrayRenumbering. <br>
6948  * \b Example: <br>
6949  * - \a this: [2,0,1,1,0,1,2,0,1,1,0,0]
6950  * - result: [10,0,5,6,1,7,11,2,8,9,3,4]
6951  * - after applying result to \a this: [0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2] 
6952  *
6953  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
6954  *          array using decrRef() as it is no more needed.
6955  *  \throw If \a this is not allocated.
6956  *  \throw If \a this->getNumberOfComponents() != 1.
6957  */
6958 DataArrayInt *DataArrayInt::buildPermArrPerLevel() const throw(INTERP_KERNEL::Exception)
6959 {
6960   checkAllocated();
6961   if(getNumberOfComponents()!=1)
6962     throw INTERP_KERNEL::Exception("DataArrayInt::buildPermArrPerLevel : number of components must == 1 !");
6963   int nbOfTuples=getNumberOfTuples();
6964   const int *pt=getConstPointer();
6965   std::map<int,int> m;
6966   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6967   ret->alloc(nbOfTuples,1);
6968   int *opt=ret->getPointer();
6969   for(int i=0;i<nbOfTuples;i++,pt++,opt++)
6970     {
6971       int val=*pt;
6972       std::map<int,int>::iterator it=m.find(val);
6973       if(it!=m.end())
6974         {
6975           *opt=(*it).second;
6976           (*it).second++;
6977         }
6978       else
6979         {
6980           *opt=0;
6981           m.insert(std::pair<int,int>(val,1));
6982         }
6983     }
6984   int sum=0;
6985   for(std::map<int,int>::iterator it=m.begin();it!=m.end();it++)
6986     {
6987       int vt=(*it).second;
6988       (*it).second=sum;
6989       sum+=vt;
6990     }
6991   pt=getConstPointer();
6992   opt=ret->getPointer();
6993   for(int i=0;i<nbOfTuples;i++,pt++,opt++)
6994     *opt+=m[*pt];
6995   //
6996   return ret.retn();
6997 }
6998
6999 /*!
7000  * Checks if contents of \a this array are equal to that of an array filled with
7001  * iota(). This method is particularly useful for DataArrayInt instances that represent
7002  * a renumbering array to check the real need in renumbering. 
7003  *  \return bool - \a true if \a this array contents == \a range( \a this->getNumberOfTuples())
7004  *  \throw If \a this is not allocated.
7005  *  \throw If \a this->getNumberOfComponents() != 1.
7006  */
7007 bool DataArrayInt::isIdentity() const throw(INTERP_KERNEL::Exception)
7008 {
7009   checkAllocated();
7010   if(getNumberOfComponents()!=1)
7011     return false;
7012   int nbOfTuples=getNumberOfTuples();
7013   const int *pt=getConstPointer();
7014   for(int i=0;i<nbOfTuples;i++,pt++)
7015     if(*pt!=i)
7016       return false;
7017   return true;
7018 }
7019
7020 /*!
7021  * Checks if all values in \a this array are equal to \a val.
7022  *  \param [in] val - value to check equality of array values to.
7023  *  \return bool - \a true if all values are \a val.
7024  *  \throw If \a this is not allocated.
7025  *  \throw If \a this->getNumberOfComponents() != 1
7026  */
7027 bool DataArrayInt::isUniform(int val) const throw(INTERP_KERNEL::Exception)
7028 {
7029   checkAllocated();
7030   if(getNumberOfComponents()!=1)
7031     throw INTERP_KERNEL::Exception("DataArrayInt::isUniform : must be applied on DataArrayInt with only one component, you can call 'rearrange' method before !");
7032   int nbOfTuples=getNumberOfTuples();
7033   const int *w=getConstPointer();
7034   const int *end2=w+nbOfTuples;
7035   for(;w!=end2;w++)
7036     if(*w!=val)
7037       return false;
7038   return true;
7039 }
7040
7041 /*!
7042  * Creates a new DataArrayDouble and assigns all (textual and numerical) data of \a this
7043  * array to the new one.
7044  *  \return DataArrayDouble * - the new instance of DataArrayInt.
7045  */
7046 DataArrayDouble *DataArrayInt::convertToDblArr() const
7047 {
7048   checkAllocated();
7049   DataArrayDouble *ret=DataArrayDouble::New();
7050   ret->alloc(getNumberOfTuples(),getNumberOfComponents());
7051   std::size_t nbOfVals=getNbOfElems();
7052   const int *src=getConstPointer();
7053   double *dest=ret->getPointer();
7054   std::copy(src,src+nbOfVals,dest);
7055   ret->copyStringInfoFrom(*this);
7056   return ret;
7057 }
7058
7059 /*!
7060  * Returns a shorten copy of \a this array. The new DataArrayInt contains all
7061  * tuples starting from the \a tupleIdBg-th tuple and including all tuples located before
7062  * the \a tupleIdEnd-th one. This methods has a similar behavior as std::string::substr().
7063  * This method is a specialization of selectByTupleId2().
7064  *  \param [in] tupleIdBg - index of the first tuple to copy from \a this array.
7065  *  \param [in] tupleIdEnd - index of the tuple before which the tuples to copy are located.
7066  *          If \a tupleIdEnd == -1, all the tuples till the end of \a this array are copied.
7067  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
7068  *          is to delete using decrRef() as it is no more needed.
7069  *  \throw If \a tupleIdBg < 0.
7070  *  \throw If \a tupleIdBg > \a this->getNumberOfTuples().
7071     \throw If \a tupleIdEnd != -1 && \a tupleIdEnd < \a this->getNumberOfTuples().
7072  *  \sa DataArrayInt::selectByTupleId2
7073  */
7074 DataArrayInt *DataArrayInt::substr(int tupleIdBg, int tupleIdEnd) const throw(INTERP_KERNEL::Exception)
7075 {
7076   checkAllocated();
7077   int nbt=getNumberOfTuples();
7078   if(tupleIdBg<0)
7079     throw INTERP_KERNEL::Exception("DataArrayInt::substr : The tupleIdBg parameter must be greater than 0 !");
7080   if(tupleIdBg>nbt)
7081     throw INTERP_KERNEL::Exception("DataArrayInt::substr : The tupleIdBg parameter is greater than number of tuples !");
7082   int trueEnd=tupleIdEnd;
7083   if(tupleIdEnd!=-1)
7084     {
7085       if(tupleIdEnd>nbt)
7086         throw INTERP_KERNEL::Exception("DataArrayInt::substr : The tupleIdBg parameter is greater or equal than number of tuples !");
7087     }
7088   else
7089     trueEnd=nbt;
7090   int nbComp=getNumberOfComponents();
7091   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
7092   ret->alloc(trueEnd-tupleIdBg,nbComp);
7093   ret->copyStringInfoFrom(*this);
7094   std::copy(getConstPointer()+tupleIdBg*nbComp,getConstPointer()+trueEnd*nbComp,ret->getPointer());
7095   return ret.retn();
7096 }
7097
7098 /*!
7099  * Changes the number of components within \a this array so that its raw data **does
7100  * not** change, instead splitting this data into tuples changes.
7101  *  \warning This method erases all (name and unit) component info set before!
7102  *  \param [in] newNbOfComp - number of components for \a this array to have.
7103  *  \throw If \a this is not allocated
7104  *  \throw If getNbOfElems() % \a newNbOfCompo != 0.
7105  *  \throw If \a newNbOfCompo is lower than 1.
7106  *  \throw If the rearrange method would lead to a number of tuples higher than 2147483647 (maximal capacity of int32 !).
7107  *  \warning This method erases all (name and unit) component info set before!
7108  */
7109 void DataArrayInt::rearrange(int newNbOfCompo) throw(INTERP_KERNEL::Exception)
7110 {
7111   checkAllocated();
7112   if(newNbOfCompo<1)
7113     throw INTERP_KERNEL::Exception("DataArrayInt::rearrange : input newNbOfCompo must be > 0 !");
7114   std::size_t nbOfElems=getNbOfElems();
7115   if(nbOfElems%newNbOfCompo!=0)
7116     throw INTERP_KERNEL::Exception("DataArrayInt::rearrange : nbOfElems%newNbOfCompo!=0 !");
7117   if(nbOfElems/newNbOfCompo>(std::size_t)std::numeric_limits<int>::max())
7118     throw INTERP_KERNEL::Exception("DataArrayInt::rearrange : the rearrangement leads to too high number of tuples (> 2147483647) !");
7119   _info_on_compo.clear();
7120   _info_on_compo.resize(newNbOfCompo);
7121   declareAsNew();
7122 }
7123
7124 /*!
7125  * Changes the number of components within \a this array to be equal to its number
7126  * of tuples, and inversely its number of tuples to become equal to its number of 
7127  * components. So that its raw data **does not** change, instead splitting this
7128  * data into tuples changes.
7129  *  \warning This method erases all (name and unit) component info set before!
7130  *  \warning Do not confuse this method with fromNoInterlace() and toNoInterlace()!
7131  *  \throw If \a this is not allocated.
7132  *  \sa rearrange()
7133  */
7134 void DataArrayInt::transpose() throw(INTERP_KERNEL::Exception)
7135 {
7136   checkAllocated();
7137   int nbOfTuples=getNumberOfTuples();
7138   rearrange(nbOfTuples);
7139 }
7140
7141 /*!
7142  * Returns a shorten or extended copy of \a this array. If \a newNbOfComp is less
7143  * than \a this->getNumberOfComponents() then the result array is shorten as each tuple
7144  * is truncated to have \a newNbOfComp components, keeping first components. If \a
7145  * newNbOfComp is more than \a this->getNumberOfComponents() then the result array is
7146  * expanded as each tuple is populated with \a dftValue to have \a newNbOfComp
7147  * components.  
7148  *  \param [in] newNbOfComp - number of components for the new array to have.
7149  *  \param [in] dftValue - value assigned to new values added to the new array.
7150  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
7151  *          is to delete using decrRef() as it is no more needed.
7152  *  \throw If \a this is not allocated.
7153  */
7154 DataArrayInt *DataArrayInt::changeNbOfComponents(int newNbOfComp, int dftValue) const throw(INTERP_KERNEL::Exception)
7155 {
7156   checkAllocated();
7157   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
7158   ret->alloc(getNumberOfTuples(),newNbOfComp);
7159   const int *oldc=getConstPointer();
7160   int *nc=ret->getPointer();
7161   int nbOfTuples=getNumberOfTuples();
7162   int oldNbOfComp=getNumberOfComponents();
7163   int dim=std::min(oldNbOfComp,newNbOfComp);
7164   for(int i=0;i<nbOfTuples;i++)
7165     {
7166       int j=0;
7167       for(;j<dim;j++)
7168         nc[newNbOfComp*i+j]=oldc[i*oldNbOfComp+j];
7169       for(;j<newNbOfComp;j++)
7170         nc[newNbOfComp*i+j]=dftValue;
7171     }
7172   ret->setName(getName().c_str());
7173   for(int i=0;i<dim;i++)
7174     ret->setInfoOnComponent(i,getInfoOnComponent(i).c_str());
7175   ret->setName(getName().c_str());
7176   return ret.retn();
7177 }
7178
7179 /*!
7180  * Changes number of tuples in the array. If the new number of tuples is smaller
7181  * than the current number the array is truncated, otherwise the array is extended.
7182  *  \param [in] nbOfTuples - new number of tuples. 
7183  *  \throw If \a this is not allocated.
7184  *  \throw If \a nbOfTuples is negative.
7185  */
7186 void DataArrayInt::reAlloc(int nbOfTuples) throw(INTERP_KERNEL::Exception)
7187 {
7188   if(nbOfTuples<0)
7189     throw INTERP_KERNEL::Exception("DataArrayInt::reAlloc : input new number of tuples should be >=0 !");
7190   checkAllocated();
7191   _mem.reAlloc(getNumberOfComponents()*(std::size_t)nbOfTuples);
7192   declareAsNew();
7193 }
7194
7195
7196 /*!
7197  * Returns a copy of \a this array composed of selected components.
7198  * The new DataArrayInt has the same number of tuples but includes components
7199  * specified by \a compoIds parameter. So that getNbOfElems() of the result array
7200  * can be either less, same or more than \a this->getNbOfElems().
7201  *  \param [in] compoIds - sequence of zero based indices of components to include
7202  *              into the new array.
7203  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
7204  *          is to delete using decrRef() as it is no more needed.
7205  *  \throw If \a this is not allocated.
7206  *  \throw If a component index (\a i) is not valid: 
7207  *         \a i < 0 || \a i >= \a this->getNumberOfComponents().
7208  *
7209  *  \ref py_mcdataarrayint_keepselectedcomponents "Here is a Python example".
7210  */
7211 DataArray *DataArrayInt::keepSelectedComponents(const std::vector<int>& compoIds) const throw(INTERP_KERNEL::Exception)
7212 {
7213   checkAllocated();
7214   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New());
7215   int newNbOfCompo=(int)compoIds.size();
7216   int oldNbOfCompo=getNumberOfComponents();
7217   for(std::vector<int>::const_iterator it=compoIds.begin();it!=compoIds.end();it++)
7218     DataArray::CheckValueInRange(oldNbOfCompo,(*it),"keepSelectedComponents invalid requested component");
7219   int nbOfTuples=getNumberOfTuples();
7220   ret->alloc(nbOfTuples,newNbOfCompo);
7221   ret->copyPartOfStringInfoFrom(*this,compoIds);
7222   const int *oldc=getConstPointer();
7223   int *nc=ret->getPointer();
7224   for(int i=0;i<nbOfTuples;i++)
7225     for(int j=0;j<newNbOfCompo;j++,nc++)
7226       *nc=oldc[i*oldNbOfCompo+compoIds[j]];
7227   return ret.retn();
7228 }
7229
7230 /*!
7231  * Appends components of another array to components of \a this one, tuple by tuple.
7232  * So that the number of tuples of \a this array remains the same and the number of 
7233  * components increases.
7234  *  \param [in] other - the DataArrayInt to append to \a this one.
7235  *  \throw If \a this is not allocated.
7236  *  \throw If \a this and \a other arrays have different number of tuples.
7237  *
7238  *  \ref cpp_mcdataarrayint_meldwith "Here is a C++ example".
7239  *
7240  *  \ref py_mcdataarrayint_meldwith "Here is a Python example".
7241  */
7242 void DataArrayInt::meldWith(const DataArrayInt *other) throw(INTERP_KERNEL::Exception)
7243 {
7244   if(!other)
7245     throw INTERP_KERNEL::Exception("DataArrayInt::meldWith : DataArrayInt pointer in input is NULL !");
7246   checkAllocated();
7247   other->checkAllocated();
7248   int nbOfTuples=getNumberOfTuples();
7249   if(nbOfTuples!=other->getNumberOfTuples())
7250     throw INTERP_KERNEL::Exception("DataArrayInt::meldWith : mismatch of number of tuples !");
7251   int nbOfComp1=getNumberOfComponents();
7252   int nbOfComp2=other->getNumberOfComponents();
7253   int *newArr=(int *)malloc(nbOfTuples*(nbOfComp1+nbOfComp2)*sizeof(int));
7254   int *w=newArr;
7255   const int *inp1=getConstPointer();
7256   const int *inp2=other->getConstPointer();
7257   for(int i=0;i<nbOfTuples;i++,inp1+=nbOfComp1,inp2+=nbOfComp2)
7258     {
7259       w=std::copy(inp1,inp1+nbOfComp1,w);
7260       w=std::copy(inp2,inp2+nbOfComp2,w);
7261     }
7262   useArray(newArr,true,C_DEALLOC,nbOfTuples,nbOfComp1+nbOfComp2);
7263   std::vector<int> compIds(nbOfComp2);
7264   for(int i=0;i<nbOfComp2;i++)
7265     compIds[i]=nbOfComp1+i;
7266   copyPartOfStringInfoFrom2(compIds,*other);
7267 }
7268
7269 /*!
7270  * Copy all components in a specified order from another DataArrayInt.
7271  * The specified components become the first ones in \a this array.
7272  * Both numerical and textual data is copied. The number of tuples in \a this and
7273  * the other array can be different.
7274  *  \param [in] a - the array to copy data from.
7275  *  \param [in] compoIds - sequence of zero based indices of components, data of which is
7276  *              to be copied.
7277  *  \throw If \a a is NULL.
7278  *  \throw If \a compoIds.size() != \a a->getNumberOfComponents().
7279  *  \throw If \a compoIds[i] < 0 or \a compoIds[i] > \a this->getNumberOfComponents().
7280  *
7281  *  \ref py_mcdataarrayint_setselectedcomponents "Here is a Python example".
7282  */
7283 void DataArrayInt::setSelectedComponents(const DataArrayInt *a, const std::vector<int>& compoIds) throw(INTERP_KERNEL::Exception)
7284 {
7285   if(!a)
7286     throw INTERP_KERNEL::Exception("DataArrayInt::setSelectedComponents : input DataArrayInt is NULL !");
7287   checkAllocated();
7288   a->checkAllocated();
7289   copyPartOfStringInfoFrom2(compoIds,*a);
7290   std::size_t partOfCompoSz=compoIds.size();
7291   int nbOfCompo=getNumberOfComponents();
7292   int nbOfTuples=std::min(getNumberOfTuples(),a->getNumberOfTuples());
7293   const int *ac=a->getConstPointer();
7294   int *nc=getPointer();
7295   for(int i=0;i<nbOfTuples;i++)
7296     for(std::size_t j=0;j<partOfCompoSz;j++,ac++)
7297       nc[nbOfCompo*i+compoIds[j]]=*ac;
7298 }
7299
7300 /*!
7301  * Copy all values from another DataArrayInt into specified tuples and components
7302  * of \a this array. Textual data is not copied.
7303  * The tree parameters defining set of indices of tuples and components are similar to
7304  * the tree parameters of the Python function \c range(\c start,\c stop,\c step).
7305  *  \param [in] a - the array to copy values from.
7306  *  \param [in] bgTuples - index of the first tuple of \a this array to assign values to.
7307  *  \param [in] endTuples - index of the tuple before which the tuples to assign to
7308  *              are located.
7309  *  \param [in] stepTuples - index increment to get index of the next tuple to assign to.
7310  *  \param [in] bgComp - index of the first component of \a this array to assign values to.
7311  *  \param [in] endComp - index of the component before which the components to assign
7312  *              to are located.
7313  *  \param [in] stepComp - index increment to get index of the next component to assign to.
7314  *  \param [in] strictCompoCompare - if \a true (by default), then \a a->getNumberOfComponents() 
7315  *              must be equal to the number of columns to assign to, else an
7316  *              exception is thrown; if \a false, then it is only required that \a
7317  *              a->getNbOfElems() equals to number of values to assign to (this condition
7318  *              must be respected even if \a strictCompoCompare is \a true). The number of 
7319  *              values to assign to is given by following Python expression:
7320  *              \a nbTargetValues = 
7321  *              \c len(\c range(\a bgTuples,\a endTuples,\a stepTuples)) *
7322  *              \c len(\c range(\a bgComp,\a endComp,\a stepComp)).
7323  *  \throw If \a a is NULL.
7324  *  \throw If \a a is not allocated.
7325  *  \throw If \a this is not allocated.
7326  *  \throw If parameters specifying tuples and components to assign to do not give a
7327  *            non-empty range of increasing indices.
7328  *  \throw If \a a->getNbOfElems() != \a nbTargetValues.
7329  *  \throw If \a strictCompoCompare == \a true && \a a->getNumberOfComponents() !=
7330  *            \c len(\c range(\a bgComp,\a endComp,\a stepComp)).
7331  *
7332  *  \ref py_mcdataarrayint_setpartofvalues1 "Here is a Python example".
7333  */
7334 void DataArrayInt::setPartOfValues1(const DataArrayInt *a, int bgTuples, int endTuples, int stepTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare) throw(INTERP_KERNEL::Exception)
7335 {
7336   if(!a)
7337     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValues1 : DataArrayInt pointer in input is NULL !");
7338   const char msg[]="DataArrayInt::setPartOfValues1";
7339   checkAllocated();
7340   a->checkAllocated();
7341   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
7342   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
7343   int nbComp=getNumberOfComponents();
7344   int nbOfTuples=getNumberOfTuples();
7345   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
7346   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
7347   bool assignTech=true;
7348   if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
7349     {
7350       if(strictCompoCompare)
7351         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
7352     }
7353   else
7354     {
7355       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
7356       assignTech=false;
7357     }
7358   int *pt=getPointer()+bgTuples*nbComp+bgComp;
7359   const int *srcPt=a->getConstPointer();
7360   if(assignTech)
7361     {
7362       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
7363         for(int j=0;j<newNbOfComp;j++,srcPt++)
7364           pt[j*stepComp]=*srcPt;
7365     }
7366   else
7367     {
7368       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
7369         {
7370           const int *srcPt2=srcPt;
7371           for(int j=0;j<newNbOfComp;j++,srcPt2++)
7372             pt[j*stepComp]=*srcPt2;
7373         }
7374     }
7375 }
7376
7377 /*!
7378  * Assign a given value to values at specified tuples and components of \a this array.
7379  * The tree parameters defining set of indices of tuples and components are similar to
7380  * the tree parameters of the Python function \c range(\c start,\c stop,\c step)..
7381  *  \param [in] a - the value to assign.
7382  *  \param [in] bgTuples - index of the first tuple of \a this array to assign to.
7383  *  \param [in] endTuples - index of the tuple before which the tuples to assign to
7384  *              are located.
7385  *  \param [in] stepTuples - index increment to get index of the next tuple to assign to.
7386  *  \param [in] bgComp - index of the first component of \a this array to assign to.
7387  *  \param [in] endComp - index of the component before which the components to assign
7388  *              to are located.
7389  *  \param [in] stepComp - index increment to get index of the next component to assign to.
7390  *  \throw If \a this is not allocated.
7391  *  \throw If parameters specifying tuples and components to assign to, do not give a
7392  *            non-empty range of increasing indices or indices are out of a valid range
7393  *            for \this array.
7394  *
7395  *  \ref py_mcdataarrayint_setpartofvaluessimple1 "Here is a Python example".
7396  */
7397 void DataArrayInt::setPartOfValuesSimple1(int a, int bgTuples, int endTuples, int stepTuples, int bgComp, int endComp, int stepComp) throw(INTERP_KERNEL::Exception)
7398 {
7399   const char msg[]="DataArrayInt::setPartOfValuesSimple1";
7400   checkAllocated();
7401   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
7402   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
7403   int nbComp=getNumberOfComponents();
7404   int nbOfTuples=getNumberOfTuples();
7405   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
7406   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
7407   int *pt=getPointer()+bgTuples*nbComp+bgComp;
7408   for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
7409     for(int j=0;j<newNbOfComp;j++)
7410       pt[j*stepComp]=a;
7411 }
7412
7413
7414 /*!
7415  * Copy all values from another DataArrayInt (\a a) into specified tuples and 
7416  * components of \a this array. Textual data is not copied.
7417  * The tuples and components to assign to are defined by C arrays of indices.
7418  * There are two *modes of usage*:
7419  * - If \a a->getNbOfElems() equals to number of values to assign to, then every value
7420  *   of \a a is assigned to its own location within \a this array. 
7421  * - If \a a includes one tuple, then all values of \a a are assigned to the specified
7422  *   components of every specified tuple of \a this array. In this mode it is required
7423  *   that \a a->getNumberOfComponents() equals to the number of specified components.
7424  * 
7425  *  \param [in] a - the array to copy values from.
7426  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
7427  *              assign values of \a a to.
7428  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
7429  *              pointer to a tuple index <em>(pi)</em> varies as this: 
7430  *              \a bgTuples <= \a pi < \a endTuples.
7431  *  \param [in] bgComp - pointer to an array of component indices of \a this array to
7432  *              assign values of \a a to.
7433  *  \param [in] endComp - specifies the end of the array \a bgTuples, so that
7434  *              pointer to a component index <em>(pi)</em> varies as this: 
7435  *              \a bgComp <= \a pi < \a endComp.
7436  *  \param [in] strictCompoCompare - this parameter is checked only if the
7437  *               *mode of usage* is the first; if it is \a true (default), 
7438  *               then \a a->getNumberOfComponents() must be equal 
7439  *               to the number of specified columns, else this is not required.
7440  *  \throw If \a a is NULL.
7441  *  \throw If \a a is not allocated.
7442  *  \throw If \a this is not allocated.
7443  *  \throw If any index of tuple/component given by <em>bgTuples / bgComp</em> is
7444  *         out of a valid range for \a this array.
7445  *  \throw In the first *mode of usage*, if <em>strictCompoCompare == true </em> and
7446  *         if <em> a->getNumberOfComponents() != (endComp - bgComp) </em>.
7447  *  \throw In the second *mode of usage*, if \a a->getNumberOfTuples() != 1 or
7448  *         <em> a->getNumberOfComponents() != (endComp - bgComp)</em>.
7449  *
7450  *  \ref py_mcdataarrayint_setpartofvalues2 "Here is a Python example".
7451  */
7452 void DataArrayInt::setPartOfValues2(const DataArrayInt *a, const int *bgTuples, const int *endTuples, const int *bgComp, const int *endComp, bool strictCompoCompare) throw(INTERP_KERNEL::Exception)
7453 {
7454   if(!a)
7455     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValues2 : DataArrayInt pointer in input is NULL !");
7456   const char msg[]="DataArrayInt::setPartOfValues2";
7457   checkAllocated();
7458   a->checkAllocated();
7459   int nbComp=getNumberOfComponents();
7460   int nbOfTuples=getNumberOfTuples();
7461   for(const int *z=bgComp;z!=endComp;z++)
7462     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
7463   int newNbOfTuples=(int)std::distance(bgTuples,endTuples);
7464   int newNbOfComp=(int)std::distance(bgComp,endComp);
7465   bool assignTech=true;
7466   if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
7467     {
7468       if(strictCompoCompare)
7469         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
7470     }
7471   else
7472     {
7473       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
7474       assignTech=false;
7475     }
7476   int *pt=getPointer();
7477   const int *srcPt=a->getConstPointer();
7478   if(assignTech)
7479     {    
7480       for(const int *w=bgTuples;w!=endTuples;w++)
7481         {
7482           DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
7483           for(const int *z=bgComp;z!=endComp;z++,srcPt++)
7484             {    
7485               pt[(std::size_t)(*w)*nbComp+(*z)]=*srcPt;
7486             }
7487         }
7488     }
7489   else
7490     {
7491       for(const int *w=bgTuples;w!=endTuples;w++)
7492         {
7493           const int *srcPt2=srcPt;
7494           DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
7495           for(const int *z=bgComp;z!=endComp;z++,srcPt2++)
7496             {    
7497               pt[(std::size_t)(*w)*nbComp+(*z)]=*srcPt2;
7498             }
7499         }
7500     }
7501 }
7502
7503 /*!
7504  * Assign a given value to values at specified tuples and components of \a this array.
7505  * The tuples and components to assign to are defined by C arrays of indices.
7506  *  \param [in] a - the value to assign.
7507  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
7508  *              assign \a a to.
7509  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
7510  *              pointer to a tuple index (\a pi) varies as this: 
7511  *              \a bgTuples <= \a pi < \a endTuples.
7512  *  \param [in] bgComp - pointer to an array of component indices of \a this array to
7513  *              assign \a a to.
7514  *  \param [in] endComp - specifies the end of the array \a bgTuples, so that
7515  *              pointer to a component index (\a pi) varies as this: 
7516  *              \a bgComp <= \a pi < \a endComp.
7517  *  \throw If \a this is not allocated.
7518  *  \throw If any index of tuple/component given by <em>bgTuples / bgComp</em> is
7519  *         out of a valid range for \a this array.
7520  *
7521  *  \ref py_mcdataarrayint_setpartofvaluessimple2 "Here is a Python example".
7522  */
7523 void DataArrayInt::setPartOfValuesSimple2(int a, const int *bgTuples, const int *endTuples, const int *bgComp, const int *endComp) throw(INTERP_KERNEL::Exception)
7524 {
7525   checkAllocated();
7526   int nbComp=getNumberOfComponents();
7527   int nbOfTuples=getNumberOfTuples();
7528   for(const int *z=bgComp;z!=endComp;z++)
7529     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
7530   int *pt=getPointer();
7531   for(const int *w=bgTuples;w!=endTuples;w++)
7532     for(const int *z=bgComp;z!=endComp;z++)
7533       {
7534         DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
7535         pt[(std::size_t)(*w)*nbComp+(*z)]=a;
7536       }
7537 }
7538
7539 /*!
7540  * Copy all values from another DataArrayInt (\a a) into specified tuples and 
7541  * components of \a this array. Textual data is not copied.
7542  * The tuples to assign to are defined by a C array of indices.
7543  * The components to assign to are defined by three values similar to parameters of
7544  * the Python function \c range(\c start,\c stop,\c step).
7545  * There are two *modes of usage*:
7546  * - If \a a->getNbOfElems() equals to number of values to assign to, then every value
7547  *   of \a a is assigned to its own location within \a this array. 
7548  * - If \a a includes one tuple, then all values of \a a are assigned to the specified
7549  *   components of every specified tuple of \a this array. In this mode it is required
7550  *   that \a a->getNumberOfComponents() equals to the number of specified components.
7551  *
7552  *  \param [in] a - the array to copy values from.
7553  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
7554  *              assign values of \a a to.
7555  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
7556  *              pointer to a tuple index <em>(pi)</em> varies as this: 
7557  *              \a bgTuples <= \a pi < \a endTuples.
7558  *  \param [in] bgComp - index of the first component of \a this array to assign to.
7559  *  \param [in] endComp - index of the component before which the components to assign
7560  *              to are located.
7561  *  \param [in] stepComp - index increment to get index of the next component to assign to.
7562  *  \param [in] strictCompoCompare - this parameter is checked only in the first
7563  *               *mode of usage*; if \a strictCompoCompare is \a true (default), 
7564  *               then \a a->getNumberOfComponents() must be equal 
7565  *               to the number of specified columns, else this is not required.
7566  *  \throw If \a a is NULL.
7567  *  \throw If \a a is not allocated.
7568  *  \throw If \a this is not allocated.
7569  *  \throw If any index of tuple given by \a bgTuples is out of a valid range for 
7570  *         \a this array.
7571  *  \throw In the first *mode of usage*, if <em>strictCompoCompare == true </em> and
7572  *         if <em> a->getNumberOfComponents()</em> is unequal to the number of components
7573  *         defined by <em>(bgComp,endComp,stepComp)</em>.
7574  *  \throw In the second *mode of usage*, if \a a->getNumberOfTuples() != 1 or
7575  *         <em> a->getNumberOfComponents()</em> is unequal to the number of components
7576  *         defined by <em>(bgComp,endComp,stepComp)</em>.
7577  *  \throw If parameters specifying components to assign to, do not give a
7578  *            non-empty range of increasing indices or indices are out of a valid range
7579  *            for \this array.
7580  *
7581  *  \ref py_mcdataarrayint_setpartofvalues3 "Here is a Python example".
7582  */
7583 void DataArrayInt::setPartOfValues3(const DataArrayInt *a, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare) throw(INTERP_KERNEL::Exception)
7584 {
7585   if(!a)
7586     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValues3 : DataArrayInt pointer in input is NULL !");
7587   const char msg[]="DataArrayInt::setPartOfValues3";
7588   checkAllocated();
7589   a->checkAllocated();
7590   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
7591   int nbComp=getNumberOfComponents();
7592   int nbOfTuples=getNumberOfTuples();
7593   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
7594   int newNbOfTuples=(int)std::distance(bgTuples,endTuples);
7595   bool assignTech=true;
7596   if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
7597     {
7598       if(strictCompoCompare)
7599         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
7600     }
7601   else
7602     {
7603       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
7604       assignTech=false;
7605     }
7606   int *pt=getPointer()+bgComp;
7607   const int *srcPt=a->getConstPointer();
7608   if(assignTech)
7609     {
7610       for(const int *w=bgTuples;w!=endTuples;w++)
7611         for(int j=0;j<newNbOfComp;j++,srcPt++)
7612           {
7613             DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
7614             pt[(std::size_t)(*w)*nbComp+j*stepComp]=*srcPt;
7615           }
7616     }
7617   else
7618     {
7619       for(const int *w=bgTuples;w!=endTuples;w++)
7620         {
7621           const int *srcPt2=srcPt;
7622           for(int j=0;j<newNbOfComp;j++,srcPt2++)
7623             {
7624               DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
7625               pt[(std::size_t)(*w)*nbComp+j*stepComp]=*srcPt2;
7626             }
7627         }
7628     }
7629 }
7630
7631 /*!
7632  * Assign a given value to values at specified tuples and components of \a this array.
7633  * The tuples to assign to are defined by a C array of indices.
7634  * The components to assign to are defined by three values similar to parameters of
7635  * the Python function \c range(\c start,\c stop,\c step).
7636  *  \param [in] a - the value to assign.
7637  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
7638  *              assign \a a to.
7639  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
7640  *              pointer to a tuple index <em>(pi)</em> varies as this: 
7641  *              \a bgTuples <= \a pi < \a endTuples.
7642  *  \param [in] bgComp - index of the first component of \a this array to assign to.
7643  *  \param [in] endComp - index of the component before which the components to assign
7644  *              to are located.
7645  *  \param [in] stepComp - index increment to get index of the next component to assign to.
7646  *  \throw If \a this is not allocated.
7647  *  \throw If any index of tuple given by \a bgTuples is out of a valid range for 
7648  *         \a this array.
7649  *  \throw If parameters specifying components to assign to, do not give a
7650  *            non-empty range of increasing indices or indices are out of a valid range
7651  *            for \this array.
7652  *
7653  *  \ref py_mcdataarrayint_setpartofvaluessimple3 "Here is a Python example".
7654  */
7655 void DataArrayInt::setPartOfValuesSimple3(int a, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp) throw(INTERP_KERNEL::Exception)
7656 {
7657   const char msg[]="DataArrayInt::setPartOfValuesSimple3";
7658   checkAllocated();
7659   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
7660   int nbComp=getNumberOfComponents();
7661   int nbOfTuples=getNumberOfTuples();
7662   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
7663   int *pt=getPointer()+bgComp;
7664   for(const int *w=bgTuples;w!=endTuples;w++)
7665     for(int j=0;j<newNbOfComp;j++)
7666       {
7667         DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
7668         pt[(std::size_t)(*w)*nbComp+j*stepComp]=a;
7669       }
7670 }
7671
7672 void DataArrayInt::setPartOfValues4(const DataArrayInt *a, int bgTuples, int endTuples, int stepTuples, const int *bgComp, const int *endComp, bool strictCompoCompare) throw(INTERP_KERNEL::Exception)
7673 {
7674   if(!a)
7675     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValues4 : input DataArrayInt is NULL !");
7676   const char msg[]="DataArrayInt::setPartOfValues4";
7677   checkAllocated();
7678   a->checkAllocated();
7679   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
7680   int newNbOfComp=(int)std::distance(bgComp,endComp);
7681   int nbComp=getNumberOfComponents();
7682   for(const int *z=bgComp;z!=endComp;z++)
7683     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
7684   int nbOfTuples=getNumberOfTuples();
7685   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
7686   bool assignTech=true;
7687   if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
7688     {
7689       if(strictCompoCompare)
7690         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
7691     }
7692   else
7693     {
7694       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
7695       assignTech=false;
7696     }
7697   const int *srcPt=a->getConstPointer();
7698   int *pt=getPointer()+bgTuples*nbComp;
7699   if(assignTech)
7700     {
7701       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
7702         for(const int *z=bgComp;z!=endComp;z++,srcPt++)
7703           pt[*z]=*srcPt;
7704     }
7705   else
7706     {
7707       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
7708         {
7709           const int *srcPt2=srcPt;
7710           for(const int *z=bgComp;z!=endComp;z++,srcPt2++)
7711             pt[*z]=*srcPt2;
7712         }
7713     }
7714 }
7715
7716 void DataArrayInt::setPartOfValuesSimple4(int a, int bgTuples, int endTuples, int stepTuples, const int *bgComp, const int *endComp) throw(INTERP_KERNEL::Exception)
7717 {
7718   const char msg[]="DataArrayInt::setPartOfValuesSimple4";
7719   checkAllocated();
7720   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
7721   int nbComp=getNumberOfComponents();
7722   for(const int *z=bgComp;z!=endComp;z++)
7723     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
7724   int nbOfTuples=getNumberOfTuples();
7725   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
7726   int *pt=getPointer()+bgTuples*nbComp;
7727   for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
7728     for(const int *z=bgComp;z!=endComp;z++)
7729       pt[*z]=a;
7730 }
7731
7732 /*!
7733  * Copy some tuples from another DataArrayInt into specified tuples
7734  * of \a this array. Textual data is not copied. Both arrays must have equal number of
7735  * components.
7736  * Both the tuples to assign and the tuples to assign to are defined by a DataArrayInt.
7737  * All components of selected tuples are copied.
7738  *  \param [in] a - the array to copy values from.
7739  *  \param [in] tuplesSelec - the array specifying both source tuples of \a a and
7740  *              target tuples of \a this. \a tuplesSelec has two components, and the
7741  *              first component specifies index of the source tuple and the second
7742  *              one specifies index of the target tuple.
7743  *  \throw If \a this is not allocated.
7744  *  \throw If \a a is NULL.
7745  *  \throw If \a a is not allocated.
7746  *  \throw If \a tuplesSelec is NULL.
7747  *  \throw If \a tuplesSelec is not allocated.
7748  *  \throw If <em>this->getNumberOfComponents() != a->getNumberOfComponents()</em>.
7749  *  \throw If \a tuplesSelec->getNumberOfComponents() != 2.
7750  *  \throw If any tuple index given by \a tuplesSelec is out of a valid range for 
7751  *         the corresponding (\a this or \a a) array.
7752  */
7753 void DataArrayInt::setPartOfValuesAdv(const DataArrayInt *a, const DataArrayInt *tuplesSelec) throw(INTERP_KERNEL::Exception)
7754 {
7755   if(!a || !tuplesSelec)
7756     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValuesAdv : DataArrayInt pointer in input is NULL !");
7757   checkAllocated();
7758   a->checkAllocated();
7759   tuplesSelec->checkAllocated();
7760   int nbOfComp=getNumberOfComponents();
7761   if(nbOfComp!=a->getNumberOfComponents())
7762     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValuesAdv : This and a do not have the same number of components !");
7763   if(tuplesSelec->getNumberOfComponents()!=2)
7764     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValuesAdv : Expecting to have a tuple selector DataArrayInt instance with exactly 2 components !");
7765   int thisNt=getNumberOfTuples();
7766   int aNt=a->getNumberOfTuples();
7767   int *valsToSet=getPointer();
7768   const int *valsSrc=a->getConstPointer();
7769   for(const int *tuple=tuplesSelec->begin();tuple!=tuplesSelec->end();tuple+=2)
7770     {
7771       if(tuple[1]>=0 && tuple[1]<aNt)
7772         {
7773           if(tuple[0]>=0 && tuple[0]<thisNt)
7774             std::copy(valsSrc+nbOfComp*tuple[1],valsSrc+nbOfComp*(tuple[1]+1),valsToSet+nbOfComp*tuple[0]);
7775           else
7776             {
7777               std::ostringstream oss; oss << "DataArrayInt::setPartOfValuesAdv : Tuple #" << std::distance(tuplesSelec->begin(),tuple)/2;
7778               oss << " of 'tuplesSelec' request of tuple id #" << tuple[0] << " in 'this' ! It should be in [0," << thisNt << ") !";
7779               throw INTERP_KERNEL::Exception(oss.str().c_str());
7780             }
7781         }
7782       else
7783         {
7784           std::ostringstream oss; oss << "DataArrayInt::setPartOfValuesAdv : Tuple #" << std::distance(tuplesSelec->begin(),tuple)/2;
7785           oss << " of 'tuplesSelec' request of tuple id #" << tuple[1] << " in 'a' ! It should be in [0," << aNt << ") !";
7786           throw INTERP_KERNEL::Exception(oss.str().c_str());
7787         }
7788     }
7789 }
7790
7791 /*!
7792  * Copy some tuples from another DataArrayInt (\a a) into contiguous tuples
7793  * of \a this array. Textual data is not copied. Both arrays must have equal number of
7794  * components.
7795  * The tuples to assign to are defined by index of the first tuple, and
7796  * their number is defined by \a tuplesSelec->getNumberOfTuples().
7797  * The tuples to copy are defined by values of a DataArrayInt.
7798  * All components of selected tuples are copied.
7799  *  \param [in] tupleIdStart - index of the first tuple of \a this array to assign
7800  *              values to.
7801  *  \param [in] a - the array to copy values from.
7802  *  \param [in] tuplesSelec - the array specifying tuples of \a a to copy.
7803  *  \throw If \a this is not allocated.
7804  *  \throw If \a a is NULL.
7805  *  \throw If \a a is not allocated.
7806  *  \throw If \a tuplesSelec is NULL.
7807  *  \throw If \a tuplesSelec is not allocated.
7808  *  \throw If <em>this->getNumberOfComponents() != a->getNumberOfComponents()</em>.
7809  *  \throw If \a tuplesSelec->getNumberOfComponents() != 1.
7810  *  \throw If <em>tupleIdStart + tuplesSelec->getNumberOfTuples() > this->getNumberOfTuples().</em>
7811  *  \throw If any tuple index given by \a tuplesSelec is out of a valid range for 
7812  *         \a a array.
7813  */
7814 void DataArrayInt::setContigPartOfSelectedValues(int tupleIdStart, const DataArray *aBase, const DataArrayInt *tuplesSelec) throw(INTERP_KERNEL::Exception)
7815 {
7816   if(!aBase || !tuplesSelec)
7817     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues : input DataArray is NULL !");
7818   const DataArrayInt *a=dynamic_cast<const DataArrayInt *>(aBase);
7819   if(!a)
7820     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues : input DataArray aBase is not a DataArrayInt !");
7821   checkAllocated();
7822   a->checkAllocated();
7823   tuplesSelec->checkAllocated();
7824   int nbOfComp=getNumberOfComponents();
7825   if(nbOfComp!=a->getNumberOfComponents())
7826     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues : This and a do not have the same number of components !");
7827   if(tuplesSelec->getNumberOfComponents()!=1)
7828     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues : Expecting to have a tuple selector DataArrayInt instance with exactly 1 component !");
7829   int thisNt=getNumberOfTuples();
7830   int aNt=a->getNumberOfTuples();
7831   int nbOfTupleToWrite=tuplesSelec->getNumberOfTuples();
7832   int *valsToSet=getPointer()+tupleIdStart*nbOfComp;
7833   if(tupleIdStart+nbOfTupleToWrite>thisNt)
7834     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues : invalid number range of values to write !");
7835   const int *valsSrc=a->getConstPointer();
7836   for(const int *tuple=tuplesSelec->begin();tuple!=tuplesSelec->end();tuple++,valsToSet+=nbOfComp)
7837     {
7838       if(*tuple>=0 && *tuple<aNt)
7839         {
7840           std::copy(valsSrc+nbOfComp*(*tuple),valsSrc+nbOfComp*(*tuple+1),valsToSet);
7841         }
7842       else
7843         {
7844           std::ostringstream oss; oss << "DataArrayInt::setContigPartOfSelectedValues : Tuple #" << std::distance(tuplesSelec->begin(),tuple);
7845           oss << " of 'tuplesSelec' request of tuple id #" << *tuple << " in 'a' ! It should be in [0," << aNt << ") !";
7846           throw INTERP_KERNEL::Exception(oss.str().c_str());
7847         }
7848     }
7849 }
7850
7851 /*!
7852  * Copy some tuples from another DataArrayInt (\a a) into contiguous tuples
7853  * of \a this array. Textual data is not copied. Both arrays must have equal number of
7854  * components.
7855  * The tuples to copy are defined by three values similar to parameters of
7856  * the Python function \c range(\c start,\c stop,\c step).
7857  * The tuples to assign to are defined by index of the first tuple, and
7858  * their number is defined by number of tuples to copy.
7859  * All components of selected tuples are copied.
7860  *  \param [in] tupleIdStart - index of the first tuple of \a this array to assign
7861  *              values to.
7862  *  \param [in] a - the array to copy values from.
7863  *  \param [in] bg - index of the first tuple to copy of the array \a a.
7864  *  \param [in] end2 - index of the tuple of \a a before which the tuples to copy
7865  *              are located.
7866  *  \param [in] step - index increment to get index of the next tuple to copy.
7867  *  \throw If \a this is not allocated.
7868  *  \throw If \a a is NULL.
7869  *  \throw If \a a is not allocated.
7870  *  \throw If <em>this->getNumberOfComponents() != a->getNumberOfComponents()</em>.
7871  *  \throw If <em>tupleIdStart + len(range(bg,end2,step)) > this->getNumberOfTuples().</em>
7872  *  \throw If parameters specifying tuples to copy, do not give a
7873  *            non-empty range of increasing indices or indices are out of a valid range
7874  *            for the array \a a.
7875  */
7876 void DataArrayInt::setContigPartOfSelectedValues2(int tupleIdStart, const DataArray *aBase, int bg, int end2, int step) throw(INTERP_KERNEL::Exception)
7877 {
7878   if(!aBase)
7879     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues2 : input DataArray is NULL !");
7880   const DataArrayInt *a=dynamic_cast<const DataArrayInt *>(aBase);
7881   if(!a)
7882     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues2 : input DataArray aBase is not a DataArrayInt !");
7883   checkAllocated();
7884   a->checkAllocated();
7885   int nbOfComp=getNumberOfComponents();
7886   const char msg[]="DataArrayInt::setContigPartOfSelectedValues2";
7887   int nbOfTupleToWrite=DataArray::GetNumberOfItemGivenBES(bg,end2,step,msg);
7888   if(nbOfComp!=a->getNumberOfComponents())
7889     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues2 : This and a do not have the same number of components !");
7890   int thisNt=getNumberOfTuples();
7891   int aNt=a->getNumberOfTuples();
7892   int *valsToSet=getPointer()+tupleIdStart*nbOfComp;
7893   if(tupleIdStart+nbOfTupleToWrite>thisNt)
7894     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues2 : invalid number range of values to write !");
7895   if(end2>aNt)
7896     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues2 : invalid range of values to read !");
7897   const int *valsSrc=a->getConstPointer()+bg*nbOfComp;
7898   for(int i=0;i<nbOfTupleToWrite;i++,valsToSet+=nbOfComp,valsSrc+=step*nbOfComp)
7899     {
7900       std::copy(valsSrc,valsSrc+nbOfComp,valsToSet);
7901     }
7902 }
7903
7904 /*!
7905  * Returns a value located at specified tuple and component.
7906  * This method is equivalent to DataArrayInt::getIJ() except that validity of
7907  * parameters is checked. So this method is safe but expensive if used to go through
7908  * all values of \a this.
7909  *  \param [in] tupleId - index of tuple of interest.
7910  *  \param [in] compoId - index of component of interest.
7911  *  \return double - value located by \a tupleId and \a compoId.
7912  *  \throw If \a this is not allocated.
7913  *  \throw If condition <em>( 0 <= tupleId < this->getNumberOfTuples() )</em> is violated.
7914  *  \throw If condition <em>( 0 <= compoId < this->getNumberOfComponents() )</em> is violated.
7915  */
7916 int DataArrayInt::getIJSafe(int tupleId, int compoId) const throw(INTERP_KERNEL::Exception)
7917 {
7918   checkAllocated();
7919   if(tupleId<0 || tupleId>=getNumberOfTuples())
7920     {
7921       std::ostringstream oss; oss << "DataArrayInt::getIJSafe : request for tupleId " << tupleId << " should be in [0," << getNumberOfTuples() << ") !";
7922       throw INTERP_KERNEL::Exception(oss.str().c_str());
7923     }
7924   if(compoId<0 || compoId>=getNumberOfComponents())
7925     {
7926       std::ostringstream oss; oss << "DataArrayInt::getIJSafe : request for compoId " << compoId << " should be in [0," << getNumberOfComponents() << ") !";
7927       throw INTERP_KERNEL::Exception(oss.str().c_str());
7928     }
7929   return _mem[tupleId*_info_on_compo.size()+compoId];
7930 }
7931
7932 /*!
7933  * Returns the first value of \a this. 
7934  *  \return int - the last value of \a this array.
7935  *  \throw If \a this is not allocated.
7936  *  \throw If \a this->getNumberOfComponents() != 1.
7937  *  \throw If \a this->getNumberOfTuples() < 1.
7938  */
7939 int DataArrayInt::front() const throw(INTERP_KERNEL::Exception)
7940 {
7941   checkAllocated();
7942   if(getNumberOfComponents()!=1)
7943     throw INTERP_KERNEL::Exception("DataArrayInt::front : number of components not equal to one !");
7944   int nbOfTuples=getNumberOfTuples();
7945   if(nbOfTuples<1)
7946     throw INTERP_KERNEL::Exception("DataArrayInt::front : number of tuples must be >= 1 !");
7947   return *(getConstPointer());
7948 }
7949
7950 /*!
7951  * Returns the last value of \a this. 
7952  *  \return int - the last value of \a this array.
7953  *  \throw If \a this is not allocated.
7954  *  \throw If \a this->getNumberOfComponents() != 1.
7955  *  \throw If \a this->getNumberOfTuples() < 1.
7956  */
7957 int DataArrayInt::back() const throw(INTERP_KERNEL::Exception)
7958 {
7959   checkAllocated();
7960   if(getNumberOfComponents()!=1)
7961     throw INTERP_KERNEL::Exception("DataArrayInt::back : number of components not equal to one !");
7962   int nbOfTuples=getNumberOfTuples();
7963   if(nbOfTuples<1)
7964     throw INTERP_KERNEL::Exception("DataArrayInt::back : number of tuples must be >= 1 !");
7965   return *(getConstPointer()+nbOfTuples-1);
7966 }
7967
7968 /*!
7969  * Assign pointer to one array to a pointer to another appay. Reference counter of
7970  * \a arrayToSet is incremented / decremented.
7971  *  \param [in] newArray - the pointer to array to assign to \a arrayToSet.
7972  *  \param [in,out] arrayToSet - the pointer to array to assign to.
7973  */
7974 void DataArrayInt::SetArrayIn(DataArrayInt *newArray, DataArrayInt* &arrayToSet)
7975 {
7976   if(newArray!=arrayToSet)
7977     {
7978       if(arrayToSet)
7979         arrayToSet->decrRef();
7980       arrayToSet=newArray;
7981       if(arrayToSet)
7982         arrayToSet->incrRef();
7983     }
7984 }
7985
7986 DataArrayIntIterator *DataArrayInt::iterator() throw(INTERP_KERNEL::Exception)
7987 {
7988   return new DataArrayIntIterator(this);
7989 }
7990
7991 /*!
7992  * Creates a new DataArrayInt containing IDs (indices) of tuples holding value equal to a
7993  * given one.
7994  *  \param [in] val - the value to find within \a this.
7995  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
7996  *          array using decrRef() as it is no more needed.
7997  *  \throw If \a this is not allocated.
7998  *  \throw If \a this->getNumberOfComponents() != 1.
7999  */
8000 DataArrayInt *DataArrayInt::getIdsEqual(int val) const throw(INTERP_KERNEL::Exception)
8001 {
8002   checkAllocated();
8003   if(getNumberOfComponents()!=1)
8004     throw INTERP_KERNEL::Exception("DataArrayInt::getIdsEqual : the array must have only one component, you can call 'rearrange' method before !");
8005   const int *cptr=getConstPointer();
8006   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
8007   int nbOfTuples=getNumberOfTuples();
8008   for(int i=0;i<nbOfTuples;i++,cptr++)
8009     if(*cptr==val)
8010       ret->pushBackSilent(i);
8011   return ret.retn();
8012 }
8013
8014 /*!
8015  * Creates a new DataArrayInt containing IDs (indices) of tuples holding value \b not
8016  * equal to a given one. 
8017  *  \param [in] val - the value to ignore within \a this.
8018  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
8019  *          array using decrRef() as it is no more needed.
8020  *  \throw If \a this is not allocated.
8021  *  \throw If \a this->getNumberOfComponents() != 1.
8022  */
8023 DataArrayInt *DataArrayInt::getIdsNotEqual(int val) const throw(INTERP_KERNEL::Exception)
8024 {
8025   checkAllocated();
8026   if(getNumberOfComponents()!=1)
8027     throw INTERP_KERNEL::Exception("DataArrayInt::getIdsNotEqual : the array must have only one component, you can call 'rearrange' method before !");
8028   const int *cptr=getConstPointer();
8029   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
8030   int nbOfTuples=getNumberOfTuples();
8031   for(int i=0;i<nbOfTuples;i++,cptr++)
8032     if(*cptr!=val)
8033       ret->pushBackSilent(i);
8034   return ret.retn();
8035 }
8036
8037
8038 /*!
8039  * Assigns \a newValue to all elements holding \a oldValue within \a this
8040  * one-dimensional array.
8041  *  \param [in] oldValue - the value to replace.
8042  *  \param [in] newValue - the value to assign.
8043  *  \return int - number of replacements performed.
8044  *  \throw If \a this is not allocated.
8045  *  \throw If \a this->getNumberOfComponents() != 1.
8046  */
8047 int DataArrayInt::changeValue(int oldValue, int newValue) throw(INTERP_KERNEL::Exception)
8048 {
8049   checkAllocated();
8050   if(getNumberOfComponents()!=1)
8051     throw INTERP_KERNEL::Exception("DataArrayInt::changeValue : the array must have only one component, you can call 'rearrange' method before !");
8052   int *start=getPointer();
8053   int *end2=start+getNbOfElems();
8054   int ret=0;
8055   for(int *val=start;val!=end2;val++)
8056     {
8057       if(*val==oldValue)
8058         {
8059           *val=newValue;
8060           ret++;
8061         }
8062     }
8063   return ret;
8064 }
8065
8066 /*!
8067  * Creates a new DataArrayInt containing IDs (indices) of tuples holding value equal to
8068  * one of given values.
8069  *  \param [in] valsBg - an array of values to find within \a this array.
8070  *  \param [in] valsEnd - specifies the end of the array \a valsBg, so that
8071  *              the last value of \a valsBg is \a valsEnd[ -1 ].
8072  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
8073  *          array using decrRef() as it is no more needed.
8074  *  \throw If \a this->getNumberOfComponents() != 1.
8075  */
8076 DataArrayInt *DataArrayInt::getIdsEqualList(const int *valsBg, const int *valsEnd) const throw(INTERP_KERNEL::Exception)
8077 {
8078   if(getNumberOfComponents()!=1)
8079     throw INTERP_KERNEL::Exception("DataArrayInt::getIdsEqualList : the array must have only one component, you can call 'rearrange' method before !");
8080   std::set<int> vals2(valsBg,valsEnd);
8081   const int *cptr=getConstPointer();
8082   std::vector<int> res;
8083   int nbOfTuples=getNumberOfTuples();
8084   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
8085   for(int i=0;i<nbOfTuples;i++,cptr++)
8086     if(vals2.find(*cptr)!=vals2.end())
8087       ret->pushBackSilent(i);
8088   return ret.retn();
8089 }
8090
8091 /*!
8092  * Creates a new DataArrayInt containing IDs (indices) of tuples holding values \b not
8093  * equal to any of given values.
8094  *  \param [in] valsBg - an array of values to ignore within \a this array.
8095  *  \param [in] valsEnd - specifies the end of the array \a valsBg, so that
8096  *              the last value of \a valsBg is \a valsEnd[ -1 ].
8097  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
8098  *          array using decrRef() as it is no more needed.
8099  *  \throw If \a this->getNumberOfComponents() != 1.
8100  */
8101 DataArrayInt *DataArrayInt::getIdsNotEqualList(const int *valsBg, const int *valsEnd) const throw(INTERP_KERNEL::Exception)
8102 {
8103   if(getNumberOfComponents()!=1)
8104     throw INTERP_KERNEL::Exception("DataArrayInt::getIdsNotEqualList : the array must have only one component, you can call 'rearrange' method before !");
8105   std::set<int> vals2(valsBg,valsEnd);
8106   const int *cptr=getConstPointer();
8107   std::vector<int> res;
8108   int nbOfTuples=getNumberOfTuples();
8109   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
8110   for(int i=0;i<nbOfTuples;i++,cptr++)
8111     if(vals2.find(*cptr)==vals2.end())
8112       ret->pushBackSilent(i);
8113   return ret.retn();
8114 }
8115
8116 /*!
8117  * This method is an extension of DataArrayInt::locateValue method because this method works for DataArrayInt with
8118  * any number of components excepted 0 (an INTERP_KERNEL::Exception is thrown in this case).
8119  * This method searches in \b this is there is a tuple that matched the input parameter \b tupl.
8120  * If any the tuple id is returned. If not -1 is returned.
8121  * 
8122  * This method throws an INTERP_KERNEL::Exception if the number of components in \b this mismatches with the size of
8123  * the input vector. An INTERP_KERNEL::Exception is thrown too if \b this is not allocated.
8124  *
8125  * \return tuple id where \b tupl is. -1 if no such tuple exists in \b this.
8126  * \sa DataArrayInt::search, DataArrayInt::presenceOfTuple.
8127  */
8128 int DataArrayInt::locateTuple(const std::vector<int>& tupl) const throw(INTERP_KERNEL::Exception)
8129 {
8130   checkAllocated();
8131   int nbOfCompo=getNumberOfComponents();
8132   if(nbOfCompo==0)
8133     throw INTERP_KERNEL::Exception("DataArrayInt::locateTuple : 0 components in 'this' !");
8134   if(nbOfCompo!=(int)tupl.size())
8135     {
8136       std::ostringstream oss; oss << "DataArrayInt::locateTuple : 'this' contains " << nbOfCompo << " components and searching for a tuple of length " << tupl.size() << " !";
8137       throw INTERP_KERNEL::Exception(oss.str().c_str());
8138     }
8139   const int *cptr=getConstPointer();
8140   std::size_t nbOfVals=getNbOfElems();
8141   for(const int *work=cptr;work!=cptr+nbOfVals;)
8142     {
8143       work=std::search(work,cptr+nbOfVals,tupl.begin(),tupl.end());
8144       if(work!=cptr+nbOfVals)
8145         {
8146           if(std::distance(cptr,work)%nbOfCompo!=0)
8147             work++;
8148           else
8149             return std::distance(cptr,work)/nbOfCompo;
8150         }
8151     }
8152   return -1;
8153 }
8154
8155 /*!
8156  * This method searches the sequence specified in input parameter \b vals in \b this.
8157  * This works only for DataArrayInt having number of components equal to one (if not an INTERP_KERNEL::Exception will be thrown).
8158  * This method differs from DataArrayInt::locateTuple in that the position is internal raw data is not considered here contrary to DataArrayInt::locateTuple.
8159  * \sa DataArrayInt::locateTuple
8160  */
8161 int DataArrayInt::search(const std::vector<int>& vals) const throw(INTERP_KERNEL::Exception)
8162 {
8163   checkAllocated();
8164   int nbOfCompo=getNumberOfComponents();
8165   if(nbOfCompo!=1)
8166     throw INTERP_KERNEL::Exception("DataArrayInt::search : works only for DataArrayInt instance with one component !");
8167   const int *cptr=getConstPointer();
8168   std::size_t nbOfVals=getNbOfElems();
8169   const int *loc=std::search(cptr,cptr+nbOfVals,vals.begin(),vals.end());
8170   if(loc!=cptr+nbOfVals)
8171     return std::distance(cptr,loc);
8172   return -1;
8173 }
8174
8175 /*!
8176  * This method expects to be called when number of components of this is equal to one.
8177  * This method returns the tuple id, if it exists, of the first tuple equal to \b value.
8178  * If not any tuple contains \b value -1 is returned.
8179  * \sa DataArrayInt::presenceOfValue
8180  */
8181 int DataArrayInt::locateValue(int value) const throw(INTERP_KERNEL::Exception)
8182 {
8183   checkAllocated();
8184   if(getNumberOfComponents()!=1)
8185     throw INTERP_KERNEL::Exception("DataArrayInt::presenceOfValue : the array must have only one component, you can call 'rearrange' method before !");
8186   const int *cptr=getConstPointer();
8187   int nbOfTuples=getNumberOfTuples();
8188   const int *ret=std::find(cptr,cptr+nbOfTuples,value);
8189   if(ret!=cptr+nbOfTuples)
8190     return std::distance(cptr,ret);
8191   return -1;
8192 }
8193
8194 /*!
8195  * This method expects to be called when number of components of this is equal to one.
8196  * This method returns the tuple id, if it exists, of the first tuple so that the value is contained in \b vals.
8197  * If not any tuple contains one of the values contained in 'vals' false is returned.
8198  * \sa DataArrayInt::presenceOfValue
8199  */
8200 int DataArrayInt::locateValue(const std::vector<int>& vals) const throw(INTERP_KERNEL::Exception)
8201 {
8202   checkAllocated();
8203   if(getNumberOfComponents()!=1)
8204     throw INTERP_KERNEL::Exception("DataArrayInt::presenceOfValue : the array must have only one component, you can call 'rearrange' method before !");
8205   std::set<int> vals2(vals.begin(),vals.end());
8206   const int *cptr=getConstPointer();
8207   int nbOfTuples=getNumberOfTuples();
8208   for(const int *w=cptr;w!=cptr+nbOfTuples;w++)
8209     if(vals2.find(*w)!=vals2.end())
8210       return std::distance(cptr,w);
8211   return -1;
8212 }
8213
8214 /*!
8215  * This method returns the number of values in \a this that are equals to input parameter \a value.
8216  * This method only works for single component array.
8217  *
8218  * \return a value in [ 0, \c this->getNumberOfTuples() )
8219  *
8220  * \throw If \a this is not allocated
8221  *
8222  */
8223 int DataArrayInt::count(int value) const throw(INTERP_KERNEL::Exception)
8224 {
8225   int ret=0;
8226   checkAllocated();
8227   if(getNumberOfComponents()!=1)
8228     throw INTERP_KERNEL::Exception("DataArrayInt::count : must be applied on DataArrayInt with only one component, you can call 'rearrange' method before !");
8229   const int *vals=begin();
8230   int nbOfTuples=getNumberOfTuples();
8231   for(int i=0;i<nbOfTuples;i++,vals++)
8232     if(*vals==value)
8233       ret++;
8234   return ret;
8235 }
8236
8237 /*!
8238  * This method is an extension of DataArrayInt::presenceOfValue method because this method works for DataArrayInt with
8239  * any number of components excepted 0 (an INTERP_KERNEL::Exception is thrown in this case).
8240  * This method searches in \b this is there is a tuple that matched the input parameter \b tupl.
8241  * This method throws an INTERP_KERNEL::Exception if the number of components in \b this mismatches with the size of
8242  * the input vector. An INTERP_KERNEL::Exception is thrown too if \b this is not allocated.
8243  * \sa DataArrayInt::locateTuple
8244  */
8245 bool DataArrayInt::presenceOfTuple(const std::vector<int>& tupl) const throw(INTERP_KERNEL::Exception)
8246 {
8247   return locateTuple(tupl)!=-1;
8248 }
8249
8250
8251 /*!
8252  * Returns \a true if a given value is present within \a this one-dimensional array.
8253  *  \param [in] value - the value to find within \a this array.
8254  *  \return bool - \a true in case if \a value is present within \a this array.
8255  *  \throw If \a this is not allocated.
8256  *  \throw If \a this->getNumberOfComponents() != 1.
8257  *  \sa locateValue()
8258  */
8259 bool DataArrayInt::presenceOfValue(int value) const throw(INTERP_KERNEL::Exception)
8260 {
8261   return locateValue(value)!=-1;
8262 }
8263
8264 /*!
8265  * This method expects to be called when number of components of this is equal to one.
8266  * This method returns true if it exists a tuple so that the value is contained in \b vals.
8267  * If not any tuple contains one of the values contained in 'vals' false is returned.
8268  * \sa DataArrayInt::locateValue
8269  */
8270 bool DataArrayInt::presenceOfValue(const std::vector<int>& vals) const throw(INTERP_KERNEL::Exception)
8271 {
8272   return locateValue(vals)!=-1;
8273 }
8274
8275 /*!
8276  * Accumulates values of each component of \a this array.
8277  *  \param [out] res - an array of length \a this->getNumberOfComponents(), allocated 
8278  *         by the caller, that is filled by this method with sum value for each
8279  *         component.
8280  *  \throw If \a this is not allocated.
8281  */
8282 void DataArrayInt::accumulate(int *res) const throw(INTERP_KERNEL::Exception)
8283 {
8284   checkAllocated();
8285   const int *ptr=getConstPointer();
8286   int nbTuple=getNumberOfTuples();
8287   int nbComps=getNumberOfComponents();
8288   std::fill(res,res+nbComps,0);
8289   for(int i=0;i<nbTuple;i++)
8290     std::transform(ptr+i*nbComps,ptr+(i+1)*nbComps,res,res,std::plus<int>());
8291 }
8292
8293 int DataArrayInt::accumulate(int compId) const throw(INTERP_KERNEL::Exception)
8294 {
8295   checkAllocated();
8296   const int *ptr=getConstPointer();
8297   int nbTuple=getNumberOfTuples();
8298   int nbComps=getNumberOfComponents();
8299   if(compId<0 || compId>=nbComps)
8300     throw INTERP_KERNEL::Exception("DataArrayInt::accumulate : Invalid compId specified : No such nb of components !");
8301   int ret=0;
8302   for(int i=0;i<nbTuple;i++)
8303     ret+=ptr[i*nbComps+compId];
8304   return ret;
8305 }
8306
8307 /*!
8308  * This method accumulate using addition tuples in \a this using input index array [ \a bgOfIndex, \a endOfIndex ).
8309  * The returned array will have same number of components than \a this and number of tuples equal to
8310  * \c std::distance(bgOfIndex,endOfIndex) \b minus \b one.
8311  *
8312  * The input index array is expected to be ascendingly sorted in which the all referenced ids should be in [0, \c this->getNumberOfTuples).
8313  *
8314  * \param [in] bgOfIndex - begin (included) of the input index array.
8315  * \param [in] endOfIndex - end (excluded) of the input index array.
8316  * \return DataArrayInt * - the new instance having the same number of components than \a this.
8317  * 
8318  * \throw If bgOfIndex or end is NULL.
8319  * \throw If input index array is not ascendingly sorted.
8320  * \throw If there is an id in [ \a bgOfIndex, \a endOfIndex ) not in [0, \c this->getNumberOfTuples).
8321  * \throw If std::distance(bgOfIndex,endOfIndex)==0.
8322  */
8323 DataArrayInt *DataArrayInt::accumulatePerChunck(const int *bgOfIndex, const int *endOfIndex) const throw(INTERP_KERNEL::Exception)
8324 {
8325   if(!bgOfIndex || !endOfIndex)
8326     throw INTERP_KERNEL::Exception("DataArrayInt::accumulatePerChunck : input pointer NULL !");
8327   checkAllocated();
8328   int nbCompo=getNumberOfComponents();
8329   int nbOfTuples=getNumberOfTuples();
8330   int sz=(int)std::distance(bgOfIndex,endOfIndex);
8331   if(sz<1)
8332     throw INTERP_KERNEL::Exception("DataArrayInt::accumulatePerChunck : invalid size of input index array !");
8333   sz--;
8334   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(sz,nbCompo);
8335   const int *w=bgOfIndex;
8336   if(*w<0 || *w>=nbOfTuples)
8337     throw INTERP_KERNEL::Exception("DataArrayInt::accumulatePerChunck : The first element of the input index not in [0,nbOfTuples) !");
8338   const int *srcPt=begin()+(*w)*nbCompo;
8339   int *tmp=ret->getPointer();
8340   for(int i=0;i<sz;i++,tmp+=nbCompo,w++)
8341     {
8342       std::fill(tmp,tmp+nbCompo,0.);
8343       if(w[1]>=w[0])
8344         {
8345           for(int j=w[0];j<w[1];j++,srcPt+=nbCompo)
8346             {
8347               if(j>=0 && j<nbOfTuples)
8348                 std::transform(srcPt,srcPt+nbCompo,tmp,tmp,std::plus<int>());
8349               else
8350                 {
8351                   std::ostringstream oss; oss << "DataArrayInt::accumulatePerChunck : At rank #" << i << " the input index array points to id " << j << " should be in [0," << nbOfTuples << ") !";
8352                   throw INTERP_KERNEL::Exception(oss.str().c_str());
8353                 }
8354             }
8355         }
8356       else
8357         {
8358           std::ostringstream oss; oss << "DataArrayInt::accumulatePerChunck : At rank #" << i << " the input index array is not in ascendingly sorted.";
8359           throw INTERP_KERNEL::Exception(oss.str().c_str());
8360         }
8361     }
8362   ret->copyStringInfoFrom(*this);
8363   return ret.retn();
8364 }
8365
8366 /*!
8367  * Returns a new DataArrayInt by concatenating two given arrays, so that (1) the number
8368  * of tuples in the result array is <em> a1->getNumberOfTuples() + a2->getNumberOfTuples() -
8369  * offsetA2</em> and (2)
8370  * the number of component in the result array is same as that of each of given arrays.
8371  * First \a offsetA2 tuples of \a a2 are skipped and thus are missing from the result array.
8372  * Info on components is copied from the first of the given arrays. Number of components
8373  * in the given arrays must be the same.
8374  *  \param [in] a1 - an array to include in the result array.
8375  *  \param [in] a2 - another array to include in the result array.
8376  *  \param [in] offsetA2 - number of tuples of \a a2 to skip.
8377  *  \return DataArrayInt * - the new instance of DataArrayInt.
8378  *          The caller is to delete this result array using decrRef() as it is no more
8379  *          needed.
8380  *  \throw If either \a a1 or \a a2 is NULL.
8381  *  \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents().
8382  */
8383 DataArrayInt *DataArrayInt::Aggregate(const DataArrayInt *a1, const DataArrayInt *a2, int offsetA2)
8384 {
8385   if(!a1 || !a2)
8386     throw INTERP_KERNEL::Exception("DataArrayInt::Aggregate : input DataArrayInt instance is NULL !");
8387   int nbOfComp=a1->getNumberOfComponents();
8388   if(nbOfComp!=a2->getNumberOfComponents())
8389     throw INTERP_KERNEL::Exception("Nb of components mismatch for array Aggregation !");
8390   int nbOfTuple1=a1->getNumberOfTuples();
8391   int nbOfTuple2=a2->getNumberOfTuples();
8392   DataArrayInt *ret=DataArrayInt::New();
8393   ret->alloc(nbOfTuple1+nbOfTuple2-offsetA2,nbOfComp);
8394   int *pt=std::copy(a1->getConstPointer(),a1->getConstPointer()+nbOfTuple1*nbOfComp,ret->getPointer());
8395   std::copy(a2->getConstPointer()+offsetA2*nbOfComp,a2->getConstPointer()+nbOfTuple2*nbOfComp,pt);
8396   ret->copyStringInfoFrom(*a1);
8397   return ret;
8398 }
8399
8400 /*!
8401  * Returns a new DataArrayInt by concatenating all given arrays, so that (1) the number
8402  * of tuples in the result array is a sum of the number of tuples of given arrays and (2)
8403  * the number of component in the result array is same as that of each of given arrays.
8404  * Info on components is copied from the first of the given arrays. Number of components
8405  * in the given arrays must be  the same.
8406  *  \param [in] arr - a sequence of arrays to include in the result array.
8407  *  \return DataArrayInt * - the new instance of DataArrayInt.
8408  *          The caller is to delete this result array using decrRef() as it is no more
8409  *          needed.
8410  *  \throw If all arrays within \a arr are NULL.
8411  *  \throw If getNumberOfComponents() of arrays within \a arr.
8412  */
8413 DataArrayInt *DataArrayInt::Aggregate(const std::vector<const DataArrayInt *>& arr) throw(INTERP_KERNEL::Exception)
8414 {
8415   std::vector<const DataArrayInt *> a;
8416   for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
8417     if(*it4)
8418       a.push_back(*it4);
8419   if(a.empty())
8420     throw INTERP_KERNEL::Exception("DataArrayInt::Aggregate : input list must be NON EMPTY !");
8421   std::vector<const DataArrayInt *>::const_iterator it=a.begin();
8422   int nbOfComp=(*it)->getNumberOfComponents();
8423   int nbt=(*it++)->getNumberOfTuples();
8424   for(int i=1;it!=a.end();it++,i++)
8425     {
8426       if((*it)->getNumberOfComponents()!=nbOfComp)
8427         throw INTERP_KERNEL::Exception("DataArrayInt::Aggregate : Nb of components mismatch for array aggregation !");
8428       nbt+=(*it)->getNumberOfTuples();
8429     }
8430   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
8431   ret->alloc(nbt,nbOfComp);
8432   int *pt=ret->getPointer();
8433   for(it=a.begin();it!=a.end();it++)
8434     pt=std::copy((*it)->getConstPointer(),(*it)->getConstPointer()+(*it)->getNbOfElems(),pt);
8435   ret->copyStringInfoFrom(*(a[0]));
8436   return ret.retn();
8437 }
8438
8439 /*!
8440  * This method takes as input a list of DataArrayInt instances \a arrs that represent each a packed index arrays.
8441  * A packed index array is an allocated array with one component, and at least one tuple. The first element
8442  * of each array in \a arrs must be 0. Each array in \a arrs is expected to be increasingly monotonic.
8443  * 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.
8444  * 
8445  * \return DataArrayInt * - a new object to be managed by the caller.
8446  */
8447 DataArrayInt *DataArrayInt::AggregateIndexes(const std::vector<const DataArrayInt *>& arrs) throw(INTERP_KERNEL::Exception)
8448 {
8449   int retSz=1;
8450   for(std::vector<const DataArrayInt *>::const_iterator it4=arrs.begin();it4!=arrs.end();it4++)
8451     {
8452       if(*it4)
8453         {
8454           (*it4)->checkAllocated();
8455           if((*it4)->getNumberOfComponents()!=1)
8456             {
8457               std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a DataArrayInt instance with nb of compo != 1 at pos " << std::distance(arrs.begin(),it4) << " !";
8458               throw INTERP_KERNEL::Exception(oss.str().c_str());
8459             }
8460           int nbTupl=(*it4)->getNumberOfTuples();
8461           if(nbTupl<1)
8462             {
8463               std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a DataArrayInt instance with nb of tuples < 1 at pos " << std::distance(arrs.begin(),it4) << " !";
8464               throw INTERP_KERNEL::Exception(oss.str().c_str());
8465             }
8466           if((*it4)->front()!=0)
8467             {
8468               std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a DataArrayInt instance with front value != 0 at pos " << std::distance(arrs.begin(),it4) << " !";
8469               throw INTERP_KERNEL::Exception(oss.str().c_str());
8470             }
8471           retSz+=nbTupl-1;
8472         }
8473       else
8474         {
8475           std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a null instance at pos " << std::distance(arrs.begin(),it4) << " !";
8476           throw INTERP_KERNEL::Exception(oss.str().c_str());
8477         }
8478     }
8479   if(arrs.empty())
8480     throw INTERP_KERNEL::Exception("DataArrayInt::AggregateIndexes : input list must be NON EMPTY !");
8481   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
8482   ret->alloc(retSz,1);
8483   int *pt=ret->getPointer(); *pt++=0;
8484   for(std::vector<const DataArrayInt *>::const_iterator it=arrs.begin();it!=arrs.end();it++)
8485     pt=std::transform((*it)->begin()+1,(*it)->end(),pt,std::bind2nd(std::plus<int>(),pt[-1]));
8486   ret->copyStringInfoFrom(*(arrs[0]));
8487   return ret.retn();
8488 }
8489
8490 /*!
8491  * Returns the maximal value and its location within \a this one-dimensional array.
8492  *  \param [out] tupleId - index of the tuple holding the maximal value.
8493  *  \return int - the maximal value among all values of \a this array.
8494  *  \throw If \a this->getNumberOfComponents() != 1
8495  *  \throw If \a this->getNumberOfTuples() < 1
8496  */
8497 int DataArrayInt::getMaxValue(int& tupleId) const throw(INTERP_KERNEL::Exception)
8498 {
8499   checkAllocated();
8500   if(getNumberOfComponents()!=1)
8501     throw INTERP_KERNEL::Exception("DataArrayInt::getMaxValue : must be applied on DataArrayInt with only one component !");
8502   int nbOfTuples=getNumberOfTuples();
8503   if(nbOfTuples<=0)
8504     throw INTERP_KERNEL::Exception("DataArrayInt::getMaxValue : array exists but number of tuples must be > 0 !");
8505   const int *vals=getConstPointer();
8506   const int *loc=std::max_element(vals,vals+nbOfTuples);
8507   tupleId=(int)std::distance(vals,loc);
8508   return *loc;
8509 }
8510
8511 /*!
8512  * Returns the maximal value within \a this array that is allowed to have more than
8513  *  one component.
8514  *  \return int - the maximal value among all values of \a this array.
8515  *  \throw If \a this is not allocated.
8516  */
8517 int DataArrayInt::getMaxValueInArray() const throw(INTERP_KERNEL::Exception)
8518 {
8519   checkAllocated();
8520   const int *loc=std::max_element(begin(),end());
8521   return *loc;
8522 }
8523
8524 /*!
8525  * Returns the minimal value and its location within \a this one-dimensional array.
8526  *  \param [out] tupleId - index of the tuple holding the minimal value.
8527  *  \return int - the minimal value among all values of \a this array.
8528  *  \throw If \a this->getNumberOfComponents() != 1
8529  *  \throw If \a this->getNumberOfTuples() < 1
8530  */
8531 int DataArrayInt::getMinValue(int& tupleId) const throw(INTERP_KERNEL::Exception)
8532 {
8533   checkAllocated();
8534   if(getNumberOfComponents()!=1)
8535     throw INTERP_KERNEL::Exception("DataArrayInt::getMaxValue : must be applied on DataArrayInt with only one component !");
8536   int nbOfTuples=getNumberOfTuples();
8537   if(nbOfTuples<=0)
8538     throw INTERP_KERNEL::Exception("DataArrayInt::getMaxValue : array exists but number of tuples must be > 0 !");
8539   const int *vals=getConstPointer();
8540   const int *loc=std::min_element(vals,vals+nbOfTuples);
8541   tupleId=(int)std::distance(vals,loc);
8542   return *loc;
8543 }
8544
8545 /*!
8546  * Returns the minimal value within \a this array that is allowed to have more than
8547  *  one component.
8548  *  \return int - the minimal value among all values of \a this array.
8549  *  \throw If \a this is not allocated.
8550  */
8551 int DataArrayInt::getMinValueInArray() const throw(INTERP_KERNEL::Exception)
8552 {
8553   checkAllocated();
8554   const int *loc=std::min_element(begin(),end());
8555   return *loc;
8556 }
8557
8558 /*!
8559  * Converts every value of \a this array to its absolute value.
8560  *  \throw If \a this is not allocated.
8561  */
8562 void DataArrayInt::abs() throw(INTERP_KERNEL::Exception)
8563 {
8564   checkAllocated();
8565   int *ptr=getPointer();
8566   std::size_t nbOfElems=getNbOfElems();
8567   std::transform(ptr,ptr+nbOfElems,ptr,std::ptr_fun<int,int>(std::abs));
8568   declareAsNew();
8569 }
8570
8571 /*!
8572  * Apply a liner function to a given component of \a this array, so that
8573  * an array element <em>(x)</em> becomes \f$ a * x + b \f$.
8574  *  \param [in] a - the first coefficient of the function.
8575  *  \param [in] b - the second coefficient of the function.
8576  *  \param [in] compoId - the index of component to modify.
8577  *  \throw If \a this is not allocated.
8578  */
8579 void DataArrayInt::applyLin(int a, int b, int compoId) throw(INTERP_KERNEL::Exception)
8580 {
8581   checkAllocated();
8582   int *ptr=getPointer()+compoId;
8583   int nbOfComp=getNumberOfComponents();
8584   int nbOfTuple=getNumberOfTuples();
8585   for(int i=0;i<nbOfTuple;i++,ptr+=nbOfComp)
8586     *ptr=a*(*ptr)+b;
8587   declareAsNew();
8588 }
8589
8590 /*!
8591  * Apply a liner function to all elements of \a this array, so that
8592  * an element _x_ becomes \f$ a * x + b \f$.
8593  *  \param [in] a - the first coefficient of the function.
8594  *  \param [in] b - the second coefficient of the function.
8595  *  \throw If \a this is not allocated.
8596  */
8597 void DataArrayInt::applyLin(int a, int b) throw(INTERP_KERNEL::Exception)
8598 {
8599   checkAllocated();
8600   int *ptr=getPointer();
8601   std::size_t nbOfElems=getNbOfElems();
8602   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
8603     *ptr=a*(*ptr)+b;
8604   declareAsNew();
8605 }
8606
8607 /*!
8608  * Returns a full copy of \a this array except that sign of all elements is reversed.
8609  *  \return DataArrayInt * - the new instance of DataArrayInt containing the
8610  *          same number of tuples and component as \a this array.
8611  *          The caller is to delete this result array using decrRef() as it is no more
8612  *          needed.
8613  *  \throw If \a this is not allocated.
8614  */
8615 DataArrayInt *DataArrayInt::negate() const throw(INTERP_KERNEL::Exception)
8616 {
8617   checkAllocated();
8618   DataArrayInt *newArr=DataArrayInt::New();
8619   int nbOfTuples=getNumberOfTuples();
8620   int nbOfComp=getNumberOfComponents();
8621   newArr->alloc(nbOfTuples,nbOfComp);
8622   const int *cptr=getConstPointer();
8623   std::transform(cptr,cptr+nbOfTuples*nbOfComp,newArr->getPointer(),std::negate<int>());
8624   newArr->copyStringInfoFrom(*this);
8625   return newArr;
8626 }
8627
8628 /*!
8629  * Modify all elements of \a this array, so that
8630  * an element _x_ becomes \f$ numerator / x \f$.
8631  *  \warning If an exception is thrown because of presence of 0 element in \a this 
8632  *           array, all elements processed before detection of the zero element remain
8633  *           modified.
8634  *  \param [in] numerator - the numerator used to modify array elements.
8635  *  \throw If \a this is not allocated.
8636  *  \throw If there is an element equal to 0 in \a this array.
8637  */
8638 void DataArrayInt::applyInv(int numerator) throw(INTERP_KERNEL::Exception)
8639 {
8640   checkAllocated();
8641   int *ptr=getPointer();
8642   std::size_t nbOfElems=getNbOfElems();
8643   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
8644     {
8645       if(*ptr!=0)
8646         {
8647           *ptr=numerator/(*ptr);
8648         }
8649       else
8650         {
8651           std::ostringstream oss; oss << "DataArrayInt::applyInv : presence of null value in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
8652           oss << " !";
8653           throw INTERP_KERNEL::Exception(oss.str().c_str());
8654         }
8655     }
8656   declareAsNew();
8657 }
8658
8659 /*!
8660  * Modify all elements of \a this array, so that
8661  * an element _x_ becomes \f$ x / val \f$.
8662  *  \param [in] val - the denominator used to modify array elements.
8663  *  \throw If \a this is not allocated.
8664  *  \throw If \a val == 0.
8665  */
8666 void DataArrayInt::applyDivideBy(int val) throw(INTERP_KERNEL::Exception)
8667 {
8668   if(val==0)
8669     throw INTERP_KERNEL::Exception("DataArrayInt::applyDivideBy : Trying to divide by 0 !");
8670   checkAllocated();
8671   int *ptr=getPointer();
8672   std::size_t nbOfElems=getNbOfElems();
8673   std::transform(ptr,ptr+nbOfElems,ptr,std::bind2nd(std::divides<int>(),val));
8674   declareAsNew();
8675 }
8676
8677 /*!
8678  * Modify all elements of \a this array, so that
8679  * an element _x_ becomes  <em> x % val </em>.
8680  *  \param [in] val - the divisor used to modify array elements.
8681  *  \throw If \a this is not allocated.
8682  *  \throw If \a val <= 0.
8683  */
8684 void DataArrayInt::applyModulus(int val) throw(INTERP_KERNEL::Exception)
8685 {
8686   if(val<=0)
8687     throw INTERP_KERNEL::Exception("DataArrayInt::applyDivideBy : Trying to operate modulus on value <= 0 !");
8688   checkAllocated();
8689   int *ptr=getPointer();
8690   std::size_t nbOfElems=getNbOfElems();
8691   std::transform(ptr,ptr+nbOfElems,ptr,std::bind2nd(std::modulus<int>(),val));
8692   declareAsNew();
8693 }
8694
8695 /*!
8696  * This method works only on data array with one component.
8697  * This method returns a newly allocated array storing stored ascendantly tuple ids in \b this so that
8698  * this[*id] in [\b vmin,\b vmax)
8699  * 
8700  * \param [in] vmin begin of range. This value is included in range (included).
8701  * \param [in] vmax end of range. This value is \b not included in range (excluded).
8702  * \return a newly allocated data array that the caller should deal with.
8703  */
8704 DataArrayInt *DataArrayInt::getIdsInRange(int vmin, int vmax) const throw(INTERP_KERNEL::Exception)
8705 {
8706   checkAllocated();
8707   if(getNumberOfComponents()!=1)
8708     throw INTERP_KERNEL::Exception("DataArrayInt::getIdsInRange : this must have exactly one component !");
8709   const int *cptr=getConstPointer();
8710   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(0,1);
8711   int nbOfTuples=getNumberOfTuples();
8712   for(int i=0;i<nbOfTuples;i++,cptr++)
8713     if(*cptr>=vmin && *cptr<vmax)
8714       ret->pushBackSilent(i);
8715   return ret.retn();
8716 }
8717
8718 /*!
8719  * This method works only on data array with one component.
8720  * 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.
8721  * 
8722  * \param [in] vmin begin of range. This value is included in range (included).
8723  * \param [in] vmax end of range. This value is \b not included in range (excluded).
8724  * \return if all ids in \a this are so that (*this)[i]==i for all i in [ 0, \c this->getNumberOfTuples() ).
8725  */
8726 bool DataArrayInt::checkAllIdsInRange(int vmin, int vmax) const throw(INTERP_KERNEL::Exception)
8727 {
8728   checkAllocated();
8729   if(getNumberOfComponents()!=1)
8730     throw INTERP_KERNEL::Exception("DataArrayInt::checkAllIdsInRange : this must have exactly one component !");
8731   int nbOfTuples=getNumberOfTuples();
8732   bool ret=true;
8733   const int *cptr=getConstPointer();
8734   for(int i=0;i<nbOfTuples;i++,cptr++)
8735     {
8736       if(*cptr>=vmin && *cptr<vmax)
8737         { ret=ret && *cptr==i; }
8738       else
8739         {
8740           std::ostringstream oss; oss << "DataArrayInt::checkAllIdsInRange : tuple #" << i << " has value " << *cptr << " should be in [" << vmin << "," << vmax << ") !";
8741           throw INTERP_KERNEL::Exception(oss.str().c_str());
8742         }
8743     }
8744   return ret;
8745 }
8746
8747 /*!
8748  * Modify all elements of \a this array, so that
8749  * an element _x_ becomes <em> val % x </em>.
8750  *  \warning If an exception is thrown because of presence of an element <= 0 in \a this 
8751  *           array, all elements processed before detection of the zero element remain
8752  *           modified.
8753  *  \param [in] val - the divident used to modify array elements.
8754  *  \throw If \a this is not allocated.
8755  *  \throw If there is an element equal to or less than 0 in \a this array.
8756  */
8757 void DataArrayInt::applyRModulus(int val) throw(INTERP_KERNEL::Exception)
8758 {
8759   checkAllocated();
8760   int *ptr=getPointer();
8761   std::size_t nbOfElems=getNbOfElems();
8762   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
8763     {
8764       if(*ptr>0)
8765         {
8766           *ptr=val%(*ptr);
8767         }
8768       else
8769         {
8770           std::ostringstream oss; oss << "DataArrayInt::applyRModulus : presence of value <=0 in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
8771           oss << " !";
8772           throw INTERP_KERNEL::Exception(oss.str().c_str());
8773         }
8774     }
8775   declareAsNew();
8776 }
8777
8778 /*!
8779  * Modify all elements of \a this array, so that
8780  * an element _x_ becomes <em> val ^ x </em>.
8781  *  \param [in] val - the value used to apply pow on all array elements.
8782  *  \throw If \a this is not allocated.
8783  *  \throw If \a val < 0.
8784  */
8785 void DataArrayInt::applyPow(int val) throw(INTERP_KERNEL::Exception)
8786 {
8787   checkAllocated();
8788   if(val<0)
8789     throw INTERP_KERNEL::Exception("DataArrayInt::applyPow : input pow in < 0 !");
8790   int *ptr=getPointer();
8791   std::size_t nbOfElems=getNbOfElems();
8792   if(val==0)
8793     {
8794       std::fill(ptr,ptr+nbOfElems,1.);
8795       return ;
8796     }
8797   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
8798     {
8799       int tmp=1;
8800       for(int j=0;j<val;j++)
8801         tmp*=*ptr;
8802       *ptr=tmp;
8803     }
8804   declareAsNew();
8805 }
8806
8807 /*!
8808  * Modify all elements of \a this array, so that
8809  * an element _x_ becomes \f$ val ^ x \f$.
8810  *  \param [in] val - the value used to apply pow on all array elements.
8811  *  \throw If \a this is not allocated.
8812  *  \throw If there is an element < 0 in \a this array.
8813  *  \warning If an exception is thrown because of presence of 0 element in \a this 
8814  *           array, all elements processed before detection of the zero element remain
8815  *           modified.
8816  */
8817 void DataArrayInt::applyRPow(int val) throw(INTERP_KERNEL::Exception)
8818 {
8819   checkAllocated();
8820   int *ptr=getPointer();
8821   std::size_t nbOfElems=getNbOfElems();
8822   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
8823     {
8824       if(*ptr>=0)
8825         {
8826           int tmp=1;
8827           for(int j=0;j<*ptr;j++)
8828             tmp*=val;
8829           *ptr=tmp;
8830         }
8831       else
8832         {
8833           std::ostringstream oss; oss << "DataArrayInt::applyRPow : presence of negative value in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
8834           oss << " !";
8835           throw INTERP_KERNEL::Exception(oss.str().c_str());
8836         }
8837     }
8838   declareAsNew();
8839 }
8840
8841 /*!
8842  * Returns a new DataArrayInt by aggregating two given arrays, so that (1) the number
8843  * of components in the result array is a sum of the number of components of given arrays
8844  * and (2) the number of tuples in the result array is same as that of each of given
8845  * arrays. In other words the i-th tuple of result array includes all components of
8846  * i-th tuples of all given arrays.
8847  * Number of tuples in the given arrays must be the same.
8848  *  \param [in] a1 - an array to include in the result array.
8849  *  \param [in] a2 - another array to include in the result array.
8850  *  \return DataArrayInt * - the new instance of DataArrayInt.
8851  *          The caller is to delete this result array using decrRef() as it is no more
8852  *          needed.
8853  *  \throw If both \a a1 and \a a2 are NULL.
8854  *  \throw If any given array is not allocated.
8855  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
8856  */
8857 DataArrayInt *DataArrayInt::Meld(const DataArrayInt *a1, const DataArrayInt *a2) throw(INTERP_KERNEL::Exception)
8858 {
8859   std::vector<const DataArrayInt *> arr(2);
8860   arr[0]=a1; arr[1]=a2;
8861   return Meld(arr);
8862 }
8863
8864 /*!
8865  * Returns a new DataArrayInt by aggregating all given arrays, so that (1) the number
8866  * of components in the result array is a sum of the number of components of given arrays
8867  * and (2) the number of tuples in the result array is same as that of each of given
8868  * arrays. In other words the i-th tuple of result array includes all components of
8869  * i-th tuples of all given arrays.
8870  * Number of tuples in the given arrays must be  the same.
8871  *  \param [in] arr - a sequence of arrays to include in the result array.
8872  *  \return DataArrayInt * - the new instance of DataArrayInt.
8873  *          The caller is to delete this result array using decrRef() as it is no more
8874  *          needed.
8875  *  \throw If all arrays within \a arr are NULL.
8876  *  \throw If any given array is not allocated.
8877  *  \throw If getNumberOfTuples() of arrays within \a arr is different.
8878  */
8879 DataArrayInt *DataArrayInt::Meld(const std::vector<const DataArrayInt *>& arr) throw(INTERP_KERNEL::Exception)
8880 {
8881   std::vector<const DataArrayInt *> a;
8882   for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
8883     if(*it4)
8884       a.push_back(*it4);
8885   if(a.empty())
8886     throw INTERP_KERNEL::Exception("DataArrayInt::Meld : array must be NON empty !");
8887   std::vector<const DataArrayInt *>::const_iterator it;
8888   for(it=a.begin();it!=a.end();it++)
8889     (*it)->checkAllocated();
8890   it=a.begin();
8891   int nbOfTuples=(*it)->getNumberOfTuples();
8892   std::vector<int> nbc(a.size());
8893   std::vector<const int *> pts(a.size());
8894   nbc[0]=(*it)->getNumberOfComponents();
8895   pts[0]=(*it++)->getConstPointer();
8896   for(int i=1;it!=a.end();it++,i++)
8897     {
8898       if(nbOfTuples!=(*it)->getNumberOfTuples())
8899         throw INTERP_KERNEL::Exception("DataArrayInt::meld : mismatch of number of tuples !");
8900       nbc[i]=(*it)->getNumberOfComponents();
8901       pts[i]=(*it)->getConstPointer();
8902     }
8903   int totalNbOfComp=std::accumulate(nbc.begin(),nbc.end(),0);
8904   DataArrayInt *ret=DataArrayInt::New();
8905   ret->alloc(nbOfTuples,totalNbOfComp);
8906   int *retPtr=ret->getPointer();
8907   for(int i=0;i<nbOfTuples;i++)
8908     for(int j=0;j<(int)a.size();j++)
8909       {
8910         retPtr=std::copy(pts[j],pts[j]+nbc[j],retPtr);
8911         pts[j]+=nbc[j];
8912       }
8913   int k=0;
8914   for(int i=0;i<(int)a.size();i++)
8915     for(int j=0;j<nbc[i];j++,k++)
8916       ret->setInfoOnComponent(k,a[i]->getInfoOnComponent(j).c_str());
8917   return ret;
8918 }
8919
8920 /*!
8921  * Returns a new DataArrayInt which is a minimal partition of elements of \a groups.
8922  * The i-th item of the result array is an ID of a set of elements belonging to a
8923  * unique set of groups, which the i-th element is a part of. This set of elements
8924  * belonging to a unique set of groups is called \a family, so the result array contains
8925  * IDs of families each element belongs to.
8926  *
8927  * \b Example: if we have two groups of elements: \a group1 [0,4] and \a group2 [ 0,1,2 ],
8928  * then there are 3 families:
8929  * - \a family1 (with ID 1) contains element [0] belonging to ( \a group1 + \a group2 ),
8930  * - \a family2 (with ID 2) contains elements [4] belonging to ( \a group1 ),
8931  * - \a family3 (with ID 3) contains element [1,2] belonging to ( \a group2 ), <br>
8932  * and the result array contains IDs of families [ 1,3,3,0,2 ]. <br> Note a family ID 0 which
8933  * stands for the element #3 which is in none of groups.
8934  *
8935  *  \param [in] groups - sequence of groups of element IDs.
8936  *  \param [in] newNb - total number of elements; it must be more than max ID of element
8937  *         in \a groups.
8938  *  \param [out] fidsOfGroups - IDs of families the elements of each group belong to.
8939  *  \return DataArrayInt * - a new instance of DataArrayInt containing IDs of families
8940  *         each element with ID from range [0, \a newNb ) belongs to. The caller is to
8941  *         delete this array using decrRef() as it is no more needed.
8942  *  \throw If any element ID in \a groups violates condition ( 0 <= ID < \a newNb ).
8943  */
8944 DataArrayInt *DataArrayInt::MakePartition(const std::vector<const DataArrayInt *>& groups, int newNb, std::vector< std::vector<int> >& fidsOfGroups) throw(INTERP_KERNEL::Exception)
8945 {
8946   std::vector<const DataArrayInt *> groups2;
8947   for(std::vector<const DataArrayInt *>::const_iterator it4=groups.begin();it4!=groups.end();it4++)
8948     if(*it4)
8949       groups2.push_back(*it4);
8950   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
8951   ret->alloc(newNb,1);
8952   int *retPtr=ret->getPointer();
8953   std::fill(retPtr,retPtr+newNb,0);
8954   int fid=1;
8955   for(std::vector<const DataArrayInt *>::const_iterator iter=groups2.begin();iter!=groups2.end();iter++)
8956     {
8957       const int *ptr=(*iter)->getConstPointer();
8958       std::size_t nbOfElem=(*iter)->getNbOfElems();
8959       int sfid=fid;
8960       for(int j=0;j<sfid;j++)
8961         {
8962           bool found=false;
8963           for(std::size_t i=0;i<nbOfElem;i++)
8964             {
8965               if(ptr[i]>=0 && ptr[i]<newNb)
8966                 {
8967                   if(retPtr[ptr[i]]==j)
8968                     {
8969                       retPtr[ptr[i]]=fid;
8970                       found=true;
8971                     }
8972                 }
8973               else
8974                 {
8975                   std::ostringstream oss; oss << "DataArrayInt::MakePartition : In group \"" << (*iter)->getName() << "\" in tuple #" << i << " value = " << ptr[i] << " ! Should be in [0," << newNb;
8976                   oss << ") !";
8977                   throw INTERP_KERNEL::Exception(oss.str().c_str());
8978                 }
8979             }
8980           if(found)
8981             fid++;
8982         }
8983     }
8984   fidsOfGroups.clear();
8985   fidsOfGroups.resize(groups2.size());
8986   int grId=0;
8987   for(std::vector<const DataArrayInt *>::const_iterator iter=groups2.begin();iter!=groups2.end();iter++,grId++)
8988     {
8989       std::set<int> tmp;
8990       const int *ptr=(*iter)->getConstPointer();
8991       std::size_t nbOfElem=(*iter)->getNbOfElems();
8992       for(const int *p=ptr;p!=ptr+nbOfElem;p++)
8993         tmp.insert(retPtr[*p]);
8994       fidsOfGroups[grId].insert(fidsOfGroups[grId].end(),tmp.begin(),tmp.end());
8995     }
8996   return ret.retn();
8997 }
8998
8999 /*!
9000  * Returns a new DataArrayInt which contains all elements of given one-dimensional
9001  * arrays. The result array does not contain any duplicates and its values
9002  * are sorted in ascending order.
9003  *  \param [in] arr - sequence of DataArrayInt's to unite.
9004  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
9005  *         array using decrRef() as it is no more needed.
9006  *  \throw If any \a arr[i] is not allocated.
9007  *  \throw If \a arr[i]->getNumberOfComponents() != 1.
9008  */
9009 DataArrayInt *DataArrayInt::BuildUnion(const std::vector<const DataArrayInt *>& arr) throw(INTERP_KERNEL::Exception)
9010 {
9011   std::vector<const DataArrayInt *> a;
9012   for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
9013     if(*it4)
9014       a.push_back(*it4);
9015   for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
9016     {
9017       (*it)->checkAllocated();
9018       if((*it)->getNumberOfComponents()!=1)
9019         throw INTERP_KERNEL::Exception("DataArrayInt::BuildUnion : only single component allowed !");
9020     }
9021   //
9022   std::set<int> r;
9023   for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
9024     {
9025       const int *pt=(*it)->getConstPointer();
9026       int nbOfTuples=(*it)->getNumberOfTuples();
9027       r.insert(pt,pt+nbOfTuples);
9028     }
9029   DataArrayInt *ret=DataArrayInt::New();
9030   ret->alloc((int)r.size(),1);
9031   std::copy(r.begin(),r.end(),ret->getPointer());
9032   return ret;
9033 }
9034
9035 /*!
9036  * Returns a new DataArrayInt which contains elements present in each of given one-dimensional
9037  * arrays. The result array does not contain any duplicates and its values
9038  * are sorted in ascending order.
9039  *  \param [in] arr - sequence of DataArrayInt's to intersect.
9040  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
9041  *         array using decrRef() as it is no more needed.
9042  *  \throw If any \a arr[i] is not allocated.
9043  *  \throw If \a arr[i]->getNumberOfComponents() != 1.
9044  */
9045 DataArrayInt *DataArrayInt::BuildIntersection(const std::vector<const DataArrayInt *>& arr) throw(INTERP_KERNEL::Exception)
9046 {
9047   std::vector<const DataArrayInt *> a;
9048   for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
9049     if(*it4)
9050       a.push_back(*it4);
9051   for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
9052     {
9053       (*it)->checkAllocated();
9054       if((*it)->getNumberOfComponents()!=1)
9055         throw INTERP_KERNEL::Exception("DataArrayInt::BuildIntersection : only single component allowed !");
9056     }
9057   //
9058   std::set<int> r;
9059   for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
9060     {
9061       const int *pt=(*it)->getConstPointer();
9062       int nbOfTuples=(*it)->getNumberOfTuples();
9063       std::set<int> s1(pt,pt+nbOfTuples);
9064       if(it!=a.begin())
9065         {
9066           std::set<int> r2;
9067           std::set_intersection(r.begin(),r.end(),s1.begin(),s1.end(),inserter(r2,r2.end()));
9068           r=r2;
9069         }
9070       else
9071         r=s1;
9072     }
9073   DataArrayInt *ret=DataArrayInt::New();
9074   ret->alloc((int)r.size(),1);
9075   std::copy(r.begin(),r.end(),ret->getPointer());
9076   return ret;
9077 }
9078
9079 /*!
9080  * Returns a new DataArrayInt which contains a complement of elements of \a this
9081  * one-dimensional array. I.e. the result array contains all elements from the range [0,
9082  * \a nbOfElement) not present in \a this array.
9083  *  \param [in] nbOfElement - maximal size of the result array.
9084  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
9085  *         array using decrRef() as it is no more needed.
9086  *  \throw If \a this is not allocated.
9087  *  \throw If \a this->getNumberOfComponents() != 1.
9088  *  \throw If any element \a x of \a this array violates condition ( 0 <= \a x < \a
9089  *         nbOfElement ).
9090  */
9091 DataArrayInt *DataArrayInt::buildComplement(int nbOfElement) const throw(INTERP_KERNEL::Exception)
9092 {
9093    checkAllocated();
9094    if(getNumberOfComponents()!=1)
9095      throw INTERP_KERNEL::Exception("DataArrayInt::buildComplement : only single component allowed !");
9096    std::vector<bool> tmp(nbOfElement);
9097    const int *pt=getConstPointer();
9098    int nbOfTuples=getNumberOfTuples();
9099    for(const int *w=pt;w!=pt+nbOfTuples;w++)
9100      if(*w>=0 && *w<nbOfElement)
9101        tmp[*w]=true;
9102      else
9103        throw INTERP_KERNEL::Exception("DataArrayInt::buildComplement : an element is not in valid range : [0,nbOfElement) !");
9104    int nbOfRetVal=(int)std::count(tmp.begin(),tmp.end(),false);
9105    DataArrayInt *ret=DataArrayInt::New();
9106    ret->alloc(nbOfRetVal,1);
9107    int j=0;
9108    int *retPtr=ret->getPointer();
9109    for(int i=0;i<nbOfElement;i++)
9110      if(!tmp[i])
9111        retPtr[j++]=i;
9112    return ret;
9113 }
9114
9115 /*!
9116  * Returns a new DataArrayInt containing elements of \a this one-dimensional missing
9117  * from an \a other one-dimensional array.
9118  *  \param [in] other - a DataArrayInt containing elements not to include in the result array.
9119  *  \return DataArrayInt * - a new instance of DataArrayInt with one component. The
9120  *         caller is to delete this array using decrRef() as it is no more needed.
9121  *  \throw If \a other is NULL.
9122  *  \throw If \a other is not allocated.
9123  *  \throw If \a other->getNumberOfComponents() != 1.
9124  *  \throw If \a this is not allocated.
9125  *  \throw If \a this->getNumberOfComponents() != 1.
9126  *  \sa DataArrayInt::buildSubstractionOptimized()
9127  */
9128 DataArrayInt *DataArrayInt::buildSubstraction(const DataArrayInt *other) const throw(INTERP_KERNEL::Exception)
9129 {
9130   if(!other)
9131     throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstraction : DataArrayInt pointer in input is NULL !");
9132   checkAllocated();
9133   other->checkAllocated();
9134   if(getNumberOfComponents()!=1)
9135      throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstraction : only single component allowed !");
9136   if(other->getNumberOfComponents()!=1)
9137      throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstraction : only single component allowed for other type !");
9138   const int *pt=getConstPointer();
9139   int nbOfTuples=getNumberOfTuples();
9140   std::set<int> s1(pt,pt+nbOfTuples);
9141   pt=other->getConstPointer();
9142   nbOfTuples=other->getNumberOfTuples();
9143   std::set<int> s2(pt,pt+nbOfTuples);
9144   std::vector<int> r;
9145   std::set_difference(s1.begin(),s1.end(),s2.begin(),s2.end(),std::back_insert_iterator< std::vector<int> >(r));
9146   DataArrayInt *ret=DataArrayInt::New();
9147   ret->alloc((int)r.size(),1);
9148   std::copy(r.begin(),r.end(),ret->getPointer());
9149   return ret;
9150 }
9151
9152 /*!
9153  * \a this is expected to have one component and to be sorted ascendingly (as for \a other).
9154  * \a other is expected to be a part of \a this. If not DataArrayInt::buildSubstraction should be called instead.
9155  * 
9156  * \param [in] other an array with one component and expected to be sorted ascendingly.
9157  * \ret list of ids in \a this but not in \a other.
9158  * \sa DataArrayInt::buildSubstraction
9159  */
9160 DataArrayInt *DataArrayInt::buildSubstractionOptimized(const DataArrayInt *other) const throw(INTERP_KERNEL::Exception)
9161 {
9162   static const char *MSG="DataArrayInt::buildSubstractionOptimized : only single component allowed !";
9163   if(!other) throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstractionOptimized : NULL input array !");
9164   checkAllocated(); other->checkAllocated();
9165   if(getNumberOfComponents()!=1) throw INTERP_KERNEL::Exception(MSG);
9166   if(other->getNumberOfComponents()!=1) throw INTERP_KERNEL::Exception(MSG);
9167   const int *pt1Bg(begin()),*pt1End(end()),*pt2Bg(other->begin()),*pt2End(other->end()),*work1(pt1Bg),*work2(pt2Bg);
9168   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
9169   for(;work1!=pt1End;work1++)
9170     {
9171       if(work2!=pt2End && *work1==*work2)
9172         work2++;
9173       else
9174         ret->pushBackSilent(*work1);
9175     }
9176   return ret.retn();
9177 }
9178
9179
9180 /*!
9181  * Returns a new DataArrayInt which contains all elements of \a this and a given
9182  * one-dimensional arrays. The result array does not contain any duplicates
9183  * and its values are sorted in ascending order.
9184  *  \param [in] other - an array to unite with \a this one.
9185  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
9186  *         array using decrRef() as it is no more needed.
9187  *  \throw If \a this or \a other is not allocated.
9188  *  \throw If \a this->getNumberOfComponents() != 1.
9189  *  \throw If \a other->getNumberOfComponents() != 1.
9190  */
9191 DataArrayInt *DataArrayInt::buildUnion(const DataArrayInt *other) const throw(INTERP_KERNEL::Exception)
9192 {
9193   std::vector<const DataArrayInt *>arrs(2);
9194   arrs[0]=this; arrs[1]=other;
9195   return BuildUnion(arrs);
9196 }
9197
9198
9199 /*!
9200  * Returns a new DataArrayInt which contains elements present in both \a this and a given
9201  * one-dimensional arrays. The result array does not contain any duplicates
9202  * and its values are sorted in ascending order.
9203  *  \param [in] other - an array to intersect with \a this one.
9204  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
9205  *         array using decrRef() as it is no more needed.
9206  *  \throw If \a this or \a other is not allocated.
9207  *  \throw If \a this->getNumberOfComponents() != 1.
9208  *  \throw If \a other->getNumberOfComponents() != 1.
9209  */
9210 DataArrayInt *DataArrayInt::buildIntersection(const DataArrayInt *other) const throw(INTERP_KERNEL::Exception)
9211 {
9212   std::vector<const DataArrayInt *>arrs(2);
9213   arrs[0]=this; arrs[1]=other;
9214   return BuildIntersection(arrs);
9215 }
9216
9217 /*!
9218  * This method can be applied on allocated with one component DataArrayInt instance.
9219  * This method is typically relevant for sorted arrays. All consecutive duplicated items in \a this will appear only once in returned DataArrayInt instance.
9220  * 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]
9221  * 
9222  * \return a newly allocated array that contain the result of the unique operation applied on \a this.
9223  * \throw if \a this is not allocated or if \a this has not exactly one component.
9224  */
9225 DataArrayInt *DataArrayInt::buildUnique() const throw(INTERP_KERNEL::Exception)
9226 {
9227   checkAllocated();
9228   if(getNumberOfComponents()!=1)
9229      throw INTERP_KERNEL::Exception("DataArrayInt::buildUnique : only single component allowed !");
9230   int nbOfTuples=getNumberOfTuples();
9231   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp=deepCpy();
9232   int *data=tmp->getPointer();
9233   int *last=std::unique(data,data+nbOfTuples);
9234   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
9235   ret->alloc(std::distance(data,last),1);
9236   std::copy(data,last,ret->getPointer());
9237   return ret.retn();
9238 }
9239
9240 /*!
9241  * Returns a new DataArrayInt which contains size of every of groups described by \a this
9242  * "index" array. Such "index" array is returned for example by 
9243  * \ref ParaMEDMEM::MEDCouplingUMesh::buildDescendingConnectivity
9244  * "MEDCouplingUMesh::buildDescendingConnectivity" and
9245  * \ref ParaMEDMEM::MEDCouplingUMesh::getNodalConnectivityIndex
9246  * "MEDCouplingUMesh::getNodalConnectivityIndex" etc.
9247  * This method preforms the reverse operation of DataArrayInt::computeOffsets2.
9248  *  \return DataArrayInt * - a new instance of DataArrayInt, whose number of tuples
9249  *          equals to \a this->getNumberOfComponents() - 1, and number of components is 1.
9250  *          The caller is to delete this array using decrRef() as it is no more needed. 
9251  *  \throw If \a this is not allocated.
9252  *  \throw If \a this->getNumberOfComponents() != 1.
9253  *  \throw If \a this->getNumberOfTuples() < 2.
9254  *
9255  *  \b Example: <br> 
9256  *         - this contains [1,3,6,7,7,9,15]
9257  *         - result array contains [2,3,1,0,2,6],
9258  *          where 2 = 3 - 1, 3 = 6 - 3, 1 = 7 - 6 etc.
9259  *
9260  * \sa DataArrayInt::computeOffsets2
9261  */
9262 DataArrayInt *DataArrayInt::deltaShiftIndex() const throw(INTERP_KERNEL::Exception)
9263 {
9264   checkAllocated();
9265   if(getNumberOfComponents()!=1)
9266      throw INTERP_KERNEL::Exception("DataArrayInt::deltaShiftIndex : only single component allowed !");
9267   int nbOfTuples=getNumberOfTuples();
9268   if(nbOfTuples<2)
9269     throw INTERP_KERNEL::Exception("DataArrayInt::deltaShiftIndex : 1 tuple at least must be present in 'this' !");
9270   const int *ptr=getConstPointer();
9271   DataArrayInt *ret=DataArrayInt::New();
9272   ret->alloc(nbOfTuples-1,1);
9273   int *out=ret->getPointer();
9274   std::transform(ptr+1,ptr+nbOfTuples,ptr,out,std::minus<int>());
9275   return ret;
9276 }
9277
9278 /*!
9279  * Modifies \a this one-dimensional array so that value of each element \a x
9280  * of \a this array (\a a) is computed as \f$ x_i = \sum_{j=0}^{i-1} a[ j ] \f$.
9281  * Or: for each i>0 new[i]=new[i-1]+old[i-1] for i==0 new[i]=0. Number of tuples
9282  * and components remains the same.<br>
9283  * This method is useful for allToAllV in MPI with contiguous policy. This method
9284  * differs from computeOffsets2() in that the number of tuples is \b not changed by
9285  * this one.
9286  *  \throw If \a this is not allocated.
9287  *  \throw If \a this->getNumberOfComponents() != 1.
9288  *
9289  *  \b Example: <br>
9290  *          - Before \a this contains [3,5,1,2,0,8]
9291  *          - After \a this contains  [0,3,8,9,11,11]<br>
9292  *          Note that the last element 19 = 11 + 8 is missing because size of \a this
9293  *          array is retained and thus there is no space to store the last element.
9294  */
9295 void DataArrayInt::computeOffsets() throw(INTERP_KERNEL::Exception)
9296 {
9297   checkAllocated();
9298   if(getNumberOfComponents()!=1)
9299      throw INTERP_KERNEL::Exception("DataArrayInt::computeOffsets : only single component allowed !");
9300   int nbOfTuples=getNumberOfTuples();
9301   if(nbOfTuples==0)
9302     return ;
9303   int *work=getPointer();
9304   int tmp=work[0];
9305   work[0]=0;
9306   for(int i=1;i<nbOfTuples;i++)
9307     {
9308       int tmp2=work[i];
9309       work[i]=work[i-1]+tmp;
9310       tmp=tmp2;
9311     }
9312   declareAsNew();
9313 }
9314
9315
9316 /*!
9317  * Modifies \a this one-dimensional array so that value of each element \a x
9318  * of \a this array (\a a) is computed as \f$ x_i = \sum_{j=0}^{i-1} a[ j ] \f$.
9319  * Or: for each i>0 new[i]=new[i-1]+old[i-1] for i==0 new[i]=0. Number
9320  * components remains the same and number of tuples is inceamented by one.<br>
9321  * This method is useful for allToAllV in MPI with contiguous policy. This method
9322  * differs from computeOffsets() in that the number of tuples is changed by this one.
9323  * This method preforms the reverse operation of DataArrayInt::deltaShiftIndex.
9324  *  \throw If \a this is not allocated.
9325  *  \throw If \a this->getNumberOfComponents() != 1.
9326  *
9327  *  \b Example: <br>
9328  *          - Before \a this contains [3,5,1,2,0,8]
9329  *          - After \a this contains  [0,3,8,9,11,11,19]<br>
9330  * \sa DataArrayInt::deltaShiftIndex
9331  */
9332 void DataArrayInt::computeOffsets2() throw(INTERP_KERNEL::Exception)
9333 {
9334   checkAllocated();
9335   if(getNumberOfComponents()!=1)
9336     throw INTERP_KERNEL::Exception("DataArrayInt::computeOffsets2 : only single component allowed !");
9337   int nbOfTuples=getNumberOfTuples();
9338   int *ret=(int *)malloc((nbOfTuples+1)*sizeof(int));
9339   if(nbOfTuples==0)
9340     return ;
9341   const int *work=getConstPointer();
9342   ret[0]=0;
9343   for(int i=0;i<nbOfTuples;i++)
9344     ret[i+1]=work[i]+ret[i];
9345   useArray(ret,true,C_DEALLOC,nbOfTuples+1,1);
9346   declareAsNew();
9347 }
9348
9349 /*!
9350  * Returns two new DataArrayInt instances whose contents is computed from that of \a this and \a listOfIds arrays as follows.
9351  * \a this is expected to be an offset format ( as returned by DataArrayInt::computeOffsets2 ) that is to say with one component
9352  * and ** sorted strictly increasingly **. \a listOfIds is expected to be sorted ascendingly (not strictly needed for \a listOfIds).
9353  * This methods searches in \a this, considered as a set of contiguous \c this->getNumberOfComponents() ranges, all ids in \a listOfIds
9354  * filling completely one of the ranges in \a this.
9355  *
9356  * \param [in] listOfIds a list of ids that has to be sorted ascendingly.
9357  * \param [out] rangeIdsFetched the range ids fetched
9358  * \param [out] idsInInputListThatFetch contains the list of ids in \a listOfIds that are \b fully included in a range in \a this. So
9359  *              \a idsInInputListThatFetch is a part of input \a listOfIds.
9360  *
9361  * \sa DataArrayInt::computeOffsets2
9362  *
9363  *  \b Example: <br>
9364  *          - \a this : [0,3,7,9,15,18]
9365  *          - \a listOfIds contains  [0,1,2,3,7,8,15,16,17]
9366  *          - \a rangeIdsFetched result array: [0,2,4]
9367  *          - \a idsInInputListThatFetch result array: [0,1,2,7,8,15,16,17]
9368  * In this example id 3 in input \a listOfIds is alone so it do not appear in output \a idsInInputListThatFetch.
9369  * <br>
9370  */
9371 void DataArrayInt::searchRangesInListOfIds(const DataArrayInt *listOfIds, DataArrayInt *& rangeIdsFetched, DataArrayInt *& idsInInputListThatFetch) const throw(INTERP_KERNEL::Exception)
9372 {
9373   if(!listOfIds)
9374     throw INTERP_KERNEL::Exception("DataArrayInt::searchRangesInListOfIds : input list of ids is null !");
9375   listOfIds->checkAllocated(); checkAllocated();
9376   if(listOfIds->getNumberOfComponents()!=1)
9377     throw INTERP_KERNEL::Exception("DataArrayInt::searchRangesInListOfIds : input list of ids must have exactly one component !");
9378   if(getNumberOfComponents()!=1)
9379     throw INTERP_KERNEL::Exception("DataArrayInt::searchRangesInListOfIds : this must have exactly one component !");
9380   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret0=DataArrayInt::New(); ret0->alloc(0,1);
9381   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret1=DataArrayInt::New(); ret1->alloc(0,1);
9382   const int *tupEnd(listOfIds->end()),*offBg(begin()),*offEnd(end()-1);
9383   const int *tupPtr(listOfIds->begin()),*offPtr(offBg);
9384   while(tupPtr!=tupEnd && offPtr!=offEnd)
9385     {
9386       if(*tupPtr==*offPtr)
9387         {
9388           int i=offPtr[0];
9389           while(i<offPtr[1] && *tupPtr==i && tupPtr!=tupEnd) { i++; tupPtr++; }
9390           if(i==offPtr[1])
9391             {
9392               ret0->pushBackSilent((int)std::distance(offBg,offPtr));
9393               ret1->pushBackValsSilent(tupPtr-(offPtr[1]-offPtr[0]),tupPtr);
9394               offPtr++;
9395             }
9396         }
9397       else
9398         { if(*tupPtr<*offPtr) tupPtr++; else offPtr++; }
9399     }
9400   rangeIdsFetched=ret0.retn();
9401   idsInInputListThatFetch=ret1.retn();
9402 }
9403
9404 /*!
9405  * Returns a new DataArrayInt whose contents is computed from that of \a this and \a
9406  * offsets arrays as follows. \a offsets is a one-dimensional array considered as an
9407  * "index" array of a "iota" array, thus, whose each element gives an index of a group
9408  * beginning within the "iota" array. And \a this is a one-dimensional array
9409  * considered as a selector of groups described by \a offsets to include into the result array.
9410  *  \throw If \a offsets is NULL.
9411  *  \throw If \a offsets is not allocated.
9412  *  \throw If \a offsets->getNumberOfComponents() != 1.
9413  *  \throw If \a offsets is not monotonically increasing.
9414  *  \throw If \a this is not allocated.
9415  *  \throw If \a this->getNumberOfComponents() != 1.
9416  *  \throw If any element of \a this is not a valid index for \a offsets array.
9417  *
9418  *  \b Example: <br>
9419  *          - \a this: [0,2,3]
9420  *          - \a offsets: [0,3,6,10,14,20]
9421  *          - result array: [0,1,2,6,7,8,9,10,11,12,13] == <br>
9422  *            \c range(0,3) + \c range(6,10) + \c range(10,14) ==<br>
9423  *            \c range( \a offsets[ \a this[0] ], offsets[ \a this[0]+1 ]) + 
9424  *            \c range( \a offsets[ \a this[1] ], offsets[ \a this[1]+1 ]) + 
9425  *            \c range( \a offsets[ \a this[2] ], offsets[ \a this[2]+1 ])
9426  */
9427 DataArrayInt *DataArrayInt::buildExplicitArrByRanges(const DataArrayInt *offsets) const throw(INTERP_KERNEL::Exception)
9428 {
9429   if(!offsets)
9430     throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrByRanges : DataArrayInt pointer in input is NULL !");
9431   checkAllocated();
9432   if(getNumberOfComponents()!=1)
9433      throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrByRanges : only single component allowed !");
9434   offsets->checkAllocated();
9435   if(offsets->getNumberOfComponents()!=1)
9436      throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrByRanges : input array should have only single component !");
9437   int othNbTuples=offsets->getNumberOfTuples()-1;
9438   int nbOfTuples=getNumberOfTuples();
9439   int retNbOftuples=0;
9440   const int *work=getConstPointer();
9441   const int *offPtr=offsets->getConstPointer();
9442   for(int i=0;i<nbOfTuples;i++)
9443     {
9444       int val=work[i];
9445       if(val>=0 && val<othNbTuples)
9446         {
9447           int delta=offPtr[val+1]-offPtr[val];
9448           if(delta>=0)
9449             retNbOftuples+=delta;
9450           else
9451             {
9452               std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrByRanges : Tuple #" << val << " of offset array has a delta < 0 !";
9453               throw INTERP_KERNEL::Exception(oss.str().c_str());
9454             }
9455         }
9456       else
9457         {
9458           std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrByRanges : Tuple #" << i << " in this contains " << val;
9459           oss << " whereas offsets array is of size " << othNbTuples+1 << " !";
9460           throw INTERP_KERNEL::Exception(oss.str().c_str());
9461         }
9462     }
9463   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
9464   ret->alloc(retNbOftuples,1);
9465   int *retPtr=ret->getPointer();
9466   for(int i=0;i<nbOfTuples;i++)
9467     {
9468       int val=work[i];
9469       int start=offPtr[val];
9470       int off=offPtr[val+1]-start;
9471       for(int j=0;j<off;j++,retPtr++)
9472         *retPtr=start+j;
9473     }
9474   return ret.retn();
9475 }
9476
9477 /*!
9478  * 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.
9479  * 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
9480  * in tuple **i** of returned DataArrayInt.
9481  * If ranges overlapped (in theory it should not) this method do not detect it and always returns the first range.
9482  *
9483  * 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)]
9484  * The return DataArrayInt will contain : **[0,4,1,2,2,3]**
9485  * 
9486  * \param [in] ranges typically come from output of MEDCouplingUMesh::ComputeRangesFromTypeDistribution. Each range is specified like this : 1st component is
9487  *             for lower value included and 2nd component is the upper value of corresponding range **excluded**.
9488  * \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
9489  *        is thrown if no ranges in \a ranges contains value in \a this.
9490  * 
9491  * \sa DataArrayInt::findIdInRangeForEachTuple
9492  */
9493 DataArrayInt *DataArrayInt::findRangeIdForEachTuple(const DataArrayInt *ranges) const throw(INTERP_KERNEL::Exception)
9494 {
9495   if(!ranges)
9496     throw INTERP_KERNEL::Exception("DataArrayInt::findRangeIdForEachTuple : null input pointer !");
9497   if(ranges->getNumberOfComponents()!=2)
9498     throw INTERP_KERNEL::Exception("DataArrayInt::findRangeIdForEachTuple : input DataArrayInt instance should have 2 components !");
9499   checkAllocated();
9500   if(getNumberOfComponents()!=1)
9501     throw INTERP_KERNEL::Exception("DataArrayInt::findRangeIdForEachTuple : this should have only one component !");
9502   int nbTuples=getNumberOfTuples();
9503   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbTuples,1);
9504   int nbOfRanges=ranges->getNumberOfTuples();
9505   const int *rangesPtr=ranges->getConstPointer();
9506   int *retPtr=ret->getPointer();
9507   const int *inPtr=getConstPointer();
9508   for(int i=0;i<nbTuples;i++,retPtr++)
9509     {
9510       int val=inPtr[i];
9511       bool found=false;
9512       for(int j=0;j<nbOfRanges && !found;j++)
9513         if(val>=rangesPtr[2*j] && val<rangesPtr[2*j+1])
9514           { *retPtr=j; found=true; }
9515       if(found)
9516         continue;
9517       else
9518         {
9519           std::ostringstream oss; oss << "DataArrayInt::findRangeIdForEachTuple : tuple #" << i << " not found by any ranges !";
9520           throw INTERP_KERNEL::Exception(oss.str().c_str());
9521         }
9522     }
9523   return ret.retn();
9524 }
9525
9526 /*!
9527  * 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.
9528  * 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
9529  * in tuple **i** of returned DataArrayInt.
9530  * If ranges overlapped (in theory it should not) this method do not detect it and always returns the sub position of the first range.
9531  *
9532  * 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)]
9533  * The return DataArrayInt will contain : **[1,2,4,0,2,2]**
9534  * This method is often called in pair with DataArrayInt::findRangeIdForEachTuple method.
9535  * 
9536  * \param [in] ranges typically come from output of MEDCouplingUMesh::ComputeRangesFromTypeDistribution. Each range is specified like this : 1st component is
9537  *             for lower value included and 2nd component is the upper value of corresponding range **excluded**.
9538  * \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
9539  *        is thrown if no ranges in \a ranges contains value in \a this.
9540  * \sa DataArrayInt::findRangeIdForEachTuple
9541  */
9542 DataArrayInt *DataArrayInt::findIdInRangeForEachTuple(const DataArrayInt *ranges) const throw(INTERP_KERNEL::Exception)
9543 {
9544   if(!ranges)
9545     throw INTERP_KERNEL::Exception("DataArrayInt::findIdInRangeForEachTuple : null input pointer !");
9546   if(ranges->getNumberOfComponents()!=2)
9547     throw INTERP_KERNEL::Exception("DataArrayInt::findIdInRangeForEachTuple : input DataArrayInt instance should have 2 components !");
9548   checkAllocated();
9549   if(getNumberOfComponents()!=1)
9550     throw INTERP_KERNEL::Exception("DataArrayInt::findIdInRangeForEachTuple : this should have only one component !");
9551   int nbTuples=getNumberOfTuples();
9552   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbTuples,1);
9553   int nbOfRanges=ranges->getNumberOfTuples();
9554   const int *rangesPtr=ranges->getConstPointer();
9555   int *retPtr=ret->getPointer();
9556   const int *inPtr=getConstPointer();
9557   for(int i=0;i<nbTuples;i++,retPtr++)
9558     {
9559       int val=inPtr[i];
9560       bool found=false;
9561       for(int j=0;j<nbOfRanges && !found;j++)
9562         if(val>=rangesPtr[2*j] && val<rangesPtr[2*j+1])
9563           { *retPtr=val-rangesPtr[2*j]; found=true; }
9564       if(found)
9565         continue;
9566       else
9567         {
9568           std::ostringstream oss; oss << "DataArrayInt::findIdInRangeForEachTuple : tuple #" << i << " not found by any ranges !";
9569           throw INTERP_KERNEL::Exception(oss.str().c_str());
9570         }
9571     }
9572   return ret.retn();
9573 }
9574
9575 /*!
9576  * 
9577  * \param [in] nbTimes specifies the nb of times each tuples in \a this will be duplicated contiguouly in returned DataArrayInt instance.
9578  *             \a nbTimes  should be at least equal to 1.
9579  * \return a newly allocated DataArrayInt having one component and number of tuples equal to \a nbTimes * \c this->getNumberOfTuples.
9580  * \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.
9581  */
9582 DataArrayInt *DataArrayInt::duplicateEachTupleNTimes(int nbTimes) const throw(INTERP_KERNEL::Exception)
9583 {
9584   checkAllocated();
9585   if(getNumberOfComponents()!=1)
9586     throw INTERP_KERNEL::Exception("DataArrayInt::duplicateEachTupleNTimes : this should have only one component !");
9587   if(nbTimes<1)
9588     throw INTERP_KERNEL::Exception("DataArrayInt::duplicateEachTupleNTimes : nb times should be >= 1 !");
9589   int nbTuples=getNumberOfTuples();
9590   const int *inPtr=getConstPointer();
9591   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbTimes*nbTuples,1);
9592   int *retPtr=ret->getPointer();
9593   for(int i=0;i<nbTuples;i++,inPtr++)
9594     {
9595       int val=*inPtr;
9596       for(int j=0;j<nbTimes;j++,retPtr++)
9597         *retPtr=val;
9598     }
9599   ret->copyStringInfoFrom(*this);
9600   return ret.retn();
9601 }
9602
9603 /*!
9604  * This method returns all different values found in \a this. This method throws if \a this has not been allocated.
9605  * But the number of components can be different from one.
9606  * \return a newly allocated array (that should be dealt by the caller) containing different values in \a this.
9607  */
9608 DataArrayInt *DataArrayInt::getDifferentValues() const throw(INTERP_KERNEL::Exception)
9609 {
9610   checkAllocated();
9611   std::set<int> ret;
9612   ret.insert(begin(),end());
9613   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret2=DataArrayInt::New(); ret2->alloc((int)ret.size(),1);
9614   std::copy(ret.begin(),ret.end(),ret2->getPointer());
9615   return ret2.retn();
9616 }
9617
9618 /*!
9619  * This method is a refinement of DataArrayInt::getDifferentValues because it returns not only different values in \a this but also, for each of
9620  * them it tells which tuple id have this id.
9621  * This method works only on arrays with one component (if it is not the case call DataArrayInt::rearrange(1) ).
9622  * This method returns two arrays having same size.
9623  * 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.
9624  * 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]]
9625  */
9626 std::vector<DataArrayInt *> DataArrayInt::partitionByDifferentValues(std::vector<int>& differentIds) const throw(INTERP_KERNEL::Exception)
9627 {
9628   checkAllocated();
9629   if(getNumberOfComponents()!=1)
9630     throw INTERP_KERNEL::Exception("DataArrayInt::partitionByDifferentValues : this should have only one component !");
9631   int id=0;
9632   std::map<int,int> m,m2,m3;
9633   for(const int *w=begin();w!=end();w++)
9634     m[*w]++;
9635   differentIds.resize(m.size());
9636   std::vector<DataArrayInt *> ret(m.size());
9637   std::vector<int *> retPtr(m.size());
9638   for(std::map<int,int>::const_iterator it=m.begin();it!=m.end();it++,id++)
9639     {
9640       m2[(*it).first]=id;
9641       ret[id]=DataArrayInt::New();
9642       ret[id]->alloc((*it).second,1);
9643       retPtr[id]=ret[id]->getPointer();
9644       differentIds[id]=(*it).first;
9645     }
9646   id=0;
9647   for(const int *w=begin();w!=end();w++,id++)
9648     {
9649       retPtr[m2[*w]][m3[*w]++]=id;
9650     }
9651   return ret;
9652 }
9653
9654 /*!
9655  * Returns a new DataArrayInt that is a sum of two given arrays. There are 3
9656  * valid cases.
9657  * 1.  The arrays have same number of tuples and components. Then each value of
9658  *   the result array (_a_) is a sum of the corresponding values of \a a1 and \a a2,
9659  *   i.e.: _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ i, j ].
9660  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
9661  *   component. Then
9662  *   _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ i, 0 ].
9663  * 3.  The arrays have same number of components and one array, say _a2_, has one
9664  *   tuple. Then
9665  *   _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ 0, j ].
9666  *
9667  * Info on components is copied either from the first array (in the first case) or from
9668  * the array with maximal number of elements (getNbOfElems()).
9669  *  \param [in] a1 - an array to sum up.
9670  *  \param [in] a2 - another array to sum up.
9671  *  \return DataArrayInt * - the new instance of DataArrayInt.
9672  *          The caller is to delete this result array using decrRef() as it is no more
9673  *          needed.
9674  *  \throw If either \a a1 or \a a2 is NULL.
9675  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
9676  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
9677  *         none of them has number of tuples or components equal to 1.
9678  */
9679 DataArrayInt *DataArrayInt::Add(const DataArrayInt *a1, const DataArrayInt *a2) throw(INTERP_KERNEL::Exception)
9680 {
9681   if(!a1 || !a2)
9682     throw INTERP_KERNEL::Exception("DataArrayInt::Add : input DataArrayInt instance is NULL !");
9683   int nbOfTuple=a1->getNumberOfTuples();
9684   int nbOfTuple2=a2->getNumberOfTuples();
9685   int nbOfComp=a1->getNumberOfComponents();
9686   int nbOfComp2=a2->getNumberOfComponents();
9687   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=0;
9688   if(nbOfTuple==nbOfTuple2)
9689     {
9690       if(nbOfComp==nbOfComp2)
9691         {
9692           ret=DataArrayInt::New();
9693           ret->alloc(nbOfTuple,nbOfComp);
9694           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::plus<int>());
9695           ret->copyStringInfoFrom(*a1);
9696         }
9697       else
9698         {
9699           int nbOfCompMin,nbOfCompMax;
9700           const DataArrayInt *aMin, *aMax;
9701           if(nbOfComp>nbOfComp2)
9702             {
9703               nbOfCompMin=nbOfComp2; nbOfCompMax=nbOfComp;
9704               aMin=a2; aMax=a1;
9705             }
9706           else
9707             {
9708               nbOfCompMin=nbOfComp; nbOfCompMax=nbOfComp2;
9709               aMin=a1; aMax=a2;
9710             }
9711           if(nbOfCompMin==1)
9712             {
9713               ret=DataArrayInt::New();
9714               ret->alloc(nbOfTuple,nbOfCompMax);
9715               const int *aMinPtr=aMin->getConstPointer();
9716               const int *aMaxPtr=aMax->getConstPointer();
9717               int *res=ret->getPointer();
9718               for(int i=0;i<nbOfTuple;i++)
9719                 res=std::transform(aMaxPtr+i*nbOfCompMax,aMaxPtr+(i+1)*nbOfCompMax,res,std::bind2nd(std::plus<int>(),aMinPtr[i]));
9720               ret->copyStringInfoFrom(*aMax);
9721             }
9722           else
9723             throw INTERP_KERNEL::Exception("Nb of components mismatch for array Add !");
9724         }
9725     }
9726   else if((nbOfTuple==1 && nbOfTuple2>1) || (nbOfTuple>1 && nbOfTuple2==1))
9727     {
9728       if(nbOfComp==nbOfComp2)
9729         {
9730           int nbOfTupleMax=std::max(nbOfTuple,nbOfTuple2);
9731           const DataArrayInt *aMin=nbOfTuple>nbOfTuple2?a2:a1;
9732           const DataArrayInt *aMax=nbOfTuple>nbOfTuple2?a1:a2;
9733           const int *aMinPtr=aMin->getConstPointer(),*aMaxPtr=aMax->getConstPointer();
9734           ret=DataArrayInt::New();
9735           ret->alloc(nbOfTupleMax,nbOfComp);
9736           int *res=ret->getPointer();
9737           for(int i=0;i<nbOfTupleMax;i++)
9738             res=std::transform(aMaxPtr+i*nbOfComp,aMaxPtr+(i+1)*nbOfComp,aMinPtr,res,std::plus<int>());
9739           ret->copyStringInfoFrom(*aMax);
9740         }
9741       else
9742         throw INTERP_KERNEL::Exception("Nb of components mismatch for array Add !");
9743     }
9744   else
9745     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Add !");
9746   return ret.retn();
9747 }
9748
9749 /*!
9750  * Adds values of another DataArrayInt to values of \a this one. There are 3
9751  * valid cases.
9752  * 1.  The arrays have same number of tuples and components. Then each value of
9753  *   \a other array is added to the corresponding value of \a this array, i.e.:
9754  *   _a_ [ i, j ] += _other_ [ i, j ].
9755  * 2.  The arrays have same number of tuples and \a other array has one component. Then
9756  *   _a_ [ i, j ] += _other_ [ i, 0 ].
9757  * 3.  The arrays have same number of components and \a other array has one tuple. Then
9758  *   _a_ [ i, j ] += _a2_ [ 0, j ].
9759  *
9760  *  \param [in] other - an array to add to \a this one.
9761  *  \throw If \a other is NULL.
9762  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
9763  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
9764  *         \a other has number of both tuples and components not equal to 1.
9765  */
9766 void DataArrayInt::addEqual(const DataArrayInt *other) throw(INTERP_KERNEL::Exception)
9767 {
9768   if(!other)
9769     throw INTERP_KERNEL::Exception("DataArrayInt::addEqual : input DataArrayInt instance is NULL !");
9770   const char *msg="Nb of tuples mismatch for DataArrayInt::addEqual  !";
9771   checkAllocated(); other->checkAllocated();
9772   int nbOfTuple=getNumberOfTuples();
9773   int nbOfTuple2=other->getNumberOfTuples();
9774   int nbOfComp=getNumberOfComponents();
9775   int nbOfComp2=other->getNumberOfComponents();
9776   if(nbOfTuple==nbOfTuple2)
9777     {
9778       if(nbOfComp==nbOfComp2)
9779         {
9780           std::transform(begin(),end(),other->begin(),getPointer(),std::plus<int>());
9781         }
9782       else if(nbOfComp2==1)
9783         {
9784           int *ptr=getPointer();
9785           const int *ptrc=other->getConstPointer();
9786           for(int i=0;i<nbOfTuple;i++)
9787             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::plus<int>(),*ptrc++));
9788         }
9789       else
9790         throw INTERP_KERNEL::Exception(msg);
9791     }
9792   else if(nbOfTuple2==1)
9793     {
9794       if(nbOfComp2==nbOfComp)
9795         {
9796           int *ptr=getPointer();
9797           const int *ptrc=other->getConstPointer();
9798           for(int i=0;i<nbOfTuple;i++)
9799             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::plus<int>());
9800         }
9801       else
9802         throw INTERP_KERNEL::Exception(msg);
9803     }
9804   else
9805     throw INTERP_KERNEL::Exception(msg);
9806   declareAsNew();
9807 }
9808
9809 /*!
9810  * Returns a new DataArrayInt that is a subtraction of two given arrays. There are 3
9811  * valid cases.
9812  * 1.  The arrays have same number of tuples and components. Then each value of
9813  *   the result array (_a_) is a subtraction of the corresponding values of \a a1 and
9814  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ i, j ].
9815  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
9816  *   component. Then
9817  *   _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ i, 0 ].
9818  * 3.  The arrays have same number of components and one array, say _a2_, has one
9819  *   tuple. Then
9820  *   _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ 0, j ].
9821  *
9822  * Info on components is copied either from the first array (in the first case) or from
9823  * the array with maximal number of elements (getNbOfElems()).
9824  *  \param [in] a1 - an array to subtract from.
9825  *  \param [in] a2 - an array to subtract.
9826  *  \return DataArrayInt * - the new instance of DataArrayInt.
9827  *          The caller is to delete this result array using decrRef() as it is no more
9828  *          needed.
9829  *  \throw If either \a a1 or \a a2 is NULL.
9830  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
9831  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
9832  *         none of them has number of tuples or components equal to 1.
9833  */
9834 DataArrayInt *DataArrayInt::Substract(const DataArrayInt *a1, const DataArrayInt *a2) throw(INTERP_KERNEL::Exception)
9835 {
9836   if(!a1 || !a2)
9837     throw INTERP_KERNEL::Exception("DataArrayInt::Substract : input DataArrayInt instance is NULL !");
9838   int nbOfTuple1=a1->getNumberOfTuples();
9839   int nbOfTuple2=a2->getNumberOfTuples();
9840   int nbOfComp1=a1->getNumberOfComponents();
9841   int nbOfComp2=a2->getNumberOfComponents();
9842   if(nbOfTuple2==nbOfTuple1)
9843     {
9844       if(nbOfComp1==nbOfComp2)
9845         {
9846           MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
9847           ret->alloc(nbOfTuple2,nbOfComp1);
9848           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::minus<int>());
9849           ret->copyStringInfoFrom(*a1);
9850           return ret.retn();
9851         }
9852       else if(nbOfComp2==1)
9853         {
9854           MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
9855           ret->alloc(nbOfTuple1,nbOfComp1);
9856           const int *a2Ptr=a2->getConstPointer();
9857           const int *a1Ptr=a1->getConstPointer();
9858           int *res=ret->getPointer();
9859           for(int i=0;i<nbOfTuple1;i++)
9860             res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::minus<int>(),a2Ptr[i]));
9861           ret->copyStringInfoFrom(*a1);
9862           return ret.retn();
9863         }
9864       else
9865         {
9866           a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Substract !");
9867           return 0;
9868         }
9869     }
9870   else if(nbOfTuple2==1)
9871     {
9872       a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Substract !");
9873       MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
9874       ret->alloc(nbOfTuple1,nbOfComp1);
9875       const int *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
9876       int *pt=ret->getPointer();
9877       for(int i=0;i<nbOfTuple1;i++)
9878         pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::minus<int>());
9879       ret->copyStringInfoFrom(*a1);
9880       return ret.retn();
9881     }
9882   else
9883     {
9884       a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Substract !");//will always throw an exception
9885       return 0;
9886     }
9887 }
9888
9889 /*!
9890  * Subtract values of another DataArrayInt from values of \a this one. There are 3
9891  * valid cases.
9892  * 1.  The arrays have same number of tuples and components. Then each value of
9893  *   \a other array is subtracted from the corresponding value of \a this array, i.e.:
9894  *   _a_ [ i, j ] -= _other_ [ i, j ].
9895  * 2.  The arrays have same number of tuples and \a other array has one component. Then
9896  *   _a_ [ i, j ] -= _other_ [ i, 0 ].
9897  * 3.  The arrays have same number of components and \a other array has one tuple. Then
9898  *   _a_ [ i, j ] -= _a2_ [ 0, j ].
9899  *
9900  *  \param [in] other - an array to subtract from \a this one.
9901  *  \throw If \a other is NULL.
9902  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
9903  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
9904  *         \a other has number of both tuples and components not equal to 1.
9905  */
9906 void DataArrayInt::substractEqual(const DataArrayInt *other) throw(INTERP_KERNEL::Exception)
9907 {
9908   if(!other)
9909     throw INTERP_KERNEL::Exception("DataArrayInt::substractEqual : input DataArrayInt instance is NULL !");
9910   const char *msg="Nb of tuples mismatch for DataArrayInt::substractEqual  !";
9911   checkAllocated(); other->checkAllocated();
9912   int nbOfTuple=getNumberOfTuples();
9913   int nbOfTuple2=other->getNumberOfTuples();
9914   int nbOfComp=getNumberOfComponents();
9915   int nbOfComp2=other->getNumberOfComponents();
9916   if(nbOfTuple==nbOfTuple2)
9917     {
9918       if(nbOfComp==nbOfComp2)
9919         {
9920           std::transform(begin(),end(),other->begin(),getPointer(),std::minus<int>());
9921         }
9922       else if(nbOfComp2==1)
9923         {
9924           int *ptr=getPointer();
9925           const int *ptrc=other->getConstPointer();
9926           for(int i=0;i<nbOfTuple;i++)
9927             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::minus<int>(),*ptrc++));
9928         }
9929       else
9930         throw INTERP_KERNEL::Exception(msg);
9931     }
9932   else if(nbOfTuple2==1)
9933     {
9934       int *ptr=getPointer();
9935       const int *ptrc=other->getConstPointer();
9936       for(int i=0;i<nbOfTuple;i++)
9937         std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::minus<int>());
9938     }
9939   else
9940     throw INTERP_KERNEL::Exception(msg);
9941   declareAsNew();
9942 }
9943
9944 /*!
9945  * Returns a new DataArrayInt that is a product of two given arrays. There are 3
9946  * valid cases.
9947  * 1.  The arrays have same number of tuples and components. Then each value of
9948  *   the result array (_a_) is a product of the corresponding values of \a a1 and
9949  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ i, j ].
9950  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
9951  *   component. Then
9952  *   _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ i, 0 ].
9953  * 3.  The arrays have same number of components and one array, say _a2_, has one
9954  *   tuple. Then
9955  *   _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ 0, j ].
9956  *
9957  * Info on components is copied either from the first array (in the first case) or from
9958  * the array with maximal number of elements (getNbOfElems()).
9959  *  \param [in] a1 - a factor array.
9960  *  \param [in] a2 - another factor array.
9961  *  \return DataArrayInt * - the new instance of DataArrayInt.
9962  *          The caller is to delete this result array using decrRef() as it is no more
9963  *          needed.
9964  *  \throw If either \a a1 or \a a2 is NULL.
9965  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
9966  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
9967  *         none of them has number of tuples or components equal to 1.
9968  */
9969 DataArrayInt *DataArrayInt::Multiply(const DataArrayInt *a1, const DataArrayInt *a2) throw(INTERP_KERNEL::Exception)
9970 {
9971   if(!a1 || !a2)
9972     throw INTERP_KERNEL::Exception("DataArrayInt::Multiply : input DataArrayInt instance is NULL !");
9973   int nbOfTuple=a1->getNumberOfTuples();
9974   int nbOfTuple2=a2->getNumberOfTuples();
9975   int nbOfComp=a1->getNumberOfComponents();
9976   int nbOfComp2=a2->getNumberOfComponents();
9977   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=0;
9978   if(nbOfTuple==nbOfTuple2)
9979     {
9980       if(nbOfComp==nbOfComp2)
9981         {
9982           ret=DataArrayInt::New();
9983           ret->alloc(nbOfTuple,nbOfComp);
9984           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::multiplies<int>());
9985           ret->copyStringInfoFrom(*a1);
9986         }
9987       else
9988         {
9989           int nbOfCompMin,nbOfCompMax;
9990           const DataArrayInt *aMin, *aMax;
9991           if(nbOfComp>nbOfComp2)
9992             {
9993               nbOfCompMin=nbOfComp2; nbOfCompMax=nbOfComp;
9994               aMin=a2; aMax=a1;
9995             }
9996           else
9997             {
9998               nbOfCompMin=nbOfComp; nbOfCompMax=nbOfComp2;
9999               aMin=a1; aMax=a2;
10000             }
10001           if(nbOfCompMin==1)
10002             {
10003               ret=DataArrayInt::New();
10004               ret->alloc(nbOfTuple,nbOfCompMax);
10005               const int *aMinPtr=aMin->getConstPointer();
10006               const int *aMaxPtr=aMax->getConstPointer();
10007               int *res=ret->getPointer();
10008               for(int i=0;i<nbOfTuple;i++)
10009                 res=std::transform(aMaxPtr+i*nbOfCompMax,aMaxPtr+(i+1)*nbOfCompMax,res,std::bind2nd(std::multiplies<int>(),aMinPtr[i]));
10010               ret->copyStringInfoFrom(*aMax);
10011             }
10012           else
10013             throw INTERP_KERNEL::Exception("Nb of components mismatch for array Multiply !");
10014         }
10015     }
10016   else if((nbOfTuple==1 && nbOfTuple2>1) || (nbOfTuple>1 && nbOfTuple2==1))
10017     {
10018       if(nbOfComp==nbOfComp2)
10019         {
10020           int nbOfTupleMax=std::max(nbOfTuple,nbOfTuple2);
10021           const DataArrayInt *aMin=nbOfTuple>nbOfTuple2?a2:a1;
10022           const DataArrayInt *aMax=nbOfTuple>nbOfTuple2?a1:a2;
10023           const int *aMinPtr=aMin->getConstPointer(),*aMaxPtr=aMax->getConstPointer();
10024           ret=DataArrayInt::New();
10025           ret->alloc(nbOfTupleMax,nbOfComp);
10026           int *res=ret->getPointer();
10027           for(int i=0;i<nbOfTupleMax;i++)
10028             res=std::transform(aMaxPtr+i*nbOfComp,aMaxPtr+(i+1)*nbOfComp,aMinPtr,res,std::multiplies<int>());
10029           ret->copyStringInfoFrom(*aMax);
10030         }
10031       else
10032         throw INTERP_KERNEL::Exception("Nb of components mismatch for array Multiply !");
10033     }
10034   else
10035     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Multiply !");
10036   return ret.retn();
10037 }
10038
10039
10040 /*!
10041  * Multiply values of another DataArrayInt to values of \a this one. There are 3
10042  * valid cases.
10043  * 1.  The arrays have same number of tuples and components. Then each value of
10044  *   \a other array is multiplied to the corresponding value of \a this array, i.e.:
10045  *   _a_ [ i, j ] *= _other_ [ i, j ].
10046  * 2.  The arrays have same number of tuples and \a other array has one component. Then
10047  *   _a_ [ i, j ] *= _other_ [ i, 0 ].
10048  * 3.  The arrays have same number of components and \a other array has one tuple. Then
10049  *   _a_ [ i, j ] *= _a2_ [ 0, j ].
10050  *
10051  *  \param [in] other - an array to multiply to \a this one.
10052  *  \throw If \a other is NULL.
10053  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
10054  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
10055  *         \a other has number of both tuples and components not equal to 1.
10056  */
10057 void DataArrayInt::multiplyEqual(const DataArrayInt *other) throw(INTERP_KERNEL::Exception)
10058 {
10059   if(!other)
10060     throw INTERP_KERNEL::Exception("DataArrayInt::multiplyEqual : input DataArrayInt instance is NULL !");
10061   const char *msg="Nb of tuples mismatch for DataArrayInt::multiplyEqual !";
10062   checkAllocated(); other->checkAllocated();
10063   int nbOfTuple=getNumberOfTuples();
10064   int nbOfTuple2=other->getNumberOfTuples();
10065   int nbOfComp=getNumberOfComponents();
10066   int nbOfComp2=other->getNumberOfComponents();
10067   if(nbOfTuple==nbOfTuple2)
10068     {
10069       if(nbOfComp==nbOfComp2)
10070         {
10071           std::transform(begin(),end(),other->begin(),getPointer(),std::multiplies<int>());
10072         }
10073       else if(nbOfComp2==1)
10074         {
10075           int *ptr=getPointer();
10076           const int *ptrc=other->getConstPointer();
10077           for(int i=0;i<nbOfTuple;i++)
10078             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::multiplies<int>(),*ptrc++));    
10079         }
10080       else
10081         throw INTERP_KERNEL::Exception(msg);
10082     }
10083   else if(nbOfTuple2==1)
10084     {
10085       if(nbOfComp2==nbOfComp)
10086         {
10087           int *ptr=getPointer();
10088           const int *ptrc=other->getConstPointer();
10089           for(int i=0;i<nbOfTuple;i++)
10090             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::multiplies<int>());
10091         }
10092       else
10093         throw INTERP_KERNEL::Exception(msg);
10094     }
10095   else
10096     throw INTERP_KERNEL::Exception(msg);
10097   declareAsNew();
10098 }
10099
10100
10101 /*!
10102  * Returns a new DataArrayInt that is a division of two given arrays. There are 3
10103  * valid cases.
10104  * 1.  The arrays have same number of tuples and components. Then each value of
10105  *   the result array (_a_) is a division of the corresponding values of \a a1 and
10106  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ i, j ].
10107  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
10108  *   component. Then
10109  *   _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ i, 0 ].
10110  * 3.  The arrays have same number of components and one array, say _a2_, has one
10111  *   tuple. Then
10112  *   _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ 0, j ].
10113  *
10114  * Info on components is copied either from the first array (in the first case) or from
10115  * the array with maximal number of elements (getNbOfElems()).
10116  *  \warning No check of division by zero is performed!
10117  *  \param [in] a1 - a numerator array.
10118  *  \param [in] a2 - a denominator array.
10119  *  \return DataArrayInt * - the new instance of DataArrayInt.
10120  *          The caller is to delete this result array using decrRef() as it is no more
10121  *          needed.
10122  *  \throw If either \a a1 or \a a2 is NULL.
10123  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
10124  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
10125  *         none of them has number of tuples or components equal to 1.
10126  */
10127 DataArrayInt *DataArrayInt::Divide(const DataArrayInt *a1, const DataArrayInt *a2) throw(INTERP_KERNEL::Exception)
10128 {
10129   if(!a1 || !a2)
10130     throw INTERP_KERNEL::Exception("DataArrayInt::Divide : input DataArrayInt instance is NULL !");
10131   int nbOfTuple1=a1->getNumberOfTuples();
10132   int nbOfTuple2=a2->getNumberOfTuples();
10133   int nbOfComp1=a1->getNumberOfComponents();
10134   int nbOfComp2=a2->getNumberOfComponents();
10135   if(nbOfTuple2==nbOfTuple1)
10136     {
10137       if(nbOfComp1==nbOfComp2)
10138         {
10139           MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
10140           ret->alloc(nbOfTuple2,nbOfComp1);
10141           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::divides<int>());
10142           ret->copyStringInfoFrom(*a1);
10143           return ret.retn();
10144         }
10145       else if(nbOfComp2==1)
10146         {
10147           MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
10148           ret->alloc(nbOfTuple1,nbOfComp1);
10149           const int *a2Ptr=a2->getConstPointer();
10150           const int *a1Ptr=a1->getConstPointer();
10151           int *res=ret->getPointer();
10152           for(int i=0;i<nbOfTuple1;i++)
10153             res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::divides<int>(),a2Ptr[i]));
10154           ret->copyStringInfoFrom(*a1);
10155           return ret.retn();
10156         }
10157       else
10158         {
10159           a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Divide !");
10160           return 0;
10161         }
10162     }
10163   else if(nbOfTuple2==1)
10164     {
10165       a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Divide !");
10166       MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
10167       ret->alloc(nbOfTuple1,nbOfComp1);
10168       const int *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
10169       int *pt=ret->getPointer();
10170       for(int i=0;i<nbOfTuple1;i++)
10171         pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::divides<int>());
10172       ret->copyStringInfoFrom(*a1);
10173       return ret.retn();
10174     }
10175   else
10176     {
10177       a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Divide !");//will always throw an exception
10178       return 0;
10179     }
10180 }
10181
10182 /*!
10183  * Divide values of \a this array by values of another DataArrayInt. There are 3
10184  * valid cases.
10185  * 1.  The arrays have same number of tuples and components. Then each value of
10186  *    \a this array is divided by the corresponding value of \a other one, i.e.:
10187  *   _a_ [ i, j ] /= _other_ [ i, j ].
10188  * 2.  The arrays have same number of tuples and \a other array has one component. Then
10189  *   _a_ [ i, j ] /= _other_ [ i, 0 ].
10190  * 3.  The arrays have same number of components and \a other array has one tuple. Then
10191  *   _a_ [ i, j ] /= _a2_ [ 0, j ].
10192  *
10193  *  \warning No check of division by zero is performed!
10194  *  \param [in] other - an array to divide \a this one by.
10195  *  \throw If \a other is NULL.
10196  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
10197  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
10198  *         \a other has number of both tuples and components not equal to 1.
10199  */
10200 void DataArrayInt::divideEqual(const DataArrayInt *other) throw(INTERP_KERNEL::Exception)
10201 {
10202   if(!other)
10203     throw INTERP_KERNEL::Exception("DataArrayInt::divideEqual : input DataArrayInt instance is NULL !");
10204   const char *msg="Nb of tuples mismatch for DataArrayInt::divideEqual !";
10205   checkAllocated(); other->checkAllocated();
10206   int nbOfTuple=getNumberOfTuples();
10207   int nbOfTuple2=other->getNumberOfTuples();
10208   int nbOfComp=getNumberOfComponents();
10209   int nbOfComp2=other->getNumberOfComponents();
10210   if(nbOfTuple==nbOfTuple2)
10211     {
10212       if(nbOfComp==nbOfComp2)
10213         {
10214           std::transform(begin(),end(),other->begin(),getPointer(),std::divides<int>());
10215         }
10216       else if(nbOfComp2==1)
10217         {
10218           int *ptr=getPointer();
10219           const int *ptrc=other->getConstPointer();
10220           for(int i=0;i<nbOfTuple;i++)
10221             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::divides<int>(),*ptrc++));
10222         }
10223       else
10224         throw INTERP_KERNEL::Exception(msg);
10225     }
10226   else if(nbOfTuple2==1)
10227     {
10228       if(nbOfComp2==nbOfComp)
10229         {
10230           int *ptr=getPointer();
10231           const int *ptrc=other->getConstPointer();
10232           for(int i=0;i<nbOfTuple;i++)
10233             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::divides<int>());
10234         }
10235       else
10236         throw INTERP_KERNEL::Exception(msg);
10237     }
10238   else
10239     throw INTERP_KERNEL::Exception(msg);
10240   declareAsNew();
10241 }
10242
10243
10244 /*!
10245  * Returns a new DataArrayInt that is a modulus of two given arrays. There are 3
10246  * valid cases.
10247  * 1.  The arrays have same number of tuples and components. Then each value of
10248  *   the result array (_a_) is a division of the corresponding values of \a a1 and
10249  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] % _a2_ [ i, j ].
10250  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
10251  *   component. Then
10252  *   _a_ [ i, j ] = _a1_ [ i, j ] % _a2_ [ i, 0 ].
10253  * 3.  The arrays have same number of components and one array, say _a2_, has one
10254  *   tuple. Then
10255  *   _a_ [ i, j ] = _a1_ [ i, j ] % _a2_ [ 0, j ].
10256  *
10257  * Info on components is copied either from the first array (in the first case) or from
10258  * the array with maximal number of elements (getNbOfElems()).
10259  *  \warning No check of division by zero is performed!
10260  *  \param [in] a1 - a dividend array.
10261  *  \param [in] a2 - a divisor array.
10262  *  \return DataArrayInt * - the new instance of DataArrayInt.
10263  *          The caller is to delete this result array using decrRef() as it is no more
10264  *          needed.
10265  *  \throw If either \a a1 or \a a2 is NULL.
10266  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
10267  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
10268  *         none of them has number of tuples or components equal to 1.
10269  */
10270 DataArrayInt *DataArrayInt::Modulus(const DataArrayInt *a1, const DataArrayInt *a2) throw(INTERP_KERNEL::Exception)
10271 {
10272     if(!a1 || !a2)
10273     throw INTERP_KERNEL::Exception("DataArrayInt::Modulus : input DataArrayInt instance is NULL !");
10274   int nbOfTuple1=a1->getNumberOfTuples();
10275   int nbOfTuple2=a2->getNumberOfTuples();
10276   int nbOfComp1=a1->getNumberOfComponents();
10277   int nbOfComp2=a2->getNumberOfComponents();
10278   if(nbOfTuple2==nbOfTuple1)
10279     {
10280       if(nbOfComp1==nbOfComp2)
10281         {
10282           MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
10283           ret->alloc(nbOfTuple2,nbOfComp1);
10284           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::modulus<int>());
10285           ret->copyStringInfoFrom(*a1);
10286           return ret.retn();
10287         }
10288       else if(nbOfComp2==1)
10289         {
10290           MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
10291           ret->alloc(nbOfTuple1,nbOfComp1);
10292           const int *a2Ptr=a2->getConstPointer();
10293           const int *a1Ptr=a1->getConstPointer();
10294           int *res=ret->getPointer();
10295           for(int i=0;i<nbOfTuple1;i++)
10296             res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::modulus<int>(),a2Ptr[i]));
10297           ret->copyStringInfoFrom(*a1);
10298           return ret.retn();
10299         }
10300       else
10301         {
10302           a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Modulus !");
10303           return 0;
10304         }
10305     }
10306   else if(nbOfTuple2==1)
10307     {
10308       a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Modulus !");
10309       MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
10310       ret->alloc(nbOfTuple1,nbOfComp1);
10311       const int *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
10312       int *pt=ret->getPointer();
10313       for(int i=0;i<nbOfTuple1;i++)
10314         pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::modulus<int>());
10315       ret->copyStringInfoFrom(*a1);
10316       return ret.retn();
10317     }
10318   else
10319     {
10320       a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Modulus !");//will always throw an exception
10321       return 0;
10322     }
10323 }
10324
10325 /*!
10326  * Modify \a this array so that each value becomes a modulus of division of this value by
10327  * a value of another DataArrayInt. There are 3 valid cases.
10328  * 1.  The arrays have same number of tuples and components. Then each value of
10329  *    \a this array is divided by the corresponding value of \a other one, i.e.:
10330  *   _a_ [ i, j ] %= _other_ [ i, j ].
10331  * 2.  The arrays have same number of tuples and \a other array has one component. Then
10332  *   _a_ [ i, j ] %= _other_ [ i, 0 ].
10333  * 3.  The arrays have same number of components and \a other array has one tuple. Then
10334  *   _a_ [ i, j ] %= _a2_ [ 0, j ].
10335  *
10336  *  \warning No check of division by zero is performed!
10337  *  \param [in] other - a divisor array.
10338  *  \throw If \a other is NULL.
10339  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
10340  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
10341  *         \a other has number of both tuples and components not equal to 1.
10342  */
10343 void DataArrayInt::modulusEqual(const DataArrayInt *other) throw(INTERP_KERNEL::Exception)
10344 {
10345   if(!other)
10346     throw INTERP_KERNEL::Exception("DataArrayInt::modulusEqual : input DataArrayInt instance is NULL !");
10347   const char *msg="Nb of tuples mismatch for DataArrayInt::modulusEqual !";
10348   checkAllocated(); other->checkAllocated();
10349   int nbOfTuple=getNumberOfTuples();
10350   int nbOfTuple2=other->getNumberOfTuples();
10351   int nbOfComp=getNumberOfComponents();
10352   int nbOfComp2=other->getNumberOfComponents();
10353   if(nbOfTuple==nbOfTuple2)
10354     {
10355       if(nbOfComp==nbOfComp2)
10356         {
10357           std::transform(begin(),end(),other->begin(),getPointer(),std::modulus<int>());
10358         }
10359       else if(nbOfComp2==1)
10360         {
10361           if(nbOfComp2==nbOfComp)
10362             {
10363               int *ptr=getPointer();
10364               const int *ptrc=other->getConstPointer();
10365               for(int i=0;i<nbOfTuple;i++)
10366                 std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::modulus<int>(),*ptrc++));
10367             }
10368           else
10369             throw INTERP_KERNEL::Exception(msg);
10370         }
10371       else
10372         throw INTERP_KERNEL::Exception(msg);
10373     }
10374   else if(nbOfTuple2==1)
10375     {
10376       int *ptr=getPointer();
10377       const int *ptrc=other->getConstPointer();
10378       for(int i=0;i<nbOfTuple;i++)
10379         std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::modulus<int>());
10380     }
10381   else
10382     throw INTERP_KERNEL::Exception(msg);
10383   declareAsNew();
10384 }
10385
10386 /*!
10387  * Returns a new DataArrayInt that is the result of pow of two given arrays. There are 3
10388  * valid cases.
10389  *
10390  *  \param [in] a1 - an array to pow up.
10391  *  \param [in] a2 - another array to sum up.
10392  *  \return DataArrayInt * - the new instance of DataArrayInt.
10393  *          The caller is to delete this result array using decrRef() as it is no more
10394  *          needed.
10395  *  \throw If either \a a1 or \a a2 is NULL.
10396  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
10397  *  \throw If \a a1->getNumberOfComponents() != 1 or \a a2->getNumberOfComponents() != 1.
10398  *  \throw If there is a negative value in \a a2.
10399  */
10400 DataArrayInt *DataArrayInt::Pow(const DataArrayInt *a1, const DataArrayInt *a2) throw(INTERP_KERNEL::Exception)
10401 {
10402   if(!a1 || !a2)
10403     throw INTERP_KERNEL::Exception("DataArrayInt::Pow : at least one of input instances is null !");
10404   int nbOfTuple=a1->getNumberOfTuples();
10405   int nbOfTuple2=a2->getNumberOfTuples();
10406   int nbOfComp=a1->getNumberOfComponents();
10407   int nbOfComp2=a2->getNumberOfComponents();
10408   if(nbOfTuple!=nbOfTuple2)
10409     throw INTERP_KERNEL::Exception("DataArrayInt::Pow : number of tuples mismatches !");
10410   if(nbOfComp!=1 || nbOfComp2!=1)
10411     throw INTERP_KERNEL::Exception("DataArrayInt::Pow : number of components of both arrays must be equal to 1 !");
10412   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbOfTuple,1);
10413   const int *ptr1(a1->begin()),*ptr2(a2->begin());
10414   int *ptr=ret->getPointer();
10415   for(int i=0;i<nbOfTuple;i++,ptr1++,ptr2++,ptr++)
10416     {
10417       if(*ptr2>=0)
10418         {
10419           int tmp=1;
10420           for(int j=0;j<*ptr2;j++)
10421             tmp*=*ptr1;
10422           *ptr=tmp;
10423         }
10424       else
10425         {
10426           std::ostringstream oss; oss << "DataArrayInt::Pow : on tuple #" << i << " of a2 value is < 0 (" << *ptr2 << ") !";
10427           throw INTERP_KERNEL::Exception(oss.str().c_str());
10428         }
10429     }
10430   return ret.retn();
10431 }
10432
10433 /*!
10434  * Apply pow on values of another DataArrayInt to values of \a this one.
10435  *
10436  *  \param [in] other - an array to pow to \a this one.
10437  *  \throw If \a other is NULL.
10438  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples()
10439  *  \throw If \a this->getNumberOfComponents() != 1 or \a other->getNumberOfComponents() != 1
10440  *  \throw If there is a negative value in \a other.
10441  */
10442 void DataArrayInt::powEqual(const DataArrayInt *other) throw(INTERP_KERNEL::Exception)
10443 {
10444   if(!other)
10445     throw INTERP_KERNEL::Exception("DataArrayInt::powEqual : input instance is null !");
10446   int nbOfTuple=getNumberOfTuples();
10447   int nbOfTuple2=other->getNumberOfTuples();
10448   int nbOfComp=getNumberOfComponents();
10449   int nbOfComp2=other->getNumberOfComponents();
10450   if(nbOfTuple!=nbOfTuple2)
10451     throw INTERP_KERNEL::Exception("DataArrayInt::powEqual : number of tuples mismatches !");
10452   if(nbOfComp!=1 || nbOfComp2!=1)
10453     throw INTERP_KERNEL::Exception("DataArrayInt::powEqual : number of components of both arrays must be equal to 1 !");
10454   int *ptr=getPointer();
10455   const int *ptrc=other->begin();
10456   for(int i=0;i<nbOfTuple;i++,ptrc++,ptr++)
10457     {
10458       if(*ptrc>=0)
10459         {
10460           int tmp=1;
10461           for(int j=0;j<*ptrc;j++)
10462             tmp*=*ptr;
10463           *ptr=tmp;
10464         }
10465       else
10466         {
10467           std::ostringstream oss; oss << "DataArrayInt::powEqual : on tuple #" << i << " of other value is < 0 (" << *ptrc << ") !";
10468           throw INTERP_KERNEL::Exception(oss.str().c_str());
10469         }
10470     }
10471   declareAsNew();
10472 }
10473
10474 /*!
10475  * Returns a C array which is a renumbering map in "Old to New" mode for the input array.
10476  * This map, if applied to \a start array, would make it sorted. For example, if
10477  * \a start array contents are [9,10,0,6,4,11,3,7] then the contents of the result array is
10478  * [5,6,0,3,2,7,1,4].
10479  *  \param [in] start - pointer to the first element of the array for which the
10480  *         permutation map is computed.
10481  *  \param [in] end - pointer specifying the end of the array \a start, so that
10482  *         the last value of \a start is \a end[ -1 ].
10483  *  \return int * - the result permutation array that the caller is to delete as it is no
10484  *         more needed.
10485  *  \throw If there are equal values in the input array.
10486  */
10487 int *DataArrayInt::CheckAndPreparePermutation(const int *start, const int *end)
10488 {
10489   std::size_t sz=std::distance(start,end);
10490   int *ret=(int *)malloc(sz*sizeof(int));
10491   int *work=new int[sz];
10492   std::copy(start,end,work);
10493   std::sort(work,work+sz);
10494   if(std::unique(work,work+sz)!=work+sz)
10495     {
10496       delete [] work;
10497       free(ret);
10498       throw INTERP_KERNEL::Exception("Some elements are equals in the specified array !");
10499     }
10500   std::map<int,int> m;
10501   for(int *workPt=work;workPt!=work+sz;workPt++)
10502     m[*workPt]=(int)std::distance(work,workPt);
10503   int *iter2=ret;
10504   for(const int *iter=start;iter!=end;iter++,iter2++)
10505     *iter2=m[*iter];
10506   delete [] work;
10507   return ret;
10508 }
10509
10510 /*!
10511  * Returns a new DataArrayInt containing an arithmetic progression
10512  * that is equal to the sequence returned by Python \c range(\a begin,\a  end,\a  step )
10513  * function.
10514  *  \param [in] begin - the start value of the result sequence.
10515  *  \param [in] end - limiting value, so that every value of the result array is less than
10516  *              \a end.
10517  *  \param [in] step - specifies the increment or decrement.
10518  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
10519  *          array using decrRef() as it is no more needed.
10520  *  \throw If \a step == 0.
10521  *  \throw If \a end < \a begin && \a step > 0.
10522  *  \throw If \a end > \a begin && \a step < 0.
10523  */
10524 DataArrayInt *DataArrayInt::Range(int begin, int end, int step) throw(INTERP_KERNEL::Exception)
10525 {
10526   int nbOfTuples=GetNumberOfItemGivenBESRelative(begin,end,step,"DataArrayInt::Range");
10527   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
10528   ret->alloc(nbOfTuples,1);
10529   int *ptr=ret->getPointer();
10530   if(step>0)
10531     {
10532       for(int i=begin;i<end;i+=step,ptr++)
10533         *ptr=i;
10534     }
10535   else
10536     {
10537       for(int i=begin;i>end;i+=step,ptr++)
10538         *ptr=i;
10539     }
10540   return ret.retn();
10541 }
10542
10543 /*!
10544  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
10545  * Server side.
10546  */
10547 void DataArrayInt::getTinySerializationIntInformation(std::vector<int>& tinyInfo) const
10548 {
10549   tinyInfo.resize(2);
10550   if(isAllocated())
10551     {
10552       tinyInfo[0]=getNumberOfTuples();
10553       tinyInfo[1]=getNumberOfComponents();
10554     }
10555   else
10556     {
10557       tinyInfo[0]=-1;
10558       tinyInfo[1]=-1;
10559     }
10560 }
10561
10562 /*!
10563  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
10564  * Server side.
10565  */
10566 void DataArrayInt::getTinySerializationStrInformation(std::vector<std::string>& tinyInfo) const
10567 {
10568   if(isAllocated())
10569     {
10570       int nbOfCompo=getNumberOfComponents();
10571       tinyInfo.resize(nbOfCompo+1);
10572       tinyInfo[0]=getName();
10573       for(int i=0;i<nbOfCompo;i++)
10574         tinyInfo[i+1]=getInfoOnComponent(i);
10575     }
10576   else
10577     {
10578       tinyInfo.resize(1);
10579       tinyInfo[0]=getName();
10580     }
10581 }
10582
10583 /*!
10584  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
10585  * This method returns if a feeding is needed.
10586  */
10587 bool DataArrayInt::resizeForUnserialization(const std::vector<int>& tinyInfoI)
10588 {
10589   int nbOfTuple=tinyInfoI[0];
10590   int nbOfComp=tinyInfoI[1];
10591   if(nbOfTuple!=-1 || nbOfComp!=-1)
10592     {
10593       alloc(nbOfTuple,nbOfComp);
10594       return true;
10595     }
10596   return false;
10597 }
10598
10599 /*!
10600  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
10601  * This method returns if a feeding is needed.
10602  */
10603 void DataArrayInt::finishUnserialization(const std::vector<int>& tinyInfoI, const std::vector<std::string>& tinyInfoS)
10604 {
10605   setName(tinyInfoS[0].c_str());
10606   if(isAllocated())
10607     {
10608       int nbOfCompo=getNumberOfComponents();
10609       for(int i=0;i<nbOfCompo;i++)
10610         setInfoOnComponent(i,tinyInfoS[i+1].c_str());
10611     }
10612 }
10613
10614 DataArrayIntIterator::DataArrayIntIterator(DataArrayInt *da):_da(da),_pt(0),_tuple_id(0),_nb_comp(0),_nb_tuple(0)
10615 {
10616   if(_da)
10617     {
10618       _da->incrRef();
10619       if(_da->isAllocated())
10620         {
10621           _nb_comp=da->getNumberOfComponents();
10622           _nb_tuple=da->getNumberOfTuples();
10623           _pt=da->getPointer();
10624         }
10625     }
10626 }
10627
10628 DataArrayIntIterator::~DataArrayIntIterator()
10629 {
10630   if(_da)
10631     _da->decrRef();
10632 }
10633
10634 DataArrayIntTuple *DataArrayIntIterator::nextt() throw(INTERP_KERNEL::Exception)
10635 {
10636   if(_tuple_id<_nb_tuple)
10637     {
10638       _tuple_id++;
10639       DataArrayIntTuple *ret=new DataArrayIntTuple(_pt,_nb_comp);
10640       _pt+=_nb_comp;
10641       return ret;
10642     }
10643   else
10644     return 0;
10645 }
10646
10647 DataArrayIntTuple::DataArrayIntTuple(int *pt, int nbOfComp):_pt(pt),_nb_of_compo(nbOfComp)
10648 {
10649 }
10650
10651 std::string DataArrayIntTuple::repr() const throw(INTERP_KERNEL::Exception)
10652 {
10653   std::ostringstream oss; oss << "(";
10654   for(int i=0;i<_nb_of_compo-1;i++)
10655     oss << _pt[i] << ", ";
10656   oss << _pt[_nb_of_compo-1] << ")";
10657   return oss.str();
10658 }
10659
10660 int DataArrayIntTuple::intValue() const throw(INTERP_KERNEL::Exception)
10661 {
10662   if(_nb_of_compo==1)
10663     return *_pt;
10664   throw INTERP_KERNEL::Exception("DataArrayIntTuple::intValue : DataArrayIntTuple instance has not exactly 1 component -> Not possible to convert it into an integer !");
10665 }
10666
10667 /*!
10668  * This method returns a newly allocated instance the caller should dealed with by a ParaMEDMEM::DataArrayInt::decrRef.
10669  * This method performs \b no copy of data. The content is only referenced using ParaMEDMEM::DataArrayInt::useArray with ownership set to \b false.
10670  * 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
10671  * \b nbOfCompo=1 and \bnbOfTuples==this->_nb_of_elem.
10672  */
10673 DataArrayInt *DataArrayIntTuple::buildDAInt(int nbOfTuples, int nbOfCompo) const throw(INTERP_KERNEL::Exception)
10674 {
10675   if((_nb_of_compo==nbOfCompo && nbOfTuples==1) || (_nb_of_compo==nbOfTuples && nbOfCompo==1))
10676     {
10677       DataArrayInt *ret=DataArrayInt::New();
10678       ret->useExternalArrayWithRWAccess(_pt,nbOfTuples,nbOfCompo);
10679       return ret;
10680     }
10681   else
10682     {
10683       std::ostringstream oss; oss << "DataArrayIntTuple::buildDAInt : unable to build a requested DataArrayInt instance with nbofTuple=" << nbOfTuples << " and nbOfCompo=" << nbOfCompo;
10684       oss << ".\nBecause the number of elements in this is " << _nb_of_compo << " !";
10685       throw INTERP_KERNEL::Exception(oss.str().c_str());
10686     }
10687 }