Salome HOME
Add missing icon name
[tools/medcoupling.git] / src / MEDCoupling / MEDCouplingMemArray.cxx
1 // Copyright (C) 2007-2013  CEA/DEN, EDF R&D
2 //
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License.
7 //
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11 // Lesser General Public License for more details.
12 //
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
16 //
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
18 //
19 // Author : Anthony Geay (CEA/DEN)
20
21 #include "MEDCouplingMemArray.txx"
22 #include "MEDCouplingAutoRefCountObjectPtr.hxx"
23
24 #include "GenMathFormulae.hxx"
25 #include "InterpKernelExprParser.hxx"
26
27 #include <set>
28 #include <cmath>
29 #include <limits>
30 #include <numeric>
31 #include <algorithm>
32 #include <functional>
33
34 typedef double (*MYFUNCPTR)(double);
35
36 using namespace ParaMEDMEM;
37
38 template<int SPACEDIM>
39 void DataArrayDouble::findCommonTuplesAlg(const double *bbox, int nbNodes, int limitNodeId, double prec, DataArrayInt *c, DataArrayInt *cI) const
40 {
41   const double *coordsPtr=getConstPointer();
42   BBTreePts<SPACEDIM,int> myTree(bbox,0,0,nbNodes,prec);
43   std::vector<bool> isDone(nbNodes);
44   for(int i=0;i<nbNodes;i++)
45     {
46       if(!isDone[i])
47         {
48           std::vector<int> intersectingElems;
49           myTree.getElementsAroundPoint(coordsPtr+i*SPACEDIM,intersectingElems);
50           if(intersectingElems.size()>1)
51             {
52               std::vector<int> commonNodes;
53               for(std::vector<int>::const_iterator it=intersectingElems.begin();it!=intersectingElems.end();it++)
54                 if(*it!=i)
55                   if(*it>=limitNodeId)
56                     {
57                       commonNodes.push_back(*it);
58                       isDone[*it]=true;
59                     }
60               if(!commonNodes.empty())
61                 {
62                   cI->pushBackSilent(cI->back()+(int)commonNodes.size()+1);
63                   c->pushBackSilent(i);
64                   c->insertAtTheEnd(commonNodes.begin(),commonNodes.end());
65                 }
66             }
67         }
68     }
69 }
70
71 template<int SPACEDIM>
72 void DataArrayDouble::FindTupleIdsNearTuplesAlg(const BBTreePts<SPACEDIM,int>& myTree, const double *pos, int nbOfTuples, double eps,
73                                                 DataArrayInt *c, DataArrayInt *cI)
74 {
75   for(int i=0;i<nbOfTuples;i++)
76     {
77       std::vector<int> intersectingElems;
78       myTree.getElementsAroundPoint(pos+i*SPACEDIM,intersectingElems);
79       std::vector<int> commonNodes;
80       for(std::vector<int>::const_iterator it=intersectingElems.begin();it!=intersectingElems.end();it++)
81         commonNodes.push_back(*it);
82       cI->pushBackSilent(cI->back()+(int)commonNodes.size());
83       c->insertAtTheEnd(commonNodes.begin(),commonNodes.end());
84     }
85 }
86
87 template<int SPACEDIM>
88 void DataArrayDouble::FindClosestTupleIdAlg(const BBTreePts<SPACEDIM,int>& myTree, double dist, const double *pos, int nbOfTuples, const double *thisPt, int thisNbOfTuples, int *res)
89 {
90   double distOpt(dist);
91   const double *p(pos);
92   int *r(res);
93   for(int i=0;i<nbOfTuples;i++,p+=SPACEDIM,r++)
94     {
95       while(true)
96         {
97           int elem=-1;
98           double ret=myTree.getElementsAroundPoint2(p,distOpt,elem);
99           if(ret!=std::numeric_limits<double>::max())
100             {
101               distOpt=std::max(ret,1e-4);
102               *r=elem;
103               break;
104             }
105           else
106             { distOpt=2*distOpt; continue; }
107         }
108     }
109 }
110
111 std::size_t DataArray::getHeapMemorySize() const
112 {
113   std::size_t sz1=_name.capacity();
114   std::size_t sz2=_info_on_compo.capacity();
115   std::size_t sz3=0;
116   for(std::vector<std::string>::const_iterator it=_info_on_compo.begin();it!=_info_on_compo.end();it++)
117     sz3+=(*it).capacity();
118   return sz1+sz2+sz3;
119 }
120
121 /*!
122  * Sets the attribute \a _name of \a this array.
123  * See \ref MEDCouplingArrayBasicsName "DataArrays infos" for more information.
124  *  \param [in] name - new array name
125  */
126 void DataArray::setName(const char *name)
127 {
128   _name=name;
129 }
130
131 /*!
132  * Copies textual data from an \a other DataArray. The copied data are
133  * - the name attribute,
134  * - the information of components.
135  *
136  * For more information on these data see \ref MEDCouplingArrayBasicsName "DataArrays infos".
137  *
138  *  \param [in] other - another instance of DataArray to copy the textual data from.
139  *  \throw If number of components of \a this array differs from that of the \a other.
140  */
141 void DataArray::copyStringInfoFrom(const DataArray& other) throw(INTERP_KERNEL::Exception)
142 {
143   if(_info_on_compo.size()!=other._info_on_compo.size())
144     throw INTERP_KERNEL::Exception("Size of arrays mismatches on copyStringInfoFrom !");
145   _name=other._name;
146   _info_on_compo=other._info_on_compo;
147 }
148
149 void DataArray::copyPartOfStringInfoFrom(const DataArray& other, const std::vector<int>& compoIds) throw(INTERP_KERNEL::Exception)
150 {
151   int nbOfCompoOth=other.getNumberOfComponents();
152   std::size_t newNbOfCompo=compoIds.size();
153   for(std::size_t i=0;i<newNbOfCompo;i++)
154     if(compoIds[i]>=nbOfCompoOth || compoIds[i]<0)
155       {
156         std::ostringstream oss; oss << "Specified component id is out of range (" << compoIds[i] << ") compared with nb of actual components (" << nbOfCompoOth << ")";
157         throw INTERP_KERNEL::Exception(oss.str().c_str());
158       }
159   for(std::size_t i=0;i<newNbOfCompo;i++)
160     setInfoOnComponent((int)i,other.getInfoOnComponent(compoIds[i]).c_str());
161 }
162
163 void DataArray::copyPartOfStringInfoFrom2(const std::vector<int>& compoIds, const DataArray& other) throw(INTERP_KERNEL::Exception)
164 {
165   int nbOfCompo=getNumberOfComponents();
166   std::size_t partOfCompoToSet=compoIds.size();
167   if((int)partOfCompoToSet!=other.getNumberOfComponents())
168     throw INTERP_KERNEL::Exception("Given compoIds has not the same size as number of components of given array !");
169   for(std::size_t i=0;i<partOfCompoToSet;i++)
170     if(compoIds[i]>=nbOfCompo || compoIds[i]<0)
171       {
172         std::ostringstream oss; oss << "Specified component id is out of range (" << compoIds[i] << ") compared with nb of actual components (" << nbOfCompo << ")";
173         throw INTERP_KERNEL::Exception(oss.str().c_str());
174       }
175   for(std::size_t i=0;i<partOfCompoToSet;i++)
176     setInfoOnComponent(compoIds[i],other.getInfoOnComponent((int)i).c_str());
177 }
178
179 bool DataArray::areInfoEqualsIfNotWhy(const DataArray& other, std::string& reason) const throw(INTERP_KERNEL::Exception)
180 {
181   std::ostringstream oss;
182   if(_name!=other._name)
183     {
184       oss << "Names DataArray mismatch : this name=\"" << _name << " other name=\"" << other._name << "\" !";
185       reason=oss.str();
186       return false;
187     }
188   if(_info_on_compo!=other._info_on_compo)
189     {
190       oss << "Components DataArray mismatch : \nThis components=";
191       for(std::vector<std::string>::const_iterator it=_info_on_compo.begin();it!=_info_on_compo.end();it++)
192         oss << "\"" << *it << "\",";
193       oss << "\nOther components=";
194       for(std::vector<std::string>::const_iterator it=other._info_on_compo.begin();it!=other._info_on_compo.end();it++)
195         oss << "\"" << *it << "\",";
196       reason=oss.str();
197       return false;
198     }
199   return true;
200 }
201
202 /*!
203  * Compares textual information of \a this DataArray with that of an \a other one.
204  * The compared data are
205  * - the name attribute,
206  * - the information of components.
207  *
208  * For more information on these data see \ref MEDCouplingArrayBasicsName "DataArrays infos".
209  *  \param [in] other - another instance of DataArray to compare the textual data of.
210  *  \return bool - \a true if the textual information is same, \a false else.
211  */
212 bool DataArray::areInfoEquals(const DataArray& other) const throw(INTERP_KERNEL::Exception)
213 {
214   std::string tmp;
215   return areInfoEqualsIfNotWhy(other,tmp);
216 }
217
218 void DataArray::reprWithoutNameStream(std::ostream& stream) const throw(INTERP_KERNEL::Exception)
219 {
220   stream << "Number of components : "<< getNumberOfComponents() << "\n";
221   stream << "Info of these components : ";
222   for(std::vector<std::string>::const_iterator iter=_info_on_compo.begin();iter!=_info_on_compo.end();iter++)
223     stream << "\"" << *iter << "\"   ";
224   stream << "\n";
225 }
226
227 std::string DataArray::cppRepr(const char *varName) const throw(INTERP_KERNEL::Exception)
228 {
229   std::ostringstream ret;
230   reprCppStream(varName,ret);
231   return ret.str();
232 }
233
234 /*!
235  * Sets information on all components. To know more on format of this information
236  * see \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
237  *  \param [in] info - a vector of strings.
238  *  \throw If size of \a info differs from the number of components of \a this.
239  */
240 void DataArray::setInfoOnComponents(const std::vector<std::string>& info) throw(INTERP_KERNEL::Exception)
241 {
242   if(getNumberOfComponents()!=(int)info.size())
243     {
244       std::ostringstream oss; oss << "DataArray::setInfoOnComponents : input is of size " << info.size() << " whereas number of components is equal to " << getNumberOfComponents() << " !";
245       throw INTERP_KERNEL::Exception(oss.str().c_str());
246     }
247   _info_on_compo=info;
248 }
249
250 std::vector<std::string> DataArray::getVarsOnComponent() const throw(INTERP_KERNEL::Exception)
251 {
252   int nbOfCompo=(int)_info_on_compo.size();
253   std::vector<std::string> ret(nbOfCompo);
254   for(int i=0;i<nbOfCompo;i++)
255     ret[i]=getVarOnComponent(i);
256   return ret;
257 }
258
259 std::vector<std::string> DataArray::getUnitsOnComponent() const throw(INTERP_KERNEL::Exception)
260 {
261   int nbOfCompo=(int)_info_on_compo.size();
262   std::vector<std::string> ret(nbOfCompo);
263   for(int i=0;i<nbOfCompo;i++)
264     ret[i]=getUnitOnComponent(i);
265   return ret;
266 }
267
268 /*!
269  * Returns information on a component specified by an index.
270  * To know more on format of this information
271  * see \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
272  *  \param [in] i - the index (zero based) of the component of interest.
273  *  \return std::string - a string containing the information on \a i-th component.
274  *  \throw If \a i is not a valid component index.
275  */
276 std::string DataArray::getInfoOnComponent(int i) const throw(INTERP_KERNEL::Exception)
277 {
278   if(i<(int)_info_on_compo.size() && i>=0)
279     return _info_on_compo[i];
280   else
281     {
282       std::ostringstream oss; oss << "DataArray::getInfoOnComponent : Specified component id is out of range (" << i << ") compared with nb of actual components (" << (int) _info_on_compo.size();
283       throw INTERP_KERNEL::Exception(oss.str().c_str());
284     }
285 }
286
287 /*!
288  * Returns the var part of the full information of the \a i-th component.
289  * For example, if \c getInfoOnComponent(0) returns "SIGXY [N/m^2]", then
290  * \c getVarOnComponent(0) returns "SIGXY".
291  * If a unit part of information is not detected by presence of
292  * two square brackets, then the full information is returned.
293  * To read more about the component information format, see
294  * \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
295  *  \param [in] i - the index (zero based) of the component of interest.
296  *  \return std::string - a string containing the var information, or the full info.
297  *  \throw If \a i is not a valid component index.
298  */
299 std::string DataArray::getVarOnComponent(int i) const throw(INTERP_KERNEL::Exception)
300 {
301   if(i<(int)_info_on_compo.size() && i>=0)
302     {
303       return GetVarNameFromInfo(_info_on_compo[i]);
304     }
305   else
306     {
307       std::ostringstream oss; oss << "DataArray::getVarOnComponent : Specified component id is out of range  (" << i << ") compared with nb of actual components (" << (int) _info_on_compo.size();
308       throw INTERP_KERNEL::Exception(oss.str().c_str());
309     }
310 }
311
312 /*!
313  * Returns the unit part of the full information of the \a i-th component.
314  * For example, if \c getInfoOnComponent(0) returns "SIGXY [ N/m^2]", then
315  * \c getUnitOnComponent(0) returns " N/m^2".
316  * If a unit part of information is not detected by presence of
317  * two square brackets, then an empty string is returned.
318  * To read more about the component information format, see
319  * \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
320  *  \param [in] i - the index (zero based) of the component of interest.
321  *  \return std::string - a string containing the unit information, if any, or "".
322  *  \throw If \a i is not a valid component index.
323  */
324 std::string DataArray::getUnitOnComponent(int i) const throw(INTERP_KERNEL::Exception)
325 {
326   if(i<(int)_info_on_compo.size() && i>=0)
327     {
328       return GetUnitFromInfo(_info_on_compo[i]);
329     }
330   else
331     {
332       std::ostringstream oss; oss << "DataArray::getUnitOnComponent : Specified component id is out of range  (" << i << ") compared with nb of actual components (" << (int) _info_on_compo.size();
333       throw INTERP_KERNEL::Exception(oss.str().c_str());
334     }
335 }
336
337 /*!
338  * Returns the var part of the full component information.
339  * For example, if \a info == "SIGXY [N/m^2]", then this method returns "SIGXY".
340  * If a unit part of information is not detected by presence of
341  * two square brackets, then the whole \a info is returned.
342  * To read more about the component information format, see
343  * \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
344  *  \param [in] info - the full component information.
345  *  \return std::string - a string containing only var information, or the \a info.
346  */
347 std::string DataArray::GetVarNameFromInfo(const std::string& info) throw(INTERP_KERNEL::Exception)
348 {
349   std::size_t p1=info.find_last_of('[');
350   std::size_t p2=info.find_last_of(']');
351   if(p1==std::string::npos || p2==std::string::npos)
352     return info;
353   if(p1>p2)
354     return info;
355   if(p1==0)
356     return std::string();
357   std::size_t p3=info.find_last_not_of(' ',p1-1);
358   return info.substr(0,p3+1);
359 }
360
361 /*!
362  * Returns the unit part of the full component information.
363  * For example, if \a info == "SIGXY [ N/m^2]", then this method returns " N/m^2".
364  * If a unit part of information is not detected by presence of
365  * two square brackets, then an empty string is returned.
366  * To read more about the component information format, see
367  * \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
368  *  \param [in] info - the full component information.
369  *  \return std::string - a string containing only unit information, if any, or "".
370  */
371 std::string DataArray::GetUnitFromInfo(const std::string& info) throw(INTERP_KERNEL::Exception)
372 {
373   std::size_t p1=info.find_last_of('[');
374   std::size_t p2=info.find_last_of(']');
375   if(p1==std::string::npos || p2==std::string::npos)
376     return std::string();
377   if(p1>p2)
378     return std::string();
379   return info.substr(p1+1,p2-p1-1);
380 }
381
382 /*!
383  * Sets information on a component specified by an index.
384  * To know more on format of this information
385  * see \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
386  *  \warning Don't pass NULL as \a info!
387  *  \param [in] i - the index (zero based) of the component of interest.
388  *  \param [in] info - the string containing the information.
389  *  \throw If \a i is not a valid component index.
390  */
391 void DataArray::setInfoOnComponent(int i, const char *info) throw(INTERP_KERNEL::Exception)
392 {
393   if(i<(int)_info_on_compo.size() && i>=0)
394     _info_on_compo[i]=info;
395   else
396     {
397       std::ostringstream oss; oss << "DataArray::setInfoOnComponent : Specified component id is out of range  (" << i << ") compared with nb of actual components (" << (int) _info_on_compo.size();
398       throw INTERP_KERNEL::Exception(oss.str().c_str());
399     }
400 }
401
402 void DataArray::checkNbOfTuples(int nbOfTuples, const char *msg) const throw(INTERP_KERNEL::Exception)
403 {
404   if(getNumberOfTuples()!=nbOfTuples)
405     {
406       std::ostringstream oss; oss << msg << " : mismatch number of tuples : expected " <<  nbOfTuples << " having " << getNumberOfTuples() << " !";
407       throw INTERP_KERNEL::Exception(oss.str().c_str());
408     }
409 }
410
411 void DataArray::checkNbOfComps(int nbOfCompo, const char *msg) const throw(INTERP_KERNEL::Exception)
412 {
413   if(getNumberOfComponents()!=nbOfCompo)
414     {
415       std::ostringstream oss; oss << msg << " : mismatch number of components : expected " << nbOfCompo << " having " << getNumberOfComponents() << " !";
416       throw INTERP_KERNEL::Exception(oss.str().c_str());
417     }
418 }
419
420 void DataArray::checkNbOfElems(std::size_t nbOfElems, const char *msg) const throw(INTERP_KERNEL::Exception)
421 {
422   if(getNbOfElems()!=nbOfElems)
423     {
424       std::ostringstream oss; oss << msg << " : mismatch number of elems : Expected " << nbOfElems << " having " << getNbOfElems() << " !";
425       throw INTERP_KERNEL::Exception(oss.str().c_str());
426     }
427 }
428
429 void DataArray::checkNbOfTuplesAndComp(const DataArray& other, const char *msg) const throw(INTERP_KERNEL::Exception)
430 {
431    if(getNumberOfTuples()!=other.getNumberOfTuples())
432     {
433       std::ostringstream oss; oss << msg << " : mismatch number of tuples : expected " <<  other.getNumberOfTuples() << " having " << getNumberOfTuples() << " !";
434       throw INTERP_KERNEL::Exception(oss.str().c_str());
435     }
436   if(getNumberOfComponents()!=other.getNumberOfComponents())
437     {
438       std::ostringstream oss; oss << msg << " : mismatch number of components : expected " << other.getNumberOfComponents() << " having " << getNumberOfComponents() << " !";
439       throw INTERP_KERNEL::Exception(oss.str().c_str());
440     }
441 }
442
443 void DataArray::checkNbOfTuplesAndComp(int nbOfTuples, int nbOfCompo, const char *msg) const throw(INTERP_KERNEL::Exception)
444 {
445   checkNbOfTuples(nbOfTuples,msg);
446   checkNbOfComps(nbOfCompo,msg);
447 }
448
449 /*!
450  * Simply this method checks that \b value is in [0,\b ref).
451  */
452 void DataArray::CheckValueInRange(int ref, int value, const char *msg) throw(INTERP_KERNEL::Exception)
453 {
454   if(value<0 || value>=ref)
455     {
456       std::ostringstream oss; oss << "DataArray::CheckValueInRange : " << msg  << " ! Expected in range [0," << ref << "[ having " << value << " !";
457       throw INTERP_KERNEL::Exception(oss.str().c_str());
458     }
459 }
460
461 /*!
462  * This method checks that [\b start, \b end) is compliant with ref length \b value.
463  * typicaly start in [0,\b value) and end in [0,\b value). If value==start and start==end, it is supported.
464  */
465 void DataArray::CheckValueInRangeEx(int value, int start, int end, const char *msg) throw(INTERP_KERNEL::Exception)
466 {
467   if(start<0 || start>=value)
468     {
469       if(value!=start || end!=start)
470         {
471           std::ostringstream oss; oss << "DataArray::CheckValueInRangeEx : " << msg  << " ! Expected start " << start << " of input range, in [0," << value << "[ !";
472           throw INTERP_KERNEL::Exception(oss.str().c_str());
473         }
474     }
475   if(end<0 || end>value)
476     {
477       std::ostringstream oss; oss << "DataArray::CheckValueInRangeEx : " << msg  << " ! Expected end " << end << " of input range, in [0," << value << "] !";
478       throw INTERP_KERNEL::Exception(oss.str().c_str());
479     }
480 }
481
482 void DataArray::CheckClosingParInRange(int ref, int value, const char *msg) throw(INTERP_KERNEL::Exception)
483 {
484   if(value<0 || value>ref)
485     {
486       std::ostringstream oss; oss << "DataArray::CheckClosingParInRange : " << msg  << " ! Expected input range in [0," << ref << "] having closing open parenthesis " << value << " !";
487       throw INTERP_KERNEL::Exception(oss.str().c_str());
488     }
489 }
490
491 int DataArray::GetNumberOfItemGivenBES(int begin, int end, int step, const char *msg) throw(INTERP_KERNEL::Exception)
492 {
493   if(end<begin)
494     {
495       std::ostringstream oss; oss << msg << " : end before begin !";
496       throw INTERP_KERNEL::Exception(oss.str().c_str());
497     }
498   if(end==begin)
499     return 0;
500   if(step<=0)
501     {
502       std::ostringstream oss; oss << msg << " : invalid step should be > 0 !";
503       throw INTERP_KERNEL::Exception(oss.str().c_str());
504     }
505   return (end-1-begin)/step+1;
506 }
507
508 int DataArray::GetNumberOfItemGivenBESRelative(int begin, int end, int step, const char *msg) throw(INTERP_KERNEL::Exception)
509 {
510   if(step==0)
511     throw INTERP_KERNEL::Exception("DataArray::GetNumberOfItemGivenBES : step=0 is not allowed !");
512   if(end<begin && step>0)
513     {
514       std::ostringstream oss; oss << msg << " : end before begin whereas step is positive !";
515       throw INTERP_KERNEL::Exception(oss.str().c_str());
516     }
517   if(begin<end && step<0)
518     {
519       std::ostringstream oss; oss << msg << " : invalid step should be > 0 !";
520       throw INTERP_KERNEL::Exception(oss.str().c_str());
521     }
522   if(begin!=end)
523     return (std::max(begin,end)-1-std::min(begin,end))/std::abs(step)+1;
524   else
525     return 0;
526 }
527
528 int DataArray::GetPosOfItemGivenBESRelativeNoThrow(int value, int begin, int end, int step) throw(INTERP_KERNEL::Exception)
529 {
530   if(step!=0)
531     {
532       if(step>0)
533         {
534           if(begin<=value && value<end)
535             {
536               if((value-begin)%step==0)
537                 return (value-begin)/step;
538               else
539                 return -1;
540             }
541           else
542             return -1;
543         }
544       else
545         {
546           if(begin>=value && value>end)
547             {
548               if((begin-value)%(-step)==0)
549                 return (begin-value)/(-step);
550               else
551                 return -1;
552             }
553           else
554             return -1;
555         }
556     }
557   else
558     return -1;
559 }
560
561 /*!
562  * Returns a new instance of DataArrayDouble. The caller is to delete this array
563  * using decrRef() as it is no more needed. 
564  */
565 DataArrayDouble *DataArrayDouble::New()
566 {
567   return new DataArrayDouble;
568 }
569
570 /*!
571  * Checks if raw data is allocated. Read more on the raw data
572  * in \ref MEDCouplingArrayBasicsTuplesAndCompo "DataArrays infos" for more information.
573  *  \return bool - \a true if the raw data is allocated, \a false else.
574  */
575 bool DataArrayDouble::isAllocated() const throw(INTERP_KERNEL::Exception)
576 {
577   return getConstPointer()!=0;
578 }
579
580 /*!
581  * Checks if raw data is allocated and throws an exception if it is not the case.
582  *  \throw If the raw data is not allocated.
583  */
584 void DataArrayDouble::checkAllocated() const throw(INTERP_KERNEL::Exception)
585 {
586   if(!isAllocated())
587     throw INTERP_KERNEL::Exception("DataArrayDouble::checkAllocated : Array is defined but not allocated ! Call alloc or setValues method first !");
588 }
589
590 std::size_t DataArrayDouble::getHeapMemorySize() const
591 {
592   std::size_t sz=_mem.getNbOfElemAllocated();
593   sz*=sizeof(double);
594   return DataArray::getHeapMemorySize()+sz;
595 }
596
597 /*!
598  * Sets information on all components. This method can change number of components
599  * at certain conditions; if the conditions are not respected, an exception is thrown.
600  * The number of components can be changed provided that \a this is not allocated.
601  *
602  * To know more on format of the component information see
603  * \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
604  *  \param [in] info - a vector of component infos.
605  *  \throw If \a this->getNumberOfComponents() != \a info.size() && \a this->isAllocated()
606  */
607 void DataArrayDouble::setInfoAndChangeNbOfCompo(const std::vector<std::string>& info) throw(INTERP_KERNEL::Exception)
608 {
609   if(getNumberOfComponents()!=(int)info.size())
610     {
611       if(!isAllocated())
612         _info_on_compo=info;
613       else
614         {
615           std::ostringstream oss; oss << "DataArrayDouble::setInfoAndChangeNbOfCompo : input is of size " << info.size() << " whereas number of components is equal to " << getNumberOfComponents() << "  and this is already allocated !";
616           throw INTERP_KERNEL::Exception(oss.str().c_str());
617         }
618     }
619   else
620     _info_on_compo=info;
621 }
622
623 /*!
624  * Returns the only one value in \a this, if and only if number of elements
625  * (nb of tuples * nb of components) is equal to 1, and that \a this is allocated.
626  *  \return double - the sole value stored in \a this array.
627  *  \throw If at least one of conditions stated above is not fulfilled.
628  */
629 double DataArrayDouble::doubleValue() const throw(INTERP_KERNEL::Exception)
630 {
631   if(isAllocated())
632     {
633       if(getNbOfElems()==1)
634         {
635           return *getConstPointer();
636         }
637       else
638         throw INTERP_KERNEL::Exception("DataArrayDouble::doubleValue : DataArrayDouble instance is allocated but number of elements is not equal to 1 !");
639     }
640   else
641     throw INTERP_KERNEL::Exception("DataArrayDouble::doubleValue : DataArrayDouble instance is not allocated !");
642 }
643
644 /*!
645  * Checks the number of tuples.
646  *  \return bool - \a true if getNumberOfTuples() == 0, \a false else.
647  *  \throw If \a this is not allocated.
648  */
649 bool DataArrayDouble::empty() const throw(INTERP_KERNEL::Exception)
650 {
651   checkAllocated();
652   return getNumberOfTuples()==0;
653 }
654
655 /*!
656  * Returns a full copy of \a this. For more info on copying data arrays see
657  * \ref MEDCouplingArrayBasicsCopyDeep.
658  *  \return DataArrayDouble * - a new instance of DataArrayDouble. The caller is to
659  *          delete this array using decrRef() as it is no more needed. 
660  */
661 DataArrayDouble *DataArrayDouble::deepCpy() const throw(INTERP_KERNEL::Exception)
662 {
663   return new DataArrayDouble(*this);
664 }
665
666 /*!
667  * Returns either a \a deep or \a shallow copy of this array. For more info see
668  * \ref MEDCouplingArrayBasicsCopyDeep and \ref MEDCouplingArrayBasicsCopyShallow.
669  *  \param [in] dCpy - if \a true, a deep copy is returned, else, a shallow one.
670  *  \return DataArrayDouble * - either a new instance of DataArrayDouble (if \a dCpy
671  *          == \a true) or \a this instance (if \a dCpy == \a false).
672  */
673 DataArrayDouble *DataArrayDouble::performCpy(bool dCpy) const throw(INTERP_KERNEL::Exception)
674 {
675   if(dCpy)
676     return deepCpy();
677   else
678     {
679       incrRef();
680       return const_cast<DataArrayDouble *>(this);
681     }
682 }
683
684 /*!
685  * Copies all the data from another DataArrayDouble. For more info see
686  * \ref MEDCouplingArrayBasicsCopyDeepAssign.
687  *  \param [in] other - another instance of DataArrayDouble to copy data from.
688  *  \throw If the \a other is not allocated.
689  */
690 void DataArrayDouble::cpyFrom(const DataArrayDouble& other) throw(INTERP_KERNEL::Exception)
691 {
692   other.checkAllocated();
693   int nbOfTuples=other.getNumberOfTuples();
694   int nbOfComp=other.getNumberOfComponents();
695   allocIfNecessary(nbOfTuples,nbOfComp);
696   std::size_t nbOfElems=(std::size_t)nbOfTuples*nbOfComp;
697   double *pt=getPointer();
698   const double *ptI=other.getConstPointer();
699   for(std::size_t i=0;i<nbOfElems;i++)
700     pt[i]=ptI[i];
701   copyStringInfoFrom(other);
702 }
703
704 /*!
705  * This method reserve nbOfElems elements in memory ( nbOfElems*8 bytes ) \b without impacting the number of tuples in \a this.
706  * 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.
707  * If \a this has not already been allocated, number of components is set to one.
708  * This method allows to reduce number of reallocations on invokation of DataArrayDouble::pushBackSilent and DataArrayDouble::pushBackValsSilent on \a this.
709  * 
710  * \sa DataArrayDouble::pack, DataArrayDouble::pushBackSilent, DataArrayDouble::pushBackValsSilent
711  */
712 void DataArrayDouble::reserve(std::size_t nbOfElems) throw(INTERP_KERNEL::Exception)
713 {
714   int nbCompo=getNumberOfComponents();
715   if(nbCompo==1)
716     {
717       _mem.reserve(nbOfElems);
718     }
719   else if(nbCompo==0)
720     {
721       _mem.reserve(nbOfElems);
722       _info_on_compo.resize(1);
723     }
724   else
725     throw INTERP_KERNEL::Exception("DataArrayDouble::reserve : not available for DataArrayDouble with number of components different than 1 !");
726 }
727
728 /*!
729  * 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
730  * of counter. So the caller is expected to call TimeLabel::declareAsNew on \a this at the end of the push session.
731  *
732  * \param [in] val the value to be added in \a this
733  * \throw If \a this has already been allocated with number of components different from one.
734  * \sa DataArrayDouble::pushBackValsSilent
735  */
736 void DataArrayDouble::pushBackSilent(double val) throw(INTERP_KERNEL::Exception)
737 {
738   int nbCompo=getNumberOfComponents();
739   if(nbCompo==1)
740     _mem.pushBack(val);
741   else if(nbCompo==0)
742     {
743       _info_on_compo.resize(1);
744       _mem.pushBack(val);
745     }
746   else
747     throw INTERP_KERNEL::Exception("DataArrayDouble::pushBackSilent : not available for DataArrayDouble with number of components different than 1 !");
748 }
749
750 /*!
751  * 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
752  * of counter. So the caller is expected to call TimeLabel::declareAsNew on \a this at the end of the push session.
753  *
754  *  \param [in] valsBg - an array of values to push at the end of \this.
755  *  \param [in] valsEnd - specifies the end of the array \a valsBg, so that
756  *              the last value of \a valsBg is \a valsEnd[ -1 ].
757  * \throw If \a this has already been allocated with number of components different from one.
758  * \sa DataArrayDouble::pushBackSilent
759  */
760 void DataArrayDouble::pushBackValsSilent(const double *valsBg, const double *valsEnd) throw(INTERP_KERNEL::Exception)
761 {
762   int nbCompo=getNumberOfComponents();
763   if(nbCompo==1)
764     _mem.insertAtTheEnd(valsBg,valsEnd);
765   else if(nbCompo==0)
766     {
767       _info_on_compo.resize(1);
768       _mem.insertAtTheEnd(valsBg,valsEnd);
769     }
770   else
771     throw INTERP_KERNEL::Exception("DataArrayDouble::pushBackValsSilent : not available for DataArrayDouble with number of components different than 1 !");
772 }
773
774 /*!
775  * This method returns silently ( without updating time label in \a this ) the last value, if any and suppress it.
776  * \throw If \a this is already empty.
777  * \throw If \a this has number of components different from one.
778  */
779 double DataArrayDouble::popBackSilent() throw(INTERP_KERNEL::Exception)
780 {
781   if(getNumberOfComponents()==1)
782     return _mem.popBack();
783   else
784     throw INTERP_KERNEL::Exception("DataArrayDouble::popBackSilent : not available for DataArrayDouble with number of components different than 1 !");
785 }
786
787 /*!
788  * 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.
789  *
790  * \sa DataArrayDouble::getHeapMemorySize, DataArrayDouble::reserve
791  */
792 void DataArrayDouble::pack() const throw(INTERP_KERNEL::Exception)
793 {
794   _mem.pack();
795 }
796
797 /*!
798  * Allocates the raw data in memory. If exactly same memory as needed already
799  * allocated, it is not re-allocated.
800  *  \param [in] nbOfTuple - number of tuples of data to allocate.
801  *  \param [in] nbOfCompo - number of components of data to allocate.
802  *  \throw If \a nbOfTuple < 0 or \a nbOfCompo < 0.
803  */
804 void DataArrayDouble::allocIfNecessary(int nbOfTuple, int nbOfCompo) throw(INTERP_KERNEL::Exception)
805 {
806   if(isAllocated())
807     {
808       if(nbOfTuple!=getNumberOfTuples() || nbOfCompo!=getNumberOfComponents())
809         alloc(nbOfTuple,nbOfCompo);
810     }
811   else
812     alloc(nbOfTuple,nbOfCompo);
813 }
814
815 /*!
816  * Allocates the raw data in memory. If the memory was already allocated, then it is
817  * freed and re-allocated. See an example of this method use
818  * \ref MEDCouplingArraySteps1WC "here".
819  *  \param [in] nbOfTuple - number of tuples of data to allocate.
820  *  \param [in] nbOfCompo - number of components of data to allocate.
821  *  \throw If \a nbOfTuple < 0 or \a nbOfCompo < 0.
822  */
823 void DataArrayDouble::alloc(int nbOfTuple, int nbOfCompo) throw(INTERP_KERNEL::Exception)
824 {
825   if(nbOfTuple<0 || nbOfCompo<0)
826     throw INTERP_KERNEL::Exception("DataArrayDouble::alloc : request for negative length of data !");
827   _info_on_compo.resize(nbOfCompo);
828   _mem.alloc(nbOfCompo*(std::size_t)nbOfTuple);
829   declareAsNew();
830 }
831
832 /*!
833  * Assign zero to all values in \a this array. To know more on filling arrays see
834  * \ref MEDCouplingArrayFill.
835  * \throw If \a this is not allocated.
836  */
837 void DataArrayDouble::fillWithZero() throw(INTERP_KERNEL::Exception)
838 {
839   checkAllocated();
840   _mem.fillWithValue(0.);
841   declareAsNew();
842 }
843
844 /*!
845  * Assign \a val to all values in \a this array. To know more on filling arrays see
846  * \ref MEDCouplingArrayFill.
847  *  \param [in] val - the value to fill with.
848  *  \throw If \a this is not allocated.
849  */
850 void DataArrayDouble::fillWithValue(double val) throw(INTERP_KERNEL::Exception)
851 {
852   checkAllocated();
853   _mem.fillWithValue(val);
854   declareAsNew();
855 }
856
857 /*!
858  * Set all values in \a this array so that the i-th element equals to \a init + i
859  * (i starts from zero). To know more on filling arrays see \ref MEDCouplingArrayFill.
860  *  \param [in] init - value to assign to the first element of array.
861  *  \throw If \a this->getNumberOfComponents() != 1
862  *  \throw If \a this is not allocated.
863  */
864 void DataArrayDouble::iota(double init) throw(INTERP_KERNEL::Exception)
865 {
866   checkAllocated();
867   if(getNumberOfComponents()!=1)
868     throw INTERP_KERNEL::Exception("DataArrayDouble::iota : works only for arrays with only one component, you can call 'rearrange' method before !");
869   double *ptr=getPointer();
870   int ntuples=getNumberOfTuples();
871   for(int i=0;i<ntuples;i++)
872     ptr[i]=init+double(i);
873   declareAsNew();
874 }
875
876 /*!
877  * Checks if all values in \a this array are equal to \a val at precision \a eps.
878  *  \param [in] val - value to check equality of array values to.
879  *  \param [in] eps - precision to check the equality.
880  *  \return bool - \a true if all values are in range (_val_ - _eps_; _val_ + _eps_),
881  *                 \a false else.
882  *  \throw If \a this->getNumberOfComponents() != 1
883  *  \throw If \a this is not allocated.
884  */
885 bool DataArrayDouble::isUniform(double val, double eps) const throw(INTERP_KERNEL::Exception)
886 {
887   checkAllocated();
888   if(getNumberOfComponents()!=1)
889     throw INTERP_KERNEL::Exception("DataArrayDouble::isUniform : must be applied on DataArrayDouble with only one component, you can call 'rearrange' method before !");
890   int nbOfTuples=getNumberOfTuples();
891   const double *w=getConstPointer();
892   const double *end2=w+nbOfTuples;
893   const double vmin=val-eps;
894   const double vmax=val+eps;
895   for(;w!=end2;w++)
896     if(*w<vmin || *w>vmax)
897       return false;
898   return true;
899 }
900
901 /*!
902  * Sorts values of the array.
903  *  \param [in] asc - \a true means ascending order, \a false, descending.
904  *  \throw If \a this is not allocated.
905  *  \throw If \a this->getNumberOfComponents() != 1.
906  */
907 void DataArrayDouble::sort(bool asc) throw(INTERP_KERNEL::Exception)
908 {
909   checkAllocated();
910   if(getNumberOfComponents()!=1)
911     throw INTERP_KERNEL::Exception("DataArrayDouble::sort : only supported with 'this' array with ONE component !");
912   _mem.sort(asc);
913   declareAsNew();
914 }
915
916 /*!
917  * Reverse the array values.
918  *  \throw If \a this->getNumberOfComponents() < 1.
919  *  \throw If \a this is not allocated.
920  */
921 void DataArrayDouble::reverse() throw(INTERP_KERNEL::Exception)
922 {
923   checkAllocated();
924   _mem.reverse(getNumberOfComponents());
925   declareAsNew();
926 }
927
928 /*!
929  * Checks that \a this array is consistently **increasing** or **decreasing** in value,
930  * with at least absolute difference value of |\a eps| at each step.
931  * If not an exception is thrown.
932  *  \param [in] increasing - if \a true, the array values should be increasing.
933  *  \param [in] eps - minimal absolute difference between the neighbor values at which 
934  *                    the values are considered different.
935  *  \throw If sequence of values is not strictly monotonic in agreement with \a
936  *         increasing arg.
937  *  \throw If \a this->getNumberOfComponents() != 1.
938  *  \throw If \a this is not allocated.
939  */
940 void DataArrayDouble::checkMonotonic(bool increasing, double eps) const throw(INTERP_KERNEL::Exception)
941 {
942   if(!isMonotonic(increasing,eps))
943     {
944       if (increasing)
945         throw INTERP_KERNEL::Exception("DataArrayDouble::checkMonotonic : 'this' is not INCREASING monotonic !");
946       else
947         throw INTERP_KERNEL::Exception("DataArrayDouble::checkMonotonic : 'this' is not DECREASING monotonic !");
948     }
949 }
950
951 /*!
952  * Checks that \a this array is consistently **increasing** or **decreasing** in value,
953  * with at least absolute difference value of |\a eps| at each step.
954  *  \param [in] increasing - if \a true, array values should be increasing.
955  *  \param [in] eps - minimal absolute difference between the neighbor values at which 
956  *                    the values are considered different.
957  *  \return bool - \a true if values change in accordance with \a increasing arg.
958  *  \throw If \a this->getNumberOfComponents() != 1.
959  *  \throw If \a this is not allocated.
960  */
961 bool DataArrayDouble::isMonotonic(bool increasing, double eps) const throw(INTERP_KERNEL::Exception)
962 {
963   checkAllocated();
964   if(getNumberOfComponents()!=1)
965     throw INTERP_KERNEL::Exception("DataArrayDouble::isMonotonic : only supported with 'this' array with ONE component !");
966   int nbOfElements=getNumberOfTuples();
967   const double *ptr=getConstPointer();
968   if(nbOfElements==0)
969     return true;
970   double ref=ptr[0];
971   double absEps=fabs(eps);
972   if(increasing)
973     {
974       for(int i=1;i<nbOfElements;i++)
975         {
976           if(ptr[i]<(ref+absEps))
977             return false;
978           ref=ptr[i];
979         }
980       return true;
981     }
982   else
983     {
984       for(int i=1;i<nbOfElements;i++)
985         {
986           if(ptr[i]>(ref-absEps))
987             return false;
988           ref=ptr[i];
989         }
990       return true;
991     }
992 }
993
994 /*!
995  * Returns a textual and human readable representation of \a this instance of
996  * DataArrayDouble. This text is shown when a DataArrayDouble is printed in Python.
997  *  \return std::string - text describing \a this DataArrayDouble.
998  */
999 std::string DataArrayDouble::repr() const throw(INTERP_KERNEL::Exception)
1000 {
1001   std::ostringstream ret;
1002   reprStream(ret);
1003   return ret.str();
1004 }
1005
1006 std::string DataArrayDouble::reprZip() const throw(INTERP_KERNEL::Exception)
1007 {
1008   std::ostringstream ret;
1009   reprZipStream(ret);
1010   return ret.str();
1011 }
1012
1013 void DataArrayDouble::writeVTK(std::ostream& ofs, int indent, const char *nameInFile) const throw(INTERP_KERNEL::Exception)
1014 {
1015   std::string idt(indent,' ');
1016   ofs.precision(17);
1017   ofs << idt << "<DataArray type=\"Float32\" Name=\"" << nameInFile << "\" NumberOfComponents=\"" << getNumberOfComponents() << "\"";
1018   ofs << " format=\"ascii\" RangeMin=\"" << getMinValueInArray() << "\" RangeMax=\"" << getMaxValueInArray() << "\">\n" << idt;
1019   std::copy(begin(),end(),std::ostream_iterator<double>(ofs," "));
1020   ofs << std::endl << idt << "</DataArray>\n";
1021 }
1022
1023 void DataArrayDouble::reprStream(std::ostream& stream) const throw(INTERP_KERNEL::Exception)
1024 {
1025   stream << "Name of double array : \"" << _name << "\"\n";
1026   reprWithoutNameStream(stream);
1027 }
1028
1029 void DataArrayDouble::reprZipStream(std::ostream& stream) const throw(INTERP_KERNEL::Exception)
1030 {
1031   stream << "Name of double array : \"" << _name << "\"\n";
1032   reprZipWithoutNameStream(stream);
1033 }
1034
1035 void DataArrayDouble::reprWithoutNameStream(std::ostream& stream) const throw(INTERP_KERNEL::Exception)
1036 {
1037   DataArray::reprWithoutNameStream(stream);
1038   stream.precision(17);
1039   _mem.repr(getNumberOfComponents(),stream);
1040 }
1041
1042 void DataArrayDouble::reprZipWithoutNameStream(std::ostream& stream) const throw(INTERP_KERNEL::Exception)
1043 {
1044   DataArray::reprWithoutNameStream(stream);
1045   stream.precision(17);
1046   _mem.reprZip(getNumberOfComponents(),stream);
1047 }
1048
1049 void DataArrayDouble::reprCppStream(const char *varName, std::ostream& stream) const throw(INTERP_KERNEL::Exception)
1050 {
1051   int nbTuples=getNumberOfTuples(),nbComp=getNumberOfComponents();
1052   const double *data=getConstPointer();
1053   stream.precision(17);
1054   stream << "DataArrayDouble *" << varName << "=DataArrayDouble::New();" << std::endl;
1055   if(nbTuples*nbComp>=1)
1056     {
1057       stream << "const double " << varName << "Data[" << nbTuples*nbComp << "]={";
1058       std::copy(data,data+nbTuples*nbComp-1,std::ostream_iterator<double>(stream,","));
1059       stream << data[nbTuples*nbComp-1] << "};" << std::endl;
1060       stream << varName << "->useArray(" << varName << "Data,false,CPP_DEALLOC," << nbTuples << "," << nbComp << ");" << std::endl;
1061     }
1062   else
1063     stream << varName << "->alloc(" << nbTuples << "," << nbComp << ");" << std::endl;
1064   stream << varName << "->setName(\"" << getName() << "\");" << std::endl;
1065 }
1066
1067 /*!
1068  * Method that gives a quick overvien of \a this for python.
1069  */
1070 void DataArrayDouble::reprQuickOverview(std::ostream& stream) const throw(INTERP_KERNEL::Exception)
1071 {
1072   static const std::size_t MAX_NB_OF_BYTE_IN_REPR=300;
1073   stream << "DataArrayDouble C++ instance at " << this << ". ";
1074   if(isAllocated())
1075     {
1076       int nbOfCompo=(int)_info_on_compo.size();
1077       if(nbOfCompo>=1)
1078         {
1079           int nbOfTuples=getNumberOfTuples();
1080           stream << "Number of tuples : " << nbOfTuples << ". Number of components : " << nbOfCompo << "." << std::endl;
1081           reprQuickOverviewData(stream,MAX_NB_OF_BYTE_IN_REPR);
1082         }
1083       else
1084         stream << "Number of components : 0.";
1085     }
1086   else
1087     stream << "*** No data allocated ****";
1088 }
1089
1090 void DataArrayDouble::reprQuickOverviewData(std::ostream& stream, std::size_t maxNbOfByteInRepr) const throw(INTERP_KERNEL::Exception)
1091 {
1092   const double *data=begin();
1093   int nbOfTuples=getNumberOfTuples();
1094   int nbOfCompo=(int)_info_on_compo.size();
1095   std::ostringstream oss2; oss2 << "[";
1096   oss2.precision(17);
1097   std::string oss2Str(oss2.str());
1098   bool isFinished=true;
1099   for(int i=0;i<nbOfTuples && isFinished;i++)
1100     {
1101       if(nbOfCompo>1)
1102         {
1103           oss2 << "(";
1104           for(int j=0;j<nbOfCompo;j++,data++)
1105             {
1106               oss2 << *data;
1107               if(j!=nbOfCompo-1) oss2 << ", ";
1108             }
1109           oss2 << ")";
1110         }
1111       else
1112         oss2 << *data++;
1113       if(i!=nbOfTuples-1) oss2 << ", ";
1114       std::string oss3Str(oss2.str());
1115       if(oss3Str.length()<maxNbOfByteInRepr)
1116         oss2Str=oss3Str;
1117       else
1118         isFinished=false;
1119     }
1120   stream << oss2Str;
1121   if(!isFinished)
1122     stream << "... ";
1123   stream << "]";
1124 }
1125
1126 /*!
1127  * Equivalent to DataArrayDouble::isEqual except that if false the reason of
1128  * mismatch is given.
1129  * 
1130  * \param [in] other the instance to be compared with \a this
1131  * \param [in] prec the precision to compare numeric data of the arrays.
1132  * \param [out] reason In case of inequality returns the reason.
1133  * \sa DataArrayDouble::isEqual
1134  */
1135 bool DataArrayDouble::isEqualIfNotWhy(const DataArrayDouble& other, double prec, std::string& reason) const throw(INTERP_KERNEL::Exception)
1136 {
1137   if(!areInfoEqualsIfNotWhy(other,reason))
1138     return false;
1139   return _mem.isEqual(other._mem,prec,reason);
1140 }
1141
1142 /*!
1143  * Checks if \a this and another DataArrayDouble are fully equal. For more info see
1144  * \ref MEDCouplingArrayBasicsCompare.
1145  *  \param [in] other - an instance of DataArrayDouble to compare with \a this one.
1146  *  \param [in] prec - precision value to compare numeric data of the arrays.
1147  *  \return bool - \a true if the two arrays are equal, \a false else.
1148  */
1149 bool DataArrayDouble::isEqual(const DataArrayDouble& other, double prec) const throw(INTERP_KERNEL::Exception)
1150 {
1151   std::string tmp;
1152   return isEqualIfNotWhy(other,prec,tmp);
1153 }
1154
1155 /*!
1156  * Checks if values of \a this and another DataArrayDouble are equal. For more info see
1157  * \ref MEDCouplingArrayBasicsCompare.
1158  *  \param [in] other - an instance of DataArrayDouble to compare with \a this one.
1159  *  \param [in] prec - precision value to compare numeric data of the arrays.
1160  *  \return bool - \a true if the values of two arrays are equal, \a false else.
1161  */
1162 bool DataArrayDouble::isEqualWithoutConsideringStr(const DataArrayDouble& other, double prec) const throw(INTERP_KERNEL::Exception)
1163 {
1164   std::string tmp;
1165   return _mem.isEqual(other._mem,prec,tmp);
1166 }
1167
1168 /*!
1169  * Changes number of tuples in the array. If the new number of tuples is smaller
1170  * than the current number the array is truncated, otherwise the array is extended.
1171  *  \param [in] nbOfTuples - new number of tuples. 
1172  *  \throw If \a this is not allocated.
1173  */
1174 void DataArrayDouble::reAlloc(int nbOfTuples) throw(INTERP_KERNEL::Exception)
1175 {
1176   checkAllocated();
1177   _mem.reAlloc(getNumberOfComponents()*(std::size_t)nbOfTuples);
1178   declareAsNew();
1179 }
1180
1181 /*!
1182  * Creates a new DataArrayInt and assigns all (textual and numerical) data of \a this
1183  * array to the new one.
1184  *  \return DataArrayInt * - the new instance of DataArrayInt.
1185  */
1186 DataArrayInt *DataArrayDouble::convertToIntArr() const
1187 {
1188   DataArrayInt *ret=DataArrayInt::New();
1189   ret->alloc(getNumberOfTuples(),getNumberOfComponents());
1190   std::size_t nbOfVals=getNbOfElems();
1191   const double *src=getConstPointer();
1192   int *dest=ret->getPointer();
1193   std::copy(src,src+nbOfVals,dest);
1194   ret->copyStringInfoFrom(*this);
1195   return ret;
1196 }
1197
1198 /*!
1199  * Returns a new DataArrayDouble holding the same values as \a this array but differently
1200  * arranged in memory. If \a this array holds 2 components of 3 values:
1201  * \f$ x_0,x_1,x_2,y_0,y_1,y_2 \f$, then the result array holds these values arranged
1202  * as follows: \f$ x_0,y_0,x_1,y_1,x_2,y_2 \f$.
1203  *  \warning Do not confuse this method with transpose()!
1204  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1205  *          is to delete using decrRef() as it is no more needed.
1206  *  \throw If \a this is not allocated.
1207  */
1208 DataArrayDouble *DataArrayDouble::fromNoInterlace() const throw(INTERP_KERNEL::Exception)
1209 {
1210   if(_mem.isNull())
1211     throw INTERP_KERNEL::Exception("DataArrayDouble::fromNoInterlace : Not defined array !");
1212   double *tab=_mem.fromNoInterlace(getNumberOfComponents());
1213   DataArrayDouble *ret=DataArrayDouble::New();
1214   ret->useArray(tab,true,CPP_DEALLOC,getNumberOfTuples(),getNumberOfComponents());
1215   return ret;
1216 }
1217
1218 /*!
1219  * Returns a new DataArrayDouble holding the same values as \a this array but differently
1220  * arranged in memory. If \a this array holds 2 components of 3 values:
1221  * \f$ x_0,y_0,x_1,y_1,x_2,y_2 \f$, then the result array holds these values arranged
1222  * as follows: \f$ x_0,x_1,x_2,y_0,y_1,y_2 \f$.
1223  *  \warning Do not confuse this method with transpose()!
1224  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1225  *          is to delete using decrRef() as it is no more needed.
1226  *  \throw If \a this is not allocated.
1227  */
1228 DataArrayDouble *DataArrayDouble::toNoInterlace() const throw(INTERP_KERNEL::Exception)
1229 {
1230   if(_mem.isNull())
1231     throw INTERP_KERNEL::Exception("DataArrayDouble::toNoInterlace : Not defined array !");
1232   double *tab=_mem.toNoInterlace(getNumberOfComponents());
1233   DataArrayDouble *ret=DataArrayDouble::New();
1234   ret->useArray(tab,true,CPP_DEALLOC,getNumberOfTuples(),getNumberOfComponents());
1235   return ret;
1236 }
1237
1238 /*!
1239  * Permutes values of \a this array as required by \a old2New array. The values are
1240  * permuted so that \c new[ \a old2New[ i ]] = \c old[ i ]. Number of tuples remains
1241  * the same as in \this one.
1242  * If a permutation reduction is needed, substr() or selectByTupleId() should be used.
1243  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
1244  *  \param [in] old2New - C array of length equal to \a this->getNumberOfTuples()
1245  *     giving a new position for i-th old value.
1246  */
1247 void DataArrayDouble::renumberInPlace(const int *old2New) throw(INTERP_KERNEL::Exception)
1248 {
1249   checkAllocated();
1250   int nbTuples=getNumberOfTuples();
1251   int nbOfCompo=getNumberOfComponents();
1252   double *tmp=new double[nbTuples*nbOfCompo];
1253   const double *iptr=getConstPointer();
1254   for(int i=0;i<nbTuples;i++)
1255     std::copy(iptr+nbOfCompo*i,iptr+nbOfCompo*(i+1),tmp+nbOfCompo*old2New[i]);
1256   std::copy(tmp,tmp+nbTuples*nbOfCompo,getPointer());
1257   delete [] tmp;
1258   declareAsNew();
1259 }
1260
1261 /*!
1262  * Permutes values of \a this array as required by \a new2Old array. The values are
1263  * permuted so that \c new[ i ] = \c old[ \a new2Old[ i ]]. Number of tuples remains
1264  * the same as in \this one.
1265  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
1266  *  \param [in] new2Old - C array of length equal to \a this->getNumberOfTuples()
1267  *     giving a previous position of i-th new value.
1268  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1269  *          is to delete using decrRef() as it is no more needed.
1270  */
1271 void DataArrayDouble::renumberInPlaceR(const int *new2Old) throw(INTERP_KERNEL::Exception)
1272 {
1273   checkAllocated();
1274   int nbTuples=getNumberOfTuples();
1275   int nbOfCompo=getNumberOfComponents();
1276   double *tmp=new double[nbTuples*nbOfCompo];
1277   const double *iptr=getConstPointer();
1278   for(int i=0;i<nbTuples;i++)
1279     std::copy(iptr+nbOfCompo*new2Old[i],iptr+nbOfCompo*(new2Old[i]+1),tmp+nbOfCompo*i);
1280   std::copy(tmp,tmp+nbTuples*nbOfCompo,getPointer());
1281   delete [] tmp;
1282   declareAsNew();
1283 }
1284
1285 /*!
1286  * Returns a copy of \a this array with values permuted as required by \a old2New array.
1287  * The values are permuted so that  \c new[ \a old2New[ i ]] = \c old[ i ].
1288  * Number of tuples in the result array remains the same as in \this one.
1289  * If a permutation reduction is needed, renumberAndReduce() should be used.
1290  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
1291  *  \param [in] old2New - C array of length equal to \a this->getNumberOfTuples()
1292  *          giving a new position for i-th old value.
1293  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1294  *          is to delete using decrRef() as it is no more needed.
1295  *  \throw If \a this is not allocated.
1296  */
1297 DataArrayDouble *DataArrayDouble::renumber(const int *old2New) const throw(INTERP_KERNEL::Exception)
1298 {
1299   checkAllocated();
1300   int nbTuples=getNumberOfTuples();
1301   int nbOfCompo=getNumberOfComponents();
1302   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
1303   ret->alloc(nbTuples,nbOfCompo);
1304   ret->copyStringInfoFrom(*this);
1305   const double *iptr=getConstPointer();
1306   double *optr=ret->getPointer();
1307   for(int i=0;i<nbTuples;i++)
1308     std::copy(iptr+nbOfCompo*i,iptr+nbOfCompo*(i+1),optr+nbOfCompo*old2New[i]);
1309   ret->copyStringInfoFrom(*this);
1310   return ret.retn();
1311 }
1312
1313 /*!
1314  * Returns a copy of \a this array with values permuted as required by \a new2Old array.
1315  * The values are permuted so that  \c new[ i ] = \c old[ \a new2Old[ i ]]. Number of
1316  * tuples in the result array remains the same as in \this one.
1317  * If a permutation reduction is needed, substr() or selectByTupleId() should be used.
1318  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
1319  *  \param [in] new2Old - C array of length equal to \a this->getNumberOfTuples()
1320  *     giving a previous position of i-th new value.
1321  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1322  *          is to delete using decrRef() as it is no more needed.
1323  */
1324 DataArrayDouble *DataArrayDouble::renumberR(const int *new2Old) const throw(INTERP_KERNEL::Exception)
1325 {
1326   checkAllocated();
1327   int nbTuples=getNumberOfTuples();
1328   int nbOfCompo=getNumberOfComponents();
1329   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
1330   ret->alloc(nbTuples,nbOfCompo);
1331   ret->copyStringInfoFrom(*this);
1332   const double *iptr=getConstPointer();
1333   double *optr=ret->getPointer();
1334   for(int i=0;i<nbTuples;i++)
1335     std::copy(iptr+nbOfCompo*new2Old[i],iptr+nbOfCompo*(new2Old[i]+1),optr+i*nbOfCompo);
1336   ret->copyStringInfoFrom(*this);
1337   return ret.retn();
1338 }
1339
1340 /*!
1341  * Returns a shorten and permuted copy of \a this array. The new DataArrayDouble is
1342  * of size \a newNbOfTuple and it's values are permuted as required by \a old2New array.
1343  * The values are permuted so that  \c new[ \a old2New[ i ]] = \c old[ i ] for all
1344  * \a old2New[ i ] >= 0. In other words every i-th tuple in \a this array, for which 
1345  * \a old2New[ i ] is negative, is missing from the result array.
1346  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
1347  *  \param [in] old2New - C array of length equal to \a this->getNumberOfTuples()
1348  *     giving a new position for i-th old tuple and giving negative position for
1349  *     for i-th old tuple that should be omitted.
1350  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1351  *          is to delete using decrRef() as it is no more needed.
1352  */
1353 DataArrayDouble *DataArrayDouble::renumberAndReduce(const int *old2New, int newNbOfTuple) const throw(INTERP_KERNEL::Exception)
1354 {
1355   checkAllocated();
1356   int nbTuples=getNumberOfTuples();
1357   int nbOfCompo=getNumberOfComponents();
1358   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
1359   ret->alloc(newNbOfTuple,nbOfCompo);
1360   const double *iptr=getConstPointer();
1361   double *optr=ret->getPointer();
1362   for(int i=0;i<nbTuples;i++)
1363     {
1364       int w=old2New[i];
1365       if(w>=0)
1366         std::copy(iptr+i*nbOfCompo,iptr+(i+1)*nbOfCompo,optr+w*nbOfCompo);
1367     }
1368   ret->copyStringInfoFrom(*this);
1369   return ret.retn();
1370 }
1371
1372 /*!
1373  * Returns a shorten and permuted copy of \a this array. The new DataArrayDouble is
1374  * of size \a new2OldEnd - \a new2OldBg and it's values are permuted as required by
1375  * \a new2OldBg array.
1376  * The values are permuted so that  \c new[ i ] = \c old[ \a new2OldBg[ i ]].
1377  * This method is equivalent to renumberAndReduce() except that convention in input is
1378  * \c new2old and \b not \c old2new.
1379  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
1380  *  \param [in] new2OldBg - pointer to the beginning of a permutation array that gives a
1381  *              tuple index in \a this array to fill the i-th tuple in the new array.
1382  *  \param [in] new2OldEnd - specifies the end of the permutation array that starts at
1383  *              \a new2OldBg, so that pointer to a tuple index (\a pi) varies as this:
1384  *              \a new2OldBg <= \a pi < \a new2OldEnd.
1385  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1386  *          is to delete using decrRef() as it is no more needed.
1387  */
1388 DataArrayDouble *DataArrayDouble::selectByTupleId(const int *new2OldBg, const int *new2OldEnd) const
1389 {
1390   checkAllocated();
1391   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
1392   int nbComp=getNumberOfComponents();
1393   ret->alloc((int)std::distance(new2OldBg,new2OldEnd),nbComp);
1394   ret->copyStringInfoFrom(*this);
1395   double *pt=ret->getPointer();
1396   const double *srcPt=getConstPointer();
1397   int i=0;
1398   for(const int *w=new2OldBg;w!=new2OldEnd;w++,i++)
1399     std::copy(srcPt+(*w)*nbComp,srcPt+((*w)+1)*nbComp,pt+i*nbComp);
1400   ret->copyStringInfoFrom(*this);
1401   return ret.retn();
1402 }
1403
1404 /*!
1405  * Returns a shorten and permuted copy of \a this array. The new DataArrayDouble is
1406  * of size \a new2OldEnd - \a new2OldBg and it's values are permuted as required by
1407  * \a new2OldBg array.
1408  * The values are permuted so that  \c new[ i ] = \c old[ \a new2OldBg[ i ]].
1409  * This method is equivalent to renumberAndReduce() except that convention in input is
1410  * \c new2old and \b not \c old2new.
1411  * This method is equivalent to selectByTupleId() except that it prevents coping data
1412  * from behind the end of \a this array.
1413  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
1414  *  \param [in] new2OldBg - pointer to the beginning of a permutation array that gives a
1415  *              tuple index in \a this array to fill the i-th tuple in the new array.
1416  *  \param [in] new2OldEnd - specifies the end of the permutation array that starts at
1417  *              \a new2OldBg, so that pointer to a tuple index (\a pi) varies as this:
1418  *              \a new2OldBg <= \a pi < \a new2OldEnd.
1419  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1420  *          is to delete using decrRef() as it is no more needed.
1421  *  \throw If \a new2OldEnd - \a new2OldBg > \a this->getNumberOfTuples().
1422  */
1423 DataArrayDouble *DataArrayDouble::selectByTupleIdSafe(const int *new2OldBg, const int *new2OldEnd) const throw(INTERP_KERNEL::Exception)
1424 {
1425   checkAllocated();
1426   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
1427   int nbComp=getNumberOfComponents();
1428   int oldNbOfTuples=getNumberOfTuples();
1429   ret->alloc((int)std::distance(new2OldBg,new2OldEnd),nbComp);
1430   ret->copyStringInfoFrom(*this);
1431   double *pt=ret->getPointer();
1432   const double *srcPt=getConstPointer();
1433   int i=0;
1434   for(const int *w=new2OldBg;w!=new2OldEnd;w++,i++)
1435     if(*w>=0 && *w<oldNbOfTuples)
1436       std::copy(srcPt+(*w)*nbComp,srcPt+((*w)+1)*nbComp,pt+i*nbComp);
1437     else
1438       throw INTERP_KERNEL::Exception("DataArrayDouble::selectByTupleIdSafe : some ids has been detected to be out of [0,this->getNumberOfTuples) !");
1439   ret->copyStringInfoFrom(*this);
1440   return ret.retn();
1441 }
1442
1443 /*!
1444  * Returns a shorten copy of \a this array. The new DataArrayDouble contains every
1445  * (\a bg + \c i * \a step)-th tuple of \a this array located before the \a end2-th
1446  * tuple. Indices of the selected tuples are the same as ones returned by the Python
1447  * command \c range( \a bg, \a end2, \a step ).
1448  * This method is equivalent to selectByTupleIdSafe() except that the input array is
1449  * not constructed explicitly.
1450  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
1451  *  \param [in] bg - index of the first tuple to copy from \a this array.
1452  *  \param [in] end2 - index of the tuple before which the tuples to copy are located.
1453  *  \param [in] step - index increment to get index of the next tuple to copy.
1454  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1455  *          is to delete using decrRef() as it is no more needed.
1456  *  \sa DataArrayDouble::substr.
1457  */
1458 DataArrayDouble *DataArrayDouble::selectByTupleId2(int bg, int end2, int step) const throw(INTERP_KERNEL::Exception)
1459 {
1460   checkAllocated();
1461   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
1462   int nbComp=getNumberOfComponents();
1463   int newNbOfTuples=GetNumberOfItemGivenBESRelative(bg,end2,step,"DataArrayDouble::selectByTupleId2 : ");
1464   ret->alloc(newNbOfTuples,nbComp);
1465   double *pt=ret->getPointer();
1466   const double *srcPt=getConstPointer()+bg*nbComp;
1467   for(int i=0;i<newNbOfTuples;i++,srcPt+=step*nbComp)
1468     std::copy(srcPt,srcPt+nbComp,pt+i*nbComp);
1469   ret->copyStringInfoFrom(*this);
1470   return ret.retn();
1471 }
1472
1473 /*!
1474  * Returns a shorten copy of \a this array. The new DataArrayDouble contains ranges
1475  * of tuples specified by \a ranges parameter.
1476  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
1477  *  \param [in] ranges - std::vector of std::pair's each of which defines a range
1478  *              of tuples in [\c begin,\c end) format.
1479  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1480  *          is to delete using decrRef() as it is no more needed.
1481  *  \throw If \a end < \a begin.
1482  *  \throw If \a end > \a this->getNumberOfTuples().
1483  *  \throw If \a this is not allocated.
1484  */
1485 DataArrayDouble *DataArrayDouble::selectByTupleRanges(const std::vector<std::pair<int,int> >& ranges) const throw(INTERP_KERNEL::Exception)
1486 {
1487   checkAllocated();
1488   int nbOfComp=getNumberOfComponents();
1489   int nbOfTuplesThis=getNumberOfTuples();
1490   if(ranges.empty())
1491     {
1492       DataArrayDouble *ret=DataArrayDouble::New();
1493       ret->alloc(0,nbOfComp);
1494       ret->copyStringInfoFrom(*this);
1495       return ret;
1496     }
1497   int ref=ranges.front().first;
1498   int nbOfTuples=0;
1499   bool isIncreasing=true;
1500   for(std::vector<std::pair<int,int> >::const_iterator it=ranges.begin();it!=ranges.end();it++)
1501     {
1502       if((*it).first<=(*it).second)
1503         {
1504           if((*it).first>=0 && (*it).second<=nbOfTuplesThis)
1505             {
1506               nbOfTuples+=(*it).second-(*it).first;
1507               if(isIncreasing)
1508                 isIncreasing=ref<=(*it).first;
1509               ref=(*it).second;
1510             }
1511           else
1512             {
1513               std::ostringstream oss; oss << "DataArrayDouble::selectByTupleRanges : on range #" << std::distance(ranges.begin(),it);
1514               oss << " (" << (*it).first << "," << (*it).second << ") is greater than number of tuples of this :" << nbOfTuples << " !";
1515               throw INTERP_KERNEL::Exception(oss.str().c_str());
1516             }
1517         }
1518       else
1519         {
1520           std::ostringstream oss; oss << "DataArrayDouble::selectByTupleRanges : on range #" << std::distance(ranges.begin(),it);
1521           oss << " (" << (*it).first << "," << (*it).second << ") end is before begin !";
1522           throw INTERP_KERNEL::Exception(oss.str().c_str());
1523         }
1524     }
1525   if(isIncreasing && nbOfTuplesThis==nbOfTuples)
1526     return deepCpy();
1527   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
1528   ret->alloc(nbOfTuples,nbOfComp);
1529   ret->copyStringInfoFrom(*this);
1530   const double *src=getConstPointer();
1531   double *work=ret->getPointer();
1532   for(std::vector<std::pair<int,int> >::const_iterator it=ranges.begin();it!=ranges.end();it++)
1533     work=std::copy(src+(*it).first*nbOfComp,src+(*it).second*nbOfComp,work);
1534   return ret.retn();
1535 }
1536
1537 /*!
1538  * Returns a shorten copy of \a this array. The new DataArrayDouble contains all
1539  * tuples starting from the \a tupleIdBg-th tuple and including all tuples located before
1540  * the \a tupleIdEnd-th one. This methods has a similar behavior as std::string::substr().
1541  * This method is a specialization of selectByTupleId2().
1542  *  \param [in] tupleIdBg - index of the first tuple to copy from \a this array.
1543  *  \param [in] tupleIdEnd - index of the tuple before which the tuples to copy are located.
1544  *          If \a tupleIdEnd == -1, all the tuples till the end of \a this array are copied.
1545  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1546  *          is to delete using decrRef() as it is no more needed.
1547  *  \throw If \a tupleIdBg < 0.
1548  *  \throw If \a tupleIdBg > \a this->getNumberOfTuples().
1549     \throw If \a tupleIdEnd != -1 && \a tupleIdEnd < \a this->getNumberOfTuples().
1550  *  \sa DataArrayDouble::selectByTupleId2
1551  */
1552 DataArrayDouble *DataArrayDouble::substr(int tupleIdBg, int tupleIdEnd) const throw(INTERP_KERNEL::Exception)
1553 {
1554   checkAllocated();
1555   int nbt=getNumberOfTuples();
1556   if(tupleIdBg<0)
1557     throw INTERP_KERNEL::Exception("DataArrayDouble::substr : The tupleIdBg parameter must be greater than 0 !");
1558   if(tupleIdBg>nbt)
1559     throw INTERP_KERNEL::Exception("DataArrayDouble::substr : The tupleIdBg parameter is greater than number of tuples !");
1560   int trueEnd=tupleIdEnd;
1561   if(tupleIdEnd!=-1)
1562     {
1563       if(tupleIdEnd>nbt)
1564         throw INTERP_KERNEL::Exception("DataArrayDouble::substr : The tupleIdBg parameter is greater or equal than number of tuples !");
1565     }
1566   else
1567     trueEnd=nbt;
1568   int nbComp=getNumberOfComponents();
1569   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
1570   ret->alloc(trueEnd-tupleIdBg,nbComp);
1571   ret->copyStringInfoFrom(*this);
1572   std::copy(getConstPointer()+tupleIdBg*nbComp,getConstPointer()+trueEnd*nbComp,ret->getPointer());
1573   return ret.retn();
1574 }
1575
1576 /*!
1577  * Returns a shorten or extended copy of \a this array. If \a newNbOfComp is less
1578  * than \a this->getNumberOfComponents() then the result array is shorten as each tuple
1579  * is truncated to have \a newNbOfComp components, keeping first components. If \a
1580  * newNbOfComp is more than \a this->getNumberOfComponents() then the result array is
1581  * expanded as each tuple is populated with \a dftValue to have \a newNbOfComp
1582  * components.  
1583  *  \param [in] newNbOfComp - number of components for the new array to have.
1584  *  \param [in] dftValue - value assigned to new values added to the new array.
1585  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1586  *          is to delete using decrRef() as it is no more needed.
1587  *  \throw If \a this is not allocated.
1588  */
1589 DataArrayDouble *DataArrayDouble::changeNbOfComponents(int newNbOfComp, double dftValue) const throw(INTERP_KERNEL::Exception)
1590 {
1591   checkAllocated();
1592   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
1593   ret->alloc(getNumberOfTuples(),newNbOfComp);
1594   const double *oldc=getConstPointer();
1595   double *nc=ret->getPointer();
1596   int nbOfTuples=getNumberOfTuples();
1597   int oldNbOfComp=getNumberOfComponents();
1598   int dim=std::min(oldNbOfComp,newNbOfComp);
1599   for(int i=0;i<nbOfTuples;i++)
1600     {
1601       int j=0;
1602       for(;j<dim;j++)
1603         nc[newNbOfComp*i+j]=oldc[i*oldNbOfComp+j];
1604       for(;j<newNbOfComp;j++)
1605         nc[newNbOfComp*i+j]=dftValue;
1606     }
1607   ret->setName(getName().c_str());
1608   for(int i=0;i<dim;i++)
1609     ret->setInfoOnComponent(i,getInfoOnComponent(i).c_str());
1610   ret->setName(getName().c_str());
1611   return ret.retn();
1612 }
1613
1614 /*!
1615  * Changes the number of components within \a this array so that its raw data **does
1616  * not** change, instead splitting this data into tuples changes.
1617  *  \warning This method erases all (name and unit) component info set before!
1618  *  \param [in] newNbOfComp - number of components for \a this array to have.
1619  *  \throw If \a this is not allocated
1620  *  \throw If getNbOfElems() % \a newNbOfCompo != 0.
1621  *  \throw If \a newNbOfCompo is lower than 1.
1622  *  \throw If the rearrange method would lead to a number of tuples higher than 2147483647 (maximal capacity of int32 !).
1623  *  \warning This method erases all (name and unit) component info set before!
1624  */
1625 void DataArrayDouble::rearrange(int newNbOfCompo) throw(INTERP_KERNEL::Exception)
1626 {
1627   checkAllocated();
1628   if(newNbOfCompo<1)
1629     throw INTERP_KERNEL::Exception("DataArrayDouble::rearrange : input newNbOfCompo must be > 0 !");
1630   std::size_t nbOfElems=getNbOfElems();
1631   if(nbOfElems%newNbOfCompo!=0)
1632     throw INTERP_KERNEL::Exception("DataArrayDouble::rearrange : nbOfElems%newNbOfCompo!=0 !");
1633   if(nbOfElems/newNbOfCompo>(std::size_t)std::numeric_limits<int>::max())
1634     throw INTERP_KERNEL::Exception("DataArrayDouble::rearrange : the rearrangement leads to too high number of tuples (> 2147483647) !");
1635   _info_on_compo.clear();
1636   _info_on_compo.resize(newNbOfCompo);
1637   declareAsNew();
1638 }
1639
1640 /*!
1641  * Changes the number of components within \a this array to be equal to its number
1642  * of tuples, and inversely its number of tuples to become equal to its number of 
1643  * components. So that its raw data **does not** change, instead splitting this
1644  * data into tuples changes.
1645  *  \warning This method erases all (name and unit) component info set before!
1646  *  \warning Do not confuse this method with fromNoInterlace() and toNoInterlace()!
1647  *  \throw If \a this is not allocated.
1648  *  \sa rearrange()
1649  */
1650 void DataArrayDouble::transpose() throw(INTERP_KERNEL::Exception)
1651 {
1652   checkAllocated();
1653   int nbOfTuples=getNumberOfTuples();
1654   rearrange(nbOfTuples);
1655 }
1656
1657 /*!
1658  * Returns a copy of \a this array composed of selected components.
1659  * The new DataArrayDouble has the same number of tuples but includes components
1660  * specified by \a compoIds parameter. So that getNbOfElems() of the result array
1661  * can be either less, same or more than \a this->getNbOfElems().
1662  *  \param [in] compoIds - sequence of zero based indices of components to include
1663  *              into the new array.
1664  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1665  *          is to delete using decrRef() as it is no more needed.
1666  *  \throw If \a this is not allocated.
1667  *  \throw If a component index (\a i) is not valid: 
1668  *         \a i < 0 || \a i >= \a this->getNumberOfComponents().
1669  *
1670  *  \ref cpp_mcdataarraydouble_keepselectedcomponents "Here is a Python example".
1671  */
1672 DataArrayDouble *DataArrayDouble::keepSelectedComponents(const std::vector<int>& compoIds) const throw(INTERP_KERNEL::Exception)
1673 {
1674   checkAllocated();
1675   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret(DataArrayDouble::New());
1676   std::size_t newNbOfCompo=compoIds.size();
1677   int oldNbOfCompo=getNumberOfComponents();
1678   for(std::vector<int>::const_iterator it=compoIds.begin();it!=compoIds.end();it++)
1679     if((*it)<0 || (*it)>=oldNbOfCompo)
1680       {
1681         std::ostringstream oss; oss << "DataArrayDouble::keepSelectedComponents : invalid requested component : " << *it << " whereas it should be in [0," << oldNbOfCompo << ") !";
1682         throw INTERP_KERNEL::Exception(oss.str().c_str());
1683       }
1684   int nbOfTuples=getNumberOfTuples();
1685   ret->alloc(nbOfTuples,(int)newNbOfCompo);
1686   ret->copyPartOfStringInfoFrom(*this,compoIds);
1687   const double *oldc=getConstPointer();
1688   double *nc=ret->getPointer();
1689   for(int i=0;i<nbOfTuples;i++)
1690     for(std::size_t j=0;j<newNbOfCompo;j++,nc++)
1691       *nc=oldc[i*oldNbOfCompo+compoIds[j]];
1692   return ret.retn();
1693 }
1694
1695 /*!
1696  * Appends components of another array to components of \a this one, tuple by tuple.
1697  * So that the number of tuples of \a this array remains the same and the number of 
1698  * components increases.
1699  *  \param [in] other - the DataArrayDouble to append to \a this one.
1700  *  \throw If \a this is not allocated.
1701  *  \throw If \a this and \a other arrays have different number of tuples.
1702  *
1703  *  \ref cpp_mcdataarraydouble_meldwith "Here is a C++ example".
1704  *
1705  *  \ref py_mcdataarraydouble_meldwith "Here is a Python example".
1706  */
1707 void DataArrayDouble::meldWith(const DataArrayDouble *other) throw(INTERP_KERNEL::Exception)
1708 {
1709   checkAllocated();
1710   other->checkAllocated();
1711   int nbOfTuples=getNumberOfTuples();
1712   if(nbOfTuples!=other->getNumberOfTuples())
1713     throw INTERP_KERNEL::Exception("DataArrayDouble::meldWith : mismatch of number of tuples !");
1714   int nbOfComp1=getNumberOfComponents();
1715   int nbOfComp2=other->getNumberOfComponents();
1716   double *newArr=new double[nbOfTuples*(nbOfComp1+nbOfComp2)];
1717   double *w=newArr;
1718   const double *inp1=getConstPointer();
1719   const double *inp2=other->getConstPointer();
1720   for(int i=0;i<nbOfTuples;i++,inp1+=nbOfComp1,inp2+=nbOfComp2)
1721     {
1722       w=std::copy(inp1,inp1+nbOfComp1,w);
1723       w=std::copy(inp2,inp2+nbOfComp2,w);
1724     }
1725   useArray(newArr,true,CPP_DEALLOC,nbOfTuples,nbOfComp1+nbOfComp2);
1726   std::vector<int> compIds(nbOfComp2);
1727   for(int i=0;i<nbOfComp2;i++)
1728     compIds[i]=nbOfComp1+i;
1729   copyPartOfStringInfoFrom2(compIds,*other);
1730 }
1731
1732 /*!
1733  * Searches for tuples coincident within \a prec tolerance. Each tuple is considered
1734  * as coordinates of a point in getNumberOfComponents()-dimensional space. The
1735  * distance is computed using norm2.
1736  *
1737  * Indices of coincident tuples are stored in output arrays.
1738  * A pair of arrays (\a comm, \a commIndex) is called "Surjective Format 2".
1739  *
1740  * This method is typically used by MEDCouplingPointSet::findCommonNodes() and
1741  * MEDCouplingUMesh::mergeNodes().
1742  *  \param [in] prec - minimal absolute distance between two tuples (infinite norm) at which they are
1743  *              considered not coincident.
1744  *  \param [in] limitTupleId - limit tuple id. If all tuples within a group of coincident
1745  *              tuples have id strictly lower than \a limitTupleId then they are not returned.
1746  *  \param [out] comm - the array holding ids (== indices) of coincident tuples. 
1747  *               \a comm->getNumberOfComponents() == 1. 
1748  *               \a comm->getNumberOfTuples() == \a commIndex->back().
1749  *  \param [out] commIndex - the array dividing all indices stored in \a comm into
1750  *               groups of (indices of) coincident tuples. Its every value is a tuple
1751  *               index where a next group of tuples begins. For example the second
1752  *               group of tuples in \a comm is described by following range of indices:
1753  *               [ \a commIndex[1], \a commIndex[2] ). \a commIndex->getNumberOfTuples()-1
1754  *               gives the number of groups of coincident tuples.
1755  *  \throw If \a this is not allocated.
1756  *  \throw If the number of components is not in [1,2,3].
1757  *
1758  *  \ref cpp_mcdataarraydouble_findcommontuples "Here is a C++ example".
1759  *
1760  *  \ref py_mcdataarraydouble_findcommontuples  "Here is a Python example".
1761  *  \sa DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2().
1762  */
1763 void DataArrayDouble::findCommonTuples(double prec, int limitTupleId, DataArrayInt *&comm, DataArrayInt *&commIndex) const throw(INTERP_KERNEL::Exception)
1764 {
1765   checkAllocated();
1766   int nbOfCompo=getNumberOfComponents();
1767   if ((nbOfCompo<1) || (nbOfCompo>3)) //test before work
1768     throw INTERP_KERNEL::Exception("DataArrayDouble::findCommonTuples : Unexpected spacedim of coords. Must be 1, 2 or 3.");
1769   
1770   int nbOfTuples=getNumberOfTuples();
1771   //
1772   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> c(DataArrayInt::New()),cI(DataArrayInt::New()); c->alloc(0,1); cI->pushBackSilent(0);
1773   switch(nbOfCompo)
1774     {
1775     case 3:
1776       findCommonTuplesAlg<3>(begin(),nbOfTuples,limitTupleId,prec,c,cI);
1777       break;
1778     case 2:
1779       findCommonTuplesAlg<2>(begin(),nbOfTuples,limitTupleId,prec,c,cI);
1780       break;
1781     case 1:
1782       findCommonTuplesAlg<1>(begin(),nbOfTuples,limitTupleId,prec,c,cI);
1783       break;
1784     default:
1785       throw INTERP_KERNEL::Exception("DataArrayDouble::findCommonTuples : nb of components managed are 1,2 and 3 ! not implemented for other number of components !");
1786     }
1787   comm=c.retn();
1788   commIndex=cI.retn();
1789 }
1790
1791 /*!
1792  * 
1793  * \param [in] nbTimes specifies the nb of times each tuples in \a this will be duplicated contiguouly in returned DataArrayDouble instance.
1794  *             \a nbTimes  should be at least equal to 1.
1795  * \return a newly allocated DataArrayDouble having one component and number of tuples equal to \a nbTimes * \c this->getNumberOfTuples.
1796  * \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.
1797  */
1798 DataArrayDouble *DataArrayDouble::duplicateEachTupleNTimes(int nbTimes) const throw(INTERP_KERNEL::Exception)
1799 {
1800   checkAllocated();
1801   if(getNumberOfComponents()!=1)
1802     throw INTERP_KERNEL::Exception("DataArrayDouble::duplicateEachTupleNTimes : this should have only one component !");
1803   if(nbTimes<1)
1804     throw INTERP_KERNEL::Exception("DataArrayDouble::duplicateEachTupleNTimes : nb times should be >= 1 !");
1805   int nbTuples=getNumberOfTuples();
1806   const double *inPtr=getConstPointer();
1807   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New(); ret->alloc(nbTimes*nbTuples,1);
1808   double *retPtr=ret->getPointer();
1809   for(int i=0;i<nbTuples;i++,inPtr++)
1810     {
1811       double val=*inPtr;
1812       for(int j=0;j<nbTimes;j++,retPtr++)
1813         *retPtr=val;
1814     }
1815   ret->copyStringInfoFrom(*this);
1816   return ret.retn();
1817 }
1818
1819 /*!
1820  * This methods returns the minimal distance between the two set of points \a this and \a other.
1821  * So \a this and \a other have to have the same number of components. If not an INTERP_KERNEL::Exception will be thrown.
1822  * This method works only if number of components of \a this (equal to those of \a other) is in 1, 2 or 3.
1823  *
1824  * \param [out] thisTupleId the tuple id in \a this corresponding to the returned minimal distance
1825  * \param [out] otherTupleId the tuple id in \a other corresponding to the returned minimal distance
1826  * \return the minimal distance between the two set of points \a this and \a other.
1827  * \sa DataArrayDouble::findClosestTupleId
1828  */
1829 double DataArrayDouble::minimalDistanceTo(const DataArrayDouble *other, int& thisTupleId, int& otherTupleId) const throw(INTERP_KERNEL::Exception)
1830 {
1831   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> part1=findClosestTupleId(other);
1832   int nbOfCompo(getNumberOfComponents());
1833   int otherNbTuples(other->getNumberOfTuples());
1834   const double *thisPt(begin()),*otherPt(other->begin());
1835   const int *part1Pt(part1->begin());
1836   double ret=std::numeric_limits<double>::max();
1837   for(int i=0;i<otherNbTuples;i++,part1Pt++,otherPt+=nbOfCompo)
1838     {
1839       double tmp(0.);
1840       for(int j=0;j<nbOfCompo;j++)
1841         tmp+=(otherPt[j]-thisPt[nbOfCompo*(*part1Pt)+j])*(otherPt[j]-thisPt[nbOfCompo*(*part1Pt)+j]);
1842       if(tmp<ret)
1843         { ret=tmp; thisTupleId=*part1Pt; otherTupleId=i; }
1844     }
1845   return sqrt(ret);
1846 }
1847
1848 /*!
1849  * This methods returns for each tuple in \a other which tuple in \a this is the closest.
1850  * So \a this and \a other have to have the same number of components. If not an INTERP_KERNEL::Exception will be thrown.
1851  * This method works only if number of components of \a this (equal to those of \a other) is in 1, 2 or 3.
1852  *
1853  * \return a newly allocated (new object to be dealt by the caller) DataArrayInt having \c other->getNumberOfTuples() tuples and one components.
1854  * \sa DataArrayDouble::minimalDistanceTo
1855  */
1856 DataArrayInt *DataArrayDouble::findClosestTupleId(const DataArrayDouble *other) const throw(INTERP_KERNEL::Exception)
1857 {
1858   if(!other)
1859     throw INTERP_KERNEL::Exception("DataArrayDouble::findClosestTupleId : other instance is NULL !");
1860   checkAllocated(); other->checkAllocated();
1861   int nbOfCompo=getNumberOfComponents();
1862   if(nbOfCompo!=other->getNumberOfComponents())
1863     {
1864       std::ostringstream oss; oss << "DataArrayDouble::findClosestTupleId : number of components in this is " << nbOfCompo;
1865       oss << ", whereas number of components in other is " << other->getNumberOfComponents() << "! Should be equal !";
1866       throw INTERP_KERNEL::Exception(oss.str().c_str());
1867     }
1868   int nbOfTuples=other->getNumberOfTuples();
1869   int thisNbOfTuples=getNumberOfTuples();
1870   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbOfTuples,1);
1871   double bounds[6];
1872   getMinMaxPerComponent(bounds);
1873   switch(nbOfCompo)
1874     {
1875     case 3:
1876       {
1877         double xDelta(fabs(bounds[1]-bounds[0])),yDelta(fabs(bounds[3]-bounds[2])),zDelta(fabs(bounds[5]-bounds[4]));
1878         double delta=std::max(xDelta,yDelta); delta=std::max(delta,zDelta);
1879         double characSize=pow((delta*delta*delta)/((double)thisNbOfTuples),1./3.);
1880         BBTreePts<3,int> myTree(begin(),0,0,getNumberOfTuples(),characSize*1e-12);
1881         FindClosestTupleIdAlg<3>(myTree,3.*characSize*characSize,other->begin(),nbOfTuples,begin(),thisNbOfTuples,ret->getPointer());
1882         break;
1883       }
1884     case 2:
1885       {
1886         double xDelta(fabs(bounds[1]-bounds[0])),yDelta(fabs(bounds[3]-bounds[2]));
1887         double delta=std::max(xDelta,yDelta);
1888         double characSize=sqrt(delta/(double)thisNbOfTuples);
1889         BBTreePts<2,int> myTree(begin(),0,0,getNumberOfTuples(),characSize*1e-12);
1890         FindClosestTupleIdAlg<2>(myTree,2.*characSize*characSize,other->begin(),nbOfTuples,begin(),thisNbOfTuples,ret->getPointer());
1891         break;
1892       }
1893     case 1:
1894       {
1895         double characSize=fabs(bounds[1]-bounds[0])/thisNbOfTuples;
1896         BBTreePts<1,int> myTree(begin(),0,0,getNumberOfTuples(),characSize*1e-12);
1897         FindClosestTupleIdAlg<1>(myTree,1.*characSize*characSize,other->begin(),nbOfTuples,begin(),thisNbOfTuples,ret->getPointer());
1898         break;
1899       }
1900     default:
1901       throw INTERP_KERNEL::Exception("Unexpected spacedim of coords for findClosestTupleId. Must be 1, 2 or 3.");
1902     }
1903   return ret.retn();
1904 }
1905
1906 /*!
1907  * Returns a copy of \a this array by excluding coincident tuples. Each tuple is
1908  * considered as coordinates of a point in getNumberOfComponents()-dimensional
1909  * space. The distance between tuples is computed using norm2. If several tuples are
1910  * not far each from other than \a prec, only one of them remains in the result
1911  * array. The order of tuples in the result array is same as in \a this one except
1912  * that coincident tuples are excluded.
1913  *  \param [in] prec - minimal absolute distance between two tuples at which they are
1914  *              considered not coincident.
1915  *  \param [in] limitTupleId - limit tuple id. If all tuples within a group of coincident
1916  *              tuples have id strictly lower than \a limitTupleId then they are not excluded.
1917  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1918  *          is to delete using decrRef() as it is no more needed.
1919  *  \throw If \a this is not allocated.
1920  *  \throw If the number of components is not in [1,2,3].
1921  *
1922  *  \ref cpp_mcdataarraydouble_getdifferentvalues "Here is a Python example".
1923  */
1924 DataArrayDouble *DataArrayDouble::getDifferentValues(double prec, int limitTupleId) const throw(INTERP_KERNEL::Exception)
1925 {
1926   checkAllocated();
1927   DataArrayInt *c0=0,*cI0=0;
1928   findCommonTuples(prec,limitTupleId,c0,cI0);
1929   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> c(c0),cI(cI0);
1930   int newNbOfTuples=-1;
1931   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> o2n=DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2(getNumberOfTuples(),c0->begin(),cI0->begin(),cI0->end(),newNbOfTuples);
1932   return renumberAndReduce(o2n->getConstPointer(),newNbOfTuples);
1933 }
1934
1935 /*!
1936  * Copy all components in a specified order from another DataArrayDouble.
1937  * The specified components become the first ones in \a this array.
1938  * Both numerical and textual data is copied. The number of tuples in \a this and
1939  * the other array can be different.
1940  *  \param [in] a - the array to copy data from.
1941  *  \param [in] compoIds - sequence of zero based indices of components, data of which is
1942  *              to be copied.
1943  *  \throw If \a a is NULL.
1944  *  \throw If \a compoIds.size() != \a a->getNumberOfComponents().
1945  *  \throw If \a compoIds[i] < 0 or \a compoIds[i] > \a this->getNumberOfComponents().
1946  *
1947  *  \ref cpp_mcdataarraydouble_setselectedcomponents "Here is a Python example".
1948  */
1949 void DataArrayDouble::setSelectedComponents(const DataArrayDouble *a, const std::vector<int>& compoIds) throw(INTERP_KERNEL::Exception)
1950 {
1951   if(!a)
1952     throw INTERP_KERNEL::Exception("DataArrayDouble::setSelectedComponents : input DataArrayDouble is NULL !");
1953   checkAllocated();
1954   copyPartOfStringInfoFrom2(compoIds,*a);
1955   std::size_t partOfCompoSz=compoIds.size();
1956   int nbOfCompo=getNumberOfComponents();
1957   int nbOfTuples=std::min(getNumberOfTuples(),a->getNumberOfTuples());
1958   const double *ac=a->getConstPointer();
1959   double *nc=getPointer();
1960   for(int i=0;i<nbOfTuples;i++)
1961     for(std::size_t j=0;j<partOfCompoSz;j++,ac++)
1962       nc[nbOfCompo*i+compoIds[j]]=*ac;
1963 }
1964
1965 /*!
1966  * Copy all values from another DataArrayDouble into specified tuples and components
1967  * of \a this array. Textual data is not copied.
1968  * The tree parameters defining set of indices of tuples and components are similar to
1969  * the tree parameters of the Python function \c range(\c start,\c stop,\c step).
1970  *  \param [in] a - the array to copy values from.
1971  *  \param [in] bgTuples - index of the first tuple of \a this array to assign values to.
1972  *  \param [in] endTuples - index of the tuple before which the tuples to assign to
1973  *              are located.
1974  *  \param [in] stepTuples - index increment to get index of the next tuple to assign to.
1975  *  \param [in] bgComp - index of the first component of \a this array to assign values to.
1976  *  \param [in] endComp - index of the component before which the components to assign
1977  *              to are located.
1978  *  \param [in] stepComp - index increment to get index of the next component to assign to.
1979  *  \param [in] strictCompoCompare - if \a true (by default), then \a a->getNumberOfComponents() 
1980  *              must be equal to the number of columns to assign to, else an
1981  *              exception is thrown; if \a false, then it is only required that \a
1982  *              a->getNbOfElems() equals to number of values to assign to (this condition
1983  *              must be respected even if \a strictCompoCompare is \a true). The number of 
1984  *              values to assign to is given by following Python expression:
1985  *              \a nbTargetValues = 
1986  *              \c len(\c range(\a bgTuples,\a endTuples,\a stepTuples)) *
1987  *              \c len(\c range(\a bgComp,\a endComp,\a stepComp)).
1988  *  \throw If \a a is NULL.
1989  *  \throw If \a a is not allocated.
1990  *  \throw If \a this is not allocated.
1991  *  \throw If parameters specifying tuples and components to assign to do not give a
1992  *            non-empty range of increasing indices.
1993  *  \throw If \a a->getNbOfElems() != \a nbTargetValues.
1994  *  \throw If \a strictCompoCompare == \a true && \a a->getNumberOfComponents() !=
1995  *            \c len(\c range(\a bgComp,\a endComp,\a stepComp)).
1996  *
1997  *  \ref cpp_mcdataarraydouble_setpartofvalues1 "Here is a Python example".
1998  */
1999 void DataArrayDouble::setPartOfValues1(const DataArrayDouble *a, int bgTuples, int endTuples, int stepTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare) throw(INTERP_KERNEL::Exception)
2000 {
2001   if(!a)
2002     throw INTERP_KERNEL::Exception("DataArrayDouble::setPartOfValues1 : input DataArrayDouble is NULL !");
2003   const char msg[]="DataArrayDouble::setPartOfValues1";
2004   checkAllocated();
2005   a->checkAllocated();
2006   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
2007   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
2008   int nbComp=getNumberOfComponents();
2009   int nbOfTuples=getNumberOfTuples();
2010   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
2011   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
2012   bool assignTech=true;
2013   if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
2014     {
2015       if(strictCompoCompare)
2016         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
2017     }
2018   else
2019     {
2020       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
2021       assignTech=false;
2022     }
2023   const double *srcPt=a->getConstPointer();
2024   double *pt=getPointer()+bgTuples*nbComp+bgComp;
2025   if(assignTech)
2026     {
2027       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
2028         for(int j=0;j<newNbOfComp;j++,srcPt++)
2029           pt[j*stepComp]=*srcPt;
2030     }
2031   else
2032     {
2033       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
2034         {
2035           const double *srcPt2=srcPt;
2036           for(int j=0;j<newNbOfComp;j++,srcPt2++)
2037             pt[j*stepComp]=*srcPt2;
2038         }
2039     }
2040 }
2041
2042 /*!
2043  * Assign a given value to values at specified tuples and components of \a this array.
2044  * The tree parameters defining set of indices of tuples and components are similar to
2045  * the tree parameters of the Python function \c range(\c start,\c stop,\c step)..
2046  *  \param [in] a - the value to assign.
2047  *  \param [in] bgTuples - index of the first tuple of \a this array to assign to.
2048  *  \param [in] endTuples - index of the tuple before which the tuples to assign to
2049  *              are located.
2050  *  \param [in] stepTuples - index increment to get index of the next tuple to assign to.
2051  *  \param [in] bgComp - index of the first component of \a this array to assign to.
2052  *  \param [in] endComp - index of the component before which the components to assign
2053  *              to are located.
2054  *  \param [in] stepComp - index increment to get index of the next component to assign to.
2055  *  \throw If \a this is not allocated.
2056  *  \throw If parameters specifying tuples and components to assign to, do not give a
2057  *            non-empty range of increasing indices or indices are out of a valid range
2058  *            for \this array.
2059  *
2060  *  \ref cpp_mcdataarraydouble_setpartofvaluessimple1 "Here is a Python example".
2061  */
2062 void DataArrayDouble::setPartOfValuesSimple1(double a, int bgTuples, int endTuples, int stepTuples, int bgComp, int endComp, int stepComp) throw(INTERP_KERNEL::Exception)
2063 {
2064   const char msg[]="DataArrayDouble::setPartOfValuesSimple1";
2065   checkAllocated();
2066   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
2067   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
2068   int nbComp=getNumberOfComponents();
2069   int nbOfTuples=getNumberOfTuples();
2070   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
2071   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
2072   double *pt=getPointer()+bgTuples*nbComp+bgComp;
2073   for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
2074     for(int j=0;j<newNbOfComp;j++)
2075       pt[j*stepComp]=a;
2076 }
2077
2078 /*!
2079  * Copy all values from another DataArrayDouble (\a a) into specified tuples and 
2080  * components of \a this array. Textual data is not copied.
2081  * The tuples and components to assign to are defined by C arrays of indices.
2082  * There are two *modes of usage*:
2083  * - If \a a->getNbOfElems() equals to number of values to assign to, then every value
2084  *   of \a a is assigned to its own location within \a this array. 
2085  * - If \a a includes one tuple, then all values of \a a are assigned to the specified
2086  *   components of every specified tuple of \a this array. In this mode it is required
2087  *   that \a a->getNumberOfComponents() equals to the number of specified components.
2088  *
2089  *  \param [in] a - the array to copy values from.
2090  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
2091  *              assign values of \a a to.
2092  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
2093  *              pointer to a tuple index <em>(pi)</em> varies as this: 
2094  *              \a bgTuples <= \a pi < \a endTuples.
2095  *  \param [in] bgComp - pointer to an array of component indices of \a this array to
2096  *              assign values of \a a to.
2097  *  \param [in] endComp - specifies the end of the array \a bgTuples, so that
2098  *              pointer to a component index <em>(pi)</em> varies as this: 
2099  *              \a bgComp <= \a pi < \a endComp.
2100  *  \param [in] strictCompoCompare - this parameter is checked only if the
2101  *               *mode of usage* is the first; if it is \a true (default), 
2102  *               then \a a->getNumberOfComponents() must be equal 
2103  *               to the number of specified columns, else this is not required.
2104  *  \throw If \a a is NULL.
2105  *  \throw If \a a is not allocated.
2106  *  \throw If \a this is not allocated.
2107  *  \throw If any index of tuple/component given by <em>bgTuples / bgComp</em> is
2108  *         out of a valid range for \a this array.
2109  *  \throw In the first *mode of usage*, if <em>strictCompoCompare == true </em> and
2110  *         if <em> a->getNumberOfComponents() != (endComp - bgComp) </em>.
2111  *  \throw In the second *mode of usage*, if \a a->getNumberOfTuples() != 1 or
2112  *         <em> a->getNumberOfComponents() != (endComp - bgComp)</em>.
2113  *
2114  *  \ref cpp_mcdataarraydouble_setpartofvalues2 "Here is a Python example".
2115  */
2116 void DataArrayDouble::setPartOfValues2(const DataArrayDouble *a, const int *bgTuples, const int *endTuples, const int *bgComp, const int *endComp, bool strictCompoCompare) throw(INTERP_KERNEL::Exception)
2117 {
2118   if(!a)
2119     throw INTERP_KERNEL::Exception("DataArrayDouble::setPartOfValues2 : input DataArrayDouble is NULL !");
2120   const char msg[]="DataArrayDouble::setPartOfValues2";
2121   checkAllocated();
2122   a->checkAllocated();
2123   int nbComp=getNumberOfComponents();
2124   int nbOfTuples=getNumberOfTuples();
2125   for(const int *z=bgComp;z!=endComp;z++)
2126     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
2127   int newNbOfTuples=(int)std::distance(bgTuples,endTuples);
2128   int newNbOfComp=(int)std::distance(bgComp,endComp);
2129   bool assignTech=true;
2130   if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
2131     {
2132       if(strictCompoCompare)
2133         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
2134     }
2135   else
2136     {
2137       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
2138       assignTech=false;
2139     }
2140   double *pt=getPointer();
2141   const double *srcPt=a->getConstPointer();
2142   if(assignTech)
2143     {    
2144       for(const int *w=bgTuples;w!=endTuples;w++)
2145         {
2146           DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
2147           for(const int *z=bgComp;z!=endComp;z++,srcPt++)
2148             {    
2149               pt[(std::size_t)(*w)*nbComp+(*z)]=*srcPt;
2150             }
2151         }
2152     }
2153   else
2154     {
2155       for(const int *w=bgTuples;w!=endTuples;w++)
2156         {
2157           const double *srcPt2=srcPt;
2158           DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
2159           for(const int *z=bgComp;z!=endComp;z++,srcPt2++)
2160             {    
2161               pt[(std::size_t)(*w)*nbComp+(*z)]=*srcPt2;
2162             }
2163         }
2164     }
2165 }
2166
2167 /*!
2168  * Assign a given value to values at specified tuples and components of \a this array.
2169  * The tuples and components to assign to are defined by C arrays of indices.
2170  *  \param [in] a - the value to assign.
2171  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
2172  *              assign \a a to.
2173  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
2174  *              pointer to a tuple index (\a pi) varies as this: 
2175  *              \a bgTuples <= \a pi < \a endTuples.
2176  *  \param [in] bgComp - pointer to an array of component indices of \a this array to
2177  *              assign \a a to.
2178  *  \param [in] endComp - specifies the end of the array \a bgTuples, so that
2179  *              pointer to a component index (\a pi) varies as this: 
2180  *              \a bgComp <= \a pi < \a endComp.
2181  *  \throw If \a this is not allocated.
2182  *  \throw If any index of tuple/component given by <em>bgTuples / bgComp</em> is
2183  *         out of a valid range for \a this array.
2184  *
2185  *  \ref cpp_mcdataarraydouble_setpartofvaluessimple2 "Here is a Python example".
2186  */
2187 void DataArrayDouble::setPartOfValuesSimple2(double a, const int *bgTuples, const int *endTuples, const int *bgComp, const int *endComp) throw(INTERP_KERNEL::Exception)
2188 {
2189   checkAllocated();
2190   int nbComp=getNumberOfComponents();
2191   int nbOfTuples=getNumberOfTuples();
2192   for(const int *z=bgComp;z!=endComp;z++)
2193     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
2194   double *pt=getPointer();
2195   for(const int *w=bgTuples;w!=endTuples;w++)
2196     for(const int *z=bgComp;z!=endComp;z++)
2197       {
2198         DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
2199         pt[(std::size_t)(*w)*nbComp+(*z)]=a;
2200       }
2201 }
2202
2203 /*!
2204  * Copy all values from another DataArrayDouble (\a a) into specified tuples and 
2205  * components of \a this array. Textual data is not copied.
2206  * The tuples to assign to are defined by a C array of indices.
2207  * The components to assign to are defined by three values similar to parameters of
2208  * the Python function \c range(\c start,\c stop,\c step).
2209  * There are two *modes of usage*:
2210  * - If \a a->getNbOfElems() equals to number of values to assign to, then every value
2211  *   of \a a is assigned to its own location within \a this array. 
2212  * - If \a a includes one tuple, then all values of \a a are assigned to the specified
2213  *   components of every specified tuple of \a this array. In this mode it is required
2214  *   that \a a->getNumberOfComponents() equals to the number of specified components.
2215  *
2216  *  \param [in] a - the array to copy values from.
2217  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
2218  *              assign values of \a a to.
2219  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
2220  *              pointer to a tuple index <em>(pi)</em> varies as this: 
2221  *              \a bgTuples <= \a pi < \a endTuples.
2222  *  \param [in] bgComp - index of the first component of \a this array to assign to.
2223  *  \param [in] endComp - index of the component before which the components to assign
2224  *              to are located.
2225  *  \param [in] stepComp - index increment to get index of the next component to assign to.
2226  *  \param [in] strictCompoCompare - this parameter is checked only in the first
2227  *               *mode of usage*; if \a strictCompoCompare is \a true (default), 
2228  *               then \a a->getNumberOfComponents() must be equal 
2229  *               to the number of specified columns, else this is not required.
2230  *  \throw If \a a is NULL.
2231  *  \throw If \a a is not allocated.
2232  *  \throw If \a this is not allocated.
2233  *  \throw If any index of tuple given by \a bgTuples is out of a valid range for 
2234  *         \a this array.
2235  *  \throw In the first *mode of usage*, if <em>strictCompoCompare == true </em> and
2236  *         if <em> a->getNumberOfComponents()</em> is unequal to the number of components
2237  *         defined by <em>(bgComp,endComp,stepComp)</em>.
2238  *  \throw In the second *mode of usage*, if \a a->getNumberOfTuples() != 1 or
2239  *         <em> a->getNumberOfComponents()</em> is unequal to the number of components
2240  *         defined by <em>(bgComp,endComp,stepComp)</em>.
2241  *  \throw If parameters specifying components to assign to, do not give a
2242  *            non-empty range of increasing indices or indices are out of a valid range
2243  *            for \this array.
2244  *
2245  *  \ref cpp_mcdataarraydouble_setpartofvalues3 "Here is a Python example".
2246  */
2247 void DataArrayDouble::setPartOfValues3(const DataArrayDouble *a, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare) throw(INTERP_KERNEL::Exception)
2248 {
2249   if(!a)
2250     throw INTERP_KERNEL::Exception("DataArrayDouble::setPartOfValues3 : input DataArrayDouble is NULL !");
2251   const char msg[]="DataArrayDouble::setPartOfValues3";
2252   checkAllocated();
2253   a->checkAllocated();
2254   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
2255   int nbComp=getNumberOfComponents();
2256   int nbOfTuples=getNumberOfTuples();
2257   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
2258   int newNbOfTuples=(int)std::distance(bgTuples,endTuples);
2259   bool assignTech=true;
2260   if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
2261     {
2262       if(strictCompoCompare)
2263         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
2264     }
2265   else
2266     {
2267       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
2268       assignTech=false;
2269     }
2270   double *pt=getPointer()+bgComp;
2271   const double *srcPt=a->getConstPointer();
2272   if(assignTech)
2273     {
2274       for(const int *w=bgTuples;w!=endTuples;w++)
2275         for(int j=0;j<newNbOfComp;j++,srcPt++)
2276           {
2277             DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
2278             pt[(std::size_t)(*w)*nbComp+j*stepComp]=*srcPt;
2279           }
2280     }
2281   else
2282     {
2283       for(const int *w=bgTuples;w!=endTuples;w++)
2284         {
2285           const double *srcPt2=srcPt;
2286           for(int j=0;j<newNbOfComp;j++,srcPt2++)
2287             {
2288               DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
2289               pt[(std::size_t)(*w)*nbComp+j*stepComp]=*srcPt2;
2290             }
2291         }
2292     }
2293 }
2294
2295 /*!
2296  * Assign a given value to values at specified tuples and components of \a this array.
2297  * The tuples to assign to are defined by a C array of indices.
2298  * The components to assign to are defined by three values similar to parameters of
2299  * the Python function \c range(\c start,\c stop,\c step).
2300  *  \param [in] a - the value to assign.
2301  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
2302  *              assign \a a to.
2303  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
2304  *              pointer to a tuple index <em>(pi)</em> varies as this: 
2305  *              \a bgTuples <= \a pi < \a endTuples.
2306  *  \param [in] bgComp - index of the first component of \a this array to assign to.
2307  *  \param [in] endComp - index of the component before which the components to assign
2308  *              to are located.
2309  *  \param [in] stepComp - index increment to get index of the next component to assign to.
2310  *  \throw If \a this is not allocated.
2311  *  \throw If any index of tuple given by \a bgTuples is out of a valid range for 
2312  *         \a this array.
2313  *  \throw If parameters specifying components to assign to, do not give a
2314  *            non-empty range of increasing indices or indices are out of a valid range
2315  *            for \this array.
2316  *
2317  *  \ref cpp_mcdataarraydouble_setpartofvaluessimple3 "Here is a Python example".
2318  */
2319 void DataArrayDouble::setPartOfValuesSimple3(double a, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp) throw(INTERP_KERNEL::Exception)
2320 {
2321   const char msg[]="DataArrayDouble::setPartOfValuesSimple3";
2322   checkAllocated();
2323   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
2324   int nbComp=getNumberOfComponents();
2325   int nbOfTuples=getNumberOfTuples();
2326   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
2327   double *pt=getPointer()+bgComp;
2328   for(const int *w=bgTuples;w!=endTuples;w++)
2329     for(int j=0;j<newNbOfComp;j++)
2330       {
2331         DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
2332         pt[(std::size_t)(*w)*nbComp+j*stepComp]=a;
2333       }
2334 }
2335
2336 /*!
2337  * Copy all values from another DataArrayDouble into specified tuples and components
2338  * of \a this array. Textual data is not copied.
2339  * The tree parameters defining set of indices of tuples and components are similar to
2340  * the tree parameters of the Python function \c range(\c start,\c stop,\c step).
2341  *  \param [in] a - the array to copy values from.
2342  *  \param [in] bgTuples - index of the first tuple of \a this array to assign values to.
2343  *  \param [in] endTuples - index of the tuple before which the tuples to assign to
2344  *              are located.
2345  *  \param [in] stepTuples - index increment to get index of the next tuple to assign to.
2346  *  \param [in] bgComp - pointer to an array of component indices of \a this array to
2347  *              assign \a a to.
2348  *  \param [in] endComp - specifies the end of the array \a bgTuples, so that
2349  *              pointer to a component index (\a pi) varies as this: 
2350  *              \a bgComp <= \a pi < \a endComp.
2351  *  \param [in] strictCompoCompare - if \a true (by default), then \a a->getNumberOfComponents() 
2352  *              must be equal to the number of columns to assign to, else an
2353  *              exception is thrown; if \a false, then it is only required that \a
2354  *              a->getNbOfElems() equals to number of values to assign to (this condition
2355  *              must be respected even if \a strictCompoCompare is \a true). The number of 
2356  *              values to assign to is given by following Python expression:
2357  *              \a nbTargetValues = 
2358  *              \c len(\c range(\a bgTuples,\a endTuples,\a stepTuples)) *
2359  *              \c len(\c range(\a bgComp,\a endComp,\a stepComp)).
2360  *  \throw If \a a is NULL.
2361  *  \throw If \a a is not allocated.
2362  *  \throw If \a this is not allocated.
2363  *  \throw If parameters specifying tuples and components to assign to do not give a
2364  *            non-empty range of increasing indices.
2365  *  \throw If \a a->getNbOfElems() != \a nbTargetValues.
2366  *  \throw If \a strictCompoCompare == \a true && \a a->getNumberOfComponents() !=
2367  *            \c len(\c range(\a bgComp,\a endComp,\a stepComp)).
2368  *
2369  */
2370 void DataArrayDouble::setPartOfValues4(const DataArrayDouble *a, int bgTuples, int endTuples, int stepTuples, const int *bgComp, const int *endComp, bool strictCompoCompare) throw(INTERP_KERNEL::Exception)
2371 {
2372   if(!a)
2373     throw INTERP_KERNEL::Exception("DataArrayDouble::setPartOfValues4 : input DataArrayDouble is NULL !");
2374   const char msg[]="DataArrayDouble::setPartOfValues4";
2375   checkAllocated();
2376   a->checkAllocated();
2377   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
2378   int newNbOfComp=(int)std::distance(bgComp,endComp);
2379   int nbComp=getNumberOfComponents();
2380   for(const int *z=bgComp;z!=endComp;z++)
2381     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
2382   int nbOfTuples=getNumberOfTuples();
2383   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
2384   bool assignTech=true;
2385   if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
2386     {
2387       if(strictCompoCompare)
2388         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
2389     }
2390   else
2391     {
2392       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
2393       assignTech=false;
2394     }
2395   const double *srcPt=a->getConstPointer();
2396   double *pt=getPointer()+bgTuples*nbComp;
2397   if(assignTech)
2398     {
2399       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
2400         for(const int *z=bgComp;z!=endComp;z++,srcPt++)
2401           pt[*z]=*srcPt;
2402     }
2403   else
2404     {
2405       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
2406         {
2407           const double *srcPt2=srcPt;
2408           for(const int *z=bgComp;z!=endComp;z++,srcPt2++)
2409             pt[*z]=*srcPt2;
2410         }
2411     }
2412 }
2413
2414 void DataArrayDouble::setPartOfValuesSimple4(double a, int bgTuples, int endTuples, int stepTuples, const int *bgComp, const int *endComp) throw(INTERP_KERNEL::Exception)
2415 {
2416   const char msg[]="DataArrayDouble::setPartOfValuesSimple4";
2417   checkAllocated();
2418   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
2419   int nbComp=getNumberOfComponents();
2420   for(const int *z=bgComp;z!=endComp;z++)
2421     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
2422   int nbOfTuples=getNumberOfTuples();
2423   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
2424   double *pt=getPointer()+bgTuples*nbComp;
2425   for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
2426     for(const int *z=bgComp;z!=endComp;z++)
2427       pt[*z]=a;
2428 }
2429
2430 /*!
2431  * Copy some tuples from another DataArrayDouble into specified tuples
2432  * of \a this array. Textual data is not copied. Both arrays must have equal number of
2433  * components.
2434  * Both the tuples to assign and the tuples to assign to are defined by a DataArrayInt.
2435  * All components of selected tuples are copied.
2436  *  \param [in] a - the array to copy values from.
2437  *  \param [in] tuplesSelec - the array specifying both source tuples of \a a and
2438  *              target tuples of \a this. \a tuplesSelec has two components, and the
2439  *              first component specifies index of the source tuple and the second
2440  *              one specifies index of the target tuple.
2441  *  \throw If \a this is not allocated.
2442  *  \throw If \a a is NULL.
2443  *  \throw If \a a is not allocated.
2444  *  \throw If \a tuplesSelec is NULL.
2445  *  \throw If \a tuplesSelec is not allocated.
2446  *  \throw If <em>this->getNumberOfComponents() != a->getNumberOfComponents()</em>.
2447  *  \throw If \a tuplesSelec->getNumberOfComponents() != 2.
2448  *  \throw If any tuple index given by \a tuplesSelec is out of a valid range for 
2449  *         the corresponding (\a this or \a a) array.
2450  */
2451 void DataArrayDouble::setPartOfValuesAdv(const DataArrayDouble *a, const DataArrayInt *tuplesSelec) throw(INTERP_KERNEL::Exception)
2452 {
2453   if(!a || !tuplesSelec)
2454     throw INTERP_KERNEL::Exception("DataArrayDouble::setPartOfValuesAdv : input DataArrayDouble is NULL !");
2455   checkAllocated();
2456   a->checkAllocated();
2457   tuplesSelec->checkAllocated();
2458   int nbOfComp=getNumberOfComponents();
2459   if(nbOfComp!=a->getNumberOfComponents())
2460     throw INTERP_KERNEL::Exception("DataArrayDouble::setPartOfValuesAdv : This and a do not have the same number of components !");
2461   if(tuplesSelec->getNumberOfComponents()!=2)
2462     throw INTERP_KERNEL::Exception("DataArrayDouble::setPartOfValuesAdv : Expecting to have a tuple selector DataArrayInt instance with exactly 2 components !");
2463   int thisNt=getNumberOfTuples();
2464   int aNt=a->getNumberOfTuples();
2465   double *valsToSet=getPointer();
2466   const double *valsSrc=a->getConstPointer();
2467   for(const int *tuple=tuplesSelec->begin();tuple!=tuplesSelec->end();tuple+=2)
2468     {
2469       if(tuple[1]>=0 && tuple[1]<aNt)
2470         {
2471           if(tuple[0]>=0 && tuple[0]<thisNt)
2472             std::copy(valsSrc+nbOfComp*tuple[1],valsSrc+nbOfComp*(tuple[1]+1),valsToSet+nbOfComp*tuple[0]);
2473           else
2474             {
2475               std::ostringstream oss; oss << "DataArrayDouble::setPartOfValuesAdv : Tuple #" << std::distance(tuplesSelec->begin(),tuple)/2;
2476               oss << " of 'tuplesSelec' request of tuple id #" << tuple[0] << " in 'this' ! It should be in [0," << thisNt << ") !";
2477               throw INTERP_KERNEL::Exception(oss.str().c_str());
2478             }
2479         }
2480       else
2481         {
2482           std::ostringstream oss; oss << "DataArrayDouble::setPartOfValuesAdv : Tuple #" << std::distance(tuplesSelec->begin(),tuple)/2;
2483           oss << " of 'tuplesSelec' request of tuple id #" << tuple[1] << " in 'a' ! It should be in [0," << aNt << ") !";
2484           throw INTERP_KERNEL::Exception(oss.str().c_str());
2485         }
2486     }
2487 }
2488
2489 /*!
2490  * Copy some tuples from another DataArrayDouble (\a a) into contiguous tuples
2491  * of \a this array. Textual data is not copied. Both arrays must have equal number of
2492  * components.
2493  * The tuples to assign to are defined by index of the first tuple, and
2494  * their number is defined by \a tuplesSelec->getNumberOfTuples().
2495  * The tuples to copy are defined by values of a DataArrayInt.
2496  * All components of selected tuples are copied.
2497  *  \param [in] tupleIdStart - index of the first tuple of \a this array to assign
2498  *              values to.
2499  *  \param [in] a - the array to copy values from.
2500  *  \param [in] tuplesSelec - the array specifying tuples of \a a to copy.
2501  *  \throw If \a this is not allocated.
2502  *  \throw If \a a is NULL.
2503  *  \throw If \a a is not allocated.
2504  *  \throw If \a tuplesSelec is NULL.
2505  *  \throw If \a tuplesSelec is not allocated.
2506  *  \throw If <em>this->getNumberOfComponents() != a->getNumberOfComponents()</em>.
2507  *  \throw If \a tuplesSelec->getNumberOfComponents() != 1.
2508  *  \throw If <em>tupleIdStart + tuplesSelec->getNumberOfTuples() > this->getNumberOfTuples().</em>
2509  *  \throw If any tuple index given by \a tuplesSelec is out of a valid range for 
2510  *         \a a array.
2511  */
2512 void DataArrayDouble::setContigPartOfSelectedValues(int tupleIdStart, const DataArrayDouble *a, const DataArrayInt *tuplesSelec) throw(INTERP_KERNEL::Exception)
2513 {
2514   if(!a || !tuplesSelec)
2515     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues : input DataArray is NULL !");
2516   checkAllocated();
2517   a->checkAllocated();
2518   tuplesSelec->checkAllocated();
2519   int nbOfComp=getNumberOfComponents();
2520   if(nbOfComp!=a->getNumberOfComponents())
2521     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues : This and a do not have the same number of components !");
2522   if(tuplesSelec->getNumberOfComponents()!=1)
2523     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues : Expecting to have a tuple selector DataArrayInt instance with exactly 1 component !");
2524   int thisNt=getNumberOfTuples();
2525   int aNt=a->getNumberOfTuples();
2526   int nbOfTupleToWrite=tuplesSelec->getNumberOfTuples();
2527   double *valsToSet=getPointer()+tupleIdStart*nbOfComp;
2528   if(tupleIdStart+nbOfTupleToWrite>thisNt)
2529     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues : invalid number range of values to write !");
2530   const double *valsSrc=a->getConstPointer();
2531   for(const int *tuple=tuplesSelec->begin();tuple!=tuplesSelec->end();tuple++,valsToSet+=nbOfComp)
2532     {
2533       if(*tuple>=0 && *tuple<aNt)
2534         {
2535           std::copy(valsSrc+nbOfComp*(*tuple),valsSrc+nbOfComp*(*tuple+1),valsToSet);
2536         }
2537       else
2538         {
2539           std::ostringstream oss; oss << "DataArrayDouble::setContigPartOfSelectedValues : Tuple #" << std::distance(tuplesSelec->begin(),tuple);
2540           oss << " of 'tuplesSelec' request of tuple id #" << *tuple << " in 'a' ! It should be in [0," << aNt << ") !";
2541           throw INTERP_KERNEL::Exception(oss.str().c_str());
2542         }
2543     }
2544 }
2545
2546 /*!
2547  * Copy some tuples from another DataArrayDouble (\a a) into contiguous tuples
2548  * of \a this array. Textual data is not copied. Both arrays must have equal number of
2549  * components.
2550  * The tuples to copy are defined by three values similar to parameters of
2551  * the Python function \c range(\c start,\c stop,\c step).
2552  * The tuples to assign to are defined by index of the first tuple, and
2553  * their number is defined by number of tuples to copy.
2554  * All components of selected tuples are copied.
2555  *  \param [in] tupleIdStart - index of the first tuple of \a this array to assign
2556  *              values to.
2557  *  \param [in] a - the array to copy values from.
2558  *  \param [in] bg - index of the first tuple to copy of the array \a a.
2559  *  \param [in] end2 - index of the tuple of \a a before which the tuples to copy
2560  *              are located.
2561  *  \param [in] step - index increment to get index of the next tuple to copy.
2562  *  \throw If \a this is not allocated.
2563  *  \throw If \a a is NULL.
2564  *  \throw If \a a is not allocated.
2565  *  \throw If <em>this->getNumberOfComponents() != a->getNumberOfComponents()</em>.
2566  *  \throw If <em>tupleIdStart + len(range(bg,end2,step)) > this->getNumberOfTuples().</em>
2567  *  \throw If parameters specifying tuples to copy, do not give a
2568  *            non-empty range of increasing indices or indices are out of a valid range
2569  *            for the array \a a.
2570  */
2571 void DataArrayDouble::setContigPartOfSelectedValues2(int tupleIdStart, const DataArrayDouble *a, int bg, int end2, int step) throw(INTERP_KERNEL::Exception)
2572 {
2573   if(!a)
2574     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues2 : input DataArrayDouble is NULL !");
2575   checkAllocated();
2576   a->checkAllocated();
2577   int nbOfComp=getNumberOfComponents();
2578   const char msg[]="DataArrayDouble::setContigPartOfSelectedValues2";
2579   int nbOfTupleToWrite=DataArray::GetNumberOfItemGivenBES(bg,end2,step,msg);
2580   if(nbOfComp!=a->getNumberOfComponents())
2581     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues2 : This and a do not have the same number of components !");
2582   int thisNt=getNumberOfTuples();
2583   int aNt=a->getNumberOfTuples();
2584   double *valsToSet=getPointer()+tupleIdStart*nbOfComp;
2585   if(tupleIdStart+nbOfTupleToWrite>thisNt)
2586     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues2 : invalid number range of values to write !");
2587   if(end2>aNt)
2588     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues2 : invalid range of values to read !");
2589   const double *valsSrc=a->getConstPointer()+bg*nbOfComp;
2590   for(int i=0;i<nbOfTupleToWrite;i++,valsToSet+=nbOfComp,valsSrc+=step*nbOfComp)
2591     {
2592       std::copy(valsSrc,valsSrc+nbOfComp,valsToSet);
2593     }
2594 }
2595
2596 /*!
2597  * Returns a value located at specified tuple and component.
2598  * This method is equivalent to DataArrayDouble::getIJ() except that validity of
2599  * parameters is checked. So this method is safe but expensive if used to go through
2600  * all values of \a this.
2601  *  \param [in] tupleId - index of tuple of interest.
2602  *  \param [in] compoId - index of component of interest.
2603  *  \return double - value located by \a tupleId and \a compoId.
2604  *  \throw If \a this is not allocated.
2605  *  \throw If condition <em>( 0 <= tupleId < this->getNumberOfTuples() )</em> is violated.
2606  *  \throw If condition <em>( 0 <= compoId < this->getNumberOfComponents() )</em> is violated.
2607  */
2608 double DataArrayDouble::getIJSafe(int tupleId, int compoId) const throw(INTERP_KERNEL::Exception)
2609 {
2610   checkAllocated();
2611   if(tupleId<0 || tupleId>=getNumberOfTuples())
2612     {
2613       std::ostringstream oss; oss << "DataArrayDouble::getIJSafe : request for tupleId " << tupleId << " should be in [0," << getNumberOfTuples() << ") !";
2614       throw INTERP_KERNEL::Exception(oss.str().c_str());
2615     }
2616   if(compoId<0 || compoId>=getNumberOfComponents())
2617     {
2618       std::ostringstream oss; oss << "DataArrayDouble::getIJSafe : request for compoId " << compoId << " should be in [0," << getNumberOfComponents() << ") !";
2619       throw INTERP_KERNEL::Exception(oss.str().c_str());
2620     }
2621   return _mem[tupleId*_info_on_compo.size()+compoId];
2622 }
2623
2624 /*!
2625  * Returns the last value of \a this. 
2626  *  \return double - the last value of \a this array.
2627  *  \throw If \a this is not allocated.
2628  *  \throw If \a this->getNumberOfComponents() != 1.
2629  *  \throw If \a this->getNumberOfTuples() < 1.
2630  */
2631 double DataArrayDouble::back() const throw(INTERP_KERNEL::Exception)
2632 {
2633   checkAllocated();
2634   if(getNumberOfComponents()!=1)
2635     throw INTERP_KERNEL::Exception("DataArrayDouble::back : number of components not equal to one !");
2636   int nbOfTuples=getNumberOfTuples();
2637   if(nbOfTuples<1)
2638     throw INTERP_KERNEL::Exception("DataArrayDouble::back : number of tuples must be >= 1 !");
2639   return *(getConstPointer()+nbOfTuples-1);
2640 }
2641
2642 void DataArrayDouble::SetArrayIn(DataArrayDouble *newArray, DataArrayDouble* &arrayToSet)
2643 {
2644   if(newArray!=arrayToSet)
2645     {
2646       if(arrayToSet)
2647         arrayToSet->decrRef();
2648       arrayToSet=newArray;
2649       if(arrayToSet)
2650         arrayToSet->incrRef();
2651     }
2652 }
2653
2654 /*!
2655  * Sets a C array to be used as raw data of \a this. The previously set info
2656  *  of components is retained and re-sized. 
2657  * For more info see \ref MEDCouplingArraySteps1.
2658  *  \param [in] array - the C array to be used as raw data of \a this.
2659  *  \param [in] ownership - if \a true, \a array will be deallocated at destruction of \a this.
2660  *  \param [in] type - specifies how to deallocate \a array. If \a type == ParaMEDMEM::CPP_DEALLOC,
2661  *                     \c delete [] \c array; will be called. If \a type == ParaMEDMEM::C_DEALLOC,
2662  *                     \c free(\c array ) will be called.
2663  *  \param [in] nbOfTuple - new number of tuples in \a this.
2664  *  \param [in] nbOfCompo - new number of components in \a this.
2665  */
2666 void DataArrayDouble::useArray(const double *array, bool ownership, DeallocType type, int nbOfTuple, int nbOfCompo) throw(INTERP_KERNEL::Exception)
2667 {
2668   _info_on_compo.resize(nbOfCompo);
2669   _mem.useArray(array,ownership,type,(std::size_t)nbOfTuple*nbOfCompo);
2670   declareAsNew();
2671 }
2672
2673 void DataArrayDouble::useExternalArrayWithRWAccess(const double *array, int nbOfTuple, int nbOfCompo) throw(INTERP_KERNEL::Exception)
2674 {
2675   _info_on_compo.resize(nbOfCompo);
2676   _mem.useExternalArrayWithRWAccess(array,(std::size_t)nbOfTuple*nbOfCompo);
2677   declareAsNew();
2678 }
2679
2680 /*!
2681  * Checks if 0.0 value is present in \a this array. If it is the case, an exception
2682  * is thrown.
2683  * \throw If zero is found in \a this array.
2684  */
2685 void DataArrayDouble::checkNoNullValues() const throw(INTERP_KERNEL::Exception)
2686 {
2687   const double *tmp=getConstPointer();
2688   std::size_t nbOfElems=getNbOfElems();
2689   const double *where=std::find(tmp,tmp+nbOfElems,0.);
2690   if(where!=tmp+nbOfElems)
2691     throw INTERP_KERNEL::Exception("A value 0.0 have been detected !");
2692 }
2693
2694 /*!
2695  * Computes minimal and maximal value in each component. An output array is filled
2696  * with \c 2 * \a this->getNumberOfComponents() values, so the caller is to allocate
2697  * enough memory before calling this method.
2698  *  \param [out] bounds - array of size at least 2 *\a this->getNumberOfComponents().
2699  *               It is filled as follows:<br>
2700  *               \a bounds[0] = \c min_of_component_0 <br>
2701  *               \a bounds[1] = \c max_of_component_0 <br>
2702  *               \a bounds[2] = \c min_of_component_1 <br>
2703  *               \a bounds[3] = \c max_of_component_1 <br>
2704  *               ...
2705  */
2706 void DataArrayDouble::getMinMaxPerComponent(double *bounds) const throw(INTERP_KERNEL::Exception)
2707 {
2708   checkAllocated();
2709   int dim=getNumberOfComponents();
2710   for (int idim=0; idim<dim; idim++)
2711     {
2712       bounds[idim*2]=std::numeric_limits<double>::max();
2713       bounds[idim*2+1]=-std::numeric_limits<double>::max();
2714     } 
2715   const double *ptr=getConstPointer();
2716   int nbOfTuples=getNumberOfTuples();
2717   for(int i=0;i<nbOfTuples;i++)
2718     {
2719       for(int idim=0;idim<dim;idim++)
2720         {
2721           if(bounds[idim*2]>ptr[i*dim+idim])
2722             {
2723               bounds[idim*2]=ptr[i*dim+idim];
2724             }
2725           if(bounds[idim*2+1]<ptr[i*dim+idim])
2726             {
2727               bounds[idim*2+1]=ptr[i*dim+idim];
2728             }
2729         }
2730     }
2731 }
2732
2733 /*!
2734  * This method retrieves a newly allocated DataArrayDouble instance having same number of tuples than \a this and twice number of components than \a this
2735  * to store both the min and max per component of each tuples. 
2736  * \param [in] epsilon the width of the bbox (identical in each direction) - 0.0 by default
2737  *
2738  * \return a newly created DataArrayDouble instance having \c this->getNumberOfTuples() tuples and 2 * \c this->getNumberOfComponent() components
2739  *
2740  * \throw If \a this is not allocated yet.
2741  */
2742 DataArrayDouble *DataArrayDouble::computeBBoxPerTuple(double epsilon)const throw(INTERP_KERNEL::Exception)
2743 {
2744   checkAllocated();
2745   const double *dataPtr=getConstPointer();
2746   int nbOfCompo=getNumberOfComponents();
2747   int nbTuples=getNumberOfTuples();
2748   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> bbox=DataArrayDouble::New();
2749   bbox->alloc(nbTuples,2*nbOfCompo);
2750   double *bboxPtr=bbox->getPointer();
2751   for(int i=0;i<nbTuples;i++)
2752     {
2753       for(int j=0;j<nbOfCompo;j++)
2754         {
2755           bboxPtr[2*nbOfCompo*i+2*j]=dataPtr[nbOfCompo*i+j]-epsilon;
2756           bboxPtr[2*nbOfCompo*i+2*j+1]=dataPtr[nbOfCompo*i+j]+epsilon;
2757         }
2758     }
2759   return bbox.retn();
2760 }
2761
2762 /*!
2763  * For each tuples **t** in \a other, this method retrieves tuples in \a this that are equal to **t**.
2764  * Two tuples are considered equal if the euclidian distance between the two tuples is lower than \a eps.
2765  * 
2766  * \param [in] other a DataArrayDouble having same number of components than \a this.
2767  * \param [in] eps absolute precision representing distance (using infinite norm) between 2 tuples behind which 2 tuples are considered equal.
2768  * \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.
2769  *             \a cI allows to extract information in \a c.
2770  * \param [out] cI is an indirection array that allows to extract the data contained in \a c.
2771  *
2772  * \throw In case of:
2773  *  - \a this is not allocated
2774  *  - \a other is not allocated or null
2775  *  - \a this and \a other do not have the same number of components
2776  *  - if number of components of \a this is not in [1,2,3]
2777  *
2778  * \sa MEDCouplingPointSet::getNodeIdsNearPoints, DataArrayDouble::getDifferentValues
2779  */
2780 void DataArrayDouble::computeTupleIdsNearTuples(const DataArrayDouble *other, double eps, DataArrayInt *& c, DataArrayInt *& cI) const throw(INTERP_KERNEL::Exception)
2781 {
2782   if(!other)
2783     throw INTERP_KERNEL::Exception("DataArrayDouble::computeTupleIdsNearTuples : input pointer other is null !");
2784   checkAllocated();
2785   other->checkAllocated();
2786   int nbOfCompo=getNumberOfComponents();
2787   int otherNbOfCompo=other->getNumberOfComponents();
2788   if(nbOfCompo!=otherNbOfCompo)
2789     throw INTERP_KERNEL::Exception("DataArrayDouble::computeTupleIdsNearTuples : number of components should be equal between this and other !");
2790   int nbOfTuplesOther=other->getNumberOfTuples();
2791   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cArr(DataArrayInt::New()),cIArr(DataArrayInt::New()); cArr->alloc(0,1); cIArr->pushBackSilent(0);
2792   switch(nbOfCompo)
2793     {
2794     case 3:
2795       {
2796         BBTreePts<3,int> myTree(begin(),0,0,getNumberOfTuples(),eps);
2797         FindTupleIdsNearTuplesAlg<3>(myTree,other->getConstPointer(),nbOfTuplesOther,eps,cArr,cIArr);
2798         break;
2799       }
2800     case 2:
2801       {
2802         BBTreePts<2,int> myTree(begin(),0,0,getNumberOfTuples(),eps);
2803         FindTupleIdsNearTuplesAlg<2>(myTree,other->getConstPointer(),nbOfTuplesOther,eps,cArr,cIArr);
2804         break;
2805       }
2806     case 1:
2807       {
2808         BBTreePts<1,int> myTree(begin(),0,0,getNumberOfTuples(),eps);
2809         FindTupleIdsNearTuplesAlg<1>(myTree,other->getConstPointer(),nbOfTuplesOther,eps,cArr,cIArr);
2810         break;
2811       }
2812     default:
2813       throw INTERP_KERNEL::Exception("Unexpected spacedim of coords for computeTupleIdsNearTuples. Must be 1, 2 or 3.");
2814     }
2815   c=cArr.retn(); cI=cIArr.retn();
2816 }
2817
2818 /*!
2819  * 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
2820  * around origin of 'radius' 1.
2821  * 
2822  * \param [in] eps absolute epsilon. under that value of delta between max and min no scale is performed.
2823  */
2824 void DataArrayDouble::recenterForMaxPrecision(double eps) throw(INTERP_KERNEL::Exception)
2825 {
2826   checkAllocated();
2827   int dim=getNumberOfComponents();
2828   std::vector<double> bounds(2*dim);
2829   getMinMaxPerComponent(&bounds[0]);
2830   for(int i=0;i<dim;i++)
2831     {
2832       double delta=bounds[2*i+1]-bounds[2*i];
2833       double offset=(bounds[2*i]+bounds[2*i+1])/2.;
2834       if(delta>eps)
2835         applyLin(1./delta,-offset/delta,i);
2836       else
2837         applyLin(1.,-offset,i);
2838     }
2839 }
2840
2841 /*!
2842  * Returns the maximal value and its location within \a this one-dimensional array.
2843  *  \param [out] tupleId - index of the tuple holding the maximal value.
2844  *  \return double - the maximal value among all values of \a this array.
2845  *  \throw If \a this->getNumberOfComponents() != 1
2846  *  \throw If \a this->getNumberOfTuples() < 1
2847  */
2848 double DataArrayDouble::getMaxValue(int& tupleId) const throw(INTERP_KERNEL::Exception)
2849 {
2850   checkAllocated();
2851   if(getNumberOfComponents()!=1)
2852     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 !");
2853   int nbOfTuples=getNumberOfTuples();
2854   if(nbOfTuples<=0)
2855     throw INTERP_KERNEL::Exception("DataArrayDouble::getMaxValue : array exists but number of tuples must be > 0 !");
2856   const double *vals=getConstPointer();
2857   const double *loc=std::max_element(vals,vals+nbOfTuples);
2858   tupleId=(int)std::distance(vals,loc);
2859   return *loc;
2860 }
2861
2862 /*!
2863  * Returns the maximal value within \a this array that is allowed to have more than
2864  *  one component.
2865  *  \return double - the maximal value among all values of \a this array.
2866  *  \throw If \a this is not allocated.
2867  */
2868 double DataArrayDouble::getMaxValueInArray() const throw(INTERP_KERNEL::Exception)
2869 {
2870   checkAllocated();
2871   const double *loc=std::max_element(begin(),end());
2872   return *loc;
2873 }
2874
2875 /*!
2876  * Returns the maximal value and all its locations within \a this one-dimensional array.
2877  *  \param [out] tupleIds - a new instance of DataArrayInt containg indices of
2878  *               tuples holding the maximal value. The caller is to delete it using
2879  *               decrRef() as it is no more needed.
2880  *  \return double - the maximal value among all values of \a this array.
2881  *  \throw If \a this->getNumberOfComponents() != 1
2882  *  \throw If \a this->getNumberOfTuples() < 1
2883  */
2884 double DataArrayDouble::getMaxValue2(DataArrayInt*& tupleIds) const throw(INTERP_KERNEL::Exception)
2885 {
2886   int tmp;
2887   tupleIds=0;
2888   double ret=getMaxValue(tmp);
2889   tupleIds=getIdsInRange(ret,ret);
2890   return ret;
2891 }
2892
2893 /*!
2894  * Returns the minimal value and its location within \a this one-dimensional array.
2895  *  \param [out] tupleId - index of the tuple holding the minimal value.
2896  *  \return double - the minimal value among all values of \a this array.
2897  *  \throw If \a this->getNumberOfComponents() != 1
2898  *  \throw If \a this->getNumberOfTuples() < 1
2899  */
2900 double DataArrayDouble::getMinValue(int& tupleId) const throw(INTERP_KERNEL::Exception)
2901 {
2902   checkAllocated();
2903   if(getNumberOfComponents()!=1)
2904     throw INTERP_KERNEL::Exception("DataArrayDouble::getMinValue : must be applied on DataArrayDouble with only one component, you can call 'rearrange' method before call 'getMinValueInArray' method !");
2905   int nbOfTuples=getNumberOfTuples();
2906   if(nbOfTuples<=0)
2907     throw INTERP_KERNEL::Exception("DataArrayDouble::getMinValue : array exists but number of tuples must be > 0 !");
2908   const double *vals=getConstPointer();
2909   const double *loc=std::min_element(vals,vals+nbOfTuples);
2910   tupleId=(int)std::distance(vals,loc);
2911   return *loc;
2912 }
2913
2914 /*!
2915  * Returns the minimal value within \a this array that is allowed to have more than
2916  *  one component.
2917  *  \return double - the minimal value among all values of \a this array.
2918  *  \throw If \a this is not allocated.
2919  */
2920 double DataArrayDouble::getMinValueInArray() const throw(INTERP_KERNEL::Exception)
2921 {
2922   checkAllocated();
2923   const double *loc=std::min_element(begin(),end());
2924   return *loc;
2925 }
2926
2927 /*!
2928  * Returns the minimal value and all its locations within \a this one-dimensional array.
2929  *  \param [out] tupleIds - a new instance of DataArrayInt containg indices of
2930  *               tuples holding the minimal value. The caller is to delete it using
2931  *               decrRef() as it is no more needed.
2932  *  \return double - the minimal value among all values of \a this array.
2933  *  \throw If \a this->getNumberOfComponents() != 1
2934  *  \throw If \a this->getNumberOfTuples() < 1
2935  */
2936 double DataArrayDouble::getMinValue2(DataArrayInt*& tupleIds) const throw(INTERP_KERNEL::Exception)
2937 {
2938   int tmp;
2939   tupleIds=0;
2940   double ret=getMinValue(tmp);
2941   tupleIds=getIdsInRange(ret,ret);
2942   return ret;
2943 }
2944
2945 /*!
2946  * Returns the average value of \a this one-dimensional array.
2947  *  \return double - the average value over all values of \a this array.
2948  *  \throw If \a this->getNumberOfComponents() != 1
2949  *  \throw If \a this->getNumberOfTuples() < 1
2950  */
2951 double DataArrayDouble::getAverageValue() const throw(INTERP_KERNEL::Exception)
2952 {
2953   if(getNumberOfComponents()!=1)
2954     throw INTERP_KERNEL::Exception("DataArrayDouble::getAverageValue : must be applied on DataArrayDouble with only one component, you can call 'rearrange' method before !");
2955   int nbOfTuples=getNumberOfTuples();
2956   if(nbOfTuples<=0)
2957     throw INTERP_KERNEL::Exception("DataArrayDouble::getAverageValue : array exists but number of tuples must be > 0 !");
2958   const double *vals=getConstPointer();
2959   double ret=std::accumulate(vals,vals+nbOfTuples,0.);
2960   return ret/nbOfTuples;
2961 }
2962
2963 /*!
2964  * Returns the Euclidean norm of the vector defined by \a this array.
2965  *  \return double - the value of the Euclidean norm, i.e.
2966  *          the square root of the inner product of vector.
2967  *  \throw If \a this is not allocated.
2968  */
2969 double DataArrayDouble::norm2() const throw(INTERP_KERNEL::Exception)
2970 {
2971   checkAllocated();
2972   double ret=0.;
2973   std::size_t nbOfElems=getNbOfElems();
2974   const double *pt=getConstPointer();
2975   for(std::size_t i=0;i<nbOfElems;i++,pt++)
2976     ret+=(*pt)*(*pt);
2977   return sqrt(ret);
2978 }
2979
2980 /*!
2981  * Returns the maximum norm of the vector defined by \a this array.
2982  *  \return double - the value of the maximum norm, i.e.
2983  *          the maximal absolute value among values of \a this array.
2984  *  \throw If \a this is not allocated.
2985  */
2986 double DataArrayDouble::normMax() const throw(INTERP_KERNEL::Exception)
2987 {
2988   checkAllocated();
2989   double ret=-1.;
2990   std::size_t nbOfElems=getNbOfElems();
2991   const double *pt=getConstPointer();
2992   for(std::size_t i=0;i<nbOfElems;i++,pt++)
2993     {
2994       double val=std::abs(*pt);
2995       if(val>ret)
2996         ret=val;
2997     }
2998   return ret;
2999 }
3000
3001 /*!
3002  * Accumulates values of each component of \a this array.
3003  *  \param [out] res - an array of length \a this->getNumberOfComponents(), allocated 
3004  *         by the caller, that is filled by this method with sum value for each
3005  *         component.
3006  *  \throw If \a this is not allocated.
3007  */
3008 void DataArrayDouble::accumulate(double *res) const throw(INTERP_KERNEL::Exception)
3009 {
3010   checkAllocated();
3011   const double *ptr=getConstPointer();
3012   int nbTuple=getNumberOfTuples();
3013   int nbComps=getNumberOfComponents();
3014   std::fill(res,res+nbComps,0.);
3015   for(int i=0;i<nbTuple;i++)
3016     std::transform(ptr+i*nbComps,ptr+(i+1)*nbComps,res,res,std::plus<double>());
3017 }
3018
3019 /*!
3020  * This method returns the min distance from an external tuple defined by [ \a tupleBg , \a tupleEnd ) to \a this and
3021  * the first tuple in \a this that matches the returned distance. If there is no tuples in \a this an exception will be thrown.
3022  *
3023  *
3024  * \a this is expected to be allocated and expected to have a number of components equal to the distance from \a tupleBg to
3025  * \a tupleEnd. If not an exception will be thrown.
3026  *
3027  * \param [in] tupleBg start pointer (included) of input external tuple
3028  * \param [in] tupleEnd end pointer (not included) of input external tuple
3029  * \param [out] tupleId the tuple id in \a this that matches the min of distance between \a this and input external tuple
3030  * \return the min distance.
3031  * \sa MEDCouplingUMesh::distanceToPoint
3032  */
3033 double DataArrayDouble::distanceToTuple(const double *tupleBg, const double *tupleEnd, int& tupleId) const throw(INTERP_KERNEL::Exception)
3034 {
3035   checkAllocated();
3036   int nbTuple=getNumberOfTuples();
3037   int nbComps=getNumberOfComponents();
3038   if(nbComps!=(int)std::distance(tupleBg,tupleEnd))
3039     { 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()); }
3040   if(nbTuple==0)
3041     throw INTERP_KERNEL::Exception("DataArrayDouble::distanceToTuple : no tuple in this ! No distance to compute !");
3042   double ret0=std::numeric_limits<double>::max();
3043   tupleId=-1;
3044   const double *work=getConstPointer();
3045   for(int i=0;i<nbTuple;i++)
3046     {
3047       double val=0.;
3048       for(int j=0;j<nbComps;j++,work++) 
3049         val+=(*work-tupleBg[j])*((*work-tupleBg[j]));
3050       if(val>=ret0)
3051         continue;
3052       else
3053         { ret0=val; tupleId=i; }
3054     }
3055   return sqrt(ret0);
3056 }
3057
3058 /*!
3059  * Accumulate values of the given component of \a this array.
3060  *  \param [in] compId - the index of the component of interest.
3061  *  \return double - a sum value of \a compId-th component.
3062  *  \throw If \a this is not allocated.
3063  *  \throw If \a the condition ( 0 <= \a compId < \a this->getNumberOfComponents() ) is
3064  *         not respected.
3065  */
3066 double DataArrayDouble::accumulate(int compId) const throw(INTERP_KERNEL::Exception)
3067 {
3068   checkAllocated();
3069   const double *ptr=getConstPointer();
3070   int nbTuple=getNumberOfTuples();
3071   int nbComps=getNumberOfComponents();
3072   if(compId<0 || compId>=nbComps)
3073     throw INTERP_KERNEL::Exception("DataArrayDouble::accumulate : Invalid compId specified : No such nb of components !");
3074   double ret=0.;
3075   for(int i=0;i<nbTuple;i++)
3076     ret+=ptr[i*nbComps+compId];
3077   return ret;
3078 }
3079
3080 /*!
3081  * Converts each 2D point defined by the tuple of \a this array from the Polar to the
3082  * Cartesian coordinate system. The two components of the tuple of \a this array are 
3083  * considered to contain (1) radius and (2) angle of the point in the Polar CS.
3084  *  \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
3085  *          contains X and Y coordinates of the point in the Cartesian CS. The caller
3086  *          is to delete this array using decrRef() as it is no more needed. The array
3087  *          does not contain any textual info on components.
3088  *  \throw If \a this->getNumberOfComponents() != 2.
3089  */
3090 DataArrayDouble *DataArrayDouble::fromPolarToCart() const throw(INTERP_KERNEL::Exception)
3091 {
3092   checkAllocated();
3093   int nbOfComp=getNumberOfComponents();
3094   if(nbOfComp!=2)
3095     throw INTERP_KERNEL::Exception("DataArrayDouble::fromPolarToCart : must be an array with exactly 2 components !");
3096   int nbOfTuple=getNumberOfTuples();
3097   DataArrayDouble *ret=DataArrayDouble::New();
3098   ret->alloc(nbOfTuple,2);
3099   double *w=ret->getPointer();
3100   const double *wIn=getConstPointer();
3101   for(int i=0;i<nbOfTuple;i++,w+=2,wIn+=2)
3102     {
3103       w[0]=wIn[0]*cos(wIn[1]);
3104       w[1]=wIn[0]*sin(wIn[1]);
3105     }
3106   return ret;
3107 }
3108
3109 /*!
3110  * Converts each 3D point defined by the tuple of \a this array from the Cylindrical to
3111  * the Cartesian coordinate system. The three components of the tuple of \a this array 
3112  * are considered to contain (1) radius, (2) azimuth and (3) altitude of the point in
3113  * the Cylindrical CS.
3114  *  \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
3115  *          contains X, Y and Z coordinates of the point in the Cartesian CS. The info
3116  *          on the third component is copied from \a this array. The caller
3117  *          is to delete this array using decrRef() as it is no more needed. 
3118  *  \throw If \a this->getNumberOfComponents() != 3.
3119  */
3120 DataArrayDouble *DataArrayDouble::fromCylToCart() const throw(INTERP_KERNEL::Exception)
3121 {
3122   checkAllocated();
3123   int nbOfComp=getNumberOfComponents();
3124   if(nbOfComp!=3)
3125     throw INTERP_KERNEL::Exception("DataArrayDouble::fromCylToCart : must be an array with exactly 3 components !");
3126   int nbOfTuple=getNumberOfTuples();
3127   DataArrayDouble *ret=DataArrayDouble::New();
3128   ret->alloc(getNumberOfTuples(),3);
3129   double *w=ret->getPointer();
3130   const double *wIn=getConstPointer();
3131   for(int i=0;i<nbOfTuple;i++,w+=3,wIn+=3)
3132     {
3133       w[0]=wIn[0]*cos(wIn[1]);
3134       w[1]=wIn[0]*sin(wIn[1]);
3135       w[2]=wIn[2];
3136     }
3137   ret->setInfoOnComponent(2,getInfoOnComponent(2).c_str());
3138   return ret;
3139 }
3140
3141 /*!
3142  * Converts each 3D point defined by the tuple of \a this array from the Spherical to
3143  * the Cartesian coordinate system. The three components of the tuple of \a this array 
3144  * are considered to contain (1) radius, (2) polar angle and (3) azimuthal angle of the
3145  * point in the Cylindrical CS.
3146  *  \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
3147  *          contains X, Y and Z coordinates of the point in the Cartesian CS. The info
3148  *          on the third component is copied from \a this array. The caller
3149  *          is to delete this array using decrRef() as it is no more needed.
3150  *  \throw If \a this->getNumberOfComponents() != 3.
3151  */
3152 DataArrayDouble *DataArrayDouble::fromSpherToCart() const throw(INTERP_KERNEL::Exception)
3153 {
3154   checkAllocated();
3155   int nbOfComp=getNumberOfComponents();
3156   if(nbOfComp!=3)
3157     throw INTERP_KERNEL::Exception("DataArrayDouble::fromSpherToCart : must be an array with exactly 3 components !");
3158   int nbOfTuple=getNumberOfTuples();
3159   DataArrayDouble *ret=DataArrayDouble::New();
3160   ret->alloc(getNumberOfTuples(),3);
3161   double *w=ret->getPointer();
3162   const double *wIn=getConstPointer();
3163   for(int i=0;i<nbOfTuple;i++,w+=3,wIn+=3)
3164     {
3165       w[0]=wIn[0]*cos(wIn[2])*sin(wIn[1]);
3166       w[1]=wIn[0]*sin(wIn[2])*sin(wIn[1]);
3167       w[2]=wIn[0]*cos(wIn[1]);
3168     }
3169   return ret;
3170 }
3171
3172 /*!
3173  * Computes the doubly contracted product of every tensor defined by the tuple of \a this
3174  * array contating 6 components.
3175  *  \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
3176  *          is calculated from the tuple <em>(t)</em> of \a this array as follows:
3177  *          \f$ t[0]^2+t[1]^2+t[2]^2+2*t[3]^2+2*t[4]^2+2*t[5]^2\f$.
3178  *         The caller is to delete this result array using decrRef() as it is no more needed. 
3179  *  \throw If \a this->getNumberOfComponents() != 6.
3180  */
3181 DataArrayDouble *DataArrayDouble::doublyContractedProduct() const throw(INTERP_KERNEL::Exception)
3182 {
3183   checkAllocated();
3184   int nbOfComp=getNumberOfComponents();
3185   if(nbOfComp!=6)
3186     throw INTERP_KERNEL::Exception("DataArrayDouble::doublyContractedProduct : must be an array with exactly 6 components !");
3187   DataArrayDouble *ret=DataArrayDouble::New();
3188   int nbOfTuple=getNumberOfTuples();
3189   ret->alloc(nbOfTuple,1);
3190   const double *src=getConstPointer();
3191   double *dest=ret->getPointer();
3192   for(int i=0;i<nbOfTuple;i++,dest++,src+=6)
3193     *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];
3194   return ret;
3195 }
3196
3197 /*!
3198  * Computes the determinant of every square matrix defined by the tuple of \a this
3199  * array, which contains either 4, 6 or 9 components. The case of 6 components
3200  * corresponds to that of the upper triangular matrix.
3201  *  \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
3202  *          is the determinant of matrix of the corresponding tuple of \a this array.
3203  *          The caller is to delete this result array using decrRef() as it is no more
3204  *          needed. 
3205  *  \throw If \a this->getNumberOfComponents() is not in [4,6,9].
3206  */
3207 DataArrayDouble *DataArrayDouble::determinant() const throw(INTERP_KERNEL::Exception)
3208 {
3209   checkAllocated();
3210   DataArrayDouble *ret=DataArrayDouble::New();
3211   int nbOfTuple=getNumberOfTuples();
3212   ret->alloc(nbOfTuple,1);
3213   const double *src=getConstPointer();
3214   double *dest=ret->getPointer();
3215   switch(getNumberOfComponents())
3216     {
3217     case 6:
3218       for(int i=0;i<nbOfTuple;i++,dest++,src+=6)
3219         *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];
3220       return ret;
3221     case 4:
3222       for(int i=0;i<nbOfTuple;i++,dest++,src+=4)
3223         *dest=src[0]*src[3]-src[1]*src[2];
3224       return ret;
3225     case 9:
3226       for(int i=0;i<nbOfTuple;i++,dest++,src+=9)
3227         *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];
3228       return ret;
3229     default:
3230       ret->decrRef();
3231       throw INTERP_KERNEL::Exception("DataArrayDouble::determinant : Invalid number of components ! must be in 4,6,9 !");
3232     }
3233 }
3234
3235 /*!
3236  * Computes 3 eigenvalues of every upper triangular matrix defined by the tuple of
3237  * \a this array, which contains 6 components.
3238  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing 3
3239  *          components, whose each tuple contains the eigenvalues of the matrix of
3240  *          corresponding tuple of \a this array. 
3241  *          The caller is to delete this result array using decrRef() as it is no more
3242  *          needed. 
3243  *  \throw If \a this->getNumberOfComponents() != 6.
3244  */
3245 DataArrayDouble *DataArrayDouble::eigenValues() const throw(INTERP_KERNEL::Exception)
3246 {
3247   checkAllocated();
3248   int nbOfComp=getNumberOfComponents();
3249   if(nbOfComp!=6)
3250     throw INTERP_KERNEL::Exception("DataArrayDouble::eigenValues : must be an array with exactly 6 components !");
3251   DataArrayDouble *ret=DataArrayDouble::New();
3252   int nbOfTuple=getNumberOfTuples();
3253   ret->alloc(nbOfTuple,3);
3254   const double *src=getConstPointer();
3255   double *dest=ret->getPointer();
3256   for(int i=0;i<nbOfTuple;i++,dest+=3,src+=6)
3257     INTERP_KERNEL::computeEigenValues6(src,dest);
3258   return ret;
3259 }
3260
3261 /*!
3262  * Computes 3 eigenvectors of every upper triangular matrix defined by the tuple of
3263  * \a this array, which contains 6 components.
3264  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing 9
3265  *          components, whose each tuple contains 3 eigenvectors of the matrix of
3266  *          corresponding tuple of \a this array.
3267  *          The caller is to delete this result array using decrRef() as it is no more
3268  *          needed.
3269  *  \throw If \a this->getNumberOfComponents() != 6.
3270  */
3271 DataArrayDouble *DataArrayDouble::eigenVectors() const throw(INTERP_KERNEL::Exception)
3272 {
3273   checkAllocated();
3274   int nbOfComp=getNumberOfComponents();
3275   if(nbOfComp!=6)
3276     throw INTERP_KERNEL::Exception("DataArrayDouble::eigenVectors : must be an array with exactly 6 components !");
3277   DataArrayDouble *ret=DataArrayDouble::New();
3278   int nbOfTuple=getNumberOfTuples();
3279   ret->alloc(nbOfTuple,9);
3280   const double *src=getConstPointer();
3281   double *dest=ret->getPointer();
3282   for(int i=0;i<nbOfTuple;i++,src+=6)
3283     {
3284       double tmp[3];
3285       INTERP_KERNEL::computeEigenValues6(src,tmp);
3286       for(int j=0;j<3;j++,dest+=3)
3287         INTERP_KERNEL::computeEigenVectorForEigenValue6(src,tmp[j],1e-12,dest);
3288     }
3289   return ret;
3290 }
3291
3292 /*!
3293  * Computes the inverse matrix of every matrix defined by the tuple of \a this
3294  * array, which contains either 4, 6 or 9 components. The case of 6 components
3295  * corresponds to that of the upper triangular matrix.
3296  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
3297  *          same number of components as \a this one, whose each tuple is the inverse
3298  *          matrix of the matrix of corresponding tuple of \a this array. 
3299  *          The caller is to delete this result array using decrRef() as it is no more
3300  *          needed. 
3301  *  \throw If \a this->getNumberOfComponents() is not in [4,6,9].
3302  */
3303 DataArrayDouble *DataArrayDouble::inverse() const throw(INTERP_KERNEL::Exception)
3304 {
3305   checkAllocated();
3306   int nbOfComp=getNumberOfComponents();
3307   if(nbOfComp!=6 && nbOfComp!=9 && nbOfComp!=4)
3308     throw INTERP_KERNEL::Exception("DataArrayDouble::inversion : must be an array with 4,6 or 9 components !");
3309   DataArrayDouble *ret=DataArrayDouble::New();
3310   int nbOfTuple=getNumberOfTuples();
3311   ret->alloc(nbOfTuple,nbOfComp);
3312   const double *src=getConstPointer();
3313   double *dest=ret->getPointer();
3314 if(nbOfComp==6)
3315     for(int i=0;i<nbOfTuple;i++,dest+=6,src+=6)
3316       {
3317         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];
3318         dest[0]=(src[1]*src[2]-src[4]*src[4])/det;
3319         dest[1]=(src[0]*src[2]-src[5]*src[5])/det;
3320         dest[2]=(src[0]*src[1]-src[3]*src[3])/det;
3321         dest[3]=(src[5]*src[4]-src[3]*src[2])/det;
3322         dest[4]=(src[5]*src[3]-src[0]*src[4])/det;
3323         dest[5]=(src[3]*src[4]-src[1]*src[5])/det;
3324       }
3325   else if(nbOfComp==4)
3326     for(int i=0;i<nbOfTuple;i++,dest+=4,src+=4)
3327       {
3328         double det=src[0]*src[3]-src[1]*src[2];
3329         dest[0]=src[3]/det;
3330         dest[1]=-src[1]/det;
3331         dest[2]=-src[2]/det;
3332         dest[3]=src[0]/det;
3333       }
3334   else
3335     for(int i=0;i<nbOfTuple;i++,dest+=9,src+=9)
3336       {
3337         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];
3338         dest[0]=(src[4]*src[8]-src[7]*src[5])/det;
3339         dest[1]=(src[7]*src[2]-src[1]*src[8])/det;
3340         dest[2]=(src[1]*src[5]-src[4]*src[2])/det;
3341         dest[3]=(src[6]*src[5]-src[3]*src[8])/det;
3342         dest[4]=(src[0]*src[8]-src[6]*src[2])/det;
3343         dest[5]=(src[2]*src[3]-src[0]*src[5])/det;
3344         dest[6]=(src[3]*src[7]-src[6]*src[4])/det;
3345         dest[7]=(src[6]*src[1]-src[0]*src[7])/det;
3346         dest[8]=(src[0]*src[4]-src[1]*src[3])/det;
3347       }
3348   return ret;
3349 }
3350
3351 /*!
3352  * Computes the trace of every matrix defined by the tuple of \a this
3353  * array, which contains either 4, 6 or 9 components. The case of 6 components
3354  * corresponds to that of the upper triangular matrix.
3355  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing 
3356  *          1 component, whose each tuple is the trace of
3357  *          the matrix of corresponding tuple of \a this array. 
3358  *          The caller is to delete this result array using decrRef() as it is no more
3359  *          needed. 
3360  *  \throw If \a this->getNumberOfComponents() is not in [4,6,9].
3361  */
3362 DataArrayDouble *DataArrayDouble::trace() const throw(INTERP_KERNEL::Exception)
3363 {
3364   checkAllocated();
3365   int nbOfComp=getNumberOfComponents();
3366   if(nbOfComp!=6 && nbOfComp!=9 && nbOfComp!=4)
3367     throw INTERP_KERNEL::Exception("DataArrayDouble::trace : must be an array with 4,6 or 9 components !");
3368   DataArrayDouble *ret=DataArrayDouble::New();
3369   int nbOfTuple=getNumberOfTuples();
3370   ret->alloc(nbOfTuple,1);
3371   const double *src=getConstPointer();
3372   double *dest=ret->getPointer();
3373   if(nbOfComp==6)
3374     for(int i=0;i<nbOfTuple;i++,dest++,src+=6)
3375       *dest=src[0]+src[1]+src[2];
3376   else if(nbOfComp==4)
3377     for(int i=0;i<nbOfTuple;i++,dest++,src+=4)
3378       *dest=src[0]+src[3];
3379   else
3380     for(int i=0;i<nbOfTuple;i++,dest++,src+=9)
3381       *dest=src[0]+src[4]+src[8];
3382   return ret;
3383 }
3384
3385 /*!
3386  * Computes the stress deviator tensor of every stress tensor defined by the tuple of
3387  * \a this array, which contains 6 components.
3388  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
3389  *          same number of components and tuples as \a this array.
3390  *          The caller is to delete this result array using decrRef() as it is no more
3391  *          needed.
3392  *  \throw If \a this->getNumberOfComponents() != 6.
3393  */
3394 DataArrayDouble *DataArrayDouble::deviator() const throw(INTERP_KERNEL::Exception)
3395 {
3396   checkAllocated();
3397   int nbOfComp=getNumberOfComponents();
3398   if(nbOfComp!=6)
3399     throw INTERP_KERNEL::Exception("DataArrayDouble::deviator : must be an array with exactly 6 components !");
3400   DataArrayDouble *ret=DataArrayDouble::New();
3401   int nbOfTuple=getNumberOfTuples();
3402   ret->alloc(nbOfTuple,6);
3403   const double *src=getConstPointer();
3404   double *dest=ret->getPointer();
3405   for(int i=0;i<nbOfTuple;i++,dest+=6,src+=6)
3406     {
3407       double tr=(src[0]+src[1]+src[2])/3.;
3408       dest[0]=src[0]-tr;
3409       dest[1]=src[1]-tr;
3410       dest[2]=src[2]-tr;
3411       dest[3]=src[3];
3412       dest[4]=src[4];
3413       dest[5]=src[5];
3414     }
3415   return ret;
3416 }
3417
3418 /*!
3419  * Computes the magnitude of every vector defined by the tuple of
3420  * \a this array.
3421  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
3422  *          same number of tuples as \a this array and one component.
3423  *          The caller is to delete this result array using decrRef() as it is no more
3424  *          needed.
3425  *  \throw If \a this is not allocated.
3426  */
3427 DataArrayDouble *DataArrayDouble::magnitude() const throw(INTERP_KERNEL::Exception)
3428 {
3429   checkAllocated();
3430   int nbOfComp=getNumberOfComponents();
3431   DataArrayDouble *ret=DataArrayDouble::New();
3432   int nbOfTuple=getNumberOfTuples();
3433   ret->alloc(nbOfTuple,1);
3434   const double *src=getConstPointer();
3435   double *dest=ret->getPointer();
3436   for(int i=0;i<nbOfTuple;i++,dest++)
3437     {
3438       double sum=0.;
3439       for(int j=0;j<nbOfComp;j++,src++)
3440         sum+=(*src)*(*src);
3441       *dest=sqrt(sum);
3442     }
3443   return ret;
3444 }
3445
3446 /*!
3447  * Computes the maximal value within every tuple of \a this array.
3448  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
3449  *          same number of tuples as \a this array and one component.
3450  *          The caller is to delete this result array using decrRef() as it is no more
3451  *          needed.
3452  *  \throw If \a this is not allocated.
3453  */
3454 DataArrayDouble *DataArrayDouble::maxPerTuple() const throw(INTERP_KERNEL::Exception)
3455 {
3456   checkAllocated();
3457   int nbOfComp=getNumberOfComponents();
3458   DataArrayDouble *ret=DataArrayDouble::New();
3459   int nbOfTuple=getNumberOfTuples();
3460   ret->alloc(nbOfTuple,1);
3461   const double *src=getConstPointer();
3462   double *dest=ret->getPointer();
3463   for(int i=0;i<nbOfTuple;i++,dest++,src+=nbOfComp)
3464     *dest=*std::max_element(src,src+nbOfComp);
3465   return ret;
3466 }
3467
3468 /*!
3469  * This method returns a newly allocated DataArrayDouble instance having one component and \c this->getNumberOfTuples() * \c this->getNumberOfTuples() tuples.
3470  * \n This returned array contains the euclidian distance for each tuple in \a this. 
3471  * \n So the returned array can be seen as a dense symmetrical matrix whose diagonal elements are equal to 0.
3472  * \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)
3473  *
3474  * \warning use this method with care because it can leads to big amount of consumed memory !
3475  * 
3476  * \return A newly allocated (huge) ParaMEDMEM::DataArrayDouble instance that the caller should deal with.
3477  *
3478  * \throw If \a this is not allocated.
3479  *
3480  * \sa DataArrayDouble::buildEuclidianDistanceDenseMatrixWith
3481  */
3482 DataArrayDouble *DataArrayDouble::buildEuclidianDistanceDenseMatrix() const throw(INTERP_KERNEL::Exception)
3483 {
3484   checkAllocated();
3485   int nbOfComp=getNumberOfComponents();
3486   int nbOfTuples=getNumberOfTuples();
3487   const double *inData=getConstPointer();
3488   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
3489   ret->alloc(nbOfTuples*nbOfTuples,1);
3490   double *outData=ret->getPointer();
3491   for(int i=0;i<nbOfTuples;i++)
3492     {
3493       outData[i*nbOfTuples+i]=0.;
3494       for(int j=i+1;j<nbOfTuples;j++)
3495         {
3496           double dist=0.;
3497           for(int k=0;k<nbOfComp;k++)
3498             { double delta=inData[i*nbOfComp+k]-inData[j*nbOfComp+k]; dist+=delta*delta; }
3499           dist=sqrt(dist);
3500           outData[i*nbOfTuples+j]=dist;
3501           outData[j*nbOfTuples+i]=dist;
3502         }
3503     }
3504   return ret.retn();
3505 }
3506
3507 /*!
3508  * This method returns a newly allocated DataArrayDouble instance having one component and \c this->getNumberOfTuples() * \c other->getNumberOfTuples() tuples.
3509  * \n This returned array contains the euclidian distance for each tuple in \a other with each tuple in \a this. 
3510  * \n So the returned array can be seen as a dense rectangular matrix with \c other->getNumberOfTuples() rows and \c this->getNumberOfTuples() columns.
3511  * \n Output rectangular matrix is sorted along rows.
3512  * \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)
3513  *
3514  * \warning use this method with care because it can leads to big amount of consumed memory !
3515  * 
3516  * \param [in] other DataArrayDouble instance having same number of components than \a this.
3517  * \return A newly allocated (huge) ParaMEDMEM::DataArrayDouble instance that the caller should deal with.
3518  *
3519  * \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.
3520  *
3521  * \sa DataArrayDouble::buildEuclidianDistanceDenseMatrix
3522  */
3523 DataArrayDouble *DataArrayDouble::buildEuclidianDistanceDenseMatrixWith(const DataArrayDouble *other) const throw(INTERP_KERNEL::Exception)
3524 {
3525   if(!other)
3526     throw INTERP_KERNEL::Exception("DataArrayDouble::buildEuclidianDistanceDenseMatrixWith : input parameter is null !");
3527   checkAllocated();
3528   other->checkAllocated();
3529   int nbOfComp=getNumberOfComponents();
3530   int otherNbOfComp=other->getNumberOfComponents();
3531   if(nbOfComp!=otherNbOfComp)
3532     {
3533       std::ostringstream oss; oss << "DataArrayDouble::buildEuclidianDistanceDenseMatrixWith : this nb of compo=" << nbOfComp << " and other nb of compo=" << otherNbOfComp << ". It should match !";
3534       throw INTERP_KERNEL::Exception(oss.str().c_str());
3535     }
3536   int nbOfTuples=getNumberOfTuples();
3537   int otherNbOfTuples=other->getNumberOfTuples();
3538   const double *inData=getConstPointer();
3539   const double *inDataOther=other->getConstPointer();
3540   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
3541   ret->alloc(otherNbOfTuples*nbOfTuples,1);
3542   double *outData=ret->getPointer();
3543   for(int i=0;i<otherNbOfTuples;i++,inDataOther+=nbOfComp)
3544     {
3545       for(int j=0;j<nbOfTuples;j++)
3546         {
3547           double dist=0.;
3548           for(int k=0;k<nbOfComp;k++)
3549             { double delta=inDataOther[k]-inData[j*nbOfComp+k]; dist+=delta*delta; }
3550           dist=sqrt(dist);
3551           outData[i*nbOfTuples+j]=dist;
3552         }
3553     }
3554   return ret.retn();
3555 }
3556
3557 /*!
3558  * Sorts value within every tuple of \a this array.
3559  *  \param [in] asc - if \a true, the values are sorted in ascending order, else,
3560  *              in descending order.
3561  *  \throw If \a this is not allocated.
3562  */
3563 void DataArrayDouble::sortPerTuple(bool asc) throw(INTERP_KERNEL::Exception)
3564 {
3565   checkAllocated();
3566   double *pt=getPointer();
3567   int nbOfTuple=getNumberOfTuples();
3568   int nbOfComp=getNumberOfComponents();
3569   if(asc)
3570     for(int i=0;i<nbOfTuple;i++,pt+=nbOfComp)
3571       std::sort(pt,pt+nbOfComp);
3572   else
3573     for(int i=0;i<nbOfTuple;i++,pt+=nbOfComp)
3574       std::sort(pt,pt+nbOfComp,std::greater<double>());
3575   declareAsNew();
3576 }
3577
3578 /*!
3579  * Converts every value of \a this array to its absolute value.
3580  *  \throw If \a this is not allocated.
3581  */
3582 void DataArrayDouble::abs() throw(INTERP_KERNEL::Exception)
3583 {
3584   checkAllocated();
3585   double *ptr=getPointer();
3586   std::size_t nbOfElems=getNbOfElems();
3587   std::transform(ptr,ptr+nbOfElems,ptr,std::ptr_fun<double,double>(fabs));
3588   declareAsNew();
3589 }
3590
3591 /*!
3592  * Apply a liner function to a given component of \a this array, so that
3593  * an array element <em>(x)</em> becomes \f$ a * x + b \f$.
3594  *  \param [in] a - the first coefficient of the function.
3595  *  \param [in] b - the second coefficient of the function.
3596  *  \param [in] compoId - the index of component to modify.
3597  *  \throw If \a this is not allocated.
3598  */
3599 void DataArrayDouble::applyLin(double a, double b, int compoId) throw(INTERP_KERNEL::Exception)
3600 {
3601   checkAllocated();
3602   double *ptr=getPointer()+compoId;
3603   int nbOfComp=getNumberOfComponents();
3604   int nbOfTuple=getNumberOfTuples();
3605   for(int i=0;i<nbOfTuple;i++,ptr+=nbOfComp)
3606     *ptr=a*(*ptr)+b;
3607   declareAsNew();
3608 }
3609
3610 /*!
3611  * Apply a liner function to all elements of \a this array, so that
3612  * an element _x_ becomes \f$ a * x + b \f$.
3613  *  \param [in] a - the first coefficient of the function.
3614  *  \param [in] b - the second coefficient of the function.
3615  *  \throw If \a this is not allocated.
3616  */
3617 void DataArrayDouble::applyLin(double a, double b) throw(INTERP_KERNEL::Exception)
3618 {
3619   checkAllocated();
3620   double *ptr=getPointer();
3621   std::size_t nbOfElems=getNbOfElems();
3622   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
3623     *ptr=a*(*ptr)+b;
3624   declareAsNew();
3625 }
3626
3627 /*!
3628  * Modify all elements of \a this array, so that
3629  * an element _x_ becomes \f$ numerator / x \f$.
3630  *  \warning If an exception is thrown because of presence of 0.0 element in \a this 
3631  *           array, all elements processed before detection of the zero element remain
3632  *           modified.
3633  *  \param [in] numerator - the numerator used to modify array elements.
3634  *  \throw If \a this is not allocated.
3635  *  \throw If there is an element equal to 0.0 in \a this array.
3636  */
3637 void DataArrayDouble::applyInv(double numerator) throw(INTERP_KERNEL::Exception)
3638 {
3639   checkAllocated();
3640   double *ptr=getPointer();
3641   std::size_t nbOfElems=getNbOfElems();
3642   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
3643     {
3644       if(std::abs(*ptr)>std::numeric_limits<double>::min())
3645         {
3646           *ptr=numerator/(*ptr);
3647         }
3648       else
3649         {
3650           std::ostringstream oss; oss << "DataArrayDouble::applyInv : presence of null value in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
3651           oss << " !";
3652           throw INTERP_KERNEL::Exception(oss.str().c_str());
3653         }
3654     }
3655   declareAsNew();
3656 }
3657
3658 /*!
3659  * Returns a full copy of \a this array except that sign of all elements is reversed.
3660  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
3661  *          same number of tuples and component as \a this array.
3662  *          The caller is to delete this result array using decrRef() as it is no more
3663  *          needed.
3664  *  \throw If \a this is not allocated.
3665  */
3666 DataArrayDouble *DataArrayDouble::negate() const throw(INTERP_KERNEL::Exception)
3667 {
3668   checkAllocated();
3669   DataArrayDouble *newArr=DataArrayDouble::New();
3670   int nbOfTuples=getNumberOfTuples();
3671   int nbOfComp=getNumberOfComponents();
3672   newArr->alloc(nbOfTuples,nbOfComp);
3673   const double *cptr=getConstPointer();
3674   std::transform(cptr,cptr+nbOfTuples*nbOfComp,newArr->getPointer(),std::negate<double>());
3675   newArr->copyStringInfoFrom(*this);
3676   return newArr;
3677 }
3678
3679 /*!
3680  * Modify all elements of \a this array, so that
3681  * an element _x_ becomes <em> val ^ x </em>. Contrary to DataArrayInt::applyPow
3682  * all values in \a this have to be >= 0 if val is \b not integer.
3683  *  \param [in] val - the value used to apply pow on all array elements.
3684  *  \throw If \a this is not allocated.
3685  *  \warning If an exception is thrown because of presence of 0 element in \a this 
3686  *           array and \a val is \b not integer, all elements processed before detection of the zero element remain
3687  *           modified.
3688  */
3689 void DataArrayDouble::applyPow(double val) throw(INTERP_KERNEL::Exception)
3690 {
3691   checkAllocated();
3692   double *ptr=getPointer();
3693   std::size_t nbOfElems=getNbOfElems();
3694   int val2=(int)val;
3695   bool isInt=((double)val2)==val;
3696   if(!isInt)
3697     {
3698       for(std::size_t i=0;i<nbOfElems;i++,ptr++)
3699         {
3700           if(*ptr>=0)
3701             *ptr=pow(*ptr,val);
3702           else
3703             {
3704               std::ostringstream oss; oss << "DataArrayDouble::applyPow (double) : At elem # " << i << " value is " << *ptr << " ! must be >=0. !";
3705               throw INTERP_KERNEL::Exception(oss.str().c_str());
3706             }
3707         }
3708     }
3709   else
3710     {
3711       for(std::size_t i=0;i<nbOfElems;i++,ptr++)
3712         *ptr=pow(*ptr,val2);
3713     }
3714   declareAsNew();
3715 }
3716
3717 /*!
3718  * Modify all elements of \a this array, so that
3719  * an element _x_ becomes \f$ val ^ x \f$.
3720  *  \param [in] val - the value used to apply pow on all array elements.
3721  *  \throw If \a this is not allocated.
3722  *  \throw If \a val < 0.
3723  *  \warning If an exception is thrown because of presence of 0 element in \a this 
3724  *           array, all elements processed before detection of the zero element remain
3725  *           modified.
3726  */
3727 void DataArrayDouble::applyRPow(double val) throw(INTERP_KERNEL::Exception)
3728 {
3729   checkAllocated();
3730   if(val<0.)
3731     throw INTERP_KERNEL::Exception("DataArrayDouble::applyRPow : the input value has to be >= 0 !");
3732   double *ptr=getPointer();
3733   std::size_t nbOfElems=getNbOfElems();
3734   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
3735     *ptr=pow(val,*ptr);
3736   declareAsNew();
3737 }
3738
3739 /*!
3740  * Returns a new DataArrayDouble created from \a this one by applying \a
3741  * FunctionToEvaluate to every tuple of \a this array. Textual data is not copied.
3742  * For more info see \ref MEDCouplingArrayApplyFunc
3743  *  \param [in] nbOfComp - number of components in the result array.
3744  *  \param [in] func - the \a FunctionToEvaluate declared as 
3745  *              \c bool (*\a func)(\c const \c double *\a pos, \c double *\a res), 
3746  *              where \a pos points to the first component of a tuple of \a this array
3747  *              and \a res points to the first component of a tuple of the result array.
3748  *              Note that length (number of components) of \a pos can differ from
3749  *              that of \a res.
3750  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
3751  *          same number of tuples as \a this array.
3752  *          The caller is to delete this result array using decrRef() as it is no more
3753  *          needed.
3754  *  \throw If \a this is not allocated.
3755  *  \throw If \a func returns \a false.
3756  */
3757 DataArrayDouble *DataArrayDouble::applyFunc(int nbOfComp, FunctionToEvaluate func) const throw(INTERP_KERNEL::Exception)
3758 {
3759   checkAllocated();
3760   DataArrayDouble *newArr=DataArrayDouble::New();
3761   int nbOfTuples=getNumberOfTuples();
3762   int oldNbOfComp=getNumberOfComponents();
3763   newArr->alloc(nbOfTuples,nbOfComp);
3764   const double *ptr=getConstPointer();
3765   double *ptrToFill=newArr->getPointer();
3766   for(int i=0;i<nbOfTuples;i++)
3767     {
3768       if(!func(ptr+i*oldNbOfComp,ptrToFill+i*nbOfComp))
3769         {
3770           std::ostringstream oss; oss << "For tuple # " << i << " with value (";
3771           std::copy(ptr+oldNbOfComp*i,ptr+oldNbOfComp*(i+1),std::ostream_iterator<double>(oss,", "));
3772           oss << ") : Evaluation of function failed !";
3773           newArr->decrRef();
3774           throw INTERP_KERNEL::Exception(oss.str().c_str());
3775         }
3776     }
3777   return newArr;
3778 }
3779
3780 /*!
3781  * Returns a new DataArrayDouble created from \a this one by applying a function to every
3782  * tuple of \a this array. Textual data is not copied.
3783  * For more info see \ref MEDCouplingArrayApplyFunc1.
3784  *  \param [in] nbOfComp - number of components in the result array.
3785  *  \param [in] func - the expression defining how to transform a tuple of \a this array.
3786  *              Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
3787  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
3788  *          same number of tuples as \a this array and \a nbOfComp components.
3789  *          The caller is to delete this result array using decrRef() as it is no more
3790  *          needed.
3791  *  \throw If \a this is not allocated.
3792  *  \throw If computing \a func fails.
3793  */
3794 DataArrayDouble *DataArrayDouble::applyFunc(int nbOfComp, const char *func) const throw(INTERP_KERNEL::Exception)
3795 {
3796   checkAllocated();
3797   INTERP_KERNEL::ExprParser expr(func);
3798   expr.parse();
3799   std::set<std::string> vars;
3800   expr.getTrueSetOfVars(vars);
3801   int oldNbOfComp=getNumberOfComponents();
3802   if((int)vars.size()>oldNbOfComp)
3803     {
3804       std::ostringstream oss; oss << "The field has " << oldNbOfComp << " components and there are ";
3805       oss << vars.size() << " variables : ";
3806       std::copy(vars.begin(),vars.end(),std::ostream_iterator<std::string>(oss," "));
3807       throw INTERP_KERNEL::Exception(oss.str().c_str());
3808     }
3809   std::vector<std::string> varsV(vars.begin(),vars.end());
3810   expr.prepareExprEvaluation(varsV,oldNbOfComp,nbOfComp);
3811   //
3812   DataArrayDouble *newArr=DataArrayDouble::New();
3813   int nbOfTuples=getNumberOfTuples();
3814   newArr->alloc(nbOfTuples,nbOfComp);
3815   const double *ptr=getConstPointer();
3816   double *ptrToFill=newArr->getPointer();
3817   for(int i=0;i<nbOfTuples;i++)
3818     {
3819       try
3820         {
3821           expr.evaluateExpr(nbOfComp,ptr+i*oldNbOfComp,ptrToFill+i*nbOfComp);
3822         }
3823       catch(INTERP_KERNEL::Exception& e)
3824         {
3825           std::ostringstream oss; oss << "For tuple # " << i << " with value (";
3826           std::copy(ptr+oldNbOfComp*i,ptr+oldNbOfComp*(i+1),std::ostream_iterator<double>(oss,", "));
3827           oss << ") : Evaluation of function failed !" << e.what();
3828           newArr->decrRef();
3829           throw INTERP_KERNEL::Exception(oss.str().c_str());
3830         }
3831     }
3832   return newArr;
3833 }
3834
3835 /*!
3836  * Returns a new DataArrayDouble created from \a this one by applying a function to every
3837  * tuple of \a this array. Textual data is not copied.
3838  * For more info see \ref MEDCouplingArrayApplyFunc0.
3839  *  \param [in] func - the expression defining how to transform a tuple of \a this array.
3840  *              Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
3841  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
3842  *          same number of tuples and components as \a this array.
3843  *          The caller is to delete this result array using decrRef() as it is no more
3844  *          needed.
3845  *  \throw If \a this is not allocated.
3846  *  \throw If computing \a func fails.
3847  */
3848 DataArrayDouble *DataArrayDouble::applyFunc(const char *func) const throw(INTERP_KERNEL::Exception)
3849 {
3850   checkAllocated();
3851   INTERP_KERNEL::ExprParser expr(func);
3852   expr.parse();
3853   expr.prepareExprEvaluationVec();
3854   //
3855   DataArrayDouble *newArr=DataArrayDouble::New();
3856   int nbOfTuples=getNumberOfTuples();
3857   int nbOfComp=getNumberOfComponents();
3858   newArr->alloc(nbOfTuples,nbOfComp);
3859   const double *ptr=getConstPointer();
3860   double *ptrToFill=newArr->getPointer();
3861   for(int i=0;i<nbOfTuples;i++)
3862     {
3863       try
3864         {
3865           expr.evaluateExpr(nbOfComp,ptr+i*nbOfComp,ptrToFill+i*nbOfComp);
3866         }
3867       catch(INTERP_KERNEL::Exception& e)
3868         {
3869           std::ostringstream oss; oss << "For tuple # " << i << " with value (";
3870           std::copy(ptr+nbOfComp*i,ptr+nbOfComp*(i+1),std::ostream_iterator<double>(oss,", "));
3871           oss << ") : Evaluation of function failed ! " << e.what();
3872           newArr->decrRef();
3873           throw INTERP_KERNEL::Exception(oss.str().c_str());
3874         }
3875     }
3876   return newArr;
3877 }
3878
3879 /*!
3880  * Returns a new DataArrayDouble created from \a this one by applying a function to every
3881  * tuple of \a this array. Textual data is not copied.
3882  * For more info see \ref MEDCouplingArrayApplyFunc2.
3883  *  \param [in] nbOfComp - number of components in the result array.
3884  *  \param [in] func - the expression defining how to transform a tuple of \a this array.
3885  *              Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
3886  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
3887  *          same number of tuples as \a this array.
3888  *          The caller is to delete this result array using decrRef() as it is no more
3889  *          needed.
3890  *  \throw If \a this is not allocated.
3891  *  \throw If \a func contains vars that are not in \a this->getInfoOnComponent().
3892  *  \throw If computing \a func fails.
3893  */
3894 DataArrayDouble *DataArrayDouble::applyFunc2(int nbOfComp, const char *func) const throw(INTERP_KERNEL::Exception)
3895 {
3896   checkAllocated();
3897   INTERP_KERNEL::ExprParser expr(func);
3898   expr.parse();
3899   std::set<std::string> vars;
3900   expr.getTrueSetOfVars(vars);
3901   int oldNbOfComp=getNumberOfComponents();
3902   if((int)vars.size()>oldNbOfComp)
3903     {
3904       std::ostringstream oss; oss << "The field has " << oldNbOfComp << " components and there are ";
3905       oss << vars.size() << " variables : ";
3906       std::copy(vars.begin(),vars.end(),std::ostream_iterator<std::string>(oss," "));
3907       throw INTERP_KERNEL::Exception(oss.str().c_str());
3908     }
3909   expr.prepareExprEvaluation(getVarsOnComponent(),oldNbOfComp,nbOfComp);
3910   //
3911   DataArrayDouble *newArr=DataArrayDouble::New();
3912   int nbOfTuples=getNumberOfTuples();
3913   newArr->alloc(nbOfTuples,nbOfComp);
3914   const double *ptr=getConstPointer();
3915   double *ptrToFill=newArr->getPointer();
3916   for(int i=0;i<nbOfTuples;i++)
3917     {
3918       try
3919         {
3920           expr.evaluateExpr(nbOfComp,ptr+i*oldNbOfComp,ptrToFill+i*nbOfComp);
3921         }
3922       catch(INTERP_KERNEL::Exception& e)
3923         {
3924           std::ostringstream oss; oss << "For tuple # " << i << " with value (";
3925           std::copy(ptr+oldNbOfComp*i,ptr+oldNbOfComp*(i+1),std::ostream_iterator<double>(oss,", "));
3926           oss << ") : Evaluation of function failed !" << e.what();
3927           newArr->decrRef();
3928           throw INTERP_KERNEL::Exception(oss.str().c_str());
3929         }
3930     }
3931   return newArr;
3932 }
3933
3934 /*!
3935  * Returns a new DataArrayDouble created from \a this one by applying a function to every
3936  * tuple of \a this array. Textual data is not copied.
3937  * For more info see \ref MEDCouplingArrayApplyFunc3.
3938  *  \param [in] nbOfComp - number of components in the result array.
3939  *  \param [in] varsOrder - sequence of vars defining their order.
3940  *  \param [in] func - the expression defining how to transform a tuple of \a this array.
3941  *              Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
3942  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
3943  *          same number of tuples as \a this array.
3944  *          The caller is to delete this result array using decrRef() as it is no more
3945  *          needed.
3946  *  \throw If \a this is not allocated.
3947  *  \throw If \a func contains vars not in \a varsOrder.
3948  *  \throw If computing \a func fails.
3949  */
3950 DataArrayDouble *DataArrayDouble::applyFunc3(int nbOfComp, const std::vector<std::string>& varsOrder, const char *func) const throw(INTERP_KERNEL::Exception)
3951 {
3952   checkAllocated();
3953   INTERP_KERNEL::ExprParser expr(func);
3954   expr.parse();
3955   std::set<std::string> vars;
3956   expr.getTrueSetOfVars(vars);
3957   int oldNbOfComp=getNumberOfComponents();
3958   if((int)vars.size()>oldNbOfComp)
3959     {
3960       std::ostringstream oss; oss << "The field has " << oldNbOfComp << " components and there are ";
3961       oss << vars.size() << " variables : ";
3962       std::copy(vars.begin(),vars.end(),std::ostream_iterator<std::string>(oss," "));
3963       throw INTERP_KERNEL::Exception(oss.str().c_str());
3964     }
3965   expr.prepareExprEvaluation(varsOrder,oldNbOfComp,nbOfComp);
3966   //
3967   DataArrayDouble *newArr=DataArrayDouble::New();
3968   int nbOfTuples=getNumberOfTuples();
3969   newArr->alloc(nbOfTuples,nbOfComp);
3970   const double *ptr=getConstPointer();
3971   double *ptrToFill=newArr->getPointer();
3972   for(int i=0;i<nbOfTuples;i++)
3973     {
3974       try
3975         {
3976           expr.evaluateExpr(nbOfComp,ptr+i*oldNbOfComp,ptrToFill+i*nbOfComp);
3977         }
3978       catch(INTERP_KERNEL::Exception& e)
3979         {
3980           std::ostringstream oss; oss << "For tuple # " << i << " with value (";
3981           std::copy(ptr+oldNbOfComp*i,ptr+oldNbOfComp*(i+1),std::ostream_iterator<double>(oss,", "));
3982           oss << ") : Evaluation of function failed !" << e.what();
3983           newArr->decrRef();
3984           throw INTERP_KERNEL::Exception(oss.str().c_str());
3985         }
3986     }
3987   return newArr;
3988 }
3989
3990 void DataArrayDouble::applyFuncFast32(const char *func) throw(INTERP_KERNEL::Exception)
3991 {
3992   checkAllocated();
3993   INTERP_KERNEL::ExprParser expr(func);
3994   expr.parse();
3995   char *funcStr=expr.compileX86();
3996   MYFUNCPTR funcPtr;
3997   *((void **)&funcPtr)=funcStr;//he he...
3998   //
3999   double *ptr=getPointer();
4000   int nbOfComp=getNumberOfComponents();
4001   int nbOfTuples=getNumberOfTuples();
4002   int nbOfElems=nbOfTuples*nbOfComp;
4003   for(int i=0;i<nbOfElems;i++,ptr++)
4004     *ptr=funcPtr(*ptr);
4005   declareAsNew();
4006 }
4007
4008 void DataArrayDouble::applyFuncFast64(const char *func) throw(INTERP_KERNEL::Exception)
4009 {
4010   checkAllocated();
4011   INTERP_KERNEL::ExprParser expr(func);
4012   expr.parse();
4013   char *funcStr=expr.compileX86_64();
4014   MYFUNCPTR funcPtr;
4015   *((void **)&funcPtr)=funcStr;//he he...
4016   //
4017   double *ptr=getPointer();
4018   int nbOfComp=getNumberOfComponents();
4019   int nbOfTuples=getNumberOfTuples();
4020   int nbOfElems=nbOfTuples*nbOfComp;
4021   for(int i=0;i<nbOfElems;i++,ptr++)
4022     *ptr=funcPtr(*ptr);
4023   declareAsNew();
4024 }
4025
4026 DataArrayDoubleIterator *DataArrayDouble::iterator() throw(INTERP_KERNEL::Exception)
4027 {
4028   return new DataArrayDoubleIterator(this);
4029 }
4030
4031 /*!
4032  * Returns a new DataArrayInt contating indices of tuples of \a this one-dimensional
4033  * array whose values are within a given range. Textual data is not copied.
4034  *  \param [in] vmin - a lowest acceptable value.
4035  *  \param [in] vmax - a greatest acceptable value.
4036  *  \return DataArrayInt * - the new instance of DataArrayInt.
4037  *          The caller is to delete this result array using decrRef() as it is no more
4038  *          needed.
4039  *  \throw If \a this->getNumberOfComponents() != 1.
4040  *
4041  *  \ref cpp_mcdataarraydouble_getidsinrange "Here is a C++ example".<br>
4042  *  \ref py_mcdataarraydouble_getidsinrange "Here is a Python example".
4043  */
4044 DataArrayInt *DataArrayDouble::getIdsInRange(double vmin, double vmax) const throw(INTERP_KERNEL::Exception)
4045 {
4046   checkAllocated();
4047   if(getNumberOfComponents()!=1)
4048     throw INTERP_KERNEL::Exception("DataArrayDouble::getIdsInRange : this must have exactly one component !");
4049   const double *cptr=getConstPointer();
4050   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(0,1);
4051   int nbOfTuples=getNumberOfTuples();
4052   for(int i=0;i<nbOfTuples;i++,cptr++)
4053     if(*cptr>=vmin && *cptr<=vmax)
4054       ret->pushBackSilent(i);
4055   return ret.retn();
4056 }
4057
4058 /*!
4059  * Returns a new DataArrayDouble by concatenating two given arrays, so that (1) the number
4060  * of tuples in the result array is a sum of the number of tuples of given arrays and (2)
4061  * the number of component in the result array is same as that of each of given arrays.
4062  * Info on components is copied from the first of the given arrays. Number of components
4063  * in the given arrays must be  the same.
4064  *  \param [in] a1 - an array to include in the result array.
4065  *  \param [in] a2 - another array to include in the result array.
4066  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4067  *          The caller is to delete this result array using decrRef() as it is no more
4068  *          needed.
4069  *  \throw If both \a a1 and \a a2 are NULL.
4070  *  \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents().
4071  */
4072 DataArrayDouble *DataArrayDouble::Aggregate(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception)
4073 {
4074   std::vector<const DataArrayDouble *> tmp(2);
4075   tmp[0]=a1; tmp[1]=a2;
4076   return Aggregate(tmp);
4077 }
4078
4079 /*!
4080  * Returns a new DataArrayDouble by concatenating all given arrays, so that (1) the number
4081  * of tuples in the result array is a sum of the number of tuples of given arrays and (2)
4082  * the number of component in the result array is same as that of each of given arrays.
4083  * Info on components is copied from the first of the given arrays. Number of components
4084  * in the given arrays must be  the same.
4085  *  \param [in] arr - a sequence of arrays to include in the result array.
4086  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4087  *          The caller is to delete this result array using decrRef() as it is no more
4088  *          needed.
4089  *  \throw If all arrays within \a arr are NULL.
4090  *  \throw If getNumberOfComponents() of arrays within \a arr.
4091  */
4092 DataArrayDouble *DataArrayDouble::Aggregate(const std::vector<const DataArrayDouble *>& arr) throw(INTERP_KERNEL::Exception)
4093 {
4094   std::vector<const DataArrayDouble *> a;
4095   for(std::vector<const DataArrayDouble *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
4096     if(*it4)
4097       a.push_back(*it4);
4098   if(a.empty())
4099     throw INTERP_KERNEL::Exception("DataArrayDouble::Aggregate : input list must contain at least one NON EMPTY DataArrayDouble !");
4100   std::vector<const DataArrayDouble *>::const_iterator it=a.begin();
4101   int nbOfComp=(*it)->getNumberOfComponents();
4102   int nbt=(*it++)->getNumberOfTuples();
4103   for(int i=1;it!=a.end();it++,i++)
4104     {
4105       if((*it)->getNumberOfComponents()!=nbOfComp)
4106         throw INTERP_KERNEL::Exception("DataArrayDouble::Aggregate : Nb of components mismatch for array aggregation !");
4107       nbt+=(*it)->getNumberOfTuples();
4108     }
4109   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
4110   ret->alloc(nbt,nbOfComp);
4111   double *pt=ret->getPointer();
4112   for(it=a.begin();it!=a.end();it++)
4113     pt=std::copy((*it)->getConstPointer(),(*it)->getConstPointer()+(*it)->getNbOfElems(),pt);
4114   ret->copyStringInfoFrom(*(a[0]));
4115   return ret.retn();
4116 }
4117
4118 /*!
4119  * Returns a new DataArrayDouble by aggregating two given arrays, so that (1) the number
4120  * of components in the result array is a sum of the number of components of given arrays
4121  * and (2) the number of tuples in the result array is same as that of each of given
4122  * arrays. In other words the i-th tuple of result array includes all components of
4123  * i-th tuples of all given arrays.
4124  * Number of tuples in the given arrays must be  the same.
4125  *  \param [in] a1 - an array to include in the result array.
4126  *  \param [in] a2 - another array to include in the result array.
4127  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4128  *          The caller is to delete this result array using decrRef() as it is no more
4129  *          needed.
4130  *  \throw If both \a a1 and \a a2 are NULL.
4131  *  \throw If any given array is not allocated.
4132  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
4133  */
4134 DataArrayDouble *DataArrayDouble::Meld(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception)
4135 {
4136   std::vector<const DataArrayDouble *> arr(2);
4137   arr[0]=a1; arr[1]=a2;
4138   return Meld(arr);
4139 }
4140
4141 /*!
4142  * Returns a new DataArrayDouble by aggregating all given arrays, so that (1) the number
4143  * of components in the result array is a sum of the number of components of given arrays
4144  * and (2) the number of tuples in the result array is same as that of each of given
4145  * arrays. In other words the i-th tuple of result array includes all components of
4146  * i-th tuples of all given arrays.
4147  * Number of tuples in the given arrays must be  the same.
4148  *  \param [in] arr - a sequence of arrays to include in the result array.
4149  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4150  *          The caller is to delete this result array using decrRef() as it is no more
4151  *          needed.
4152  *  \throw If all arrays within \a arr are NULL.
4153  *  \throw If any given array is not allocated.
4154  *  \throw If getNumberOfTuples() of arrays within \a arr is different.
4155  */
4156 DataArrayDouble *DataArrayDouble::Meld(const std::vector<const DataArrayDouble *>& arr) throw(INTERP_KERNEL::Exception)
4157 {
4158   std::vector<const DataArrayDouble *> a;
4159   for(std::vector<const DataArrayDouble *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
4160     if(*it4)
4161       a.push_back(*it4);
4162   if(a.empty())
4163     throw INTERP_KERNEL::Exception("DataArrayDouble::Meld : input list must contain at least one NON EMPTY DataArrayDouble !");
4164   std::vector<const DataArrayDouble *>::const_iterator it;
4165   for(it=a.begin();it!=a.end();it++)
4166     (*it)->checkAllocated();
4167   it=a.begin();
4168   int nbOfTuples=(*it)->getNumberOfTuples();
4169   std::vector<int> nbc(a.size());
4170   std::vector<const double *> pts(a.size());
4171   nbc[0]=(*it)->getNumberOfComponents();
4172   pts[0]=(*it++)->getConstPointer();
4173   for(int i=1;it!=a.end();it++,i++)
4174     {
4175       if(nbOfTuples!=(*it)->getNumberOfTuples())
4176         throw INTERP_KERNEL::Exception("DataArrayDouble::Meld : mismatch of number of tuples !");
4177       nbc[i]=(*it)->getNumberOfComponents();
4178       pts[i]=(*it)->getConstPointer();
4179     }
4180   int totalNbOfComp=std::accumulate(nbc.begin(),nbc.end(),0);
4181   DataArrayDouble *ret=DataArrayDouble::New();
4182   ret->alloc(nbOfTuples,totalNbOfComp);
4183   double *retPtr=ret->getPointer();
4184   for(int i=0;i<nbOfTuples;i++)
4185     for(int j=0;j<(int)a.size();j++)
4186       {
4187         retPtr=std::copy(pts[j],pts[j]+nbc[j],retPtr);
4188         pts[j]+=nbc[j];
4189       }
4190   int k=0;
4191   for(int i=0;i<(int)a.size();i++)
4192     for(int j=0;j<nbc[i];j++,k++)
4193       ret->setInfoOnComponent(k,a[i]->getInfoOnComponent(j).c_str());
4194   return ret;
4195 }
4196
4197 /*!
4198  * Returns a new DataArrayDouble containing a dot product of two given arrays, so that
4199  * the i-th tuple of the result array is a sum of products of j-th components of i-th
4200  * tuples of given arrays (\f$ a_i = \sum_{j=1}^n a1_j * a2_j \f$).
4201  * Info on components and name is copied from the first of the given arrays.
4202  * Number of tuples and components in the given arrays must be the same.
4203  *  \param [in] a1 - a given array.
4204  *  \param [in] a2 - another given array.
4205  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4206  *          The caller is to delete this result array using decrRef() as it is no more
4207  *          needed.
4208  *  \throw If either \a a1 or \a a2 is NULL.
4209  *  \throw If any given array is not allocated.
4210  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
4211  *  \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents()
4212  */
4213 DataArrayDouble *DataArrayDouble::Dot(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception)
4214 {
4215   if(!a1 || !a2)
4216     throw INTERP_KERNEL::Exception("DataArrayDouble::Dot : input DataArrayDouble instance is NULL !");
4217   a1->checkAllocated();
4218   a2->checkAllocated();
4219   int nbOfComp=a1->getNumberOfComponents();
4220   if(nbOfComp!=a2->getNumberOfComponents())
4221     throw INTERP_KERNEL::Exception("Nb of components mismatch for array Dot !");
4222   int nbOfTuple=a1->getNumberOfTuples();
4223   if(nbOfTuple!=a2->getNumberOfTuples())
4224     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Dot !");
4225   DataArrayDouble *ret=DataArrayDouble::New();
4226   ret->alloc(nbOfTuple,1);
4227   double *retPtr=ret->getPointer();
4228   const double *a1Ptr=a1->getConstPointer();
4229   const double *a2Ptr=a2->getConstPointer();
4230   for(int i=0;i<nbOfTuple;i++)
4231     {
4232       double sum=0.;
4233       for(int j=0;j<nbOfComp;j++)
4234         sum+=a1Ptr[i*nbOfComp+j]*a2Ptr[i*nbOfComp+j];
4235       retPtr[i]=sum;
4236     }
4237   ret->setInfoOnComponent(0,a1->getInfoOnComponent(0).c_str());
4238   ret->setName(a1->getName().c_str());
4239   return ret;
4240 }
4241
4242 /*!
4243  * Returns a new DataArrayDouble containing a cross product of two given arrays, so that
4244  * the i-th tuple of the result array contains 3 components of a vector which is a cross
4245  * product of two vectors defined by the i-th tuples of given arrays.
4246  * Info on components is copied from the first of the given arrays.
4247  * Number of tuples in the given arrays must be the same.
4248  * Number of components in the given arrays must be 3.
4249  *  \param [in] a1 - a given array.
4250  *  \param [in] a2 - another given array.
4251  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4252  *          The caller is to delete this result array using decrRef() as it is no more
4253  *          needed.
4254  *  \throw If either \a a1 or \a a2 is NULL.
4255  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
4256  *  \throw If \a a1->getNumberOfComponents() != 3
4257  *  \throw If \a a2->getNumberOfComponents() != 3
4258  */
4259 DataArrayDouble *DataArrayDouble::CrossProduct(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception)
4260 {
4261   if(!a1 || !a2)
4262     throw INTERP_KERNEL::Exception("DataArrayDouble::CrossProduct : input DataArrayDouble instance is NULL !");
4263   int nbOfComp=a1->getNumberOfComponents();
4264   if(nbOfComp!=a2->getNumberOfComponents())
4265     throw INTERP_KERNEL::Exception("Nb of components mismatch for array crossProduct !");
4266   if(nbOfComp!=3)
4267     throw INTERP_KERNEL::Exception("Nb of components must be equal to 3 for array crossProduct !");
4268   int nbOfTuple=a1->getNumberOfTuples();
4269   if(nbOfTuple!=a2->getNumberOfTuples())
4270     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array crossProduct !");
4271   DataArrayDouble *ret=DataArrayDouble::New();
4272   ret->alloc(nbOfTuple,3);
4273   double *retPtr=ret->getPointer();
4274   const double *a1Ptr=a1->getConstPointer();
4275   const double *a2Ptr=a2->getConstPointer();
4276   for(int i=0;i<nbOfTuple;i++)
4277     {
4278       retPtr[3*i]=a1Ptr[3*i+1]*a2Ptr[3*i+2]-a1Ptr[3*i+2]*a2Ptr[3*i+1];
4279       retPtr[3*i+1]=a1Ptr[3*i+2]*a2Ptr[3*i]-a1Ptr[3*i]*a2Ptr[3*i+2];
4280       retPtr[3*i+2]=a1Ptr[3*i]*a2Ptr[3*i+1]-a1Ptr[3*i+1]*a2Ptr[3*i];
4281     }
4282   ret->copyStringInfoFrom(*a1);
4283   return ret;
4284 }
4285
4286 /*!
4287  * Returns a new DataArrayDouble containing maximal values of two given arrays.
4288  * Info on components is copied from the first of the given arrays.
4289  * Number of tuples and components in the given arrays must be the same.
4290  *  \param [in] a1 - an array to compare values with another one.
4291  *  \param [in] a2 - another array to compare values with the first one.
4292  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4293  *          The caller is to delete this result array using decrRef() as it is no more
4294  *          needed.
4295  *  \throw If either \a a1 or \a a2 is NULL.
4296  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
4297  *  \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents()
4298  */
4299 DataArrayDouble *DataArrayDouble::Max(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception)
4300 {
4301   if(!a1 || !a2)
4302     throw INTERP_KERNEL::Exception("DataArrayDouble::Max : input DataArrayDouble instance is NULL !");
4303   int nbOfComp=a1->getNumberOfComponents();
4304   if(nbOfComp!=a2->getNumberOfComponents())
4305     throw INTERP_KERNEL::Exception("Nb of components mismatch for array Max !");
4306   int nbOfTuple=a1->getNumberOfTuples();
4307   if(nbOfTuple!=a2->getNumberOfTuples())
4308     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Max !");
4309   DataArrayDouble *ret=DataArrayDouble::New();
4310   ret->alloc(nbOfTuple,nbOfComp);
4311   double *retPtr=ret->getPointer();
4312   const double *a1Ptr=a1->getConstPointer();
4313   const double *a2Ptr=a2->getConstPointer();
4314   int nbElem=nbOfTuple*nbOfComp;
4315   for(int i=0;i<nbElem;i++)
4316     retPtr[i]=std::max(a1Ptr[i],a2Ptr[i]);
4317   ret->copyStringInfoFrom(*a1);
4318   return ret;
4319 }
4320
4321 /*!
4322  * Returns a new DataArrayDouble containing minimal values of two given arrays.
4323  * Info on components is copied from the first of the given arrays.
4324  * Number of tuples and components in the given arrays must be the same.
4325  *  \param [in] a1 - an array to compare values with another one.
4326  *  \param [in] a2 - another array to compare values with the first one.
4327  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4328  *          The caller is to delete this result array using decrRef() as it is no more
4329  *          needed.
4330  *  \throw If either \a a1 or \a a2 is NULL.
4331  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
4332  *  \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents()
4333  */
4334 DataArrayDouble *DataArrayDouble::Min(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception)
4335 {
4336   if(!a1 || !a2)
4337     throw INTERP_KERNEL::Exception("DataArrayDouble::Min : input DataArrayDouble instance is NULL !");
4338   int nbOfComp=a1->getNumberOfComponents();
4339   if(nbOfComp!=a2->getNumberOfComponents())
4340     throw INTERP_KERNEL::Exception("Nb of components mismatch for array min !");
4341   int nbOfTuple=a1->getNumberOfTuples();
4342   if(nbOfTuple!=a2->getNumberOfTuples())
4343     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array min !");
4344   DataArrayDouble *ret=DataArrayDouble::New();
4345   ret->alloc(nbOfTuple,nbOfComp);
4346   double *retPtr=ret->getPointer();
4347   const double *a1Ptr=a1->getConstPointer();
4348   const double *a2Ptr=a2->getConstPointer();
4349   int nbElem=nbOfTuple*nbOfComp;
4350   for(int i=0;i<nbElem;i++)
4351     retPtr[i]=std::min(a1Ptr[i],a2Ptr[i]);
4352   ret->copyStringInfoFrom(*a1);
4353   return ret;
4354 }
4355
4356 /*!
4357  * Returns a new DataArrayDouble that is a sum of two given arrays. There are 3
4358  * valid cases.
4359  * 1.  The arrays have same number of tuples and components. Then each value of
4360  *   the result array (_a_) is a sum of the corresponding values of \a a1 and \a a2,
4361  *   i.e.: _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ i, j ].
4362  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
4363  *   component. Then
4364  *   _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ i, 0 ].
4365  * 3.  The arrays have same number of components and one array, say _a2_, has one
4366  *   tuple. Then
4367  *   _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ 0, j ].
4368  *
4369  * Info on components is copied either from the first array (in the first case) or from
4370  * the array with maximal number of elements (getNbOfElems()).
4371  *  \param [in] a1 - an array to sum up.
4372  *  \param [in] a2 - another array to sum up.
4373  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4374  *          The caller is to delete this result array using decrRef() as it is no more
4375  *          needed.
4376  *  \throw If either \a a1 or \a a2 is NULL.
4377  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
4378  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
4379  *         none of them has number of tuples or components equal to 1.
4380  */
4381 DataArrayDouble *DataArrayDouble::Add(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception)
4382 {
4383   if(!a1 || !a2)
4384     throw INTERP_KERNEL::Exception("DataArrayDouble::Add : input DataArrayDouble instance is NULL !");
4385   int nbOfTuple=a1->getNumberOfTuples();
4386   int nbOfTuple2=a2->getNumberOfTuples();
4387   int nbOfComp=a1->getNumberOfComponents();
4388   int nbOfComp2=a2->getNumberOfComponents();
4389   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=0;
4390   if(nbOfTuple==nbOfTuple2)
4391     {
4392       if(nbOfComp==nbOfComp2)
4393         {
4394           ret=DataArrayDouble::New();
4395           ret->alloc(nbOfTuple,nbOfComp);
4396           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::plus<double>());
4397           ret->copyStringInfoFrom(*a1);
4398         }
4399       else
4400         {
4401           int nbOfCompMin,nbOfCompMax;
4402           const DataArrayDouble *aMin, *aMax;
4403           if(nbOfComp>nbOfComp2)
4404             {
4405               nbOfCompMin=nbOfComp2; nbOfCompMax=nbOfComp;
4406               aMin=a2; aMax=a1;
4407             }
4408           else
4409             {
4410               nbOfCompMin=nbOfComp; nbOfCompMax=nbOfComp2;
4411               aMin=a1; aMax=a2;
4412             }
4413           if(nbOfCompMin==1)
4414             {
4415               ret=DataArrayDouble::New();
4416               ret->alloc(nbOfTuple,nbOfCompMax);
4417               const double *aMinPtr=aMin->getConstPointer();
4418               const double *aMaxPtr=aMax->getConstPointer();
4419               double *res=ret->getPointer();
4420               for(int i=0;i<nbOfTuple;i++)
4421                 res=std::transform(aMaxPtr+i*nbOfCompMax,aMaxPtr+(i+1)*nbOfCompMax,res,std::bind2nd(std::plus<double>(),aMinPtr[i]));
4422               ret->copyStringInfoFrom(*aMax);
4423             }
4424           else
4425             throw INTERP_KERNEL::Exception("Nb of components mismatch for array Add !");
4426         }
4427     }
4428   else if((nbOfTuple==1 && nbOfTuple2>1) || (nbOfTuple>1 && nbOfTuple2==1))
4429     {
4430       if(nbOfComp==nbOfComp2)
4431         {
4432           int nbOfTupleMax=std::max(nbOfTuple,nbOfTuple2);
4433           const DataArrayDouble *aMin=nbOfTuple>nbOfTuple2?a2:a1;
4434           const DataArrayDouble *aMax=nbOfTuple>nbOfTuple2?a1:a2;
4435           const double *aMinPtr=aMin->getConstPointer(),*aMaxPtr=aMax->getConstPointer();
4436           ret=DataArrayDouble::New();
4437           ret->alloc(nbOfTupleMax,nbOfComp);
4438           double *res=ret->getPointer();
4439           for(int i=0;i<nbOfTupleMax;i++)
4440             res=std::transform(aMaxPtr+i*nbOfComp,aMaxPtr+(i+1)*nbOfComp,aMinPtr,res,std::plus<double>());
4441           ret->copyStringInfoFrom(*aMax);
4442         }
4443       else
4444         throw INTERP_KERNEL::Exception("Nb of components mismatch for array Add !");
4445     }
4446   else
4447     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Add !");
4448   return ret.retn();
4449 }
4450
4451 /*!
4452  * Adds values of another DataArrayDouble to values of \a this one. There are 3
4453  * valid cases.
4454  * 1.  The arrays have same number of tuples and components. Then each value of
4455  *   \a other array is added to the corresponding value of \a this array, i.e.:
4456  *   _a_ [ i, j ] += _other_ [ i, j ].
4457  * 2.  The arrays have same number of tuples and \a other array has one component. Then
4458  *   _a_ [ i, j ] += _other_ [ i, 0 ].
4459  * 3.  The arrays have same number of components and \a other array has one tuple. Then
4460  *   _a_ [ i, j ] += _a2_ [ 0, j ].
4461  *
4462  *  \param [in] other - an array to add to \a this one.
4463  *  \throw If \a other is NULL.
4464  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
4465  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
4466  *         \a other has number of both tuples and components not equal to 1.
4467  */
4468 void DataArrayDouble::addEqual(const DataArrayDouble *other) throw(INTERP_KERNEL::Exception)
4469 {
4470   if(!other)
4471     throw INTERP_KERNEL::Exception("DataArrayDouble::addEqual : input DataArrayDouble instance is NULL !");
4472   const char *msg="Nb of tuples mismatch for DataArrayDouble::addEqual  !";
4473   checkAllocated();
4474   other->checkAllocated();
4475   int nbOfTuple=getNumberOfTuples();
4476   int nbOfTuple2=other->getNumberOfTuples();
4477   int nbOfComp=getNumberOfComponents();
4478   int nbOfComp2=other->getNumberOfComponents();
4479   if(nbOfTuple==nbOfTuple2)
4480     {
4481       if(nbOfComp==nbOfComp2)
4482         {
4483           std::transform(begin(),end(),other->begin(),getPointer(),std::plus<double>());
4484         }
4485       else if(nbOfComp2==1)
4486         {
4487           double *ptr=getPointer();
4488           const double *ptrc=other->getConstPointer();
4489           for(int i=0;i<nbOfTuple;i++)
4490             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::plus<double>(),*ptrc++));
4491         }
4492       else
4493         throw INTERP_KERNEL::Exception(msg);
4494     }
4495   else if(nbOfTuple2==1)
4496     {
4497       if(nbOfComp2==nbOfComp)
4498         {
4499           double *ptr=getPointer();
4500           const double *ptrc=other->getConstPointer();
4501           for(int i=0;i<nbOfTuple;i++)
4502             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::plus<double>());
4503         }
4504       else
4505         throw INTERP_KERNEL::Exception(msg);
4506     }
4507   else
4508     throw INTERP_KERNEL::Exception(msg);
4509   declareAsNew();
4510 }
4511
4512 /*!
4513  * Returns a new DataArrayDouble that is a subtraction of two given arrays. There are 3
4514  * valid cases.
4515  * 1.  The arrays have same number of tuples and components. Then each value of
4516  *   the result array (_a_) is a subtraction of the corresponding values of \a a1 and
4517  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ i, j ].
4518  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
4519  *   component. Then
4520  *   _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ i, 0 ].
4521  * 3.  The arrays have same number of components and one array, say _a2_, has one
4522  *   tuple. Then
4523  *   _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ 0, j ].
4524  *
4525  * Info on components is copied either from the first array (in the first case) or from
4526  * the array with maximal number of elements (getNbOfElems()).
4527  *  \param [in] a1 - an array to subtract from.
4528  *  \param [in] a2 - an array to subtract.
4529  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4530  *          The caller is to delete this result array using decrRef() as it is no more
4531  *          needed.
4532  *  \throw If either \a a1 or \a a2 is NULL.
4533  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
4534  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
4535  *         none of them has number of tuples or components equal to 1.
4536  */
4537 DataArrayDouble *DataArrayDouble::Substract(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception)
4538 {
4539   if(!a1 || !a2)
4540     throw INTERP_KERNEL::Exception("DataArrayDouble::Substract : input DataArrayDouble instance is NULL !");
4541   int nbOfTuple1=a1->getNumberOfTuples();
4542   int nbOfTuple2=a2->getNumberOfTuples();
4543   int nbOfComp1=a1->getNumberOfComponents();
4544   int nbOfComp2=a2->getNumberOfComponents();
4545   if(nbOfTuple2==nbOfTuple1)
4546     {
4547       if(nbOfComp1==nbOfComp2)
4548         {
4549           MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
4550           ret->alloc(nbOfTuple2,nbOfComp1);
4551           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::minus<double>());
4552           ret->copyStringInfoFrom(*a1);
4553           return ret.retn();
4554         }
4555       else if(nbOfComp2==1)
4556         {
4557           MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
4558           ret->alloc(nbOfTuple1,nbOfComp1);
4559           const double *a2Ptr=a2->getConstPointer();
4560           const double *a1Ptr=a1->getConstPointer();
4561           double *res=ret->getPointer();
4562           for(int i=0;i<nbOfTuple1;i++)
4563             res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::minus<double>(),a2Ptr[i]));
4564           ret->copyStringInfoFrom(*a1);
4565           return ret.retn();
4566         }
4567       else
4568         {
4569           a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Substract !");
4570           return 0;
4571         }
4572     }
4573   else if(nbOfTuple2==1)
4574     {
4575       a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Substract !");
4576       MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
4577       ret->alloc(nbOfTuple1,nbOfComp1);
4578       const double *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
4579       double *pt=ret->getPointer();
4580       for(int i=0;i<nbOfTuple1;i++)
4581         pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::minus<double>());
4582       ret->copyStringInfoFrom(*a1);
4583       return ret.retn();
4584     }
4585   else
4586     {
4587       a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Substract !");//will always throw an exception
4588       return 0;
4589     }
4590 }
4591
4592 /*!
4593  * Subtract values of another DataArrayDouble from values of \a this one. There are 3
4594  * valid cases.
4595  * 1.  The arrays have same number of tuples and components. Then each value of
4596  *   \a other array is subtracted from the corresponding value of \a this array, i.e.:
4597  *   _a_ [ i, j ] -= _other_ [ i, j ].
4598  * 2.  The arrays have same number of tuples and \a other array has one component. Then
4599  *   _a_ [ i, j ] -= _other_ [ i, 0 ].
4600  * 3.  The arrays have same number of components and \a other array has one tuple. Then
4601  *   _a_ [ i, j ] -= _a2_ [ 0, j ].
4602  *
4603  *  \param [in] other - an array to subtract from \a this one.
4604  *  \throw If \a other is NULL.
4605  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
4606  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
4607  *         \a other has number of both tuples and components not equal to 1.
4608  */
4609 void DataArrayDouble::substractEqual(const DataArrayDouble *other) throw(INTERP_KERNEL::Exception)
4610 {
4611   if(!other)
4612     throw INTERP_KERNEL::Exception("DataArrayDouble::substractEqual : input DataArrayDouble instance is NULL !");
4613   const char *msg="Nb of tuples mismatch for DataArrayDouble::substractEqual  !";
4614   checkAllocated();
4615   other->checkAllocated();
4616   int nbOfTuple=getNumberOfTuples();
4617   int nbOfTuple2=other->getNumberOfTuples();
4618   int nbOfComp=getNumberOfComponents();
4619   int nbOfComp2=other->getNumberOfComponents();
4620   if(nbOfTuple==nbOfTuple2)
4621     {
4622       if(nbOfComp==nbOfComp2)
4623         {
4624           std::transform(begin(),end(),other->begin(),getPointer(),std::minus<double>());
4625         }
4626       else if(nbOfComp2==1)
4627         {
4628           double *ptr=getPointer();
4629           const double *ptrc=other->getConstPointer();
4630           for(int i=0;i<nbOfTuple;i++)
4631             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::minus<double>(),*ptrc++)); 
4632         }
4633       else
4634         throw INTERP_KERNEL::Exception(msg);
4635     }
4636   else if(nbOfTuple2==1)
4637     {
4638       if(nbOfComp2==nbOfComp)
4639         {
4640           double *ptr=getPointer();
4641           const double *ptrc=other->getConstPointer();
4642           for(int i=0;i<nbOfTuple;i++)
4643             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::minus<double>());
4644         }
4645       else
4646         throw INTERP_KERNEL::Exception(msg);
4647     }
4648   else
4649     throw INTERP_KERNEL::Exception(msg);
4650   declareAsNew();
4651 }
4652
4653 /*!
4654  * Returns a new DataArrayDouble that is a product of two given arrays. There are 3
4655  * valid cases.
4656  * 1.  The arrays have same number of tuples and components. Then each value of
4657  *   the result array (_a_) is a product of the corresponding values of \a a1 and
4658  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ i, j ].
4659  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
4660  *   component. Then
4661  *   _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ i, 0 ].
4662  * 3.  The arrays have same number of components and one array, say _a2_, has one
4663  *   tuple. Then
4664  *   _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ 0, j ].
4665  *
4666  * Info on components is copied either from the first array (in the first case) or from
4667  * the array with maximal number of elements (getNbOfElems()).
4668  *  \param [in] a1 - a factor array.
4669  *  \param [in] a2 - another factor array.
4670  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4671  *          The caller is to delete this result array using decrRef() as it is no more
4672  *          needed.
4673  *  \throw If either \a a1 or \a a2 is NULL.
4674  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
4675  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
4676  *         none of them has number of tuples or components equal to 1.
4677  */
4678 DataArrayDouble *DataArrayDouble::Multiply(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception)
4679 {
4680   if(!a1 || !a2)
4681     throw INTERP_KERNEL::Exception("DataArrayDouble::Multiply : input DataArrayDouble instance is NULL !");
4682   int nbOfTuple=a1->getNumberOfTuples();
4683   int nbOfTuple2=a2->getNumberOfTuples();
4684   int nbOfComp=a1->getNumberOfComponents();
4685   int nbOfComp2=a2->getNumberOfComponents();
4686   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=0;
4687   if(nbOfTuple==nbOfTuple2)
4688     {
4689       if(nbOfComp==nbOfComp2)
4690         {
4691           ret=DataArrayDouble::New();
4692           ret->alloc(nbOfTuple,nbOfComp);
4693           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::multiplies<double>());
4694           ret->copyStringInfoFrom(*a1);
4695         }
4696       else
4697         {
4698           int nbOfCompMin,nbOfCompMax;
4699           const DataArrayDouble *aMin, *aMax;
4700           if(nbOfComp>nbOfComp2)
4701             {
4702               nbOfCompMin=nbOfComp2; nbOfCompMax=nbOfComp;
4703               aMin=a2; aMax=a1;
4704             }
4705           else
4706             {
4707               nbOfCompMin=nbOfComp; nbOfCompMax=nbOfComp2;
4708               aMin=a1; aMax=a2;
4709             }
4710           if(nbOfCompMin==1)
4711             {
4712               ret=DataArrayDouble::New();
4713               ret->alloc(nbOfTuple,nbOfCompMax);
4714               const double *aMinPtr=aMin->getConstPointer();
4715               const double *aMaxPtr=aMax->getConstPointer();
4716               double *res=ret->getPointer();
4717               for(int i=0;i<nbOfTuple;i++)
4718                 res=std::transform(aMaxPtr+i*nbOfCompMax,aMaxPtr+(i+1)*nbOfCompMax,res,std::bind2nd(std::multiplies<double>(),aMinPtr[i]));
4719               ret->copyStringInfoFrom(*aMax);
4720             }
4721           else
4722             throw INTERP_KERNEL::Exception("Nb of components mismatch for array Multiply !");
4723         }
4724     }
4725   else if((nbOfTuple==1 && nbOfTuple2>1) || (nbOfTuple>1 && nbOfTuple2==1))
4726     {
4727       if(nbOfComp==nbOfComp2)
4728         {
4729           int nbOfTupleMax=std::max(nbOfTuple,nbOfTuple2);
4730           const DataArrayDouble *aMin=nbOfTuple>nbOfTuple2?a2:a1;
4731           const DataArrayDouble *aMax=nbOfTuple>nbOfTuple2?a1:a2;
4732           const double *aMinPtr=aMin->getConstPointer(),*aMaxPtr=aMax->getConstPointer();
4733           ret=DataArrayDouble::New();
4734           ret->alloc(nbOfTupleMax,nbOfComp);
4735           double *res=ret->getPointer();
4736           for(int i=0;i<nbOfTupleMax;i++)
4737             res=std::transform(aMaxPtr+i*nbOfComp,aMaxPtr+(i+1)*nbOfComp,aMinPtr,res,std::multiplies<double>());
4738           ret->copyStringInfoFrom(*aMax);
4739         }
4740       else
4741         throw INTERP_KERNEL::Exception("Nb of components mismatch for array Multiply !");
4742     }
4743   else
4744     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Multiply !");
4745   return ret.retn();
4746 }
4747
4748 /*!
4749  * Multiply values of another DataArrayDouble to values of \a this one. There are 3
4750  * valid cases.
4751  * 1.  The arrays have same number of tuples and components. Then each value of
4752  *   \a other array is multiplied to the corresponding value of \a this array, i.e.:
4753  *   _a_ [ i, j ] *= _other_ [ i, j ].
4754  * 2.  The arrays have same number of tuples and \a other array has one component. Then
4755  *   _a_ [ i, j ] *= _other_ [ i, 0 ].
4756  * 3.  The arrays have same number of components and \a other array has one tuple. Then
4757  *   _a_ [ i, j ] *= _a2_ [ 0, j ].
4758  *
4759  *  \param [in] other - an array to multiply to \a this one.
4760  *  \throw If \a other is NULL.
4761  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
4762  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
4763  *         \a other has number of both tuples and components not equal to 1.
4764  */
4765 void DataArrayDouble::multiplyEqual(const DataArrayDouble *other) throw(INTERP_KERNEL::Exception)
4766 {
4767   if(!other)
4768     throw INTERP_KERNEL::Exception("DataArrayDouble::multiplyEqual : input DataArrayDouble instance is NULL !");
4769   const char *msg="Nb of tuples mismatch for DataArrayDouble::multiplyEqual !";
4770   checkAllocated();
4771   other->checkAllocated();
4772   int nbOfTuple=getNumberOfTuples();
4773   int nbOfTuple2=other->getNumberOfTuples();
4774   int nbOfComp=getNumberOfComponents();
4775   int nbOfComp2=other->getNumberOfComponents();
4776   if(nbOfTuple==nbOfTuple2)
4777     {
4778       if(nbOfComp==nbOfComp2)
4779         {
4780           std::transform(begin(),end(),other->begin(),getPointer(),std::multiplies<double>());
4781         }
4782       else if(nbOfComp2==1)
4783         {
4784           double *ptr=getPointer();
4785           const double *ptrc=other->getConstPointer();
4786           for(int i=0;i<nbOfTuple;i++)
4787             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::multiplies<double>(),*ptrc++));
4788         }
4789       else
4790         throw INTERP_KERNEL::Exception(msg);
4791     }
4792   else if(nbOfTuple2==1)
4793     {
4794       if(nbOfComp2==nbOfComp)
4795         {
4796           double *ptr=getPointer();
4797           const double *ptrc=other->getConstPointer();
4798           for(int i=0;i<nbOfTuple;i++)
4799             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::multiplies<double>());
4800         }
4801       else
4802         throw INTERP_KERNEL::Exception(msg);
4803     }
4804   else
4805     throw INTERP_KERNEL::Exception(msg);
4806   declareAsNew();
4807 }
4808
4809 /*!
4810  * Returns a new DataArrayDouble that is a division of two given arrays. There are 3
4811  * valid cases.
4812  * 1.  The arrays have same number of tuples and components. Then each value of
4813  *   the result array (_a_) is a division of the corresponding values of \a a1 and
4814  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ i, j ].
4815  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
4816  *   component. Then
4817  *   _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ i, 0 ].
4818  * 3.  The arrays have same number of components and one array, say _a2_, has one
4819  *   tuple. Then
4820  *   _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ 0, j ].
4821  *
4822  * Info on components is copied either from the first array (in the first case) or from
4823  * the array with maximal number of elements (getNbOfElems()).
4824  *  \warning No check of division by zero is performed!
4825  *  \param [in] a1 - a numerator array.
4826  *  \param [in] a2 - a denominator array.
4827  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4828  *          The caller is to delete this result array using decrRef() as it is no more
4829  *          needed.
4830  *  \throw If either \a a1 or \a a2 is NULL.
4831  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
4832  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
4833  *         none of them has number of tuples or components equal to 1.
4834  */
4835 DataArrayDouble *DataArrayDouble::Divide(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception)
4836 {
4837   if(!a1 || !a2)
4838     throw INTERP_KERNEL::Exception("DataArrayDouble::Divide : input DataArrayDouble instance is NULL !");
4839   int nbOfTuple1=a1->getNumberOfTuples();
4840   int nbOfTuple2=a2->getNumberOfTuples();
4841   int nbOfComp1=a1->getNumberOfComponents();
4842   int nbOfComp2=a2->getNumberOfComponents();
4843   if(nbOfTuple2==nbOfTuple1)
4844     {
4845       if(nbOfComp1==nbOfComp2)
4846         {
4847           MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
4848           ret->alloc(nbOfTuple2,nbOfComp1);
4849           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::divides<double>());
4850           ret->copyStringInfoFrom(*a1);
4851           return ret.retn();
4852         }
4853       else if(nbOfComp2==1)
4854         {
4855           MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
4856           ret->alloc(nbOfTuple1,nbOfComp1);
4857           const double *a2Ptr=a2->getConstPointer();
4858           const double *a1Ptr=a1->getConstPointer();
4859           double *res=ret->getPointer();
4860           for(int i=0;i<nbOfTuple1;i++)
4861             res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::divides<double>(),a2Ptr[i]));
4862           ret->copyStringInfoFrom(*a1);
4863           return ret.retn();
4864         }
4865       else
4866         {
4867           a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Divide !");
4868           return 0;
4869         }
4870     }
4871   else if(nbOfTuple2==1)
4872     {
4873       a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Divide !");
4874       MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
4875       ret->alloc(nbOfTuple1,nbOfComp1);
4876       const double *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
4877       double *pt=ret->getPointer();
4878       for(int i=0;i<nbOfTuple1;i++)
4879         pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::divides<double>());
4880       ret->copyStringInfoFrom(*a1);
4881       return ret.retn();
4882     }
4883   else
4884     {
4885       a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Divide !");//will always throw an exception
4886       return 0;
4887     }
4888 }
4889
4890 /*!
4891  * Divide values of \a this array by values of another DataArrayDouble. There are 3
4892  * valid cases.
4893  * 1.  The arrays have same number of tuples and components. Then each value of
4894  *    \a this array is divided by the corresponding value of \a other one, i.e.:
4895  *   _a_ [ i, j ] /= _other_ [ i, j ].
4896  * 2.  The arrays have same number of tuples and \a other array has one component. Then
4897  *   _a_ [ i, j ] /= _other_ [ i, 0 ].
4898  * 3.  The arrays have same number of components and \a other array has one tuple. Then
4899  *   _a_ [ i, j ] /= _a2_ [ 0, j ].
4900  *
4901  *  \warning No check of division by zero is performed!
4902  *  \param [in] other - an array to divide \a this one by.
4903  *  \throw If \a other is NULL.
4904  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
4905  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
4906  *         \a other has number of both tuples and components not equal to 1.
4907  */
4908 void DataArrayDouble::divideEqual(const DataArrayDouble *other) throw(INTERP_KERNEL::Exception)
4909 {
4910   if(!other)
4911     throw INTERP_KERNEL::Exception("DataArrayDouble::divideEqual : input DataArrayDouble instance is NULL !");
4912   const char *msg="Nb of tuples mismatch for DataArrayDouble::divideEqual !";
4913   checkAllocated();
4914   other->checkAllocated();
4915   int nbOfTuple=getNumberOfTuples();
4916   int nbOfTuple2=other->getNumberOfTuples();
4917   int nbOfComp=getNumberOfComponents();
4918   int nbOfComp2=other->getNumberOfComponents();
4919   if(nbOfTuple==nbOfTuple2)
4920     {
4921       if(nbOfComp==nbOfComp2)
4922         {
4923           std::transform(begin(),end(),other->begin(),getPointer(),std::divides<double>());
4924         }
4925       else if(nbOfComp2==1)
4926         {
4927           double *ptr=getPointer();
4928           const double *ptrc=other->getConstPointer();
4929           for(int i=0;i<nbOfTuple;i++)
4930             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::divides<double>(),*ptrc++));
4931         }
4932       else
4933         throw INTERP_KERNEL::Exception(msg);
4934     }
4935   else if(nbOfTuple2==1)
4936     {
4937       if(nbOfComp2==nbOfComp)
4938         {
4939           double *ptr=getPointer();
4940           const double *ptrc=other->getConstPointer();
4941           for(int i=0;i<nbOfTuple;i++)
4942             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::divides<double>());
4943         }
4944       else
4945         throw INTERP_KERNEL::Exception(msg);
4946     }
4947   else
4948     throw INTERP_KERNEL::Exception(msg);
4949   declareAsNew();
4950 }
4951
4952 /*!
4953  * Returns a new DataArrayDouble that is the result of pow of two given arrays. There are 3
4954  * valid cases.
4955  *
4956  *  \param [in] a1 - an array to pow up.
4957  *  \param [in] a2 - another array to sum up.
4958  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4959  *          The caller is to delete this result array using decrRef() as it is no more
4960  *          needed.
4961  *  \throw If either \a a1 or \a a2 is NULL.
4962  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
4963  *  \throw If \a a1->getNumberOfComponents() != 1 or \a a2->getNumberOfComponents() != 1.
4964  *  \throw If there is a negative value in \a a1.
4965  */
4966 DataArrayDouble *DataArrayDouble::Pow(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception)
4967 {
4968   if(!a1 || !a2)
4969     throw INTERP_KERNEL::Exception("DataArrayDouble::Pow : at least one of input instances is null !");
4970   int nbOfTuple=a1->getNumberOfTuples();
4971   int nbOfTuple2=a2->getNumberOfTuples();
4972   int nbOfComp=a1->getNumberOfComponents();
4973   int nbOfComp2=a2->getNumberOfComponents();
4974   if(nbOfTuple!=nbOfTuple2)
4975     throw INTERP_KERNEL::Exception("DataArrayDouble::Pow : number of tuples mismatches !");
4976   if(nbOfComp!=1 || nbOfComp2!=1)
4977     throw INTERP_KERNEL::Exception("DataArrayDouble::Pow : number of components of both arrays must be equal to 1 !");
4978   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New(); ret->alloc(nbOfTuple,1);
4979   const double *ptr1(a1->begin()),*ptr2(a2->begin());
4980   double *ptr=ret->getPointer();
4981   for(int i=0;i<nbOfTuple;i++,ptr1++,ptr2++,ptr++)
4982     {
4983       if(*ptr1>=0)
4984         {
4985           *ptr=pow(*ptr1,*ptr2);
4986         }
4987       else
4988         {
4989           std::ostringstream oss; oss << "DataArrayDouble::Pow : on tuple #" << i << " of a1 value is < 0 (" << *ptr1 << ") !";
4990           throw INTERP_KERNEL::Exception(oss.str().c_str());
4991         }
4992     }
4993   return ret.retn();
4994 }
4995
4996 /*!
4997  * Apply pow on values of another DataArrayDouble to values of \a this one.
4998  *
4999  *  \param [in] other - an array to pow to \a this one.
5000  *  \throw If \a other is NULL.
5001  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples()
5002  *  \throw If \a this->getNumberOfComponents() != 1 or \a other->getNumberOfComponents() != 1
5003  *  \throw If there is a negative value in \a this.
5004  */
5005 void DataArrayDouble::powEqual(const DataArrayDouble *other) throw(INTERP_KERNEL::Exception)
5006 {
5007   if(!other)
5008     throw INTERP_KERNEL::Exception("DataArrayDouble::powEqual : input instance is null !");
5009   int nbOfTuple=getNumberOfTuples();
5010   int nbOfTuple2=other->getNumberOfTuples();
5011   int nbOfComp=getNumberOfComponents();
5012   int nbOfComp2=other->getNumberOfComponents();
5013   if(nbOfTuple!=nbOfTuple2)
5014     throw INTERP_KERNEL::Exception("DataArrayDouble::powEqual : number of tuples mismatches !");
5015   if(nbOfComp!=1 || nbOfComp2!=1)
5016     throw INTERP_KERNEL::Exception("DataArrayDouble::powEqual : number of components of both arrays must be equal to 1 !");
5017   double *ptr=getPointer();
5018   const double *ptrc=other->begin();
5019   for(int i=0;i<nbOfTuple;i++,ptrc++,ptr++)
5020     {
5021       if(*ptr>=0)
5022         *ptr=pow(*ptr,*ptrc);
5023       else
5024         {
5025           std::ostringstream oss; oss << "DataArrayDouble::powEqual : on tuple #" << i << " of this value is < 0 (" << *ptr << ") !";
5026           throw INTERP_KERNEL::Exception(oss.str().c_str());
5027         }
5028     }
5029   declareAsNew();
5030 }
5031
5032 /*!
5033  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
5034  * Server side.
5035  */
5036 void DataArrayDouble::getTinySerializationIntInformation(std::vector<int>& tinyInfo) const
5037 {
5038   tinyInfo.resize(2);
5039   if(isAllocated())
5040     {
5041       tinyInfo[0]=getNumberOfTuples();
5042       tinyInfo[1]=getNumberOfComponents();
5043     }
5044   else
5045     {
5046       tinyInfo[0]=-1;
5047       tinyInfo[1]=-1;
5048     }
5049 }
5050
5051 /*!
5052  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
5053  * Server side.
5054  */
5055 void DataArrayDouble::getTinySerializationStrInformation(std::vector<std::string>& tinyInfo) const
5056 {
5057   if(isAllocated())
5058     {
5059       int nbOfCompo=getNumberOfComponents();
5060       tinyInfo.resize(nbOfCompo+1);
5061       tinyInfo[0]=getName();
5062       for(int i=0;i<nbOfCompo;i++)
5063         tinyInfo[i+1]=getInfoOnComponent(i);
5064     }
5065   else
5066     {
5067       tinyInfo.resize(1);
5068       tinyInfo[0]=getName();
5069     }
5070 }
5071
5072 /*!
5073  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
5074  * This method returns if a feeding is needed.
5075  */
5076 bool DataArrayDouble::resizeForUnserialization(const std::vector<int>& tinyInfoI)
5077 {
5078   int nbOfTuple=tinyInfoI[0];
5079   int nbOfComp=tinyInfoI[1];
5080   if(nbOfTuple!=-1 || nbOfComp!=-1)
5081     {
5082       alloc(nbOfTuple,nbOfComp);
5083       return true;
5084     }
5085   return false;
5086 }
5087
5088 /*!
5089  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
5090  */
5091 void DataArrayDouble::finishUnserialization(const std::vector<int>& tinyInfoI, const std::vector<std::string>& tinyInfoS)
5092 {
5093   setName(tinyInfoS[0].c_str());
5094   if(isAllocated())
5095     {
5096       int nbOfCompo=getNumberOfComponents();
5097       for(int i=0;i<nbOfCompo;i++)
5098         setInfoOnComponent(i,tinyInfoS[i+1].c_str());
5099     }
5100 }
5101
5102 DataArrayDoubleIterator::DataArrayDoubleIterator(DataArrayDouble *da):_da(da),_tuple_id(0),_nb_comp(0),_nb_tuple(0)
5103 {
5104   if(_da)
5105     {
5106       _da->incrRef();
5107       if(_da->isAllocated())
5108         {
5109           _nb_comp=da->getNumberOfComponents();
5110           _nb_tuple=da->getNumberOfTuples();
5111           _pt=da->getPointer();
5112         }
5113     }
5114 }
5115
5116 DataArrayDoubleIterator::~DataArrayDoubleIterator()
5117 {
5118   if(_da)
5119     _da->decrRef();
5120 }
5121
5122 DataArrayDoubleTuple *DataArrayDoubleIterator::nextt() throw(INTERP_KERNEL::Exception)
5123 {
5124   if(_tuple_id<_nb_tuple)
5125     {
5126       _tuple_id++;
5127       DataArrayDoubleTuple *ret=new DataArrayDoubleTuple(_pt,_nb_comp);
5128       _pt+=_nb_comp;
5129       return ret;
5130     }
5131   else
5132     return 0;
5133 }
5134
5135 DataArrayDoubleTuple::DataArrayDoubleTuple(double *pt, int nbOfComp):_pt(pt),_nb_of_compo(nbOfComp)
5136 {
5137 }
5138
5139
5140 std::string DataArrayDoubleTuple::repr() const throw(INTERP_KERNEL::Exception)
5141 {
5142   std::ostringstream oss; oss.precision(17); oss << "(";
5143   for(int i=0;i<_nb_of_compo-1;i++)
5144     oss << _pt[i] << ", ";
5145   oss << _pt[_nb_of_compo-1] << ")";
5146   return oss.str();
5147 }
5148
5149 double DataArrayDoubleTuple::doubleValue() const throw(INTERP_KERNEL::Exception)
5150 {
5151   if(_nb_of_compo==1)
5152     return *_pt;
5153   throw INTERP_KERNEL::Exception("DataArrayDoubleTuple::doubleValue : DataArrayDoubleTuple instance has not exactly 1 component -> Not possible to convert it into a double precision float !");
5154 }
5155
5156 /*!
5157  * This method returns a newly allocated instance the caller should dealed with by a ParaMEDMEM::DataArrayDouble::decrRef.
5158  * This method performs \b no copy of data. The content is only referenced using ParaMEDMEM::DataArrayDouble::useArray with ownership set to \b false.
5159  * 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
5160  * \b nbOfCompo=1 and \bnbOfTuples==this->_nb_of_elem.
5161  */
5162 DataArrayDouble *DataArrayDoubleTuple::buildDADouble(int nbOfTuples, int nbOfCompo) const throw(INTERP_KERNEL::Exception)
5163 {
5164   if((_nb_of_compo==nbOfCompo && nbOfTuples==1) || (_nb_of_compo==nbOfTuples && nbOfCompo==1))
5165     {
5166       DataArrayDouble *ret=DataArrayDouble::New();
5167       ret->useExternalArrayWithRWAccess(_pt,nbOfTuples,nbOfCompo);
5168       return ret;
5169     }
5170   else
5171     {
5172       std::ostringstream oss; oss << "DataArrayDoubleTuple::buildDADouble : unable to build a requested DataArrayDouble instance with nbofTuple=" << nbOfTuples << " and nbOfCompo=" << nbOfCompo;
5173       oss << ".\nBecause the number of elements in this is " << _nb_of_compo << " !";
5174       throw INTERP_KERNEL::Exception(oss.str().c_str());
5175     }
5176 }
5177
5178 /*!
5179  * Returns a new instance of DataArrayInt. The caller is to delete this array
5180  * using decrRef() as it is no more needed. 
5181  */
5182 DataArrayInt *DataArrayInt::New()
5183 {
5184   return new DataArrayInt;
5185 }
5186
5187 /*!
5188  * Checks if raw data is allocated. Read more on the raw data
5189  * in \ref MEDCouplingArrayBasicsTuplesAndCompo "DataArrays infos" for more information.
5190  *  \return bool - \a true if the raw data is allocated, \a false else.
5191  */
5192 bool DataArrayInt::isAllocated() const throw(INTERP_KERNEL::Exception)
5193 {
5194   return getConstPointer()!=0;
5195 }
5196
5197 /*!
5198  * Checks if raw data is allocated and throws an exception if it is not the case.
5199  *  \throw If the raw data is not allocated.
5200  */
5201 void DataArrayInt::checkAllocated() const throw(INTERP_KERNEL::Exception)
5202 {
5203   if(!isAllocated())
5204     throw INTERP_KERNEL::Exception("DataArrayInt::checkAllocated : Array is defined but not allocated ! Call alloc or setValues method first !");
5205 }
5206
5207 std::size_t DataArrayInt::getHeapMemorySize() const
5208 {
5209   std::size_t sz=_mem.getNbOfElemAllocated();
5210   sz*=sizeof(int);
5211   return DataArray::getHeapMemorySize()+sz;
5212 }
5213
5214 /*!
5215  * Sets information on all components. This method can change number of components
5216  * at certain conditions; if the conditions are not respected, an exception is thrown.
5217  * The number of components can be changed provided that \a this is not allocated.
5218  *
5219  * To know more on format of the component information see
5220  * \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
5221  *  \param [in] info - a vector of component infos.
5222  *  \throw If \a this->getNumberOfComponents() != \a info.size() && \a this->isAllocated()
5223  */
5224 void DataArrayInt::setInfoAndChangeNbOfCompo(const std::vector<std::string>& info) throw(INTERP_KERNEL::Exception)
5225 {
5226   if(getNumberOfComponents()!=(int)info.size())
5227     {
5228       if(!isAllocated())
5229         _info_on_compo=info;
5230       else
5231         {
5232           std::ostringstream oss; oss << "DataArrayInt::setInfoAndChangeNbOfCompo : input is of size " << info.size() << " whereas number of components is equal to " << getNumberOfComponents() << "  and this is already allocated !";
5233           throw INTERP_KERNEL::Exception(oss.str().c_str());
5234         }
5235     }
5236   else
5237     _info_on_compo=info;
5238 }
5239
5240 /*!
5241  * Returns the only one value in \a this, if and only if number of elements
5242  * (nb of tuples * nb of components) is equal to 1, and that \a this is allocated.
5243  *  \return double - the sole value stored in \a this array.
5244  *  \throw If at least one of conditions stated above is not fulfilled.
5245  */
5246 int DataArrayInt::intValue() const throw(INTERP_KERNEL::Exception)
5247 {
5248   if(isAllocated())
5249     {
5250       if(getNbOfElems()==1)
5251         {
5252           return *getConstPointer();
5253         }
5254       else
5255         throw INTERP_KERNEL::Exception("DataArrayInt::intValue : DataArrayInt instance is allocated but number of elements is not equal to 1 !");
5256     }
5257   else
5258     throw INTERP_KERNEL::Exception("DataArrayInt::intValue : DataArrayInt instance is not allocated !");
5259 }
5260
5261 /*!
5262  * Returns an integer value characterizing \a this array, which is useful for a quick
5263  * comparison of many instances of DataArrayInt.
5264  *  \return int - the hash value.
5265  *  \throw If \a this is not allocated.
5266  */
5267 int DataArrayInt::getHashCode() const throw(INTERP_KERNEL::Exception)
5268 {
5269   checkAllocated();
5270   std::size_t nbOfElems=getNbOfElems();
5271   int ret=nbOfElems*65536;
5272   int delta=3;
5273   if(nbOfElems>48)
5274     delta=nbOfElems/8;
5275   int ret0=0;
5276   const int *pt=begin();
5277   for(std::size_t i=0;i<nbOfElems;i+=delta)
5278     ret0+=pt[i] & 0x1FFF;
5279   return ret+ret0;
5280 }
5281
5282 /*!
5283  * Checks the number of tuples.
5284  *  \return bool - \a true if getNumberOfTuples() == 0, \a false else.
5285  *  \throw If \a this is not allocated.
5286  */
5287 bool DataArrayInt::empty() const throw(INTERP_KERNEL::Exception)
5288 {
5289   checkAllocated();
5290   return getNumberOfTuples()==0;
5291 }
5292
5293 /*!
5294  * Returns a full copy of \a this. For more info on copying data arrays see
5295  * \ref MEDCouplingArrayBasicsCopyDeep.
5296  *  \return DataArrayInt * - a new instance of DataArrayInt.
5297  */
5298 DataArrayInt *DataArrayInt::deepCpy() const throw(INTERP_KERNEL::Exception)
5299 {
5300   return new DataArrayInt(*this);
5301 }
5302
5303 /*!
5304  * Returns either a \a deep or \a shallow copy of this array. For more info see
5305  * \ref MEDCouplingArrayBasicsCopyDeep and \ref MEDCouplingArrayBasicsCopyShallow.
5306  *  \param [in] dCpy - if \a true, a deep copy is returned, else, a shallow one.
5307  *  \return DataArrayInt * - either a new instance of DataArrayInt (if \a dCpy
5308  *          == \a true) or \a this instance (if \a dCpy == \a false).
5309  */
5310 DataArrayInt *DataArrayInt::performCpy(bool dCpy) const throw(INTERP_KERNEL::Exception)
5311 {
5312   if(dCpy)
5313     return deepCpy();
5314   else
5315     {
5316       incrRef();
5317       return const_cast<DataArrayInt *>(this);
5318     }
5319 }
5320
5321 /*!
5322  * Copies all the data from another DataArrayInt. For more info see
5323  * \ref MEDCouplingArrayBasicsCopyDeepAssign.
5324  *  \param [in] other - another instance of DataArrayInt to copy data from.
5325  *  \throw If the \a other is not allocated.
5326  */
5327 void DataArrayInt::cpyFrom(const DataArrayInt& other) throw(INTERP_KERNEL::Exception)
5328 {
5329   other.checkAllocated();
5330   int nbOfTuples=other.getNumberOfTuples();
5331   int nbOfComp=other.getNumberOfComponents();
5332   allocIfNecessary(nbOfTuples,nbOfComp);
5333   std::size_t nbOfElems=(std::size_t)nbOfTuples*nbOfComp;
5334   int *pt=getPointer();
5335   const int *ptI=other.getConstPointer();
5336   for(std::size_t i=0;i<nbOfElems;i++)
5337     pt[i]=ptI[i];
5338   copyStringInfoFrom(other);
5339 }
5340
5341 /*!
5342  * This method reserve nbOfElems elements in memory ( nbOfElems*4 bytes ) \b without impacting the number of tuples in \a this.
5343  * 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.
5344  * If \a this has not already been allocated, number of components is set to one.
5345  * This method allows to reduce number of reallocations on invokation of DataArrayInt::pushBackSilent and DataArrayInt::pushBackValsSilent on \a this.
5346  * 
5347  * \sa DataArrayInt::pack, DataArrayInt::pushBackSilent, DataArrayInt::pushBackValsSilent
5348  */
5349 void DataArrayInt::reserve(std::size_t nbOfElems) throw(INTERP_KERNEL::Exception)
5350 {
5351   int nbCompo=getNumberOfComponents();
5352   if(nbCompo==1)
5353     {
5354       _mem.reserve(nbOfElems);
5355     }
5356   else if(nbCompo==0)
5357     {
5358       _mem.reserve(nbOfElems);
5359       _info_on_compo.resize(1);
5360     }
5361   else
5362     throw INTERP_KERNEL::Exception("DataArrayInt::reserve : not available for DataArrayInt with number of components different than 1 !");
5363 }
5364
5365 /*!
5366  * 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
5367  * of counter. So the caller is expected to call TimeLabel::declareAsNew on \a this at the end of the push session.
5368  *
5369  * \param [in] val the value to be added in \a this
5370  * \throw If \a this has already been allocated with number of components different from one.
5371  * \sa DataArrayInt::pushBackValsSilent
5372  */
5373 void DataArrayInt::pushBackSilent(int val) throw(INTERP_KERNEL::Exception)
5374 {
5375   int nbCompo=getNumberOfComponents();
5376   if(nbCompo==1)
5377     _mem.pushBack(val);
5378   else if(nbCompo==0)
5379     {
5380       _info_on_compo.resize(1);
5381       _mem.pushBack(val);
5382     }
5383   else
5384     throw INTERP_KERNEL::Exception("DataArrayInt::pushBackSilent : not available for DataArrayInt with number of components different than 1 !");
5385 }
5386
5387 /*!
5388  * 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
5389  * of counter. So the caller is expected to call TimeLabel::declareAsNew on \a this at the end of the push session.
5390  *
5391  *  \param [in] valsBg - an array of values to push at the end of \this.
5392  *  \param [in] valsEnd - specifies the end of the array \a valsBg, so that
5393  *              the last value of \a valsBg is \a valsEnd[ -1 ].
5394  * \throw If \a this has already been allocated with number of components different from one.
5395  * \sa DataArrayInt::pushBackSilent
5396  */
5397 void DataArrayInt::pushBackValsSilent(const int *valsBg, const int *valsEnd) throw(INTERP_KERNEL::Exception)
5398 {
5399   int nbCompo=getNumberOfComponents();
5400   if(nbCompo==1)
5401     _mem.insertAtTheEnd(valsBg,valsEnd);
5402   else if(nbCompo==0)
5403     {
5404       _info_on_compo.resize(1);
5405       _mem.insertAtTheEnd(valsBg,valsEnd);
5406     }
5407   else
5408     throw INTERP_KERNEL::Exception("DataArrayInt::pushBackValsSilent : not available for DataArrayInt with number of components different than 1 !");
5409 }
5410
5411 /*!
5412  * This method returns silently ( without updating time label in \a this ) the last value, if any and suppress it.
5413  * \throw If \a this is already empty.
5414  * \throw If \a this has number of components different from one.
5415  */
5416 int DataArrayInt::popBackSilent() throw(INTERP_KERNEL::Exception)
5417 {
5418   if(getNumberOfComponents()==1)
5419     return _mem.popBack();
5420   else
5421     throw INTERP_KERNEL::Exception("DataArrayInt::popBackSilent : not available for DataArrayInt with number of components different than 1 !");
5422 }
5423
5424 /*!
5425  * 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.
5426  *
5427  * \sa DataArrayInt::getHeapMemorySize, DataArrayInt::reserve
5428  */
5429 void DataArrayInt::pack() const throw(INTERP_KERNEL::Exception)
5430 {
5431   _mem.pack();
5432 }
5433
5434 /*!
5435  * Allocates the raw data in memory. If exactly as same memory as needed already
5436  * allocated, it is not re-allocated.
5437  *  \param [in] nbOfTuple - number of tuples of data to allocate.
5438  *  \param [in] nbOfCompo - number of components of data to allocate.
5439  *  \throw If \a nbOfTuple < 0 or \a nbOfCompo < 0.
5440  */
5441 void DataArrayInt::allocIfNecessary(int nbOfTuple, int nbOfCompo) throw(INTERP_KERNEL::Exception)
5442 {
5443   if(isAllocated())
5444     {
5445       if(nbOfTuple!=getNumberOfTuples() || nbOfCompo!=getNumberOfComponents())
5446         alloc(nbOfTuple,nbOfCompo);
5447     }
5448   else
5449     alloc(nbOfTuple,nbOfCompo);
5450 }
5451
5452 /*!
5453  * Allocates the raw data in memory. If the memory was already allocated, then it is
5454  * freed and re-allocated. See an example of this method use
5455  * \ref MEDCouplingArraySteps1WC "here".
5456  *  \param [in] nbOfTuple - number of tuples of data to allocate.
5457  *  \param [in] nbOfCompo - number of components of data to allocate.
5458  *  \throw If \a nbOfTuple < 0 or \a nbOfCompo < 0.
5459  */
5460 void DataArrayInt::alloc(int nbOfTuple, int nbOfCompo) throw(INTERP_KERNEL::Exception)
5461 {
5462   if(nbOfTuple<0 || nbOfCompo<0)
5463     throw INTERP_KERNEL::Exception("DataArrayInt::alloc : request for negative length of data !");
5464   _info_on_compo.resize(nbOfCompo);
5465   _mem.alloc(nbOfCompo*(std::size_t)nbOfTuple);
5466   declareAsNew();
5467 }
5468
5469 /*!
5470  * Assign zero to all values in \a this array. To know more on filling arrays see
5471  * \ref MEDCouplingArrayFill.
5472  * \throw If \a this is not allocated.
5473  */
5474 void DataArrayInt::fillWithZero() throw(INTERP_KERNEL::Exception)
5475 {
5476   checkAllocated();
5477   _mem.fillWithValue(0);
5478   declareAsNew();
5479 }
5480
5481 /*!
5482  * Assign \a val to all values in \a this array. To know more on filling arrays see
5483  * \ref MEDCouplingArrayFill.
5484  *  \param [in] val - the value to fill with.
5485  *  \throw If \a this is not allocated.
5486  */
5487 void DataArrayInt::fillWithValue(int val) throw(INTERP_KERNEL::Exception)
5488 {
5489   checkAllocated();
5490   _mem.fillWithValue(val);
5491   declareAsNew();
5492 }
5493
5494 /*!
5495  * Set all values in \a this array so that the i-th element equals to \a init + i
5496  * (i starts from zero). To know more on filling arrays see \ref MEDCouplingArrayFill.
5497  *  \param [in] init - value to assign to the first element of array.
5498  *  \throw If \a this->getNumberOfComponents() != 1
5499  *  \throw If \a this is not allocated.
5500  */
5501 void DataArrayInt::iota(int init) throw(INTERP_KERNEL::Exception)
5502 {
5503   checkAllocated();
5504   if(getNumberOfComponents()!=1)
5505     throw INTERP_KERNEL::Exception("DataArrayInt::iota : works only for arrays with only one component, you can call 'rearrange' method before !");
5506   int *ptr=getPointer();
5507   int ntuples=getNumberOfTuples();
5508   for(int i=0;i<ntuples;i++)
5509     ptr[i]=init+i;
5510   declareAsNew();
5511 }
5512
5513 /*!
5514  * Returns a textual and human readable representation of \a this instance of
5515  * DataArrayInt. This text is shown when a DataArrayInt is printed in Python.
5516  *  \return std::string - text describing \a this DataArrayInt.
5517  */
5518 std::string DataArrayInt::repr() const throw(INTERP_KERNEL::Exception)
5519 {
5520   std::ostringstream ret;
5521   reprStream(ret);
5522   return ret.str();
5523 }
5524
5525 std::string DataArrayInt::reprZip() const throw(INTERP_KERNEL::Exception)
5526 {
5527   std::ostringstream ret;
5528   reprZipStream(ret);
5529   return ret.str();
5530 }
5531
5532 void DataArrayInt::writeVTK(std::ostream& ofs, int indent, const char *type, const char *nameInFile) const throw(INTERP_KERNEL::Exception)
5533 {
5534   checkAllocated();
5535   std::string idt(indent,' ');
5536   ofs << idt << "<DataArray type=\"" << type << "\" Name=\"" << nameInFile << "\" NumberOfComponents=\"" << getNumberOfComponents() << "\"";
5537   ofs << " format=\"ascii\" RangeMin=\"" << getMinValueInArray() << "\" RangeMax=\"" << getMaxValueInArray() << "\">\n" << idt;
5538   std::copy(begin(),end(),std::ostream_iterator<int>(ofs," "));
5539   ofs << std::endl << idt << "</DataArray>\n";
5540 }
5541
5542 void DataArrayInt::reprStream(std::ostream& stream) const throw(INTERP_KERNEL::Exception)
5543 {
5544   stream << "Name of int array : \"" << _name << "\"\n";
5545   reprWithoutNameStream(stream);
5546 }
5547
5548 void DataArrayInt::reprZipStream(std::ostream& stream) const throw(INTERP_KERNEL::Exception)
5549 {
5550   stream << "Name of int array : \"" << _name << "\"\n";
5551   reprZipWithoutNameStream(stream);
5552 }
5553
5554 void DataArrayInt::reprWithoutNameStream(std::ostream& stream) const throw(INTERP_KERNEL::Exception)
5555 {
5556   DataArray::reprWithoutNameStream(stream);
5557   _mem.repr(getNumberOfComponents(),stream);
5558 }
5559
5560 void DataArrayInt::reprZipWithoutNameStream(std::ostream& stream) const throw(INTERP_KERNEL::Exception)
5561 {
5562   DataArray::reprWithoutNameStream(stream);
5563   _mem.reprZip(getNumberOfComponents(),stream);
5564 }
5565
5566 void DataArrayInt::reprCppStream(const char *varName, std::ostream& stream) const throw(INTERP_KERNEL::Exception)
5567 {
5568   int nbTuples=getNumberOfTuples(),nbComp=getNumberOfComponents();
5569   const int *data=getConstPointer();
5570   stream << "DataArrayInt *" << varName << "=DataArrayInt::New();" << std::endl;
5571   if(nbTuples*nbComp>=1)
5572     {
5573       stream << "const int " << varName << "Data[" << nbTuples*nbComp << "]={";
5574       std::copy(data,data+nbTuples*nbComp-1,std::ostream_iterator<int>(stream,","));
5575       stream << data[nbTuples*nbComp-1] << "};" << std::endl;
5576       stream << varName << "->useArray(" << varName << "Data,false,CPP_DEALLOC," << nbTuples << "," << nbComp << ");" << std::endl;
5577     }
5578   else
5579     stream << varName << "->alloc(" << nbTuples << "," << nbComp << ");" << std::endl;
5580   stream << varName << "->setName(\"" << getName() << "\");" << std::endl;
5581 }
5582
5583 /*!
5584  * Method that gives a quick overvien of \a this for python.
5585  */
5586 void DataArrayInt::reprQuickOverview(std::ostream& stream) const throw(INTERP_KERNEL::Exception)
5587 {
5588   static const std::size_t MAX_NB_OF_BYTE_IN_REPR=300;
5589   stream << "DataArrayInt C++ instance at " << this << ". ";
5590   if(isAllocated())
5591     {
5592       int nbOfCompo=(int)_info_on_compo.size();
5593       if(nbOfCompo>=1)
5594         {
5595           int nbOfTuples=getNumberOfTuples();
5596           stream << "Number of tuples : " << nbOfTuples << ". Number of components : " << nbOfCompo << "." << std::endl;
5597           reprQuickOverviewData(stream,MAX_NB_OF_BYTE_IN_REPR);
5598         }
5599       else
5600         stream << "Number of components : 0.";
5601     }
5602   else
5603     stream << "*** No data allocated ****";
5604 }
5605
5606 void DataArrayInt::reprQuickOverviewData(std::ostream& stream, std::size_t maxNbOfByteInRepr) const throw(INTERP_KERNEL::Exception)
5607 {
5608   const int *data=begin();
5609   int nbOfTuples=getNumberOfTuples();
5610   int nbOfCompo=(int)_info_on_compo.size();
5611   std::ostringstream oss2; oss2 << "[";
5612   std::string oss2Str(oss2.str());
5613   bool isFinished=true;
5614   for(int i=0;i<nbOfTuples && isFinished;i++)
5615     {
5616       if(nbOfCompo>1)
5617         {
5618           oss2 << "(";
5619           for(int j=0;j<nbOfCompo;j++,data++)
5620             {
5621               oss2 << *data;
5622               if(j!=nbOfCompo-1) oss2 << ", ";
5623             }
5624           oss2 << ")";
5625         }
5626       else
5627         oss2 << *data++;
5628       if(i!=nbOfTuples-1) oss2 << ", ";
5629       std::string oss3Str(oss2.str());
5630       if(oss3Str.length()<maxNbOfByteInRepr)
5631         oss2Str=oss3Str;
5632       else
5633         isFinished=false;
5634     }
5635   stream << oss2Str;
5636   if(!isFinished)
5637     stream << "... ";
5638   stream << "]";
5639 }
5640
5641 /*!
5642  * Modifies \a this one-dimensional array so that each value \a v = \a indArrBg[ \a v ],
5643  * i.e. a current value is used as in index to get a new value from \a indArrBg.
5644  *  \param [in] indArrBg - pointer to the first element of array of new values to assign
5645  *         to \a this array.
5646  *  \param [in] indArrEnd - specifies the end of the array \a indArrBg, so that
5647  *              the last value of \a indArrBg is \a indArrEnd[ -1 ].
5648  *  \throw If \a this->getNumberOfComponents() != 1
5649  *  \throw If any value of \a this can't be used as a valid index for 
5650  *         [\a indArrBg, \a indArrEnd).
5651  */
5652 void DataArrayInt::transformWithIndArr(const int *indArrBg, const int *indArrEnd) throw(INTERP_KERNEL::Exception)
5653 {
5654   checkAllocated();
5655   if(getNumberOfComponents()!=1)
5656     throw INTERP_KERNEL::Exception("Call transformWithIndArr method on DataArrayInt with only one component, you can call 'rearrange' method before !");
5657   int nbElemsIn=(int)std::distance(indArrBg,indArrEnd);
5658   int nbOfTuples=getNumberOfTuples();
5659   int *pt=getPointer();
5660   for(int i=0;i<nbOfTuples;i++,pt++)
5661     {
5662       if(*pt>=0 && *pt<nbElemsIn)
5663         *pt=indArrBg[*pt];
5664       else
5665         {
5666           std::ostringstream oss; oss << "DataArrayInt::transformWithIndArr : error on tuple #" << i << " value is " << *pt << " and indirectionnal array as a size equal to " << nbElemsIn;
5667           throw INTERP_KERNEL::Exception(oss.str().c_str());
5668         }
5669     }
5670   declareAsNew();
5671 }
5672
5673 /*!
5674  * Computes distribution of values of \a this one-dimensional array between given value
5675  * ranges (casts). This method is typically useful for entity number spliting by types,
5676  * for example. 
5677  *  \warning The values contained in \a arrBg should be sorted ascendently. No
5678  *           check of this is be done. If not, the result is not warranted. 
5679  *  \param [in] arrBg - the array of ascending values defining the value ranges. The i-th
5680  *         value of \a arrBg (\a arrBg[ i ]) gives the lowest value of the i-th range,
5681  *         and the greatest value of the i-th range equals to \a arrBg[ i+1 ] - 1. \a
5682  *         arrBg containing \a n values defines \a n-1 ranges. The last value of \a arrBg
5683  *         should be more than every value in \a this array.
5684  *  \param [in] arrEnd - specifies the end of the array \a arrBg, so that
5685  *              the last value of \a arrBg is \a arrEnd[ -1 ].
5686  *  \param [out] castArr - a new instance of DataArrayInt, of same size as \a this array
5687  *         (same number of tuples and components), the caller is to delete 
5688  *         using decrRef() as it is no more needed.
5689  *         This array contains indices of ranges for every value of \a this array. I.e.
5690  *         the i-th value of \a castArr gives the index of range the i-th value of \a this
5691  *         belongs to. Or, in other words, this parameter contains for each tuple in \a
5692  *         this in which cast it holds.
5693  *  \param [out] rankInsideCast - a new instance of DataArrayInt, of same size as \a this
5694  *         array, the caller is to delete using decrRef() as it is no more needed.
5695  *         This array contains ranks of values of \a this array within ranges
5696  *         they belongs to. I.e. the i-th value of \a rankInsideCast gives the rank of
5697  *         the i-th value of \a this array within the \a castArr[ i ]-th range, to which
5698  *         the i-th value of \a this belongs to. Or, in other words, this param contains 
5699  *         for each tuple its rank inside its cast. The rank is computed as difference
5700  *         between the value and the lowest value of range.
5701  *  \param [out] castsPresent - a new instance of DataArrayInt, containing indices of
5702  *         ranges (casts) to which at least one value of \a this array belongs.
5703  *         Or, in other words, this param contains the casts that \a this contains.
5704  *         The caller is to delete this array using decrRef() as it is no more needed.
5705  *
5706  * \b Example: If \a this contains [6,5,0,3,2,7,8,1,4] and \a arrBg contains [0,4,9] then
5707  *            the output of this method will be : 
5708  * - \a castArr       : [1,1,0,0,0,1,1,0,1]
5709  * - \a rankInsideCast: [2,1,0,3,2,3,4,1,0]
5710  * - \a castsPresent  : [0,1]
5711  *
5712  * I.e. values of \a this array belong to 2 ranges: #0 and #1. Value 6 belongs to the
5713  * range #1 and its rank within this range is 2; etc.
5714  *
5715  *  \throw If \a this->getNumberOfComponents() != 1.
5716  *  \throw If \a arrEnd - arrBg < 2.
5717  *  \throw If any value of \a this is not less than \a arrEnd[-1].
5718  */
5719 void DataArrayInt::splitByValueRange(const int *arrBg, const int *arrEnd,
5720                                      DataArrayInt *& castArr, DataArrayInt *& rankInsideCast, DataArrayInt *& castsPresent) const throw(INTERP_KERNEL::Exception)
5721 {
5722   checkAllocated();
5723   if(getNumberOfComponents()!=1)
5724     throw INTERP_KERNEL::Exception("Call splitByValueRange  method on DataArrayInt with only one component, you can call 'rearrange' method before !");
5725   int nbOfTuples=getNumberOfTuples();
5726   std::size_t nbOfCast=std::distance(arrBg,arrEnd);
5727   if(nbOfCast<2)
5728     throw INTERP_KERNEL::Exception("DataArrayInt::splitByValueRange : The input array giving the cast range values should be of size >=2 !");
5729   nbOfCast--;
5730   const int *work=getConstPointer();
5731   typedef std::reverse_iterator<const int *> rintstart;
5732   rintstart bg(arrEnd);//OK no problem because size of 'arr' is greater or equal 2
5733   rintstart end2(arrBg);
5734   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret1=DataArrayInt::New();
5735   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret2=DataArrayInt::New();
5736   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret3=DataArrayInt::New();
5737   ret1->alloc(nbOfTuples,1);
5738   ret2->alloc(nbOfTuples,1);
5739   int *ret1Ptr=ret1->getPointer();
5740   int *ret2Ptr=ret2->getPointer();
5741   std::set<std::size_t> castsDetected;
5742   for(int i=0;i<nbOfTuples;i++)
5743     {
5744       rintstart res=std::find_if(bg,end2,std::bind2nd(std::less_equal<int>(), work[i]));
5745       std::size_t pos=std::distance(bg,res);
5746       std::size_t pos2=nbOfCast-pos;
5747       if(pos2<nbOfCast)
5748         {
5749           ret1Ptr[i]=(int)pos2;
5750           ret2Ptr[i]=work[i]-arrBg[pos2];
5751           castsDetected.insert(pos2);
5752         }
5753       else
5754         {
5755           std::ostringstream oss; oss << "DataArrayInt::splitByValueRange : At rank #" << i << " the value is " << work[i] << " whereas the last value is " << *bg;
5756           throw INTERP_KERNEL::Exception(oss.str().c_str());
5757         }
5758     }
5759   ret3->alloc((int)castsDetected.size(),1);
5760   std::copy(castsDetected.begin(),castsDetected.end(),ret3->getPointer());
5761   castArr=ret1.retn();
5762   rankInsideCast=ret2.retn();
5763   castsPresent=ret3.retn();
5764 }
5765
5766 /*!
5767  * Creates a one-dimensional DataArrayInt (\a res) whose contents are computed from 
5768  * values of \a this (\a a) and the given (\a indArr) arrays as follows:
5769  * \a res[ \a indArr[ \a a[ i ]]] = i. I.e. for each value in place i \a v = \a a[ i ],
5770  * new value in place \a indArr[ \a v ] is i.
5771  *  \param [in] indArrBg - the array holding indices within the result array to assign
5772  *         indices of values of \a this array pointing to values of \a indArrBg.
5773  *  \param [in] indArrEnd - specifies the end of the array \a indArrBg, so that
5774  *              the last value of \a indArrBg is \a indArrEnd[ -1 ].
5775  *  \return DataArrayInt * - the new instance of DataArrayInt.
5776  *          The caller is to delete this result array using decrRef() as it is no more
5777  *          needed.
5778  *  \throw If \a this->getNumberOfComponents() != 1.
5779  *  \throw If any value of \a this array is not a valid index for \a indArrBg array.
5780  *  \throw If any value of \a indArrBg is not a valid index for \a this array.
5781  */
5782 DataArrayInt *DataArrayInt::transformWithIndArrR(const int *indArrBg, const int *indArrEnd) const throw(INTERP_KERNEL::Exception)
5783 {
5784   checkAllocated();
5785   if(getNumberOfComponents()!=1)
5786     throw INTERP_KERNEL::Exception("Call transformWithIndArrR method on DataArrayInt with only one component, you can call 'rearrange' method before !");
5787   int nbElemsIn=(int)std::distance(indArrBg,indArrEnd);
5788   int nbOfTuples=getNumberOfTuples();
5789   const int *pt=getConstPointer();
5790   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
5791   ret->alloc(nbOfTuples,1);
5792   ret->fillWithValue(-1);
5793   int *tmp=ret->getPointer();
5794   for(int i=0;i<nbOfTuples;i++,pt++)
5795     {
5796       if(*pt>=0 && *pt<nbElemsIn)
5797         {
5798           int pos=indArrBg[*pt];
5799           if(pos>=0 && pos<nbOfTuples)
5800             tmp[pos]=i;
5801           else
5802             {
5803               std::ostringstream oss; oss << "DataArrayInt::transformWithIndArrR : error on tuple #" << i << " value of new pos is " << pos << " ( indArrBg[" << *pt << "]) ! Should be in [0," << nbOfTuples << ") !";
5804               throw INTERP_KERNEL::Exception(oss.str().c_str());
5805             }
5806         }
5807       else
5808         {
5809           std::ostringstream oss; oss << "DataArrayInt::transformWithIndArrR : error on tuple #" << i << " value is " << *pt << " and indirectionnal array as a size equal to " << nbElemsIn << " !";
5810           throw INTERP_KERNEL::Exception(oss.str().c_str());
5811         }
5812     }
5813   return ret.retn();
5814 }
5815
5816 /*!
5817  * Creates a one-dimensional DataArrayInt of given length, whose contents are computed
5818  * from values of \a this array, which is supposed to contain a renumbering map in 
5819  * "Old to New" mode. The result array contains a renumbering map in "New to Old" mode.
5820  * To know how to use the renumbering maps see \ref MEDCouplingArrayRenumbering.
5821  *  \param [in] newNbOfElem - the number of tuples in the result array.
5822  *  \return DataArrayInt * - the new instance of DataArrayInt.
5823  *          The caller is to delete this result array using decrRef() as it is no more
5824  *          needed.
5825  * 
5826  *  \ref cpp_mcdataarrayint_invertarrayo2n2n2o "Here is a C++ example".<br>
5827  *  \ref py_mcdataarrayint_invertarrayo2n2n2o  "Here is a Python example".
5828  */
5829 DataArrayInt *DataArrayInt::invertArrayO2N2N2O(int newNbOfElem) const
5830 {
5831   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
5832   ret->alloc(newNbOfElem,1);
5833   int nbOfOldNodes=getNumberOfTuples();
5834   const int *old2New=getConstPointer();
5835   int *pt=ret->getPointer();
5836   for(int i=0;i!=nbOfOldNodes;i++)
5837     if(old2New[i]!=-1)
5838       pt[old2New[i]]=i;
5839   return ret.retn();
5840 }
5841
5842 /*!
5843  * This method is similar to DataArrayInt::invertArrayO2N2N2O except that 
5844  * 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]
5845  */
5846 DataArrayInt *DataArrayInt::invertArrayO2N2N2OBis(int newNbOfElem) const throw(INTERP_KERNEL::Exception)
5847 {
5848   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
5849   ret->alloc(newNbOfElem,1);
5850   int nbOfOldNodes=getNumberOfTuples();
5851   const int *old2New=getConstPointer();
5852   int *pt=ret->getPointer();
5853   for(int i=nbOfOldNodes-1;i>=0;i--)
5854     if(old2New[i]!=-1)
5855       pt[old2New[i]]=i;
5856   return ret.retn();
5857 }
5858
5859 /*!
5860  * Creates a one-dimensional DataArrayInt of given length, whose contents are computed
5861  * from values of \a this array, which is supposed to contain a renumbering map in 
5862  * "New to Old" mode. The result array contains a renumbering map in "Old to New" mode.
5863  * To know how to use the renumbering maps see \ref MEDCouplingArrayRenumbering.
5864  *  \param [in] newNbOfElem - the number of tuples in the result array.
5865  *  \return DataArrayInt * - the new instance of DataArrayInt.
5866  *          The caller is to delete this result array using decrRef() as it is no more
5867  *          needed.
5868  * 
5869  *  \ref cpp_mcdataarrayint_invertarrayn2o2o2n "Here is a C++ example".
5870  *
5871  *  \ref py_mcdataarrayint_invertarrayn2o2o2n "Here is a Python example".
5872  */
5873 DataArrayInt *DataArrayInt::invertArrayN2O2O2N(int oldNbOfElem) const
5874 {
5875   checkAllocated();
5876   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
5877   ret->alloc(oldNbOfElem,1);
5878   const int *new2Old=getConstPointer();
5879   int *pt=ret->getPointer();
5880   std::fill(pt,pt+oldNbOfElem,-1);
5881   int nbOfNewElems=getNumberOfTuples();
5882   for(int i=0;i<nbOfNewElems;i++)
5883     pt[new2Old[i]]=i;
5884   return ret.retn();
5885 }
5886
5887 /*!
5888  * Equivalent to DataArrayInt::isEqual except that if false the reason of
5889  * mismatch is given.
5890  * 
5891  * \param [in] other the instance to be compared with \a this
5892  * \param [out] reason In case of inequality returns the reason.
5893  * \sa DataArrayInt::isEqual
5894  */
5895 bool DataArrayInt::isEqualIfNotWhy(const DataArrayInt& other, std::string& reason) const throw(INTERP_KERNEL::Exception)
5896 {
5897   if(!areInfoEqualsIfNotWhy(other,reason))
5898     return false;
5899   return _mem.isEqual(other._mem,0,reason);
5900 }
5901
5902 /*!
5903  * Checks if \a this and another DataArrayInt are fully equal. For more info see
5904  * \ref MEDCouplingArrayBasicsCompare.
5905  *  \param [in] other - an instance of DataArrayInt to compare with \a this one.
5906  *  \return bool - \a true if the two arrays are equal, \a false else.
5907  */
5908 bool DataArrayInt::isEqual(const DataArrayInt& other) const throw(INTERP_KERNEL::Exception)
5909 {
5910   std::string tmp;
5911   return isEqualIfNotWhy(other,tmp);
5912 }
5913
5914 /*!
5915  * Checks if values of \a this and another DataArrayInt are equal. For more info see
5916  * \ref MEDCouplingArrayBasicsCompare.
5917  *  \param [in] other - an instance of DataArrayInt to compare with \a this one.
5918  *  \return bool - \a true if the values of two arrays are equal, \a false else.
5919  */
5920 bool DataArrayInt::isEqualWithoutConsideringStr(const DataArrayInt& other) const throw(INTERP_KERNEL::Exception)
5921 {
5922   std::string tmp;
5923   return _mem.isEqual(other._mem,0,tmp);
5924 }
5925
5926 /*!
5927  * Checks if values of \a this and another DataArrayInt are equal. Comparison is
5928  * performed on sorted value sequences.
5929  * For more info see\ref MEDCouplingArrayBasicsCompare.
5930  *  \param [in] other - an instance of DataArrayInt to compare with \a this one.
5931  *  \return bool - \a true if the sorted values of two arrays are equal, \a false else.
5932  */
5933 bool DataArrayInt::isEqualWithoutConsideringStrAndOrder(const DataArrayInt& other) const throw(INTERP_KERNEL::Exception)
5934 {
5935   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> a=deepCpy();
5936   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> b=other.deepCpy();
5937   a->sort();
5938   b->sort();
5939   return a->isEqualWithoutConsideringStr(*b);
5940 }
5941
5942 /*!
5943  * Sorts values of the array.
5944  *  \param [in] asc - \a true means ascending order, \a false, descending.
5945  *  \throw If \a this is not allocated.
5946  *  \throw If \a this->getNumberOfComponents() != 1.
5947  */
5948 void DataArrayInt::sort(bool asc) throw(INTERP_KERNEL::Exception)
5949 {
5950   checkAllocated();
5951   if(getNumberOfComponents()!=1)
5952     throw INTERP_KERNEL::Exception("DataArrayInt::sort : only supported with 'this' array with ONE component !");
5953   _mem.sort(asc);
5954   declareAsNew();
5955 }
5956
5957 /*!
5958  * Reverse the array values.
5959  *  \throw If \a this->getNumberOfComponents() < 1.
5960  *  \throw If \a this is not allocated.
5961  */
5962 void DataArrayInt::reverse() throw(INTERP_KERNEL::Exception)
5963 {
5964   checkAllocated();
5965   _mem.reverse(getNumberOfComponents());
5966   declareAsNew();
5967 }
5968
5969 /*!
5970  * Checks that \a this array is consistently **increasing** or **decreasing** in value.
5971  * If not an exception is thrown.
5972  *  \param [in] increasing - if \a true, the array values should be increasing.
5973  *  \throw If sequence of values is not strictly monotonic in agreement with \a
5974  *         increasing arg.
5975  *  \throw If \a this->getNumberOfComponents() != 1.
5976  *  \throw If \a this is not allocated.
5977  */
5978 void DataArrayInt::checkMonotonic(bool increasing) const throw(INTERP_KERNEL::Exception)
5979 {
5980   if(!isMonotonic(increasing))
5981     {
5982       if (increasing)
5983         throw INTERP_KERNEL::Exception("DataArrayInt::checkMonotonic : 'this' is not INCREASING monotonic !");
5984       else
5985         throw INTERP_KERNEL::Exception("DataArrayInt::checkMonotonic : 'this' is not DECREASING monotonic !");
5986     }
5987 }
5988
5989 /*!
5990  * Checks that \a this array is consistently **increasing** or **decreasing** in value.
5991  *  \param [in] increasing - if \a true, array values should be increasing.
5992  *  \return bool - \a true if values change in accordance with \a increasing arg.
5993  *  \throw If \a this->getNumberOfComponents() != 1.
5994  *  \throw If \a this is not allocated.
5995  */
5996 bool DataArrayInt::isMonotonic(bool increasing) const throw(INTERP_KERNEL::Exception)
5997 {
5998   checkAllocated();
5999   if(getNumberOfComponents()!=1)
6000     throw INTERP_KERNEL::Exception("DataArrayInt::isMonotonic : only supported with 'this' array with ONE component !");
6001   int nbOfElements=getNumberOfTuples();
6002   const int *ptr=getConstPointer();
6003   if(nbOfElements==0)
6004     return true;
6005   int ref=ptr[0];
6006   if(increasing)
6007     {
6008       for(int i=1;i<nbOfElements;i++)
6009         {
6010           if(ptr[i]>=ref)
6011             ref=ptr[i];
6012           else
6013             return false;
6014         }
6015     }
6016   else
6017     {
6018       for(int i=1;i<nbOfElements;i++)
6019         {
6020           if(ptr[i]<=ref)
6021             ref=ptr[i];
6022           else
6023             return false;
6024         }
6025     }
6026   return true;
6027 }
6028
6029 /*!
6030  * This method check that array consistently INCREASING or DECREASING in value.
6031  */
6032 bool DataArrayInt::isStrictlyMonotonic(bool increasing) const throw(INTERP_KERNEL::Exception)
6033 {
6034   checkAllocated();
6035   if(getNumberOfComponents()!=1)
6036     throw INTERP_KERNEL::Exception("DataArrayInt::isStrictlyMonotonic : only supported with 'this' array with ONE component !");
6037   int nbOfElements=getNumberOfTuples();
6038   const int *ptr=getConstPointer();
6039   if(nbOfElements==0)
6040     return true;
6041   int ref=ptr[0];
6042   if(increasing)
6043     {
6044       for(int i=1;i<nbOfElements;i++)
6045         {
6046           if(ptr[i]>ref)
6047             ref=ptr[i];
6048           else
6049             return false;
6050         }
6051     }
6052   else
6053     {
6054       for(int i=1;i<nbOfElements;i++)
6055         {
6056           if(ptr[i]<ref)
6057             ref=ptr[i];
6058           else
6059             return false;
6060         }
6061     }
6062   return true;
6063 }
6064
6065 /*!
6066  * This method check that array consistently INCREASING or DECREASING in value.
6067  */
6068 void DataArrayInt::checkStrictlyMonotonic(bool increasing) const throw(INTERP_KERNEL::Exception)
6069 {
6070   if(!isStrictlyMonotonic(increasing))
6071     {
6072       if (increasing)
6073         throw INTERP_KERNEL::Exception("DataArrayInt::checkStrictlyMonotonic : 'this' is not strictly INCREASING monotonic !");
6074       else
6075         throw INTERP_KERNEL::Exception("DataArrayInt::checkStrictlyMonotonic : 'this' is not strictly DECREASING monotonic !");
6076     }
6077 }
6078
6079 /*!
6080  * Creates a new one-dimensional DataArrayInt of the same size as \a this and a given
6081  * one-dimensional arrays that must be of the same length. The result array describes
6082  * correspondence between \a this and \a other arrays, so that 
6083  * <em> other.getIJ(i,0) == this->getIJ(ret->getIJ(i),0)</em>. If such a permutation is
6084  * not possible because some element in \a other is not in \a this, an exception is thrown.
6085  *  \param [in] other - an array to compute permutation to.
6086  *  \return DataArrayInt * - a new instance of DataArrayInt, which is a permutation array
6087  * from \a this to \a other. The caller is to delete this array using decrRef() as it is
6088  * no more needed.
6089  *  \throw If \a this->getNumberOfComponents() != 1.
6090  *  \throw If \a other->getNumberOfComponents() != 1.
6091  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples().
6092  *  \throw If \a other includes a value which is not in \a this array.
6093  * 
6094  *  \ref cpp_mcdataarrayint_buildpermutationarr "Here is a C++ example".
6095  *
6096  *  \ref py_mcdataarrayint_buildpermutationarr "Here is a Python example".
6097  */
6098 DataArrayInt *DataArrayInt::buildPermutationArr(const DataArrayInt& other) const throw(INTERP_KERNEL::Exception)
6099 {
6100   checkAllocated();
6101   if(getNumberOfComponents()!=1 || other.getNumberOfComponents()!=1)
6102     throw INTERP_KERNEL::Exception("DataArrayInt::buildPermutationArr : 'this' and 'other' have to have exactly ONE component !");
6103   int nbTuple=getNumberOfTuples();
6104   other.checkAllocated();
6105   if(nbTuple!=other.getNumberOfTuples())
6106     throw INTERP_KERNEL::Exception("DataArrayInt::buildPermutationArr : 'this' and 'other' must have the same number of tuple !");
6107   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6108   ret->alloc(nbTuple,1);
6109   ret->fillWithValue(-1);
6110   const int *pt=getConstPointer();
6111   std::map<int,int> mm;
6112   for(int i=0;i<nbTuple;i++)
6113     mm[pt[i]]=i;
6114   pt=other.getConstPointer();
6115   int *retToFill=ret->getPointer();
6116   for(int i=0;i<nbTuple;i++)
6117     {
6118       std::map<int,int>::const_iterator it=mm.find(pt[i]);
6119       if(it==mm.end())
6120         {
6121           std::ostringstream oss; oss << "DataArrayInt::buildPermutationArr : Arrays mismatch : element (" << pt[i] << ") in 'other' not findable in 'this' !";
6122           throw INTERP_KERNEL::Exception(oss.str().c_str());
6123         }
6124       retToFill[i]=(*it).second;
6125     }
6126   return ret.retn();
6127 }
6128
6129 /*!
6130  * Sets a C array to be used as raw data of \a this. The previously set info
6131  *  of components is retained and re-sized. 
6132  * For more info see \ref MEDCouplingArraySteps1.
6133  *  \param [in] array - the C array to be used as raw data of \a this.
6134  *  \param [in] ownership - if \a true, \a array will be deallocated at destruction of \a this.
6135  *  \param [in] type - specifies how to deallocate \a array. If \a type == ParaMEDMEM::CPP_DEALLOC,
6136  *                     \c delete [] \c array; will be called. If \a type == ParaMEDMEM::C_DEALLOC,
6137  *                     \c free(\c array ) will be called.
6138  *  \param [in] nbOfTuple - new number of tuples in \a this.
6139  *  \param [in] nbOfCompo - new number of components in \a this.
6140  */
6141 void DataArrayInt::useArray(const int *array, bool ownership,  DeallocType type, int nbOfTuple, int nbOfCompo) throw(INTERP_KERNEL::Exception)
6142 {
6143   _info_on_compo.resize(nbOfCompo);
6144   _mem.useArray(array,ownership,type,nbOfTuple*nbOfCompo);
6145   declareAsNew();
6146 }
6147
6148 void DataArrayInt::useExternalArrayWithRWAccess(const int *array, int nbOfTuple, int nbOfCompo) throw(INTERP_KERNEL::Exception)
6149 {
6150   _info_on_compo.resize(nbOfCompo);
6151   _mem.useExternalArrayWithRWAccess(array,nbOfTuple*nbOfCompo);
6152   declareAsNew();
6153 }
6154
6155 /*!
6156  * Returns a new DataArrayInt holding the same values as \a this array but differently
6157  * arranged in memory. If \a this array holds 2 components of 3 values:
6158  * \f$ x_0,x_1,x_2,y_0,y_1,y_2 \f$, then the result array holds these values arranged
6159  * as follows: \f$ x_0,y_0,x_1,y_1,x_2,y_2 \f$.
6160  *  \warning Do not confuse this method with transpose()!
6161  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
6162  *          is to delete using decrRef() as it is no more needed.
6163  *  \throw If \a this is not allocated.
6164  */
6165 DataArrayInt *DataArrayInt::fromNoInterlace() const throw(INTERP_KERNEL::Exception)
6166 {
6167   checkAllocated();
6168   if(_mem.isNull())
6169     throw INTERP_KERNEL::Exception("DataArrayInt::fromNoInterlace : Not defined array !");
6170   int *tab=_mem.fromNoInterlace(getNumberOfComponents());
6171   DataArrayInt *ret=DataArrayInt::New();
6172   ret->useArray(tab,true,CPP_DEALLOC,getNumberOfTuples(),getNumberOfComponents());
6173   return ret;
6174 }
6175
6176 /*!
6177  * Returns a new DataArrayInt holding the same values as \a this array but differently
6178  * arranged in memory. If \a this array holds 2 components of 3 values:
6179  * \f$ x_0,y_0,x_1,y_1,x_2,y_2 \f$, then the result array holds these values arranged
6180  * as follows: \f$ x_0,x_1,x_2,y_0,y_1,y_2 \f$.
6181  *  \warning Do not confuse this method with transpose()!
6182  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
6183  *          is to delete using decrRef() as it is no more needed.
6184  *  \throw If \a this is not allocated.
6185  */
6186 DataArrayInt *DataArrayInt::toNoInterlace() const throw(INTERP_KERNEL::Exception)
6187 {
6188   checkAllocated();
6189   if(_mem.isNull())
6190     throw INTERP_KERNEL::Exception("DataArrayInt::toNoInterlace : Not defined array !");
6191   int *tab=_mem.toNoInterlace(getNumberOfComponents());
6192   DataArrayInt *ret=DataArrayInt::New();
6193   ret->useArray(tab,true,CPP_DEALLOC,getNumberOfTuples(),getNumberOfComponents());
6194   return ret;
6195 }
6196
6197 /*!
6198  * Permutes values of \a this array as required by \a old2New array. The values are
6199  * permuted so that \c new[ \a old2New[ i ]] = \c old[ i ]. Number of tuples remains
6200  * the same as in \this one.
6201  * If a permutation reduction is needed, substr() or selectByTupleId() should be used.
6202  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
6203  *  \param [in] old2New - C array of length equal to \a this->getNumberOfTuples()
6204  *     giving a new position for i-th old value.
6205  */
6206 void DataArrayInt::renumberInPlace(const int *old2New) throw(INTERP_KERNEL::Exception)
6207 {
6208   checkAllocated();
6209   int nbTuples=getNumberOfTuples();
6210   int nbOfCompo=getNumberOfComponents();
6211   int *tmp=new int[nbTuples*nbOfCompo];
6212   const int *iptr=getConstPointer();
6213   for(int i=0;i<nbTuples;i++)
6214     std::copy(iptr+nbOfCompo*i,iptr+nbOfCompo*(i+1),tmp+nbOfCompo*old2New[i]);
6215   std::copy(tmp,tmp+nbTuples*nbOfCompo,getPointer());
6216   delete [] tmp;
6217   declareAsNew();
6218 }
6219
6220 /*!
6221  * Permutes values of \a this array as required by \a new2Old array. The values are
6222  * permuted so that \c new[ i ] = \c old[ \a new2Old[ i ]]. Number of tuples remains
6223  * the same as in \this one.
6224  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
6225  *  \param [in] new2Old - C array of length equal to \a this->getNumberOfTuples()
6226  *     giving a previous position of i-th new value.
6227  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
6228  *          is to delete using decrRef() as it is no more needed.
6229  */
6230 void DataArrayInt::renumberInPlaceR(const int *new2Old) throw(INTERP_KERNEL::Exception)
6231 {
6232   checkAllocated();
6233   int nbTuples=getNumberOfTuples();
6234   int nbOfCompo=getNumberOfComponents();
6235   int *tmp=new int[nbTuples*nbOfCompo];
6236   const int *iptr=getConstPointer();
6237   for(int i=0;i<nbTuples;i++)
6238     std::copy(iptr+nbOfCompo*new2Old[i],iptr+nbOfCompo*(new2Old[i]+1),tmp+nbOfCompo*i);
6239   std::copy(tmp,tmp+nbTuples*nbOfCompo,getPointer());
6240   delete [] tmp;
6241   declareAsNew();
6242 }
6243
6244 /*!
6245  * Returns a copy of \a this array with values permuted as required by \a old2New array.
6246  * The values are permuted so that  \c new[ \a old2New[ i ]] = \c old[ i ].
6247  * Number of tuples in the result array remains the same as in \this one.
6248  * If a permutation reduction is needed, renumberAndReduce() should be used.
6249  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
6250  *  \param [in] old2New - C array of length equal to \a this->getNumberOfTuples()
6251  *          giving a new position for i-th old value.
6252  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
6253  *          is to delete using decrRef() as it is no more needed.
6254  *  \throw If \a this is not allocated.
6255  */
6256 DataArrayInt *DataArrayInt::renumber(const int *old2New) const throw(INTERP_KERNEL::Exception)
6257 {
6258   checkAllocated();
6259   int nbTuples=getNumberOfTuples();
6260   int nbOfCompo=getNumberOfComponents();
6261   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6262   ret->alloc(nbTuples,nbOfCompo);
6263   ret->copyStringInfoFrom(*this);
6264   const int *iptr=getConstPointer();
6265   int *optr=ret->getPointer();
6266   for(int i=0;i<nbTuples;i++)
6267     std::copy(iptr+nbOfCompo*i,iptr+nbOfCompo*(i+1),optr+nbOfCompo*old2New[i]);
6268   ret->copyStringInfoFrom(*this);
6269   return ret.retn();
6270 }
6271
6272 /*!
6273  * Returns a copy of \a this array with values permuted as required by \a new2Old array.
6274  * The values are permuted so that  \c new[ i ] = \c old[ \a new2Old[ i ]]. Number of
6275  * tuples in the result array remains the same as in \this one.
6276  * If a permutation reduction is needed, substr() or selectByTupleId() should be used.
6277  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
6278  *  \param [in] new2Old - C array of length equal to \a this->getNumberOfTuples()
6279  *     giving a previous position of i-th new value.
6280  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
6281  *          is to delete using decrRef() as it is no more needed.
6282  */
6283 DataArrayInt *DataArrayInt::renumberR(const int *new2Old) const throw(INTERP_KERNEL::Exception)
6284 {
6285   checkAllocated();
6286   int nbTuples=getNumberOfTuples();
6287   int nbOfCompo=getNumberOfComponents();
6288   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6289   ret->alloc(nbTuples,nbOfCompo);
6290   ret->copyStringInfoFrom(*this);
6291   const int *iptr=getConstPointer();
6292   int *optr=ret->getPointer();
6293   for(int i=0;i<nbTuples;i++)
6294     std::copy(iptr+nbOfCompo*new2Old[i],iptr+nbOfCompo*(new2Old[i]+1),optr+nbOfCompo*i);
6295   ret->copyStringInfoFrom(*this);
6296   return ret.retn();
6297 }
6298
6299 /*!
6300  * Returns a shorten and permuted copy of \a this array. The new DataArrayInt is
6301  * of size \a newNbOfTuple and it's values are permuted as required by \a old2New array.
6302  * The values are permuted so that  \c new[ \a old2New[ i ]] = \c old[ i ] for all
6303  * \a old2New[ i ] >= 0. In other words every i-th tuple in \a this array, for which 
6304  * \a old2New[ i ] is negative, is missing from the result array.
6305  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
6306  *  \param [in] old2New - C array of length equal to \a this->getNumberOfTuples()
6307  *     giving a new position for i-th old tuple and giving negative position for
6308  *     for i-th old tuple that should be omitted.
6309  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
6310  *          is to delete using decrRef() as it is no more needed.
6311  */
6312 DataArrayInt *DataArrayInt::renumberAndReduce(const int *old2New, int newNbOfTuple) const throw(INTERP_KERNEL::Exception)
6313 {
6314   checkAllocated();
6315   int nbTuples=getNumberOfTuples();
6316   int nbOfCompo=getNumberOfComponents();
6317   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6318   ret->alloc(newNbOfTuple,nbOfCompo);
6319   const int *iptr=getConstPointer();
6320   int *optr=ret->getPointer();
6321   for(int i=0;i<nbTuples;i++)
6322     {
6323       int w=old2New[i];
6324       if(w>=0)
6325         std::copy(iptr+i*nbOfCompo,iptr+(i+1)*nbOfCompo,optr+w*nbOfCompo);
6326     }
6327   ret->copyStringInfoFrom(*this);
6328   return ret.retn();
6329 }
6330
6331 /*!
6332  * Returns a shorten and permuted copy of \a this array. The new DataArrayInt is
6333  * of size \a new2OldEnd - \a new2OldBg and it's values are permuted as required by
6334  * \a new2OldBg array.
6335  * The values are permuted so that  \c new[ i ] = \c old[ \a new2OldBg[ i ]].
6336  * This method is equivalent to renumberAndReduce() except that convention in input is
6337  * \c new2old and \b not \c old2new.
6338  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
6339  *  \param [in] new2OldBg - pointer to the beginning of a permutation array that gives a
6340  *              tuple index in \a this array to fill the i-th tuple in the new array.
6341  *  \param [in] new2OldEnd - specifies the end of the permutation array that starts at
6342  *              \a new2OldBg, so that pointer to a tuple index (\a pi) varies as this:
6343  *              \a new2OldBg <= \a pi < \a new2OldEnd.
6344  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
6345  *          is to delete using decrRef() as it is no more needed.
6346  */
6347 DataArrayInt *DataArrayInt::selectByTupleId(const int *new2OldBg, const int *new2OldEnd) const
6348 {
6349   checkAllocated();
6350   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6351   int nbComp=getNumberOfComponents();
6352   ret->alloc((int)std::distance(new2OldBg,new2OldEnd),nbComp);
6353   ret->copyStringInfoFrom(*this);
6354   int *pt=ret->getPointer();
6355   const int *srcPt=getConstPointer();
6356   int i=0;
6357   for(const int *w=new2OldBg;w!=new2OldEnd;w++,i++)
6358     std::copy(srcPt+(*w)*nbComp,srcPt+((*w)+1)*nbComp,pt+i*nbComp);
6359   ret->copyStringInfoFrom(*this);
6360   return ret.retn();
6361 }
6362
6363 /*!
6364  * Returns a shorten and permuted copy of \a this array. The new DataArrayInt is
6365  * of size \a new2OldEnd - \a new2OldBg and it's values are permuted as required by
6366  * \a new2OldBg array.
6367  * The values are permuted so that  \c new[ i ] = \c old[ \a new2OldBg[ i ]].
6368  * This method is equivalent to renumberAndReduce() except that convention in input is
6369  * \c new2old and \b not \c old2new.
6370  * This method is equivalent to selectByTupleId() except that it prevents coping data
6371  * from behind the end of \a this array.
6372  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
6373  *  \param [in] new2OldBg - pointer to the beginning of a permutation array that gives a
6374  *              tuple index in \a this array to fill the i-th tuple in the new array.
6375  *  \param [in] new2OldEnd - specifies the end of the permutation array that starts at
6376  *              \a new2OldBg, so that pointer to a tuple index (\a pi) varies as this:
6377  *              \a new2OldBg <= \a pi < \a new2OldEnd.
6378  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
6379  *          is to delete using decrRef() as it is no more needed.
6380  *  \throw If \a new2OldEnd - \a new2OldBg > \a this->getNumberOfTuples().
6381  */
6382 DataArrayInt *DataArrayInt::selectByTupleIdSafe(const int *new2OldBg, const int *new2OldEnd) const throw(INTERP_KERNEL::Exception)
6383 {
6384   checkAllocated();
6385   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6386   int nbComp=getNumberOfComponents();
6387   int oldNbOfTuples=getNumberOfTuples();
6388   ret->alloc((int)std::distance(new2OldBg,new2OldEnd),nbComp);
6389   ret->copyStringInfoFrom(*this);
6390   int *pt=ret->getPointer();
6391   const int *srcPt=getConstPointer();
6392   int i=0;
6393   for(const int *w=new2OldBg;w!=new2OldEnd;w++,i++)
6394     if(*w>=0 && *w<oldNbOfTuples)
6395       std::copy(srcPt+(*w)*nbComp,srcPt+((*w)+1)*nbComp,pt+i*nbComp);
6396     else
6397       throw INTERP_KERNEL::Exception("DataArrayInt::selectByTupleIdSafe : some ids has been detected to be out of [0,this->getNumberOfTuples) !");
6398   ret->copyStringInfoFrom(*this);
6399   return ret.retn();
6400 }
6401
6402 /*!
6403  * Returns a shorten copy of \a this array. The new DataArrayInt contains every
6404  * (\a bg + \c i * \a step)-th tuple of \a this array located before the \a end2-th
6405  * tuple. Indices of the selected tuples are the same as ones returned by the Python
6406  * command \c range( \a bg, \a end2, \a step ).
6407  * This method is equivalent to selectByTupleIdSafe() except that the input array is
6408  * not constructed explicitly.
6409  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
6410  *  \param [in] bg - index of the first tuple to copy from \a this array.
6411  *  \param [in] end2 - index of the tuple before which the tuples to copy are located.
6412  *  \param [in] step - index increment to get index of the next tuple to copy.
6413  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
6414  *          is to delete using decrRef() as it is no more needed.
6415  *  \sa DataArrayInt::substr.
6416  */
6417 DataArrayInt *DataArrayInt::selectByTupleId2(int bg, int end2, int step) const throw(INTERP_KERNEL::Exception)
6418 {
6419   checkAllocated();
6420   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6421   int nbComp=getNumberOfComponents();
6422   int newNbOfTuples=GetNumberOfItemGivenBESRelative(bg,end2,step,"DataArrayInt::selectByTupleId2 : ");
6423   ret->alloc(newNbOfTuples,nbComp);
6424   int *pt=ret->getPointer();
6425   const int *srcPt=getConstPointer()+bg*nbComp;
6426   for(int i=0;i<newNbOfTuples;i++,srcPt+=step*nbComp)
6427     std::copy(srcPt,srcPt+nbComp,pt+i*nbComp);
6428   ret->copyStringInfoFrom(*this);
6429   return ret.retn();
6430 }
6431
6432 /*!
6433  * Returns a shorten copy of \a this array. The new DataArrayInt contains ranges
6434  * of tuples specified by \a ranges parameter.
6435  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
6436  *  \param [in] ranges - std::vector of std::pair's each of which defines a range
6437  *              of tuples in [\c begin,\c end) format.
6438  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
6439  *          is to delete using decrRef() as it is no more needed.
6440  *  \throw If \a end < \a begin.
6441  *  \throw If \a end > \a this->getNumberOfTuples().
6442  *  \throw If \a this is not allocated.
6443  */
6444 DataArrayInt *DataArrayInt::selectByTupleRanges(const std::vector<std::pair<int,int> >& ranges) const throw(INTERP_KERNEL::Exception)
6445 {
6446   checkAllocated();
6447   int nbOfComp=getNumberOfComponents();
6448   int nbOfTuplesThis=getNumberOfTuples();
6449   if(ranges.empty())
6450     {
6451       MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6452       ret->alloc(0,nbOfComp);
6453       ret->copyStringInfoFrom(*this);
6454       return ret.retn();
6455     }
6456   int ref=ranges.front().first;
6457   int nbOfTuples=0;
6458   bool isIncreasing=true;
6459   for(std::vector<std::pair<int,int> >::const_iterator it=ranges.begin();it!=ranges.end();it++)
6460     {
6461       if((*it).first<=(*it).second)
6462         {
6463           if((*it).first>=0 && (*it).second<=nbOfTuplesThis)
6464             {
6465               nbOfTuples+=(*it).second-(*it).first;
6466               if(isIncreasing)
6467                 isIncreasing=ref<=(*it).first;
6468               ref=(*it).second;
6469             }
6470           else
6471             {
6472               std::ostringstream oss; oss << "DataArrayInt::selectByTupleRanges : on range #" << std::distance(ranges.begin(),it);
6473               oss << " (" << (*it).first << "," << (*it).second << ") is greater than number of tuples of this :" << nbOfTuples << " !";
6474               throw INTERP_KERNEL::Exception(oss.str().c_str());
6475             }
6476         }
6477       else
6478         {
6479           std::ostringstream oss; oss << "DataArrayInt::selectByTupleRanges : on range #" << std::distance(ranges.begin(),it);
6480           oss << " (" << (*it).first << "," << (*it).second << ") end is before begin !";
6481           throw INTERP_KERNEL::Exception(oss.str().c_str());
6482         }
6483     }
6484   if(isIncreasing && nbOfTuplesThis==nbOfTuples)
6485     return deepCpy();
6486   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6487   ret->alloc(nbOfTuples,nbOfComp);
6488   ret->copyStringInfoFrom(*this);
6489   const int *src=getConstPointer();
6490   int *work=ret->getPointer();
6491   for(std::vector<std::pair<int,int> >::const_iterator it=ranges.begin();it!=ranges.end();it++)
6492     work=std::copy(src+(*it).first*nbOfComp,src+(*it).second*nbOfComp,work);
6493   return ret.retn();
6494 }
6495
6496 /*!
6497  * Returns a new DataArrayInt containing a renumbering map in "Old to New" mode.
6498  * This map, if applied to \a this array, would make it sorted. For example, if
6499  * \a this array contents are [9,10,0,6,4,11,3,7] then the contents of the result array
6500  * are [5,6,0,3,2,7,1,4]; if this result array (\a res) is used as an argument in call
6501  * \a this->renumber(\a res) then the returned array contains [0,3,4,6,7,9,10,11].
6502  * This method is useful for renumbering (in MED file for example). For more info
6503  * on renumbering see \ref MEDCouplingArrayRenumbering.
6504  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
6505  *          array using decrRef() as it is no more needed.
6506  *  \throw If \a this is not allocated.
6507  *  \throw If \a this->getNumberOfComponents() != 1.
6508  *  \throw If there are equal values in \a this array.
6509  */
6510 DataArrayInt *DataArrayInt::checkAndPreparePermutation() const throw(INTERP_KERNEL::Exception)
6511 {
6512   checkAllocated();
6513   if(getNumberOfComponents()!=1)
6514     throw INTERP_KERNEL::Exception("DataArrayInt::checkAndPreparePermutation : number of components must == 1 !");
6515   int nbTuples=getNumberOfTuples();
6516   const int *pt=getConstPointer();
6517   int *pt2=CheckAndPreparePermutation(pt,pt+nbTuples);
6518   DataArrayInt *ret=DataArrayInt::New();
6519   ret->useArray(pt2,true,CPP_DEALLOC,nbTuples,1);
6520   return ret;
6521 }
6522
6523 /*!
6524  * Returns two arrays describing a surjective mapping from \a this set of values (\a A)
6525  * onto a set of values of size \a targetNb (\a B). The surjective function is 
6526  * \a B[ \a A[ i ]] = i. That is to say that for each \a id in [0,\a targetNb), where \a
6527  * targetNb < \a this->getNumberOfTuples(), there exists at least one tupleId (\a tid) so
6528  * that <em> this->getIJ( tid, 0 ) == id</em>. <br>
6529  * The first of out arrays returns indices of elements of \a this array, grouped by their
6530  * place in the set \a B. The second out array is the index of the first one; it shows how
6531  * many elements of \a A are mapped into each element of \a B. <br>
6532  * For more info on
6533  * mapping and its usage in renumbering see \ref MEDCouplingArrayRenumbering. <br>
6534  * \b Example:
6535  * - \a this: [0,3,2,3,2,2,1,2]
6536  * - \a targetNb: 4
6537  * - \a arr:  [0,  6,  2,4,5,7,  1,3]
6538  * - \a arrI: [0,1,2,6,8]
6539  *
6540  * This result means: <br>
6541  * the element of \a B 0 encounters within \a A once (\a arrI[ 0+1 ] - \a arrI[ 0 ]) and
6542  * its index within \a A is 0 ( \a arr[ 0:1 ] == \a arr[ \a arrI[ 0 ] : \a arrI[ 0+1 ]]);<br>
6543  * the element of \a B 2 encounters within \a A 4 times (\a arrI[ 2+1 ] - \a arrI[ 2 ]) and
6544  * its indices within \a A are [2,4,5,7] ( \a arr[ 2:6 ] == \a arr[ \a arrI[ 2 ] : 
6545  * \a arrI[ 2+1 ]]); <br> etc.
6546  *  \param [in] targetNb - the size of the set \a B. \a targetNb must be equal or more
6547  *         than the maximal value of \a A.
6548  *  \param [out] arr - a new instance of DataArrayInt returning indices of
6549  *         elements of \a this, grouped by their place in the set \a B. The caller is to delete
6550  *         this array using decrRef() as it is no more needed.
6551  *  \param [out] arrI - a new instance of DataArrayInt returning size of groups of equal
6552  *         elements of \a this. The caller is to delete this array using decrRef() as it
6553  *         is no more needed.
6554  *  \throw If \a this is not allocated.
6555  *  \throw If \a this->getNumberOfComponents() != 1.
6556  *  \throw If any value in \a this is more or equal to \a targetNb.
6557  */
6558 void DataArrayInt::changeSurjectiveFormat(int targetNb, DataArrayInt *&arr, DataArrayInt *&arrI) const throw(INTERP_KERNEL::Exception)
6559 {
6560   checkAllocated();
6561   if(getNumberOfComponents()!=1)
6562     throw INTERP_KERNEL::Exception("DataArrayInt::changeSurjectiveFormat : number of components must == 1 !");
6563   int nbOfTuples=getNumberOfTuples();
6564   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New());
6565   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> retI(DataArrayInt::New());
6566   retI->alloc(targetNb+1,1);
6567   const int *input=getConstPointer();
6568   std::vector< std::vector<int> > tmp(targetNb);
6569   for(int i=0;i<nbOfTuples;i++)
6570     {
6571       int tmp2=input[i];
6572       if(tmp2>=0 && tmp2<targetNb)
6573         tmp[tmp2].push_back(i);
6574       else
6575         {
6576           std::ostringstream oss; oss << "DataArrayInt::changeSurjectiveFormat : At pos " << i << " presence of element " << tmp2 << " ! should be in [0," << targetNb << ") !";
6577           throw INTERP_KERNEL::Exception(oss.str().c_str());
6578         }
6579     }
6580   int *retIPtr=retI->getPointer();
6581   *retIPtr=0;
6582   for(std::vector< std::vector<int> >::const_iterator it1=tmp.begin();it1!=tmp.end();it1++,retIPtr++)
6583     retIPtr[1]=retIPtr[0]+(int)((*it1).size());
6584   if(nbOfTuples!=retI->getIJ(targetNb,0))
6585     throw INTERP_KERNEL::Exception("DataArrayInt::changeSurjectiveFormat : big problem should never happen !");
6586   ret->alloc(nbOfTuples,1);
6587   int *retPtr=ret->getPointer();
6588   for(std::vector< std::vector<int> >::const_iterator it1=tmp.begin();it1!=tmp.end();it1++)
6589     retPtr=std::copy((*it1).begin(),(*it1).end(),retPtr);
6590   arr=ret.retn();
6591   arrI=retI.retn();
6592 }
6593
6594
6595 /*!
6596  * Returns a new DataArrayInt containing a renumbering map in "Old to New" mode computed
6597  * from a zip representation of a surjective format (returned e.g. by
6598  * \ref ParaMEDMEM::DataArrayDouble::findCommonTuples() "DataArrayDouble::findCommonTuples()"
6599  * for example). The result array minimizes the permutation. <br>
6600  * For more info on renumbering see \ref MEDCouplingArrayRenumbering. <br>
6601  * \b Example: <br>
6602  * - \a nbOfOldTuples: 10 
6603  * - \a arr          : [0,3, 5,7,9]
6604  * - \a arrIBg       : [0,2,5]
6605  * - \a newNbOfTuples: 7
6606  * - result array    : [0,1,2,0,3,4,5,4,6,4]
6607  *
6608  *  \param [in] nbOfOldTuples - number of tuples in the initial array \a arr.
6609  *  \param [in] arr - the array of tuple indices grouped by \a arrIBg array.
6610  *  \param [in] arrIBg - the array dividing all indices stored in \a arr into groups of
6611  *         (indices of) equal values. Its every element (except the last one) points to
6612  *         the first element of a group of equal values.
6613  *  \param [in] arrIEnd - specifies the end of \a arrIBg, so that the last element of \a
6614  *          arrIBg is \a arrIEnd[ -1 ].
6615  *  \param [out] newNbOfTuples - number of tuples after surjection application.
6616  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
6617  *          array using decrRef() as it is no more needed.
6618  *  \throw If any value of \a arr breaks condition ( 0 <= \a arr[ i ] < \a nbOfOldTuples ).
6619  */
6620 DataArrayInt *DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2(int nbOfOldTuples, const int *arr, const int *arrIBg, const int *arrIEnd, int &newNbOfTuples) throw(INTERP_KERNEL::Exception)
6621 {
6622   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6623   ret->alloc(nbOfOldTuples,1);
6624   int *pt=ret->getPointer();
6625   std::fill(pt,pt+nbOfOldTuples,-1);
6626   int nbOfGrps=((int)std::distance(arrIBg,arrIEnd))-1;
6627   const int *cIPtr=arrIBg;
6628   for(int i=0;i<nbOfGrps;i++)
6629     pt[arr[cIPtr[i]]]=-(i+2);
6630   int newNb=0;
6631   for(int iNode=0;iNode<nbOfOldTuples;iNode++)
6632     {
6633       if(pt[iNode]<0)
6634         {
6635           if(pt[iNode]==-1)
6636             pt[iNode]=newNb++;
6637           else
6638             {
6639               int grpId=-(pt[iNode]+2);
6640               for(int j=cIPtr[grpId];j<cIPtr[grpId+1];j++)
6641                 {
6642                   if(arr[j]>=0 && arr[j]<nbOfOldTuples)
6643                     pt[arr[j]]=newNb;
6644                   else
6645                     {
6646                       std::ostringstream oss; oss << "DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2 : With element #" << j << " value is " << arr[j] << " should be in [0," << nbOfOldTuples << ") !";
6647                       throw INTERP_KERNEL::Exception(oss.str().c_str());
6648                     }
6649                 }
6650               newNb++;
6651             }
6652         }
6653     }
6654   newNbOfTuples=newNb;
6655   return ret.retn();
6656 }
6657
6658 /*!
6659  * Returns a new DataArrayInt containing a renumbering map in "New to Old" mode,
6660  * which if applied to \a this array would make it sorted ascendingly.
6661  * For more info on renumbering see \ref MEDCouplingArrayRenumbering. <br>
6662  * \b Example: <br>
6663  * - \a this: [2,0,1,1,0,1,2,0,1,1,0,0]
6664  * - result: [10,0,5,6,1,7,11,2,8,9,3,4]
6665  * - after applying result to \a this: [0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2] 
6666  *
6667  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
6668  *          array using decrRef() as it is no more needed.
6669  *  \throw If \a this is not allocated.
6670  *  \throw If \a this->getNumberOfComponents() != 1.
6671  */
6672 DataArrayInt *DataArrayInt::buildPermArrPerLevel() const throw(INTERP_KERNEL::Exception)
6673 {
6674   checkAllocated();
6675   if(getNumberOfComponents()!=1)
6676     throw INTERP_KERNEL::Exception("DataArrayInt::buildPermArrPerLevel : number of components must == 1 !");
6677   int nbOfTuples=getNumberOfTuples();
6678   const int *pt=getConstPointer();
6679   std::map<int,int> m;
6680   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6681   ret->alloc(nbOfTuples,1);
6682   int *opt=ret->getPointer();
6683   for(int i=0;i<nbOfTuples;i++,pt++,opt++)
6684     {
6685       int val=*pt;
6686       std::map<int,int>::iterator it=m.find(val);
6687       if(it!=m.end())
6688         {
6689           *opt=(*it).second;
6690           (*it).second++;
6691         }
6692       else
6693         {
6694           *opt=0;
6695           m.insert(std::pair<int,int>(val,1));
6696         }
6697     }
6698   int sum=0;
6699   for(std::map<int,int>::iterator it=m.begin();it!=m.end();it++)
6700     {
6701       int vt=(*it).second;
6702       (*it).second=sum;
6703       sum+=vt;
6704     }
6705   pt=getConstPointer();
6706   opt=ret->getPointer();
6707   for(int i=0;i<nbOfTuples;i++,pt++,opt++)
6708     *opt+=m[*pt];
6709   //
6710   return ret.retn();
6711 }
6712
6713 /*!
6714  * Checks if contents of \a this array are equal to that of an array filled with
6715  * iota(). This method is particularly useful for DataArrayInt instances that represent
6716  * a renumbering array to check the real need in renumbering. 
6717  *  \return bool - \a true if \a this array contents == \a range( \a this->getNumberOfTuples())
6718  *  \throw If \a this is not allocated.
6719  *  \throw If \a this->getNumberOfComponents() != 1.
6720  */
6721 bool DataArrayInt::isIdentity() const throw(INTERP_KERNEL::Exception)
6722 {
6723   checkAllocated();
6724   if(getNumberOfComponents()!=1)
6725     return false;
6726   int nbOfTuples=getNumberOfTuples();
6727   const int *pt=getConstPointer();
6728   for(int i=0;i<nbOfTuples;i++,pt++)
6729     if(*pt!=i)
6730       return false;
6731   return true;
6732 }
6733
6734 /*!
6735  * Checks if all values in \a this array are equal to \a val.
6736  *  \param [in] val - value to check equality of array values to.
6737  *  \return bool - \a true if all values are \a val.
6738  *  \throw If \a this is not allocated.
6739  *  \throw If \a this->getNumberOfComponents() != 1
6740  */
6741 bool DataArrayInt::isUniform(int val) const throw(INTERP_KERNEL::Exception)
6742 {
6743   checkAllocated();
6744   if(getNumberOfComponents()!=1)
6745     throw INTERP_KERNEL::Exception("DataArrayInt::isUniform : must be applied on DataArrayInt with only one component, you can call 'rearrange' method before !");
6746   int nbOfTuples=getNumberOfTuples();
6747   const int *w=getConstPointer();
6748   const int *end2=w+nbOfTuples;
6749   for(;w!=end2;w++)
6750     if(*w!=val)
6751       return false;
6752   return true;
6753 }
6754
6755 /*!
6756  * Creates a new DataArrayDouble and assigns all (textual and numerical) data of \a this
6757  * array to the new one.
6758  *  \return DataArrayDouble * - the new instance of DataArrayInt.
6759  */
6760 DataArrayDouble *DataArrayInt::convertToDblArr() const
6761 {
6762   checkAllocated();
6763   DataArrayDouble *ret=DataArrayDouble::New();
6764   ret->alloc(getNumberOfTuples(),getNumberOfComponents());
6765   std::size_t nbOfVals=getNbOfElems();
6766   const int *src=getConstPointer();
6767   double *dest=ret->getPointer();
6768   std::copy(src,src+nbOfVals,dest);
6769   ret->copyStringInfoFrom(*this);
6770   return ret;
6771 }
6772
6773 /*!
6774  * Returns a shorten copy of \a this array. The new DataArrayInt contains all
6775  * tuples starting from the \a tupleIdBg-th tuple and including all tuples located before
6776  * the \a tupleIdEnd-th one. This methods has a similar behavior as std::string::substr().
6777  * This method is a specialization of selectByTupleId2().
6778  *  \param [in] tupleIdBg - index of the first tuple to copy from \a this array.
6779  *  \param [in] tupleIdEnd - index of the tuple before which the tuples to copy are located.
6780  *          If \a tupleIdEnd == -1, all the tuples till the end of \a this array are copied.
6781  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
6782  *          is to delete using decrRef() as it is no more needed.
6783  *  \throw If \a tupleIdBg < 0.
6784  *  \throw If \a tupleIdBg > \a this->getNumberOfTuples().
6785     \throw If \a tupleIdEnd != -1 && \a tupleIdEnd < \a this->getNumberOfTuples().
6786  *  \sa DataArrayInt::selectByTupleId2
6787  */
6788 DataArrayInt *DataArrayInt::substr(int tupleIdBg, int tupleIdEnd) const throw(INTERP_KERNEL::Exception)
6789 {
6790   checkAllocated();
6791   int nbt=getNumberOfTuples();
6792   if(tupleIdBg<0)
6793     throw INTERP_KERNEL::Exception("DataArrayInt::substr : The tupleIdBg parameter must be greater than 0 !");
6794   if(tupleIdBg>nbt)
6795     throw INTERP_KERNEL::Exception("DataArrayInt::substr : The tupleIdBg parameter is greater than number of tuples !");
6796   int trueEnd=tupleIdEnd;
6797   if(tupleIdEnd!=-1)
6798     {
6799       if(tupleIdEnd>nbt)
6800         throw INTERP_KERNEL::Exception("DataArrayInt::substr : The tupleIdBg parameter is greater or equal than number of tuples !");
6801     }
6802   else
6803     trueEnd=nbt;
6804   int nbComp=getNumberOfComponents();
6805   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6806   ret->alloc(trueEnd-tupleIdBg,nbComp);
6807   ret->copyStringInfoFrom(*this);
6808   std::copy(getConstPointer()+tupleIdBg*nbComp,getConstPointer()+trueEnd*nbComp,ret->getPointer());
6809   return ret.retn();
6810 }
6811
6812 /*!
6813  * Changes the number of components within \a this array so that its raw data **does
6814  * not** change, instead splitting this data into tuples changes.
6815  *  \warning This method erases all (name and unit) component info set before!
6816  *  \param [in] newNbOfComp - number of components for \a this array to have.
6817  *  \throw If \a this is not allocated
6818  *  \throw If getNbOfElems() % \a newNbOfCompo != 0.
6819  *  \throw If \a newNbOfCompo is lower than 1.
6820  *  \throw If the rearrange method would lead to a number of tuples higher than 2147483647 (maximal capacity of int32 !).
6821  *  \warning This method erases all (name and unit) component info set before!
6822  */
6823 void DataArrayInt::rearrange(int newNbOfCompo) throw(INTERP_KERNEL::Exception)
6824 {
6825   checkAllocated();
6826   if(newNbOfCompo<1)
6827     throw INTERP_KERNEL::Exception("DataArrayInt::rearrange : input newNbOfCompo must be > 0 !");
6828   std::size_t nbOfElems=getNbOfElems();
6829   if(nbOfElems%newNbOfCompo!=0)
6830     throw INTERP_KERNEL::Exception("DataArrayInt::rearrange : nbOfElems%newNbOfCompo!=0 !");
6831   if(nbOfElems/newNbOfCompo>(std::size_t)std::numeric_limits<int>::max())
6832     throw INTERP_KERNEL::Exception("DataArrayInt::rearrange : the rearrangement leads to too high number of tuples (> 2147483647) !");
6833   _info_on_compo.clear();
6834   _info_on_compo.resize(newNbOfCompo);
6835   declareAsNew();
6836 }
6837
6838 /*!
6839  * Changes the number of components within \a this array to be equal to its number
6840  * of tuples, and inversely its number of tuples to become equal to its number of 
6841  * components. So that its raw data **does not** change, instead splitting this
6842  * data into tuples changes.
6843  *  \warning This method erases all (name and unit) component info set before!
6844  *  \warning Do not confuse this method with fromNoInterlace() and toNoInterlace()!
6845  *  \throw If \a this is not allocated.
6846  *  \sa rearrange()
6847  */
6848 void DataArrayInt::transpose() throw(INTERP_KERNEL::Exception)
6849 {
6850   checkAllocated();
6851   int nbOfTuples=getNumberOfTuples();
6852   rearrange(nbOfTuples);
6853 }
6854
6855 /*!
6856  * Returns a shorten or extended copy of \a this array. If \a newNbOfComp is less
6857  * than \a this->getNumberOfComponents() then the result array is shorten as each tuple
6858  * is truncated to have \a newNbOfComp components, keeping first components. If \a
6859  * newNbOfComp is more than \a this->getNumberOfComponents() then the result array is
6860  * expanded as each tuple is populated with \a dftValue to have \a newNbOfComp
6861  * components.  
6862  *  \param [in] newNbOfComp - number of components for the new array to have.
6863  *  \param [in] dftValue - value assigned to new values added to the new array.
6864  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
6865  *          is to delete using decrRef() as it is no more needed.
6866  *  \throw If \a this is not allocated.
6867  */
6868 DataArrayInt *DataArrayInt::changeNbOfComponents(int newNbOfComp, int dftValue) const throw(INTERP_KERNEL::Exception)
6869 {
6870   checkAllocated();
6871   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6872   ret->alloc(getNumberOfTuples(),newNbOfComp);
6873   const int *oldc=getConstPointer();
6874   int *nc=ret->getPointer();
6875   int nbOfTuples=getNumberOfTuples();
6876   int oldNbOfComp=getNumberOfComponents();
6877   int dim=std::min(oldNbOfComp,newNbOfComp);
6878   for(int i=0;i<nbOfTuples;i++)
6879     {
6880       int j=0;
6881       for(;j<dim;j++)
6882         nc[newNbOfComp*i+j]=oldc[i*oldNbOfComp+j];
6883       for(;j<newNbOfComp;j++)
6884         nc[newNbOfComp*i+j]=dftValue;
6885     }
6886   ret->setName(getName().c_str());
6887   for(int i=0;i<dim;i++)
6888     ret->setInfoOnComponent(i,getInfoOnComponent(i).c_str());
6889   ret->setName(getName().c_str());
6890   return ret.retn();
6891 }
6892
6893 /*!
6894  * Changes number of tuples in the array. If the new number of tuples is smaller
6895  * than the current number the array is truncated, otherwise the array is extended.
6896  *  \param [in] nbOfTuples - new number of tuples. 
6897  *  \throw If \a this is not allocated.
6898  */
6899 void DataArrayInt::reAlloc(int nbOfTuples) throw(INTERP_KERNEL::Exception)
6900 {
6901   checkAllocated();
6902   _mem.reAlloc(getNumberOfComponents()*(std::size_t)nbOfTuples);
6903   declareAsNew();
6904 }
6905
6906
6907 /*!
6908  * Returns a copy of \a this array composed of selected components.
6909  * The new DataArrayInt has the same number of tuples but includes components
6910  * specified by \a compoIds parameter. So that getNbOfElems() of the result array
6911  * can be either less, same or more than \a this->getNbOfElems().
6912  *  \param [in] compoIds - sequence of zero based indices of components to include
6913  *              into the new array.
6914  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
6915  *          is to delete using decrRef() as it is no more needed.
6916  *  \throw If \a this is not allocated.
6917  *  \throw If a component index (\a i) is not valid: 
6918  *         \a i < 0 || \a i >= \a this->getNumberOfComponents().
6919  *
6920  *  \ref cpp_mcdataarrayint_keepselectedcomponents "Here is a Python example".
6921  */
6922 DataArrayInt *DataArrayInt::keepSelectedComponents(const std::vector<int>& compoIds) const throw(INTERP_KERNEL::Exception)
6923 {
6924   checkAllocated();
6925   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New());
6926   int newNbOfCompo=(int)compoIds.size();
6927   int oldNbOfCompo=getNumberOfComponents();
6928   for(std::vector<int>::const_iterator it=compoIds.begin();it!=compoIds.end();it++)
6929     DataArray::CheckValueInRange(oldNbOfCompo,(*it),"keepSelectedComponents invalid requested component");
6930   int nbOfTuples=getNumberOfTuples();
6931   ret->alloc(nbOfTuples,newNbOfCompo);
6932   ret->copyPartOfStringInfoFrom(*this,compoIds);
6933   const int *oldc=getConstPointer();
6934   int *nc=ret->getPointer();
6935   for(int i=0;i<nbOfTuples;i++)
6936     for(int j=0;j<newNbOfCompo;j++,nc++)
6937       *nc=oldc[i*oldNbOfCompo+compoIds[j]];
6938   return ret.retn();
6939 }
6940
6941 /*!
6942  * Appends components of another array to components of \a this one, tuple by tuple.
6943  * So that the number of tuples of \a this array remains the same and the number of 
6944  * components increases.
6945  *  \param [in] other - the DataArrayInt to append to \a this one.
6946  *  \throw If \a this is not allocated.
6947  *  \throw If \a this and \a other arrays have different number of tuples.
6948  *
6949  *  \ref cpp_mcdataarrayint_meldwith "Here is a C++ example".
6950  *
6951  *  \ref py_mcdataarrayint_meldwith "Here is a Python example".
6952  */
6953 void DataArrayInt::meldWith(const DataArrayInt *other) throw(INTERP_KERNEL::Exception)
6954 {
6955   if(!other)
6956     throw INTERP_KERNEL::Exception("DataArrayInt::meldWith : DataArrayInt pointer in input is NULL !");
6957   checkAllocated();
6958   other->checkAllocated();
6959   int nbOfTuples=getNumberOfTuples();
6960   if(nbOfTuples!=other->getNumberOfTuples())
6961     throw INTERP_KERNEL::Exception("DataArrayInt::meldWith : mismatch of number of tuples !");
6962   int nbOfComp1=getNumberOfComponents();
6963   int nbOfComp2=other->getNumberOfComponents();
6964   int *newArr=new int[nbOfTuples*(nbOfComp1+nbOfComp2)];
6965   int *w=newArr;
6966   const int *inp1=getConstPointer();
6967   const int *inp2=other->getConstPointer();
6968   for(int i=0;i<nbOfTuples;i++,inp1+=nbOfComp1,inp2+=nbOfComp2)
6969     {
6970       w=std::copy(inp1,inp1+nbOfComp1,w);
6971       w=std::copy(inp2,inp2+nbOfComp2,w);
6972     }
6973   useArray(newArr,true,CPP_DEALLOC,nbOfTuples,nbOfComp1+nbOfComp2);
6974   std::vector<int> compIds(nbOfComp2);
6975   for(int i=0;i<nbOfComp2;i++)
6976     compIds[i]=nbOfComp1+i;
6977   copyPartOfStringInfoFrom2(compIds,*other);
6978 }
6979
6980 /*!
6981  * Copy all components in a specified order from another DataArrayInt.
6982  * The specified components become the first ones in \a this array.
6983  * Both numerical and textual data is copied. The number of tuples in \a this and
6984  * the other array can be different.
6985  *  \param [in] a - the array to copy data from.
6986  *  \param [in] compoIds - sequence of zero based indices of components, data of which is
6987  *              to be copied.
6988  *  \throw If \a a is NULL.
6989  *  \throw If \a compoIds.size() != \a a->getNumberOfComponents().
6990  *  \throw If \a compoIds[i] < 0 or \a compoIds[i] > \a this->getNumberOfComponents().
6991  *
6992  *  \ref cpp_mcdataarrayint_setselectedcomponents "Here is a Python example".
6993  */
6994 void DataArrayInt::setSelectedComponents(const DataArrayInt *a, const std::vector<int>& compoIds) throw(INTERP_KERNEL::Exception)
6995 {
6996   if(!a)
6997     throw INTERP_KERNEL::Exception("DataArrayInt::setSelectedComponents : input DataArrayInt is NULL !");
6998   checkAllocated();
6999   a->checkAllocated();
7000   copyPartOfStringInfoFrom2(compoIds,*a);
7001   std::size_t partOfCompoSz=compoIds.size();
7002   int nbOfCompo=getNumberOfComponents();
7003   int nbOfTuples=std::min(getNumberOfTuples(),a->getNumberOfTuples());
7004   const int *ac=a->getConstPointer();
7005   int *nc=getPointer();
7006   for(int i=0;i<nbOfTuples;i++)
7007     for(std::size_t j=0;j<partOfCompoSz;j++,ac++)
7008       nc[nbOfCompo*i+compoIds[j]]=*ac;
7009 }
7010
7011 /*!
7012  * Copy all values from another DataArrayInt into specified tuples and components
7013  * of \a this array. Textual data is not copied.
7014  * The tree parameters defining set of indices of tuples and components are similar to
7015  * the tree parameters of the Python function \c range(\c start,\c stop,\c step).
7016  *  \param [in] a - the array to copy values from.
7017  *  \param [in] bgTuples - index of the first tuple of \a this array to assign values to.
7018  *  \param [in] endTuples - index of the tuple before which the tuples to assign to
7019  *              are located.
7020  *  \param [in] stepTuples - index increment to get index of the next tuple to assign to.
7021  *  \param [in] bgComp - index of the first component of \a this array to assign values to.
7022  *  \param [in] endComp - index of the component before which the components to assign
7023  *              to are located.
7024  *  \param [in] stepComp - index increment to get index of the next component to assign to.
7025  *  \param [in] strictCompoCompare - if \a true (by default), then \a a->getNumberOfComponents() 
7026  *              must be equal to the number of columns to assign to, else an
7027  *              exception is thrown; if \a false, then it is only required that \a
7028  *              a->getNbOfElems() equals to number of values to assign to (this condition
7029  *              must be respected even if \a strictCompoCompare is \a true). The number of 
7030  *              values to assign to is given by following Python expression:
7031  *              \a nbTargetValues = 
7032  *              \c len(\c range(\a bgTuples,\a endTuples,\a stepTuples)) *
7033  *              \c len(\c range(\a bgComp,\a endComp,\a stepComp)).
7034  *  \throw If \a a is NULL.
7035  *  \throw If \a a is not allocated.
7036  *  \throw If \a this is not allocated.
7037  *  \throw If parameters specifying tuples and components to assign to do not give a
7038  *            non-empty range of increasing indices.
7039  *  \throw If \a a->getNbOfElems() != \a nbTargetValues.
7040  *  \throw If \a strictCompoCompare == \a true && \a a->getNumberOfComponents() !=
7041  *            \c len(\c range(\a bgComp,\a endComp,\a stepComp)).
7042  *
7043  *  \ref cpp_mcdataarrayint_setpartofvalues1 "Here is a Python example".
7044  */
7045 void DataArrayInt::setPartOfValues1(const DataArrayInt *a, int bgTuples, int endTuples, int stepTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare) throw(INTERP_KERNEL::Exception)
7046 {
7047   if(!a)
7048     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValues1 : DataArrayInt pointer in input is NULL !");
7049   const char msg[]="DataArrayInt::setPartOfValues1";
7050   checkAllocated();
7051   a->checkAllocated();
7052   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
7053   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
7054   int nbComp=getNumberOfComponents();
7055   int nbOfTuples=getNumberOfTuples();
7056   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
7057   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
7058   bool assignTech=true;
7059   if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
7060     {
7061       if(strictCompoCompare)
7062         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
7063     }
7064   else
7065     {
7066       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
7067       assignTech=false;
7068     }
7069   int *pt=getPointer()+bgTuples*nbComp+bgComp;
7070   const int *srcPt=a->getConstPointer();
7071   if(assignTech)
7072     {
7073       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
7074         for(int j=0;j<newNbOfComp;j++,srcPt++)
7075           pt[j*stepComp]=*srcPt;
7076     }
7077   else
7078     {
7079       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
7080         {
7081           const int *srcPt2=srcPt;
7082           for(int j=0;j<newNbOfComp;j++,srcPt2++)
7083             pt[j*stepComp]=*srcPt2;
7084         }
7085     }
7086 }
7087
7088 /*!
7089  * Assign a given value to values at specified tuples and components of \a this array.
7090  * The tree parameters defining set of indices of tuples and components are similar to
7091  * the tree parameters of the Python function \c range(\c start,\c stop,\c step)..
7092  *  \param [in] a - the value to assign.
7093  *  \param [in] bgTuples - index of the first tuple of \a this array to assign to.
7094  *  \param [in] endTuples - index of the tuple before which the tuples to assign to
7095  *              are located.
7096  *  \param [in] stepTuples - index increment to get index of the next tuple to assign to.
7097  *  \param [in] bgComp - index of the first component of \a this array to assign to.
7098  *  \param [in] endComp - index of the component before which the components to assign
7099  *              to are located.
7100  *  \param [in] stepComp - index increment to get index of the next component to assign to.
7101  *  \throw If \a this is not allocated.
7102  *  \throw If parameters specifying tuples and components to assign to, do not give a
7103  *            non-empty range of increasing indices or indices are out of a valid range
7104  *            for \this array.
7105  *
7106  *  \ref cpp_mcdataarrayint_setpartofvaluessimple1 "Here is a Python example".
7107  */
7108 void DataArrayInt::setPartOfValuesSimple1(int a, int bgTuples, int endTuples, int stepTuples, int bgComp, int endComp, int stepComp) throw(INTERP_KERNEL::Exception)
7109 {
7110   const char msg[]="DataArrayInt::setPartOfValuesSimple1";
7111   checkAllocated();
7112   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
7113   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
7114   int nbComp=getNumberOfComponents();
7115   int nbOfTuples=getNumberOfTuples();
7116   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
7117   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
7118   int *pt=getPointer()+bgTuples*nbComp+bgComp;
7119   for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
7120     for(int j=0;j<newNbOfComp;j++)
7121       pt[j*stepComp]=a;
7122 }
7123
7124
7125 /*!
7126  * Copy all values from another DataArrayInt (\a a) into specified tuples and 
7127  * components of \a this array. Textual data is not copied.
7128  * The tuples and components to assign to are defined by C arrays of indices.
7129  * There are two *modes of usage*:
7130  * - If \a a->getNbOfElems() equals to number of values to assign to, then every value
7131  *   of \a a is assigned to its own location within \a this array. 
7132  * - If \a a includes one tuple, then all values of \a a are assigned to the specified
7133  *   components of every specified tuple of \a this array. In this mode it is required
7134  *   that \a a->getNumberOfComponents() equals to the number of specified components.
7135  * 
7136  *  \param [in] a - the array to copy values from.
7137  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
7138  *              assign values of \a a to.
7139  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
7140  *              pointer to a tuple index <em>(pi)</em> varies as this: 
7141  *              \a bgTuples <= \a pi < \a endTuples.
7142  *  \param [in] bgComp - pointer to an array of component indices of \a this array to
7143  *              assign values of \a a to.
7144  *  \param [in] endComp - specifies the end of the array \a bgTuples, so that
7145  *              pointer to a component index <em>(pi)</em> varies as this: 
7146  *              \a bgComp <= \a pi < \a endComp.
7147  *  \param [in] strictCompoCompare - this parameter is checked only if the
7148  *               *mode of usage* is the first; if it is \a true (default), 
7149  *               then \a a->getNumberOfComponents() must be equal 
7150  *               to the number of specified columns, else this is not required.
7151  *  \throw If \a a is NULL.
7152  *  \throw If \a a is not allocated.
7153  *  \throw If \a this is not allocated.
7154  *  \throw If any index of tuple/component given by <em>bgTuples / bgComp</em> is
7155  *         out of a valid range for \a this array.
7156  *  \throw In the first *mode of usage*, if <em>strictCompoCompare == true </em> and
7157  *         if <em> a->getNumberOfComponents() != (endComp - bgComp) </em>.
7158  *  \throw In the second *mode of usage*, if \a a->getNumberOfTuples() != 1 or
7159  *         <em> a->getNumberOfComponents() != (endComp - bgComp)</em>.
7160  *
7161  *  \ref cpp_mcdataarrayint_setpartofvalues2 "Here is a Python example".
7162  */
7163 void DataArrayInt::setPartOfValues2(const DataArrayInt *a, const int *bgTuples, const int *endTuples, const int *bgComp, const int *endComp, bool strictCompoCompare) throw(INTERP_KERNEL::Exception)
7164 {
7165   if(!a)
7166     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValues2 : DataArrayInt pointer in input is NULL !");
7167   const char msg[]="DataArrayInt::setPartOfValues2";
7168   checkAllocated();
7169   a->checkAllocated();
7170   int nbComp=getNumberOfComponents();
7171   int nbOfTuples=getNumberOfTuples();
7172   for(const int *z=bgComp;z!=endComp;z++)
7173     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
7174   int newNbOfTuples=(int)std::distance(bgTuples,endTuples);
7175   int newNbOfComp=(int)std::distance(bgComp,endComp);
7176   bool assignTech=true;
7177   if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
7178     {
7179       if(strictCompoCompare)
7180         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
7181     }
7182   else
7183     {
7184       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
7185       assignTech=false;
7186     }
7187   int *pt=getPointer();
7188   const int *srcPt=a->getConstPointer();
7189   if(assignTech)
7190     {    
7191       for(const int *w=bgTuples;w!=endTuples;w++)
7192         {
7193           DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
7194           for(const int *z=bgComp;z!=endComp;z++,srcPt++)
7195             {    
7196               pt[(std::size_t)(*w)*nbComp+(*z)]=*srcPt;
7197             }
7198         }
7199     }
7200   else
7201     {
7202       for(const int *w=bgTuples;w!=endTuples;w++)
7203         {
7204           const int *srcPt2=srcPt;
7205           DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
7206           for(const int *z=bgComp;z!=endComp;z++,srcPt2++)
7207             {    
7208               pt[(std::size_t)(*w)*nbComp+(*z)]=*srcPt2;
7209             }
7210         }
7211     }
7212 }
7213
7214 /*!
7215  * Assign a given value to values at specified tuples and components of \a this array.
7216  * The tuples and components to assign to are defined by C arrays of indices.
7217  *  \param [in] a - the value to assign.
7218  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
7219  *              assign \a a to.
7220  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
7221  *              pointer to a tuple index (\a pi) varies as this: 
7222  *              \a bgTuples <= \a pi < \a endTuples.
7223  *  \param [in] bgComp - pointer to an array of component indices of \a this array to
7224  *              assign \a a to.
7225  *  \param [in] endComp - specifies the end of the array \a bgTuples, so that
7226  *              pointer to a component index (\a pi) varies as this: 
7227  *              \a bgComp <= \a pi < \a endComp.
7228  *  \throw If \a this is not allocated.
7229  *  \throw If any index of tuple/component given by <em>bgTuples / bgComp</em> is
7230  *         out of a valid range for \a this array.
7231  *
7232  *  \ref cpp_mcdataarrayint_setpartofvaluessimple2 "Here is a Python example".
7233  */
7234 void DataArrayInt::setPartOfValuesSimple2(int a, const int *bgTuples, const int *endTuples, const int *bgComp, const int *endComp) throw(INTERP_KERNEL::Exception)
7235 {
7236   checkAllocated();
7237   int nbComp=getNumberOfComponents();
7238   int nbOfTuples=getNumberOfTuples();
7239   for(const int *z=bgComp;z!=endComp;z++)
7240     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
7241   int *pt=getPointer();
7242   for(const int *w=bgTuples;w!=endTuples;w++)
7243     for(const int *z=bgComp;z!=endComp;z++)
7244       {
7245         DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
7246         pt[(std::size_t)(*w)*nbComp+(*z)]=a;
7247       }
7248 }
7249
7250 /*!
7251  * Copy all values from another DataArrayInt (\a a) into specified tuples and 
7252  * components of \a this array. Textual data is not copied.
7253  * The tuples to assign to are defined by a C array of indices.
7254  * The components to assign to are defined by three values similar to parameters of
7255  * the Python function \c range(\c start,\c stop,\c step).
7256  * There are two *modes of usage*:
7257  * - If \a a->getNbOfElems() equals to number of values to assign to, then every value
7258  *   of \a a is assigned to its own location within \a this array. 
7259  * - If \a a includes one tuple, then all values of \a a are assigned to the specified
7260  *   components of every specified tuple of \a this array. In this mode it is required
7261  *   that \a a->getNumberOfComponents() equals to the number of specified components.
7262  *
7263  *  \param [in] a - the array to copy values from.
7264  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
7265  *              assign values of \a a to.
7266  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
7267  *              pointer to a tuple index <em>(pi)</em> varies as this: 
7268  *              \a bgTuples <= \a pi < \a endTuples.
7269  *  \param [in] bgComp - index of the first component of \a this array to assign to.
7270  *  \param [in] endComp - index of the component before which the components to assign
7271  *              to are located.
7272  *  \param [in] stepComp - index increment to get index of the next component to assign to.
7273  *  \param [in] strictCompoCompare - this parameter is checked only in the first
7274  *               *mode of usage*; if \a strictCompoCompare is \a true (default), 
7275  *               then \a a->getNumberOfComponents() must be equal 
7276  *               to the number of specified columns, else this is not required.
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 any index of tuple given by \a bgTuples is out of a valid range for 
7281  *         \a this array.
7282  *  \throw In the first *mode of usage*, if <em>strictCompoCompare == true </em> and
7283  *         if <em> a->getNumberOfComponents()</em> is unequal to the number of components
7284  *         defined by <em>(bgComp,endComp,stepComp)</em>.
7285  *  \throw In the second *mode of usage*, if \a a->getNumberOfTuples() != 1 or
7286  *         <em> a->getNumberOfComponents()</em> is unequal to the number of components
7287  *         defined by <em>(bgComp,endComp,stepComp)</em>.
7288  *  \throw If parameters specifying components to assign to, do not give a
7289  *            non-empty range of increasing indices or indices are out of a valid range
7290  *            for \this array.
7291  *
7292  *  \ref cpp_mcdataarrayint_setpartofvalues3 "Here is a Python example".
7293  */
7294 void DataArrayInt::setPartOfValues3(const DataArrayInt *a, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare) throw(INTERP_KERNEL::Exception)
7295 {
7296   if(!a)
7297     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValues3 : DataArrayInt pointer in input is NULL !");
7298   const char msg[]="DataArrayInt::setPartOfValues3";
7299   checkAllocated();
7300   a->checkAllocated();
7301   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
7302   int nbComp=getNumberOfComponents();
7303   int nbOfTuples=getNumberOfTuples();
7304   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
7305   int newNbOfTuples=(int)std::distance(bgTuples,endTuples);
7306   bool assignTech=true;
7307   if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
7308     {
7309       if(strictCompoCompare)
7310         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
7311     }
7312   else
7313     {
7314       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
7315       assignTech=false;
7316     }
7317   int *pt=getPointer()+bgComp;
7318   const int *srcPt=a->getConstPointer();
7319   if(assignTech)
7320     {
7321       for(const int *w=bgTuples;w!=endTuples;w++)
7322         for(int j=0;j<newNbOfComp;j++,srcPt++)
7323           {
7324             DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
7325             pt[(std::size_t)(*w)*nbComp+j*stepComp]=*srcPt;
7326           }
7327     }
7328   else
7329     {
7330       for(const int *w=bgTuples;w!=endTuples;w++)
7331         {
7332           const int *srcPt2=srcPt;
7333           for(int j=0;j<newNbOfComp;j++,srcPt2++)
7334             {
7335               DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
7336               pt[(std::size_t)(*w)*nbComp+j*stepComp]=*srcPt2;
7337             }
7338         }
7339     }
7340 }
7341
7342 /*!
7343  * Assign a given value to values at specified tuples and components of \a this array.
7344  * The tuples to assign to are defined by a C array of indices.
7345  * The components to assign to are defined by three values similar to parameters of
7346  * the Python function \c range(\c start,\c stop,\c step).
7347  *  \param [in] a - the value to assign.
7348  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
7349  *              assign \a a to.
7350  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
7351  *              pointer to a tuple index <em>(pi)</em> varies as this: 
7352  *              \a bgTuples <= \a pi < \a endTuples.
7353  *  \param [in] bgComp - index of the first component of \a this array to assign to.
7354  *  \param [in] endComp - index of the component before which the components to assign
7355  *              to are located.
7356  *  \param [in] stepComp - index increment to get index of the next component to assign to.
7357  *  \throw If \a this is not allocated.
7358  *  \throw If any index of tuple given by \a bgTuples is out of a valid range for 
7359  *         \a this array.
7360  *  \throw If parameters specifying components to assign to, do not give a
7361  *            non-empty range of increasing indices or indices are out of a valid range
7362  *            for \this array.
7363  *
7364  *  \ref cpp_mcdataarrayint_setpartofvaluessimple3 "Here is a Python example".
7365  */
7366 void DataArrayInt::setPartOfValuesSimple3(int a, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp) throw(INTERP_KERNEL::Exception)
7367 {
7368   const char msg[]="DataArrayInt::setPartOfValuesSimple3";
7369   checkAllocated();
7370   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
7371   int nbComp=getNumberOfComponents();
7372   int nbOfTuples=getNumberOfTuples();
7373   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
7374   int *pt=getPointer()+bgComp;
7375   for(const int *w=bgTuples;w!=endTuples;w++)
7376     for(int j=0;j<newNbOfComp;j++)
7377       {
7378         DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
7379         pt[(std::size_t)(*w)*nbComp+j*stepComp]=a;
7380       }
7381 }
7382
7383 void DataArrayInt::setPartOfValues4(const DataArrayInt *a, int bgTuples, int endTuples, int stepTuples, const int *bgComp, const int *endComp, bool strictCompoCompare) throw(INTERP_KERNEL::Exception)
7384 {
7385   if(!a)
7386     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValues4 : input DataArrayInt is NULL !");
7387   const char msg[]="DataArrayInt::setPartOfValues4";
7388   checkAllocated();
7389   a->checkAllocated();
7390   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
7391   int newNbOfComp=(int)std::distance(bgComp,endComp);
7392   int nbComp=getNumberOfComponents();
7393   for(const int *z=bgComp;z!=endComp;z++)
7394     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
7395   int nbOfTuples=getNumberOfTuples();
7396   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
7397   bool assignTech=true;
7398   if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
7399     {
7400       if(strictCompoCompare)
7401         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
7402     }
7403   else
7404     {
7405       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
7406       assignTech=false;
7407     }
7408   const int *srcPt=a->getConstPointer();
7409   int *pt=getPointer()+bgTuples*nbComp;
7410   if(assignTech)
7411     {
7412       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
7413         for(const int *z=bgComp;z!=endComp;z++,srcPt++)
7414           pt[*z]=*srcPt;
7415     }
7416   else
7417     {
7418       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
7419         {
7420           const int *srcPt2=srcPt;
7421           for(const int *z=bgComp;z!=endComp;z++,srcPt2++)
7422             pt[*z]=*srcPt2;
7423         }
7424     }
7425 }
7426
7427 void DataArrayInt::setPartOfValuesSimple4(int a, int bgTuples, int endTuples, int stepTuples, const int *bgComp, const int *endComp) throw(INTERP_KERNEL::Exception)
7428 {
7429   const char msg[]="DataArrayInt::setPartOfValuesSimple4";
7430   checkAllocated();
7431   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
7432   int nbComp=getNumberOfComponents();
7433   for(const int *z=bgComp;z!=endComp;z++)
7434     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
7435   int nbOfTuples=getNumberOfTuples();
7436   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
7437   int *pt=getPointer()+bgTuples*nbComp;
7438   for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
7439     for(const int *z=bgComp;z!=endComp;z++)
7440       pt[*z]=a;
7441 }
7442
7443 /*!
7444  * Copy some tuples from another DataArrayInt into specified tuples
7445  * of \a this array. Textual data is not copied. Both arrays must have equal number of
7446  * components.
7447  * Both the tuples to assign and the tuples to assign to are defined by a DataArrayInt.
7448  * All components of selected tuples are copied.
7449  *  \param [in] a - the array to copy values from.
7450  *  \param [in] tuplesSelec - the array specifying both source tuples of \a a and
7451  *              target tuples of \a this. \a tuplesSelec has two components, and the
7452  *              first component specifies index of the source tuple and the second
7453  *              one specifies index of the target tuple.
7454  *  \throw If \a this is not allocated.
7455  *  \throw If \a a is NULL.
7456  *  \throw If \a a is not allocated.
7457  *  \throw If \a tuplesSelec is NULL.
7458  *  \throw If \a tuplesSelec is not allocated.
7459  *  \throw If <em>this->getNumberOfComponents() != a->getNumberOfComponents()</em>.
7460  *  \throw If \a tuplesSelec->getNumberOfComponents() != 2.
7461  *  \throw If any tuple index given by \a tuplesSelec is out of a valid range for 
7462  *         the corresponding (\a this or \a a) array.
7463  */
7464 void DataArrayInt::setPartOfValuesAdv(const DataArrayInt *a, const DataArrayInt *tuplesSelec) throw(INTERP_KERNEL::Exception)
7465 {
7466   if(!a || !tuplesSelec)
7467     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValuesAdv : DataArrayInt pointer in input is NULL !");
7468   checkAllocated();
7469   a->checkAllocated();
7470   tuplesSelec->checkAllocated();
7471   int nbOfComp=getNumberOfComponents();
7472   if(nbOfComp!=a->getNumberOfComponents())
7473     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValuesAdv : This and a do not have the same number of components !");
7474   if(tuplesSelec->getNumberOfComponents()!=2)
7475     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValuesAdv : Expecting to have a tuple selector DataArrayInt instance with exactly 2 components !");
7476   int thisNt=getNumberOfTuples();
7477   int aNt=a->getNumberOfTuples();
7478   int *valsToSet=getPointer();
7479   const int *valsSrc=a->getConstPointer();
7480   for(const int *tuple=tuplesSelec->begin();tuple!=tuplesSelec->end();tuple+=2)
7481     {
7482       if(tuple[1]>=0 && tuple[1]<aNt)
7483         {
7484           if(tuple[0]>=0 && tuple[0]<thisNt)
7485             std::copy(valsSrc+nbOfComp*tuple[1],valsSrc+nbOfComp*(tuple[1]+1),valsToSet+nbOfComp*tuple[0]);
7486           else
7487             {
7488               std::ostringstream oss; oss << "DataArrayInt::setPartOfValuesAdv : Tuple #" << std::distance(tuplesSelec->begin(),tuple)/2;
7489               oss << " of 'tuplesSelec' request of tuple id #" << tuple[0] << " in 'this' ! It should be in [0," << thisNt << ") !";
7490               throw INTERP_KERNEL::Exception(oss.str().c_str());
7491             }
7492         }
7493       else
7494         {
7495           std::ostringstream oss; oss << "DataArrayInt::setPartOfValuesAdv : Tuple #" << std::distance(tuplesSelec->begin(),tuple)/2;
7496           oss << " of 'tuplesSelec' request of tuple id #" << tuple[1] << " in 'a' ! It should be in [0," << aNt << ") !";
7497           throw INTERP_KERNEL::Exception(oss.str().c_str());
7498         }
7499     }
7500 }
7501
7502 /*!
7503  * Copy some tuples from another DataArrayInt (\a a) into contiguous tuples
7504  * of \a this array. Textual data is not copied. Both arrays must have equal number of
7505  * components.
7506  * The tuples to assign to are defined by index of the first tuple, and
7507  * their number is defined by \a tuplesSelec->getNumberOfTuples().
7508  * The tuples to copy are defined by values of a DataArrayInt.
7509  * All components of selected tuples are copied.
7510  *  \param [in] tupleIdStart - index of the first tuple of \a this array to assign
7511  *              values to.
7512  *  \param [in] a - the array to copy values from.
7513  *  \param [in] tuplesSelec - the array specifying tuples of \a a to copy.
7514  *  \throw If \a this is not allocated.
7515  *  \throw If \a a is NULL.
7516  *  \throw If \a a is not allocated.
7517  *  \throw If \a tuplesSelec is NULL.
7518  *  \throw If \a tuplesSelec is not allocated.
7519  *  \throw If <em>this->getNumberOfComponents() != a->getNumberOfComponents()</em>.
7520  *  \throw If \a tuplesSelec->getNumberOfComponents() != 1.
7521  *  \throw If <em>tupleIdStart + tuplesSelec->getNumberOfTuples() > this->getNumberOfTuples().</em>
7522  *  \throw If any tuple index given by \a tuplesSelec is out of a valid range for 
7523  *         \a a array.
7524  */
7525 void DataArrayInt::setContigPartOfSelectedValues(int tupleIdStart, const DataArrayInt*a, const DataArrayInt *tuplesSelec) throw(INTERP_KERNEL::Exception)
7526 {
7527   checkAllocated();
7528   a->checkAllocated();
7529   tuplesSelec->checkAllocated();
7530   int nbOfComp=getNumberOfComponents();
7531   if(nbOfComp!=a->getNumberOfComponents())
7532     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues : This and a do not have the same number of components !");
7533   if(tuplesSelec->getNumberOfComponents()!=1)
7534     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues : Expecting to have a tuple selector DataArrayInt instance with exactly 1 component !");
7535   int thisNt=getNumberOfTuples();
7536   int aNt=a->getNumberOfTuples();
7537   int nbOfTupleToWrite=tuplesSelec->getNumberOfTuples();
7538   int *valsToSet=getPointer()+tupleIdStart*nbOfComp;
7539   if(tupleIdStart+nbOfTupleToWrite>thisNt)
7540     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues : invalid number range of values to write !");
7541   const int *valsSrc=a->getConstPointer();
7542   for(const int *tuple=tuplesSelec->begin();tuple!=tuplesSelec->end();tuple++,valsToSet+=nbOfComp)
7543     {
7544       if(*tuple>=0 && *tuple<aNt)
7545         {
7546           std::copy(valsSrc+nbOfComp*(*tuple),valsSrc+nbOfComp*(*tuple+1),valsToSet);
7547         }
7548       else
7549         {
7550           std::ostringstream oss; oss << "DataArrayInt::setContigPartOfSelectedValues : Tuple #" << std::distance(tuplesSelec->begin(),tuple);
7551           oss << " of 'tuplesSelec' request of tuple id #" << *tuple << " in 'a' ! It should be in [0," << aNt << ") !";
7552           throw INTERP_KERNEL::Exception(oss.str().c_str());
7553         }
7554     }
7555 }
7556
7557 /*!
7558  * Copy some tuples from another DataArrayInt (\a a) into contiguous tuples
7559  * of \a this array. Textual data is not copied. Both arrays must have equal number of
7560  * components.
7561  * The tuples to copy are defined by three values similar to parameters of
7562  * the Python function \c range(\c start,\c stop,\c step).
7563  * The tuples to assign to are defined by index of the first tuple, and
7564  * their number is defined by number of tuples to copy.
7565  * All components of selected tuples are copied.
7566  *  \param [in] tupleIdStart - index of the first tuple of \a this array to assign
7567  *              values to.
7568  *  \param [in] a - the array to copy values from.
7569  *  \param [in] bg - index of the first tuple to copy of the array \a a.
7570  *  \param [in] end2 - index of the tuple of \a a before which the tuples to copy
7571  *              are located.
7572  *  \param [in] step - index increment to get index of the next tuple to copy.
7573  *  \throw If \a this is not allocated.
7574  *  \throw If \a a is NULL.
7575  *  \throw If \a a is not allocated.
7576  *  \throw If <em>this->getNumberOfComponents() != a->getNumberOfComponents()</em>.
7577  *  \throw If <em>tupleIdStart + len(range(bg,end2,step)) > this->getNumberOfTuples().</em>
7578  *  \throw If parameters specifying tuples to copy, do not give a
7579  *            non-empty range of increasing indices or indices are out of a valid range
7580  *            for the array \a a.
7581  */
7582 void DataArrayInt::setContigPartOfSelectedValues2(int tupleIdStart, const DataArrayInt *a, int bg, int end2, int step) throw(INTERP_KERNEL::Exception)
7583 {
7584   checkAllocated();
7585   a->checkAllocated();
7586   int nbOfComp=getNumberOfComponents();
7587   const char msg[]="DataArrayInt::setContigPartOfSelectedValues2";
7588   int nbOfTupleToWrite=DataArray::GetNumberOfItemGivenBES(bg,end2,step,msg);
7589   if(nbOfComp!=a->getNumberOfComponents())
7590     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues2 : This and a do not have the same number of components !");
7591   int thisNt=getNumberOfTuples();
7592   int aNt=a->getNumberOfTuples();
7593   int *valsToSet=getPointer()+tupleIdStart*nbOfComp;
7594   if(tupleIdStart+nbOfTupleToWrite>thisNt)
7595     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues2 : invalid number range of values to write !");
7596   if(end2>aNt)
7597     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues2 : invalid range of values to read !");
7598   const int *valsSrc=a->getConstPointer()+bg*nbOfComp;
7599   for(int i=0;i<nbOfTupleToWrite;i++,valsToSet+=nbOfComp,valsSrc+=step*nbOfComp)
7600     {
7601       std::copy(valsSrc,valsSrc+nbOfComp,valsToSet);
7602     }
7603 }
7604
7605 /*!
7606  * Returns a value located at specified tuple and component.
7607  * This method is equivalent to DataArrayInt::getIJ() except that validity of
7608  * parameters is checked. So this method is safe but expensive if used to go through
7609  * all values of \a this.
7610  *  \param [in] tupleId - index of tuple of interest.
7611  *  \param [in] compoId - index of component of interest.
7612  *  \return double - value located by \a tupleId and \a compoId.
7613  *  \throw If \a this is not allocated.
7614  *  \throw If condition <em>( 0 <= tupleId < this->getNumberOfTuples() )</em> is violated.
7615  *  \throw If condition <em>( 0 <= compoId < this->getNumberOfComponents() )</em> is violated.
7616  */
7617 int DataArrayInt::getIJSafe(int tupleId, int compoId) const throw(INTERP_KERNEL::Exception)
7618 {
7619   checkAllocated();
7620   if(tupleId<0 || tupleId>=getNumberOfTuples())
7621     {
7622       std::ostringstream oss; oss << "DataArrayInt::getIJSafe : request for tupleId " << tupleId << " should be in [0," << getNumberOfTuples() << ") !";
7623       throw INTERP_KERNEL::Exception(oss.str().c_str());
7624     }
7625   if(compoId<0 || compoId>=getNumberOfComponents())
7626     {
7627       std::ostringstream oss; oss << "DataArrayInt::getIJSafe : request for compoId " << compoId << " should be in [0," << getNumberOfComponents() << ") !";
7628       throw INTERP_KERNEL::Exception(oss.str().c_str());
7629     }
7630   return _mem[tupleId*_info_on_compo.size()+compoId];
7631 }
7632
7633 /*!
7634  * Returns the last value of \a this. 
7635  *  \return double - the last value of \a this array.
7636  *  \throw If \a this is not allocated.
7637  *  \throw If \a this->getNumberOfComponents() != 1.
7638  *  \throw If \a this->getNumberOfTuples() < 1.
7639  */
7640 int DataArrayInt::back() const throw(INTERP_KERNEL::Exception)
7641 {
7642   checkAllocated();
7643   if(getNumberOfComponents()!=1)
7644     throw INTERP_KERNEL::Exception("DataArrayInt::back : number of components not equal to one !");
7645   int nbOfTuples=getNumberOfTuples();
7646   if(nbOfTuples<1)
7647     throw INTERP_KERNEL::Exception("DataArrayInt::back : number of tuples must be >= 1 !");
7648   return *(getConstPointer()+nbOfTuples-1);
7649 }
7650
7651 /*!
7652  * Assign pointer to one array to a pointer to another appay. Reference counter of
7653  * \a arrayToSet is incremented / decremented.
7654  *  \param [in] newArray - the pointer to array to assign to \a arrayToSet.
7655  *  \param [in,out] arrayToSet - the pointer to array to assign to.
7656  */
7657 void DataArrayInt::SetArrayIn(DataArrayInt *newArray, DataArrayInt* &arrayToSet)
7658 {
7659   if(newArray!=arrayToSet)
7660     {
7661       if(arrayToSet)
7662         arrayToSet->decrRef();
7663       arrayToSet=newArray;
7664       if(arrayToSet)
7665         arrayToSet->incrRef();
7666     }
7667 }
7668
7669 DataArrayIntIterator *DataArrayInt::iterator() throw(INTERP_KERNEL::Exception)
7670 {
7671   return new DataArrayIntIterator(this);
7672 }
7673
7674 /*!
7675  * Creates a new DataArrayInt containing IDs (indices) of tuples holding value equal to a
7676  * given one.
7677  *  \param [in] val - the value to find within \a this.
7678  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
7679  *          array using decrRef() as it is no more needed.
7680  *  \throw If \a this is not allocated.
7681  *  \throw If \a this->getNumberOfComponents() != 1.
7682  */
7683 DataArrayInt *DataArrayInt::getIdsEqual(int val) const throw(INTERP_KERNEL::Exception)
7684 {
7685   checkAllocated();
7686   if(getNumberOfComponents()!=1)
7687     throw INTERP_KERNEL::Exception("DataArrayInt::getIdsEqual : the array must have only one component, you can call 'rearrange' method before !");
7688   const int *cptr=getConstPointer();
7689   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
7690   int nbOfTuples=getNumberOfTuples();
7691   for(int i=0;i<nbOfTuples;i++,cptr++)
7692     if(*cptr==val)
7693       ret->pushBackSilent(i);
7694   return ret.retn();
7695 }
7696
7697 /*!
7698  * Creates a new DataArrayInt containing IDs (indices) of tuples holding value \b not
7699  * equal to a given one. 
7700  *  \param [in] val - the value to ignore within \a this.
7701  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
7702  *          array using decrRef() as it is no more needed.
7703  *  \throw If \a this is not allocated.
7704  *  \throw If \a this->getNumberOfComponents() != 1.
7705  */
7706 DataArrayInt *DataArrayInt::getIdsNotEqual(int val) const throw(INTERP_KERNEL::Exception)
7707 {
7708   checkAllocated();
7709   if(getNumberOfComponents()!=1)
7710     throw INTERP_KERNEL::Exception("DataArrayInt::getIdsNotEqual : the array must have only one component, you can call 'rearrange' method before !");
7711   const int *cptr=getConstPointer();
7712   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
7713   int nbOfTuples=getNumberOfTuples();
7714   for(int i=0;i<nbOfTuples;i++,cptr++)
7715     if(*cptr!=val)
7716       ret->pushBackSilent(i);
7717   return ret.retn();
7718 }
7719
7720
7721 /*!
7722  * Assigns \a newValue to all elements holding \a oldValue within \a this
7723  * one-dimensional array.
7724  *  \param [in] oldValue - the value to replace.
7725  *  \param [in] newValue - the value to assign.
7726  *  \return int - number of replacements performed.
7727  *  \throw If \a this is not allocated.
7728  *  \throw If \a this->getNumberOfComponents() != 1.
7729  */
7730 int DataArrayInt::changeValue(int oldValue, int newValue) throw(INTERP_KERNEL::Exception)
7731 {
7732   checkAllocated();
7733   if(getNumberOfComponents()!=1)
7734     throw INTERP_KERNEL::Exception("DataArrayInt::changeValue : the array must have only one component, you can call 'rearrange' method before !");
7735   int *start=getPointer();
7736   int *end2=start+getNbOfElems();
7737   int ret=0;
7738   for(int *val=start;val!=end2;val++)
7739     {
7740       if(*val==oldValue)
7741         {
7742           *val=newValue;
7743           ret++;
7744         }
7745     }
7746   return ret;
7747 }
7748
7749 /*!
7750  * Creates a new DataArrayInt containing IDs (indices) of tuples holding value equal to
7751  * one of given values.
7752  *  \param [in] valsBg - an array of values to find within \a this array.
7753  *  \param [in] valsEnd - specifies the end of the array \a valsBg, so that
7754  *              the last value of \a valsBg is \a valsEnd[ -1 ].
7755  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
7756  *          array using decrRef() as it is no more needed.
7757  *  \throw If \a this->getNumberOfComponents() != 1.
7758  */
7759 DataArrayInt *DataArrayInt::getIdsEqualList(const int *valsBg, const int *valsEnd) const throw(INTERP_KERNEL::Exception)
7760 {
7761   if(getNumberOfComponents()!=1)
7762     throw INTERP_KERNEL::Exception("DataArrayInt::getIdsEqualList : the array must have only one component, you can call 'rearrange' method before !");
7763   std::set<int> vals2(valsBg,valsEnd);
7764   const int *cptr=getConstPointer();
7765   std::vector<int> res;
7766   int nbOfTuples=getNumberOfTuples();
7767   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
7768   for(int i=0;i<nbOfTuples;i++,cptr++)
7769     if(vals2.find(*cptr)!=vals2.end())
7770       ret->pushBackSilent(i);
7771   return ret.retn();
7772 }
7773
7774 /*!
7775  * Creates a new DataArrayInt containing IDs (indices) of tuples holding values \b not
7776  * equal to any of given values.
7777  *  \param [in] valsBg - an array of values to ignore within \a this array.
7778  *  \param [in] valsEnd - specifies the end of the array \a valsBg, so that
7779  *              the last value of \a valsBg is \a valsEnd[ -1 ].
7780  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
7781  *          array using decrRef() as it is no more needed.
7782  *  \throw If \a this->getNumberOfComponents() != 1.
7783  */
7784 DataArrayInt *DataArrayInt::getIdsNotEqualList(const int *valsBg, const int *valsEnd) const throw(INTERP_KERNEL::Exception)
7785 {
7786   if(getNumberOfComponents()!=1)
7787     throw INTERP_KERNEL::Exception("DataArrayInt::getIdsNotEqualList : the array must have only one component, you can call 'rearrange' method before !");
7788   std::set<int> vals2(valsBg,valsEnd);
7789   const int *cptr=getConstPointer();
7790   std::vector<int> res;
7791   int nbOfTuples=getNumberOfTuples();
7792   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
7793   for(int i=0;i<nbOfTuples;i++,cptr++)
7794     if(vals2.find(*cptr)==vals2.end())
7795       ret->pushBackSilent(i);
7796   return ret.retn();
7797 }
7798
7799 /*!
7800  * This method is an extension of DataArrayInt::locateValue method because this method works for DataArrayInt with
7801  * any number of components excepted 0 (an INTERP_KERNEL::Exception is thrown in this case).
7802  * This method searches in \b this is there is a tuple that matched the input parameter \b tupl.
7803  * If any the tuple id is returned. If not -1 is returned.
7804  * 
7805  * This method throws an INTERP_KERNEL::Exception if the number of components in \b this mismatches with the size of
7806  * the input vector. An INTERP_KERNEL::Exception is thrown too if \b this is not allocated.
7807  *
7808  * \return tuple id where \b tupl is. -1 if no such tuple exists in \b this.
7809  * \sa DataArrayInt::search, DataArrayInt::presenceOfTuple.
7810  */
7811 int DataArrayInt::locateTuple(const std::vector<int>& tupl) const throw(INTERP_KERNEL::Exception)
7812 {
7813   checkAllocated();
7814   int nbOfCompo=getNumberOfComponents();
7815   if(nbOfCompo==0)
7816     throw INTERP_KERNEL::Exception("DataArrayInt::locateTuple : 0 components in 'this' !");
7817   if(nbOfCompo!=(int)tupl.size())
7818     {
7819       std::ostringstream oss; oss << "DataArrayInt::locateTuple : 'this' contains " << nbOfCompo << " components and searching for a tuple of length " << tupl.size() << " !";
7820       throw INTERP_KERNEL::Exception(oss.str().c_str());
7821     }
7822   const int *cptr=getConstPointer();
7823   std::size_t nbOfVals=getNbOfElems();
7824   for(const int *work=cptr;work!=cptr+nbOfVals;)
7825     {
7826       work=std::search(work,cptr+nbOfVals,tupl.begin(),tupl.end());
7827       if(work!=cptr+nbOfVals)
7828         {
7829           if(std::distance(cptr,work)%nbOfCompo!=0)
7830             work++;
7831           else
7832             return std::distance(cptr,work)/nbOfCompo;
7833         }
7834     }
7835   return -1;
7836 }
7837
7838 /*!
7839  * This method searches the sequence specified in input parameter \b vals in \b this.
7840  * This works only for DataArrayInt having number of components equal to one (if not an INTERP_KERNEL::Exception will be thrown).
7841  * This method differs from DataArrayInt::locateTuple in that the position is internal raw data is not considered here contrary to DataArrayInt::locateTuple.
7842  * \sa DataArrayInt::locateTuple
7843  */
7844 int DataArrayInt::search(const std::vector<int>& vals) const throw(INTERP_KERNEL::Exception)
7845 {
7846   checkAllocated();
7847   int nbOfCompo=getNumberOfComponents();
7848   if(nbOfCompo!=1)
7849     throw INTERP_KERNEL::Exception("DataArrayInt::search : works only for DataArrayInt instance with one component !");
7850   const int *cptr=getConstPointer();
7851   std::size_t nbOfVals=getNbOfElems();
7852   const int *loc=std::search(cptr,cptr+nbOfVals,vals.begin(),vals.end());
7853   if(loc!=cptr+nbOfVals)
7854     return std::distance(cptr,loc);
7855   return -1;
7856 }
7857
7858 /*!
7859  * This method expects to be called when number of components of this is equal to one.
7860  * This method returns the tuple id, if it exists, of the first tuple equal to \b value.
7861  * If not any tuple contains \b value -1 is returned.
7862  * \sa DataArrayInt::presenceOfValue
7863  */
7864 int DataArrayInt::locateValue(int value) const throw(INTERP_KERNEL::Exception)
7865 {
7866   checkAllocated();
7867   if(getNumberOfComponents()!=1)
7868     throw INTERP_KERNEL::Exception("DataArrayInt::presenceOfValue : the array must have only one component, you can call 'rearrange' method before !");
7869   const int *cptr=getConstPointer();
7870   int nbOfTuples=getNumberOfTuples();
7871   const int *ret=std::find(cptr,cptr+nbOfTuples,value);
7872   if(ret!=cptr+nbOfTuples)
7873     return std::distance(cptr,ret);
7874   return -1;
7875 }
7876
7877 /*!
7878  * This method expects to be called when number of components of this is equal to one.
7879  * This method returns the tuple id, if it exists, of the first tuple so that the value is contained in \b vals.
7880  * If not any tuple contains one of the values contained in 'vals' false is returned.
7881  * \sa DataArrayInt::presenceOfValue
7882  */
7883 int DataArrayInt::locateValue(const std::vector<int>& vals) const throw(INTERP_KERNEL::Exception)
7884 {
7885   checkAllocated();
7886   if(getNumberOfComponents()!=1)
7887     throw INTERP_KERNEL::Exception("DataArrayInt::presenceOfValue : the array must have only one component, you can call 'rearrange' method before !");
7888   std::set<int> vals2(vals.begin(),vals.end());
7889   const int *cptr=getConstPointer();
7890   int nbOfTuples=getNumberOfTuples();
7891   for(const int *w=cptr;w!=cptr+nbOfTuples;w++)
7892     if(vals2.find(*w)!=vals2.end())
7893       return std::distance(cptr,w);
7894   return -1;
7895 }
7896
7897 /*!
7898  * This method is an extension of DataArrayInt::presenceOfValue method because this method works for DataArrayInt with
7899  * any number of components excepted 0 (an INTERP_KERNEL::Exception is thrown in this case).
7900  * This method searches in \b this is there is a tuple that matched the input parameter \b tupl.
7901  * This method throws an INTERP_KERNEL::Exception if the number of components in \b this mismatches with the size of
7902  * the input vector. An INTERP_KERNEL::Exception is thrown too if \b this is not allocated.
7903  * \sa DataArrayInt::locateTuple
7904  */
7905 bool DataArrayInt::presenceOfTuple(const std::vector<int>& tupl) const throw(INTERP_KERNEL::Exception)
7906 {
7907   return locateTuple(tupl)!=-1;
7908 }
7909
7910
7911 /*!
7912  * Returns \a true if a given value is present within \a this one-dimensional array.
7913  *  \param [in] value - the value to find within \a this array.
7914  *  \return bool - \a true in case if \a value is present within \a this array.
7915  *  \throw If \a this is not allocated.
7916  *  \throw If \a this->getNumberOfComponents() != 1.
7917  *  \sa locateValue()
7918  */
7919 bool DataArrayInt::presenceOfValue(int value) const throw(INTERP_KERNEL::Exception)
7920 {
7921   return locateValue(value)!=-1;
7922 }
7923
7924 /*!
7925  * This method expects to be called when number of components of this is equal to one.
7926  * This method returns true if it exists a tuple so that the value is contained in \b vals.
7927  * If not any tuple contains one of the values contained in 'vals' false is returned.
7928  * \sa DataArrayInt::locateValue
7929  */
7930 bool DataArrayInt::presenceOfValue(const std::vector<int>& vals) const throw(INTERP_KERNEL::Exception)
7931 {
7932   return locateValue(vals)!=-1;
7933 }
7934
7935 /*!
7936  * Accumulates values of each component of \a this array.
7937  *  \param [out] res - an array of length \a this->getNumberOfComponents(), allocated 
7938  *         by the caller, that is filled by this method with sum value for each
7939  *         component.
7940  *  \throw If \a this is not allocated.
7941  */
7942 void DataArrayInt::accumulate(int *res) const throw(INTERP_KERNEL::Exception)
7943 {
7944   checkAllocated();
7945   const int *ptr=getConstPointer();
7946   int nbTuple=getNumberOfTuples();
7947   int nbComps=getNumberOfComponents();
7948   std::fill(res,res+nbComps,0);
7949   for(int i=0;i<nbTuple;i++)
7950     std::transform(ptr+i*nbComps,ptr+(i+1)*nbComps,res,res,std::plus<int>());
7951 }
7952
7953 int DataArrayInt::accumulate(int compId) const throw(INTERP_KERNEL::Exception)
7954 {
7955   checkAllocated();
7956   const int *ptr=getConstPointer();
7957   int nbTuple=getNumberOfTuples();
7958   int nbComps=getNumberOfComponents();
7959   if(compId<0 || compId>=nbComps)
7960     throw INTERP_KERNEL::Exception("DataArrayInt::accumulate : Invalid compId specified : No such nb of components !");
7961   int ret=0;
7962   for(int i=0;i<nbTuple;i++)
7963     ret+=ptr[i*nbComps+compId];
7964   return ret;
7965 }
7966
7967 /*!
7968  * Returns a new DataArrayInt by concatenating two given arrays, so that (1) the number
7969  * of tuples in the result array is <em> a1->getNumberOfTuples() + a2->getNumberOfTuples() -
7970  * offsetA2</em> and (2)
7971  * the number of component in the result array is same as that of each of given arrays.
7972  * First \a offsetA2 tuples of \a a2 are skipped and thus are missing from the result array.
7973  * Info on components is copied from the first of the given arrays. Number of components
7974  * in the given arrays must be the same.
7975  *  \param [in] a1 - an array to include in the result array.
7976  *  \param [in] a2 - another array to include in the result array.
7977  *  \param [in] offsetA2 - number of tuples of \a a2 to skip.
7978  *  \return DataArrayInt * - the new instance of DataArrayInt.
7979  *          The caller is to delete this result array using decrRef() as it is no more
7980  *          needed.
7981  *  \throw If either \a a1 or \a a2 is NULL.
7982  *  \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents().
7983  */
7984 DataArrayInt *DataArrayInt::Aggregate(const DataArrayInt *a1, const DataArrayInt *a2, int offsetA2)
7985 {
7986   if(!a1 || !a2)
7987     throw INTERP_KERNEL::Exception("DataArrayInt::Aggregate : input DataArrayInt instance is NULL !");
7988   int nbOfComp=a1->getNumberOfComponents();
7989   if(nbOfComp!=a2->getNumberOfComponents())
7990     throw INTERP_KERNEL::Exception("Nb of components mismatch for array Aggregation !");
7991   int nbOfTuple1=a1->getNumberOfTuples();
7992   int nbOfTuple2=a2->getNumberOfTuples();
7993   DataArrayInt *ret=DataArrayInt::New();
7994   ret->alloc(nbOfTuple1+nbOfTuple2-offsetA2,nbOfComp);
7995   int *pt=std::copy(a1->getConstPointer(),a1->getConstPointer()+nbOfTuple1*nbOfComp,ret->getPointer());
7996   std::copy(a2->getConstPointer()+offsetA2*nbOfComp,a2->getConstPointer()+nbOfTuple2*nbOfComp,pt);
7997   ret->copyStringInfoFrom(*a1);
7998   return ret;
7999 }
8000
8001 /*!
8002  * Returns a new DataArrayInt by concatenating all given arrays, so that (1) the number
8003  * of tuples in the result array is a sum of the number of tuples of given arrays and (2)
8004  * the number of component in the result array is same as that of each of given arrays.
8005  * Info on components is copied from the first of the given arrays. Number of components
8006  * in the given arrays must be  the same.
8007  *  \param [in] arr - a sequence of arrays to include in the result array.
8008  *  \return DataArrayInt * - the new instance of DataArrayInt.
8009  *          The caller is to delete this result array using decrRef() as it is no more
8010  *          needed.
8011  *  \throw If all arrays within \a arr are NULL.
8012  *  \throw If getNumberOfComponents() of arrays within \a arr.
8013  */
8014 DataArrayInt *DataArrayInt::Aggregate(const std::vector<const DataArrayInt *>& arr) throw(INTERP_KERNEL::Exception)
8015 {
8016   std::vector<const DataArrayInt *> a;
8017   for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
8018     if(*it4)
8019       a.push_back(*it4);
8020   if(a.empty())
8021     throw INTERP_KERNEL::Exception("DataArrayInt::Aggregate : input list must be NON EMPTY !");
8022   std::vector<const DataArrayInt *>::const_iterator it=a.begin();
8023   int nbOfComp=(*it)->getNumberOfComponents();
8024   int nbt=(*it++)->getNumberOfTuples();
8025   for(int i=1;it!=a.end();it++,i++)
8026     {
8027       if((*it)->getNumberOfComponents()!=nbOfComp)
8028         throw INTERP_KERNEL::Exception("DataArrayInt::Aggregate : Nb of components mismatch for array aggregation !");
8029       nbt+=(*it)->getNumberOfTuples();
8030     }
8031   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
8032   ret->alloc(nbt,nbOfComp);
8033   int *pt=ret->getPointer();
8034   for(it=a.begin();it!=a.end();it++)
8035     pt=std::copy((*it)->getConstPointer(),(*it)->getConstPointer()+(*it)->getNbOfElems(),pt);
8036   ret->copyStringInfoFrom(*(a[0]));
8037   return ret.retn();
8038 }
8039
8040 /*!
8041  * Returns the maximal value and its location within \a this one-dimensional array.
8042  *  \param [out] tupleId - index of the tuple holding the maximal value.
8043  *  \return double - the maximal value among all values of \a this array.
8044  *  \throw If \a this->getNumberOfComponents() != 1
8045  *  \throw If \a this->getNumberOfTuples() < 1
8046  */
8047 int DataArrayInt::getMaxValue(int& tupleId) const throw(INTERP_KERNEL::Exception)
8048 {
8049   checkAllocated();
8050   if(getNumberOfComponents()!=1)
8051     throw INTERP_KERNEL::Exception("DataArrayInt::getMaxValue : must be applied on DataArrayInt with only one component !");
8052   int nbOfTuples=getNumberOfTuples();
8053   if(nbOfTuples<=0)
8054     throw INTERP_KERNEL::Exception("DataArrayInt::getMaxValue : array exists but number of tuples must be > 0 !");
8055   const int *vals=getConstPointer();
8056   const int *loc=std::max_element(vals,vals+nbOfTuples);
8057   tupleId=(int)std::distance(vals,loc);
8058   return *loc;
8059 }
8060
8061 /*!
8062  * Returns the maximal value within \a this array that is allowed to have more than
8063  *  one component.
8064  *  \return int - the maximal value among all values of \a this array.
8065  *  \throw If \a this is not allocated.
8066  */
8067 int DataArrayInt::getMaxValueInArray() const throw(INTERP_KERNEL::Exception)
8068 {
8069   checkAllocated();
8070   const int *loc=std::max_element(begin(),end());
8071   return *loc;
8072 }
8073
8074 /*!
8075  * Returns the minimal value and its location within \a this one-dimensional array.
8076  *  \param [out] tupleId - index of the tuple holding the minimal value.
8077  *  \return int - the minimal value among all values of \a this array.
8078  *  \throw If \a this->getNumberOfComponents() != 1
8079  *  \throw If \a this->getNumberOfTuples() < 1
8080  */
8081 int DataArrayInt::getMinValue(int& tupleId) const throw(INTERP_KERNEL::Exception)
8082 {
8083   checkAllocated();
8084   if(getNumberOfComponents()!=1)
8085     throw INTERP_KERNEL::Exception("DataArrayInt::getMaxValue : must be applied on DataArrayInt with only one component !");
8086   int nbOfTuples=getNumberOfTuples();
8087   if(nbOfTuples<=0)
8088     throw INTERP_KERNEL::Exception("DataArrayInt::getMaxValue : array exists but number of tuples must be > 0 !");
8089   const int *vals=getConstPointer();
8090   const int *loc=std::min_element(vals,vals+nbOfTuples);
8091   tupleId=(int)std::distance(vals,loc);
8092   return *loc;
8093 }
8094
8095 /*!
8096  * Returns the minimal value within \a this array that is allowed to have more than
8097  *  one component.
8098  *  \return int - the minimal value among all values of \a this array.
8099  *  \throw If \a this is not allocated.
8100  */
8101 int DataArrayInt::getMinValueInArray() const throw(INTERP_KERNEL::Exception)
8102 {
8103   checkAllocated();
8104   const int *loc=std::min_element(begin(),end());
8105   return *loc;
8106 }
8107
8108 /*!
8109  * Converts every value of \a this array to its absolute value.
8110  *  \throw If \a this is not allocated.
8111  */
8112 void DataArrayInt::abs() throw(INTERP_KERNEL::Exception)
8113 {
8114   checkAllocated();
8115   int *ptr=getPointer();
8116   std::size_t nbOfElems=getNbOfElems();
8117   std::transform(ptr,ptr+nbOfElems,ptr,std::ptr_fun<int,int>(std::abs));
8118   declareAsNew();
8119 }
8120
8121 /*!
8122  * Apply a liner function to a given component of \a this array, so that
8123  * an array element <em>(x)</em> becomes \f$ a * x + b \f$.
8124  *  \param [in] a - the first coefficient of the function.
8125  *  \param [in] b - the second coefficient of the function.
8126  *  \param [in] compoId - the index of component to modify.
8127  *  \throw If \a this is not allocated.
8128  */
8129 void DataArrayInt::applyLin(int a, int b, int compoId) throw(INTERP_KERNEL::Exception)
8130 {
8131   checkAllocated();
8132   int *ptr=getPointer()+compoId;
8133   int nbOfComp=getNumberOfComponents();
8134   int nbOfTuple=getNumberOfTuples();
8135   for(int i=0;i<nbOfTuple;i++,ptr+=nbOfComp)
8136     *ptr=a*(*ptr)+b;
8137   declareAsNew();
8138 }
8139
8140 /*!
8141  * Apply a liner function to all elements of \a this array, so that
8142  * an element _x_ becomes \f$ a * x + b \f$.
8143  *  \param [in] a - the first coefficient of the function.
8144  *  \param [in] b - the second coefficient of the function.
8145  *  \throw If \a this is not allocated.
8146  */
8147 void DataArrayInt::applyLin(int a, int b) throw(INTERP_KERNEL::Exception)
8148 {
8149   checkAllocated();
8150   int *ptr=getPointer();
8151   std::size_t nbOfElems=getNbOfElems();
8152   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
8153     *ptr=a*(*ptr)+b;
8154   declareAsNew();
8155 }
8156
8157 /*!
8158  * Returns a full copy of \a this array except that sign of all elements is reversed.
8159  *  \return DataArrayInt * - the new instance of DataArrayInt containing the
8160  *          same number of tuples and component as \a this array.
8161  *          The caller is to delete this result array using decrRef() as it is no more
8162  *          needed.
8163  *  \throw If \a this is not allocated.
8164  */
8165 DataArrayInt *DataArrayInt::negate() const throw(INTERP_KERNEL::Exception)
8166 {
8167   checkAllocated();
8168   DataArrayInt *newArr=DataArrayInt::New();
8169   int nbOfTuples=getNumberOfTuples();
8170   int nbOfComp=getNumberOfComponents();
8171   newArr->alloc(nbOfTuples,nbOfComp);
8172   const int *cptr=getConstPointer();
8173   std::transform(cptr,cptr+nbOfTuples*nbOfComp,newArr->getPointer(),std::negate<int>());
8174   newArr->copyStringInfoFrom(*this);
8175   return newArr;
8176 }
8177
8178 /*!
8179  * Modify all elements of \a this array, so that
8180  * an element _x_ becomes \f$ numerator / x \f$.
8181  *  \warning If an exception is thrown because of presence of 0 element in \a this 
8182  *           array, all elements processed before detection of the zero element remain
8183  *           modified.
8184  *  \param [in] numerator - the numerator used to modify array elements.
8185  *  \throw If \a this is not allocated.
8186  *  \throw If there is an element equal to 0 in \a this array.
8187  */
8188 void DataArrayInt::applyInv(int numerator) throw(INTERP_KERNEL::Exception)
8189 {
8190   checkAllocated();
8191   int *ptr=getPointer();
8192   std::size_t nbOfElems=getNbOfElems();
8193   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
8194     {
8195       if(*ptr!=0)
8196         {
8197           *ptr=numerator/(*ptr);
8198         }
8199       else
8200         {
8201           std::ostringstream oss; oss << "DataArrayInt::applyInv : presence of null value in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
8202           oss << " !";
8203           throw INTERP_KERNEL::Exception(oss.str().c_str());
8204         }
8205     }
8206   declareAsNew();
8207 }
8208
8209 /*!
8210  * Modify all elements of \a this array, so that
8211  * an element _x_ becomes \f$ x / val \f$.
8212  *  \param [in] val - the denominator used to modify array elements.
8213  *  \throw If \a this is not allocated.
8214  *  \throw If \a val == 0.
8215  */
8216 void DataArrayInt::applyDivideBy(int val) throw(INTERP_KERNEL::Exception)
8217 {
8218   if(val==0)
8219     throw INTERP_KERNEL::Exception("DataArrayInt::applyDivideBy : Trying to divide by 0 !");
8220   checkAllocated();
8221   int *ptr=getPointer();
8222   std::size_t nbOfElems=getNbOfElems();
8223   std::transform(ptr,ptr+nbOfElems,ptr,std::bind2nd(std::divides<int>(),val));
8224   declareAsNew();
8225 }
8226
8227 /*!
8228  * Modify all elements of \a this array, so that
8229  * an element _x_ becomes  <em> x % val </em>.
8230  *  \param [in] val - the divisor used to modify array elements.
8231  *  \throw If \a this is not allocated.
8232  *  \throw If \a val <= 0.
8233  */
8234 void DataArrayInt::applyModulus(int val) throw(INTERP_KERNEL::Exception)
8235 {
8236   if(val<=0)
8237     throw INTERP_KERNEL::Exception("DataArrayInt::applyDivideBy : Trying to operate modulus on value <= 0 !");
8238   checkAllocated();
8239   int *ptr=getPointer();
8240   std::size_t nbOfElems=getNbOfElems();
8241   std::transform(ptr,ptr+nbOfElems,ptr,std::bind2nd(std::modulus<int>(),val));
8242   declareAsNew();
8243 }
8244
8245 /*!
8246  * This method works only on data array with one component.
8247  * This method returns a newly allocated array storing stored ascendantly tuple ids in \b this so that
8248  * this[*id] in [\b vmin,\b vmax)
8249  * 
8250  * \param [in] vmin begin of range. This value is included in range.
8251  * \param [out] vmax end of range. This value is \b not included in range.
8252  * \return a newly allocated data array that the caller should deal with.
8253  */
8254 DataArrayInt *DataArrayInt::getIdsInRange(int vmin, int vmax) const throw(INTERP_KERNEL::Exception)
8255 {
8256   checkAllocated();
8257   if(getNumberOfComponents()!=1)
8258     throw INTERP_KERNEL::Exception("DataArrayInt::getIdsInRange : this must have exactly one component !");
8259   const int *cptr=getConstPointer();
8260   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(0,1);
8261   int nbOfTuples=getNumberOfTuples();
8262   for(int i=0;i<nbOfTuples;i++,cptr++)
8263     if(*cptr>=vmin && *cptr<vmax)
8264       ret->pushBackSilent(i);
8265   return ret.retn();
8266 }
8267
8268 /*!
8269  * Modify all elements of \a this array, so that
8270  * an element _x_ becomes <em> val % x </em>.
8271  *  \warning If an exception is thrown because of presence of an element <= 0 in \a this 
8272  *           array, all elements processed before detection of the zero element remain
8273  *           modified.
8274  *  \param [in] val - the divident used to modify array elements.
8275  *  \throw If \a this is not allocated.
8276  *  \throw If there is an element equal to or less than 0 in \a this array.
8277  */
8278 void DataArrayInt::applyRModulus(int val) throw(INTERP_KERNEL::Exception)
8279 {
8280   checkAllocated();
8281   int *ptr=getPointer();
8282   std::size_t nbOfElems=getNbOfElems();
8283   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
8284     {
8285       if(*ptr>0)
8286         {
8287           *ptr=val%(*ptr);
8288         }
8289       else
8290         {
8291           std::ostringstream oss; oss << "DataArrayInt::applyRModulus : presence of value <=0 in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
8292           oss << " !";
8293           throw INTERP_KERNEL::Exception(oss.str().c_str());
8294         }
8295     }
8296   declareAsNew();
8297 }
8298
8299 /*!
8300  * Modify all elements of \a this array, so that
8301  * an element _x_ becomes <em> val ^ x </em>.
8302  *  \param [in] val - the value used to apply pow on all array elements.
8303  *  \throw If \a this is not allocated.
8304  *  \throw If \a val < 0.
8305  */
8306 void DataArrayInt::applyPow(int val) throw(INTERP_KERNEL::Exception)
8307 {
8308   checkAllocated();
8309   if(val<0)
8310     throw INTERP_KERNEL::Exception("DataArrayInt::applyPow : input pow in < 0 !");
8311   int *ptr=getPointer();
8312   std::size_t nbOfElems=getNbOfElems();
8313   if(val==0)
8314     {
8315       std::fill(ptr,ptr+nbOfElems,1.);
8316       return ;
8317     }
8318   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
8319     {
8320       int tmp=1;
8321       for(int j=0;j<val;j++)
8322         tmp*=*ptr;
8323       *ptr=tmp;
8324     }
8325   declareAsNew();
8326 }
8327
8328 /*!
8329  * Modify all elements of \a this array, so that
8330  * an element _x_ becomes \f$ val ^ x \f$.
8331  *  \param [in] val - the value used to apply pow on all array elements.
8332  *  \throw If \a this is not allocated.
8333  *  \throw If there is an element < 0 in \a this array.
8334  *  \warning If an exception is thrown because of presence of 0 element in \a this 
8335  *           array, all elements processed before detection of the zero element remain
8336  *           modified.
8337  */
8338 void DataArrayInt::applyRPow(int val) throw(INTERP_KERNEL::Exception)
8339 {
8340   checkAllocated();
8341   int *ptr=getPointer();
8342   std::size_t nbOfElems=getNbOfElems();
8343   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
8344     {
8345       if(*ptr>=0)
8346         {
8347           int tmp=1;
8348           for(int j=0;j<*ptr;j++)
8349             tmp*=val;
8350           *ptr=tmp;
8351         }
8352       else
8353         {
8354           std::ostringstream oss; oss << "DataArrayInt::applyRPow : presence of negative value in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
8355           oss << " !";
8356           throw INTERP_KERNEL::Exception(oss.str().c_str());
8357         }
8358     }
8359   declareAsNew();
8360 }
8361
8362 /*!
8363  * Returns a new DataArrayInt by aggregating two given arrays, so that (1) the number
8364  * of components in the result array is a sum of the number of components of given arrays
8365  * and (2) the number of tuples in the result array is same as that of each of given
8366  * arrays. In other words the i-th tuple of result array includes all components of
8367  * i-th tuples of all given arrays.
8368  * Number of tuples in the given arrays must be the same.
8369  *  \param [in] a1 - an array to include in the result array.
8370  *  \param [in] a2 - another array to include in the result array.
8371  *  \return DataArrayInt * - the new instance of DataArrayInt.
8372  *          The caller is to delete this result array using decrRef() as it is no more
8373  *          needed.
8374  *  \throw If both \a a1 and \a a2 are NULL.
8375  *  \throw If any given array is not allocated.
8376  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
8377  */
8378 DataArrayInt *DataArrayInt::Meld(const DataArrayInt *a1, const DataArrayInt *a2) throw(INTERP_KERNEL::Exception)
8379 {
8380   std::vector<const DataArrayInt *> arr(2);
8381   arr[0]=a1; arr[1]=a2;
8382   return Meld(arr);
8383 }
8384
8385 /*!
8386  * Returns a new DataArrayInt by aggregating all given arrays, so that (1) the number
8387  * of components in the result array is a sum of the number of components of given arrays
8388  * and (2) the number of tuples in the result array is same as that of each of given
8389  * arrays. In other words the i-th tuple of result array includes all components of
8390  * i-th tuples of all given arrays.
8391  * Number of tuples in the given arrays must be  the same.
8392  *  \param [in] arr - a sequence of arrays to include in the result array.
8393  *  \return DataArrayInt * - the new instance of DataArrayInt.
8394  *          The caller is to delete this result array using decrRef() as it is no more
8395  *          needed.
8396  *  \throw If all arrays within \a arr are NULL.
8397  *  \throw If any given array is not allocated.
8398  *  \throw If getNumberOfTuples() of arrays within \a arr is different.
8399  */
8400 DataArrayInt *DataArrayInt::Meld(const std::vector<const DataArrayInt *>& arr) throw(INTERP_KERNEL::Exception)
8401 {
8402   std::vector<const DataArrayInt *> a;
8403   for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
8404     if(*it4)
8405       a.push_back(*it4);
8406   if(a.empty())
8407     throw INTERP_KERNEL::Exception("DataArrayInt::Meld : array must be NON empty !");
8408   std::vector<const DataArrayInt *>::const_iterator it;
8409   for(it=a.begin();it!=a.end();it++)
8410     (*it)->checkAllocated();
8411   it=a.begin();
8412   int nbOfTuples=(*it)->getNumberOfTuples();
8413   std::vector<int> nbc(a.size());
8414   std::vector<const int *> pts(a.size());
8415   nbc[0]=(*it)->getNumberOfComponents();
8416   pts[0]=(*it++)->getConstPointer();
8417   for(int i=1;it!=a.end();it++,i++)
8418     {
8419       if(nbOfTuples!=(*it)->getNumberOfTuples())
8420         throw INTERP_KERNEL::Exception("DataArrayInt::meld : mismatch of number of tuples !");
8421       nbc[i]=(*it)->getNumberOfComponents();
8422       pts[i]=(*it)->getConstPointer();
8423     }
8424   int totalNbOfComp=std::accumulate(nbc.begin(),nbc.end(),0);
8425   DataArrayInt *ret=DataArrayInt::New();
8426   ret->alloc(nbOfTuples,totalNbOfComp);
8427   int *retPtr=ret->getPointer();
8428   for(int i=0;i<nbOfTuples;i++)
8429     for(int j=0;j<(int)a.size();j++)
8430       {
8431         retPtr=std::copy(pts[j],pts[j]+nbc[j],retPtr);
8432         pts[j]+=nbc[j];
8433       }
8434   int k=0;
8435   for(int i=0;i<(int)a.size();i++)
8436     for(int j=0;j<nbc[i];j++,k++)
8437       ret->setInfoOnComponent(k,a[i]->getInfoOnComponent(j).c_str());
8438   return ret;
8439 }
8440
8441 /*!
8442  * Returns a new DataArrayInt which is a minimal partition of elements of \a groups.
8443  * The i-th item of the result array is an ID of a set of elements belonging to a
8444  * unique set of groups, which the i-th element is a part of. This set of elements
8445  * belonging to a unique set of groups is called \a family, so the result array contains
8446  * IDs of families each element belongs to.
8447  *
8448  * \b Example: if we have two groups of elements: \a group1 [0,4] and \a group2 [ 0,1,2 ],
8449  * then there are 3 families:
8450  * - \a family1 (with ID 1) contains element [0] belonging to ( \a group1 + \a group2 ),
8451  * - \a family2 (with ID 2) contains elements [4] belonging to ( \a group1 ),
8452  * - \a family3 (with ID 3) contains element [1,2] belonging to ( \a group2 ), <br>
8453  * and the result array contains IDs of families [ 1,3,3,0,2 ]. <br> Note a family ID 0 which
8454  * stands for the element #3 which is in none of groups.
8455  *
8456  *  \param [in] groups - sequence of groups of element IDs.
8457  *  \param [in] newNb - total number of elements; it must be more than max ID of element
8458  *         in \a groups.
8459  *  \param [out] fidsOfGroups - IDs of families the elements of each group belong to.
8460  *  \return DataArrayInt * - a new instance of DataArrayInt containing IDs of families
8461  *         each element with ID from range [0, \a newNb ) belongs to. The caller is to
8462  *         delete this array using decrRef() as it is no more needed.
8463  *  \throw If any element ID in \a groups violates condition ( 0 <= ID < \a newNb ).
8464  */
8465 DataArrayInt *DataArrayInt::MakePartition(const std::vector<const DataArrayInt *>& groups, int newNb, std::vector< std::vector<int> >& fidsOfGroups) throw(INTERP_KERNEL::Exception)
8466 {
8467   std::vector<const DataArrayInt *> groups2;
8468   for(std::vector<const DataArrayInt *>::const_iterator it4=groups.begin();it4!=groups.end();it4++)
8469     if(*it4)
8470       groups2.push_back(*it4);
8471   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
8472   ret->alloc(newNb,1);
8473   int *retPtr=ret->getPointer();
8474   std::fill(retPtr,retPtr+newNb,0);
8475   int fid=1;
8476   for(std::vector<const DataArrayInt *>::const_iterator iter=groups2.begin();iter!=groups2.end();iter++)
8477     {
8478       const int *ptr=(*iter)->getConstPointer();
8479       std::size_t nbOfElem=(*iter)->getNbOfElems();
8480       int sfid=fid;
8481       for(int j=0;j<sfid;j++)
8482         {
8483           bool found=false;
8484           for(std::size_t i=0;i<nbOfElem;i++)
8485             {
8486               if(ptr[i]>=0 && ptr[i]<newNb)
8487                 {
8488                   if(retPtr[ptr[i]]==j)
8489                     {
8490                       retPtr[ptr[i]]=fid;
8491                       found=true;
8492                     }
8493                 }
8494               else
8495                 {
8496                   std::ostringstream oss; oss << "DataArrayInt::MakePartition : In group \"" << (*iter)->getName() << "\" in tuple #" << i << " value = " << ptr[i] << " ! Should be in [0," << newNb;
8497                   oss << ") !";
8498                   throw INTERP_KERNEL::Exception(oss.str().c_str());
8499                 }
8500             }
8501           if(found)
8502             fid++;
8503         }
8504     }
8505   fidsOfGroups.clear();
8506   fidsOfGroups.resize(groups2.size());
8507   int grId=0;
8508   for(std::vector<const DataArrayInt *>::const_iterator iter=groups2.begin();iter!=groups2.end();iter++,grId++)
8509     {
8510       std::set<int> tmp;
8511       const int *ptr=(*iter)->getConstPointer();
8512       std::size_t nbOfElem=(*iter)->getNbOfElems();
8513       for(const int *p=ptr;p!=ptr+nbOfElem;p++)
8514         tmp.insert(retPtr[*p]);
8515       fidsOfGroups[grId].insert(fidsOfGroups[grId].end(),tmp.begin(),tmp.end());
8516     }
8517   return ret.retn();
8518 }
8519
8520 /*!
8521  * Returns a new DataArrayInt which contains all elements of given one-dimensional
8522  * not negative arrays. The result array does not contain any duplicates and its values
8523  * are sorted in ascending order.
8524  *  \param [in] arr - sequence of DataArrayInt's to unite.
8525  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
8526  *         array using decrRef() as it is no more needed.
8527  *  \throw If any \a arr[i] is not allocated.
8528  *  \throw If \a arr[i]->getNumberOfComponents() != 1.
8529  *  \throw If any value of \a arr[i] is negative.
8530  */
8531 DataArrayInt *DataArrayInt::BuildUnion(const std::vector<const DataArrayInt *>& arr) throw(INTERP_KERNEL::Exception)
8532 {
8533   std::vector<const DataArrayInt *> a;
8534   for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
8535     if(*it4)
8536       a.push_back(*it4);
8537   int valm=std::numeric_limits<int>::max();
8538   for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
8539     {
8540       (*it)->checkAllocated();
8541       if((*it)->getNumberOfComponents()!=1)
8542         throw INTERP_KERNEL::Exception("DataArrayInt::BuildUnion : only single component allowed !");
8543       int tmp1;
8544       valm=std::min((*it)->getMinValue(tmp1),valm);
8545     }
8546   if(valm<0)
8547     throw INTERP_KERNEL::Exception("DataArrayInt::BuildUnion : a negative value has been detected !");
8548   //
8549   std::set<int> r;
8550   for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
8551     {
8552       const int *pt=(*it)->getConstPointer();
8553       int nbOfTuples=(*it)->getNumberOfTuples();
8554       r.insert(pt,pt+nbOfTuples);
8555     }
8556   DataArrayInt *ret=DataArrayInt::New();
8557   ret->alloc((int)r.size(),1);
8558   std::copy(r.begin(),r.end(),ret->getPointer());
8559   return ret;
8560 }
8561
8562 /*!
8563  * Returns a new DataArrayInt which contains elements present in each of given one-dimensional
8564  * not negative arrays. The result array does not contain any duplicates and its values
8565  * are sorted in ascending order.
8566  *  \param [in] arr - sequence of DataArrayInt's to intersect.
8567  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
8568  *         array using decrRef() as it is no more needed.
8569  *  \throw If any \a arr[i] is not allocated.
8570  *  \throw If \a arr[i]->getNumberOfComponents() != 1.
8571  *  \throw If any value of \a arr[i] < 0.
8572  */
8573 DataArrayInt *DataArrayInt::BuildIntersection(const std::vector<const DataArrayInt *>& arr) throw(INTERP_KERNEL::Exception)
8574 {
8575   std::vector<const DataArrayInt *> a;
8576   for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
8577     if(*it4)
8578       a.push_back(*it4);
8579   int valm=std::numeric_limits<int>::max();
8580   for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
8581     {
8582       (*it)->checkAllocated();
8583       if((*it)->getNumberOfComponents()!=1)
8584         throw INTERP_KERNEL::Exception("DataArrayInt::BuildIntersection : only single component allowed !");
8585       int tmp1;
8586       valm=std::min((*it)->getMinValue(tmp1),valm);
8587     }
8588   if(valm<0)
8589     throw INTERP_KERNEL::Exception("DataArrayInt::BuildIntersection : a negative value has been detected !");
8590   //
8591   std::set<int> r;
8592   for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
8593     {
8594       const int *pt=(*it)->getConstPointer();
8595       int nbOfTuples=(*it)->getNumberOfTuples();
8596       std::set<int> s1(pt,pt+nbOfTuples);
8597       if(it!=a.begin())
8598         {
8599           std::set<int> r2;
8600           std::set_intersection(r.begin(),r.end(),s1.begin(),s1.end(),inserter(r2,r2.end()));
8601           r=r2;
8602         }
8603       else
8604         r=s1;
8605     }
8606   DataArrayInt *ret=DataArrayInt::New();
8607   ret->alloc((int)r.size(),1);
8608   std::copy(r.begin(),r.end(),ret->getPointer());
8609   return ret;
8610 }
8611
8612 /*!
8613  * Returns a new DataArrayInt which contains a complement of elements of \a this
8614  * one-dimensional array. I.e. the result array contains all elements from the range [0,
8615  * \a nbOfElement) not present in \a this array.
8616  *  \param [in] nbOfElement - maximal size of the result array.
8617  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
8618  *         array using decrRef() as it is no more needed.
8619  *  \throw If \a this is not allocated.
8620  *  \throw If \a this->getNumberOfComponents() != 1.
8621  *  \throw If any element \a x of \a this array violates condition ( 0 <= \a x < \a
8622  *         nbOfElement ).
8623  */
8624 DataArrayInt *DataArrayInt::buildComplement(int nbOfElement) const throw(INTERP_KERNEL::Exception)
8625 {
8626    checkAllocated();
8627    if(getNumberOfComponents()!=1)
8628      throw INTERP_KERNEL::Exception("DataArrayInt::buildComplement : only single component allowed !");
8629    std::vector<bool> tmp(nbOfElement);
8630    const int *pt=getConstPointer();
8631    int nbOfTuples=getNumberOfTuples();
8632    for(const int *w=pt;w!=pt+nbOfTuples;w++)
8633      if(*w>=0 && *w<nbOfElement)
8634        tmp[*w]=true;
8635      else
8636        throw INTERP_KERNEL::Exception("DataArrayInt::buildComplement : an element is not in valid range : [0,nbOfElement) !");
8637    int nbOfRetVal=(int)std::count(tmp.begin(),tmp.end(),false);
8638    DataArrayInt *ret=DataArrayInt::New();
8639    ret->alloc(nbOfRetVal,1);
8640    int j=0;
8641    int *retPtr=ret->getPointer();
8642    for(int i=0;i<nbOfElement;i++)
8643      if(!tmp[i])
8644        retPtr[j++]=i;
8645    return ret;
8646 }
8647
8648 /*!
8649  * Returns a new DataArrayInt containing elements of \a this one-dimensional missing
8650  * from an \a other one-dimensional array.
8651  *  \param [in] other - a DataArrayInt containing elements not to include in the result array.
8652  *  \return DataArrayInt * - a new instance of DataArrayInt with one component. The
8653  *         caller is to delete this array using decrRef() as it is no more needed.
8654  *  \throw If \a other is NULL.
8655  *  \throw If \a other is not allocated.
8656  *  \throw If \a other->getNumberOfComponents() != 1.
8657  *  \throw If \a this is not allocated.
8658  *  \throw If \a this->getNumberOfComponents() != 1.
8659  *  \sa DataArrayInt::buildSubstractionOptimized()
8660  */
8661 DataArrayInt *DataArrayInt::buildSubstraction(const DataArrayInt *other) const throw(INTERP_KERNEL::Exception)
8662 {
8663   if(!other)
8664     throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstraction : DataArrayInt pointer in input is NULL !");
8665   checkAllocated();
8666   other->checkAllocated();
8667   if(getNumberOfComponents()!=1)
8668      throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstraction : only single component allowed !");
8669   if(other->getNumberOfComponents()!=1)
8670      throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstraction : only single component allowed for other type !");
8671   const int *pt=getConstPointer();
8672   int nbOfTuples=getNumberOfTuples();
8673   std::set<int> s1(pt,pt+nbOfTuples);
8674   pt=other->getConstPointer();
8675   nbOfTuples=other->getNumberOfTuples();
8676   std::set<int> s2(pt,pt+nbOfTuples);
8677   std::vector<int> r;
8678   std::set_difference(s1.begin(),s1.end(),s2.begin(),s2.end(),std::back_insert_iterator< std::vector<int> >(r));
8679   DataArrayInt *ret=DataArrayInt::New();
8680   ret->alloc((int)r.size(),1);
8681   std::copy(r.begin(),r.end(),ret->getPointer());
8682   return ret;
8683 }
8684
8685 /*!
8686  * \a this is expected to have one component and to be sorted ascendingly (as for \a other).
8687  * \a other is expected to be a part of \a this. If not DataArrayInt::buildSubstraction should be called instead.
8688  * 
8689  * \param [in] other an array with one component and expected to be sorted ascendingly.
8690  * \ret list of ids in \a this but not in \a other.
8691  * \sa DataArrayInt::buildSubstraction
8692  */
8693 DataArrayInt *DataArrayInt::buildSubstractionOptimized(const DataArrayInt *other) const throw(INTERP_KERNEL::Exception)
8694 {
8695   static const char *MSG="DataArrayInt::buildSubstractionOptimized : only single component allowed !";
8696   if(!other) throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstractionOptimized : NULL input array !");
8697   checkAllocated(); other->checkAllocated();
8698   if(getNumberOfComponents()!=1) throw INTERP_KERNEL::Exception(MSG);
8699   if(other->getNumberOfComponents()!=1) throw INTERP_KERNEL::Exception(MSG);
8700   const int *pt1Bg(begin()),*pt1End(end()),*pt2Bg(other->begin()),*pt2End(other->end()),*work1(pt1Bg),*work2(pt2Bg);
8701   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
8702   for(;work1!=pt1End;work1++)
8703     {
8704       if(work2!=pt2End && *work1==*work2)
8705         work2++;
8706       else
8707         ret->pushBackSilent(*work1);
8708     }
8709   return ret.retn();
8710 }
8711
8712
8713 /*!
8714  * Returns a new DataArrayInt which contains all elements of \a this and a given
8715  * one-dimensional not negative arrays. The result array does not contain any duplicates
8716  * and its values are sorted in ascending order.
8717  *  \param [in] other - an array to unite with \a this one.
8718  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
8719  *         array using decrRef() as it is no more needed.
8720  *  \throw If \a this or \a other is not allocated.
8721  *  \throw If \a this->getNumberOfComponents() != 1.
8722  *  \throw If \a other->getNumberOfComponents() != 1.
8723  *  \throw If any value of \a this or \a other is negative.
8724  */
8725 DataArrayInt *DataArrayInt::buildUnion(const DataArrayInt *other) const throw(INTERP_KERNEL::Exception)
8726 {
8727   std::vector<const DataArrayInt *>arrs(2);
8728   arrs[0]=this; arrs[1]=other;
8729   return BuildUnion(arrs);
8730 }
8731
8732
8733 /*!
8734  * Returns a new DataArrayInt which contains elements present in both \a this and a given
8735  * one-dimensional not negative arrays. The result array does not contain any duplicates
8736  * and its values are sorted in ascending order.
8737  *  \param [in] other - an array to intersect with \a this one.
8738  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
8739  *         array using decrRef() as it is no more needed.
8740  *  \throw If \a this or \a other is not allocated.
8741  *  \throw If \a this->getNumberOfComponents() != 1.
8742  *  \throw If \a other->getNumberOfComponents() != 1.
8743  *  \throw If any value of \a this or \a other is negative.
8744  */
8745 DataArrayInt *DataArrayInt::buildIntersection(const DataArrayInt *other) const throw(INTERP_KERNEL::Exception)
8746 {
8747   std::vector<const DataArrayInt *>arrs(2);
8748   arrs[0]=this; arrs[1]=other;
8749   return BuildIntersection(arrs);
8750 }
8751
8752 /*!
8753  * This method can be applied on allocated with one component DataArrayInt instance.
8754  * This method is typically relevant for sorted arrays. All consecutive duplicated items in \a this will appear only once in returned DataArrayInt instance.
8755  * 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]
8756  * 
8757  * \return a newly allocated array that contain the result of the unique operation applied on \a this.
8758  * \throw if \a this is not allocated or if \a this has not exactly one component.
8759  */
8760 DataArrayInt *DataArrayInt::buildUnique() const throw(INTERP_KERNEL::Exception)
8761 {
8762   checkAllocated();
8763   if(getNumberOfComponents()!=1)
8764      throw INTERP_KERNEL::Exception("DataArrayInt::buildUnique : only single component allowed !");
8765   int nbOfTuples=getNumberOfTuples();
8766   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp=deepCpy();
8767   int *data=tmp->getPointer();
8768   int *last=std::unique(data,data+nbOfTuples);
8769   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
8770   ret->alloc(std::distance(data,last),1);
8771   std::copy(data,last,ret->getPointer());
8772   return ret.retn();
8773 }
8774
8775 /*!
8776  * Returns a new DataArrayInt which contains size of every of groups described by \a this
8777  * "index" array. Such "index" array is returned for example by 
8778  * \ref ParaMEDMEM::MEDCouplingUMesh::buildDescendingConnectivity
8779  * "MEDCouplingUMesh::buildDescendingConnectivity" and
8780  * \ref ParaMEDMEM::MEDCouplingUMesh::getNodalConnectivityIndex
8781  * "MEDCouplingUMesh::getNodalConnectivityIndex" etc.
8782  *  \return DataArrayInt * - a new instance of DataArrayInt, whose number of tuples
8783  *          equals to \a this->getNumberOfComponents() - 1, and number of components is 1.
8784  *          The caller is to delete this array using decrRef() as it is no more needed. 
8785  *  \throw If \a this is not allocated.
8786  *  \throw If \a this->getNumberOfComponents() != 1.
8787  *  \throw If \a this->getNumberOfTuples() < 2.
8788  *
8789  *  \b Example: <br> 
8790  *         - this contains [1,3,6,7,7,9,15]
8791  *         - result array contains [2,3,1,0,2,6],
8792  *          where 2 = 3 - 1, 3 = 6 - 3, 1 = 7 - 6 etc.
8793  */
8794 DataArrayInt *DataArrayInt::deltaShiftIndex() const throw(INTERP_KERNEL::Exception)
8795 {
8796   checkAllocated();
8797   if(getNumberOfComponents()!=1)
8798      throw INTERP_KERNEL::Exception("DataArrayInt::deltaShiftIndex : only single component allowed !");
8799   int nbOfTuples=getNumberOfTuples();
8800   if(nbOfTuples<2)
8801     throw INTERP_KERNEL::Exception("DataArrayInt::deltaShiftIndex : 1 tuple at least must be present in 'this' !");
8802   const int *ptr=getConstPointer();
8803   DataArrayInt *ret=DataArrayInt::New();
8804   ret->alloc(nbOfTuples-1,1);
8805   int *out=ret->getPointer();
8806   std::transform(ptr+1,ptr+nbOfTuples,ptr,out,std::minus<int>());
8807   return ret;
8808 }
8809
8810 /*!
8811  * Modifies \a this one-dimensional array so that value of each element \a x
8812  * of \a this array (\a a) is computed as \f$ x_i = \sum_{j=0}^{i-1} a[ j ] \f$.
8813  * Or: for each i>0 new[i]=new[i-1]+old[i-1] for i==0 new[i]=0. Number of tuples
8814  * and components remains the same.<br>
8815  * This method is useful for allToAllV in MPI with contiguous policy. This method
8816  * differs from computeOffsets2() in that the number of tuples is \b not changed by
8817  * this one.
8818  *  \throw If \a this is not allocated.
8819  *  \throw If \a this->getNumberOfComponents() != 1.
8820  *
8821  *  \b Example: <br>
8822  *          - Before \a this contains [3,5,1,2,0,8]
8823  *          - After \a this contains  [0,3,8,9,11,11]<br>
8824  *          Note that the last element 19 = 11 + 8 is missing because size of \a this
8825  *          array is retained and thus there is no space to store the last element.
8826  */
8827 void DataArrayInt::computeOffsets() throw(INTERP_KERNEL::Exception)
8828 {
8829   checkAllocated();
8830   if(getNumberOfComponents()!=1)
8831      throw INTERP_KERNEL::Exception("DataArrayInt::computeOffsets : only single component allowed !");
8832   int nbOfTuples=getNumberOfTuples();
8833   if(nbOfTuples==0)
8834     return ;
8835   int *work=getPointer();
8836   int tmp=work[0];
8837   work[0]=0;
8838   for(int i=1;i<nbOfTuples;i++)
8839     {
8840       int tmp2=work[i];
8841       work[i]=work[i-1]+tmp;
8842       tmp=tmp2;
8843     }
8844   declareAsNew();
8845 }
8846
8847
8848 /*!
8849  * Modifies \a this one-dimensional array so that value of each element \a x
8850  * of \a this array (\a a) is computed as \f$ x_i = \sum_{j=0}^{i-1} a[ j ] \f$.
8851  * Or: for each i>0 new[i]=new[i-1]+old[i-1] for i==0 new[i]=0. Number
8852  * components remains the same and number of tuples is inceamented by one.<br>
8853  * This method is useful for allToAllV in MPI with contiguous policy. This method
8854  * differs from computeOffsets() in that the number of tuples is changed by this one.
8855  *  \throw If \a this is not allocated.
8856  *  \throw If \a this->getNumberOfComponents() != 1.
8857  *
8858  *  \b Example: <br>
8859  *          - Before \a this contains [3,5,1,2,0,8]
8860  *          - After \a this contains  [0,3,8,9,11,11,19]<br>
8861  */
8862 void DataArrayInt::computeOffsets2() throw(INTERP_KERNEL::Exception)
8863 {
8864   checkAllocated();
8865   if(getNumberOfComponents()!=1)
8866     throw INTERP_KERNEL::Exception("DataArrayInt::computeOffsets2 : only single component allowed !");
8867   int nbOfTuples=getNumberOfTuples();
8868   int *ret=new int[nbOfTuples+1];
8869   if(nbOfTuples==0)
8870     return ;
8871   const int *work=getConstPointer();
8872   ret[0]=0;
8873   for(int i=0;i<nbOfTuples;i++)
8874     ret[i+1]=work[i]+ret[i];
8875   useArray(ret,true,CPP_DEALLOC,nbOfTuples+1,1);
8876   declareAsNew();
8877 }
8878
8879 /*!
8880  * Returns two new DataArrayInt instances whose contents is computed from that of \a this and \a listOfIds arrays as follows.
8881  * \a this is expected to be an offset format ( as returned by DataArrayInt::computeOffsets2 ) that is to say with one component
8882  * and ** sorted strictly increasingly **. \a listOfIds is expected to be sorted ascendingly (not strictly needed for \a listOfIds).
8883  * This methods searches in \a this, considered as a set of contiguous \c this->getNumberOfComponents() ranges, all ids in \a listOfIds
8884  * filling completely one of the ranges in \a this.
8885  *
8886  * \param [in] listOfIds a list of ids that has to be sorted ascendingly.
8887  * \param [out] rangeIdsFetched the range ids fetched
8888  * \param [out] idsInInputListThatFetch contains the list of ids in \a listOfIds that are \b fully included in a range in \a this. So
8889  *              \a idsInInputListThatFetch is a part of input \a listOfIds.
8890  *
8891  * \sa DataArrayInt::computeOffsets2
8892  *
8893  *  \b Example: <br>
8894  *          - \a this : [0,3,7,9,15,18]
8895  *          - \a listOfIds contains  [0,1,2,3,7,8,15,16,17]
8896  *          - \a rangeIdsFetched result array: [0,2,4]
8897  *          - \a idsInInputListThatFetch result array: [0,1,2,7,8,15,16,17]
8898  * In this example id 3 in input \a listOfIds is alone so it do not appear in output \a idsInInputListThatFetch.
8899  * <br>
8900  */
8901 void DataArrayInt::searchRangesInListOfIds(const DataArrayInt *listOfIds, DataArrayInt *& rangeIdsFetched, DataArrayInt *& idsInInputListThatFetch) const throw(INTERP_KERNEL::Exception)
8902 {
8903   if(!listOfIds)
8904     throw INTERP_KERNEL::Exception("DataArrayInt::searchRangesInListOfIds : input list of ids is null !");
8905   listOfIds->checkAllocated(); checkAllocated();
8906   if(listOfIds->getNumberOfComponents()!=1)
8907     throw INTERP_KERNEL::Exception("DataArrayInt::searchRangesInListOfIds : input list of ids must have exactly one component !");
8908   if(getNumberOfComponents()!=1)
8909     throw INTERP_KERNEL::Exception("DataArrayInt::searchRangesInListOfIds : this must have exactly one component !");
8910   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret0=DataArrayInt::New(); ret0->alloc(0,1);
8911   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret1=DataArrayInt::New(); ret1->alloc(0,1);
8912   const int *tupEnd(listOfIds->end()),*offBg(begin()),*offEnd(end()-1);
8913   const int *tupPtr(listOfIds->begin()),*offPtr(offBg);
8914   while(tupPtr!=tupEnd && offPtr!=offEnd)
8915     {
8916       if(*tupPtr==*offPtr)
8917         {
8918           int i=offPtr[0];
8919           while(i<offPtr[1] && *tupPtr==i && tupPtr!=tupEnd) { i++; tupPtr++; }
8920           if(i==offPtr[1])
8921             {
8922               ret0->pushBackSilent((int)std::distance(offBg,offPtr));
8923               ret1->pushBackValsSilent(tupPtr-(offPtr[1]-offPtr[0]),tupPtr);
8924               offPtr++;
8925             }
8926         }
8927       else
8928         { if(*tupPtr<*offPtr) tupPtr++; else offPtr++; }
8929     }
8930   rangeIdsFetched=ret0.retn();
8931   idsInInputListThatFetch=ret1.retn();
8932 }
8933
8934 /*!
8935  * Returns a new DataArrayInt whose contents is computed from that of \a this and \a
8936  * offsets arrays as follows. \a offsets is a one-dimensional array considered as an
8937  * "index" array of a "iota" array, thus, whose each element gives an index of a group
8938  * beginning within the "iota" array. And \a this is a one-dimensional array
8939  * considered as a selector of groups described by \a offsets to include into the result array.
8940  *  \throw If \a offsets is NULL.
8941  *  \throw If \a offsets is not allocated.
8942  *  \throw If \a offsets->getNumberOfComponents() != 1.
8943  *  \throw If \a offsets is not monotonically increasing.
8944  *  \throw If \a this is not allocated.
8945  *  \throw If \a this->getNumberOfComponents() != 1.
8946  *  \throw If any element of \a this is not a valid index for \a offsets array.
8947  *
8948  *  \b Example: <br>
8949  *          - \a this: [0,2,3]
8950  *          - \a offsets: [0,3,6,10,14,20]
8951  *          - result array: [0,1,2,6,7,8,9,10,11,12,13] == <br>
8952  *            \c range(0,3) + \c range(6,10) + \c range(10,14) ==<br>
8953  *            \c range( \a offsets[ \a this[0] ], offsets[ \a this[0]+1 ]) + 
8954  *            \c range( \a offsets[ \a this[1] ], offsets[ \a this[1]+1 ]) + 
8955  *            \c range( \a offsets[ \a this[2] ], offsets[ \a this[2]+1 ])
8956  */
8957 DataArrayInt *DataArrayInt::buildExplicitArrByRanges(const DataArrayInt *offsets) const throw(INTERP_KERNEL::Exception)
8958 {
8959   if(!offsets)
8960     throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrByRanges : DataArrayInt pointer in input is NULL !");
8961   checkAllocated();
8962   if(getNumberOfComponents()!=1)
8963      throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrByRanges : only single component allowed !");
8964   offsets->checkAllocated();
8965   if(offsets->getNumberOfComponents()!=1)
8966      throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrByRanges : input array should have only single component !");
8967   int othNbTuples=offsets->getNumberOfTuples()-1;
8968   int nbOfTuples=getNumberOfTuples();
8969   int retNbOftuples=0;
8970   const int *work=getConstPointer();
8971   const int *offPtr=offsets->getConstPointer();
8972   for(int i=0;i<nbOfTuples;i++)
8973     {
8974       int val=work[i];
8975       if(val>=0 && val<othNbTuples)
8976         {
8977           int delta=offPtr[val+1]-offPtr[val];
8978           if(delta>=0)
8979             retNbOftuples+=delta;
8980           else
8981             {
8982               std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrByRanges : Tuple #" << val << " of offset array has a delta < 0 !";
8983               throw INTERP_KERNEL::Exception(oss.str().c_str());
8984             }
8985         }
8986       else
8987         {
8988           std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrByRanges : Tuple #" << i << " in this contains " << val;
8989           oss << " whereas offsets array is of size " << othNbTuples+1 << " !";
8990           throw INTERP_KERNEL::Exception(oss.str().c_str());
8991         }
8992     }
8993   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
8994   ret->alloc(retNbOftuples,1);
8995   int *retPtr=ret->getPointer();
8996   for(int i=0;i<nbOfTuples;i++)
8997     {
8998       int val=work[i];
8999       int start=offPtr[val];
9000       int off=offPtr[val+1]-start;
9001       for(int j=0;j<off;j++,retPtr++)
9002         *retPtr=start+j;
9003     }
9004   return ret.retn();
9005 }
9006
9007 /*!
9008  * 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.
9009  * 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
9010  * in tuple **i** of returned DataArrayInt.
9011  * If ranges overlapped (in theory it should not) this method do not detect it and always returns the first range.
9012  *
9013  * 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)]
9014  * The return DataArrayInt will contain : **[0,4,1,2,2,3]**
9015  * 
9016  * \param [in] ranges typically come from output of MEDCouplingUMesh::ComputeRangesFromTypeDistribution. Each range is specified like this : 1st component is
9017  *             for lower value included and 2nd component is the upper value of corresponding range **excluded**.
9018  * \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
9019  *        is thrown if no ranges in \a ranges contains value in \a this.
9020  * 
9021  * \sa DataArrayInt::findIdInRangeForEachTuple
9022  */
9023 DataArrayInt *DataArrayInt::findRangeIdForEachTuple(const DataArrayInt *ranges) const throw(INTERP_KERNEL::Exception)
9024 {
9025   if(!ranges)
9026     throw INTERP_KERNEL::Exception("DataArrayInt::findRangeIdForEachTuple : null input pointer !");
9027   if(ranges->getNumberOfComponents()!=2)
9028     throw INTERP_KERNEL::Exception("DataArrayInt::findRangeIdForEachTuple : input DataArrayInt instance should have 2 components !");
9029   checkAllocated();
9030   if(getNumberOfComponents()!=1)
9031     throw INTERP_KERNEL::Exception("DataArrayInt::findRangeIdForEachTuple : this should have only one component !");
9032   int nbTuples=getNumberOfTuples();
9033   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbTuples,1);
9034   int nbOfRanges=ranges->getNumberOfTuples();
9035   const int *rangesPtr=ranges->getConstPointer();
9036   int *retPtr=ret->getPointer();
9037   const int *inPtr=getConstPointer();
9038   for(int i=0;i<nbTuples;i++,retPtr++)
9039     {
9040       int val=inPtr[i];
9041       bool found=false;
9042       for(int j=0;j<nbOfRanges && !found;j++)
9043         if(val>=rangesPtr[2*j] && val<rangesPtr[2*j+1])
9044           { *retPtr=j; found=true; }
9045       if(found)
9046         continue;
9047       else
9048         {
9049           std::ostringstream oss; oss << "DataArrayInt::findRangeIdForEachTuple : tuple #" << i << " not found by any ranges !";
9050           throw INTERP_KERNEL::Exception(oss.str().c_str());
9051         }
9052     }
9053   return ret.retn();
9054 }
9055
9056 /*!
9057  * 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.
9058  * 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
9059  * in tuple **i** of returned DataArrayInt.
9060  * If ranges overlapped (in theory it should not) this method do not detect it and always returns the sub position of the first range.
9061  *
9062  * 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)]
9063  * The return DataArrayInt will contain : **[1,2,4,0,2,2]**
9064  * This method is often called in pair with DataArrayInt::findRangeIdForEachTuple method.
9065  * 
9066  * \param [in] ranges typically come from output of MEDCouplingUMesh::ComputeRangesFromTypeDistribution. Each range is specified like this : 1st component is
9067  *             for lower value included and 2nd component is the upper value of corresponding range **excluded**.
9068  * \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
9069  *        is thrown if no ranges in \a ranges contains value in \a this.
9070  * \sa DataArrayInt::findRangeIdForEachTuple
9071  */
9072 DataArrayInt *DataArrayInt::findIdInRangeForEachTuple(const DataArrayInt *ranges) const throw(INTERP_KERNEL::Exception)
9073 {
9074   if(!ranges)
9075     throw INTERP_KERNEL::Exception("DataArrayInt::findIdInRangeForEachTuple : null input pointer !");
9076   if(ranges->getNumberOfComponents()!=2)
9077     throw INTERP_KERNEL::Exception("DataArrayInt::findIdInRangeForEachTuple : input DataArrayInt instance should have 2 components !");
9078   checkAllocated();
9079   if(getNumberOfComponents()!=1)
9080     throw INTERP_KERNEL::Exception("DataArrayInt::findIdInRangeForEachTuple : this should have only one component !");
9081   int nbTuples=getNumberOfTuples();
9082   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbTuples,1);
9083   int nbOfRanges=ranges->getNumberOfTuples();
9084   const int *rangesPtr=ranges->getConstPointer();
9085   int *retPtr=ret->getPointer();
9086   const int *inPtr=getConstPointer();
9087   for(int i=0;i<nbTuples;i++,retPtr++)
9088     {
9089       int val=inPtr[i];
9090       bool found=false;
9091       for(int j=0;j<nbOfRanges && !found;j++)
9092         if(val>=rangesPtr[2*j] && val<rangesPtr[2*j+1])
9093           { *retPtr=val-rangesPtr[2*j]; found=true; }
9094       if(found)
9095         continue;
9096       else
9097         {
9098           std::ostringstream oss; oss << "DataArrayInt::findIdInRangeForEachTuple : tuple #" << i << " not found by any ranges !";
9099           throw INTERP_KERNEL::Exception(oss.str().c_str());
9100         }
9101     }
9102   return ret.retn();
9103 }
9104
9105 /*!
9106  * 
9107  * \param [in] nbTimes specifies the nb of times each tuples in \a this will be duplicated contiguouly in returned DataArrayInt instance.
9108  *             \a nbTimes  should be at least equal to 1.
9109  * \return a newly allocated DataArrayInt having one component and number of tuples equal to \a nbTimes * \c this->getNumberOfTuples.
9110  * \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.
9111  */
9112 DataArrayInt *DataArrayInt::duplicateEachTupleNTimes(int nbTimes) const throw(INTERP_KERNEL::Exception)
9113 {
9114   checkAllocated();
9115   if(getNumberOfComponents()!=1)
9116     throw INTERP_KERNEL::Exception("DataArrayInt::duplicateEachTupleNTimes : this should have only one component !");
9117   if(nbTimes<1)
9118     throw INTERP_KERNEL::Exception("DataArrayInt::duplicateEachTupleNTimes : nb times should be >= 1 !");
9119   int nbTuples=getNumberOfTuples();
9120   const int *inPtr=getConstPointer();
9121   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbTimes*nbTuples,1);
9122   int *retPtr=ret->getPointer();
9123   for(int i=0;i<nbTuples;i++,inPtr++)
9124     {
9125       int val=*inPtr;
9126       for(int j=0;j<nbTimes;j++,retPtr++)
9127         *retPtr=val;
9128     }
9129   ret->copyStringInfoFrom(*this);
9130   return ret.retn();
9131 }
9132
9133 /*!
9134  * This method returns all different values found in \a this. This method throws if \a this has not been allocated.
9135  * But the number of components can be different from one.
9136  * \return a newly allocated array (that should be dealt by the caller) containing different values in \a this.
9137  */
9138 DataArrayInt *DataArrayInt::getDifferentValues() const throw(INTERP_KERNEL::Exception)
9139 {
9140   checkAllocated();
9141   std::set<int> ret;
9142   ret.insert(begin(),end());
9143   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret2=DataArrayInt::New(); ret2->alloc((int)ret.size(),1);
9144   std::copy(ret.begin(),ret.end(),ret2->getPointer());
9145   return ret2.retn();
9146 }
9147
9148 /*!
9149  * This method is a refinement of DataArrayInt::getDifferentValues because it returns not only different values in \a this but also, for each of
9150  * them it tells which tuple id have this id.
9151  * This method works only on arrays with one component (if it is not the case call DataArrayInt::rearrange(1) ).
9152  * This method returns two arrays having same size.
9153  * 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.
9154  * 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]]
9155  */
9156 std::vector<DataArrayInt *> DataArrayInt::partitionByDifferentValues(std::vector<int>& differentIds) const throw(INTERP_KERNEL::Exception)
9157 {
9158   checkAllocated();
9159   if(getNumberOfComponents()!=1)
9160     throw INTERP_KERNEL::Exception("DataArrayInt::partitionByDifferentValues : this should have only one component !");
9161   int id=0;
9162   std::map<int,int> m,m2,m3;
9163   for(const int *w=begin();w!=end();w++)
9164     m[*w]++;
9165   differentIds.resize(m.size());
9166   std::vector<DataArrayInt *> ret(m.size());
9167   std::vector<int *> retPtr(m.size());
9168   for(std::map<int,int>::const_iterator it=m.begin();it!=m.end();it++,id++)
9169     {
9170       m2[(*it).first]=id;
9171       ret[id]=DataArrayInt::New();
9172       ret[id]->alloc((*it).second,1);
9173       retPtr[id]=ret[id]->getPointer();
9174       differentIds[id]=(*it).first;
9175     }
9176   id=0;
9177   for(const int *w=begin();w!=end();w++,id++)
9178     {
9179       retPtr[m2[*w]][m3[*w]++]=id;
9180     }
9181   return ret;
9182 }
9183
9184 /*!
9185  * Returns a new DataArrayInt that is a sum of two given arrays. There are 3
9186  * valid cases.
9187  * 1.  The arrays have same number of tuples and components. Then each value of
9188  *   the result array (_a_) is a sum of the corresponding values of \a a1 and \a a2,
9189  *   i.e.: _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ i, j ].
9190  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
9191  *   component. Then
9192  *   _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ i, 0 ].
9193  * 3.  The arrays have same number of components and one array, say _a2_, has one
9194  *   tuple. Then
9195  *   _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ 0, j ].
9196  *
9197  * Info on components is copied either from the first array (in the first case) or from
9198  * the array with maximal number of elements (getNbOfElems()).
9199  *  \param [in] a1 - an array to sum up.
9200  *  \param [in] a2 - another array to sum up.
9201  *  \return DataArrayInt * - the new instance of DataArrayInt.
9202  *          The caller is to delete this result array using decrRef() as it is no more
9203  *          needed.
9204  *  \throw If either \a a1 or \a a2 is NULL.
9205  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
9206  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
9207  *         none of them has number of tuples or components equal to 1.
9208  */
9209 DataArrayInt *DataArrayInt::Add(const DataArrayInt *a1, const DataArrayInt *a2) throw(INTERP_KERNEL::Exception)
9210 {
9211   if(!a1 || !a2)
9212     throw INTERP_KERNEL::Exception("DataArrayInt::Add : input DataArrayInt instance is NULL !");
9213   int nbOfTuple=a1->getNumberOfTuples();
9214   int nbOfTuple2=a2->getNumberOfTuples();
9215   int nbOfComp=a1->getNumberOfComponents();
9216   int nbOfComp2=a2->getNumberOfComponents();
9217   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=0;
9218   if(nbOfTuple==nbOfTuple2)
9219     {
9220       if(nbOfComp==nbOfComp2)
9221         {
9222           ret=DataArrayInt::New();
9223           ret->alloc(nbOfTuple,nbOfComp);
9224           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::plus<int>());
9225           ret->copyStringInfoFrom(*a1);
9226         }
9227       else
9228         {
9229           int nbOfCompMin,nbOfCompMax;
9230           const DataArrayInt *aMin, *aMax;
9231           if(nbOfComp>nbOfComp2)
9232             {
9233               nbOfCompMin=nbOfComp2; nbOfCompMax=nbOfComp;
9234               aMin=a2; aMax=a1;
9235             }
9236           else
9237             {
9238               nbOfCompMin=nbOfComp; nbOfCompMax=nbOfComp2;
9239               aMin=a1; aMax=a2;
9240             }
9241           if(nbOfCompMin==1)
9242             {
9243               ret=DataArrayInt::New();
9244               ret->alloc(nbOfTuple,nbOfCompMax);
9245               const int *aMinPtr=aMin->getConstPointer();
9246               const int *aMaxPtr=aMax->getConstPointer();
9247               int *res=ret->getPointer();
9248               for(int i=0;i<nbOfTuple;i++)
9249                 res=std::transform(aMaxPtr+i*nbOfCompMax,aMaxPtr+(i+1)*nbOfCompMax,res,std::bind2nd(std::plus<int>(),aMinPtr[i]));
9250               ret->copyStringInfoFrom(*aMax);
9251             }
9252           else
9253             throw INTERP_KERNEL::Exception("Nb of components mismatch for array Add !");
9254         }
9255     }
9256   else if((nbOfTuple==1 && nbOfTuple2>1) || (nbOfTuple>1 && nbOfTuple2==1))
9257     {
9258       if(nbOfComp==nbOfComp2)
9259         {
9260           int nbOfTupleMax=std::max(nbOfTuple,nbOfTuple2);
9261           const DataArrayInt *aMin=nbOfTuple>nbOfTuple2?a2:a1;
9262           const DataArrayInt *aMax=nbOfTuple>nbOfTuple2?a1:a2;
9263           const int *aMinPtr=aMin->getConstPointer(),*aMaxPtr=aMax->getConstPointer();
9264           ret=DataArrayInt::New();
9265           ret->alloc(nbOfTupleMax,nbOfComp);
9266           int *res=ret->getPointer();
9267           for(int i=0;i<nbOfTupleMax;i++)
9268             res=std::transform(aMaxPtr+i*nbOfComp,aMaxPtr+(i+1)*nbOfComp,aMinPtr,res,std::plus<int>());
9269           ret->copyStringInfoFrom(*aMax);
9270         }
9271       else
9272         throw INTERP_KERNEL::Exception("Nb of components mismatch for array Add !");
9273     }
9274   else
9275     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Add !");
9276   return ret.retn();
9277 }
9278
9279 /*!
9280  * Adds values of another DataArrayInt to values of \a this one. There are 3
9281  * valid cases.
9282  * 1.  The arrays have same number of tuples and components. Then each value of
9283  *   \a other array is added to the corresponding value of \a this array, i.e.:
9284  *   _a_ [ i, j ] += _other_ [ i, j ].
9285  * 2.  The arrays have same number of tuples and \a other array has one component. Then
9286  *   _a_ [ i, j ] += _other_ [ i, 0 ].
9287  * 3.  The arrays have same number of components and \a other array has one tuple. Then
9288  *   _a_ [ i, j ] += _a2_ [ 0, j ].
9289  *
9290  *  \param [in] other - an array to add to \a this one.
9291  *  \throw If \a other is NULL.
9292  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
9293  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
9294  *         \a other has number of both tuples and components not equal to 1.
9295  */
9296 void DataArrayInt::addEqual(const DataArrayInt *other) throw(INTERP_KERNEL::Exception)
9297 {
9298   if(!other)
9299     throw INTERP_KERNEL::Exception("DataArrayInt::addEqual : input DataArrayInt instance is NULL !");
9300   const char *msg="Nb of tuples mismatch for DataArrayInt::addEqual  !";
9301   checkAllocated(); other->checkAllocated();
9302   int nbOfTuple=getNumberOfTuples();
9303   int nbOfTuple2=other->getNumberOfTuples();
9304   int nbOfComp=getNumberOfComponents();
9305   int nbOfComp2=other->getNumberOfComponents();
9306   if(nbOfTuple==nbOfTuple2)
9307     {
9308       if(nbOfComp==nbOfComp2)
9309         {
9310           std::transform(begin(),end(),other->begin(),getPointer(),std::plus<int>());
9311         }
9312       else if(nbOfComp2==1)
9313         {
9314           int *ptr=getPointer();
9315           const int *ptrc=other->getConstPointer();
9316           for(int i=0;i<nbOfTuple;i++)
9317             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::plus<int>(),*ptrc++));
9318         }
9319       else
9320         throw INTERP_KERNEL::Exception(msg);
9321     }
9322   else if(nbOfTuple2==1)
9323     {
9324       if(nbOfComp2==nbOfComp)
9325         {
9326           int *ptr=getPointer();
9327           const int *ptrc=other->getConstPointer();
9328           for(int i=0;i<nbOfTuple;i++)
9329             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::plus<int>());
9330         }
9331       else
9332         throw INTERP_KERNEL::Exception(msg);
9333     }
9334   else
9335     throw INTERP_KERNEL::Exception(msg);
9336   declareAsNew();
9337 }
9338
9339 /*!
9340  * Returns a new DataArrayInt that is a subtraction of two given arrays. There are 3
9341  * valid cases.
9342  * 1.  The arrays have same number of tuples and components. Then each value of
9343  *   the result array (_a_) is a subtraction of the corresponding values of \a a1 and
9344  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ i, j ].
9345  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
9346  *   component. Then
9347  *   _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ i, 0 ].
9348  * 3.  The arrays have same number of components and one array, say _a2_, has one
9349  *   tuple. Then
9350  *   _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ 0, j ].
9351  *
9352  * Info on components is copied either from the first array (in the first case) or from
9353  * the array with maximal number of elements (getNbOfElems()).
9354  *  \param [in] a1 - an array to subtract from.
9355  *  \param [in] a2 - an array to subtract.
9356  *  \return DataArrayInt * - the new instance of DataArrayInt.
9357  *          The caller is to delete this result array using decrRef() as it is no more
9358  *          needed.
9359  *  \throw If either \a a1 or \a a2 is NULL.
9360  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
9361  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
9362  *         none of them has number of tuples or components equal to 1.
9363  */
9364 DataArrayInt *DataArrayInt::Substract(const DataArrayInt *a1, const DataArrayInt *a2) throw(INTERP_KERNEL::Exception)
9365 {
9366   if(!a1 || !a2)
9367     throw INTERP_KERNEL::Exception("DataArrayInt::Substract : input DataArrayInt instance is NULL !");
9368   int nbOfTuple1=a1->getNumberOfTuples();
9369   int nbOfTuple2=a2->getNumberOfTuples();
9370   int nbOfComp1=a1->getNumberOfComponents();
9371   int nbOfComp2=a2->getNumberOfComponents();
9372   if(nbOfTuple2==nbOfTuple1)
9373     {
9374       if(nbOfComp1==nbOfComp2)
9375         {
9376           MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
9377           ret->alloc(nbOfTuple2,nbOfComp1);
9378           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::minus<int>());
9379           ret->copyStringInfoFrom(*a1);
9380           return ret.retn();
9381         }
9382       else if(nbOfComp2==1)
9383         {
9384           MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
9385           ret->alloc(nbOfTuple1,nbOfComp1);
9386           const int *a2Ptr=a2->getConstPointer();
9387           const int *a1Ptr=a1->getConstPointer();
9388           int *res=ret->getPointer();
9389           for(int i=0;i<nbOfTuple1;i++)
9390             res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::minus<int>(),a2Ptr[i]));
9391           ret->copyStringInfoFrom(*a1);
9392           return ret.retn();
9393         }
9394       else
9395         {
9396           a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Substract !");
9397           return 0;
9398         }
9399     }
9400   else if(nbOfTuple2==1)
9401     {
9402       a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Substract !");
9403       MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
9404       ret->alloc(nbOfTuple1,nbOfComp1);
9405       const int *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
9406       int *pt=ret->getPointer();
9407       for(int i=0;i<nbOfTuple1;i++)
9408         pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::minus<int>());
9409       ret->copyStringInfoFrom(*a1);
9410       return ret.retn();
9411     }
9412   else
9413     {
9414       a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Substract !");//will always throw an exception
9415       return 0;
9416     }
9417 }
9418
9419 /*!
9420  * Subtract values of another DataArrayInt from values of \a this one. There are 3
9421  * valid cases.
9422  * 1.  The arrays have same number of tuples and components. Then each value of
9423  *   \a other array is subtracted from the corresponding value of \a this array, i.e.:
9424  *   _a_ [ i, j ] -= _other_ [ i, j ].
9425  * 2.  The arrays have same number of tuples and \a other array has one component. Then
9426  *   _a_ [ i, j ] -= _other_ [ i, 0 ].
9427  * 3.  The arrays have same number of components and \a other array has one tuple. Then
9428  *   _a_ [ i, j ] -= _a2_ [ 0, j ].
9429  *
9430  *  \param [in] other - an array to subtract from \a this one.
9431  *  \throw If \a other is NULL.
9432  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
9433  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
9434  *         \a other has number of both tuples and components not equal to 1.
9435  */
9436 void DataArrayInt::substractEqual(const DataArrayInt *other) throw(INTERP_KERNEL::Exception)
9437 {
9438   if(!other)
9439     throw INTERP_KERNEL::Exception("DataArrayInt::substractEqual : input DataArrayInt instance is NULL !");
9440   const char *msg="Nb of tuples mismatch for DataArrayInt::substractEqual  !";
9441   checkAllocated(); other->checkAllocated();
9442   int nbOfTuple=getNumberOfTuples();
9443   int nbOfTuple2=other->getNumberOfTuples();
9444   int nbOfComp=getNumberOfComponents();
9445   int nbOfComp2=other->getNumberOfComponents();
9446   if(nbOfTuple==nbOfTuple2)
9447     {
9448       if(nbOfComp==nbOfComp2)
9449         {
9450           std::transform(begin(),end(),other->begin(),getPointer(),std::minus<int>());
9451         }
9452       else if(nbOfComp2==1)
9453         {
9454           int *ptr=getPointer();
9455           const int *ptrc=other->getConstPointer();
9456           for(int i=0;i<nbOfTuple;i++)
9457             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::minus<int>(),*ptrc++));
9458         }
9459       else
9460         throw INTERP_KERNEL::Exception(msg);
9461     }
9462   else if(nbOfTuple2==1)
9463     {
9464       int *ptr=getPointer();
9465       const int *ptrc=other->getConstPointer();
9466       for(int i=0;i<nbOfTuple;i++)
9467         std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::minus<int>());
9468     }
9469   else
9470     throw INTERP_KERNEL::Exception(msg);
9471   declareAsNew();
9472 }
9473
9474 /*!
9475  * Returns a new DataArrayInt that is a product of two given arrays. There are 3
9476  * valid cases.
9477  * 1.  The arrays have same number of tuples and components. Then each value of
9478  *   the result array (_a_) is a product of the corresponding values of \a a1 and
9479  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ i, j ].
9480  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
9481  *   component. Then
9482  *   _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ i, 0 ].
9483  * 3.  The arrays have same number of components and one array, say _a2_, has one
9484  *   tuple. Then
9485  *   _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ 0, j ].
9486  *
9487  * Info on components is copied either from the first array (in the first case) or from
9488  * the array with maximal number of elements (getNbOfElems()).
9489  *  \param [in] a1 - a factor array.
9490  *  \param [in] a2 - another factor array.
9491  *  \return DataArrayInt * - the new instance of DataArrayInt.
9492  *          The caller is to delete this result array using decrRef() as it is no more
9493  *          needed.
9494  *  \throw If either \a a1 or \a a2 is NULL.
9495  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
9496  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
9497  *         none of them has number of tuples or components equal to 1.
9498  */
9499 DataArrayInt *DataArrayInt::Multiply(const DataArrayInt *a1, const DataArrayInt *a2) throw(INTERP_KERNEL::Exception)
9500 {
9501   if(!a1 || !a2)
9502     throw INTERP_KERNEL::Exception("DataArrayInt::Multiply : input DataArrayInt instance is NULL !");
9503   int nbOfTuple=a1->getNumberOfTuples();
9504   int nbOfTuple2=a2->getNumberOfTuples();
9505   int nbOfComp=a1->getNumberOfComponents();
9506   int nbOfComp2=a2->getNumberOfComponents();
9507   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=0;
9508   if(nbOfTuple==nbOfTuple2)
9509     {
9510       if(nbOfComp==nbOfComp2)
9511         {
9512           ret=DataArrayInt::New();
9513           ret->alloc(nbOfTuple,nbOfComp);
9514           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::multiplies<int>());
9515           ret->copyStringInfoFrom(*a1);
9516         }
9517       else
9518         {
9519           int nbOfCompMin,nbOfCompMax;
9520           const DataArrayInt *aMin, *aMax;
9521           if(nbOfComp>nbOfComp2)
9522             {
9523               nbOfCompMin=nbOfComp2; nbOfCompMax=nbOfComp;
9524               aMin=a2; aMax=a1;
9525             }
9526           else
9527             {
9528               nbOfCompMin=nbOfComp; nbOfCompMax=nbOfComp2;
9529               aMin=a1; aMax=a2;
9530             }
9531           if(nbOfCompMin==1)
9532             {
9533               ret=DataArrayInt::New();
9534               ret->alloc(nbOfTuple,nbOfCompMax);
9535               const int *aMinPtr=aMin->getConstPointer();
9536               const int *aMaxPtr=aMax->getConstPointer();
9537               int *res=ret->getPointer();
9538               for(int i=0;i<nbOfTuple;i++)
9539                 res=std::transform(aMaxPtr+i*nbOfCompMax,aMaxPtr+(i+1)*nbOfCompMax,res,std::bind2nd(std::multiplies<int>(),aMinPtr[i]));
9540               ret->copyStringInfoFrom(*aMax);
9541             }
9542           else
9543             throw INTERP_KERNEL::Exception("Nb of components mismatch for array Multiply !");
9544         }
9545     }
9546   else if((nbOfTuple==1 && nbOfTuple2>1) || (nbOfTuple>1 && nbOfTuple2==1))
9547     {
9548       if(nbOfComp==nbOfComp2)
9549         {
9550           int nbOfTupleMax=std::max(nbOfTuple,nbOfTuple2);
9551           const DataArrayInt *aMin=nbOfTuple>nbOfTuple2?a2:a1;
9552           const DataArrayInt *aMax=nbOfTuple>nbOfTuple2?a1:a2;
9553           const int *aMinPtr=aMin->getConstPointer(),*aMaxPtr=aMax->getConstPointer();
9554           ret=DataArrayInt::New();
9555           ret->alloc(nbOfTupleMax,nbOfComp);
9556           int *res=ret->getPointer();
9557           for(int i=0;i<nbOfTupleMax;i++)
9558             res=std::transform(aMaxPtr+i*nbOfComp,aMaxPtr+(i+1)*nbOfComp,aMinPtr,res,std::multiplies<int>());
9559           ret->copyStringInfoFrom(*aMax);
9560         }
9561       else
9562         throw INTERP_KERNEL::Exception("Nb of components mismatch for array Multiply !");
9563     }
9564   else
9565     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Multiply !");
9566   return ret.retn();
9567 }
9568
9569
9570 /*!
9571  * Multiply values of another DataArrayInt to values of \a this one. There are 3
9572  * valid cases.
9573  * 1.  The arrays have same number of tuples and components. Then each value of
9574  *   \a other array is multiplied to the corresponding value of \a this array, i.e.:
9575  *   _a_ [ i, j ] *= _other_ [ i, j ].
9576  * 2.  The arrays have same number of tuples and \a other array has one component. Then
9577  *   _a_ [ i, j ] *= _other_ [ i, 0 ].
9578  * 3.  The arrays have same number of components and \a other array has one tuple. Then
9579  *   _a_ [ i, j ] *= _a2_ [ 0, j ].
9580  *
9581  *  \param [in] other - an array to multiply to \a this one.
9582  *  \throw If \a other is NULL.
9583  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
9584  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
9585  *         \a other has number of both tuples and components not equal to 1.
9586  */
9587 void DataArrayInt::multiplyEqual(const DataArrayInt *other) throw(INTERP_KERNEL::Exception)
9588 {
9589   if(!other)
9590     throw INTERP_KERNEL::Exception("DataArrayInt::multiplyEqual : input DataArrayInt instance is NULL !");
9591   const char *msg="Nb of tuples mismatch for DataArrayInt::multiplyEqual !";
9592   checkAllocated(); other->checkAllocated();
9593   int nbOfTuple=getNumberOfTuples();
9594   int nbOfTuple2=other->getNumberOfTuples();
9595   int nbOfComp=getNumberOfComponents();
9596   int nbOfComp2=other->getNumberOfComponents();
9597   if(nbOfTuple==nbOfTuple2)
9598     {
9599       if(nbOfComp==nbOfComp2)
9600         {
9601           std::transform(begin(),end(),other->begin(),getPointer(),std::multiplies<int>());
9602         }
9603       else if(nbOfComp2==1)
9604         {
9605           int *ptr=getPointer();
9606           const int *ptrc=other->getConstPointer();
9607           for(int i=0;i<nbOfTuple;i++)
9608             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::multiplies<int>(),*ptrc++));    
9609         }
9610       else
9611         throw INTERP_KERNEL::Exception(msg);
9612     }
9613   else if(nbOfTuple2==1)
9614     {
9615       if(nbOfComp2==nbOfComp)
9616         {
9617           int *ptr=getPointer();
9618           const int *ptrc=other->getConstPointer();
9619           for(int i=0;i<nbOfTuple;i++)
9620             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::multiplies<int>());
9621         }
9622       else
9623         throw INTERP_KERNEL::Exception(msg);
9624     }
9625   else
9626     throw INTERP_KERNEL::Exception(msg);
9627   declareAsNew();
9628 }
9629
9630
9631 /*!
9632  * Returns a new DataArrayInt that is a division of two given arrays. There are 3
9633  * valid cases.
9634  * 1.  The arrays have same number of tuples and components. Then each value of
9635  *   the result array (_a_) is a division of the corresponding values of \a a1 and
9636  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ i, j ].
9637  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
9638  *   component. Then
9639  *   _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ i, 0 ].
9640  * 3.  The arrays have same number of components and one array, say _a2_, has one
9641  *   tuple. Then
9642  *   _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ 0, j ].
9643  *
9644  * Info on components is copied either from the first array (in the first case) or from
9645  * the array with maximal number of elements (getNbOfElems()).
9646  *  \warning No check of division by zero is performed!
9647  *  \param [in] a1 - a numerator array.
9648  *  \param [in] a2 - a denominator array.
9649  *  \return DataArrayInt * - the new instance of DataArrayInt.
9650  *          The caller is to delete this result array using decrRef() as it is no more
9651  *          needed.
9652  *  \throw If either \a a1 or \a a2 is NULL.
9653  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
9654  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
9655  *         none of them has number of tuples or components equal to 1.
9656  */
9657 DataArrayInt *DataArrayInt::Divide(const DataArrayInt *a1, const DataArrayInt *a2) throw(INTERP_KERNEL::Exception)
9658 {
9659   if(!a1 || !a2)
9660     throw INTERP_KERNEL::Exception("DataArrayInt::Divide : input DataArrayInt instance is NULL !");
9661   int nbOfTuple1=a1->getNumberOfTuples();
9662   int nbOfTuple2=a2->getNumberOfTuples();
9663   int nbOfComp1=a1->getNumberOfComponents();
9664   int nbOfComp2=a2->getNumberOfComponents();
9665   if(nbOfTuple2==nbOfTuple1)
9666     {
9667       if(nbOfComp1==nbOfComp2)
9668         {
9669           MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
9670           ret->alloc(nbOfTuple2,nbOfComp1);
9671           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::divides<int>());
9672           ret->copyStringInfoFrom(*a1);
9673           return ret.retn();
9674         }
9675       else if(nbOfComp2==1)
9676         {
9677           MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
9678           ret->alloc(nbOfTuple1,nbOfComp1);
9679           const int *a2Ptr=a2->getConstPointer();
9680           const int *a1Ptr=a1->getConstPointer();
9681           int *res=ret->getPointer();
9682           for(int i=0;i<nbOfTuple1;i++)
9683             res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::divides<int>(),a2Ptr[i]));
9684           ret->copyStringInfoFrom(*a1);
9685           return ret.retn();
9686         }
9687       else
9688         {
9689           a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Divide !");
9690           return 0;
9691         }
9692     }
9693   else if(nbOfTuple2==1)
9694     {
9695       a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Divide !");
9696       MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
9697       ret->alloc(nbOfTuple1,nbOfComp1);
9698       const int *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
9699       int *pt=ret->getPointer();
9700       for(int i=0;i<nbOfTuple1;i++)
9701         pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::divides<int>());
9702       ret->copyStringInfoFrom(*a1);
9703       return ret.retn();
9704     }
9705   else
9706     {
9707       a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Divide !");//will always throw an exception
9708       return 0;
9709     }
9710 }
9711
9712 /*!
9713  * Divide values of \a this array by values of another DataArrayInt. There are 3
9714  * valid cases.
9715  * 1.  The arrays have same number of tuples and components. Then each value of
9716  *    \a this array is divided by the corresponding value of \a other one, i.e.:
9717  *   _a_ [ i, j ] /= _other_ [ i, j ].
9718  * 2.  The arrays have same number of tuples and \a other array has one component. Then
9719  *   _a_ [ i, j ] /= _other_ [ i, 0 ].
9720  * 3.  The arrays have same number of components and \a other array has one tuple. Then
9721  *   _a_ [ i, j ] /= _a2_ [ 0, j ].
9722  *
9723  *  \warning No check of division by zero is performed!
9724  *  \param [in] other - an array to divide \a this one by.
9725  *  \throw If \a other is NULL.
9726  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
9727  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
9728  *         \a other has number of both tuples and components not equal to 1.
9729  */
9730 void DataArrayInt::divideEqual(const DataArrayInt *other) throw(INTERP_KERNEL::Exception)
9731 {
9732   if(!other)
9733     throw INTERP_KERNEL::Exception("DataArrayInt::divideEqual : input DataArrayInt instance is NULL !");
9734   const char *msg="Nb of tuples mismatch for DataArrayInt::divideEqual !";
9735   checkAllocated(); other->checkAllocated();
9736   int nbOfTuple=getNumberOfTuples();
9737   int nbOfTuple2=other->getNumberOfTuples();
9738   int nbOfComp=getNumberOfComponents();
9739   int nbOfComp2=other->getNumberOfComponents();
9740   if(nbOfTuple==nbOfTuple2)
9741     {
9742       if(nbOfComp==nbOfComp2)
9743         {
9744           std::transform(begin(),end(),other->begin(),getPointer(),std::divides<int>());
9745         }
9746       else if(nbOfComp2==1)
9747         {
9748           int *ptr=getPointer();
9749           const int *ptrc=other->getConstPointer();
9750           for(int i=0;i<nbOfTuple;i++)
9751             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::divides<int>(),*ptrc++));
9752         }
9753       else
9754         throw INTERP_KERNEL::Exception(msg);
9755     }
9756   else if(nbOfTuple2==1)
9757     {
9758       if(nbOfComp2==nbOfComp)
9759         {
9760           int *ptr=getPointer();
9761           const int *ptrc=other->getConstPointer();
9762           for(int i=0;i<nbOfTuple;i++)
9763             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::divides<int>());
9764         }
9765       else
9766         throw INTERP_KERNEL::Exception(msg);
9767     }
9768   else
9769     throw INTERP_KERNEL::Exception(msg);
9770   declareAsNew();
9771 }
9772
9773
9774 /*!
9775  * Returns a new DataArrayInt that is a modulus of two given arrays. There are 3
9776  * valid cases.
9777  * 1.  The arrays have same number of tuples and components. Then each value of
9778  *   the result array (_a_) is a division of the corresponding values of \a a1 and
9779  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] % _a2_ [ i, j ].
9780  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
9781  *   component. Then
9782  *   _a_ [ i, j ] = _a1_ [ i, j ] % _a2_ [ i, 0 ].
9783  * 3.  The arrays have same number of components and one array, say _a2_, has one
9784  *   tuple. Then
9785  *   _a_ [ i, j ] = _a1_ [ i, j ] % _a2_ [ 0, j ].
9786  *
9787  * Info on components is copied either from the first array (in the first case) or from
9788  * the array with maximal number of elements (getNbOfElems()).
9789  *  \warning No check of division by zero is performed!
9790  *  \param [in] a1 - a dividend array.
9791  *  \param [in] a2 - a divisor array.
9792  *  \return DataArrayInt * - the new instance of DataArrayInt.
9793  *          The caller is to delete this result array using decrRef() as it is no more
9794  *          needed.
9795  *  \throw If either \a a1 or \a a2 is NULL.
9796  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
9797  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
9798  *         none of them has number of tuples or components equal to 1.
9799  */
9800 DataArrayInt *DataArrayInt::Modulus(const DataArrayInt *a1, const DataArrayInt *a2) throw(INTERP_KERNEL::Exception)
9801 {
9802     if(!a1 || !a2)
9803     throw INTERP_KERNEL::Exception("DataArrayInt::Modulus : input DataArrayInt instance is NULL !");
9804   int nbOfTuple1=a1->getNumberOfTuples();
9805   int nbOfTuple2=a2->getNumberOfTuples();
9806   int nbOfComp1=a1->getNumberOfComponents();
9807   int nbOfComp2=a2->getNumberOfComponents();
9808   if(nbOfTuple2==nbOfTuple1)
9809     {
9810       if(nbOfComp1==nbOfComp2)
9811         {
9812           MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
9813           ret->alloc(nbOfTuple2,nbOfComp1);
9814           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::modulus<int>());
9815           ret->copyStringInfoFrom(*a1);
9816           return ret.retn();
9817         }
9818       else if(nbOfComp2==1)
9819         {
9820           MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
9821           ret->alloc(nbOfTuple1,nbOfComp1);
9822           const int *a2Ptr=a2->getConstPointer();
9823           const int *a1Ptr=a1->getConstPointer();
9824           int *res=ret->getPointer();
9825           for(int i=0;i<nbOfTuple1;i++)
9826             res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::modulus<int>(),a2Ptr[i]));
9827           ret->copyStringInfoFrom(*a1);
9828           return ret.retn();
9829         }
9830       else
9831         {
9832           a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Modulus !");
9833           return 0;
9834         }
9835     }
9836   else if(nbOfTuple2==1)
9837     {
9838       a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Modulus !");
9839       MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
9840       ret->alloc(nbOfTuple1,nbOfComp1);
9841       const int *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
9842       int *pt=ret->getPointer();
9843       for(int i=0;i<nbOfTuple1;i++)
9844         pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::modulus<int>());
9845       ret->copyStringInfoFrom(*a1);
9846       return ret.retn();
9847     }
9848   else
9849     {
9850       a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Modulus !");//will always throw an exception
9851       return 0;
9852     }
9853 }
9854
9855 /*!
9856  * Modify \a this array so that each value becomes a modulus of division of this value by
9857  * a value of another DataArrayInt. There are 3 valid cases.
9858  * 1.  The arrays have same number of tuples and components. Then each value of
9859  *    \a this array is divided by the corresponding value of \a other one, i.e.:
9860  *   _a_ [ i, j ] %= _other_ [ i, j ].
9861  * 2.  The arrays have same number of tuples and \a other array has one component. Then
9862  *   _a_ [ i, j ] %= _other_ [ i, 0 ].
9863  * 3.  The arrays have same number of components and \a other array has one tuple. Then
9864  *   _a_ [ i, j ] %= _a2_ [ 0, j ].
9865  *
9866  *  \warning No check of division by zero is performed!
9867  *  \param [in] other - a divisor array.
9868  *  \throw If \a other is NULL.
9869  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
9870  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
9871  *         \a other has number of both tuples and components not equal to 1.
9872  */
9873 void DataArrayInt::modulusEqual(const DataArrayInt *other) throw(INTERP_KERNEL::Exception)
9874 {
9875   if(!other)
9876     throw INTERP_KERNEL::Exception("DataArrayInt::modulusEqual : input DataArrayInt instance is NULL !");
9877   const char *msg="Nb of tuples mismatch for DataArrayInt::modulusEqual !";
9878   checkAllocated(); other->checkAllocated();
9879   int nbOfTuple=getNumberOfTuples();
9880   int nbOfTuple2=other->getNumberOfTuples();
9881   int nbOfComp=getNumberOfComponents();
9882   int nbOfComp2=other->getNumberOfComponents();
9883   if(nbOfTuple==nbOfTuple2)
9884     {
9885       if(nbOfComp==nbOfComp2)
9886         {
9887           std::transform(begin(),end(),other->begin(),getPointer(),std::modulus<int>());
9888         }
9889       else if(nbOfComp2==1)
9890         {
9891           if(nbOfComp2==nbOfComp)
9892             {
9893               int *ptr=getPointer();
9894               const int *ptrc=other->getConstPointer();
9895               for(int i=0;i<nbOfTuple;i++)
9896                 std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::modulus<int>(),*ptrc++));
9897             }
9898           else
9899             throw INTERP_KERNEL::Exception(msg);
9900         }
9901       else
9902         throw INTERP_KERNEL::Exception(msg);
9903     }
9904   else if(nbOfTuple2==1)
9905     {
9906       int *ptr=getPointer();
9907       const int *ptrc=other->getConstPointer();
9908       for(int i=0;i<nbOfTuple;i++)
9909         std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::modulus<int>());
9910     }
9911   else
9912     throw INTERP_KERNEL::Exception(msg);
9913   declareAsNew();
9914 }
9915
9916 /*!
9917  * Returns a new DataArrayInt that is the result of pow of two given arrays. There are 3
9918  * valid cases.
9919  *
9920  *  \param [in] a1 - an array to pow up.
9921  *  \param [in] a2 - another array to sum up.
9922  *  \return DataArrayInt * - the new instance of DataArrayInt.
9923  *          The caller is to delete this result array using decrRef() as it is no more
9924  *          needed.
9925  *  \throw If either \a a1 or \a a2 is NULL.
9926  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
9927  *  \throw If \a a1->getNumberOfComponents() != 1 or \a a2->getNumberOfComponents() != 1.
9928  *  \throw If there is a negative value in \a a2.
9929  */
9930 DataArrayInt *DataArrayInt::Pow(const DataArrayInt *a1, const DataArrayInt *a2) throw(INTERP_KERNEL::Exception)
9931 {
9932   if(!a1 || !a2)
9933     throw INTERP_KERNEL::Exception("DataArrayInt::Pow : at least one of input instances is null !");
9934   int nbOfTuple=a1->getNumberOfTuples();
9935   int nbOfTuple2=a2->getNumberOfTuples();
9936   int nbOfComp=a1->getNumberOfComponents();
9937   int nbOfComp2=a2->getNumberOfComponents();
9938   if(nbOfTuple!=nbOfTuple2)
9939     throw INTERP_KERNEL::Exception("DataArrayInt::Pow : number of tuples mismatches !");
9940   if(nbOfComp!=1 || nbOfComp2!=1)
9941     throw INTERP_KERNEL::Exception("DataArrayInt::Pow : number of components of both arrays must be equal to 1 !");
9942   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbOfTuple,1);
9943   const int *ptr1(a1->begin()),*ptr2(a2->begin());
9944   int *ptr=ret->getPointer();
9945   for(int i=0;i<nbOfTuple;i++,ptr1++,ptr2++,ptr++)
9946     {
9947       if(*ptr2>=0)
9948         {
9949           int tmp=1;
9950           for(int j=0;j<*ptr2;j++)
9951             tmp*=*ptr1;
9952           *ptr=tmp;
9953         }
9954       else
9955         {
9956           std::ostringstream oss; oss << "DataArrayInt::Pow : on tuple #" << i << " of a2 value is < 0 (" << *ptr2 << ") !";
9957           throw INTERP_KERNEL::Exception(oss.str().c_str());
9958         }
9959     }
9960   return ret.retn();
9961 }
9962
9963 /*!
9964  * Apply pow on values of another DataArrayInt to values of \a this one.
9965  *
9966  *  \param [in] other - an array to pow to \a this one.
9967  *  \throw If \a other is NULL.
9968  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples()
9969  *  \throw If \a this->getNumberOfComponents() != 1 or \a other->getNumberOfComponents() != 1
9970  *  \throw If there is a negative value in \a other.
9971  */
9972 void DataArrayInt::powEqual(const DataArrayInt *other) throw(INTERP_KERNEL::Exception)
9973 {
9974   if(!other)
9975     throw INTERP_KERNEL::Exception("DataArrayInt::powEqual : input instance is null !");
9976   int nbOfTuple=getNumberOfTuples();
9977   int nbOfTuple2=other->getNumberOfTuples();
9978   int nbOfComp=getNumberOfComponents();
9979   int nbOfComp2=other->getNumberOfComponents();
9980   if(nbOfTuple!=nbOfTuple2)
9981     throw INTERP_KERNEL::Exception("DataArrayInt::powEqual : number of tuples mismatches !");
9982   if(nbOfComp!=1 || nbOfComp2!=1)
9983     throw INTERP_KERNEL::Exception("DataArrayInt::powEqual : number of components of both arrays must be equal to 1 !");
9984   int *ptr=getPointer();
9985   const int *ptrc=other->begin();
9986   for(int i=0;i<nbOfTuple;i++,ptrc++,ptr++)
9987     {
9988       if(*ptrc>=0)
9989         {
9990           int tmp=1;
9991           for(int j=0;j<*ptrc;j++)
9992             tmp*=*ptr;
9993           *ptr=tmp;
9994         }
9995       else
9996         {
9997           std::ostringstream oss; oss << "DataArrayInt::powEqual : on tuple #" << i << " of other value is < 0 (" << *ptrc << ") !";
9998           throw INTERP_KERNEL::Exception(oss.str().c_str());
9999         }
10000     }
10001   declareAsNew();
10002 }
10003
10004 /*!
10005  * Returns a C array which is a renumbering map in "Old to New" mode for the input array.
10006  * This map, if applied to \a start array, would make it sorted. For example, if
10007  * \a start array contents are [9,10,0,6,4,11,3,7] then the contents of the result array is
10008  * [5,6,0,3,2,7,1,4].
10009  *  \param [in] start - pointer to the first element of the array for which the
10010  *         permutation map is computed.
10011  *  \param [in] end - pointer specifying the end of the array \a start, so that
10012  *         the last value of \a start is \a end[ -1 ].
10013  *  \return int * - the result permutation array that the caller is to delete as it is no
10014  *         more needed.
10015  *  \throw If there are equal values in the input array.
10016  */
10017 int *DataArrayInt::CheckAndPreparePermutation(const int *start, const int *end)
10018 {
10019   std::size_t sz=std::distance(start,end);
10020   int *ret=new int[sz];
10021   int *work=new int[sz];
10022   std::copy(start,end,work);
10023   std::sort(work,work+sz);
10024   if(std::unique(work,work+sz)!=work+sz)
10025     {
10026       delete [] work;
10027       delete [] ret;
10028       throw INTERP_KERNEL::Exception("Some elements are equals in the specified array !");
10029     }
10030   int *iter2=ret;
10031   for(const int *iter=start;iter!=end;iter++,iter2++)
10032     *iter2=(int)std::distance(work,std::find(work,work+sz,*iter));
10033   delete [] work;
10034   return ret;
10035 }
10036
10037 /*!
10038  * Returns a new DataArrayInt containing an arithmetic progression
10039  * that is equal to the sequence returned by Python \c range(\a begin,\a  end,\a  step )
10040  * function.
10041  *  \param [in] begin - the start value of the result sequence.
10042  *  \param [in] end - limiting value, so that every value of the result array is less than
10043  *              \a end.
10044  *  \param [in] step - specifies the increment or decrement.
10045  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
10046  *          array using decrRef() as it is no more needed.
10047  *  \throw If \a step == 0.
10048  *  \throw If \a end < \a begin && \a step > 0.
10049  *  \throw If \a end > \a begin && \a step < 0.
10050  */
10051 DataArrayInt *DataArrayInt::Range(int begin, int end, int step) throw(INTERP_KERNEL::Exception)
10052 {
10053   int nbOfTuples=GetNumberOfItemGivenBESRelative(begin,end,step,"DataArrayInt::Range");
10054   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
10055   ret->alloc(nbOfTuples,1);
10056   int *ptr=ret->getPointer();
10057   if(step>0)
10058     {
10059       for(int i=begin;i<end;i+=step,ptr++)
10060         *ptr=i;
10061     }
10062   else
10063     {
10064       for(int i=begin;i>end;i+=step,ptr++)
10065         *ptr=i;
10066     }
10067   return ret.retn();
10068 }
10069
10070 /*!
10071  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
10072  * Server side.
10073  */
10074 void DataArrayInt::getTinySerializationIntInformation(std::vector<int>& tinyInfo) const
10075 {
10076   tinyInfo.resize(2);
10077   if(isAllocated())
10078     {
10079       tinyInfo[0]=getNumberOfTuples();
10080       tinyInfo[1]=getNumberOfComponents();
10081     }
10082   else
10083     {
10084       tinyInfo[0]=-1;
10085       tinyInfo[1]=-1;
10086     }
10087 }
10088
10089 /*!
10090  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
10091  * Server side.
10092  */
10093 void DataArrayInt::getTinySerializationStrInformation(std::vector<std::string>& tinyInfo) const
10094 {
10095   if(isAllocated())
10096     {
10097       int nbOfCompo=getNumberOfComponents();
10098       tinyInfo.resize(nbOfCompo+1);
10099       tinyInfo[0]=getName();
10100       for(int i=0;i<nbOfCompo;i++)
10101         tinyInfo[i+1]=getInfoOnComponent(i);
10102     }
10103   else
10104     {
10105       tinyInfo.resize(1);
10106       tinyInfo[0]=getName();
10107     }
10108 }
10109
10110 /*!
10111  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
10112  * This method returns if a feeding is needed.
10113  */
10114 bool DataArrayInt::resizeForUnserialization(const std::vector<int>& tinyInfoI)
10115 {
10116   int nbOfTuple=tinyInfoI[0];
10117   int nbOfComp=tinyInfoI[1];
10118   if(nbOfTuple!=-1 || nbOfComp!=-1)
10119     {
10120       alloc(nbOfTuple,nbOfComp);
10121       return true;
10122     }
10123   return false;
10124 }
10125
10126 /*!
10127  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
10128  * This method returns if a feeding is needed.
10129  */
10130 void DataArrayInt::finishUnserialization(const std::vector<int>& tinyInfoI, const std::vector<std::string>& tinyInfoS)
10131 {
10132   setName(tinyInfoS[0].c_str());
10133   if(isAllocated())
10134     {
10135       int nbOfCompo=getNumberOfComponents();
10136       for(int i=0;i<nbOfCompo;i++)
10137         setInfoOnComponent(i,tinyInfoS[i+1].c_str());
10138     }
10139 }
10140
10141 DataArrayIntIterator::DataArrayIntIterator(DataArrayInt *da):_da(da),_pt(0),_tuple_id(0),_nb_comp(0),_nb_tuple(0)
10142 {
10143   if(_da)
10144     {
10145       _da->incrRef();
10146       if(_da->isAllocated())
10147         {
10148           _nb_comp=da->getNumberOfComponents();
10149           _nb_tuple=da->getNumberOfTuples();
10150           _pt=da->getPointer();
10151         }
10152     }
10153 }
10154
10155 DataArrayIntIterator::~DataArrayIntIterator()
10156 {
10157   if(_da)
10158     _da->decrRef();
10159 }
10160
10161 DataArrayIntTuple *DataArrayIntIterator::nextt() throw(INTERP_KERNEL::Exception)
10162 {
10163   if(_tuple_id<_nb_tuple)
10164     {
10165       _tuple_id++;
10166       DataArrayIntTuple *ret=new DataArrayIntTuple(_pt,_nb_comp);
10167       _pt+=_nb_comp;
10168       return ret;
10169     }
10170   else
10171     return 0;
10172 }
10173
10174 DataArrayIntTuple::DataArrayIntTuple(int *pt, int nbOfComp):_pt(pt),_nb_of_compo(nbOfComp)
10175 {
10176 }
10177
10178 std::string DataArrayIntTuple::repr() const throw(INTERP_KERNEL::Exception)
10179 {
10180   std::ostringstream oss; oss << "(";
10181   for(int i=0;i<_nb_of_compo-1;i++)
10182     oss << _pt[i] << ", ";
10183   oss << _pt[_nb_of_compo-1] << ")";
10184   return oss.str();
10185 }
10186
10187 int DataArrayIntTuple::intValue() const throw(INTERP_KERNEL::Exception)
10188 {
10189   if(_nb_of_compo==1)
10190     return *_pt;
10191   throw INTERP_KERNEL::Exception("DataArrayIntTuple::intValue : DataArrayIntTuple instance has not exactly 1 component -> Not possible to convert it into an integer !");
10192 }
10193
10194 /*!
10195  * This method returns a newly allocated instance the caller should dealed with by a ParaMEDMEM::DataArrayInt::decrRef.
10196  * This method performs \b no copy of data. The content is only referenced using ParaMEDMEM::DataArrayInt::useArray with ownership set to \b false.
10197  * 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
10198  * \b nbOfCompo=1 and \bnbOfTuples==this->_nb_of_elem.
10199  */
10200 DataArrayInt *DataArrayIntTuple::buildDAInt(int nbOfTuples, int nbOfCompo) const throw(INTERP_KERNEL::Exception)
10201 {
10202   if((_nb_of_compo==nbOfCompo && nbOfTuples==1) || (_nb_of_compo==nbOfTuples && nbOfCompo==1))
10203     {
10204       DataArrayInt *ret=DataArrayInt::New();
10205       ret->useExternalArrayWithRWAccess(_pt,nbOfTuples,nbOfCompo);
10206       return ret;
10207     }
10208   else
10209     {
10210       std::ostringstream oss; oss << "DataArrayIntTuple::buildDAInt : unable to build a requested DataArrayInt instance with nbofTuple=" << nbOfTuples << " and nbOfCompo=" << nbOfCompo;
10211       oss << ".\nBecause the number of elements in this is " << _nb_of_compo << " !";
10212       throw INTERP_KERNEL::Exception(oss.str().c_str());
10213     }
10214 }