Salome HOME
OK thanks to INV !
[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  * Sorts values of the array.
6166  *  \param [in] asc - \a true means ascending order, \a false, descending.
6167  *  \throw If \a this is not allocated.
6168  *  \throw If \a this->getNumberOfComponents() != 1.
6169  */
6170 void DataArrayInt::sort(bool asc) throw(INTERP_KERNEL::Exception)
6171 {
6172   checkAllocated();
6173   if(getNumberOfComponents()!=1)
6174     throw INTERP_KERNEL::Exception("DataArrayInt::sort : only supported with 'this' array with ONE component !");
6175   _mem.sort(asc);
6176   declareAsNew();
6177 }
6178
6179 /*!
6180  * Reverse the array values.
6181  *  \throw If \a this->getNumberOfComponents() < 1.
6182  *  \throw If \a this is not allocated.
6183  */
6184 void DataArrayInt::reverse() throw(INTERP_KERNEL::Exception)
6185 {
6186   checkAllocated();
6187   _mem.reverse(getNumberOfComponents());
6188   declareAsNew();
6189 }
6190
6191 /*!
6192  * Checks that \a this array is consistently **increasing** or **decreasing** in value.
6193  * If not an exception is thrown.
6194  *  \param [in] increasing - if \a true, the array values should be increasing.
6195  *  \throw If sequence of values is not strictly monotonic in agreement with \a
6196  *         increasing arg.
6197  *  \throw If \a this->getNumberOfComponents() != 1.
6198  *  \throw If \a this is not allocated.
6199  */
6200 void DataArrayInt::checkMonotonic(bool increasing) const throw(INTERP_KERNEL::Exception)
6201 {
6202   if(!isMonotonic(increasing))
6203     {
6204       if (increasing)
6205         throw INTERP_KERNEL::Exception("DataArrayInt::checkMonotonic : 'this' is not INCREASING monotonic !");
6206       else
6207         throw INTERP_KERNEL::Exception("DataArrayInt::checkMonotonic : 'this' is not DECREASING monotonic !");
6208     }
6209 }
6210
6211 /*!
6212  * Checks that \a this array is consistently **increasing** or **decreasing** in value.
6213  *  \param [in] increasing - if \a true, array values should be increasing.
6214  *  \return bool - \a true if values change in accordance with \a increasing arg.
6215  *  \throw If \a this->getNumberOfComponents() != 1.
6216  *  \throw If \a this is not allocated.
6217  */
6218 bool DataArrayInt::isMonotonic(bool increasing) const throw(INTERP_KERNEL::Exception)
6219 {
6220   checkAllocated();
6221   if(getNumberOfComponents()!=1)
6222     throw INTERP_KERNEL::Exception("DataArrayInt::isMonotonic : only supported with 'this' array with ONE component !");
6223   int nbOfElements=getNumberOfTuples();
6224   const int *ptr=getConstPointer();
6225   if(nbOfElements==0)
6226     return true;
6227   int ref=ptr[0];
6228   if(increasing)
6229     {
6230       for(int i=1;i<nbOfElements;i++)
6231         {
6232           if(ptr[i]>=ref)
6233             ref=ptr[i];
6234           else
6235             return false;
6236         }
6237     }
6238   else
6239     {
6240       for(int i=1;i<nbOfElements;i++)
6241         {
6242           if(ptr[i]<=ref)
6243             ref=ptr[i];
6244           else
6245             return false;
6246         }
6247     }
6248   return true;
6249 }
6250
6251 /*!
6252  * This method check that array consistently INCREASING or DECREASING in value.
6253  */
6254 bool DataArrayInt::isStrictlyMonotonic(bool increasing) const throw(INTERP_KERNEL::Exception)
6255 {
6256   checkAllocated();
6257   if(getNumberOfComponents()!=1)
6258     throw INTERP_KERNEL::Exception("DataArrayInt::isStrictlyMonotonic : only supported with 'this' array with ONE component !");
6259   int nbOfElements=getNumberOfTuples();
6260   const int *ptr=getConstPointer();
6261   if(nbOfElements==0)
6262     return true;
6263   int ref=ptr[0];
6264   if(increasing)
6265     {
6266       for(int i=1;i<nbOfElements;i++)
6267         {
6268           if(ptr[i]>ref)
6269             ref=ptr[i];
6270           else
6271             return false;
6272         }
6273     }
6274   else
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   return true;
6285 }
6286
6287 /*!
6288  * This method check that array consistently INCREASING or DECREASING in value.
6289  */
6290 void DataArrayInt::checkStrictlyMonotonic(bool increasing) const throw(INTERP_KERNEL::Exception)
6291 {
6292   if(!isStrictlyMonotonic(increasing))
6293     {
6294       if (increasing)
6295         throw INTERP_KERNEL::Exception("DataArrayInt::checkStrictlyMonotonic : 'this' is not strictly INCREASING monotonic !");
6296       else
6297         throw INTERP_KERNEL::Exception("DataArrayInt::checkStrictlyMonotonic : 'this' is not strictly DECREASING monotonic !");
6298     }
6299 }
6300
6301 /*!
6302  * Creates a new one-dimensional DataArrayInt of the same size as \a this and a given
6303  * one-dimensional arrays that must be of the same length. The result array describes
6304  * correspondence between \a this and \a other arrays, so that 
6305  * <em> other.getIJ(i,0) == this->getIJ(ret->getIJ(i),0)</em>. If such a permutation is
6306  * not possible because some element in \a other is not in \a this, an exception is thrown.
6307  *  \param [in] other - an array to compute permutation to.
6308  *  \return DataArrayInt * - a new instance of DataArrayInt, which is a permutation array
6309  * from \a this to \a other. The caller is to delete this array using decrRef() as it is
6310  * no more needed.
6311  *  \throw If \a this->getNumberOfComponents() != 1.
6312  *  \throw If \a other->getNumberOfComponents() != 1.
6313  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples().
6314  *  \throw If \a other includes a value which is not in \a this array.
6315  * 
6316  *  \ref cpp_mcdataarrayint_buildpermutationarr "Here is a C++ example".
6317  *
6318  *  \ref py_mcdataarrayint_buildpermutationarr "Here is a Python example".
6319  */
6320 DataArrayInt *DataArrayInt::buildPermutationArr(const DataArrayInt& other) const throw(INTERP_KERNEL::Exception)
6321 {
6322   checkAllocated();
6323   if(getNumberOfComponents()!=1 || other.getNumberOfComponents()!=1)
6324     throw INTERP_KERNEL::Exception("DataArrayInt::buildPermutationArr : 'this' and 'other' have to have exactly ONE component !");
6325   int nbTuple=getNumberOfTuples();
6326   other.checkAllocated();
6327   if(nbTuple!=other.getNumberOfTuples())
6328     throw INTERP_KERNEL::Exception("DataArrayInt::buildPermutationArr : 'this' and 'other' must have the same number of tuple !");
6329   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6330   ret->alloc(nbTuple,1);
6331   ret->fillWithValue(-1);
6332   const int *pt=getConstPointer();
6333   std::map<int,int> mm;
6334   for(int i=0;i<nbTuple;i++)
6335     mm[pt[i]]=i;
6336   pt=other.getConstPointer();
6337   int *retToFill=ret->getPointer();
6338   for(int i=0;i<nbTuple;i++)
6339     {
6340       std::map<int,int>::const_iterator it=mm.find(pt[i]);
6341       if(it==mm.end())
6342         {
6343           std::ostringstream oss; oss << "DataArrayInt::buildPermutationArr : Arrays mismatch : element (" << pt[i] << ") in 'other' not findable in 'this' !";
6344           throw INTERP_KERNEL::Exception(oss.str().c_str());
6345         }
6346       retToFill[i]=(*it).second;
6347     }
6348   return ret.retn();
6349 }
6350
6351 /*!
6352  * Sets a C array to be used as raw data of \a this. The previously set info
6353  *  of components is retained and re-sized. 
6354  * For more info see \ref MEDCouplingArraySteps1.
6355  *  \param [in] array - the C array to be used as raw data of \a this.
6356  *  \param [in] ownership - if \a true, \a array will be deallocated at destruction of \a this.
6357  *  \param [in] type - specifies how to deallocate \a array. If \a type == ParaMEDMEM::CPP_DEALLOC,
6358  *                     \c delete [] \c array; will be called. If \a type == ParaMEDMEM::C_DEALLOC,
6359  *                     \c free(\c array ) will be called.
6360  *  \param [in] nbOfTuple - new number of tuples in \a this.
6361  *  \param [in] nbOfCompo - new number of components in \a this.
6362  */
6363 void DataArrayInt::useArray(const int *array, bool ownership,  DeallocType type, int nbOfTuple, int nbOfCompo) throw(INTERP_KERNEL::Exception)
6364 {
6365   _info_on_compo.resize(nbOfCompo);
6366   _mem.useArray(array,ownership,type,nbOfTuple*nbOfCompo);
6367   declareAsNew();
6368 }
6369
6370 void DataArrayInt::useExternalArrayWithRWAccess(const int *array, int nbOfTuple, int nbOfCompo) throw(INTERP_KERNEL::Exception)
6371 {
6372   _info_on_compo.resize(nbOfCompo);
6373   _mem.useExternalArrayWithRWAccess(array,nbOfTuple*nbOfCompo);
6374   declareAsNew();
6375 }
6376
6377 /*!
6378  * Returns a new DataArrayInt holding the same values as \a this array but differently
6379  * arranged in memory. If \a this array holds 2 components of 3 values:
6380  * \f$ x_0,x_1,x_2,y_0,y_1,y_2 \f$, then the result array holds these values arranged
6381  * as follows: \f$ x_0,y_0,x_1,y_1,x_2,y_2 \f$.
6382  *  \warning Do not confuse this method with transpose()!
6383  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
6384  *          is to delete using decrRef() as it is no more needed.
6385  *  \throw If \a this is not allocated.
6386  */
6387 DataArrayInt *DataArrayInt::fromNoInterlace() const throw(INTERP_KERNEL::Exception)
6388 {
6389   checkAllocated();
6390   if(_mem.isNull())
6391     throw INTERP_KERNEL::Exception("DataArrayInt::fromNoInterlace : Not defined array !");
6392   int *tab=_mem.fromNoInterlace(getNumberOfComponents());
6393   DataArrayInt *ret=DataArrayInt::New();
6394   ret->useArray(tab,true,C_DEALLOC,getNumberOfTuples(),getNumberOfComponents());
6395   return ret;
6396 }
6397
6398 /*!
6399  * Returns a new DataArrayInt holding the same values as \a this array but differently
6400  * arranged in memory. If \a this array holds 2 components of 3 values:
6401  * \f$ x_0,y_0,x_1,y_1,x_2,y_2 \f$, then the result array holds these values arranged
6402  * as follows: \f$ x_0,x_1,x_2,y_0,y_1,y_2 \f$.
6403  *  \warning Do not confuse this method with transpose()!
6404  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
6405  *          is to delete using decrRef() as it is no more needed.
6406  *  \throw If \a this is not allocated.
6407  */
6408 DataArrayInt *DataArrayInt::toNoInterlace() const throw(INTERP_KERNEL::Exception)
6409 {
6410   checkAllocated();
6411   if(_mem.isNull())
6412     throw INTERP_KERNEL::Exception("DataArrayInt::toNoInterlace : Not defined array !");
6413   int *tab=_mem.toNoInterlace(getNumberOfComponents());
6414   DataArrayInt *ret=DataArrayInt::New();
6415   ret->useArray(tab,true,C_DEALLOC,getNumberOfTuples(),getNumberOfComponents());
6416   return ret;
6417 }
6418
6419 /*!
6420  * Permutes values of \a this array as required by \a old2New array. The values are
6421  * permuted so that \c new[ \a old2New[ i ]] = \c old[ i ]. Number of tuples remains
6422  * the same as in \this one.
6423  * If a permutation reduction is needed, substr() or selectByTupleId() should be used.
6424  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
6425  *  \param [in] old2New - C array of length equal to \a this->getNumberOfTuples()
6426  *     giving a new position for i-th old value.
6427  */
6428 void DataArrayInt::renumberInPlace(const int *old2New) throw(INTERP_KERNEL::Exception)
6429 {
6430   checkAllocated();
6431   int nbTuples=getNumberOfTuples();
6432   int nbOfCompo=getNumberOfComponents();
6433   int *tmp=new int[nbTuples*nbOfCompo];
6434   const int *iptr=getConstPointer();
6435   for(int i=0;i<nbTuples;i++)
6436     {
6437       int v=old2New[i];
6438       if(v>=0 && v<nbTuples)
6439         std::copy(iptr+nbOfCompo*i,iptr+nbOfCompo*(i+1),tmp+nbOfCompo*v);
6440       else
6441         {
6442           std::ostringstream oss; oss << "DataArrayInt::renumberInPlace : At place #" << i << " value is " << v << " ! Should be in [0," << nbTuples << ") !";
6443           throw INTERP_KERNEL::Exception(oss.str().c_str());
6444         }
6445     }
6446   std::copy(tmp,tmp+nbTuples*nbOfCompo,getPointer());
6447   delete [] tmp;
6448   declareAsNew();
6449 }
6450
6451 /*!
6452  * Permutes values of \a this array as required by \a new2Old array. The values are
6453  * permuted so that \c new[ i ] = \c old[ \a new2Old[ i ]]. Number of tuples remains
6454  * the same as in \this one.
6455  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
6456  *  \param [in] new2Old - C array of length equal to \a this->getNumberOfTuples()
6457  *     giving a previous position of i-th new value.
6458  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
6459  *          is to delete using decrRef() as it is no more needed.
6460  */
6461 void DataArrayInt::renumberInPlaceR(const int *new2Old) throw(INTERP_KERNEL::Exception)
6462 {
6463   checkAllocated();
6464   int nbTuples=getNumberOfTuples();
6465   int nbOfCompo=getNumberOfComponents();
6466   int *tmp=new int[nbTuples*nbOfCompo];
6467   const int *iptr=getConstPointer();
6468   for(int i=0;i<nbTuples;i++)
6469     {
6470       int v=new2Old[i];
6471       if(v>=0 && v<nbTuples)
6472         std::copy(iptr+nbOfCompo*v,iptr+nbOfCompo*(v+1),tmp+nbOfCompo*i);
6473       else
6474         {
6475           std::ostringstream oss; oss << "DataArrayInt::renumberInPlaceR : At place #" << i << " value is " << v << " ! Should be in [0," << nbTuples << ") !";
6476           throw INTERP_KERNEL::Exception(oss.str().c_str());
6477         }
6478     }
6479   std::copy(tmp,tmp+nbTuples*nbOfCompo,getPointer());
6480   delete [] tmp;
6481   declareAsNew();
6482 }
6483
6484 /*!
6485  * Returns a copy of \a this array with values permuted as required by \a old2New array.
6486  * The values are permuted so that  \c new[ \a old2New[ i ]] = \c old[ i ].
6487  * Number of tuples in the result array remains the same as in \this one.
6488  * If a permutation reduction is needed, renumberAndReduce() should be used.
6489  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
6490  *  \param [in] old2New - C array of length equal to \a this->getNumberOfTuples()
6491  *          giving a new position for i-th old value.
6492  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
6493  *          is to delete using decrRef() as it is no more needed.
6494  *  \throw If \a this is not allocated.
6495  */
6496 DataArrayInt *DataArrayInt::renumber(const int *old2New) const throw(INTERP_KERNEL::Exception)
6497 {
6498   checkAllocated();
6499   int nbTuples=getNumberOfTuples();
6500   int nbOfCompo=getNumberOfComponents();
6501   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6502   ret->alloc(nbTuples,nbOfCompo);
6503   ret->copyStringInfoFrom(*this);
6504   const int *iptr=getConstPointer();
6505   int *optr=ret->getPointer();
6506   for(int i=0;i<nbTuples;i++)
6507     std::copy(iptr+nbOfCompo*i,iptr+nbOfCompo*(i+1),optr+nbOfCompo*old2New[i]);
6508   ret->copyStringInfoFrom(*this);
6509   return ret.retn();
6510 }
6511
6512 /*!
6513  * Returns a copy of \a this array with values permuted as required by \a new2Old array.
6514  * The values are permuted so that  \c new[ i ] = \c old[ \a new2Old[ i ]]. Number of
6515  * tuples in the result array remains the same as in \this one.
6516  * If a permutation reduction is needed, substr() or selectByTupleId() should be used.
6517  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
6518  *  \param [in] new2Old - C array of length equal to \a this->getNumberOfTuples()
6519  *     giving a previous position of i-th new value.
6520  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
6521  *          is to delete using decrRef() as it is no more needed.
6522  */
6523 DataArrayInt *DataArrayInt::renumberR(const int *new2Old) const throw(INTERP_KERNEL::Exception)
6524 {
6525   checkAllocated();
6526   int nbTuples=getNumberOfTuples();
6527   int nbOfCompo=getNumberOfComponents();
6528   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6529   ret->alloc(nbTuples,nbOfCompo);
6530   ret->copyStringInfoFrom(*this);
6531   const int *iptr=getConstPointer();
6532   int *optr=ret->getPointer();
6533   for(int i=0;i<nbTuples;i++)
6534     std::copy(iptr+nbOfCompo*new2Old[i],iptr+nbOfCompo*(new2Old[i]+1),optr+nbOfCompo*i);
6535   ret->copyStringInfoFrom(*this);
6536   return ret.retn();
6537 }
6538
6539 /*!
6540  * Returns a shorten and permuted copy of \a this array. The new DataArrayInt is
6541  * of size \a newNbOfTuple and it's values are permuted as required by \a old2New array.
6542  * The values are permuted so that  \c new[ \a old2New[ i ]] = \c old[ i ] for all
6543  * \a old2New[ i ] >= 0. In other words every i-th tuple in \a this array, for which 
6544  * \a old2New[ i ] is negative, is missing from the result array.
6545  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
6546  *  \param [in] old2New - C array of length equal to \a this->getNumberOfTuples()
6547  *     giving a new position for i-th old tuple and giving negative position for
6548  *     for i-th old tuple that should be omitted.
6549  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
6550  *          is to delete using decrRef() as it is no more needed.
6551  */
6552 DataArrayInt *DataArrayInt::renumberAndReduce(const int *old2New, int newNbOfTuple) const throw(INTERP_KERNEL::Exception)
6553 {
6554   checkAllocated();
6555   int nbTuples=getNumberOfTuples();
6556   int nbOfCompo=getNumberOfComponents();
6557   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6558   ret->alloc(newNbOfTuple,nbOfCompo);
6559   const int *iptr=getConstPointer();
6560   int *optr=ret->getPointer();
6561   for(int i=0;i<nbTuples;i++)
6562     {
6563       int w=old2New[i];
6564       if(w>=0)
6565         std::copy(iptr+i*nbOfCompo,iptr+(i+1)*nbOfCompo,optr+w*nbOfCompo);
6566     }
6567   ret->copyStringInfoFrom(*this);
6568   return ret.retn();
6569 }
6570
6571 /*!
6572  * Returns a shorten and permuted copy of \a this array. The new DataArrayInt is
6573  * of size \a new2OldEnd - \a new2OldBg and it's values are permuted as required by
6574  * \a new2OldBg array.
6575  * The values are permuted so that  \c new[ i ] = \c old[ \a new2OldBg[ i ]].
6576  * This method is equivalent to renumberAndReduce() except that convention in input is
6577  * \c new2old and \b not \c old2new.
6578  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
6579  *  \param [in] new2OldBg - pointer to the beginning of a permutation array that gives a
6580  *              tuple index in \a this array to fill the i-th tuple in the new array.
6581  *  \param [in] new2OldEnd - specifies the end of the permutation array that starts at
6582  *              \a new2OldBg, so that pointer to a tuple index (\a pi) varies as this:
6583  *              \a new2OldBg <= \a pi < \a new2OldEnd.
6584  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
6585  *          is to delete using decrRef() as it is no more needed.
6586  */
6587 DataArrayInt *DataArrayInt::selectByTupleId(const int *new2OldBg, const int *new2OldEnd) const
6588 {
6589   checkAllocated();
6590   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6591   int nbComp=getNumberOfComponents();
6592   ret->alloc((int)std::distance(new2OldBg,new2OldEnd),nbComp);
6593   ret->copyStringInfoFrom(*this);
6594   int *pt=ret->getPointer();
6595   const int *srcPt=getConstPointer();
6596   int i=0;
6597   for(const int *w=new2OldBg;w!=new2OldEnd;w++,i++)
6598     std::copy(srcPt+(*w)*nbComp,srcPt+((*w)+1)*nbComp,pt+i*nbComp);
6599   ret->copyStringInfoFrom(*this);
6600   return ret.retn();
6601 }
6602
6603 /*!
6604  * Returns a shorten and permuted copy of \a this array. The new DataArrayInt is
6605  * of size \a new2OldEnd - \a new2OldBg and it's values are permuted as required by
6606  * \a new2OldBg array.
6607  * The values are permuted so that  \c new[ i ] = \c old[ \a new2OldBg[ i ]].
6608  * This method is equivalent to renumberAndReduce() except that convention in input is
6609  * \c new2old and \b not \c old2new.
6610  * This method is equivalent to selectByTupleId() except that it prevents coping data
6611  * from behind the end of \a this array.
6612  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
6613  *  \param [in] new2OldBg - pointer to the beginning of a permutation array that gives a
6614  *              tuple index in \a this array to fill the i-th tuple in the new array.
6615  *  \param [in] new2OldEnd - specifies the end of the permutation array that starts at
6616  *              \a new2OldBg, so that pointer to a tuple index (\a pi) varies as this:
6617  *              \a new2OldBg <= \a pi < \a new2OldEnd.
6618  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
6619  *          is to delete using decrRef() as it is no more needed.
6620  *  \throw If \a new2OldEnd - \a new2OldBg > \a this->getNumberOfTuples().
6621  */
6622 DataArrayInt *DataArrayInt::selectByTupleIdSafe(const int *new2OldBg, const int *new2OldEnd) const throw(INTERP_KERNEL::Exception)
6623 {
6624   checkAllocated();
6625   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6626   int nbComp=getNumberOfComponents();
6627   int oldNbOfTuples=getNumberOfTuples();
6628   ret->alloc((int)std::distance(new2OldBg,new2OldEnd),nbComp);
6629   ret->copyStringInfoFrom(*this);
6630   int *pt=ret->getPointer();
6631   const int *srcPt=getConstPointer();
6632   int i=0;
6633   for(const int *w=new2OldBg;w!=new2OldEnd;w++,i++)
6634     if(*w>=0 && *w<oldNbOfTuples)
6635       std::copy(srcPt+(*w)*nbComp,srcPt+((*w)+1)*nbComp,pt+i*nbComp);
6636     else
6637       throw INTERP_KERNEL::Exception("DataArrayInt::selectByTupleIdSafe : some ids has been detected to be out of [0,this->getNumberOfTuples) !");
6638   ret->copyStringInfoFrom(*this);
6639   return ret.retn();
6640 }
6641
6642 /*!
6643  * Returns a shorten copy of \a this array. The new DataArrayInt contains every
6644  * (\a bg + \c i * \a step)-th tuple of \a this array located before the \a end2-th
6645  * tuple. Indices of the selected tuples are the same as ones returned by the Python
6646  * command \c range( \a bg, \a end2, \a step ).
6647  * This method is equivalent to selectByTupleIdSafe() except that the input array is
6648  * not constructed explicitly.
6649  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
6650  *  \param [in] bg - index of the first tuple to copy from \a this array.
6651  *  \param [in] end2 - index of the tuple before which the tuples to copy are located.
6652  *  \param [in] step - index increment to get index of the next tuple to copy.
6653  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
6654  *          is to delete using decrRef() as it is no more needed.
6655  *  \sa DataArrayInt::substr.
6656  */
6657 DataArrayInt *DataArrayInt::selectByTupleId2(int bg, int end2, int step) const throw(INTERP_KERNEL::Exception)
6658 {
6659   checkAllocated();
6660   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6661   int nbComp=getNumberOfComponents();
6662   int newNbOfTuples=GetNumberOfItemGivenBESRelative(bg,end2,step,"DataArrayInt::selectByTupleId2 : ");
6663   ret->alloc(newNbOfTuples,nbComp);
6664   int *pt=ret->getPointer();
6665   const int *srcPt=getConstPointer()+bg*nbComp;
6666   for(int i=0;i<newNbOfTuples;i++,srcPt+=step*nbComp)
6667     std::copy(srcPt,srcPt+nbComp,pt+i*nbComp);
6668   ret->copyStringInfoFrom(*this);
6669   return ret.retn();
6670 }
6671
6672 /*!
6673  * Returns a shorten copy of \a this array. The new DataArrayInt contains ranges
6674  * of tuples specified by \a ranges parameter.
6675  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
6676  *  \param [in] ranges - std::vector of std::pair's each of which defines a range
6677  *              of tuples in [\c begin,\c end) format.
6678  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
6679  *          is to delete using decrRef() as it is no more needed.
6680  *  \throw If \a end < \a begin.
6681  *  \throw If \a end > \a this->getNumberOfTuples().
6682  *  \throw If \a this is not allocated.
6683  */
6684 DataArray *DataArrayInt::selectByTupleRanges(const std::vector<std::pair<int,int> >& ranges) const throw(INTERP_KERNEL::Exception)
6685 {
6686   checkAllocated();
6687   int nbOfComp=getNumberOfComponents();
6688   int nbOfTuplesThis=getNumberOfTuples();
6689   if(ranges.empty())
6690     {
6691       MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6692       ret->alloc(0,nbOfComp);
6693       ret->copyStringInfoFrom(*this);
6694       return ret.retn();
6695     }
6696   int ref=ranges.front().first;
6697   int nbOfTuples=0;
6698   bool isIncreasing=true;
6699   for(std::vector<std::pair<int,int> >::const_iterator it=ranges.begin();it!=ranges.end();it++)
6700     {
6701       if((*it).first<=(*it).second)
6702         {
6703           if((*it).first>=0 && (*it).second<=nbOfTuplesThis)
6704             {
6705               nbOfTuples+=(*it).second-(*it).first;
6706               if(isIncreasing)
6707                 isIncreasing=ref<=(*it).first;
6708               ref=(*it).second;
6709             }
6710           else
6711             {
6712               std::ostringstream oss; oss << "DataArrayInt::selectByTupleRanges : on range #" << std::distance(ranges.begin(),it);
6713               oss << " (" << (*it).first << "," << (*it).second << ") is greater than number of tuples of this :" << nbOfTuples << " !";
6714               throw INTERP_KERNEL::Exception(oss.str().c_str());
6715             }
6716         }
6717       else
6718         {
6719           std::ostringstream oss; oss << "DataArrayInt::selectByTupleRanges : on range #" << std::distance(ranges.begin(),it);
6720           oss << " (" << (*it).first << "," << (*it).second << ") end is before begin !";
6721           throw INTERP_KERNEL::Exception(oss.str().c_str());
6722         }
6723     }
6724   if(isIncreasing && nbOfTuplesThis==nbOfTuples)
6725     return deepCpy();
6726   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6727   ret->alloc(nbOfTuples,nbOfComp);
6728   ret->copyStringInfoFrom(*this);
6729   const int *src=getConstPointer();
6730   int *work=ret->getPointer();
6731   for(std::vector<std::pair<int,int> >::const_iterator it=ranges.begin();it!=ranges.end();it++)
6732     work=std::copy(src+(*it).first*nbOfComp,src+(*it).second*nbOfComp,work);
6733   return ret.retn();
6734 }
6735
6736 /*!
6737  * Returns a new DataArrayInt containing a renumbering map in "Old to New" mode.
6738  * This map, if applied to \a this array, would make it sorted. For example, if
6739  * \a this array contents are [9,10,0,6,4,11,3,7] then the contents of the result array
6740  * are [5,6,0,3,2,7,1,4]; if this result array (\a res) is used as an argument in call
6741  * \a this->renumber(\a res) then the returned array contains [0,3,4,6,7,9,10,11].
6742  * This method is useful for renumbering (in MED file for example). For more info
6743  * on renumbering see \ref MEDCouplingArrayRenumbering.
6744  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
6745  *          array using decrRef() as it is no more needed.
6746  *  \throw If \a this is not allocated.
6747  *  \throw If \a this->getNumberOfComponents() != 1.
6748  *  \throw If there are equal values in \a this array.
6749  */
6750 DataArrayInt *DataArrayInt::checkAndPreparePermutation() const throw(INTERP_KERNEL::Exception)
6751 {
6752   checkAllocated();
6753   if(getNumberOfComponents()!=1)
6754     throw INTERP_KERNEL::Exception("DataArrayInt::checkAndPreparePermutation : number of components must == 1 !");
6755   int nbTuples=getNumberOfTuples();
6756   const int *pt=getConstPointer();
6757   int *pt2=CheckAndPreparePermutation(pt,pt+nbTuples);
6758   DataArrayInt *ret=DataArrayInt::New();
6759   ret->useArray(pt2,true,C_DEALLOC,nbTuples,1);
6760   return ret;
6761 }
6762
6763 /*!
6764  * Returns two arrays describing a surjective mapping from \a this set of values (\a A)
6765  * onto a set of values of size \a targetNb (\a B). The surjective function is 
6766  * \a B[ \a A[ i ]] = i. That is to say that for each \a id in [0,\a targetNb), where \a
6767  * targetNb < \a this->getNumberOfTuples(), there exists at least one tupleId (\a tid) so
6768  * that <em> this->getIJ( tid, 0 ) == id</em>. <br>
6769  * The first of out arrays returns indices of elements of \a this array, grouped by their
6770  * place in the set \a B. The second out array is the index of the first one; it shows how
6771  * many elements of \a A are mapped into each element of \a B. <br>
6772  * For more info on
6773  * mapping and its usage in renumbering see \ref MEDCouplingArrayRenumbering. <br>
6774  * \b Example:
6775  * - \a this: [0,3,2,3,2,2,1,2]
6776  * - \a targetNb: 4
6777  * - \a arr:  [0,  6,  2,4,5,7,  1,3]
6778  * - \a arrI: [0,1,2,6,8]
6779  *
6780  * This result means: <br>
6781  * the element of \a B 0 encounters within \a A once (\a arrI[ 0+1 ] - \a arrI[ 0 ]) and
6782  * its index within \a A is 0 ( \a arr[ 0:1 ] == \a arr[ \a arrI[ 0 ] : \a arrI[ 0+1 ]]);<br>
6783  * the element of \a B 2 encounters within \a A 4 times (\a arrI[ 2+1 ] - \a arrI[ 2 ]) and
6784  * its indices within \a A are [2,4,5,7] ( \a arr[ 2:6 ] == \a arr[ \a arrI[ 2 ] : 
6785  * \a arrI[ 2+1 ]]); <br> etc.
6786  *  \param [in] targetNb - the size of the set \a B. \a targetNb must be equal or more
6787  *         than the maximal value of \a A.
6788  *  \param [out] arr - a new instance of DataArrayInt returning indices of
6789  *         elements of \a this, grouped by their place in the set \a B. The caller is to delete
6790  *         this array using decrRef() as it is no more needed.
6791  *  \param [out] arrI - a new instance of DataArrayInt returning size of groups of equal
6792  *         elements of \a this. The caller is to delete this array using decrRef() as it
6793  *         is no more needed.
6794  *  \throw If \a this is not allocated.
6795  *  \throw If \a this->getNumberOfComponents() != 1.
6796  *  \throw If any value in \a this is more or equal to \a targetNb.
6797  */
6798 void DataArrayInt::changeSurjectiveFormat(int targetNb, DataArrayInt *&arr, DataArrayInt *&arrI) const throw(INTERP_KERNEL::Exception)
6799 {
6800   checkAllocated();
6801   if(getNumberOfComponents()!=1)
6802     throw INTERP_KERNEL::Exception("DataArrayInt::changeSurjectiveFormat : number of components must == 1 !");
6803   int nbOfTuples=getNumberOfTuples();
6804   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New());
6805   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> retI(DataArrayInt::New());
6806   retI->alloc(targetNb+1,1);
6807   const int *input=getConstPointer();
6808   std::vector< std::vector<int> > tmp(targetNb);
6809   for(int i=0;i<nbOfTuples;i++)
6810     {
6811       int tmp2=input[i];
6812       if(tmp2>=0 && tmp2<targetNb)
6813         tmp[tmp2].push_back(i);
6814       else
6815         {
6816           std::ostringstream oss; oss << "DataArrayInt::changeSurjectiveFormat : At pos " << i << " presence of element " << tmp2 << " ! should be in [0," << targetNb << ") !";
6817           throw INTERP_KERNEL::Exception(oss.str().c_str());
6818         }
6819     }
6820   int *retIPtr=retI->getPointer();
6821   *retIPtr=0;
6822   for(std::vector< std::vector<int> >::const_iterator it1=tmp.begin();it1!=tmp.end();it1++,retIPtr++)
6823     retIPtr[1]=retIPtr[0]+(int)((*it1).size());
6824   if(nbOfTuples!=retI->getIJ(targetNb,0))
6825     throw INTERP_KERNEL::Exception("DataArrayInt::changeSurjectiveFormat : big problem should never happen !");
6826   ret->alloc(nbOfTuples,1);
6827   int *retPtr=ret->getPointer();
6828   for(std::vector< std::vector<int> >::const_iterator it1=tmp.begin();it1!=tmp.end();it1++)
6829     retPtr=std::copy((*it1).begin(),(*it1).end(),retPtr);
6830   arr=ret.retn();
6831   arrI=retI.retn();
6832 }
6833
6834
6835 /*!
6836  * Returns a new DataArrayInt containing a renumbering map in "Old to New" mode computed
6837  * from a zip representation of a surjective format (returned e.g. by
6838  * \ref ParaMEDMEM::DataArrayDouble::findCommonTuples() "DataArrayDouble::findCommonTuples()"
6839  * for example). The result array minimizes the permutation. <br>
6840  * For more info on renumbering see \ref MEDCouplingArrayRenumbering. <br>
6841  * \b Example: <br>
6842  * - \a nbOfOldTuples: 10 
6843  * - \a arr          : [0,3, 5,7,9]
6844  * - \a arrIBg       : [0,2,5]
6845  * - \a newNbOfTuples: 7
6846  * - result array    : [0,1,2,0,3,4,5,4,6,4]
6847  *
6848  *  \param [in] nbOfOldTuples - number of tuples in the initial array \a arr.
6849  *  \param [in] arr - the array of tuple indices grouped by \a arrIBg array.
6850  *  \param [in] arrIBg - the array dividing all indices stored in \a arr into groups of
6851  *         (indices of) equal values. Its every element (except the last one) points to
6852  *         the first element of a group of equal values.
6853  *  \param [in] arrIEnd - specifies the end of \a arrIBg, so that the last element of \a
6854  *          arrIBg is \a arrIEnd[ -1 ].
6855  *  \param [out] newNbOfTuples - number of tuples after surjection application.
6856  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
6857  *          array using decrRef() as it is no more needed.
6858  *  \throw If any value of \a arr breaks condition ( 0 <= \a arr[ i ] < \a nbOfOldTuples ).
6859  */
6860 DataArrayInt *DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2(int nbOfOldTuples, const int *arr, const int *arrIBg, const int *arrIEnd, int &newNbOfTuples) throw(INTERP_KERNEL::Exception)
6861 {
6862   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6863   ret->alloc(nbOfOldTuples,1);
6864   int *pt=ret->getPointer();
6865   std::fill(pt,pt+nbOfOldTuples,-1);
6866   int nbOfGrps=((int)std::distance(arrIBg,arrIEnd))-1;
6867   const int *cIPtr=arrIBg;
6868   for(int i=0;i<nbOfGrps;i++)
6869     pt[arr[cIPtr[i]]]=-(i+2);
6870   int newNb=0;
6871   for(int iNode=0;iNode<nbOfOldTuples;iNode++)
6872     {
6873       if(pt[iNode]<0)
6874         {
6875           if(pt[iNode]==-1)
6876             pt[iNode]=newNb++;
6877           else
6878             {
6879               int grpId=-(pt[iNode]+2);
6880               for(int j=cIPtr[grpId];j<cIPtr[grpId+1];j++)
6881                 {
6882                   if(arr[j]>=0 && arr[j]<nbOfOldTuples)
6883                     pt[arr[j]]=newNb;
6884                   else
6885                     {
6886                       std::ostringstream oss; oss << "DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2 : With element #" << j << " value is " << arr[j] << " should be in [0," << nbOfOldTuples << ") !";
6887                       throw INTERP_KERNEL::Exception(oss.str().c_str());
6888                     }
6889                 }
6890               newNb++;
6891             }
6892         }
6893     }
6894   newNbOfTuples=newNb;
6895   return ret.retn();
6896 }
6897
6898 /*!
6899  * Returns a new DataArrayInt containing a renumbering map in "New to Old" mode,
6900  * which if applied to \a this array would make it sorted ascendingly.
6901  * For more info on renumbering see \ref MEDCouplingArrayRenumbering. <br>
6902  * \b Example: <br>
6903  * - \a this: [2,0,1,1,0,1,2,0,1,1,0,0]
6904  * - result: [10,0,5,6,1,7,11,2,8,9,3,4]
6905  * - after applying result to \a this: [0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2] 
6906  *
6907  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
6908  *          array using decrRef() as it is no more needed.
6909  *  \throw If \a this is not allocated.
6910  *  \throw If \a this->getNumberOfComponents() != 1.
6911  */
6912 DataArrayInt *DataArrayInt::buildPermArrPerLevel() const throw(INTERP_KERNEL::Exception)
6913 {
6914   checkAllocated();
6915   if(getNumberOfComponents()!=1)
6916     throw INTERP_KERNEL::Exception("DataArrayInt::buildPermArrPerLevel : number of components must == 1 !");
6917   int nbOfTuples=getNumberOfTuples();
6918   const int *pt=getConstPointer();
6919   std::map<int,int> m;
6920   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6921   ret->alloc(nbOfTuples,1);
6922   int *opt=ret->getPointer();
6923   for(int i=0;i<nbOfTuples;i++,pt++,opt++)
6924     {
6925       int val=*pt;
6926       std::map<int,int>::iterator it=m.find(val);
6927       if(it!=m.end())
6928         {
6929           *opt=(*it).second;
6930           (*it).second++;
6931         }
6932       else
6933         {
6934           *opt=0;
6935           m.insert(std::pair<int,int>(val,1));
6936         }
6937     }
6938   int sum=0;
6939   for(std::map<int,int>::iterator it=m.begin();it!=m.end();it++)
6940     {
6941       int vt=(*it).second;
6942       (*it).second=sum;
6943       sum+=vt;
6944     }
6945   pt=getConstPointer();
6946   opt=ret->getPointer();
6947   for(int i=0;i<nbOfTuples;i++,pt++,opt++)
6948     *opt+=m[*pt];
6949   //
6950   return ret.retn();
6951 }
6952
6953 /*!
6954  * Checks if contents of \a this array are equal to that of an array filled with
6955  * iota(). This method is particularly useful for DataArrayInt instances that represent
6956  * a renumbering array to check the real need in renumbering. 
6957  *  \return bool - \a true if \a this array contents == \a range( \a this->getNumberOfTuples())
6958  *  \throw If \a this is not allocated.
6959  *  \throw If \a this->getNumberOfComponents() != 1.
6960  */
6961 bool DataArrayInt::isIdentity() const throw(INTERP_KERNEL::Exception)
6962 {
6963   checkAllocated();
6964   if(getNumberOfComponents()!=1)
6965     return false;
6966   int nbOfTuples=getNumberOfTuples();
6967   const int *pt=getConstPointer();
6968   for(int i=0;i<nbOfTuples;i++,pt++)
6969     if(*pt!=i)
6970       return false;
6971   return true;
6972 }
6973
6974 /*!
6975  * Checks if all values in \a this array are equal to \a val.
6976  *  \param [in] val - value to check equality of array values to.
6977  *  \return bool - \a true if all values are \a val.
6978  *  \throw If \a this is not allocated.
6979  *  \throw If \a this->getNumberOfComponents() != 1
6980  */
6981 bool DataArrayInt::isUniform(int val) const throw(INTERP_KERNEL::Exception)
6982 {
6983   checkAllocated();
6984   if(getNumberOfComponents()!=1)
6985     throw INTERP_KERNEL::Exception("DataArrayInt::isUniform : must be applied on DataArrayInt with only one component, you can call 'rearrange' method before !");
6986   int nbOfTuples=getNumberOfTuples();
6987   const int *w=getConstPointer();
6988   const int *end2=w+nbOfTuples;
6989   for(;w!=end2;w++)
6990     if(*w!=val)
6991       return false;
6992   return true;
6993 }
6994
6995 /*!
6996  * Creates a new DataArrayDouble and assigns all (textual and numerical) data of \a this
6997  * array to the new one.
6998  *  \return DataArrayDouble * - the new instance of DataArrayInt.
6999  */
7000 DataArrayDouble *DataArrayInt::convertToDblArr() const
7001 {
7002   checkAllocated();
7003   DataArrayDouble *ret=DataArrayDouble::New();
7004   ret->alloc(getNumberOfTuples(),getNumberOfComponents());
7005   std::size_t nbOfVals=getNbOfElems();
7006   const int *src=getConstPointer();
7007   double *dest=ret->getPointer();
7008   std::copy(src,src+nbOfVals,dest);
7009   ret->copyStringInfoFrom(*this);
7010   return ret;
7011 }
7012
7013 /*!
7014  * Returns a shorten copy of \a this array. The new DataArrayInt contains all
7015  * tuples starting from the \a tupleIdBg-th tuple and including all tuples located before
7016  * the \a tupleIdEnd-th one. This methods has a similar behavior as std::string::substr().
7017  * This method is a specialization of selectByTupleId2().
7018  *  \param [in] tupleIdBg - index of the first tuple to copy from \a this array.
7019  *  \param [in] tupleIdEnd - index of the tuple before which the tuples to copy are located.
7020  *          If \a tupleIdEnd == -1, all the tuples till the end of \a this array are copied.
7021  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
7022  *          is to delete using decrRef() as it is no more needed.
7023  *  \throw If \a tupleIdBg < 0.
7024  *  \throw If \a tupleIdBg > \a this->getNumberOfTuples().
7025     \throw If \a tupleIdEnd != -1 && \a tupleIdEnd < \a this->getNumberOfTuples().
7026  *  \sa DataArrayInt::selectByTupleId2
7027  */
7028 DataArrayInt *DataArrayInt::substr(int tupleIdBg, int tupleIdEnd) const throw(INTERP_KERNEL::Exception)
7029 {
7030   checkAllocated();
7031   int nbt=getNumberOfTuples();
7032   if(tupleIdBg<0)
7033     throw INTERP_KERNEL::Exception("DataArrayInt::substr : The tupleIdBg parameter must be greater than 0 !");
7034   if(tupleIdBg>nbt)
7035     throw INTERP_KERNEL::Exception("DataArrayInt::substr : The tupleIdBg parameter is greater than number of tuples !");
7036   int trueEnd=tupleIdEnd;
7037   if(tupleIdEnd!=-1)
7038     {
7039       if(tupleIdEnd>nbt)
7040         throw INTERP_KERNEL::Exception("DataArrayInt::substr : The tupleIdBg parameter is greater or equal than number of tuples !");
7041     }
7042   else
7043     trueEnd=nbt;
7044   int nbComp=getNumberOfComponents();
7045   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
7046   ret->alloc(trueEnd-tupleIdBg,nbComp);
7047   ret->copyStringInfoFrom(*this);
7048   std::copy(getConstPointer()+tupleIdBg*nbComp,getConstPointer()+trueEnd*nbComp,ret->getPointer());
7049   return ret.retn();
7050 }
7051
7052 /*!
7053  * Changes the number of components within \a this array so that its raw data **does
7054  * not** change, instead splitting this data into tuples changes.
7055  *  \warning This method erases all (name and unit) component info set before!
7056  *  \param [in] newNbOfComp - number of components for \a this array to have.
7057  *  \throw If \a this is not allocated
7058  *  \throw If getNbOfElems() % \a newNbOfCompo != 0.
7059  *  \throw If \a newNbOfCompo is lower than 1.
7060  *  \throw If the rearrange method would lead to a number of tuples higher than 2147483647 (maximal capacity of int32 !).
7061  *  \warning This method erases all (name and unit) component info set before!
7062  */
7063 void DataArrayInt::rearrange(int newNbOfCompo) throw(INTERP_KERNEL::Exception)
7064 {
7065   checkAllocated();
7066   if(newNbOfCompo<1)
7067     throw INTERP_KERNEL::Exception("DataArrayInt::rearrange : input newNbOfCompo must be > 0 !");
7068   std::size_t nbOfElems=getNbOfElems();
7069   if(nbOfElems%newNbOfCompo!=0)
7070     throw INTERP_KERNEL::Exception("DataArrayInt::rearrange : nbOfElems%newNbOfCompo!=0 !");
7071   if(nbOfElems/newNbOfCompo>(std::size_t)std::numeric_limits<int>::max())
7072     throw INTERP_KERNEL::Exception("DataArrayInt::rearrange : the rearrangement leads to too high number of tuples (> 2147483647) !");
7073   _info_on_compo.clear();
7074   _info_on_compo.resize(newNbOfCompo);
7075   declareAsNew();
7076 }
7077
7078 /*!
7079  * Changes the number of components within \a this array to be equal to its number
7080  * of tuples, and inversely its number of tuples to become equal to its number of 
7081  * components. So that its raw data **does not** change, instead splitting this
7082  * data into tuples changes.
7083  *  \warning This method erases all (name and unit) component info set before!
7084  *  \warning Do not confuse this method with fromNoInterlace() and toNoInterlace()!
7085  *  \throw If \a this is not allocated.
7086  *  \sa rearrange()
7087  */
7088 void DataArrayInt::transpose() throw(INTERP_KERNEL::Exception)
7089 {
7090   checkAllocated();
7091   int nbOfTuples=getNumberOfTuples();
7092   rearrange(nbOfTuples);
7093 }
7094
7095 /*!
7096  * Returns a shorten or extended copy of \a this array. If \a newNbOfComp is less
7097  * than \a this->getNumberOfComponents() then the result array is shorten as each tuple
7098  * is truncated to have \a newNbOfComp components, keeping first components. If \a
7099  * newNbOfComp is more than \a this->getNumberOfComponents() then the result array is
7100  * expanded as each tuple is populated with \a dftValue to have \a newNbOfComp
7101  * components.  
7102  *  \param [in] newNbOfComp - number of components for the new array to have.
7103  *  \param [in] dftValue - value assigned to new values added to the new array.
7104  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
7105  *          is to delete using decrRef() as it is no more needed.
7106  *  \throw If \a this is not allocated.
7107  */
7108 DataArrayInt *DataArrayInt::changeNbOfComponents(int newNbOfComp, int dftValue) const throw(INTERP_KERNEL::Exception)
7109 {
7110   checkAllocated();
7111   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
7112   ret->alloc(getNumberOfTuples(),newNbOfComp);
7113   const int *oldc=getConstPointer();
7114   int *nc=ret->getPointer();
7115   int nbOfTuples=getNumberOfTuples();
7116   int oldNbOfComp=getNumberOfComponents();
7117   int dim=std::min(oldNbOfComp,newNbOfComp);
7118   for(int i=0;i<nbOfTuples;i++)
7119     {
7120       int j=0;
7121       for(;j<dim;j++)
7122         nc[newNbOfComp*i+j]=oldc[i*oldNbOfComp+j];
7123       for(;j<newNbOfComp;j++)
7124         nc[newNbOfComp*i+j]=dftValue;
7125     }
7126   ret->setName(getName().c_str());
7127   for(int i=0;i<dim;i++)
7128     ret->setInfoOnComponent(i,getInfoOnComponent(i).c_str());
7129   ret->setName(getName().c_str());
7130   return ret.retn();
7131 }
7132
7133 /*!
7134  * Changes number of tuples in the array. If the new number of tuples is smaller
7135  * than the current number the array is truncated, otherwise the array is extended.
7136  *  \param [in] nbOfTuples - new number of tuples. 
7137  *  \throw If \a this is not allocated.
7138  *  \throw If \a nbOfTuples is negative.
7139  */
7140 void DataArrayInt::reAlloc(int nbOfTuples) throw(INTERP_KERNEL::Exception)
7141 {
7142   if(nbOfTuples<0)
7143     throw INTERP_KERNEL::Exception("DataArrayInt::reAlloc : input new number of tuples should be >=0 !");
7144   checkAllocated();
7145   _mem.reAlloc(getNumberOfComponents()*(std::size_t)nbOfTuples);
7146   declareAsNew();
7147 }
7148
7149
7150 /*!
7151  * Returns a copy of \a this array composed of selected components.
7152  * The new DataArrayInt has the same number of tuples but includes components
7153  * specified by \a compoIds parameter. So that getNbOfElems() of the result array
7154  * can be either less, same or more than \a this->getNbOfElems().
7155  *  \param [in] compoIds - sequence of zero based indices of components to include
7156  *              into the new array.
7157  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
7158  *          is to delete using decrRef() as it is no more needed.
7159  *  \throw If \a this is not allocated.
7160  *  \throw If a component index (\a i) is not valid: 
7161  *         \a i < 0 || \a i >= \a this->getNumberOfComponents().
7162  *
7163  *  \ref py_mcdataarrayint_keepselectedcomponents "Here is a Python example".
7164  */
7165 DataArray *DataArrayInt::keepSelectedComponents(const std::vector<int>& compoIds) const throw(INTERP_KERNEL::Exception)
7166 {
7167   checkAllocated();
7168   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New());
7169   int newNbOfCompo=(int)compoIds.size();
7170   int oldNbOfCompo=getNumberOfComponents();
7171   for(std::vector<int>::const_iterator it=compoIds.begin();it!=compoIds.end();it++)
7172     DataArray::CheckValueInRange(oldNbOfCompo,(*it),"keepSelectedComponents invalid requested component");
7173   int nbOfTuples=getNumberOfTuples();
7174   ret->alloc(nbOfTuples,newNbOfCompo);
7175   ret->copyPartOfStringInfoFrom(*this,compoIds);
7176   const int *oldc=getConstPointer();
7177   int *nc=ret->getPointer();
7178   for(int i=0;i<nbOfTuples;i++)
7179     for(int j=0;j<newNbOfCompo;j++,nc++)
7180       *nc=oldc[i*oldNbOfCompo+compoIds[j]];
7181   return ret.retn();
7182 }
7183
7184 /*!
7185  * Appends components of another array to components of \a this one, tuple by tuple.
7186  * So that the number of tuples of \a this array remains the same and the number of 
7187  * components increases.
7188  *  \param [in] other - the DataArrayInt to append to \a this one.
7189  *  \throw If \a this is not allocated.
7190  *  \throw If \a this and \a other arrays have different number of tuples.
7191  *
7192  *  \ref cpp_mcdataarrayint_meldwith "Here is a C++ example".
7193  *
7194  *  \ref py_mcdataarrayint_meldwith "Here is a Python example".
7195  */
7196 void DataArrayInt::meldWith(const DataArrayInt *other) throw(INTERP_KERNEL::Exception)
7197 {
7198   if(!other)
7199     throw INTERP_KERNEL::Exception("DataArrayInt::meldWith : DataArrayInt pointer in input is NULL !");
7200   checkAllocated();
7201   other->checkAllocated();
7202   int nbOfTuples=getNumberOfTuples();
7203   if(nbOfTuples!=other->getNumberOfTuples())
7204     throw INTERP_KERNEL::Exception("DataArrayInt::meldWith : mismatch of number of tuples !");
7205   int nbOfComp1=getNumberOfComponents();
7206   int nbOfComp2=other->getNumberOfComponents();
7207   int *newArr=(int *)malloc(nbOfTuples*(nbOfComp1+nbOfComp2)*sizeof(int));
7208   int *w=newArr;
7209   const int *inp1=getConstPointer();
7210   const int *inp2=other->getConstPointer();
7211   for(int i=0;i<nbOfTuples;i++,inp1+=nbOfComp1,inp2+=nbOfComp2)
7212     {
7213       w=std::copy(inp1,inp1+nbOfComp1,w);
7214       w=std::copy(inp2,inp2+nbOfComp2,w);
7215     }
7216   useArray(newArr,true,C_DEALLOC,nbOfTuples,nbOfComp1+nbOfComp2);
7217   std::vector<int> compIds(nbOfComp2);
7218   for(int i=0;i<nbOfComp2;i++)
7219     compIds[i]=nbOfComp1+i;
7220   copyPartOfStringInfoFrom2(compIds,*other);
7221 }
7222
7223 /*!
7224  * Copy all components in a specified order from another DataArrayInt.
7225  * The specified components become the first ones in \a this array.
7226  * Both numerical and textual data is copied. The number of tuples in \a this and
7227  * the other array can be different.
7228  *  \param [in] a - the array to copy data from.
7229  *  \param [in] compoIds - sequence of zero based indices of components, data of which is
7230  *              to be copied.
7231  *  \throw If \a a is NULL.
7232  *  \throw If \a compoIds.size() != \a a->getNumberOfComponents().
7233  *  \throw If \a compoIds[i] < 0 or \a compoIds[i] > \a this->getNumberOfComponents().
7234  *
7235  *  \ref py_mcdataarrayint_setselectedcomponents "Here is a Python example".
7236  */
7237 void DataArrayInt::setSelectedComponents(const DataArrayInt *a, const std::vector<int>& compoIds) throw(INTERP_KERNEL::Exception)
7238 {
7239   if(!a)
7240     throw INTERP_KERNEL::Exception("DataArrayInt::setSelectedComponents : input DataArrayInt is NULL !");
7241   checkAllocated();
7242   a->checkAllocated();
7243   copyPartOfStringInfoFrom2(compoIds,*a);
7244   std::size_t partOfCompoSz=compoIds.size();
7245   int nbOfCompo=getNumberOfComponents();
7246   int nbOfTuples=std::min(getNumberOfTuples(),a->getNumberOfTuples());
7247   const int *ac=a->getConstPointer();
7248   int *nc=getPointer();
7249   for(int i=0;i<nbOfTuples;i++)
7250     for(std::size_t j=0;j<partOfCompoSz;j++,ac++)
7251       nc[nbOfCompo*i+compoIds[j]]=*ac;
7252 }
7253
7254 /*!
7255  * Copy all values from another DataArrayInt into specified tuples and components
7256  * of \a this array. Textual data is not copied.
7257  * The tree parameters defining set of indices of tuples and components are similar to
7258  * the tree parameters of the Python function \c range(\c start,\c stop,\c step).
7259  *  \param [in] a - the array to copy values from.
7260  *  \param [in] bgTuples - index of the first tuple of \a this array to assign values to.
7261  *  \param [in] endTuples - index of the tuple before which the tuples to assign to
7262  *              are located.
7263  *  \param [in] stepTuples - index increment to get index of the next tuple to assign to.
7264  *  \param [in] bgComp - index of the first component of \a this array to assign values to.
7265  *  \param [in] endComp - index of the component before which the components to assign
7266  *              to are located.
7267  *  \param [in] stepComp - index increment to get index of the next component to assign to.
7268  *  \param [in] strictCompoCompare - if \a true (by default), then \a a->getNumberOfComponents() 
7269  *              must be equal to the number of columns to assign to, else an
7270  *              exception is thrown; if \a false, then it is only required that \a
7271  *              a->getNbOfElems() equals to number of values to assign to (this condition
7272  *              must be respected even if \a strictCompoCompare is \a true). The number of 
7273  *              values to assign to is given by following Python expression:
7274  *              \a nbTargetValues = 
7275  *              \c len(\c range(\a bgTuples,\a endTuples,\a stepTuples)) *
7276  *              \c len(\c range(\a bgComp,\a endComp,\a stepComp)).
7277  *  \throw If \a a is NULL.
7278  *  \throw If \a a is not allocated.
7279  *  \throw If \a this is not allocated.
7280  *  \throw If parameters specifying tuples and components to assign to do not give a
7281  *            non-empty range of increasing indices.
7282  *  \throw If \a a->getNbOfElems() != \a nbTargetValues.
7283  *  \throw If \a strictCompoCompare == \a true && \a a->getNumberOfComponents() !=
7284  *            \c len(\c range(\a bgComp,\a endComp,\a stepComp)).
7285  *
7286  *  \ref py_mcdataarrayint_setpartofvalues1 "Here is a Python example".
7287  */
7288 void DataArrayInt::setPartOfValues1(const DataArrayInt *a, int bgTuples, int endTuples, int stepTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare) throw(INTERP_KERNEL::Exception)
7289 {
7290   if(!a)
7291     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValues1 : DataArrayInt pointer in input is NULL !");
7292   const char msg[]="DataArrayInt::setPartOfValues1";
7293   checkAllocated();
7294   a->checkAllocated();
7295   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
7296   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
7297   int nbComp=getNumberOfComponents();
7298   int nbOfTuples=getNumberOfTuples();
7299   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
7300   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
7301   bool assignTech=true;
7302   if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
7303     {
7304       if(strictCompoCompare)
7305         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
7306     }
7307   else
7308     {
7309       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
7310       assignTech=false;
7311     }
7312   int *pt=getPointer()+bgTuples*nbComp+bgComp;
7313   const int *srcPt=a->getConstPointer();
7314   if(assignTech)
7315     {
7316       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
7317         for(int j=0;j<newNbOfComp;j++,srcPt++)
7318           pt[j*stepComp]=*srcPt;
7319     }
7320   else
7321     {
7322       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
7323         {
7324           const int *srcPt2=srcPt;
7325           for(int j=0;j<newNbOfComp;j++,srcPt2++)
7326             pt[j*stepComp]=*srcPt2;
7327         }
7328     }
7329 }
7330
7331 /*!
7332  * Assign a given value to values at specified tuples and components of \a this array.
7333  * The tree parameters defining set of indices of tuples and components are similar to
7334  * the tree parameters of the Python function \c range(\c start,\c stop,\c step)..
7335  *  \param [in] a - the value to assign.
7336  *  \param [in] bgTuples - index of the first tuple of \a this array to assign to.
7337  *  \param [in] endTuples - index of the tuple before which the tuples to assign to
7338  *              are located.
7339  *  \param [in] stepTuples - index increment to get index of the next tuple to assign to.
7340  *  \param [in] bgComp - index of the first component of \a this array to assign to.
7341  *  \param [in] endComp - index of the component before which the components to assign
7342  *              to are located.
7343  *  \param [in] stepComp - index increment to get index of the next component to assign to.
7344  *  \throw If \a this is not allocated.
7345  *  \throw If parameters specifying tuples and components to assign to, do not give a
7346  *            non-empty range of increasing indices or indices are out of a valid range
7347  *            for \this array.
7348  *
7349  *  \ref py_mcdataarrayint_setpartofvaluessimple1 "Here is a Python example".
7350  */
7351 void DataArrayInt::setPartOfValuesSimple1(int a, int bgTuples, int endTuples, int stepTuples, int bgComp, int endComp, int stepComp) throw(INTERP_KERNEL::Exception)
7352 {
7353   const char msg[]="DataArrayInt::setPartOfValuesSimple1";
7354   checkAllocated();
7355   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
7356   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
7357   int nbComp=getNumberOfComponents();
7358   int nbOfTuples=getNumberOfTuples();
7359   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
7360   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
7361   int *pt=getPointer()+bgTuples*nbComp+bgComp;
7362   for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
7363     for(int j=0;j<newNbOfComp;j++)
7364       pt[j*stepComp]=a;
7365 }
7366
7367
7368 /*!
7369  * Copy all values from another DataArrayInt (\a a) into specified tuples and 
7370  * components of \a this array. Textual data is not copied.
7371  * The tuples and components to assign to are defined by C arrays of indices.
7372  * There are two *modes of usage*:
7373  * - If \a a->getNbOfElems() equals to number of values to assign to, then every value
7374  *   of \a a is assigned to its own location within \a this array. 
7375  * - If \a a includes one tuple, then all values of \a a are assigned to the specified
7376  *   components of every specified tuple of \a this array. In this mode it is required
7377  *   that \a a->getNumberOfComponents() equals to the number of specified components.
7378  * 
7379  *  \param [in] a - the array to copy values from.
7380  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
7381  *              assign values of \a a to.
7382  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
7383  *              pointer to a tuple index <em>(pi)</em> varies as this: 
7384  *              \a bgTuples <= \a pi < \a endTuples.
7385  *  \param [in] bgComp - pointer to an array of component indices of \a this array to
7386  *              assign values of \a a to.
7387  *  \param [in] endComp - specifies the end of the array \a bgTuples, so that
7388  *              pointer to a component index <em>(pi)</em> varies as this: 
7389  *              \a bgComp <= \a pi < \a endComp.
7390  *  \param [in] strictCompoCompare - this parameter is checked only if the
7391  *               *mode of usage* is the first; if it is \a true (default), 
7392  *               then \a a->getNumberOfComponents() must be equal 
7393  *               to the number of specified columns, else this is not required.
7394  *  \throw If \a a is NULL.
7395  *  \throw If \a a is not allocated.
7396  *  \throw If \a this is not allocated.
7397  *  \throw If any index of tuple/component given by <em>bgTuples / bgComp</em> is
7398  *         out of a valid range for \a this array.
7399  *  \throw In the first *mode of usage*, if <em>strictCompoCompare == true </em> and
7400  *         if <em> a->getNumberOfComponents() != (endComp - bgComp) </em>.
7401  *  \throw In the second *mode of usage*, if \a a->getNumberOfTuples() != 1 or
7402  *         <em> a->getNumberOfComponents() != (endComp - bgComp)</em>.
7403  *
7404  *  \ref py_mcdataarrayint_setpartofvalues2 "Here is a Python example".
7405  */
7406 void DataArrayInt::setPartOfValues2(const DataArrayInt *a, const int *bgTuples, const int *endTuples, const int *bgComp, const int *endComp, bool strictCompoCompare) throw(INTERP_KERNEL::Exception)
7407 {
7408   if(!a)
7409     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValues2 : DataArrayInt pointer in input is NULL !");
7410   const char msg[]="DataArrayInt::setPartOfValues2";
7411   checkAllocated();
7412   a->checkAllocated();
7413   int nbComp=getNumberOfComponents();
7414   int nbOfTuples=getNumberOfTuples();
7415   for(const int *z=bgComp;z!=endComp;z++)
7416     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
7417   int newNbOfTuples=(int)std::distance(bgTuples,endTuples);
7418   int newNbOfComp=(int)std::distance(bgComp,endComp);
7419   bool assignTech=true;
7420   if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
7421     {
7422       if(strictCompoCompare)
7423         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
7424     }
7425   else
7426     {
7427       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
7428       assignTech=false;
7429     }
7430   int *pt=getPointer();
7431   const int *srcPt=a->getConstPointer();
7432   if(assignTech)
7433     {    
7434       for(const int *w=bgTuples;w!=endTuples;w++)
7435         {
7436           DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
7437           for(const int *z=bgComp;z!=endComp;z++,srcPt++)
7438             {    
7439               pt[(std::size_t)(*w)*nbComp+(*z)]=*srcPt;
7440             }
7441         }
7442     }
7443   else
7444     {
7445       for(const int *w=bgTuples;w!=endTuples;w++)
7446         {
7447           const int *srcPt2=srcPt;
7448           DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
7449           for(const int *z=bgComp;z!=endComp;z++,srcPt2++)
7450             {    
7451               pt[(std::size_t)(*w)*nbComp+(*z)]=*srcPt2;
7452             }
7453         }
7454     }
7455 }
7456
7457 /*!
7458  * Assign a given value to values at specified tuples and components of \a this array.
7459  * The tuples and components to assign to are defined by C arrays of indices.
7460  *  \param [in] a - the value to assign.
7461  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
7462  *              assign \a a to.
7463  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
7464  *              pointer to a tuple index (\a pi) varies as this: 
7465  *              \a bgTuples <= \a pi < \a endTuples.
7466  *  \param [in] bgComp - pointer to an array of component indices of \a this array to
7467  *              assign \a a to.
7468  *  \param [in] endComp - specifies the end of the array \a bgTuples, so that
7469  *              pointer to a component index (\a pi) varies as this: 
7470  *              \a bgComp <= \a pi < \a endComp.
7471  *  \throw If \a this is not allocated.
7472  *  \throw If any index of tuple/component given by <em>bgTuples / bgComp</em> is
7473  *         out of a valid range for \a this array.
7474  *
7475  *  \ref py_mcdataarrayint_setpartofvaluessimple2 "Here is a Python example".
7476  */
7477 void DataArrayInt::setPartOfValuesSimple2(int a, const int *bgTuples, const int *endTuples, const int *bgComp, const int *endComp) throw(INTERP_KERNEL::Exception)
7478 {
7479   checkAllocated();
7480   int nbComp=getNumberOfComponents();
7481   int nbOfTuples=getNumberOfTuples();
7482   for(const int *z=bgComp;z!=endComp;z++)
7483     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
7484   int *pt=getPointer();
7485   for(const int *w=bgTuples;w!=endTuples;w++)
7486     for(const int *z=bgComp;z!=endComp;z++)
7487       {
7488         DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
7489         pt[(std::size_t)(*w)*nbComp+(*z)]=a;
7490       }
7491 }
7492
7493 /*!
7494  * Copy all values from another DataArrayInt (\a a) into specified tuples and 
7495  * components of \a this array. Textual data is not copied.
7496  * The tuples to assign to are defined by a C array of indices.
7497  * The components to assign to are defined by three values similar to parameters of
7498  * the Python function \c range(\c start,\c stop,\c step).
7499  * There are two *modes of usage*:
7500  * - If \a a->getNbOfElems() equals to number of values to assign to, then every value
7501  *   of \a a is assigned to its own location within \a this array. 
7502  * - If \a a includes one tuple, then all values of \a a are assigned to the specified
7503  *   components of every specified tuple of \a this array. In this mode it is required
7504  *   that \a a->getNumberOfComponents() equals to the number of specified components.
7505  *
7506  *  \param [in] a - the array to copy values from.
7507  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
7508  *              assign values of \a a to.
7509  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
7510  *              pointer to a tuple index <em>(pi)</em> varies as this: 
7511  *              \a bgTuples <= \a pi < \a endTuples.
7512  *  \param [in] bgComp - index of the first component of \a this array to assign to.
7513  *  \param [in] endComp - index of the component before which the components to assign
7514  *              to are located.
7515  *  \param [in] stepComp - index increment to get index of the next component to assign to.
7516  *  \param [in] strictCompoCompare - this parameter is checked only in the first
7517  *               *mode of usage*; if \a strictCompoCompare is \a true (default), 
7518  *               then \a a->getNumberOfComponents() must be equal 
7519  *               to the number of specified columns, else this is not required.
7520  *  \throw If \a a is NULL.
7521  *  \throw If \a a is not allocated.
7522  *  \throw If \a this is not allocated.
7523  *  \throw If any index of tuple given by \a bgTuples is out of a valid range for 
7524  *         \a this array.
7525  *  \throw In the first *mode of usage*, if <em>strictCompoCompare == true </em> and
7526  *         if <em> a->getNumberOfComponents()</em> is unequal to the number of components
7527  *         defined by <em>(bgComp,endComp,stepComp)</em>.
7528  *  \throw In the second *mode of usage*, if \a a->getNumberOfTuples() != 1 or
7529  *         <em> a->getNumberOfComponents()</em> is unequal to the number of components
7530  *         defined by <em>(bgComp,endComp,stepComp)</em>.
7531  *  \throw If parameters specifying components to assign to, do not give a
7532  *            non-empty range of increasing indices or indices are out of a valid range
7533  *            for \this array.
7534  *
7535  *  \ref py_mcdataarrayint_setpartofvalues3 "Here is a Python example".
7536  */
7537 void DataArrayInt::setPartOfValues3(const DataArrayInt *a, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare) throw(INTERP_KERNEL::Exception)
7538 {
7539   if(!a)
7540     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValues3 : DataArrayInt pointer in input is NULL !");
7541   const char msg[]="DataArrayInt::setPartOfValues3";
7542   checkAllocated();
7543   a->checkAllocated();
7544   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
7545   int nbComp=getNumberOfComponents();
7546   int nbOfTuples=getNumberOfTuples();
7547   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
7548   int newNbOfTuples=(int)std::distance(bgTuples,endTuples);
7549   bool assignTech=true;
7550   if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
7551     {
7552       if(strictCompoCompare)
7553         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
7554     }
7555   else
7556     {
7557       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
7558       assignTech=false;
7559     }
7560   int *pt=getPointer()+bgComp;
7561   const int *srcPt=a->getConstPointer();
7562   if(assignTech)
7563     {
7564       for(const int *w=bgTuples;w!=endTuples;w++)
7565         for(int j=0;j<newNbOfComp;j++,srcPt++)
7566           {
7567             DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
7568             pt[(std::size_t)(*w)*nbComp+j*stepComp]=*srcPt;
7569           }
7570     }
7571   else
7572     {
7573       for(const int *w=bgTuples;w!=endTuples;w++)
7574         {
7575           const int *srcPt2=srcPt;
7576           for(int j=0;j<newNbOfComp;j++,srcPt2++)
7577             {
7578               DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
7579               pt[(std::size_t)(*w)*nbComp+j*stepComp]=*srcPt2;
7580             }
7581         }
7582     }
7583 }
7584
7585 /*!
7586  * Assign a given value to values at specified tuples and components of \a this array.
7587  * The tuples to assign to are defined by a C array of indices.
7588  * The components to assign to are defined by three values similar to parameters of
7589  * the Python function \c range(\c start,\c stop,\c step).
7590  *  \param [in] a - the value to assign.
7591  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
7592  *              assign \a a to.
7593  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
7594  *              pointer to a tuple index <em>(pi)</em> varies as this: 
7595  *              \a bgTuples <= \a pi < \a endTuples.
7596  *  \param [in] bgComp - index of the first component of \a this array to assign to.
7597  *  \param [in] endComp - index of the component before which the components to assign
7598  *              to are located.
7599  *  \param [in] stepComp - index increment to get index of the next component to assign to.
7600  *  \throw If \a this is not allocated.
7601  *  \throw If any index of tuple given by \a bgTuples is out of a valid range for 
7602  *         \a this array.
7603  *  \throw If parameters specifying components to assign to, do not give a
7604  *            non-empty range of increasing indices or indices are out of a valid range
7605  *            for \this array.
7606  *
7607  *  \ref py_mcdataarrayint_setpartofvaluessimple3 "Here is a Python example".
7608  */
7609 void DataArrayInt::setPartOfValuesSimple3(int a, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp) throw(INTERP_KERNEL::Exception)
7610 {
7611   const char msg[]="DataArrayInt::setPartOfValuesSimple3";
7612   checkAllocated();
7613   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
7614   int nbComp=getNumberOfComponents();
7615   int nbOfTuples=getNumberOfTuples();
7616   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
7617   int *pt=getPointer()+bgComp;
7618   for(const int *w=bgTuples;w!=endTuples;w++)
7619     for(int j=0;j<newNbOfComp;j++)
7620       {
7621         DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
7622         pt[(std::size_t)(*w)*nbComp+j*stepComp]=a;
7623       }
7624 }
7625
7626 void DataArrayInt::setPartOfValues4(const DataArrayInt *a, int bgTuples, int endTuples, int stepTuples, const int *bgComp, const int *endComp, bool strictCompoCompare) throw(INTERP_KERNEL::Exception)
7627 {
7628   if(!a)
7629     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValues4 : input DataArrayInt is NULL !");
7630   const char msg[]="DataArrayInt::setPartOfValues4";
7631   checkAllocated();
7632   a->checkAllocated();
7633   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
7634   int newNbOfComp=(int)std::distance(bgComp,endComp);
7635   int nbComp=getNumberOfComponents();
7636   for(const int *z=bgComp;z!=endComp;z++)
7637     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
7638   int nbOfTuples=getNumberOfTuples();
7639   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
7640   bool assignTech=true;
7641   if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
7642     {
7643       if(strictCompoCompare)
7644         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
7645     }
7646   else
7647     {
7648       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
7649       assignTech=false;
7650     }
7651   const int *srcPt=a->getConstPointer();
7652   int *pt=getPointer()+bgTuples*nbComp;
7653   if(assignTech)
7654     {
7655       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
7656         for(const int *z=bgComp;z!=endComp;z++,srcPt++)
7657           pt[*z]=*srcPt;
7658     }
7659   else
7660     {
7661       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
7662         {
7663           const int *srcPt2=srcPt;
7664           for(const int *z=bgComp;z!=endComp;z++,srcPt2++)
7665             pt[*z]=*srcPt2;
7666         }
7667     }
7668 }
7669
7670 void DataArrayInt::setPartOfValuesSimple4(int a, int bgTuples, int endTuples, int stepTuples, const int *bgComp, const int *endComp) throw(INTERP_KERNEL::Exception)
7671 {
7672   const char msg[]="DataArrayInt::setPartOfValuesSimple4";
7673   checkAllocated();
7674   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
7675   int nbComp=getNumberOfComponents();
7676   for(const int *z=bgComp;z!=endComp;z++)
7677     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
7678   int nbOfTuples=getNumberOfTuples();
7679   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
7680   int *pt=getPointer()+bgTuples*nbComp;
7681   for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
7682     for(const int *z=bgComp;z!=endComp;z++)
7683       pt[*z]=a;
7684 }
7685
7686 /*!
7687  * Copy some tuples from another DataArrayInt into specified tuples
7688  * of \a this array. Textual data is not copied. Both arrays must have equal number of
7689  * components.
7690  * Both the tuples to assign and the tuples to assign to are defined by a DataArrayInt.
7691  * All components of selected tuples are copied.
7692  *  \param [in] a - the array to copy values from.
7693  *  \param [in] tuplesSelec - the array specifying both source tuples of \a a and
7694  *              target tuples of \a this. \a tuplesSelec has two components, and the
7695  *              first component specifies index of the source tuple and the second
7696  *              one specifies index of the target tuple.
7697  *  \throw If \a this is not allocated.
7698  *  \throw If \a a is NULL.
7699  *  \throw If \a a is not allocated.
7700  *  \throw If \a tuplesSelec is NULL.
7701  *  \throw If \a tuplesSelec is not allocated.
7702  *  \throw If <em>this->getNumberOfComponents() != a->getNumberOfComponents()</em>.
7703  *  \throw If \a tuplesSelec->getNumberOfComponents() != 2.
7704  *  \throw If any tuple index given by \a tuplesSelec is out of a valid range for 
7705  *         the corresponding (\a this or \a a) array.
7706  */
7707 void DataArrayInt::setPartOfValuesAdv(const DataArrayInt *a, const DataArrayInt *tuplesSelec) throw(INTERP_KERNEL::Exception)
7708 {
7709   if(!a || !tuplesSelec)
7710     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValuesAdv : DataArrayInt pointer in input is NULL !");
7711   checkAllocated();
7712   a->checkAllocated();
7713   tuplesSelec->checkAllocated();
7714   int nbOfComp=getNumberOfComponents();
7715   if(nbOfComp!=a->getNumberOfComponents())
7716     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValuesAdv : This and a do not have the same number of components !");
7717   if(tuplesSelec->getNumberOfComponents()!=2)
7718     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValuesAdv : Expecting to have a tuple selector DataArrayInt instance with exactly 2 components !");
7719   int thisNt=getNumberOfTuples();
7720   int aNt=a->getNumberOfTuples();
7721   int *valsToSet=getPointer();
7722   const int *valsSrc=a->getConstPointer();
7723   for(const int *tuple=tuplesSelec->begin();tuple!=tuplesSelec->end();tuple+=2)
7724     {
7725       if(tuple[1]>=0 && tuple[1]<aNt)
7726         {
7727           if(tuple[0]>=0 && tuple[0]<thisNt)
7728             std::copy(valsSrc+nbOfComp*tuple[1],valsSrc+nbOfComp*(tuple[1]+1),valsToSet+nbOfComp*tuple[0]);
7729           else
7730             {
7731               std::ostringstream oss; oss << "DataArrayInt::setPartOfValuesAdv : Tuple #" << std::distance(tuplesSelec->begin(),tuple)/2;
7732               oss << " of 'tuplesSelec' request of tuple id #" << tuple[0] << " in 'this' ! It should be in [0," << thisNt << ") !";
7733               throw INTERP_KERNEL::Exception(oss.str().c_str());
7734             }
7735         }
7736       else
7737         {
7738           std::ostringstream oss; oss << "DataArrayInt::setPartOfValuesAdv : Tuple #" << std::distance(tuplesSelec->begin(),tuple)/2;
7739           oss << " of 'tuplesSelec' request of tuple id #" << tuple[1] << " in 'a' ! It should be in [0," << aNt << ") !";
7740           throw INTERP_KERNEL::Exception(oss.str().c_str());
7741         }
7742     }
7743 }
7744
7745 /*!
7746  * Copy some tuples from another DataArrayInt (\a a) into contiguous tuples
7747  * of \a this array. Textual data is not copied. Both arrays must have equal number of
7748  * components.
7749  * The tuples to assign to are defined by index of the first tuple, and
7750  * their number is defined by \a tuplesSelec->getNumberOfTuples().
7751  * The tuples to copy are defined by values of a DataArrayInt.
7752  * All components of selected tuples are copied.
7753  *  \param [in] tupleIdStart - index of the first tuple of \a this array to assign
7754  *              values to.
7755  *  \param [in] a - the array to copy values from.
7756  *  \param [in] tuplesSelec - the array specifying tuples of \a a to copy.
7757  *  \throw If \a this is not allocated.
7758  *  \throw If \a a is NULL.
7759  *  \throw If \a a is not allocated.
7760  *  \throw If \a tuplesSelec is NULL.
7761  *  \throw If \a tuplesSelec is not allocated.
7762  *  \throw If <em>this->getNumberOfComponents() != a->getNumberOfComponents()</em>.
7763  *  \throw If \a tuplesSelec->getNumberOfComponents() != 1.
7764  *  \throw If <em>tupleIdStart + tuplesSelec->getNumberOfTuples() > this->getNumberOfTuples().</em>
7765  *  \throw If any tuple index given by \a tuplesSelec is out of a valid range for 
7766  *         \a a array.
7767  */
7768 void DataArrayInt::setContigPartOfSelectedValues(int tupleIdStart, const DataArray *aBase, const DataArrayInt *tuplesSelec) throw(INTERP_KERNEL::Exception)
7769 {
7770   if(!aBase || !tuplesSelec)
7771     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues : input DataArray is NULL !");
7772   const DataArrayInt *a=dynamic_cast<const DataArrayInt *>(aBase);
7773   if(!a)
7774     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues : input DataArray aBase is not a DataArrayInt !");
7775   checkAllocated();
7776   a->checkAllocated();
7777   tuplesSelec->checkAllocated();
7778   int nbOfComp=getNumberOfComponents();
7779   if(nbOfComp!=a->getNumberOfComponents())
7780     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues : This and a do not have the same number of components !");
7781   if(tuplesSelec->getNumberOfComponents()!=1)
7782     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues : Expecting to have a tuple selector DataArrayInt instance with exactly 1 component !");
7783   int thisNt=getNumberOfTuples();
7784   int aNt=a->getNumberOfTuples();
7785   int nbOfTupleToWrite=tuplesSelec->getNumberOfTuples();
7786   int *valsToSet=getPointer()+tupleIdStart*nbOfComp;
7787   if(tupleIdStart+nbOfTupleToWrite>thisNt)
7788     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues : invalid number range of values to write !");
7789   const int *valsSrc=a->getConstPointer();
7790   for(const int *tuple=tuplesSelec->begin();tuple!=tuplesSelec->end();tuple++,valsToSet+=nbOfComp)
7791     {
7792       if(*tuple>=0 && *tuple<aNt)
7793         {
7794           std::copy(valsSrc+nbOfComp*(*tuple),valsSrc+nbOfComp*(*tuple+1),valsToSet);
7795         }
7796       else
7797         {
7798           std::ostringstream oss; oss << "DataArrayInt::setContigPartOfSelectedValues : Tuple #" << std::distance(tuplesSelec->begin(),tuple);
7799           oss << " of 'tuplesSelec' request of tuple id #" << *tuple << " in 'a' ! It should be in [0," << aNt << ") !";
7800           throw INTERP_KERNEL::Exception(oss.str().c_str());
7801         }
7802     }
7803 }
7804
7805 /*!
7806  * Copy some tuples from another DataArrayInt (\a a) into contiguous tuples
7807  * of \a this array. Textual data is not copied. Both arrays must have equal number of
7808  * components.
7809  * The tuples to copy are defined by three values similar to parameters of
7810  * the Python function \c range(\c start,\c stop,\c step).
7811  * The tuples to assign to are defined by index of the first tuple, and
7812  * their number is defined by number of tuples to copy.
7813  * All components of selected tuples are copied.
7814  *  \param [in] tupleIdStart - index of the first tuple of \a this array to assign
7815  *              values to.
7816  *  \param [in] a - the array to copy values from.
7817  *  \param [in] bg - index of the first tuple to copy of the array \a a.
7818  *  \param [in] end2 - index of the tuple of \a a before which the tuples to copy
7819  *              are located.
7820  *  \param [in] step - index increment to get index of the next tuple to copy.
7821  *  \throw If \a this is not allocated.
7822  *  \throw If \a a is NULL.
7823  *  \throw If \a a is not allocated.
7824  *  \throw If <em>this->getNumberOfComponents() != a->getNumberOfComponents()</em>.
7825  *  \throw If <em>tupleIdStart + len(range(bg,end2,step)) > this->getNumberOfTuples().</em>
7826  *  \throw If parameters specifying tuples to copy, do not give a
7827  *            non-empty range of increasing indices or indices are out of a valid range
7828  *            for the array \a a.
7829  */
7830 void DataArrayInt::setContigPartOfSelectedValues2(int tupleIdStart, const DataArray *aBase, int bg, int end2, int step) throw(INTERP_KERNEL::Exception)
7831 {
7832   if(!aBase)
7833     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues2 : input DataArray is NULL !");
7834   const DataArrayInt *a=dynamic_cast<const DataArrayInt *>(aBase);
7835   if(!a)
7836     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues2 : input DataArray aBase is not a DataArrayInt !");
7837   checkAllocated();
7838   a->checkAllocated();
7839   int nbOfComp=getNumberOfComponents();
7840   const char msg[]="DataArrayInt::setContigPartOfSelectedValues2";
7841   int nbOfTupleToWrite=DataArray::GetNumberOfItemGivenBES(bg,end2,step,msg);
7842   if(nbOfComp!=a->getNumberOfComponents())
7843     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues2 : This and a do not have the same number of components !");
7844   int thisNt=getNumberOfTuples();
7845   int aNt=a->getNumberOfTuples();
7846   int *valsToSet=getPointer()+tupleIdStart*nbOfComp;
7847   if(tupleIdStart+nbOfTupleToWrite>thisNt)
7848     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues2 : invalid number range of values to write !");
7849   if(end2>aNt)
7850     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues2 : invalid range of values to read !");
7851   const int *valsSrc=a->getConstPointer()+bg*nbOfComp;
7852   for(int i=0;i<nbOfTupleToWrite;i++,valsToSet+=nbOfComp,valsSrc+=step*nbOfComp)
7853     {
7854       std::copy(valsSrc,valsSrc+nbOfComp,valsToSet);
7855     }
7856 }
7857
7858 /*!
7859  * Returns a value located at specified tuple and component.
7860  * This method is equivalent to DataArrayInt::getIJ() except that validity of
7861  * parameters is checked. So this method is safe but expensive if used to go through
7862  * all values of \a this.
7863  *  \param [in] tupleId - index of tuple of interest.
7864  *  \param [in] compoId - index of component of interest.
7865  *  \return double - value located by \a tupleId and \a compoId.
7866  *  \throw If \a this is not allocated.
7867  *  \throw If condition <em>( 0 <= tupleId < this->getNumberOfTuples() )</em> is violated.
7868  *  \throw If condition <em>( 0 <= compoId < this->getNumberOfComponents() )</em> is violated.
7869  */
7870 int DataArrayInt::getIJSafe(int tupleId, int compoId) const throw(INTERP_KERNEL::Exception)
7871 {
7872   checkAllocated();
7873   if(tupleId<0 || tupleId>=getNumberOfTuples())
7874     {
7875       std::ostringstream oss; oss << "DataArrayInt::getIJSafe : request for tupleId " << tupleId << " should be in [0," << getNumberOfTuples() << ") !";
7876       throw INTERP_KERNEL::Exception(oss.str().c_str());
7877     }
7878   if(compoId<0 || compoId>=getNumberOfComponents())
7879     {
7880       std::ostringstream oss; oss << "DataArrayInt::getIJSafe : request for compoId " << compoId << " should be in [0," << getNumberOfComponents() << ") !";
7881       throw INTERP_KERNEL::Exception(oss.str().c_str());
7882     }
7883   return _mem[tupleId*_info_on_compo.size()+compoId];
7884 }
7885
7886 /*!
7887  * Returns the first value of \a this. 
7888  *  \return int - the last value of \a this array.
7889  *  \throw If \a this is not allocated.
7890  *  \throw If \a this->getNumberOfComponents() != 1.
7891  *  \throw If \a this->getNumberOfTuples() < 1.
7892  */
7893 int DataArrayInt::front() const throw(INTERP_KERNEL::Exception)
7894 {
7895   checkAllocated();
7896   if(getNumberOfComponents()!=1)
7897     throw INTERP_KERNEL::Exception("DataArrayInt::front : number of components not equal to one !");
7898   int nbOfTuples=getNumberOfTuples();
7899   if(nbOfTuples<1)
7900     throw INTERP_KERNEL::Exception("DataArrayInt::front : number of tuples must be >= 1 !");
7901   return *(getConstPointer());
7902 }
7903
7904 /*!
7905  * Returns the last value of \a this. 
7906  *  \return int - the last value of \a this array.
7907  *  \throw If \a this is not allocated.
7908  *  \throw If \a this->getNumberOfComponents() != 1.
7909  *  \throw If \a this->getNumberOfTuples() < 1.
7910  */
7911 int DataArrayInt::back() const throw(INTERP_KERNEL::Exception)
7912 {
7913   checkAllocated();
7914   if(getNumberOfComponents()!=1)
7915     throw INTERP_KERNEL::Exception("DataArrayInt::back : number of components not equal to one !");
7916   int nbOfTuples=getNumberOfTuples();
7917   if(nbOfTuples<1)
7918     throw INTERP_KERNEL::Exception("DataArrayInt::back : number of tuples must be >= 1 !");
7919   return *(getConstPointer()+nbOfTuples-1);
7920 }
7921
7922 /*!
7923  * Assign pointer to one array to a pointer to another appay. Reference counter of
7924  * \a arrayToSet is incremented / decremented.
7925  *  \param [in] newArray - the pointer to array to assign to \a arrayToSet.
7926  *  \param [in,out] arrayToSet - the pointer to array to assign to.
7927  */
7928 void DataArrayInt::SetArrayIn(DataArrayInt *newArray, DataArrayInt* &arrayToSet)
7929 {
7930   if(newArray!=arrayToSet)
7931     {
7932       if(arrayToSet)
7933         arrayToSet->decrRef();
7934       arrayToSet=newArray;
7935       if(arrayToSet)
7936         arrayToSet->incrRef();
7937     }
7938 }
7939
7940 DataArrayIntIterator *DataArrayInt::iterator() throw(INTERP_KERNEL::Exception)
7941 {
7942   return new DataArrayIntIterator(this);
7943 }
7944
7945 /*!
7946  * Creates a new DataArrayInt containing IDs (indices) of tuples holding value equal to a
7947  * given one.
7948  *  \param [in] val - the value to find within \a this.
7949  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
7950  *          array using decrRef() as it is no more needed.
7951  *  \throw If \a this is not allocated.
7952  *  \throw If \a this->getNumberOfComponents() != 1.
7953  */
7954 DataArrayInt *DataArrayInt::getIdsEqual(int val) const throw(INTERP_KERNEL::Exception)
7955 {
7956   checkAllocated();
7957   if(getNumberOfComponents()!=1)
7958     throw INTERP_KERNEL::Exception("DataArrayInt::getIdsEqual : the array must have only one component, you can call 'rearrange' method before !");
7959   const int *cptr=getConstPointer();
7960   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
7961   int nbOfTuples=getNumberOfTuples();
7962   for(int i=0;i<nbOfTuples;i++,cptr++)
7963     if(*cptr==val)
7964       ret->pushBackSilent(i);
7965   return ret.retn();
7966 }
7967
7968 /*!
7969  * Creates a new DataArrayInt containing IDs (indices) of tuples holding value \b not
7970  * equal to a given one. 
7971  *  \param [in] val - the value to ignore within \a this.
7972  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
7973  *          array using decrRef() as it is no more needed.
7974  *  \throw If \a this is not allocated.
7975  *  \throw If \a this->getNumberOfComponents() != 1.
7976  */
7977 DataArrayInt *DataArrayInt::getIdsNotEqual(int val) const throw(INTERP_KERNEL::Exception)
7978 {
7979   checkAllocated();
7980   if(getNumberOfComponents()!=1)
7981     throw INTERP_KERNEL::Exception("DataArrayInt::getIdsNotEqual : the array must have only one component, you can call 'rearrange' method before !");
7982   const int *cptr=getConstPointer();
7983   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
7984   int nbOfTuples=getNumberOfTuples();
7985   for(int i=0;i<nbOfTuples;i++,cptr++)
7986     if(*cptr!=val)
7987       ret->pushBackSilent(i);
7988   return ret.retn();
7989 }
7990
7991
7992 /*!
7993  * Assigns \a newValue to all elements holding \a oldValue within \a this
7994  * one-dimensional array.
7995  *  \param [in] oldValue - the value to replace.
7996  *  \param [in] newValue - the value to assign.
7997  *  \return int - number of replacements performed.
7998  *  \throw If \a this is not allocated.
7999  *  \throw If \a this->getNumberOfComponents() != 1.
8000  */
8001 int DataArrayInt::changeValue(int oldValue, int newValue) throw(INTERP_KERNEL::Exception)
8002 {
8003   checkAllocated();
8004   if(getNumberOfComponents()!=1)
8005     throw INTERP_KERNEL::Exception("DataArrayInt::changeValue : the array must have only one component, you can call 'rearrange' method before !");
8006   int *start=getPointer();
8007   int *end2=start+getNbOfElems();
8008   int ret=0;
8009   for(int *val=start;val!=end2;val++)
8010     {
8011       if(*val==oldValue)
8012         {
8013           *val=newValue;
8014           ret++;
8015         }
8016     }
8017   return ret;
8018 }
8019
8020 /*!
8021  * Creates a new DataArrayInt containing IDs (indices) of tuples holding value equal to
8022  * one of given values.
8023  *  \param [in] valsBg - an array of values to find within \a this array.
8024  *  \param [in] valsEnd - specifies the end of the array \a valsBg, so that
8025  *              the last value of \a valsBg is \a valsEnd[ -1 ].
8026  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
8027  *          array using decrRef() as it is no more needed.
8028  *  \throw If \a this->getNumberOfComponents() != 1.
8029  */
8030 DataArrayInt *DataArrayInt::getIdsEqualList(const int *valsBg, const int *valsEnd) const throw(INTERP_KERNEL::Exception)
8031 {
8032   if(getNumberOfComponents()!=1)
8033     throw INTERP_KERNEL::Exception("DataArrayInt::getIdsEqualList : the array must have only one component, you can call 'rearrange' method before !");
8034   std::set<int> vals2(valsBg,valsEnd);
8035   const int *cptr=getConstPointer();
8036   std::vector<int> res;
8037   int nbOfTuples=getNumberOfTuples();
8038   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
8039   for(int i=0;i<nbOfTuples;i++,cptr++)
8040     if(vals2.find(*cptr)!=vals2.end())
8041       ret->pushBackSilent(i);
8042   return ret.retn();
8043 }
8044
8045 /*!
8046  * Creates a new DataArrayInt containing IDs (indices) of tuples holding values \b not
8047  * equal to any of given values.
8048  *  \param [in] valsBg - an array of values to ignore within \a this array.
8049  *  \param [in] valsEnd - specifies the end of the array \a valsBg, so that
8050  *              the last value of \a valsBg is \a valsEnd[ -1 ].
8051  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
8052  *          array using decrRef() as it is no more needed.
8053  *  \throw If \a this->getNumberOfComponents() != 1.
8054  */
8055 DataArrayInt *DataArrayInt::getIdsNotEqualList(const int *valsBg, const int *valsEnd) const throw(INTERP_KERNEL::Exception)
8056 {
8057   if(getNumberOfComponents()!=1)
8058     throw INTERP_KERNEL::Exception("DataArrayInt::getIdsNotEqualList : the array must have only one component, you can call 'rearrange' method before !");
8059   std::set<int> vals2(valsBg,valsEnd);
8060   const int *cptr=getConstPointer();
8061   std::vector<int> res;
8062   int nbOfTuples=getNumberOfTuples();
8063   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
8064   for(int i=0;i<nbOfTuples;i++,cptr++)
8065     if(vals2.find(*cptr)==vals2.end())
8066       ret->pushBackSilent(i);
8067   return ret.retn();
8068 }
8069
8070 /*!
8071  * This method is an extension of DataArrayInt::locateValue method because this method works for DataArrayInt with
8072  * any number of components excepted 0 (an INTERP_KERNEL::Exception is thrown in this case).
8073  * This method searches in \b this is there is a tuple that matched the input parameter \b tupl.
8074  * If any the tuple id is returned. If not -1 is returned.
8075  * 
8076  * This method throws an INTERP_KERNEL::Exception if the number of components in \b this mismatches with the size of
8077  * the input vector. An INTERP_KERNEL::Exception is thrown too if \b this is not allocated.
8078  *
8079  * \return tuple id where \b tupl is. -1 if no such tuple exists in \b this.
8080  * \sa DataArrayInt::search, DataArrayInt::presenceOfTuple.
8081  */
8082 int DataArrayInt::locateTuple(const std::vector<int>& tupl) const throw(INTERP_KERNEL::Exception)
8083 {
8084   checkAllocated();
8085   int nbOfCompo=getNumberOfComponents();
8086   if(nbOfCompo==0)
8087     throw INTERP_KERNEL::Exception("DataArrayInt::locateTuple : 0 components in 'this' !");
8088   if(nbOfCompo!=(int)tupl.size())
8089     {
8090       std::ostringstream oss; oss << "DataArrayInt::locateTuple : 'this' contains " << nbOfCompo << " components and searching for a tuple of length " << tupl.size() << " !";
8091       throw INTERP_KERNEL::Exception(oss.str().c_str());
8092     }
8093   const int *cptr=getConstPointer();
8094   std::size_t nbOfVals=getNbOfElems();
8095   for(const int *work=cptr;work!=cptr+nbOfVals;)
8096     {
8097       work=std::search(work,cptr+nbOfVals,tupl.begin(),tupl.end());
8098       if(work!=cptr+nbOfVals)
8099         {
8100           if(std::distance(cptr,work)%nbOfCompo!=0)
8101             work++;
8102           else
8103             return std::distance(cptr,work)/nbOfCompo;
8104         }
8105     }
8106   return -1;
8107 }
8108
8109 /*!
8110  * This method searches the sequence specified in input parameter \b vals in \b this.
8111  * This works only for DataArrayInt having number of components equal to one (if not an INTERP_KERNEL::Exception will be thrown).
8112  * This method differs from DataArrayInt::locateTuple in that the position is internal raw data is not considered here contrary to DataArrayInt::locateTuple.
8113  * \sa DataArrayInt::locateTuple
8114  */
8115 int DataArrayInt::search(const std::vector<int>& vals) const throw(INTERP_KERNEL::Exception)
8116 {
8117   checkAllocated();
8118   int nbOfCompo=getNumberOfComponents();
8119   if(nbOfCompo!=1)
8120     throw INTERP_KERNEL::Exception("DataArrayInt::search : works only for DataArrayInt instance with one component !");
8121   const int *cptr=getConstPointer();
8122   std::size_t nbOfVals=getNbOfElems();
8123   const int *loc=std::search(cptr,cptr+nbOfVals,vals.begin(),vals.end());
8124   if(loc!=cptr+nbOfVals)
8125     return std::distance(cptr,loc);
8126   return -1;
8127 }
8128
8129 /*!
8130  * This method expects to be called when number of components of this is equal to one.
8131  * This method returns the tuple id, if it exists, of the first tuple equal to \b value.
8132  * If not any tuple contains \b value -1 is returned.
8133  * \sa DataArrayInt::presenceOfValue
8134  */
8135 int DataArrayInt::locateValue(int value) const throw(INTERP_KERNEL::Exception)
8136 {
8137   checkAllocated();
8138   if(getNumberOfComponents()!=1)
8139     throw INTERP_KERNEL::Exception("DataArrayInt::presenceOfValue : the array must have only one component, you can call 'rearrange' method before !");
8140   const int *cptr=getConstPointer();
8141   int nbOfTuples=getNumberOfTuples();
8142   const int *ret=std::find(cptr,cptr+nbOfTuples,value);
8143   if(ret!=cptr+nbOfTuples)
8144     return std::distance(cptr,ret);
8145   return -1;
8146 }
8147
8148 /*!
8149  * This method expects to be called when number of components of this is equal to one.
8150  * This method returns the tuple id, if it exists, of the first tuple so that the value is contained in \b vals.
8151  * If not any tuple contains one of the values contained in 'vals' false is returned.
8152  * \sa DataArrayInt::presenceOfValue
8153  */
8154 int DataArrayInt::locateValue(const std::vector<int>& vals) const throw(INTERP_KERNEL::Exception)
8155 {
8156   checkAllocated();
8157   if(getNumberOfComponents()!=1)
8158     throw INTERP_KERNEL::Exception("DataArrayInt::presenceOfValue : the array must have only one component, you can call 'rearrange' method before !");
8159   std::set<int> vals2(vals.begin(),vals.end());
8160   const int *cptr=getConstPointer();
8161   int nbOfTuples=getNumberOfTuples();
8162   for(const int *w=cptr;w!=cptr+nbOfTuples;w++)
8163     if(vals2.find(*w)!=vals2.end())
8164       return std::distance(cptr,w);
8165   return -1;
8166 }
8167
8168 /*!
8169  * This method returns the number of values in \a this that are equals to input parameter \a value.
8170  * This method only works for single component array.
8171  *
8172  * \return a value in [ 0, \c this->getNumberOfTuples() )
8173  *
8174  * \throw If \a this is not allocated
8175  *
8176  */
8177 int DataArrayInt::count(int value) const throw(INTERP_KERNEL::Exception)
8178 {
8179   int ret=0;
8180   checkAllocated();
8181   if(getNumberOfComponents()!=1)
8182     throw INTERP_KERNEL::Exception("DataArrayInt::count : must be applied on DataArrayInt with only one component, you can call 'rearrange' method before !");
8183   const int *vals=begin();
8184   int nbOfTuples=getNumberOfTuples();
8185   for(int i=0;i<nbOfTuples;i++,vals++)
8186     if(*vals==value)
8187       ret++;
8188   return ret;
8189 }
8190
8191 /*!
8192  * This method is an extension of DataArrayInt::presenceOfValue method because this method works for DataArrayInt with
8193  * any number of components excepted 0 (an INTERP_KERNEL::Exception is thrown in this case).
8194  * This method searches in \b this is there is a tuple that matched the input parameter \b tupl.
8195  * This method throws an INTERP_KERNEL::Exception if the number of components in \b this mismatches with the size of
8196  * the input vector. An INTERP_KERNEL::Exception is thrown too if \b this is not allocated.
8197  * \sa DataArrayInt::locateTuple
8198  */
8199 bool DataArrayInt::presenceOfTuple(const std::vector<int>& tupl) const throw(INTERP_KERNEL::Exception)
8200 {
8201   return locateTuple(tupl)!=-1;
8202 }
8203
8204
8205 /*!
8206  * Returns \a true if a given value is present within \a this one-dimensional array.
8207  *  \param [in] value - the value to find within \a this array.
8208  *  \return bool - \a true in case if \a value is present within \a this array.
8209  *  \throw If \a this is not allocated.
8210  *  \throw If \a this->getNumberOfComponents() != 1.
8211  *  \sa locateValue()
8212  */
8213 bool DataArrayInt::presenceOfValue(int value) const throw(INTERP_KERNEL::Exception)
8214 {
8215   return locateValue(value)!=-1;
8216 }
8217
8218 /*!
8219  * This method expects to be called when number of components of this is equal to one.
8220  * This method returns true if it exists a tuple so that the value is contained in \b vals.
8221  * If not any tuple contains one of the values contained in 'vals' false is returned.
8222  * \sa DataArrayInt::locateValue
8223  */
8224 bool DataArrayInt::presenceOfValue(const std::vector<int>& vals) const throw(INTERP_KERNEL::Exception)
8225 {
8226   return locateValue(vals)!=-1;
8227 }
8228
8229 /*!
8230  * Accumulates values of each component of \a this array.
8231  *  \param [out] res - an array of length \a this->getNumberOfComponents(), allocated 
8232  *         by the caller, that is filled by this method with sum value for each
8233  *         component.
8234  *  \throw If \a this is not allocated.
8235  */
8236 void DataArrayInt::accumulate(int *res) const throw(INTERP_KERNEL::Exception)
8237 {
8238   checkAllocated();
8239   const int *ptr=getConstPointer();
8240   int nbTuple=getNumberOfTuples();
8241   int nbComps=getNumberOfComponents();
8242   std::fill(res,res+nbComps,0);
8243   for(int i=0;i<nbTuple;i++)
8244     std::transform(ptr+i*nbComps,ptr+(i+1)*nbComps,res,res,std::plus<int>());
8245 }
8246
8247 int DataArrayInt::accumulate(int compId) const throw(INTERP_KERNEL::Exception)
8248 {
8249   checkAllocated();
8250   const int *ptr=getConstPointer();
8251   int nbTuple=getNumberOfTuples();
8252   int nbComps=getNumberOfComponents();
8253   if(compId<0 || compId>=nbComps)
8254     throw INTERP_KERNEL::Exception("DataArrayInt::accumulate : Invalid compId specified : No such nb of components !");
8255   int ret=0;
8256   for(int i=0;i<nbTuple;i++)
8257     ret+=ptr[i*nbComps+compId];
8258   return ret;
8259 }
8260
8261 /*!
8262  * This method accumulate using addition tuples in \a this using input index array [ \a bgOfIndex, \a endOfIndex ).
8263  * The returned array will have same number of components than \a this and number of tuples equal to
8264  * \c std::distance(bgOfIndex,endOfIndex) \b minus \b one.
8265  *
8266  * The input index array is expected to be ascendingly sorted in which the all referenced ids should be in [0, \c this->getNumberOfTuples).
8267  *
8268  * \param [in] bgOfIndex - begin (included) of the input index array.
8269  * \param [in] endOfIndex - end (excluded) of the input index array.
8270  * \return DataArrayInt * - the new instance having the same number of components than \a this.
8271  * 
8272  * \throw If bgOfIndex or end is NULL.
8273  * \throw If input index array is not ascendingly sorted.
8274  * \throw If there is an id in [ \a bgOfIndex, \a endOfIndex ) not in [0, \c this->getNumberOfTuples).
8275  * \throw If std::distance(bgOfIndex,endOfIndex)==0.
8276  */
8277 DataArrayInt *DataArrayInt::accumulatePerChunck(const int *bgOfIndex, const int *endOfIndex) const throw(INTERP_KERNEL::Exception)
8278 {
8279   if(!bgOfIndex || !endOfIndex)
8280     throw INTERP_KERNEL::Exception("DataArrayInt::accumulatePerChunck : input pointer NULL !");
8281   checkAllocated();
8282   int nbCompo=getNumberOfComponents();
8283   int nbOfTuples=getNumberOfTuples();
8284   int sz=(int)std::distance(bgOfIndex,endOfIndex);
8285   if(sz<1)
8286     throw INTERP_KERNEL::Exception("DataArrayInt::accumulatePerChunck : invalid size of input index array !");
8287   sz--;
8288   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(sz,nbCompo);
8289   const int *w=bgOfIndex;
8290   if(*w<0 || *w>=nbOfTuples)
8291     throw INTERP_KERNEL::Exception("DataArrayInt::accumulatePerChunck : The first element of the input index not in [0,nbOfTuples) !");
8292   const int *srcPt=begin()+(*w)*nbCompo;
8293   int *tmp=ret->getPointer();
8294   for(int i=0;i<sz;i++,tmp+=nbCompo,w++)
8295     {
8296       std::fill(tmp,tmp+nbCompo,0.);
8297       if(w[1]>=w[0])
8298         {
8299           for(int j=w[0];j<w[1];j++,srcPt+=nbCompo)
8300             {
8301               if(j>=0 && j<nbOfTuples)
8302                 std::transform(srcPt,srcPt+nbCompo,tmp,tmp,std::plus<int>());
8303               else
8304                 {
8305                   std::ostringstream oss; oss << "DataArrayInt::accumulatePerChunck : At rank #" << i << " the input index array points to id " << j << " should be in [0," << nbOfTuples << ") !";
8306                   throw INTERP_KERNEL::Exception(oss.str().c_str());
8307                 }
8308             }
8309         }
8310       else
8311         {
8312           std::ostringstream oss; oss << "DataArrayInt::accumulatePerChunck : At rank #" << i << " the input index array is not in ascendingly sorted.";
8313           throw INTERP_KERNEL::Exception(oss.str().c_str());
8314         }
8315     }
8316   ret->copyStringInfoFrom(*this);
8317   return ret.retn();
8318 }
8319
8320 /*!
8321  * Returns a new DataArrayInt by concatenating two given arrays, so that (1) the number
8322  * of tuples in the result array is <em> a1->getNumberOfTuples() + a2->getNumberOfTuples() -
8323  * offsetA2</em> and (2)
8324  * the number of component in the result array is same as that of each of given arrays.
8325  * First \a offsetA2 tuples of \a a2 are skipped and thus are missing from the result array.
8326  * Info on components is copied from the first of the given arrays. Number of components
8327  * in the given arrays must be the same.
8328  *  \param [in] a1 - an array to include in the result array.
8329  *  \param [in] a2 - another array to include in the result array.
8330  *  \param [in] offsetA2 - number of tuples of \a a2 to skip.
8331  *  \return DataArrayInt * - the new instance of DataArrayInt.
8332  *          The caller is to delete this result array using decrRef() as it is no more
8333  *          needed.
8334  *  \throw If either \a a1 or \a a2 is NULL.
8335  *  \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents().
8336  */
8337 DataArrayInt *DataArrayInt::Aggregate(const DataArrayInt *a1, const DataArrayInt *a2, int offsetA2)
8338 {
8339   if(!a1 || !a2)
8340     throw INTERP_KERNEL::Exception("DataArrayInt::Aggregate : input DataArrayInt instance is NULL !");
8341   int nbOfComp=a1->getNumberOfComponents();
8342   if(nbOfComp!=a2->getNumberOfComponents())
8343     throw INTERP_KERNEL::Exception("Nb of components mismatch for array Aggregation !");
8344   int nbOfTuple1=a1->getNumberOfTuples();
8345   int nbOfTuple2=a2->getNumberOfTuples();
8346   DataArrayInt *ret=DataArrayInt::New();
8347   ret->alloc(nbOfTuple1+nbOfTuple2-offsetA2,nbOfComp);
8348   int *pt=std::copy(a1->getConstPointer(),a1->getConstPointer()+nbOfTuple1*nbOfComp,ret->getPointer());
8349   std::copy(a2->getConstPointer()+offsetA2*nbOfComp,a2->getConstPointer()+nbOfTuple2*nbOfComp,pt);
8350   ret->copyStringInfoFrom(*a1);
8351   return ret;
8352 }
8353
8354 /*!
8355  * Returns a new DataArrayInt by concatenating all given arrays, so that (1) the number
8356  * of tuples in the result array is a sum of the number of tuples of given arrays and (2)
8357  * the number of component in the result array is same as that of each of given arrays.
8358  * Info on components is copied from the first of the given arrays. Number of components
8359  * in the given arrays must be  the same.
8360  *  \param [in] arr - a sequence of arrays to include in the result array.
8361  *  \return DataArrayInt * - the new instance of DataArrayInt.
8362  *          The caller is to delete this result array using decrRef() as it is no more
8363  *          needed.
8364  *  \throw If all arrays within \a arr are NULL.
8365  *  \throw If getNumberOfComponents() of arrays within \a arr.
8366  */
8367 DataArrayInt *DataArrayInt::Aggregate(const std::vector<const DataArrayInt *>& arr) throw(INTERP_KERNEL::Exception)
8368 {
8369   std::vector<const DataArrayInt *> a;
8370   for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
8371     if(*it4)
8372       a.push_back(*it4);
8373   if(a.empty())
8374     throw INTERP_KERNEL::Exception("DataArrayInt::Aggregate : input list must be NON EMPTY !");
8375   std::vector<const DataArrayInt *>::const_iterator it=a.begin();
8376   int nbOfComp=(*it)->getNumberOfComponents();
8377   int nbt=(*it++)->getNumberOfTuples();
8378   for(int i=1;it!=a.end();it++,i++)
8379     {
8380       if((*it)->getNumberOfComponents()!=nbOfComp)
8381         throw INTERP_KERNEL::Exception("DataArrayInt::Aggregate : Nb of components mismatch for array aggregation !");
8382       nbt+=(*it)->getNumberOfTuples();
8383     }
8384   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
8385   ret->alloc(nbt,nbOfComp);
8386   int *pt=ret->getPointer();
8387   for(it=a.begin();it!=a.end();it++)
8388     pt=std::copy((*it)->getConstPointer(),(*it)->getConstPointer()+(*it)->getNbOfElems(),pt);
8389   ret->copyStringInfoFrom(*(a[0]));
8390   return ret.retn();
8391 }
8392
8393 /*!
8394  * This method takes as input a list of DataArrayInt instances \a arrs that represent each a packed index arrays.
8395  * A packed index array is an allocated array with one component, and at least one tuple. The first element
8396  * of each array in \a arrs must be 0. Each array in \a arrs is expected to be increasingly monotonic.
8397  * 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.
8398  * 
8399  * \return DataArrayInt * - a new object to be managed by the caller.
8400  */
8401 DataArrayInt *DataArrayInt::AggregateIndexes(const std::vector<const DataArrayInt *>& arrs) throw(INTERP_KERNEL::Exception)
8402 {
8403   int retSz=1;
8404   for(std::vector<const DataArrayInt *>::const_iterator it4=arrs.begin();it4!=arrs.end();it4++)
8405     {
8406       if(*it4)
8407         {
8408           (*it4)->checkAllocated();
8409           if((*it4)->getNumberOfComponents()!=1)
8410             {
8411               std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a DataArrayInt instance with nb of compo != 1 at pos " << std::distance(arrs.begin(),it4) << " !";
8412               throw INTERP_KERNEL::Exception(oss.str().c_str());
8413             }
8414           int nbTupl=(*it4)->getNumberOfTuples();
8415           if(nbTupl<1)
8416             {
8417               std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a DataArrayInt instance with nb of tuples < 1 at pos " << std::distance(arrs.begin(),it4) << " !";
8418               throw INTERP_KERNEL::Exception(oss.str().c_str());
8419             }
8420           if((*it4)->front()!=0)
8421             {
8422               std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a DataArrayInt instance with front value != 0 at pos " << std::distance(arrs.begin(),it4) << " !";
8423               throw INTERP_KERNEL::Exception(oss.str().c_str());
8424             }
8425           retSz+=nbTupl-1;
8426         }
8427       else
8428         {
8429           std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a null instance at pos " << std::distance(arrs.begin(),it4) << " !";
8430           throw INTERP_KERNEL::Exception(oss.str().c_str());
8431         }
8432     }
8433   if(arrs.empty())
8434     throw INTERP_KERNEL::Exception("DataArrayInt::AggregateIndexes : input list must be NON EMPTY !");
8435   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
8436   ret->alloc(retSz,1);
8437   int *pt=ret->getPointer(); *pt++=0;
8438   for(std::vector<const DataArrayInt *>::const_iterator it=arrs.begin();it!=arrs.end();it++)
8439     pt=std::transform((*it)->begin()+1,(*it)->end(),pt,std::bind2nd(std::plus<int>(),pt[-1]));
8440   ret->copyStringInfoFrom(*(arrs[0]));
8441   return ret.retn();
8442 }
8443
8444 /*!
8445  * Returns the maximal value and its location within \a this one-dimensional array.
8446  *  \param [out] tupleId - index of the tuple holding the maximal value.
8447  *  \return int - the maximal value among all values of \a this array.
8448  *  \throw If \a this->getNumberOfComponents() != 1
8449  *  \throw If \a this->getNumberOfTuples() < 1
8450  */
8451 int DataArrayInt::getMaxValue(int& tupleId) const throw(INTERP_KERNEL::Exception)
8452 {
8453   checkAllocated();
8454   if(getNumberOfComponents()!=1)
8455     throw INTERP_KERNEL::Exception("DataArrayInt::getMaxValue : must be applied on DataArrayInt with only one component !");
8456   int nbOfTuples=getNumberOfTuples();
8457   if(nbOfTuples<=0)
8458     throw INTERP_KERNEL::Exception("DataArrayInt::getMaxValue : array exists but number of tuples must be > 0 !");
8459   const int *vals=getConstPointer();
8460   const int *loc=std::max_element(vals,vals+nbOfTuples);
8461   tupleId=(int)std::distance(vals,loc);
8462   return *loc;
8463 }
8464
8465 /*!
8466  * Returns the maximal value within \a this array that is allowed to have more than
8467  *  one component.
8468  *  \return int - the maximal value among all values of \a this array.
8469  *  \throw If \a this is not allocated.
8470  */
8471 int DataArrayInt::getMaxValueInArray() const throw(INTERP_KERNEL::Exception)
8472 {
8473   checkAllocated();
8474   const int *loc=std::max_element(begin(),end());
8475   return *loc;
8476 }
8477
8478 /*!
8479  * Returns the minimal value and its location within \a this one-dimensional array.
8480  *  \param [out] tupleId - index of the tuple holding the minimal value.
8481  *  \return int - the minimal value among all values of \a this array.
8482  *  \throw If \a this->getNumberOfComponents() != 1
8483  *  \throw If \a this->getNumberOfTuples() < 1
8484  */
8485 int DataArrayInt::getMinValue(int& tupleId) const throw(INTERP_KERNEL::Exception)
8486 {
8487   checkAllocated();
8488   if(getNumberOfComponents()!=1)
8489     throw INTERP_KERNEL::Exception("DataArrayInt::getMaxValue : must be applied on DataArrayInt with only one component !");
8490   int nbOfTuples=getNumberOfTuples();
8491   if(nbOfTuples<=0)
8492     throw INTERP_KERNEL::Exception("DataArrayInt::getMaxValue : array exists but number of tuples must be > 0 !");
8493   const int *vals=getConstPointer();
8494   const int *loc=std::min_element(vals,vals+nbOfTuples);
8495   tupleId=(int)std::distance(vals,loc);
8496   return *loc;
8497 }
8498
8499 /*!
8500  * Returns the minimal value within \a this array that is allowed to have more than
8501  *  one component.
8502  *  \return int - the minimal value among all values of \a this array.
8503  *  \throw If \a this is not allocated.
8504  */
8505 int DataArrayInt::getMinValueInArray() const throw(INTERP_KERNEL::Exception)
8506 {
8507   checkAllocated();
8508   const int *loc=std::min_element(begin(),end());
8509   return *loc;
8510 }
8511
8512 /*!
8513  * Converts every value of \a this array to its absolute value.
8514  *  \throw If \a this is not allocated.
8515  */
8516 void DataArrayInt::abs() throw(INTERP_KERNEL::Exception)
8517 {
8518   checkAllocated();
8519   int *ptr=getPointer();
8520   std::size_t nbOfElems=getNbOfElems();
8521   std::transform(ptr,ptr+nbOfElems,ptr,std::ptr_fun<int,int>(std::abs));
8522   declareAsNew();
8523 }
8524
8525 /*!
8526  * Apply a liner function to a given component of \a this array, so that
8527  * an array element <em>(x)</em> becomes \f$ a * x + b \f$.
8528  *  \param [in] a - the first coefficient of the function.
8529  *  \param [in] b - the second coefficient of the function.
8530  *  \param [in] compoId - the index of component to modify.
8531  *  \throw If \a this is not allocated.
8532  */
8533 void DataArrayInt::applyLin(int a, int b, int compoId) throw(INTERP_KERNEL::Exception)
8534 {
8535   checkAllocated();
8536   int *ptr=getPointer()+compoId;
8537   int nbOfComp=getNumberOfComponents();
8538   int nbOfTuple=getNumberOfTuples();
8539   for(int i=0;i<nbOfTuple;i++,ptr+=nbOfComp)
8540     *ptr=a*(*ptr)+b;
8541   declareAsNew();
8542 }
8543
8544 /*!
8545  * Apply a liner function to all elements of \a this array, so that
8546  * an element _x_ becomes \f$ a * x + b \f$.
8547  *  \param [in] a - the first coefficient of the function.
8548  *  \param [in] b - the second coefficient of the function.
8549  *  \throw If \a this is not allocated.
8550  */
8551 void DataArrayInt::applyLin(int a, int b) throw(INTERP_KERNEL::Exception)
8552 {
8553   checkAllocated();
8554   int *ptr=getPointer();
8555   std::size_t nbOfElems=getNbOfElems();
8556   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
8557     *ptr=a*(*ptr)+b;
8558   declareAsNew();
8559 }
8560
8561 /*!
8562  * Returns a full copy of \a this array except that sign of all elements is reversed.
8563  *  \return DataArrayInt * - the new instance of DataArrayInt containing the
8564  *          same number of tuples and component as \a this array.
8565  *          The caller is to delete this result array using decrRef() as it is no more
8566  *          needed.
8567  *  \throw If \a this is not allocated.
8568  */
8569 DataArrayInt *DataArrayInt::negate() const throw(INTERP_KERNEL::Exception)
8570 {
8571   checkAllocated();
8572   DataArrayInt *newArr=DataArrayInt::New();
8573   int nbOfTuples=getNumberOfTuples();
8574   int nbOfComp=getNumberOfComponents();
8575   newArr->alloc(nbOfTuples,nbOfComp);
8576   const int *cptr=getConstPointer();
8577   std::transform(cptr,cptr+nbOfTuples*nbOfComp,newArr->getPointer(),std::negate<int>());
8578   newArr->copyStringInfoFrom(*this);
8579   return newArr;
8580 }
8581
8582 /*!
8583  * Modify all elements of \a this array, so that
8584  * an element _x_ becomes \f$ numerator / x \f$.
8585  *  \warning If an exception is thrown because of presence of 0 element in \a this 
8586  *           array, all elements processed before detection of the zero element remain
8587  *           modified.
8588  *  \param [in] numerator - the numerator used to modify array elements.
8589  *  \throw If \a this is not allocated.
8590  *  \throw If there is an element equal to 0 in \a this array.
8591  */
8592 void DataArrayInt::applyInv(int numerator) throw(INTERP_KERNEL::Exception)
8593 {
8594   checkAllocated();
8595   int *ptr=getPointer();
8596   std::size_t nbOfElems=getNbOfElems();
8597   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
8598     {
8599       if(*ptr!=0)
8600         {
8601           *ptr=numerator/(*ptr);
8602         }
8603       else
8604         {
8605           std::ostringstream oss; oss << "DataArrayInt::applyInv : presence of null value in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
8606           oss << " !";
8607           throw INTERP_KERNEL::Exception(oss.str().c_str());
8608         }
8609     }
8610   declareAsNew();
8611 }
8612
8613 /*!
8614  * Modify all elements of \a this array, so that
8615  * an element _x_ becomes \f$ x / val \f$.
8616  *  \param [in] val - the denominator used to modify array elements.
8617  *  \throw If \a this is not allocated.
8618  *  \throw If \a val == 0.
8619  */
8620 void DataArrayInt::applyDivideBy(int val) throw(INTERP_KERNEL::Exception)
8621 {
8622   if(val==0)
8623     throw INTERP_KERNEL::Exception("DataArrayInt::applyDivideBy : Trying to divide by 0 !");
8624   checkAllocated();
8625   int *ptr=getPointer();
8626   std::size_t nbOfElems=getNbOfElems();
8627   std::transform(ptr,ptr+nbOfElems,ptr,std::bind2nd(std::divides<int>(),val));
8628   declareAsNew();
8629 }
8630
8631 /*!
8632  * Modify all elements of \a this array, so that
8633  * an element _x_ becomes  <em> x % val </em>.
8634  *  \param [in] val - the divisor used to modify array elements.
8635  *  \throw If \a this is not allocated.
8636  *  \throw If \a val <= 0.
8637  */
8638 void DataArrayInt::applyModulus(int val) throw(INTERP_KERNEL::Exception)
8639 {
8640   if(val<=0)
8641     throw INTERP_KERNEL::Exception("DataArrayInt::applyDivideBy : Trying to operate modulus on value <= 0 !");
8642   checkAllocated();
8643   int *ptr=getPointer();
8644   std::size_t nbOfElems=getNbOfElems();
8645   std::transform(ptr,ptr+nbOfElems,ptr,std::bind2nd(std::modulus<int>(),val));
8646   declareAsNew();
8647 }
8648
8649 /*!
8650  * This method works only on data array with one component.
8651  * This method returns a newly allocated array storing stored ascendantly tuple ids in \b this so that
8652  * this[*id] in [\b vmin,\b vmax)
8653  * 
8654  * \param [in] vmin begin of range. This value is included in range (included).
8655  * \param [in] vmax end of range. This value is \b not included in range (excluded).
8656  * \return a newly allocated data array that the caller should deal with.
8657  */
8658 DataArrayInt *DataArrayInt::getIdsInRange(int vmin, int vmax) const throw(INTERP_KERNEL::Exception)
8659 {
8660   checkAllocated();
8661   if(getNumberOfComponents()!=1)
8662     throw INTERP_KERNEL::Exception("DataArrayInt::getIdsInRange : this must have exactly one component !");
8663   const int *cptr=getConstPointer();
8664   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(0,1);
8665   int nbOfTuples=getNumberOfTuples();
8666   for(int i=0;i<nbOfTuples;i++,cptr++)
8667     if(*cptr>=vmin && *cptr<vmax)
8668       ret->pushBackSilent(i);
8669   return ret.retn();
8670 }
8671
8672 /*!
8673  * This method works only on data array with one component.
8674  * 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.
8675  * 
8676  * \param [in] vmin begin of range. This value is included in range (included).
8677  * \param [in] vmax end of range. This value is \b not included in range (excluded).
8678  * \return if all ids in \a this are so that (*this)[i]==i for all i in [ 0, \c this->getNumberOfTuples() ).
8679  */
8680 bool DataArrayInt::checkAllIdsInRange(int vmin, int vmax) const throw(INTERP_KERNEL::Exception)
8681 {
8682   checkAllocated();
8683   if(getNumberOfComponents()!=1)
8684     throw INTERP_KERNEL::Exception("DataArrayInt::checkAllIdsInRange : this must have exactly one component !");
8685   int nbOfTuples=getNumberOfTuples();
8686   bool ret=true;
8687   const int *cptr=getConstPointer();
8688   for(int i=0;i<nbOfTuples;i++,cptr++)
8689     {
8690       if(*cptr>=vmin && *cptr<vmax)
8691         { ret=ret && *cptr==i; }
8692       else
8693         {
8694           std::ostringstream oss; oss << "DataArrayInt::checkAllIdsInRange : tuple #" << i << " has value " << *cptr << " should be in [" << vmin << "," << vmax << ") !";
8695           throw INTERP_KERNEL::Exception(oss.str().c_str());
8696         }
8697     }
8698   return ret;
8699 }
8700
8701 /*!
8702  * Modify all elements of \a this array, so that
8703  * an element _x_ becomes <em> val % x </em>.
8704  *  \warning If an exception is thrown because of presence of an element <= 0 in \a this 
8705  *           array, all elements processed before detection of the zero element remain
8706  *           modified.
8707  *  \param [in] val - the divident used to modify array elements.
8708  *  \throw If \a this is not allocated.
8709  *  \throw If there is an element equal to or less than 0 in \a this array.
8710  */
8711 void DataArrayInt::applyRModulus(int val) throw(INTERP_KERNEL::Exception)
8712 {
8713   checkAllocated();
8714   int *ptr=getPointer();
8715   std::size_t nbOfElems=getNbOfElems();
8716   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
8717     {
8718       if(*ptr>0)
8719         {
8720           *ptr=val%(*ptr);
8721         }
8722       else
8723         {
8724           std::ostringstream oss; oss << "DataArrayInt::applyRModulus : presence of value <=0 in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
8725           oss << " !";
8726           throw INTERP_KERNEL::Exception(oss.str().c_str());
8727         }
8728     }
8729   declareAsNew();
8730 }
8731
8732 /*!
8733  * Modify all elements of \a this array, so that
8734  * an element _x_ becomes <em> val ^ x </em>.
8735  *  \param [in] val - the value used to apply pow on all array elements.
8736  *  \throw If \a this is not allocated.
8737  *  \throw If \a val < 0.
8738  */
8739 void DataArrayInt::applyPow(int val) throw(INTERP_KERNEL::Exception)
8740 {
8741   checkAllocated();
8742   if(val<0)
8743     throw INTERP_KERNEL::Exception("DataArrayInt::applyPow : input pow in < 0 !");
8744   int *ptr=getPointer();
8745   std::size_t nbOfElems=getNbOfElems();
8746   if(val==0)
8747     {
8748       std::fill(ptr,ptr+nbOfElems,1.);
8749       return ;
8750     }
8751   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
8752     {
8753       int tmp=1;
8754       for(int j=0;j<val;j++)
8755         tmp*=*ptr;
8756       *ptr=tmp;
8757     }
8758   declareAsNew();
8759 }
8760
8761 /*!
8762  * Modify all elements of \a this array, so that
8763  * an element _x_ becomes \f$ val ^ x \f$.
8764  *  \param [in] val - the value used to apply pow on all array elements.
8765  *  \throw If \a this is not allocated.
8766  *  \throw If there is an element < 0 in \a this array.
8767  *  \warning If an exception is thrown because of presence of 0 element in \a this 
8768  *           array, all elements processed before detection of the zero element remain
8769  *           modified.
8770  */
8771 void DataArrayInt::applyRPow(int val) throw(INTERP_KERNEL::Exception)
8772 {
8773   checkAllocated();
8774   int *ptr=getPointer();
8775   std::size_t nbOfElems=getNbOfElems();
8776   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
8777     {
8778       if(*ptr>=0)
8779         {
8780           int tmp=1;
8781           for(int j=0;j<*ptr;j++)
8782             tmp*=val;
8783           *ptr=tmp;
8784         }
8785       else
8786         {
8787           std::ostringstream oss; oss << "DataArrayInt::applyRPow : presence of negative value in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
8788           oss << " !";
8789           throw INTERP_KERNEL::Exception(oss.str().c_str());
8790         }
8791     }
8792   declareAsNew();
8793 }
8794
8795 /*!
8796  * Returns a new DataArrayInt by aggregating two given arrays, so that (1) the number
8797  * of components in the result array is a sum of the number of components of given arrays
8798  * and (2) the number of tuples in the result array is same as that of each of given
8799  * arrays. In other words the i-th tuple of result array includes all components of
8800  * i-th tuples of all given arrays.
8801  * Number of tuples in the given arrays must be the same.
8802  *  \param [in] a1 - an array to include in the result array.
8803  *  \param [in] a2 - another array to include in the result array.
8804  *  \return DataArrayInt * - the new instance of DataArrayInt.
8805  *          The caller is to delete this result array using decrRef() as it is no more
8806  *          needed.
8807  *  \throw If both \a a1 and \a a2 are NULL.
8808  *  \throw If any given array is not allocated.
8809  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
8810  */
8811 DataArrayInt *DataArrayInt::Meld(const DataArrayInt *a1, const DataArrayInt *a2) throw(INTERP_KERNEL::Exception)
8812 {
8813   std::vector<const DataArrayInt *> arr(2);
8814   arr[0]=a1; arr[1]=a2;
8815   return Meld(arr);
8816 }
8817
8818 /*!
8819  * Returns a new DataArrayInt by aggregating all given arrays, so that (1) the number
8820  * of components in the result array is a sum of the number of components of given arrays
8821  * and (2) the number of tuples in the result array is same as that of each of given
8822  * arrays. In other words the i-th tuple of result array includes all components of
8823  * i-th tuples of all given arrays.
8824  * Number of tuples in the given arrays must be  the same.
8825  *  \param [in] arr - a sequence of arrays to include in the result array.
8826  *  \return DataArrayInt * - the new instance of DataArrayInt.
8827  *          The caller is to delete this result array using decrRef() as it is no more
8828  *          needed.
8829  *  \throw If all arrays within \a arr are NULL.
8830  *  \throw If any given array is not allocated.
8831  *  \throw If getNumberOfTuples() of arrays within \a arr is different.
8832  */
8833 DataArrayInt *DataArrayInt::Meld(const std::vector<const DataArrayInt *>& arr) throw(INTERP_KERNEL::Exception)
8834 {
8835   std::vector<const DataArrayInt *> a;
8836   for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
8837     if(*it4)
8838       a.push_back(*it4);
8839   if(a.empty())
8840     throw INTERP_KERNEL::Exception("DataArrayInt::Meld : array must be NON empty !");
8841   std::vector<const DataArrayInt *>::const_iterator it;
8842   for(it=a.begin();it!=a.end();it++)
8843     (*it)->checkAllocated();
8844   it=a.begin();
8845   int nbOfTuples=(*it)->getNumberOfTuples();
8846   std::vector<int> nbc(a.size());
8847   std::vector<const int *> pts(a.size());
8848   nbc[0]=(*it)->getNumberOfComponents();
8849   pts[0]=(*it++)->getConstPointer();
8850   for(int i=1;it!=a.end();it++,i++)
8851     {
8852       if(nbOfTuples!=(*it)->getNumberOfTuples())
8853         throw INTERP_KERNEL::Exception("DataArrayInt::meld : mismatch of number of tuples !");
8854       nbc[i]=(*it)->getNumberOfComponents();
8855       pts[i]=(*it)->getConstPointer();
8856     }
8857   int totalNbOfComp=std::accumulate(nbc.begin(),nbc.end(),0);
8858   DataArrayInt *ret=DataArrayInt::New();
8859   ret->alloc(nbOfTuples,totalNbOfComp);
8860   int *retPtr=ret->getPointer();
8861   for(int i=0;i<nbOfTuples;i++)
8862     for(int j=0;j<(int)a.size();j++)
8863       {
8864         retPtr=std::copy(pts[j],pts[j]+nbc[j],retPtr);
8865         pts[j]+=nbc[j];
8866       }
8867   int k=0;
8868   for(int i=0;i<(int)a.size();i++)
8869     for(int j=0;j<nbc[i];j++,k++)
8870       ret->setInfoOnComponent(k,a[i]->getInfoOnComponent(j).c_str());
8871   return ret;
8872 }
8873
8874 /*!
8875  * Returns a new DataArrayInt which is a minimal partition of elements of \a groups.
8876  * The i-th item of the result array is an ID of a set of elements belonging to a
8877  * unique set of groups, which the i-th element is a part of. This set of elements
8878  * belonging to a unique set of groups is called \a family, so the result array contains
8879  * IDs of families each element belongs to.
8880  *
8881  * \b Example: if we have two groups of elements: \a group1 [0,4] and \a group2 [ 0,1,2 ],
8882  * then there are 3 families:
8883  * - \a family1 (with ID 1) contains element [0] belonging to ( \a group1 + \a group2 ),
8884  * - \a family2 (with ID 2) contains elements [4] belonging to ( \a group1 ),
8885  * - \a family3 (with ID 3) contains element [1,2] belonging to ( \a group2 ), <br>
8886  * and the result array contains IDs of families [ 1,3,3,0,2 ]. <br> Note a family ID 0 which
8887  * stands for the element #3 which is in none of groups.
8888  *
8889  *  \param [in] groups - sequence of groups of element IDs.
8890  *  \param [in] newNb - total number of elements; it must be more than max ID of element
8891  *         in \a groups.
8892  *  \param [out] fidsOfGroups - IDs of families the elements of each group belong to.
8893  *  \return DataArrayInt * - a new instance of DataArrayInt containing IDs of families
8894  *         each element with ID from range [0, \a newNb ) belongs to. The caller is to
8895  *         delete this array using decrRef() as it is no more needed.
8896  *  \throw If any element ID in \a groups violates condition ( 0 <= ID < \a newNb ).
8897  */
8898 DataArrayInt *DataArrayInt::MakePartition(const std::vector<const DataArrayInt *>& groups, int newNb, std::vector< std::vector<int> >& fidsOfGroups) throw(INTERP_KERNEL::Exception)
8899 {
8900   std::vector<const DataArrayInt *> groups2;
8901   for(std::vector<const DataArrayInt *>::const_iterator it4=groups.begin();it4!=groups.end();it4++)
8902     if(*it4)
8903       groups2.push_back(*it4);
8904   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
8905   ret->alloc(newNb,1);
8906   int *retPtr=ret->getPointer();
8907   std::fill(retPtr,retPtr+newNb,0);
8908   int fid=1;
8909   for(std::vector<const DataArrayInt *>::const_iterator iter=groups2.begin();iter!=groups2.end();iter++)
8910     {
8911       const int *ptr=(*iter)->getConstPointer();
8912       std::size_t nbOfElem=(*iter)->getNbOfElems();
8913       int sfid=fid;
8914       for(int j=0;j<sfid;j++)
8915         {
8916           bool found=false;
8917           for(std::size_t i=0;i<nbOfElem;i++)
8918             {
8919               if(ptr[i]>=0 && ptr[i]<newNb)
8920                 {
8921                   if(retPtr[ptr[i]]==j)
8922                     {
8923                       retPtr[ptr[i]]=fid;
8924                       found=true;
8925                     }
8926                 }
8927               else
8928                 {
8929                   std::ostringstream oss; oss << "DataArrayInt::MakePartition : In group \"" << (*iter)->getName() << "\" in tuple #" << i << " value = " << ptr[i] << " ! Should be in [0," << newNb;
8930                   oss << ") !";
8931                   throw INTERP_KERNEL::Exception(oss.str().c_str());
8932                 }
8933             }
8934           if(found)
8935             fid++;
8936         }
8937     }
8938   fidsOfGroups.clear();
8939   fidsOfGroups.resize(groups2.size());
8940   int grId=0;
8941   for(std::vector<const DataArrayInt *>::const_iterator iter=groups2.begin();iter!=groups2.end();iter++,grId++)
8942     {
8943       std::set<int> tmp;
8944       const int *ptr=(*iter)->getConstPointer();
8945       std::size_t nbOfElem=(*iter)->getNbOfElems();
8946       for(const int *p=ptr;p!=ptr+nbOfElem;p++)
8947         tmp.insert(retPtr[*p]);
8948       fidsOfGroups[grId].insert(fidsOfGroups[grId].end(),tmp.begin(),tmp.end());
8949     }
8950   return ret.retn();
8951 }
8952
8953 /*!
8954  * Returns a new DataArrayInt which contains all elements of given one-dimensional
8955  * arrays. The result array does not contain any duplicates and its values
8956  * are sorted in ascending order.
8957  *  \param [in] arr - sequence of DataArrayInt's to unite.
8958  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
8959  *         array using decrRef() as it is no more needed.
8960  *  \throw If any \a arr[i] is not allocated.
8961  *  \throw If \a arr[i]->getNumberOfComponents() != 1.
8962  */
8963 DataArrayInt *DataArrayInt::BuildUnion(const std::vector<const DataArrayInt *>& arr) throw(INTERP_KERNEL::Exception)
8964 {
8965   std::vector<const DataArrayInt *> a;
8966   for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
8967     if(*it4)
8968       a.push_back(*it4);
8969   for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
8970     {
8971       (*it)->checkAllocated();
8972       if((*it)->getNumberOfComponents()!=1)
8973         throw INTERP_KERNEL::Exception("DataArrayInt::BuildUnion : only single component allowed !");
8974     }
8975   //
8976   std::set<int> r;
8977   for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
8978     {
8979       const int *pt=(*it)->getConstPointer();
8980       int nbOfTuples=(*it)->getNumberOfTuples();
8981       r.insert(pt,pt+nbOfTuples);
8982     }
8983   DataArrayInt *ret=DataArrayInt::New();
8984   ret->alloc((int)r.size(),1);
8985   std::copy(r.begin(),r.end(),ret->getPointer());
8986   return ret;
8987 }
8988
8989 /*!
8990  * Returns a new DataArrayInt which contains elements present in each of given one-dimensional
8991  * arrays. The result array does not contain any duplicates and its values
8992  * are sorted in ascending order.
8993  *  \param [in] arr - sequence of DataArrayInt's to intersect.
8994  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
8995  *         array using decrRef() as it is no more needed.
8996  *  \throw If any \a arr[i] is not allocated.
8997  *  \throw If \a arr[i]->getNumberOfComponents() != 1.
8998  */
8999 DataArrayInt *DataArrayInt::BuildIntersection(const std::vector<const DataArrayInt *>& arr) throw(INTERP_KERNEL::Exception)
9000 {
9001   std::vector<const DataArrayInt *> a;
9002   for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
9003     if(*it4)
9004       a.push_back(*it4);
9005   for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
9006     {
9007       (*it)->checkAllocated();
9008       if((*it)->getNumberOfComponents()!=1)
9009         throw INTERP_KERNEL::Exception("DataArrayInt::BuildIntersection : only single component allowed !");
9010     }
9011   //
9012   std::set<int> r;
9013   for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
9014     {
9015       const int *pt=(*it)->getConstPointer();
9016       int nbOfTuples=(*it)->getNumberOfTuples();
9017       std::set<int> s1(pt,pt+nbOfTuples);
9018       if(it!=a.begin())
9019         {
9020           std::set<int> r2;
9021           std::set_intersection(r.begin(),r.end(),s1.begin(),s1.end(),inserter(r2,r2.end()));
9022           r=r2;
9023         }
9024       else
9025         r=s1;
9026     }
9027   DataArrayInt *ret=DataArrayInt::New();
9028   ret->alloc((int)r.size(),1);
9029   std::copy(r.begin(),r.end(),ret->getPointer());
9030   return ret;
9031 }
9032
9033 /*!
9034  * Returns a new DataArrayInt which contains a complement of elements of \a this
9035  * one-dimensional array. I.e. the result array contains all elements from the range [0,
9036  * \a nbOfElement) not present in \a this array.
9037  *  \param [in] nbOfElement - maximal size of the result array.
9038  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
9039  *         array using decrRef() as it is no more needed.
9040  *  \throw If \a this is not allocated.
9041  *  \throw If \a this->getNumberOfComponents() != 1.
9042  *  \throw If any element \a x of \a this array violates condition ( 0 <= \a x < \a
9043  *         nbOfElement ).
9044  */
9045 DataArrayInt *DataArrayInt::buildComplement(int nbOfElement) const throw(INTERP_KERNEL::Exception)
9046 {
9047    checkAllocated();
9048    if(getNumberOfComponents()!=1)
9049      throw INTERP_KERNEL::Exception("DataArrayInt::buildComplement : only single component allowed !");
9050    std::vector<bool> tmp(nbOfElement);
9051    const int *pt=getConstPointer();
9052    int nbOfTuples=getNumberOfTuples();
9053    for(const int *w=pt;w!=pt+nbOfTuples;w++)
9054      if(*w>=0 && *w<nbOfElement)
9055        tmp[*w]=true;
9056      else
9057        throw INTERP_KERNEL::Exception("DataArrayInt::buildComplement : an element is not in valid range : [0,nbOfElement) !");
9058    int nbOfRetVal=(int)std::count(tmp.begin(),tmp.end(),false);
9059    DataArrayInt *ret=DataArrayInt::New();
9060    ret->alloc(nbOfRetVal,1);
9061    int j=0;
9062    int *retPtr=ret->getPointer();
9063    for(int i=0;i<nbOfElement;i++)
9064      if(!tmp[i])
9065        retPtr[j++]=i;
9066    return ret;
9067 }
9068
9069 /*!
9070  * Returns a new DataArrayInt containing elements of \a this one-dimensional missing
9071  * from an \a other one-dimensional array.
9072  *  \param [in] other - a DataArrayInt containing elements not to include in the result array.
9073  *  \return DataArrayInt * - a new instance of DataArrayInt with one component. The
9074  *         caller is to delete this array using decrRef() as it is no more needed.
9075  *  \throw If \a other is NULL.
9076  *  \throw If \a other is not allocated.
9077  *  \throw If \a other->getNumberOfComponents() != 1.
9078  *  \throw If \a this is not allocated.
9079  *  \throw If \a this->getNumberOfComponents() != 1.
9080  *  \sa DataArrayInt::buildSubstractionOptimized()
9081  */
9082 DataArrayInt *DataArrayInt::buildSubstraction(const DataArrayInt *other) const throw(INTERP_KERNEL::Exception)
9083 {
9084   if(!other)
9085     throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstraction : DataArrayInt pointer in input is NULL !");
9086   checkAllocated();
9087   other->checkAllocated();
9088   if(getNumberOfComponents()!=1)
9089      throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstraction : only single component allowed !");
9090   if(other->getNumberOfComponents()!=1)
9091      throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstraction : only single component allowed for other type !");
9092   const int *pt=getConstPointer();
9093   int nbOfTuples=getNumberOfTuples();
9094   std::set<int> s1(pt,pt+nbOfTuples);
9095   pt=other->getConstPointer();
9096   nbOfTuples=other->getNumberOfTuples();
9097   std::set<int> s2(pt,pt+nbOfTuples);
9098   std::vector<int> r;
9099   std::set_difference(s1.begin(),s1.end(),s2.begin(),s2.end(),std::back_insert_iterator< std::vector<int> >(r));
9100   DataArrayInt *ret=DataArrayInt::New();
9101   ret->alloc((int)r.size(),1);
9102   std::copy(r.begin(),r.end(),ret->getPointer());
9103   return ret;
9104 }
9105
9106 /*!
9107  * \a this is expected to have one component and to be sorted ascendingly (as for \a other).
9108  * \a other is expected to be a part of \a this. If not DataArrayInt::buildSubstraction should be called instead.
9109  * 
9110  * \param [in] other an array with one component and expected to be sorted ascendingly.
9111  * \ret list of ids in \a this but not in \a other.
9112  * \sa DataArrayInt::buildSubstraction
9113  */
9114 DataArrayInt *DataArrayInt::buildSubstractionOptimized(const DataArrayInt *other) const throw(INTERP_KERNEL::Exception)
9115 {
9116   static const char *MSG="DataArrayInt::buildSubstractionOptimized : only single component allowed !";
9117   if(!other) throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstractionOptimized : NULL input array !");
9118   checkAllocated(); other->checkAllocated();
9119   if(getNumberOfComponents()!=1) throw INTERP_KERNEL::Exception(MSG);
9120   if(other->getNumberOfComponents()!=1) throw INTERP_KERNEL::Exception(MSG);
9121   const int *pt1Bg(begin()),*pt1End(end()),*pt2Bg(other->begin()),*pt2End(other->end()),*work1(pt1Bg),*work2(pt2Bg);
9122   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
9123   for(;work1!=pt1End;work1++)
9124     {
9125       if(work2!=pt2End && *work1==*work2)
9126         work2++;
9127       else
9128         ret->pushBackSilent(*work1);
9129     }
9130   return ret.retn();
9131 }
9132
9133
9134 /*!
9135  * Returns a new DataArrayInt which contains all elements of \a this and a given
9136  * one-dimensional arrays. The result array does not contain any duplicates
9137  * and its values are sorted in ascending order.
9138  *  \param [in] other - an array to unite with \a this one.
9139  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
9140  *         array using decrRef() as it is no more needed.
9141  *  \throw If \a this or \a other is not allocated.
9142  *  \throw If \a this->getNumberOfComponents() != 1.
9143  *  \throw If \a other->getNumberOfComponents() != 1.
9144  */
9145 DataArrayInt *DataArrayInt::buildUnion(const DataArrayInt *other) const throw(INTERP_KERNEL::Exception)
9146 {
9147   std::vector<const DataArrayInt *>arrs(2);
9148   arrs[0]=this; arrs[1]=other;
9149   return BuildUnion(arrs);
9150 }
9151
9152
9153 /*!
9154  * Returns a new DataArrayInt which contains elements present in both \a this and a given
9155  * one-dimensional arrays. The result array does not contain any duplicates
9156  * and its values are sorted in ascending order.
9157  *  \param [in] other - an array to intersect with \a this one.
9158  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
9159  *         array using decrRef() as it is no more needed.
9160  *  \throw If \a this or \a other is not allocated.
9161  *  \throw If \a this->getNumberOfComponents() != 1.
9162  *  \throw If \a other->getNumberOfComponents() != 1.
9163  */
9164 DataArrayInt *DataArrayInt::buildIntersection(const DataArrayInt *other) const throw(INTERP_KERNEL::Exception)
9165 {
9166   std::vector<const DataArrayInt *>arrs(2);
9167   arrs[0]=this; arrs[1]=other;
9168   return BuildIntersection(arrs);
9169 }
9170
9171 /*!
9172  * This method can be applied on allocated with one component DataArrayInt instance.
9173  * This method is typically relevant for sorted arrays. All consecutive duplicated items in \a this will appear only once in returned DataArrayInt instance.
9174  * 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]
9175  * 
9176  * \return a newly allocated array that contain the result of the unique operation applied on \a this.
9177  * \throw if \a this is not allocated or if \a this has not exactly one component.
9178  */
9179 DataArrayInt *DataArrayInt::buildUnique() const throw(INTERP_KERNEL::Exception)
9180 {
9181   checkAllocated();
9182   if(getNumberOfComponents()!=1)
9183      throw INTERP_KERNEL::Exception("DataArrayInt::buildUnique : only single component allowed !");
9184   int nbOfTuples=getNumberOfTuples();
9185   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp=deepCpy();
9186   int *data=tmp->getPointer();
9187   int *last=std::unique(data,data+nbOfTuples);
9188   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
9189   ret->alloc(std::distance(data,last),1);
9190   std::copy(data,last,ret->getPointer());
9191   return ret.retn();
9192 }
9193
9194 /*!
9195  * Returns a new DataArrayInt which contains size of every of groups described by \a this
9196  * "index" array. Such "index" array is returned for example by 
9197  * \ref ParaMEDMEM::MEDCouplingUMesh::buildDescendingConnectivity
9198  * "MEDCouplingUMesh::buildDescendingConnectivity" and
9199  * \ref ParaMEDMEM::MEDCouplingUMesh::getNodalConnectivityIndex
9200  * "MEDCouplingUMesh::getNodalConnectivityIndex" etc.
9201  * This method preforms the reverse operation of DataArrayInt::computeOffsets2.
9202  *  \return DataArrayInt * - a new instance of DataArrayInt, whose number of tuples
9203  *          equals to \a this->getNumberOfComponents() - 1, and number of components is 1.
9204  *          The caller is to delete this array using decrRef() as it is no more needed. 
9205  *  \throw If \a this is not allocated.
9206  *  \throw If \a this->getNumberOfComponents() != 1.
9207  *  \throw If \a this->getNumberOfTuples() < 2.
9208  *
9209  *  \b Example: <br> 
9210  *         - this contains [1,3,6,7,7,9,15]
9211  *         - result array contains [2,3,1,0,2,6],
9212  *          where 2 = 3 - 1, 3 = 6 - 3, 1 = 7 - 6 etc.
9213  *
9214  * \sa DataArrayInt::computeOffsets2
9215  */
9216 DataArrayInt *DataArrayInt::deltaShiftIndex() const throw(INTERP_KERNEL::Exception)
9217 {
9218   checkAllocated();
9219   if(getNumberOfComponents()!=1)
9220      throw INTERP_KERNEL::Exception("DataArrayInt::deltaShiftIndex : only single component allowed !");
9221   int nbOfTuples=getNumberOfTuples();
9222   if(nbOfTuples<2)
9223     throw INTERP_KERNEL::Exception("DataArrayInt::deltaShiftIndex : 1 tuple at least must be present in 'this' !");
9224   const int *ptr=getConstPointer();
9225   DataArrayInt *ret=DataArrayInt::New();
9226   ret->alloc(nbOfTuples-1,1);
9227   int *out=ret->getPointer();
9228   std::transform(ptr+1,ptr+nbOfTuples,ptr,out,std::minus<int>());
9229   return ret;
9230 }
9231
9232 /*!
9233  * Modifies \a this one-dimensional array so that value of each element \a x
9234  * of \a this array (\a a) is computed as \f$ x_i = \sum_{j=0}^{i-1} a[ j ] \f$.
9235  * Or: for each i>0 new[i]=new[i-1]+old[i-1] for i==0 new[i]=0. Number of tuples
9236  * and components remains the same.<br>
9237  * This method is useful for allToAllV in MPI with contiguous policy. This method
9238  * differs from computeOffsets2() in that the number of tuples is \b not changed by
9239  * this one.
9240  *  \throw If \a this is not allocated.
9241  *  \throw If \a this->getNumberOfComponents() != 1.
9242  *
9243  *  \b Example: <br>
9244  *          - Before \a this contains [3,5,1,2,0,8]
9245  *          - After \a this contains  [0,3,8,9,11,11]<br>
9246  *          Note that the last element 19 = 11 + 8 is missing because size of \a this
9247  *          array is retained and thus there is no space to store the last element.
9248  */
9249 void DataArrayInt::computeOffsets() throw(INTERP_KERNEL::Exception)
9250 {
9251   checkAllocated();
9252   if(getNumberOfComponents()!=1)
9253      throw INTERP_KERNEL::Exception("DataArrayInt::computeOffsets : only single component allowed !");
9254   int nbOfTuples=getNumberOfTuples();
9255   if(nbOfTuples==0)
9256     return ;
9257   int *work=getPointer();
9258   int tmp=work[0];
9259   work[0]=0;
9260   for(int i=1;i<nbOfTuples;i++)
9261     {
9262       int tmp2=work[i];
9263       work[i]=work[i-1]+tmp;
9264       tmp=tmp2;
9265     }
9266   declareAsNew();
9267 }
9268
9269
9270 /*!
9271  * Modifies \a this one-dimensional array so that value of each element \a x
9272  * of \a this array (\a a) is computed as \f$ x_i = \sum_{j=0}^{i-1} a[ j ] \f$.
9273  * Or: for each i>0 new[i]=new[i-1]+old[i-1] for i==0 new[i]=0. Number
9274  * components remains the same and number of tuples is inceamented by one.<br>
9275  * This method is useful for allToAllV in MPI with contiguous policy. This method
9276  * differs from computeOffsets() in that the number of tuples is changed by this one.
9277  * This method preforms the reverse operation of DataArrayInt::deltaShiftIndex.
9278  *  \throw If \a this is not allocated.
9279  *  \throw If \a this->getNumberOfComponents() != 1.
9280  *
9281  *  \b Example: <br>
9282  *          - Before \a this contains [3,5,1,2,0,8]
9283  *          - After \a this contains  [0,3,8,9,11,11,19]<br>
9284  * \sa DataArrayInt::deltaShiftIndex
9285  */
9286 void DataArrayInt::computeOffsets2() throw(INTERP_KERNEL::Exception)
9287 {
9288   checkAllocated();
9289   if(getNumberOfComponents()!=1)
9290     throw INTERP_KERNEL::Exception("DataArrayInt::computeOffsets2 : only single component allowed !");
9291   int nbOfTuples=getNumberOfTuples();
9292   int *ret=(int *)malloc((nbOfTuples+1)*sizeof(int));
9293   if(nbOfTuples==0)
9294     return ;
9295   const int *work=getConstPointer();
9296   ret[0]=0;
9297   for(int i=0;i<nbOfTuples;i++)
9298     ret[i+1]=work[i]+ret[i];
9299   useArray(ret,true,C_DEALLOC,nbOfTuples+1,1);
9300   declareAsNew();
9301 }
9302
9303 /*!
9304  * Returns two new DataArrayInt instances whose contents is computed from that of \a this and \a listOfIds arrays as follows.
9305  * \a this is expected to be an offset format ( as returned by DataArrayInt::computeOffsets2 ) that is to say with one component
9306  * and ** sorted strictly increasingly **. \a listOfIds is expected to be sorted ascendingly (not strictly needed for \a listOfIds).
9307  * This methods searches in \a this, considered as a set of contiguous \c this->getNumberOfComponents() ranges, all ids in \a listOfIds
9308  * filling completely one of the ranges in \a this.
9309  *
9310  * \param [in] listOfIds a list of ids that has to be sorted ascendingly.
9311  * \param [out] rangeIdsFetched the range ids fetched
9312  * \param [out] idsInInputListThatFetch contains the list of ids in \a listOfIds that are \b fully included in a range in \a this. So
9313  *              \a idsInInputListThatFetch is a part of input \a listOfIds.
9314  *
9315  * \sa DataArrayInt::computeOffsets2
9316  *
9317  *  \b Example: <br>
9318  *          - \a this : [0,3,7,9,15,18]
9319  *          - \a listOfIds contains  [0,1,2,3,7,8,15,16,17]
9320  *          - \a rangeIdsFetched result array: [0,2,4]
9321  *          - \a idsInInputListThatFetch result array: [0,1,2,7,8,15,16,17]
9322  * In this example id 3 in input \a listOfIds is alone so it do not appear in output \a idsInInputListThatFetch.
9323  * <br>
9324  */
9325 void DataArrayInt::searchRangesInListOfIds(const DataArrayInt *listOfIds, DataArrayInt *& rangeIdsFetched, DataArrayInt *& idsInInputListThatFetch) const throw(INTERP_KERNEL::Exception)
9326 {
9327   if(!listOfIds)
9328     throw INTERP_KERNEL::Exception("DataArrayInt::searchRangesInListOfIds : input list of ids is null !");
9329   listOfIds->checkAllocated(); checkAllocated();
9330   if(listOfIds->getNumberOfComponents()!=1)
9331     throw INTERP_KERNEL::Exception("DataArrayInt::searchRangesInListOfIds : input list of ids must have exactly one component !");
9332   if(getNumberOfComponents()!=1)
9333     throw INTERP_KERNEL::Exception("DataArrayInt::searchRangesInListOfIds : this must have exactly one component !");
9334   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret0=DataArrayInt::New(); ret0->alloc(0,1);
9335   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret1=DataArrayInt::New(); ret1->alloc(0,1);
9336   const int *tupEnd(listOfIds->end()),*offBg(begin()),*offEnd(end()-1);
9337   const int *tupPtr(listOfIds->begin()),*offPtr(offBg);
9338   while(tupPtr!=tupEnd && offPtr!=offEnd)
9339     {
9340       if(*tupPtr==*offPtr)
9341         {
9342           int i=offPtr[0];
9343           while(i<offPtr[1] && *tupPtr==i && tupPtr!=tupEnd) { i++; tupPtr++; }
9344           if(i==offPtr[1])
9345             {
9346               ret0->pushBackSilent((int)std::distance(offBg,offPtr));
9347               ret1->pushBackValsSilent(tupPtr-(offPtr[1]-offPtr[0]),tupPtr);
9348               offPtr++;
9349             }
9350         }
9351       else
9352         { if(*tupPtr<*offPtr) tupPtr++; else offPtr++; }
9353     }
9354   rangeIdsFetched=ret0.retn();
9355   idsInInputListThatFetch=ret1.retn();
9356 }
9357
9358 /*!
9359  * Returns a new DataArrayInt whose contents is computed from that of \a this and \a
9360  * offsets arrays as follows. \a offsets is a one-dimensional array considered as an
9361  * "index" array of a "iota" array, thus, whose each element gives an index of a group
9362  * beginning within the "iota" array. And \a this is a one-dimensional array
9363  * considered as a selector of groups described by \a offsets to include into the result array.
9364  *  \throw If \a offsets is NULL.
9365  *  \throw If \a offsets is not allocated.
9366  *  \throw If \a offsets->getNumberOfComponents() != 1.
9367  *  \throw If \a offsets is not monotonically increasing.
9368  *  \throw If \a this is not allocated.
9369  *  \throw If \a this->getNumberOfComponents() != 1.
9370  *  \throw If any element of \a this is not a valid index for \a offsets array.
9371  *
9372  *  \b Example: <br>
9373  *          - \a this: [0,2,3]
9374  *          - \a offsets: [0,3,6,10,14,20]
9375  *          - result array: [0,1,2,6,7,8,9,10,11,12,13] == <br>
9376  *            \c range(0,3) + \c range(6,10) + \c range(10,14) ==<br>
9377  *            \c range( \a offsets[ \a this[0] ], offsets[ \a this[0]+1 ]) + 
9378  *            \c range( \a offsets[ \a this[1] ], offsets[ \a this[1]+1 ]) + 
9379  *            \c range( \a offsets[ \a this[2] ], offsets[ \a this[2]+1 ])
9380  */
9381 DataArrayInt *DataArrayInt::buildExplicitArrByRanges(const DataArrayInt *offsets) const throw(INTERP_KERNEL::Exception)
9382 {
9383   if(!offsets)
9384     throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrByRanges : DataArrayInt pointer in input is NULL !");
9385   checkAllocated();
9386   if(getNumberOfComponents()!=1)
9387      throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrByRanges : only single component allowed !");
9388   offsets->checkAllocated();
9389   if(offsets->getNumberOfComponents()!=1)
9390      throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrByRanges : input array should have only single component !");
9391   int othNbTuples=offsets->getNumberOfTuples()-1;
9392   int nbOfTuples=getNumberOfTuples();
9393   int retNbOftuples=0;
9394   const int *work=getConstPointer();
9395   const int *offPtr=offsets->getConstPointer();
9396   for(int i=0;i<nbOfTuples;i++)
9397     {
9398       int val=work[i];
9399       if(val>=0 && val<othNbTuples)
9400         {
9401           int delta=offPtr[val+1]-offPtr[val];
9402           if(delta>=0)
9403             retNbOftuples+=delta;
9404           else
9405             {
9406               std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrByRanges : Tuple #" << val << " of offset array has a delta < 0 !";
9407               throw INTERP_KERNEL::Exception(oss.str().c_str());
9408             }
9409         }
9410       else
9411         {
9412           std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrByRanges : Tuple #" << i << " in this contains " << val;
9413           oss << " whereas offsets array is of size " << othNbTuples+1 << " !";
9414           throw INTERP_KERNEL::Exception(oss.str().c_str());
9415         }
9416     }
9417   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
9418   ret->alloc(retNbOftuples,1);
9419   int *retPtr=ret->getPointer();
9420   for(int i=0;i<nbOfTuples;i++)
9421     {
9422       int val=work[i];
9423       int start=offPtr[val];
9424       int off=offPtr[val+1]-start;
9425       for(int j=0;j<off;j++,retPtr++)
9426         *retPtr=start+j;
9427     }
9428   return ret.retn();
9429 }
9430
9431 /*!
9432  * 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.
9433  * 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
9434  * in tuple **i** of returned DataArrayInt.
9435  * If ranges overlapped (in theory it should not) this method do not detect it and always returns the first range.
9436  *
9437  * 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)]
9438  * The return DataArrayInt will contain : **[0,4,1,2,2,3]**
9439  * 
9440  * \param [in] ranges typically come from output of MEDCouplingUMesh::ComputeRangesFromTypeDistribution. Each range is specified like this : 1st component is
9441  *             for lower value included and 2nd component is the upper value of corresponding range **excluded**.
9442  * \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
9443  *        is thrown if no ranges in \a ranges contains value in \a this.
9444  * 
9445  * \sa DataArrayInt::findIdInRangeForEachTuple
9446  */
9447 DataArrayInt *DataArrayInt::findRangeIdForEachTuple(const DataArrayInt *ranges) const throw(INTERP_KERNEL::Exception)
9448 {
9449   if(!ranges)
9450     throw INTERP_KERNEL::Exception("DataArrayInt::findRangeIdForEachTuple : null input pointer !");
9451   if(ranges->getNumberOfComponents()!=2)
9452     throw INTERP_KERNEL::Exception("DataArrayInt::findRangeIdForEachTuple : input DataArrayInt instance should have 2 components !");
9453   checkAllocated();
9454   if(getNumberOfComponents()!=1)
9455     throw INTERP_KERNEL::Exception("DataArrayInt::findRangeIdForEachTuple : this should have only one component !");
9456   int nbTuples=getNumberOfTuples();
9457   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbTuples,1);
9458   int nbOfRanges=ranges->getNumberOfTuples();
9459   const int *rangesPtr=ranges->getConstPointer();
9460   int *retPtr=ret->getPointer();
9461   const int *inPtr=getConstPointer();
9462   for(int i=0;i<nbTuples;i++,retPtr++)
9463     {
9464       int val=inPtr[i];
9465       bool found=false;
9466       for(int j=0;j<nbOfRanges && !found;j++)
9467         if(val>=rangesPtr[2*j] && val<rangesPtr[2*j+1])
9468           { *retPtr=j; found=true; }
9469       if(found)
9470         continue;
9471       else
9472         {
9473           std::ostringstream oss; oss << "DataArrayInt::findRangeIdForEachTuple : tuple #" << i << " not found by any ranges !";
9474           throw INTERP_KERNEL::Exception(oss.str().c_str());
9475         }
9476     }
9477   return ret.retn();
9478 }
9479
9480 /*!
9481  * 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.
9482  * 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
9483  * in tuple **i** of returned DataArrayInt.
9484  * If ranges overlapped (in theory it should not) this method do not detect it and always returns the sub position of the first range.
9485  *
9486  * 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)]
9487  * The return DataArrayInt will contain : **[1,2,4,0,2,2]**
9488  * This method is often called in pair with DataArrayInt::findRangeIdForEachTuple method.
9489  * 
9490  * \param [in] ranges typically come from output of MEDCouplingUMesh::ComputeRangesFromTypeDistribution. Each range is specified like this : 1st component is
9491  *             for lower value included and 2nd component is the upper value of corresponding range **excluded**.
9492  * \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
9493  *        is thrown if no ranges in \a ranges contains value in \a this.
9494  * \sa DataArrayInt::findRangeIdForEachTuple
9495  */
9496 DataArrayInt *DataArrayInt::findIdInRangeForEachTuple(const DataArrayInt *ranges) const throw(INTERP_KERNEL::Exception)
9497 {
9498   if(!ranges)
9499     throw INTERP_KERNEL::Exception("DataArrayInt::findIdInRangeForEachTuple : null input pointer !");
9500   if(ranges->getNumberOfComponents()!=2)
9501     throw INTERP_KERNEL::Exception("DataArrayInt::findIdInRangeForEachTuple : input DataArrayInt instance should have 2 components !");
9502   checkAllocated();
9503   if(getNumberOfComponents()!=1)
9504     throw INTERP_KERNEL::Exception("DataArrayInt::findIdInRangeForEachTuple : this should have only one component !");
9505   int nbTuples=getNumberOfTuples();
9506   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbTuples,1);
9507   int nbOfRanges=ranges->getNumberOfTuples();
9508   const int *rangesPtr=ranges->getConstPointer();
9509   int *retPtr=ret->getPointer();
9510   const int *inPtr=getConstPointer();
9511   for(int i=0;i<nbTuples;i++,retPtr++)
9512     {
9513       int val=inPtr[i];
9514       bool found=false;
9515       for(int j=0;j<nbOfRanges && !found;j++)
9516         if(val>=rangesPtr[2*j] && val<rangesPtr[2*j+1])
9517           { *retPtr=val-rangesPtr[2*j]; found=true; }
9518       if(found)
9519         continue;
9520       else
9521         {
9522           std::ostringstream oss; oss << "DataArrayInt::findIdInRangeForEachTuple : tuple #" << i << " not found by any ranges !";
9523           throw INTERP_KERNEL::Exception(oss.str().c_str());
9524         }
9525     }
9526   return ret.retn();
9527 }
9528
9529 /*!
9530  * 
9531  * \param [in] nbTimes specifies the nb of times each tuples in \a this will be duplicated contiguouly in returned DataArrayInt instance.
9532  *             \a nbTimes  should be at least equal to 1.
9533  * \return a newly allocated DataArrayInt having one component and number of tuples equal to \a nbTimes * \c this->getNumberOfTuples.
9534  * \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.
9535  */
9536 DataArrayInt *DataArrayInt::duplicateEachTupleNTimes(int nbTimes) const throw(INTERP_KERNEL::Exception)
9537 {
9538   checkAllocated();
9539   if(getNumberOfComponents()!=1)
9540     throw INTERP_KERNEL::Exception("DataArrayInt::duplicateEachTupleNTimes : this should have only one component !");
9541   if(nbTimes<1)
9542     throw INTERP_KERNEL::Exception("DataArrayInt::duplicateEachTupleNTimes : nb times should be >= 1 !");
9543   int nbTuples=getNumberOfTuples();
9544   const int *inPtr=getConstPointer();
9545   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbTimes*nbTuples,1);
9546   int *retPtr=ret->getPointer();
9547   for(int i=0;i<nbTuples;i++,inPtr++)
9548     {
9549       int val=*inPtr;
9550       for(int j=0;j<nbTimes;j++,retPtr++)
9551         *retPtr=val;
9552     }
9553   ret->copyStringInfoFrom(*this);
9554   return ret.retn();
9555 }
9556
9557 /*!
9558  * This method returns all different values found in \a this. This method throws if \a this has not been allocated.
9559  * But the number of components can be different from one.
9560  * \return a newly allocated array (that should be dealt by the caller) containing different values in \a this.
9561  */
9562 DataArrayInt *DataArrayInt::getDifferentValues() const throw(INTERP_KERNEL::Exception)
9563 {
9564   checkAllocated();
9565   std::set<int> ret;
9566   ret.insert(begin(),end());
9567   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret2=DataArrayInt::New(); ret2->alloc((int)ret.size(),1);
9568   std::copy(ret.begin(),ret.end(),ret2->getPointer());
9569   return ret2.retn();
9570 }
9571
9572 /*!
9573  * This method is a refinement of DataArrayInt::getDifferentValues because it returns not only different values in \a this but also, for each of
9574  * them it tells which tuple id have this id.
9575  * This method works only on arrays with one component (if it is not the case call DataArrayInt::rearrange(1) ).
9576  * This method returns two arrays having same size.
9577  * 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.
9578  * 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]]
9579  */
9580 std::vector<DataArrayInt *> DataArrayInt::partitionByDifferentValues(std::vector<int>& differentIds) const throw(INTERP_KERNEL::Exception)
9581 {
9582   checkAllocated();
9583   if(getNumberOfComponents()!=1)
9584     throw INTERP_KERNEL::Exception("DataArrayInt::partitionByDifferentValues : this should have only one component !");
9585   int id=0;
9586   std::map<int,int> m,m2,m3;
9587   for(const int *w=begin();w!=end();w++)
9588     m[*w]++;
9589   differentIds.resize(m.size());
9590   std::vector<DataArrayInt *> ret(m.size());
9591   std::vector<int *> retPtr(m.size());
9592   for(std::map<int,int>::const_iterator it=m.begin();it!=m.end();it++,id++)
9593     {
9594       m2[(*it).first]=id;
9595       ret[id]=DataArrayInt::New();
9596       ret[id]->alloc((*it).second,1);
9597       retPtr[id]=ret[id]->getPointer();
9598       differentIds[id]=(*it).first;
9599     }
9600   id=0;
9601   for(const int *w=begin();w!=end();w++,id++)
9602     {
9603       retPtr[m2[*w]][m3[*w]++]=id;
9604     }
9605   return ret;
9606 }
9607
9608 /*!
9609  * Returns a new DataArrayInt that is a sum of two given arrays. There are 3
9610  * valid cases.
9611  * 1.  The arrays have same number of tuples and components. Then each value of
9612  *   the result array (_a_) is a sum of the corresponding values of \a a1 and \a a2,
9613  *   i.e.: _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ i, j ].
9614  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
9615  *   component. Then
9616  *   _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ i, 0 ].
9617  * 3.  The arrays have same number of components and one array, say _a2_, has one
9618  *   tuple. Then
9619  *   _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ 0, j ].
9620  *
9621  * Info on components is copied either from the first array (in the first case) or from
9622  * the array with maximal number of elements (getNbOfElems()).
9623  *  \param [in] a1 - an array to sum up.
9624  *  \param [in] a2 - another array to sum up.
9625  *  \return DataArrayInt * - the new instance of DataArrayInt.
9626  *          The caller is to delete this result array using decrRef() as it is no more
9627  *          needed.
9628  *  \throw If either \a a1 or \a a2 is NULL.
9629  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
9630  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
9631  *         none of them has number of tuples or components equal to 1.
9632  */
9633 DataArrayInt *DataArrayInt::Add(const DataArrayInt *a1, const DataArrayInt *a2) throw(INTERP_KERNEL::Exception)
9634 {
9635   if(!a1 || !a2)
9636     throw INTERP_KERNEL::Exception("DataArrayInt::Add : input DataArrayInt instance is NULL !");
9637   int nbOfTuple=a1->getNumberOfTuples();
9638   int nbOfTuple2=a2->getNumberOfTuples();
9639   int nbOfComp=a1->getNumberOfComponents();
9640   int nbOfComp2=a2->getNumberOfComponents();
9641   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=0;
9642   if(nbOfTuple==nbOfTuple2)
9643     {
9644       if(nbOfComp==nbOfComp2)
9645         {
9646           ret=DataArrayInt::New();
9647           ret->alloc(nbOfTuple,nbOfComp);
9648           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::plus<int>());
9649           ret->copyStringInfoFrom(*a1);
9650         }
9651       else
9652         {
9653           int nbOfCompMin,nbOfCompMax;
9654           const DataArrayInt *aMin, *aMax;
9655           if(nbOfComp>nbOfComp2)
9656             {
9657               nbOfCompMin=nbOfComp2; nbOfCompMax=nbOfComp;
9658               aMin=a2; aMax=a1;
9659             }
9660           else
9661             {
9662               nbOfCompMin=nbOfComp; nbOfCompMax=nbOfComp2;
9663               aMin=a1; aMax=a2;
9664             }
9665           if(nbOfCompMin==1)
9666             {
9667               ret=DataArrayInt::New();
9668               ret->alloc(nbOfTuple,nbOfCompMax);
9669               const int *aMinPtr=aMin->getConstPointer();
9670               const int *aMaxPtr=aMax->getConstPointer();
9671               int *res=ret->getPointer();
9672               for(int i=0;i<nbOfTuple;i++)
9673                 res=std::transform(aMaxPtr+i*nbOfCompMax,aMaxPtr+(i+1)*nbOfCompMax,res,std::bind2nd(std::plus<int>(),aMinPtr[i]));
9674               ret->copyStringInfoFrom(*aMax);
9675             }
9676           else
9677             throw INTERP_KERNEL::Exception("Nb of components mismatch for array Add !");
9678         }
9679     }
9680   else if((nbOfTuple==1 && nbOfTuple2>1) || (nbOfTuple>1 && nbOfTuple2==1))
9681     {
9682       if(nbOfComp==nbOfComp2)
9683         {
9684           int nbOfTupleMax=std::max(nbOfTuple,nbOfTuple2);
9685           const DataArrayInt *aMin=nbOfTuple>nbOfTuple2?a2:a1;
9686           const DataArrayInt *aMax=nbOfTuple>nbOfTuple2?a1:a2;
9687           const int *aMinPtr=aMin->getConstPointer(),*aMaxPtr=aMax->getConstPointer();
9688           ret=DataArrayInt::New();
9689           ret->alloc(nbOfTupleMax,nbOfComp);
9690           int *res=ret->getPointer();
9691           for(int i=0;i<nbOfTupleMax;i++)
9692             res=std::transform(aMaxPtr+i*nbOfComp,aMaxPtr+(i+1)*nbOfComp,aMinPtr,res,std::plus<int>());
9693           ret->copyStringInfoFrom(*aMax);
9694         }
9695       else
9696         throw INTERP_KERNEL::Exception("Nb of components mismatch for array Add !");
9697     }
9698   else
9699     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Add !");
9700   return ret.retn();
9701 }
9702
9703 /*!
9704  * Adds values of another DataArrayInt to values of \a this one. There are 3
9705  * valid cases.
9706  * 1.  The arrays have same number of tuples and components. Then each value of
9707  *   \a other array is added to the corresponding value of \a this array, i.e.:
9708  *   _a_ [ i, j ] += _other_ [ i, j ].
9709  * 2.  The arrays have same number of tuples and \a other array has one component. Then
9710  *   _a_ [ i, j ] += _other_ [ i, 0 ].
9711  * 3.  The arrays have same number of components and \a other array has one tuple. Then
9712  *   _a_ [ i, j ] += _a2_ [ 0, j ].
9713  *
9714  *  \param [in] other - an array to add to \a this one.
9715  *  \throw If \a other is NULL.
9716  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
9717  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
9718  *         \a other has number of both tuples and components not equal to 1.
9719  */
9720 void DataArrayInt::addEqual(const DataArrayInt *other) throw(INTERP_KERNEL::Exception)
9721 {
9722   if(!other)
9723     throw INTERP_KERNEL::Exception("DataArrayInt::addEqual : input DataArrayInt instance is NULL !");
9724   const char *msg="Nb of tuples mismatch for DataArrayInt::addEqual  !";
9725   checkAllocated(); other->checkAllocated();
9726   int nbOfTuple=getNumberOfTuples();
9727   int nbOfTuple2=other->getNumberOfTuples();
9728   int nbOfComp=getNumberOfComponents();
9729   int nbOfComp2=other->getNumberOfComponents();
9730   if(nbOfTuple==nbOfTuple2)
9731     {
9732       if(nbOfComp==nbOfComp2)
9733         {
9734           std::transform(begin(),end(),other->begin(),getPointer(),std::plus<int>());
9735         }
9736       else if(nbOfComp2==1)
9737         {
9738           int *ptr=getPointer();
9739           const int *ptrc=other->getConstPointer();
9740           for(int i=0;i<nbOfTuple;i++)
9741             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::plus<int>(),*ptrc++));
9742         }
9743       else
9744         throw INTERP_KERNEL::Exception(msg);
9745     }
9746   else if(nbOfTuple2==1)
9747     {
9748       if(nbOfComp2==nbOfComp)
9749         {
9750           int *ptr=getPointer();
9751           const int *ptrc=other->getConstPointer();
9752           for(int i=0;i<nbOfTuple;i++)
9753             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::plus<int>());
9754         }
9755       else
9756         throw INTERP_KERNEL::Exception(msg);
9757     }
9758   else
9759     throw INTERP_KERNEL::Exception(msg);
9760   declareAsNew();
9761 }
9762
9763 /*!
9764  * Returns a new DataArrayInt that is a subtraction of two given arrays. There are 3
9765  * valid cases.
9766  * 1.  The arrays have same number of tuples and components. Then each value of
9767  *   the result array (_a_) is a subtraction of the corresponding values of \a a1 and
9768  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ i, j ].
9769  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
9770  *   component. Then
9771  *   _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ i, 0 ].
9772  * 3.  The arrays have same number of components and one array, say _a2_, has one
9773  *   tuple. Then
9774  *   _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ 0, j ].
9775  *
9776  * Info on components is copied either from the first array (in the first case) or from
9777  * the array with maximal number of elements (getNbOfElems()).
9778  *  \param [in] a1 - an array to subtract from.
9779  *  \param [in] a2 - an array to subtract.
9780  *  \return DataArrayInt * - the new instance of DataArrayInt.
9781  *          The caller is to delete this result array using decrRef() as it is no more
9782  *          needed.
9783  *  \throw If either \a a1 or \a a2 is NULL.
9784  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
9785  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
9786  *         none of them has number of tuples or components equal to 1.
9787  */
9788 DataArrayInt *DataArrayInt::Substract(const DataArrayInt *a1, const DataArrayInt *a2) throw(INTERP_KERNEL::Exception)
9789 {
9790   if(!a1 || !a2)
9791     throw INTERP_KERNEL::Exception("DataArrayInt::Substract : input DataArrayInt instance is NULL !");
9792   int nbOfTuple1=a1->getNumberOfTuples();
9793   int nbOfTuple2=a2->getNumberOfTuples();
9794   int nbOfComp1=a1->getNumberOfComponents();
9795   int nbOfComp2=a2->getNumberOfComponents();
9796   if(nbOfTuple2==nbOfTuple1)
9797     {
9798       if(nbOfComp1==nbOfComp2)
9799         {
9800           MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
9801           ret->alloc(nbOfTuple2,nbOfComp1);
9802           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::minus<int>());
9803           ret->copyStringInfoFrom(*a1);
9804           return ret.retn();
9805         }
9806       else if(nbOfComp2==1)
9807         {
9808           MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
9809           ret->alloc(nbOfTuple1,nbOfComp1);
9810           const int *a2Ptr=a2->getConstPointer();
9811           const int *a1Ptr=a1->getConstPointer();
9812           int *res=ret->getPointer();
9813           for(int i=0;i<nbOfTuple1;i++)
9814             res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::minus<int>(),a2Ptr[i]));
9815           ret->copyStringInfoFrom(*a1);
9816           return ret.retn();
9817         }
9818       else
9819         {
9820           a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Substract !");
9821           return 0;
9822         }
9823     }
9824   else if(nbOfTuple2==1)
9825     {
9826       a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Substract !");
9827       MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
9828       ret->alloc(nbOfTuple1,nbOfComp1);
9829       const int *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
9830       int *pt=ret->getPointer();
9831       for(int i=0;i<nbOfTuple1;i++)
9832         pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::minus<int>());
9833       ret->copyStringInfoFrom(*a1);
9834       return ret.retn();
9835     }
9836   else
9837     {
9838       a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Substract !");//will always throw an exception
9839       return 0;
9840     }
9841 }
9842
9843 /*!
9844  * Subtract values of another DataArrayInt from values of \a this one. There are 3
9845  * valid cases.
9846  * 1.  The arrays have same number of tuples and components. Then each value of
9847  *   \a other array is subtracted from the corresponding value of \a this array, i.e.:
9848  *   _a_ [ i, j ] -= _other_ [ i, j ].
9849  * 2.  The arrays have same number of tuples and \a other array has one component. Then
9850  *   _a_ [ i, j ] -= _other_ [ i, 0 ].
9851  * 3.  The arrays have same number of components and \a other array has one tuple. Then
9852  *   _a_ [ i, j ] -= _a2_ [ 0, j ].
9853  *
9854  *  \param [in] other - an array to subtract from \a this one.
9855  *  \throw If \a other is NULL.
9856  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
9857  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
9858  *         \a other has number of both tuples and components not equal to 1.
9859  */
9860 void DataArrayInt::substractEqual(const DataArrayInt *other) throw(INTERP_KERNEL::Exception)
9861 {
9862   if(!other)
9863     throw INTERP_KERNEL::Exception("DataArrayInt::substractEqual : input DataArrayInt instance is NULL !");
9864   const char *msg="Nb of tuples mismatch for DataArrayInt::substractEqual  !";
9865   checkAllocated(); other->checkAllocated();
9866   int nbOfTuple=getNumberOfTuples();
9867   int nbOfTuple2=other->getNumberOfTuples();
9868   int nbOfComp=getNumberOfComponents();
9869   int nbOfComp2=other->getNumberOfComponents();
9870   if(nbOfTuple==nbOfTuple2)
9871     {
9872       if(nbOfComp==nbOfComp2)
9873         {
9874           std::transform(begin(),end(),other->begin(),getPointer(),std::minus<int>());
9875         }
9876       else if(nbOfComp2==1)
9877         {
9878           int *ptr=getPointer();
9879           const int *ptrc=other->getConstPointer();
9880           for(int i=0;i<nbOfTuple;i++)
9881             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::minus<int>(),*ptrc++));
9882         }
9883       else
9884         throw INTERP_KERNEL::Exception(msg);
9885     }
9886   else if(nbOfTuple2==1)
9887     {
9888       int *ptr=getPointer();
9889       const int *ptrc=other->getConstPointer();
9890       for(int i=0;i<nbOfTuple;i++)
9891         std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::minus<int>());
9892     }
9893   else
9894     throw INTERP_KERNEL::Exception(msg);
9895   declareAsNew();
9896 }
9897
9898 /*!
9899  * Returns a new DataArrayInt that is a product of two given arrays. There are 3
9900  * valid cases.
9901  * 1.  The arrays have same number of tuples and components. Then each value of
9902  *   the result array (_a_) is a product of the corresponding values of \a a1 and
9903  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ i, j ].
9904  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
9905  *   component. Then
9906  *   _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ i, 0 ].
9907  * 3.  The arrays have same number of components and one array, say _a2_, has one
9908  *   tuple. Then
9909  *   _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ 0, j ].
9910  *
9911  * Info on components is copied either from the first array (in the first case) or from
9912  * the array with maximal number of elements (getNbOfElems()).
9913  *  \param [in] a1 - a factor array.
9914  *  \param [in] a2 - another factor array.
9915  *  \return DataArrayInt * - the new instance of DataArrayInt.
9916  *          The caller is to delete this result array using decrRef() as it is no more
9917  *          needed.
9918  *  \throw If either \a a1 or \a a2 is NULL.
9919  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
9920  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
9921  *         none of them has number of tuples or components equal to 1.
9922  */
9923 DataArrayInt *DataArrayInt::Multiply(const DataArrayInt *a1, const DataArrayInt *a2) throw(INTERP_KERNEL::Exception)
9924 {
9925   if(!a1 || !a2)
9926     throw INTERP_KERNEL::Exception("DataArrayInt::Multiply : input DataArrayInt instance is NULL !");
9927   int nbOfTuple=a1->getNumberOfTuples();
9928   int nbOfTuple2=a2->getNumberOfTuples();
9929   int nbOfComp=a1->getNumberOfComponents();
9930   int nbOfComp2=a2->getNumberOfComponents();
9931   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=0;
9932   if(nbOfTuple==nbOfTuple2)
9933     {
9934       if(nbOfComp==nbOfComp2)
9935         {
9936           ret=DataArrayInt::New();
9937           ret->alloc(nbOfTuple,nbOfComp);
9938           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::multiplies<int>());
9939           ret->copyStringInfoFrom(*a1);
9940         }
9941       else
9942         {
9943           int nbOfCompMin,nbOfCompMax;
9944           const DataArrayInt *aMin, *aMax;
9945           if(nbOfComp>nbOfComp2)
9946             {
9947               nbOfCompMin=nbOfComp2; nbOfCompMax=nbOfComp;
9948               aMin=a2; aMax=a1;
9949             }
9950           else
9951             {
9952               nbOfCompMin=nbOfComp; nbOfCompMax=nbOfComp2;
9953               aMin=a1; aMax=a2;
9954             }
9955           if(nbOfCompMin==1)
9956             {
9957               ret=DataArrayInt::New();
9958               ret->alloc(nbOfTuple,nbOfCompMax);
9959               const int *aMinPtr=aMin->getConstPointer();
9960               const int *aMaxPtr=aMax->getConstPointer();
9961               int *res=ret->getPointer();
9962               for(int i=0;i<nbOfTuple;i++)
9963                 res=std::transform(aMaxPtr+i*nbOfCompMax,aMaxPtr+(i+1)*nbOfCompMax,res,std::bind2nd(std::multiplies<int>(),aMinPtr[i]));
9964               ret->copyStringInfoFrom(*aMax);
9965             }
9966           else
9967             throw INTERP_KERNEL::Exception("Nb of components mismatch for array Multiply !");
9968         }
9969     }
9970   else if((nbOfTuple==1 && nbOfTuple2>1) || (nbOfTuple>1 && nbOfTuple2==1))
9971     {
9972       if(nbOfComp==nbOfComp2)
9973         {
9974           int nbOfTupleMax=std::max(nbOfTuple,nbOfTuple2);
9975           const DataArrayInt *aMin=nbOfTuple>nbOfTuple2?a2:a1;
9976           const DataArrayInt *aMax=nbOfTuple>nbOfTuple2?a1:a2;
9977           const int *aMinPtr=aMin->getConstPointer(),*aMaxPtr=aMax->getConstPointer();
9978           ret=DataArrayInt::New();
9979           ret->alloc(nbOfTupleMax,nbOfComp);
9980           int *res=ret->getPointer();
9981           for(int i=0;i<nbOfTupleMax;i++)
9982             res=std::transform(aMaxPtr+i*nbOfComp,aMaxPtr+(i+1)*nbOfComp,aMinPtr,res,std::multiplies<int>());
9983           ret->copyStringInfoFrom(*aMax);
9984         }
9985       else
9986         throw INTERP_KERNEL::Exception("Nb of components mismatch for array Multiply !");
9987     }
9988   else
9989     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Multiply !");
9990   return ret.retn();
9991 }
9992
9993
9994 /*!
9995  * Multiply values of another DataArrayInt to values of \a this one. There are 3
9996  * valid cases.
9997  * 1.  The arrays have same number of tuples and components. Then each value of
9998  *   \a other array is multiplied to the corresponding value of \a this array, i.e.:
9999  *   _a_ [ i, j ] *= _other_ [ i, j ].
10000  * 2.  The arrays have same number of tuples and \a other array has one component. Then
10001  *   _a_ [ i, j ] *= _other_ [ i, 0 ].
10002  * 3.  The arrays have same number of components and \a other array has one tuple. Then
10003  *   _a_ [ i, j ] *= _a2_ [ 0, j ].
10004  *
10005  *  \param [in] other - an array to multiply to \a this one.
10006  *  \throw If \a other is NULL.
10007  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
10008  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
10009  *         \a other has number of both tuples and components not equal to 1.
10010  */
10011 void DataArrayInt::multiplyEqual(const DataArrayInt *other) throw(INTERP_KERNEL::Exception)
10012 {
10013   if(!other)
10014     throw INTERP_KERNEL::Exception("DataArrayInt::multiplyEqual : input DataArrayInt instance is NULL !");
10015   const char *msg="Nb of tuples mismatch for DataArrayInt::multiplyEqual !";
10016   checkAllocated(); other->checkAllocated();
10017   int nbOfTuple=getNumberOfTuples();
10018   int nbOfTuple2=other->getNumberOfTuples();
10019   int nbOfComp=getNumberOfComponents();
10020   int nbOfComp2=other->getNumberOfComponents();
10021   if(nbOfTuple==nbOfTuple2)
10022     {
10023       if(nbOfComp==nbOfComp2)
10024         {
10025           std::transform(begin(),end(),other->begin(),getPointer(),std::multiplies<int>());
10026         }
10027       else if(nbOfComp2==1)
10028         {
10029           int *ptr=getPointer();
10030           const int *ptrc=other->getConstPointer();
10031           for(int i=0;i<nbOfTuple;i++)
10032             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::multiplies<int>(),*ptrc++));    
10033         }
10034       else
10035         throw INTERP_KERNEL::Exception(msg);
10036     }
10037   else if(nbOfTuple2==1)
10038     {
10039       if(nbOfComp2==nbOfComp)
10040         {
10041           int *ptr=getPointer();
10042           const int *ptrc=other->getConstPointer();
10043           for(int i=0;i<nbOfTuple;i++)
10044             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::multiplies<int>());
10045         }
10046       else
10047         throw INTERP_KERNEL::Exception(msg);
10048     }
10049   else
10050     throw INTERP_KERNEL::Exception(msg);
10051   declareAsNew();
10052 }
10053
10054
10055 /*!
10056  * Returns a new DataArrayInt that is a division of two given arrays. There are 3
10057  * valid cases.
10058  * 1.  The arrays have same number of tuples and components. Then each value of
10059  *   the result array (_a_) is a division of the corresponding values of \a a1 and
10060  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ i, j ].
10061  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
10062  *   component. Then
10063  *   _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ i, 0 ].
10064  * 3.  The arrays have same number of components and one array, say _a2_, has one
10065  *   tuple. Then
10066  *   _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ 0, j ].
10067  *
10068  * Info on components is copied either from the first array (in the first case) or from
10069  * the array with maximal number of elements (getNbOfElems()).
10070  *  \warning No check of division by zero is performed!
10071  *  \param [in] a1 - a numerator array.
10072  *  \param [in] a2 - a denominator array.
10073  *  \return DataArrayInt * - the new instance of DataArrayInt.
10074  *          The caller is to delete this result array using decrRef() as it is no more
10075  *          needed.
10076  *  \throw If either \a a1 or \a a2 is NULL.
10077  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
10078  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
10079  *         none of them has number of tuples or components equal to 1.
10080  */
10081 DataArrayInt *DataArrayInt::Divide(const DataArrayInt *a1, const DataArrayInt *a2) throw(INTERP_KERNEL::Exception)
10082 {
10083   if(!a1 || !a2)
10084     throw INTERP_KERNEL::Exception("DataArrayInt::Divide : input DataArrayInt instance is NULL !");
10085   int nbOfTuple1=a1->getNumberOfTuples();
10086   int nbOfTuple2=a2->getNumberOfTuples();
10087   int nbOfComp1=a1->getNumberOfComponents();
10088   int nbOfComp2=a2->getNumberOfComponents();
10089   if(nbOfTuple2==nbOfTuple1)
10090     {
10091       if(nbOfComp1==nbOfComp2)
10092         {
10093           MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
10094           ret->alloc(nbOfTuple2,nbOfComp1);
10095           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::divides<int>());
10096           ret->copyStringInfoFrom(*a1);
10097           return ret.retn();
10098         }
10099       else if(nbOfComp2==1)
10100         {
10101           MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
10102           ret->alloc(nbOfTuple1,nbOfComp1);
10103           const int *a2Ptr=a2->getConstPointer();
10104           const int *a1Ptr=a1->getConstPointer();
10105           int *res=ret->getPointer();
10106           for(int i=0;i<nbOfTuple1;i++)
10107             res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::divides<int>(),a2Ptr[i]));
10108           ret->copyStringInfoFrom(*a1);
10109           return ret.retn();
10110         }
10111       else
10112         {
10113           a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Divide !");
10114           return 0;
10115         }
10116     }
10117   else if(nbOfTuple2==1)
10118     {
10119       a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Divide !");
10120       MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
10121       ret->alloc(nbOfTuple1,nbOfComp1);
10122       const int *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
10123       int *pt=ret->getPointer();
10124       for(int i=0;i<nbOfTuple1;i++)
10125         pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::divides<int>());
10126       ret->copyStringInfoFrom(*a1);
10127       return ret.retn();
10128     }
10129   else
10130     {
10131       a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Divide !");//will always throw an exception
10132       return 0;
10133     }
10134 }
10135
10136 /*!
10137  * Divide values of \a this array by values of another DataArrayInt. There are 3
10138  * valid cases.
10139  * 1.  The arrays have same number of tuples and components. Then each value of
10140  *    \a this array is divided by the corresponding value of \a other one, i.e.:
10141  *   _a_ [ i, j ] /= _other_ [ i, j ].
10142  * 2.  The arrays have same number of tuples and \a other array has one component. Then
10143  *   _a_ [ i, j ] /= _other_ [ i, 0 ].
10144  * 3.  The arrays have same number of components and \a other array has one tuple. Then
10145  *   _a_ [ i, j ] /= _a2_ [ 0, j ].
10146  *
10147  *  \warning No check of division by zero is performed!
10148  *  \param [in] other - an array to divide \a this one by.
10149  *  \throw If \a other is NULL.
10150  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
10151  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
10152  *         \a other has number of both tuples and components not equal to 1.
10153  */
10154 void DataArrayInt::divideEqual(const DataArrayInt *other) throw(INTERP_KERNEL::Exception)
10155 {
10156   if(!other)
10157     throw INTERP_KERNEL::Exception("DataArrayInt::divideEqual : input DataArrayInt instance is NULL !");
10158   const char *msg="Nb of tuples mismatch for DataArrayInt::divideEqual !";
10159   checkAllocated(); other->checkAllocated();
10160   int nbOfTuple=getNumberOfTuples();
10161   int nbOfTuple2=other->getNumberOfTuples();
10162   int nbOfComp=getNumberOfComponents();
10163   int nbOfComp2=other->getNumberOfComponents();
10164   if(nbOfTuple==nbOfTuple2)
10165     {
10166       if(nbOfComp==nbOfComp2)
10167         {
10168           std::transform(begin(),end(),other->begin(),getPointer(),std::divides<int>());
10169         }
10170       else if(nbOfComp2==1)
10171         {
10172           int *ptr=getPointer();
10173           const int *ptrc=other->getConstPointer();
10174           for(int i=0;i<nbOfTuple;i++)
10175             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::divides<int>(),*ptrc++));
10176         }
10177       else
10178         throw INTERP_KERNEL::Exception(msg);
10179     }
10180   else if(nbOfTuple2==1)
10181     {
10182       if(nbOfComp2==nbOfComp)
10183         {
10184           int *ptr=getPointer();
10185           const int *ptrc=other->getConstPointer();
10186           for(int i=0;i<nbOfTuple;i++)
10187             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::divides<int>());
10188         }
10189       else
10190         throw INTERP_KERNEL::Exception(msg);
10191     }
10192   else
10193     throw INTERP_KERNEL::Exception(msg);
10194   declareAsNew();
10195 }
10196
10197
10198 /*!
10199  * Returns a new DataArrayInt that is a modulus of two given arrays. There are 3
10200  * valid cases.
10201  * 1.  The arrays have same number of tuples and components. Then each value of
10202  *   the result array (_a_) is a division of the corresponding values of \a a1 and
10203  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] % _a2_ [ i, j ].
10204  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
10205  *   component. Then
10206  *   _a_ [ i, j ] = _a1_ [ i, j ] % _a2_ [ i, 0 ].
10207  * 3.  The arrays have same number of components and one array, say _a2_, has one
10208  *   tuple. Then
10209  *   _a_ [ i, j ] = _a1_ [ i, j ] % _a2_ [ 0, j ].
10210  *
10211  * Info on components is copied either from the first array (in the first case) or from
10212  * the array with maximal number of elements (getNbOfElems()).
10213  *  \warning No check of division by zero is performed!
10214  *  \param [in] a1 - a dividend array.
10215  *  \param [in] a2 - a divisor array.
10216  *  \return DataArrayInt * - the new instance of DataArrayInt.
10217  *          The caller is to delete this result array using decrRef() as it is no more
10218  *          needed.
10219  *  \throw If either \a a1 or \a a2 is NULL.
10220  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
10221  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
10222  *         none of them has number of tuples or components equal to 1.
10223  */
10224 DataArrayInt *DataArrayInt::Modulus(const DataArrayInt *a1, const DataArrayInt *a2) throw(INTERP_KERNEL::Exception)
10225 {
10226     if(!a1 || !a2)
10227     throw INTERP_KERNEL::Exception("DataArrayInt::Modulus : input DataArrayInt instance is NULL !");
10228   int nbOfTuple1=a1->getNumberOfTuples();
10229   int nbOfTuple2=a2->getNumberOfTuples();
10230   int nbOfComp1=a1->getNumberOfComponents();
10231   int nbOfComp2=a2->getNumberOfComponents();
10232   if(nbOfTuple2==nbOfTuple1)
10233     {
10234       if(nbOfComp1==nbOfComp2)
10235         {
10236           MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
10237           ret->alloc(nbOfTuple2,nbOfComp1);
10238           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::modulus<int>());
10239           ret->copyStringInfoFrom(*a1);
10240           return ret.retn();
10241         }
10242       else if(nbOfComp2==1)
10243         {
10244           MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
10245           ret->alloc(nbOfTuple1,nbOfComp1);
10246           const int *a2Ptr=a2->getConstPointer();
10247           const int *a1Ptr=a1->getConstPointer();
10248           int *res=ret->getPointer();
10249           for(int i=0;i<nbOfTuple1;i++)
10250             res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::modulus<int>(),a2Ptr[i]));
10251           ret->copyStringInfoFrom(*a1);
10252           return ret.retn();
10253         }
10254       else
10255         {
10256           a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Modulus !");
10257           return 0;
10258         }
10259     }
10260   else if(nbOfTuple2==1)
10261     {
10262       a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Modulus !");
10263       MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
10264       ret->alloc(nbOfTuple1,nbOfComp1);
10265       const int *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
10266       int *pt=ret->getPointer();
10267       for(int i=0;i<nbOfTuple1;i++)
10268         pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::modulus<int>());
10269       ret->copyStringInfoFrom(*a1);
10270       return ret.retn();
10271     }
10272   else
10273     {
10274       a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Modulus !");//will always throw an exception
10275       return 0;
10276     }
10277 }
10278
10279 /*!
10280  * Modify \a this array so that each value becomes a modulus of division of this value by
10281  * a value of another DataArrayInt. There are 3 valid cases.
10282  * 1.  The arrays have same number of tuples and components. Then each value of
10283  *    \a this array is divided by the corresponding value of \a other one, i.e.:
10284  *   _a_ [ i, j ] %= _other_ [ i, j ].
10285  * 2.  The arrays have same number of tuples and \a other array has one component. Then
10286  *   _a_ [ i, j ] %= _other_ [ i, 0 ].
10287  * 3.  The arrays have same number of components and \a other array has one tuple. Then
10288  *   _a_ [ i, j ] %= _a2_ [ 0, j ].
10289  *
10290  *  \warning No check of division by zero is performed!
10291  *  \param [in] other - a divisor array.
10292  *  \throw If \a other is NULL.
10293  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
10294  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
10295  *         \a other has number of both tuples and components not equal to 1.
10296  */
10297 void DataArrayInt::modulusEqual(const DataArrayInt *other) throw(INTERP_KERNEL::Exception)
10298 {
10299   if(!other)
10300     throw INTERP_KERNEL::Exception("DataArrayInt::modulusEqual : input DataArrayInt instance is NULL !");
10301   const char *msg="Nb of tuples mismatch for DataArrayInt::modulusEqual !";
10302   checkAllocated(); other->checkAllocated();
10303   int nbOfTuple=getNumberOfTuples();
10304   int nbOfTuple2=other->getNumberOfTuples();
10305   int nbOfComp=getNumberOfComponents();
10306   int nbOfComp2=other->getNumberOfComponents();
10307   if(nbOfTuple==nbOfTuple2)
10308     {
10309       if(nbOfComp==nbOfComp2)
10310         {
10311           std::transform(begin(),end(),other->begin(),getPointer(),std::modulus<int>());
10312         }
10313       else if(nbOfComp2==1)
10314         {
10315           if(nbOfComp2==nbOfComp)
10316             {
10317               int *ptr=getPointer();
10318               const int *ptrc=other->getConstPointer();
10319               for(int i=0;i<nbOfTuple;i++)
10320                 std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::modulus<int>(),*ptrc++));
10321             }
10322           else
10323             throw INTERP_KERNEL::Exception(msg);
10324         }
10325       else
10326         throw INTERP_KERNEL::Exception(msg);
10327     }
10328   else if(nbOfTuple2==1)
10329     {
10330       int *ptr=getPointer();
10331       const int *ptrc=other->getConstPointer();
10332       for(int i=0;i<nbOfTuple;i++)
10333         std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::modulus<int>());
10334     }
10335   else
10336     throw INTERP_KERNEL::Exception(msg);
10337   declareAsNew();
10338 }
10339
10340 /*!
10341  * Returns a new DataArrayInt that is the result of pow of two given arrays. There are 3
10342  * valid cases.
10343  *
10344  *  \param [in] a1 - an array to pow up.
10345  *  \param [in] a2 - another array to sum up.
10346  *  \return DataArrayInt * - the new instance of DataArrayInt.
10347  *          The caller is to delete this result array using decrRef() as it is no more
10348  *          needed.
10349  *  \throw If either \a a1 or \a a2 is NULL.
10350  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
10351  *  \throw If \a a1->getNumberOfComponents() != 1 or \a a2->getNumberOfComponents() != 1.
10352  *  \throw If there is a negative value in \a a2.
10353  */
10354 DataArrayInt *DataArrayInt::Pow(const DataArrayInt *a1, const DataArrayInt *a2) throw(INTERP_KERNEL::Exception)
10355 {
10356   if(!a1 || !a2)
10357     throw INTERP_KERNEL::Exception("DataArrayInt::Pow : at least one of input instances is null !");
10358   int nbOfTuple=a1->getNumberOfTuples();
10359   int nbOfTuple2=a2->getNumberOfTuples();
10360   int nbOfComp=a1->getNumberOfComponents();
10361   int nbOfComp2=a2->getNumberOfComponents();
10362   if(nbOfTuple!=nbOfTuple2)
10363     throw INTERP_KERNEL::Exception("DataArrayInt::Pow : number of tuples mismatches !");
10364   if(nbOfComp!=1 || nbOfComp2!=1)
10365     throw INTERP_KERNEL::Exception("DataArrayInt::Pow : number of components of both arrays must be equal to 1 !");
10366   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbOfTuple,1);
10367   const int *ptr1(a1->begin()),*ptr2(a2->begin());
10368   int *ptr=ret->getPointer();
10369   for(int i=0;i<nbOfTuple;i++,ptr1++,ptr2++,ptr++)
10370     {
10371       if(*ptr2>=0)
10372         {
10373           int tmp=1;
10374           for(int j=0;j<*ptr2;j++)
10375             tmp*=*ptr1;
10376           *ptr=tmp;
10377         }
10378       else
10379         {
10380           std::ostringstream oss; oss << "DataArrayInt::Pow : on tuple #" << i << " of a2 value is < 0 (" << *ptr2 << ") !";
10381           throw INTERP_KERNEL::Exception(oss.str().c_str());
10382         }
10383     }
10384   return ret.retn();
10385 }
10386
10387 /*!
10388  * Apply pow on values of another DataArrayInt to values of \a this one.
10389  *
10390  *  \param [in] other - an array to pow to \a this one.
10391  *  \throw If \a other is NULL.
10392  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples()
10393  *  \throw If \a this->getNumberOfComponents() != 1 or \a other->getNumberOfComponents() != 1
10394  *  \throw If there is a negative value in \a other.
10395  */
10396 void DataArrayInt::powEqual(const DataArrayInt *other) throw(INTERP_KERNEL::Exception)
10397 {
10398   if(!other)
10399     throw INTERP_KERNEL::Exception("DataArrayInt::powEqual : input instance is null !");
10400   int nbOfTuple=getNumberOfTuples();
10401   int nbOfTuple2=other->getNumberOfTuples();
10402   int nbOfComp=getNumberOfComponents();
10403   int nbOfComp2=other->getNumberOfComponents();
10404   if(nbOfTuple!=nbOfTuple2)
10405     throw INTERP_KERNEL::Exception("DataArrayInt::powEqual : number of tuples mismatches !");
10406   if(nbOfComp!=1 || nbOfComp2!=1)
10407     throw INTERP_KERNEL::Exception("DataArrayInt::powEqual : number of components of both arrays must be equal to 1 !");
10408   int *ptr=getPointer();
10409   const int *ptrc=other->begin();
10410   for(int i=0;i<nbOfTuple;i++,ptrc++,ptr++)
10411     {
10412       if(*ptrc>=0)
10413         {
10414           int tmp=1;
10415           for(int j=0;j<*ptrc;j++)
10416             tmp*=*ptr;
10417           *ptr=tmp;
10418         }
10419       else
10420         {
10421           std::ostringstream oss; oss << "DataArrayInt::powEqual : on tuple #" << i << " of other value is < 0 (" << *ptrc << ") !";
10422           throw INTERP_KERNEL::Exception(oss.str().c_str());
10423         }
10424     }
10425   declareAsNew();
10426 }
10427
10428 /*!
10429  * Returns a C array which is a renumbering map in "Old to New" mode for the input array.
10430  * This map, if applied to \a start array, would make it sorted. For example, if
10431  * \a start array contents are [9,10,0,6,4,11,3,7] then the contents of the result array is
10432  * [5,6,0,3,2,7,1,4].
10433  *  \param [in] start - pointer to the first element of the array for which the
10434  *         permutation map is computed.
10435  *  \param [in] end - pointer specifying the end of the array \a start, so that
10436  *         the last value of \a start is \a end[ -1 ].
10437  *  \return int * - the result permutation array that the caller is to delete as it is no
10438  *         more needed.
10439  *  \throw If there are equal values in the input array.
10440  */
10441 int *DataArrayInt::CheckAndPreparePermutation(const int *start, const int *end)
10442 {
10443   std::size_t sz=std::distance(start,end);
10444   int *ret=(int *)malloc(sz*sizeof(int));
10445   int *work=new int[sz];
10446   std::copy(start,end,work);
10447   std::sort(work,work+sz);
10448   if(std::unique(work,work+sz)!=work+sz)
10449     {
10450       delete [] work;
10451       free(ret);
10452       throw INTERP_KERNEL::Exception("Some elements are equals in the specified array !");
10453     }
10454   std::map<int,int> m;
10455   for(int *workPt=work;workPt!=work+sz;workPt++)
10456     m[*workPt]=(int)std::distance(work,workPt);
10457   int *iter2=ret;
10458   for(const int *iter=start;iter!=end;iter++,iter2++)
10459     *iter2=m[*iter];
10460   delete [] work;
10461   return ret;
10462 }
10463
10464 /*!
10465  * Returns a new DataArrayInt containing an arithmetic progression
10466  * that is equal to the sequence returned by Python \c range(\a begin,\a  end,\a  step )
10467  * function.
10468  *  \param [in] begin - the start value of the result sequence.
10469  *  \param [in] end - limiting value, so that every value of the result array is less than
10470  *              \a end.
10471  *  \param [in] step - specifies the increment or decrement.
10472  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
10473  *          array using decrRef() as it is no more needed.
10474  *  \throw If \a step == 0.
10475  *  \throw If \a end < \a begin && \a step > 0.
10476  *  \throw If \a end > \a begin && \a step < 0.
10477  */
10478 DataArrayInt *DataArrayInt::Range(int begin, int end, int step) throw(INTERP_KERNEL::Exception)
10479 {
10480   int nbOfTuples=GetNumberOfItemGivenBESRelative(begin,end,step,"DataArrayInt::Range");
10481   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
10482   ret->alloc(nbOfTuples,1);
10483   int *ptr=ret->getPointer();
10484   if(step>0)
10485     {
10486       for(int i=begin;i<end;i+=step,ptr++)
10487         *ptr=i;
10488     }
10489   else
10490     {
10491       for(int i=begin;i>end;i+=step,ptr++)
10492         *ptr=i;
10493     }
10494   return ret.retn();
10495 }
10496
10497 /*!
10498  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
10499  * Server side.
10500  */
10501 void DataArrayInt::getTinySerializationIntInformation(std::vector<int>& tinyInfo) const
10502 {
10503   tinyInfo.resize(2);
10504   if(isAllocated())
10505     {
10506       tinyInfo[0]=getNumberOfTuples();
10507       tinyInfo[1]=getNumberOfComponents();
10508     }
10509   else
10510     {
10511       tinyInfo[0]=-1;
10512       tinyInfo[1]=-1;
10513     }
10514 }
10515
10516 /*!
10517  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
10518  * Server side.
10519  */
10520 void DataArrayInt::getTinySerializationStrInformation(std::vector<std::string>& tinyInfo) const
10521 {
10522   if(isAllocated())
10523     {
10524       int nbOfCompo=getNumberOfComponents();
10525       tinyInfo.resize(nbOfCompo+1);
10526       tinyInfo[0]=getName();
10527       for(int i=0;i<nbOfCompo;i++)
10528         tinyInfo[i+1]=getInfoOnComponent(i);
10529     }
10530   else
10531     {
10532       tinyInfo.resize(1);
10533       tinyInfo[0]=getName();
10534     }
10535 }
10536
10537 /*!
10538  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
10539  * This method returns if a feeding is needed.
10540  */
10541 bool DataArrayInt::resizeForUnserialization(const std::vector<int>& tinyInfoI)
10542 {
10543   int nbOfTuple=tinyInfoI[0];
10544   int nbOfComp=tinyInfoI[1];
10545   if(nbOfTuple!=-1 || nbOfComp!=-1)
10546     {
10547       alloc(nbOfTuple,nbOfComp);
10548       return true;
10549     }
10550   return false;
10551 }
10552
10553 /*!
10554  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
10555  * This method returns if a feeding is needed.
10556  */
10557 void DataArrayInt::finishUnserialization(const std::vector<int>& tinyInfoI, const std::vector<std::string>& tinyInfoS)
10558 {
10559   setName(tinyInfoS[0].c_str());
10560   if(isAllocated())
10561     {
10562       int nbOfCompo=getNumberOfComponents();
10563       for(int i=0;i<nbOfCompo;i++)
10564         setInfoOnComponent(i,tinyInfoS[i+1].c_str());
10565     }
10566 }
10567
10568 DataArrayIntIterator::DataArrayIntIterator(DataArrayInt *da):_da(da),_pt(0),_tuple_id(0),_nb_comp(0),_nb_tuple(0)
10569 {
10570   if(_da)
10571     {
10572       _da->incrRef();
10573       if(_da->isAllocated())
10574         {
10575           _nb_comp=da->getNumberOfComponents();
10576           _nb_tuple=da->getNumberOfTuples();
10577           _pt=da->getPointer();
10578         }
10579     }
10580 }
10581
10582 DataArrayIntIterator::~DataArrayIntIterator()
10583 {
10584   if(_da)
10585     _da->decrRef();
10586 }
10587
10588 DataArrayIntTuple *DataArrayIntIterator::nextt() throw(INTERP_KERNEL::Exception)
10589 {
10590   if(_tuple_id<_nb_tuple)
10591     {
10592       _tuple_id++;
10593       DataArrayIntTuple *ret=new DataArrayIntTuple(_pt,_nb_comp);
10594       _pt+=_nb_comp;
10595       return ret;
10596     }
10597   else
10598     return 0;
10599 }
10600
10601 DataArrayIntTuple::DataArrayIntTuple(int *pt, int nbOfComp):_pt(pt),_nb_of_compo(nbOfComp)
10602 {
10603 }
10604
10605 std::string DataArrayIntTuple::repr() const throw(INTERP_KERNEL::Exception)
10606 {
10607   std::ostringstream oss; oss << "(";
10608   for(int i=0;i<_nb_of_compo-1;i++)
10609     oss << _pt[i] << ", ";
10610   oss << _pt[_nb_of_compo-1] << ")";
10611   return oss.str();
10612 }
10613
10614 int DataArrayIntTuple::intValue() const throw(INTERP_KERNEL::Exception)
10615 {
10616   if(_nb_of_compo==1)
10617     return *_pt;
10618   throw INTERP_KERNEL::Exception("DataArrayIntTuple::intValue : DataArrayIntTuple instance has not exactly 1 component -> Not possible to convert it into an integer !");
10619 }
10620
10621 /*!
10622  * This method returns a newly allocated instance the caller should dealed with by a ParaMEDMEM::DataArrayInt::decrRef.
10623  * This method performs \b no copy of data. The content is only referenced using ParaMEDMEM::DataArrayInt::useArray with ownership set to \b false.
10624  * 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
10625  * \b nbOfCompo=1 and \bnbOfTuples==this->_nb_of_elem.
10626  */
10627 DataArrayInt *DataArrayIntTuple::buildDAInt(int nbOfTuples, int nbOfCompo) const throw(INTERP_KERNEL::Exception)
10628 {
10629   if((_nb_of_compo==nbOfCompo && nbOfTuples==1) || (_nb_of_compo==nbOfTuples && nbOfCompo==1))
10630     {
10631       DataArrayInt *ret=DataArrayInt::New();
10632       ret->useExternalArrayWithRWAccess(_pt,nbOfTuples,nbOfCompo);
10633       return ret;
10634     }
10635   else
10636     {
10637       std::ostringstream oss; oss << "DataArrayIntTuple::buildDAInt : unable to build a requested DataArrayInt instance with nbofTuple=" << nbOfTuples << " and nbOfCompo=" << nbOfCompo;
10638       oss << ".\nBecause the number of elements in this is " << _nb_of_compo << " !";
10639       throw INTERP_KERNEL::Exception(oss.str().c_str());
10640     }
10641 }