Salome HOME
Merge last changes for 0021856: [CEA 663] Documenting API of MEDCoupling and MEDLoade...
[modules/med.git] / src / MEDCoupling / MEDCouplingMemArray.cxx
1 // Copyright (C) 2007-2013  CEA/DEN, EDF R&D
2 //
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License.
7 //
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11 // Lesser General Public License for more details.
12 //
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
16 //
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
18 //
19 // Author : Anthony Geay (CEA/DEN)
20
21 #include "MEDCouplingMemArray.txx"
22 #include "MEDCouplingAutoRefCountObjectPtr.hxx"
23
24 #include "GenMathFormulae.hxx"
25 #include "InterpKernelExprParser.hxx"
26
27 #include <set>
28 #include <cmath>
29 #include <limits>
30 #include <numeric>
31 #include <algorithm>
32 #include <functional>
33
34 typedef double (*MYFUNCPTR)(double);
35
36 using namespace ParaMEDMEM;
37
38 template<int SPACEDIM>
39 void DataArrayDouble::findCommonTuplesAlg(const double *bbox, int nbNodes, int limitNodeId, double prec, DataArrayInt *c, DataArrayInt *cI) const
40 {
41   const double *coordsPtr=getConstPointer();
42   BBTreePts<SPACEDIM,int> myTree(bbox,0,0,nbNodes,prec);
43   std::vector<bool> isDone(nbNodes);
44   for(int i=0;i<nbNodes;i++)
45     {
46       if(!isDone[i])
47         {
48           std::vector<int> intersectingElems;
49           myTree.getElementsAroundPoint(coordsPtr+i*SPACEDIM,intersectingElems);
50           if(intersectingElems.size()>1)
51             {
52               std::vector<int> commonNodes;
53               for(std::vector<int>::const_iterator it=intersectingElems.begin();it!=intersectingElems.end();it++)
54                 if(*it!=i)
55                   if(*it>=limitNodeId)
56                     {
57                       commonNodes.push_back(*it);
58                       isDone[*it]=true;
59                     }
60               if(!commonNodes.empty())
61                 {
62                   cI->pushBackSilent(cI->back()+(int)commonNodes.size()+1);
63                   c->pushBackSilent(i);
64                   c->insertAtTheEnd(commonNodes.begin(),commonNodes.end());
65                 }
66             }
67         }
68     }
69 }
70
71 template<int SPACEDIM>
72 void DataArrayDouble::FindTupleIdsNearTuplesAlg(const BBTreePts<SPACEDIM,int>& myTree, const double *pos, int nbOfTuples, double eps,
73                                                 DataArrayInt *c, DataArrayInt *cI)
74 {
75   for(int i=0;i<nbOfTuples;i++)
76     {
77       std::vector<int> intersectingElems;
78       myTree.getElementsAroundPoint(pos+i*SPACEDIM,intersectingElems);
79       std::vector<int> commonNodes;
80       for(std::vector<int>::const_iterator it=intersectingElems.begin();it!=intersectingElems.end();it++)
81         commonNodes.push_back(*it);
82       cI->pushBackSilent(cI->back()+(int)commonNodes.size());
83       c->insertAtTheEnd(commonNodes.begin(),commonNodes.end());
84     }
85 }
86
87 template<int SPACEDIM>
88 void DataArrayDouble::FindClosestTupleIdAlg(const BBTreePts<SPACEDIM,int>& myTree, double dist, const double *pos, int nbOfTuples, const double *thisPt, int thisNbOfTuples, int *res)
89 {
90   double distOpt(dist);
91   const double *p(pos);
92   int *r(res);
93   for(int i=0;i<nbOfTuples;i++,p+=SPACEDIM,r++)
94     {
95       while(true)
96         {
97           int elem=-1;
98           double ret=myTree.getElementsAroundPoint2(p,distOpt,elem);
99           if(ret!=std::numeric_limits<double>::max())
100             {
101               distOpt=std::max(ret,1e-4);
102               *r=elem;
103               break;
104             }
105           else
106             { distOpt=2*distOpt; continue; }
107         }
108     }
109 }
110
111 std::size_t DataArray::getHeapMemorySize() const
112 {
113   std::size_t sz1=_name.capacity();
114   std::size_t sz2=_info_on_compo.capacity();
115   std::size_t sz3=0;
116   for(std::vector<std::string>::const_iterator it=_info_on_compo.begin();it!=_info_on_compo.end();it++)
117     sz3+=(*it).capacity();
118   return sz1+sz2+sz3;
119 }
120
121 /*!
122  * Sets the attribute \a _name of \a this array.
123  * See \ref MEDCouplingArrayBasicsName "DataArrays infos" for more information.
124  *  \param [in] name - new array name
125  */
126 void DataArray::setName(const char *name)
127 {
128   _name=name;
129 }
130
131 /*!
132  * Copies textual data from an \a other DataArray. The copied data are
133  * - the name attribute,
134  * - the information of components.
135  *
136  * For more information on these data see \ref MEDCouplingArrayBasicsName "DataArrays infos".
137  *
138  *  \param [in] other - another instance of DataArray to copy the textual data from.
139  *  \throw If number of components of \a this array differs from that of the \a other.
140  */
141 void DataArray::copyStringInfoFrom(const DataArray& other) throw(INTERP_KERNEL::Exception)
142 {
143   if(_info_on_compo.size()!=other._info_on_compo.size())
144     throw INTERP_KERNEL::Exception("Size of arrays mismatches on copyStringInfoFrom !");
145   _name=other._name;
146   _info_on_compo=other._info_on_compo;
147 }
148
149 void DataArray::copyPartOfStringInfoFrom(const DataArray& other, const std::vector<int>& compoIds) throw(INTERP_KERNEL::Exception)
150 {
151   int nbOfCompoOth=other.getNumberOfComponents();
152   std::size_t newNbOfCompo=compoIds.size();
153   for(std::size_t i=0;i<newNbOfCompo;i++)
154     if(compoIds[i]>=nbOfCompoOth || compoIds[i]<0)
155       {
156         std::ostringstream oss; oss << "Specified component id is out of range (" << compoIds[i] << ") compared with nb of actual components (" << nbOfCompoOth << ")";
157         throw INTERP_KERNEL::Exception(oss.str().c_str());
158       }
159   for(std::size_t i=0;i<newNbOfCompo;i++)
160     setInfoOnComponent((int)i,other.getInfoOnComponent(compoIds[i]).c_str());
161 }
162
163 void DataArray::copyPartOfStringInfoFrom2(const std::vector<int>& compoIds, const DataArray& other) throw(INTERP_KERNEL::Exception)
164 {
165   int nbOfCompo=getNumberOfComponents();
166   std::size_t partOfCompoToSet=compoIds.size();
167   if((int)partOfCompoToSet!=other.getNumberOfComponents())
168     throw INTERP_KERNEL::Exception("Given compoIds has not the same size as number of components of given array !");
169   for(std::size_t i=0;i<partOfCompoToSet;i++)
170     if(compoIds[i]>=nbOfCompo || compoIds[i]<0)
171       {
172         std::ostringstream oss; oss << "Specified component id is out of range (" << compoIds[i] << ") compared with nb of actual components (" << nbOfCompo << ")";
173         throw INTERP_KERNEL::Exception(oss.str().c_str());
174       }
175   for(std::size_t i=0;i<partOfCompoToSet;i++)
176     setInfoOnComponent(compoIds[i],other.getInfoOnComponent((int)i).c_str());
177 }
178
179 bool DataArray::areInfoEqualsIfNotWhy(const DataArray& other, std::string& reason) const throw(INTERP_KERNEL::Exception)
180 {
181   std::ostringstream oss;
182   if(_name!=other._name)
183     {
184       oss << "Names DataArray mismatch : this name=\"" << _name << " other name=\"" << other._name << "\" !";
185       reason=oss.str();
186       return false;
187     }
188   if(_info_on_compo!=other._info_on_compo)
189     {
190       oss << "Components DataArray mismatch : \nThis components=";
191       for(std::vector<std::string>::const_iterator it=_info_on_compo.begin();it!=_info_on_compo.end();it++)
192         oss << "\"" << *it << "\",";
193       oss << "\nOther components=";
194       for(std::vector<std::string>::const_iterator it=other._info_on_compo.begin();it!=other._info_on_compo.end();it++)
195         oss << "\"" << *it << "\",";
196       reason=oss.str();
197       return false;
198     }
199   return true;
200 }
201
202 /*!
203  * Compares textual information of \a this DataArray with that of an \a other one.
204  * The compared data are
205  * - the name attribute,
206  * - the information of components.
207  *
208  * For more information on these data see \ref MEDCouplingArrayBasicsName "DataArrays infos".
209  *  \param [in] other - another instance of DataArray to compare the textual data of.
210  *  \return bool - \a true if the textual information is same, \a false else.
211  */
212 bool DataArray::areInfoEquals(const DataArray& other) const throw(INTERP_KERNEL::Exception)
213 {
214   std::string tmp;
215   return areInfoEqualsIfNotWhy(other,tmp);
216 }
217
218 void DataArray::reprWithoutNameStream(std::ostream& stream) const throw(INTERP_KERNEL::Exception)
219 {
220   stream << "Number of components : "<< getNumberOfComponents() << "\n";
221   stream << "Info of these components : ";
222   for(std::vector<std::string>::const_iterator iter=_info_on_compo.begin();iter!=_info_on_compo.end();iter++)
223     stream << "\"" << *iter << "\"   ";
224   stream << "\n";
225 }
226
227 std::string DataArray::cppRepr(const char *varName) const throw(INTERP_KERNEL::Exception)
228 {
229   std::ostringstream ret;
230   reprCppStream(varName,ret);
231   return ret.str();
232 }
233
234 /*!
235  * Sets information on all components. To know more on format of this information
236  * see \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
237  *  \param [in] info - a vector of strings.
238  *  \throw If size of \a info differs from the number of components of \a this.
239  */
240 void DataArray::setInfoOnComponents(const std::vector<std::string>& info) throw(INTERP_KERNEL::Exception)
241 {
242   if(getNumberOfComponents()!=(int)info.size())
243     {
244       std::ostringstream oss; oss << "DataArray::setInfoOnComponents : input is of size " << info.size() << " whereas number of components is equal to " << getNumberOfComponents() << " !";
245       throw INTERP_KERNEL::Exception(oss.str().c_str());
246     }
247   _info_on_compo=info;
248 }
249
250 std::vector<std::string> DataArray::getVarsOnComponent() const throw(INTERP_KERNEL::Exception)
251 {
252   int nbOfCompo=(int)_info_on_compo.size();
253   std::vector<std::string> ret(nbOfCompo);
254   for(int i=0;i<nbOfCompo;i++)
255     ret[i]=getVarOnComponent(i);
256   return ret;
257 }
258
259 std::vector<std::string> DataArray::getUnitsOnComponent() const throw(INTERP_KERNEL::Exception)
260 {
261   int nbOfCompo=(int)_info_on_compo.size();
262   std::vector<std::string> ret(nbOfCompo);
263   for(int i=0;i<nbOfCompo;i++)
264     ret[i]=getUnitOnComponent(i);
265   return ret;
266 }
267
268 /*!
269  * Returns information on a component specified by an index.
270  * To know more on format of this information
271  * see \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
272  *  \param [in] i - the index (zero based) of the component of interest.
273  *  \return std::string - a string containing the information on \a i-th component.
274  *  \throw If \a i is not a valid component index.
275  */
276 std::string DataArray::getInfoOnComponent(int i) const throw(INTERP_KERNEL::Exception)
277 {
278   if(i<(int)_info_on_compo.size() && i>=0)
279     return _info_on_compo[i];
280   else
281     {
282       std::ostringstream oss; oss << "DataArray::getInfoOnComponent : Specified component id is out of range (" << i << ") compared with nb of actual components (" << (int) _info_on_compo.size();
283       throw INTERP_KERNEL::Exception(oss.str().c_str());
284     }
285 }
286
287 /*!
288  * Returns the var part of the full information of the \a i-th component.
289  * For example, if \c getInfoOnComponent(0) returns "SIGXY [N/m^2]", then
290  * \c getVarOnComponent(0) returns "SIGXY".
291  * If a unit part of information is not detected by presence of
292  * two square brackets, then the full information is returned.
293  * To read more about the component information format, see
294  * \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
295  *  \param [in] i - the index (zero based) of the component of interest.
296  *  \return std::string - a string containing the var information, or the full info.
297  *  \throw If \a i is not a valid component index.
298  */
299 std::string DataArray::getVarOnComponent(int i) const throw(INTERP_KERNEL::Exception)
300 {
301   if(i<(int)_info_on_compo.size() && i>=0)
302     {
303       return GetVarNameFromInfo(_info_on_compo[i]);
304     }
305   else
306     {
307       std::ostringstream oss; oss << "DataArray::getVarOnComponent : Specified component id is out of range  (" << i << ") compared with nb of actual components (" << (int) _info_on_compo.size();
308       throw INTERP_KERNEL::Exception(oss.str().c_str());
309     }
310 }
311
312 /*!
313  * Returns the unit part of the full information of the \a i-th component.
314  * For example, if \c getInfoOnComponent(0) returns "SIGXY [ N/m^2]", then
315  * \c getUnitOnComponent(0) returns " N/m^2".
316  * If a unit part of information is not detected by presence of
317  * two square brackets, then an empty string is returned.
318  * To read more about the component information format, see
319  * \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
320  *  \param [in] i - the index (zero based) of the component of interest.
321  *  \return std::string - a string containing the unit information, if any, or "".
322  *  \throw If \a i is not a valid component index.
323  */
324 std::string DataArray::getUnitOnComponent(int i) const throw(INTERP_KERNEL::Exception)
325 {
326   if(i<(int)_info_on_compo.size() && i>=0)
327     {
328       return GetUnitFromInfo(_info_on_compo[i]);
329     }
330   else
331     {
332       std::ostringstream oss; oss << "DataArray::getUnitOnComponent : Specified component id is out of range  (" << i << ") compared with nb of actual components (" << (int) _info_on_compo.size();
333       throw INTERP_KERNEL::Exception(oss.str().c_str());
334     }
335 }
336
337 /*!
338  * Returns the var part of the full component information.
339  * For example, if \a info == "SIGXY [N/m^2]", then this method returns "SIGXY".
340  * If a unit part of information is not detected by presence of
341  * two square brackets, then the whole \a info is returned.
342  * To read more about the component information format, see
343  * \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
344  *  \param [in] info - the full component information.
345  *  \return std::string - a string containing only var information, or the \a info.
346  */
347 std::string DataArray::GetVarNameFromInfo(const std::string& info) throw(INTERP_KERNEL::Exception)
348 {
349   std::size_t p1=info.find_last_of('[');
350   std::size_t p2=info.find_last_of(']');
351   if(p1==std::string::npos || p2==std::string::npos)
352     return info;
353   if(p1>p2)
354     return info;
355   if(p1==0)
356     return std::string();
357   std::size_t p3=info.find_last_not_of(' ',p1-1);
358   return info.substr(0,p3+1);
359 }
360
361 /*!
362  * Returns the unit part of the full component information.
363  * For example, if \a info == "SIGXY [ N/m^2]", then this method returns " N/m^2".
364  * If a unit part of information is not detected by presence of
365  * two square brackets, then an empty string is returned.
366  * To read more about the component information format, see
367  * \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
368  *  \param [in] info - the full component information.
369  *  \return std::string - a string containing only unit information, if any, or "".
370  */
371 std::string DataArray::GetUnitFromInfo(const std::string& info) throw(INTERP_KERNEL::Exception)
372 {
373   std::size_t p1=info.find_last_of('[');
374   std::size_t p2=info.find_last_of(']');
375   if(p1==std::string::npos || p2==std::string::npos)
376     return std::string();
377   if(p1>p2)
378     return std::string();
379   return info.substr(p1+1,p2-p1-1);
380 }
381
382 /*!
383  * Sets information on a component specified by an index.
384  * To know more on format of this information
385  * see \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
386  *  \warning Don't pass NULL as \a info!
387  *  \param [in] i - the index (zero based) of the component of interest.
388  *  \param [in] info - the string containing the information.
389  *  \throw If \a i is not a valid component index.
390  */
391 void DataArray::setInfoOnComponent(int i, const char *info) throw(INTERP_KERNEL::Exception)
392 {
393   if(i<(int)_info_on_compo.size() && i>=0)
394     _info_on_compo[i]=info;
395   else
396     {
397       std::ostringstream oss; oss << "DataArray::setInfoOnComponent : Specified component id is out of range  (" << i << ") compared with nb of actual components (" << (int) _info_on_compo.size();
398       throw INTERP_KERNEL::Exception(oss.str().c_str());
399     }
400 }
401
402 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 py_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 py_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  * Both numerical and textual data is copied. The number of tuples in \a this and
1938  * the other array can be different.
1939  *  \param [in] a - the array to copy data from.
1940  *  \param [in] compoIds - sequence of zero based indices of components, data of which is
1941  *              to be copied.
1942  *  \throw If \a a is NULL.
1943  *  \throw If \a compoIds.size() != \a a->getNumberOfComponents().
1944  *  \throw If \a compoIds[i] < 0 or \a compoIds[i] > \a this->getNumberOfComponents().
1945  *
1946  *  \ref py_mcdataarraydouble_setselectedcomponents "Here is a Python example".
1947  */
1948 void DataArrayDouble::setSelectedComponents(const DataArrayDouble *a, const std::vector<int>& compoIds) throw(INTERP_KERNEL::Exception)
1949 {
1950   if(!a)
1951     throw INTERP_KERNEL::Exception("DataArrayDouble::setSelectedComponents : input DataArrayDouble is NULL !");
1952   checkAllocated();
1953   copyPartOfStringInfoFrom2(compoIds,*a);
1954   std::size_t partOfCompoSz=compoIds.size();
1955   int nbOfCompo=getNumberOfComponents();
1956   int nbOfTuples=std::min(getNumberOfTuples(),a->getNumberOfTuples());
1957   const double *ac=a->getConstPointer();
1958   double *nc=getPointer();
1959   for(int i=0;i<nbOfTuples;i++)
1960     for(std::size_t j=0;j<partOfCompoSz;j++,ac++)
1961       nc[nbOfCompo*i+compoIds[j]]=*ac;
1962 }
1963
1964 /*!
1965  * Copy all values from another DataArrayDouble into specified tuples and components
1966  * of \a this array. Textual data is not copied.
1967  * The tree parameters defining set of indices of tuples and components are similar to
1968  * the tree parameters of the Python function \c range(\c start,\c stop,\c step).
1969  *  \param [in] a - the array to copy values from.
1970  *  \param [in] bgTuples - index of the first tuple of \a this array to assign values to.
1971  *  \param [in] endTuples - index of the tuple before which the tuples to assign to
1972  *              are located.
1973  *  \param [in] stepTuples - index increment to get index of the next tuple to assign to.
1974  *  \param [in] bgComp - index of the first component of \a this array to assign values to.
1975  *  \param [in] endComp - index of the component before which the components to assign
1976  *              to are located.
1977  *  \param [in] stepComp - index increment to get index of the next component to assign to.
1978  *  \param [in] strictCompoCompare - if \a true (by default), then \a a->getNumberOfComponents() 
1979  *              must be equal to the number of columns to assign to, else an
1980  *              exception is thrown; if \a false, then it is only required that \a
1981  *              a->getNbOfElems() equals to number of values to assign to (this condition
1982  *              must be respected even if \a strictCompoCompare is \a true). The number of 
1983  *              values to assign to is given by following Python expression:
1984  *              \a nbTargetValues = 
1985  *              \c len(\c range(\a bgTuples,\a endTuples,\a stepTuples)) *
1986  *              \c len(\c range(\a bgComp,\a endComp,\a stepComp)).
1987  *  \throw If \a a is NULL.
1988  *  \throw If \a a is not allocated.
1989  *  \throw If \a this is not allocated.
1990  *  \throw If parameters specifying tuples and components to assign to do not give a
1991  *            non-empty range of increasing indices.
1992  *  \throw If \a a->getNbOfElems() != \a nbTargetValues.
1993  *  \throw If \a strictCompoCompare == \a true && \a a->getNumberOfComponents() !=
1994  *            \c len(\c range(\a bgComp,\a endComp,\a stepComp)).
1995  *
1996  *  \ref py_mcdataarraydouble_setpartofvalues1 "Here is a Python example".
1997  */
1998 void DataArrayDouble::setPartOfValues1(const DataArrayDouble *a, int bgTuples, int endTuples, int stepTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare) throw(INTERP_KERNEL::Exception)
1999 {
2000   if(!a)
2001     throw INTERP_KERNEL::Exception("DataArrayDouble::setPartOfValues1 : input DataArrayDouble is NULL !");
2002   const char msg[]="DataArrayDouble::setPartOfValues1";
2003   checkAllocated();
2004   a->checkAllocated();
2005   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
2006   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
2007   int nbComp=getNumberOfComponents();
2008   int nbOfTuples=getNumberOfTuples();
2009   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
2010   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
2011   bool assignTech=true;
2012   if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
2013     {
2014       if(strictCompoCompare)
2015         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
2016     }
2017   else
2018     {
2019       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
2020       assignTech=false;
2021     }
2022   const double *srcPt=a->getConstPointer();
2023   double *pt=getPointer()+bgTuples*nbComp+bgComp;
2024   if(assignTech)
2025     {
2026       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
2027         for(int j=0;j<newNbOfComp;j++,srcPt++)
2028           pt[j*stepComp]=*srcPt;
2029     }
2030   else
2031     {
2032       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
2033         {
2034           const double *srcPt2=srcPt;
2035           for(int j=0;j<newNbOfComp;j++,srcPt2++)
2036             pt[j*stepComp]=*srcPt2;
2037         }
2038     }
2039 }
2040
2041 /*!
2042  * Assign a given value to values at specified tuples and components of \a this array.
2043  * The tree parameters defining set of indices of tuples and components are similar to
2044  * the tree parameters of the Python function \c range(\c start,\c stop,\c step)..
2045  *  \param [in] a - the value to assign.
2046  *  \param [in] bgTuples - index of the first tuple of \a this array to assign to.
2047  *  \param [in] endTuples - index of the tuple before which the tuples to assign to
2048  *              are located.
2049  *  \param [in] stepTuples - index increment to get index of the next tuple to assign to.
2050  *  \param [in] bgComp - index of the first component of \a this array to assign to.
2051  *  \param [in] endComp - index of the component before which the components to assign
2052  *              to are located.
2053  *  \param [in] stepComp - index increment to get index of the next component to assign to.
2054  *  \throw If \a this is not allocated.
2055  *  \throw If parameters specifying tuples and components to assign to, do not give a
2056  *            non-empty range of increasing indices or indices are out of a valid range
2057  *            for \this array.
2058  *
2059  *  \ref py_mcdataarraydouble_setpartofvaluessimple1 "Here is a Python example".
2060  */
2061 void DataArrayDouble::setPartOfValuesSimple1(double a, int bgTuples, int endTuples, int stepTuples, int bgComp, int endComp, int stepComp) throw(INTERP_KERNEL::Exception)
2062 {
2063   const char msg[]="DataArrayDouble::setPartOfValuesSimple1";
2064   checkAllocated();
2065   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
2066   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
2067   int nbComp=getNumberOfComponents();
2068   int nbOfTuples=getNumberOfTuples();
2069   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
2070   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
2071   double *pt=getPointer()+bgTuples*nbComp+bgComp;
2072   for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
2073     for(int j=0;j<newNbOfComp;j++)
2074       pt[j*stepComp]=a;
2075 }
2076
2077 /*!
2078  * Copy all values from another DataArrayDouble (\a a) into specified tuples and 
2079  * components of \a this array. Textual data is not copied.
2080  * The tuples and components to assign to are defined by C arrays of indices.
2081  * There are two *modes of usage*:
2082  * - If \a a->getNbOfElems() equals to number of values to assign to, then every value
2083  *   of \a a is assigned to its own location within \a this array. 
2084  * - If \a a includes one tuple, then all values of \a a are assigned to the specified
2085  *   components of every specified tuple of \a this array. In this mode it is required
2086  *   that \a a->getNumberOfComponents() equals to the number of specified components.
2087  *
2088  *  \param [in] a - the array to copy values from.
2089  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
2090  *              assign values of \a a to.
2091  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
2092  *              pointer to a tuple index <em>(pi)</em> varies as this: 
2093  *              \a bgTuples <= \a pi < \a endTuples.
2094  *  \param [in] bgComp - pointer to an array of component indices of \a this array to
2095  *              assign values of \a a to.
2096  *  \param [in] endComp - specifies the end of the array \a bgTuples, so that
2097  *              pointer to a component index <em>(pi)</em> varies as this: 
2098  *              \a bgComp <= \a pi < \a endComp.
2099  *  \param [in] strictCompoCompare - this parameter is checked only if the
2100  *               *mode of usage* is the first; if it is \a true (default), 
2101  *               then \a a->getNumberOfComponents() must be equal 
2102  *               to the number of specified columns, else this is not required.
2103  *  \throw If \a a is NULL.
2104  *  \throw If \a a is not allocated.
2105  *  \throw If \a this is not allocated.
2106  *  \throw If any index of tuple/component given by <em>bgTuples / bgComp</em> is
2107  *         out of a valid range for \a this array.
2108  *  \throw In the first *mode of usage*, if <em>strictCompoCompare == true </em> and
2109  *         if <em> a->getNumberOfComponents() != (endComp - bgComp) </em>.
2110  *  \throw In the second *mode of usage*, if \a a->getNumberOfTuples() != 1 or
2111  *         <em> a->getNumberOfComponents() != (endComp - bgComp)</em>.
2112  *
2113  *  \ref py_mcdataarraydouble_setpartofvalues2 "Here is a Python example".
2114  */
2115 void DataArrayDouble::setPartOfValues2(const DataArrayDouble *a, const int *bgTuples, const int *endTuples, const int *bgComp, const int *endComp, bool strictCompoCompare) throw(INTERP_KERNEL::Exception)
2116 {
2117   if(!a)
2118     throw INTERP_KERNEL::Exception("DataArrayDouble::setPartOfValues2 : input DataArrayDouble is NULL !");
2119   const char msg[]="DataArrayDouble::setPartOfValues2";
2120   checkAllocated();
2121   a->checkAllocated();
2122   int nbComp=getNumberOfComponents();
2123   int nbOfTuples=getNumberOfTuples();
2124   for(const int *z=bgComp;z!=endComp;z++)
2125     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
2126   int newNbOfTuples=(int)std::distance(bgTuples,endTuples);
2127   int newNbOfComp=(int)std::distance(bgComp,endComp);
2128   bool assignTech=true;
2129   if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
2130     {
2131       if(strictCompoCompare)
2132         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
2133     }
2134   else
2135     {
2136       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
2137       assignTech=false;
2138     }
2139   double *pt=getPointer();
2140   const double *srcPt=a->getConstPointer();
2141   if(assignTech)
2142     {    
2143       for(const int *w=bgTuples;w!=endTuples;w++)
2144         {
2145           DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
2146           for(const int *z=bgComp;z!=endComp;z++,srcPt++)
2147             {    
2148               pt[(std::size_t)(*w)*nbComp+(*z)]=*srcPt;
2149             }
2150         }
2151     }
2152   else
2153     {
2154       for(const int *w=bgTuples;w!=endTuples;w++)
2155         {
2156           const double *srcPt2=srcPt;
2157           DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
2158           for(const int *z=bgComp;z!=endComp;z++,srcPt2++)
2159             {    
2160               pt[(std::size_t)(*w)*nbComp+(*z)]=*srcPt2;
2161             }
2162         }
2163     }
2164 }
2165
2166 /*!
2167  * Assign a given value to values at specified tuples and components of \a this array.
2168  * The tuples and components to assign to are defined by C arrays of indices.
2169  *  \param [in] a - the value to assign.
2170  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
2171  *              assign \a a to.
2172  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
2173  *              pointer to a tuple index (\a pi) varies as this: 
2174  *              \a bgTuples <= \a pi < \a endTuples.
2175  *  \param [in] bgComp - pointer to an array of component indices of \a this array to
2176  *              assign \a a to.
2177  *  \param [in] endComp - specifies the end of the array \a bgTuples, so that
2178  *              pointer to a component index (\a pi) varies as this: 
2179  *              \a bgComp <= \a pi < \a endComp.
2180  *  \throw If \a this is not allocated.
2181  *  \throw If any index of tuple/component given by <em>bgTuples / bgComp</em> is
2182  *         out of a valid range for \a this array.
2183  *
2184  *  \ref py_mcdataarraydouble_setpartofvaluessimple2 "Here is a Python example".
2185  */
2186 void DataArrayDouble::setPartOfValuesSimple2(double a, const int *bgTuples, const int *endTuples, const int *bgComp, const int *endComp) throw(INTERP_KERNEL::Exception)
2187 {
2188   checkAllocated();
2189   int nbComp=getNumberOfComponents();
2190   int nbOfTuples=getNumberOfTuples();
2191   for(const int *z=bgComp;z!=endComp;z++)
2192     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
2193   double *pt=getPointer();
2194   for(const int *w=bgTuples;w!=endTuples;w++)
2195     for(const int *z=bgComp;z!=endComp;z++)
2196       {
2197         DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
2198         pt[(std::size_t)(*w)*nbComp+(*z)]=a;
2199       }
2200 }
2201
2202 /*!
2203  * Copy all values from another DataArrayDouble (\a a) into specified tuples and 
2204  * components of \a this array. Textual data is not copied.
2205  * The tuples to assign to are defined by a C array of indices.
2206  * The components to assign to are defined by three values similar to parameters of
2207  * the Python function \c range(\c start,\c stop,\c step).
2208  * There are two *modes of usage*:
2209  * - If \a a->getNbOfElems() equals to number of values to assign to, then every value
2210  *   of \a a is assigned to its own location within \a this array. 
2211  * - If \a a includes one tuple, then all values of \a a are assigned to the specified
2212  *   components of every specified tuple of \a this array. In this mode it is required
2213  *   that \a a->getNumberOfComponents() equals to the number of specified components.
2214  *
2215  *  \param [in] a - the array to copy values from.
2216  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
2217  *              assign values of \a a to.
2218  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
2219  *              pointer to a tuple index <em>(pi)</em> varies as this: 
2220  *              \a bgTuples <= \a pi < \a endTuples.
2221  *  \param [in] bgComp - index of the first component of \a this array to assign to.
2222  *  \param [in] endComp - index of the component before which the components to assign
2223  *              to are located.
2224  *  \param [in] stepComp - index increment to get index of the next component to assign to.
2225  *  \param [in] strictCompoCompare - this parameter is checked only in the first
2226  *               *mode of usage*; if \a strictCompoCompare is \a true (default), 
2227  *               then \a a->getNumberOfComponents() must be equal 
2228  *               to the number of specified columns, else this is not required.
2229  *  \throw If \a a is NULL.
2230  *  \throw If \a a is not allocated.
2231  *  \throw If \a this is not allocated.
2232  *  \throw If any index of tuple given by \a bgTuples is out of a valid range for 
2233  *         \a this array.
2234  *  \throw In the first *mode of usage*, if <em>strictCompoCompare == true </em> and
2235  *         if <em> a->getNumberOfComponents()</em> is unequal to the number of components
2236  *         defined by <em>(bgComp,endComp,stepComp)</em>.
2237  *  \throw In the second *mode of usage*, if \a a->getNumberOfTuples() != 1 or
2238  *         <em> a->getNumberOfComponents()</em> is unequal to the number of components
2239  *         defined by <em>(bgComp,endComp,stepComp)</em>.
2240  *  \throw If parameters specifying components to assign to, do not give a
2241  *            non-empty range of increasing indices or indices are out of a valid range
2242  *            for \this array.
2243  *
2244  *  \ref py_mcdataarraydouble_setpartofvalues3 "Here is a Python example".
2245  */
2246 void DataArrayDouble::setPartOfValues3(const DataArrayDouble *a, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare) throw(INTERP_KERNEL::Exception)
2247 {
2248   if(!a)
2249     throw INTERP_KERNEL::Exception("DataArrayDouble::setPartOfValues3 : input DataArrayDouble is NULL !");
2250   const char msg[]="DataArrayDouble::setPartOfValues3";
2251   checkAllocated();
2252   a->checkAllocated();
2253   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
2254   int nbComp=getNumberOfComponents();
2255   int nbOfTuples=getNumberOfTuples();
2256   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
2257   int newNbOfTuples=(int)std::distance(bgTuples,endTuples);
2258   bool assignTech=true;
2259   if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
2260     {
2261       if(strictCompoCompare)
2262         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
2263     }
2264   else
2265     {
2266       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
2267       assignTech=false;
2268     }
2269   double *pt=getPointer()+bgComp;
2270   const double *srcPt=a->getConstPointer();
2271   if(assignTech)
2272     {
2273       for(const int *w=bgTuples;w!=endTuples;w++)
2274         for(int j=0;j<newNbOfComp;j++,srcPt++)
2275           {
2276             DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
2277             pt[(std::size_t)(*w)*nbComp+j*stepComp]=*srcPt;
2278           }
2279     }
2280   else
2281     {
2282       for(const int *w=bgTuples;w!=endTuples;w++)
2283         {
2284           const double *srcPt2=srcPt;
2285           for(int j=0;j<newNbOfComp;j++,srcPt2++)
2286             {
2287               DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
2288               pt[(std::size_t)(*w)*nbComp+j*stepComp]=*srcPt2;
2289             }
2290         }
2291     }
2292 }
2293
2294 /*!
2295  * Assign a given value to values at specified tuples and components of \a this array.
2296  * The tuples to assign to are defined by a C array of indices.
2297  * The components to assign to are defined by three values similar to parameters of
2298  * the Python function \c range(\c start,\c stop,\c step).
2299  *  \param [in] a - the value to assign.
2300  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
2301  *              assign \a a to.
2302  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
2303  *              pointer to a tuple index <em>(pi)</em> varies as this: 
2304  *              \a bgTuples <= \a pi < \a endTuples.
2305  *  \param [in] bgComp - index of the first component of \a this array to assign to.
2306  *  \param [in] endComp - index of the component before which the components to assign
2307  *              to are located.
2308  *  \param [in] stepComp - index increment to get index of the next component to assign to.
2309  *  \throw If \a this is not allocated.
2310  *  \throw If any index of tuple given by \a bgTuples is out of a valid range for 
2311  *         \a this array.
2312  *  \throw If parameters specifying components to assign to, do not give a
2313  *            non-empty range of increasing indices or indices are out of a valid range
2314  *            for \this array.
2315  *
2316  *  \ref py_mcdataarraydouble_setpartofvaluessimple3 "Here is a Python example".
2317  */
2318 void DataArrayDouble::setPartOfValuesSimple3(double a, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp) throw(INTERP_KERNEL::Exception)
2319 {
2320   const char msg[]="DataArrayDouble::setPartOfValuesSimple3";
2321   checkAllocated();
2322   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
2323   int nbComp=getNumberOfComponents();
2324   int nbOfTuples=getNumberOfTuples();
2325   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
2326   double *pt=getPointer()+bgComp;
2327   for(const int *w=bgTuples;w!=endTuples;w++)
2328     for(int j=0;j<newNbOfComp;j++)
2329       {
2330         DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
2331         pt[(std::size_t)(*w)*nbComp+j*stepComp]=a;
2332       }
2333 }
2334
2335 /*!
2336  * Copy all values from another DataArrayDouble into specified tuples and components
2337  * of \a this array. Textual data is not copied.
2338  * The tree parameters defining set of indices of tuples and components are similar to
2339  * the tree parameters of the Python function \c range(\c start,\c stop,\c step).
2340  *  \param [in] a - the array to copy values from.
2341  *  \param [in] bgTuples - index of the first tuple of \a this array to assign values to.
2342  *  \param [in] endTuples - index of the tuple before which the tuples to assign to
2343  *              are located.
2344  *  \param [in] stepTuples - index increment to get index of the next tuple to assign to.
2345  *  \param [in] bgComp - pointer to an array of component indices of \a this array to
2346  *              assign \a a to.
2347  *  \param [in] endComp - specifies the end of the array \a bgTuples, so that
2348  *              pointer to a component index (\a pi) varies as this: 
2349  *              \a bgComp <= \a pi < \a endComp.
2350  *  \param [in] strictCompoCompare - if \a true (by default), then \a a->getNumberOfComponents() 
2351  *              must be equal to the number of columns to assign to, else an
2352  *              exception is thrown; if \a false, then it is only required that \a
2353  *              a->getNbOfElems() equals to number of values to assign to (this condition
2354  *              must be respected even if \a strictCompoCompare is \a true). The number of 
2355  *              values to assign to is given by following Python expression:
2356  *              \a nbTargetValues = 
2357  *              \c len(\c range(\a bgTuples,\a endTuples,\a stepTuples)) *
2358  *              \c len(\c range(\a bgComp,\a endComp,\a stepComp)).
2359  *  \throw If \a a is NULL.
2360  *  \throw If \a a is not allocated.
2361  *  \throw If \a this is not allocated.
2362  *  \throw If parameters specifying tuples and components to assign to do not give a
2363  *            non-empty range of increasing indices.
2364  *  \throw If \a a->getNbOfElems() != \a nbTargetValues.
2365  *  \throw If \a strictCompoCompare == \a true && \a a->getNumberOfComponents() !=
2366  *            \c len(\c range(\a bgComp,\a endComp,\a stepComp)).
2367  *
2368  */
2369 void DataArrayDouble::setPartOfValues4(const DataArrayDouble *a, int bgTuples, int endTuples, int stepTuples, const int *bgComp, const int *endComp, bool strictCompoCompare) throw(INTERP_KERNEL::Exception)
2370 {
2371   if(!a)
2372     throw INTERP_KERNEL::Exception("DataArrayDouble::setPartOfValues4 : input DataArrayDouble is NULL !");
2373   const char msg[]="DataArrayDouble::setPartOfValues4";
2374   checkAllocated();
2375   a->checkAllocated();
2376   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
2377   int newNbOfComp=(int)std::distance(bgComp,endComp);
2378   int nbComp=getNumberOfComponents();
2379   for(const int *z=bgComp;z!=endComp;z++)
2380     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
2381   int nbOfTuples=getNumberOfTuples();
2382   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
2383   bool assignTech=true;
2384   if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
2385     {
2386       if(strictCompoCompare)
2387         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
2388     }
2389   else
2390     {
2391       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
2392       assignTech=false;
2393     }
2394   const double *srcPt=a->getConstPointer();
2395   double *pt=getPointer()+bgTuples*nbComp;
2396   if(assignTech)
2397     {
2398       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
2399         for(const int *z=bgComp;z!=endComp;z++,srcPt++)
2400           pt[*z]=*srcPt;
2401     }
2402   else
2403     {
2404       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
2405         {
2406           const double *srcPt2=srcPt;
2407           for(const int *z=bgComp;z!=endComp;z++,srcPt2++)
2408             pt[*z]=*srcPt2;
2409         }
2410     }
2411 }
2412
2413 void DataArrayDouble::setPartOfValuesSimple4(double a, int bgTuples, int endTuples, int stepTuples, const int *bgComp, const int *endComp) throw(INTERP_KERNEL::Exception)
2414 {
2415   const char msg[]="DataArrayDouble::setPartOfValuesSimple4";
2416   checkAllocated();
2417   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
2418   int nbComp=getNumberOfComponents();
2419   for(const int *z=bgComp;z!=endComp;z++)
2420     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
2421   int nbOfTuples=getNumberOfTuples();
2422   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
2423   double *pt=getPointer()+bgTuples*nbComp;
2424   for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
2425     for(const int *z=bgComp;z!=endComp;z++)
2426       pt[*z]=a;
2427 }
2428
2429 /*!
2430  * Copy some tuples from another DataArrayDouble into specified tuples
2431  * of \a this array. Textual data is not copied. Both arrays must have equal number of
2432  * components.
2433  * Both the tuples to assign and the tuples to assign to are defined by a DataArrayInt.
2434  * All components of selected tuples are copied.
2435  *  \param [in] a - the array to copy values from.
2436  *  \param [in] tuplesSelec - the array specifying both source tuples of \a a and
2437  *              target tuples of \a this. \a tuplesSelec has two components, and the
2438  *              first component specifies index of the source tuple and the second
2439  *              one specifies index of the target tuple.
2440  *  \throw If \a this is not allocated.
2441  *  \throw If \a a is NULL.
2442  *  \throw If \a a is not allocated.
2443  *  \throw If \a tuplesSelec is NULL.
2444  *  \throw If \a tuplesSelec is not allocated.
2445  *  \throw If <em>this->getNumberOfComponents() != a->getNumberOfComponents()</em>.
2446  *  \throw If \a tuplesSelec->getNumberOfComponents() != 2.
2447  *  \throw If any tuple index given by \a tuplesSelec is out of a valid range for 
2448  *         the corresponding (\a this or \a a) array.
2449  */
2450 void DataArrayDouble::setPartOfValuesAdv(const DataArrayDouble *a, const DataArrayInt *tuplesSelec) throw(INTERP_KERNEL::Exception)
2451 {
2452   if(!a || !tuplesSelec)
2453     throw INTERP_KERNEL::Exception("DataArrayDouble::setPartOfValuesAdv : input DataArrayDouble is NULL !");
2454   checkAllocated();
2455   a->checkAllocated();
2456   tuplesSelec->checkAllocated();
2457   int nbOfComp=getNumberOfComponents();
2458   if(nbOfComp!=a->getNumberOfComponents())
2459     throw INTERP_KERNEL::Exception("DataArrayDouble::setPartOfValuesAdv : This and a do not have the same number of components !");
2460   if(tuplesSelec->getNumberOfComponents()!=2)
2461     throw INTERP_KERNEL::Exception("DataArrayDouble::setPartOfValuesAdv : Expecting to have a tuple selector DataArrayInt instance with exactly 2 components !");
2462   int thisNt=getNumberOfTuples();
2463   int aNt=a->getNumberOfTuples();
2464   double *valsToSet=getPointer();
2465   const double *valsSrc=a->getConstPointer();
2466   for(const int *tuple=tuplesSelec->begin();tuple!=tuplesSelec->end();tuple+=2)
2467     {
2468       if(tuple[1]>=0 && tuple[1]<aNt)
2469         {
2470           if(tuple[0]>=0 && tuple[0]<thisNt)
2471             std::copy(valsSrc+nbOfComp*tuple[1],valsSrc+nbOfComp*(tuple[1]+1),valsToSet+nbOfComp*tuple[0]);
2472           else
2473             {
2474               std::ostringstream oss; oss << "DataArrayDouble::setPartOfValuesAdv : Tuple #" << std::distance(tuplesSelec->begin(),tuple)/2;
2475               oss << " of 'tuplesSelec' request of tuple id #" << tuple[0] << " in 'this' ! It should be in [0," << thisNt << ") !";
2476               throw INTERP_KERNEL::Exception(oss.str().c_str());
2477             }
2478         }
2479       else
2480         {
2481           std::ostringstream oss; oss << "DataArrayDouble::setPartOfValuesAdv : Tuple #" << std::distance(tuplesSelec->begin(),tuple)/2;
2482           oss << " of 'tuplesSelec' request of tuple id #" << tuple[1] << " in 'a' ! It should be in [0," << aNt << ") !";
2483           throw INTERP_KERNEL::Exception(oss.str().c_str());
2484         }
2485     }
2486 }
2487
2488 /*!
2489  * Copy some tuples from another DataArrayDouble (\a a) into contiguous tuples
2490  * of \a this array. Textual data is not copied. Both arrays must have equal number of
2491  * components.
2492  * The tuples to assign to are defined by index of the first tuple, and
2493  * their number is defined by \a tuplesSelec->getNumberOfTuples().
2494  * The tuples to copy are defined by values of a DataArrayInt.
2495  * All components of selected tuples are copied.
2496  *  \param [in] tupleIdStart - index of the first tuple of \a this array to assign
2497  *              values to.
2498  *  \param [in] a - the array to copy values from.
2499  *  \param [in] tuplesSelec - the array specifying tuples of \a a to copy.
2500  *  \throw If \a this is not allocated.
2501  *  \throw If \a a is NULL.
2502  *  \throw If \a a is not allocated.
2503  *  \throw If \a tuplesSelec is NULL.
2504  *  \throw If \a tuplesSelec is not allocated.
2505  *  \throw If <em>this->getNumberOfComponents() != a->getNumberOfComponents()</em>.
2506  *  \throw If \a tuplesSelec->getNumberOfComponents() != 1.
2507  *  \throw If <em>tupleIdStart + tuplesSelec->getNumberOfTuples() > this->getNumberOfTuples().</em>
2508  *  \throw If any tuple index given by \a tuplesSelec is out of a valid range for 
2509  *         \a a array.
2510  */
2511 void DataArrayDouble::setContigPartOfSelectedValues(int tupleIdStart, const DataArrayDouble *a, const DataArrayInt *tuplesSelec) throw(INTERP_KERNEL::Exception)
2512 {
2513   if(!a || !tuplesSelec)
2514     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues : input DataArray is NULL !");
2515   checkAllocated();
2516   a->checkAllocated();
2517   tuplesSelec->checkAllocated();
2518   int nbOfComp=getNumberOfComponents();
2519   if(nbOfComp!=a->getNumberOfComponents())
2520     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues : This and a do not have the same number of components !");
2521   if(tuplesSelec->getNumberOfComponents()!=1)
2522     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues : Expecting to have a tuple selector DataArrayInt instance with exactly 1 component !");
2523   int thisNt=getNumberOfTuples();
2524   int aNt=a->getNumberOfTuples();
2525   int nbOfTupleToWrite=tuplesSelec->getNumberOfTuples();
2526   double *valsToSet=getPointer()+tupleIdStart*nbOfComp;
2527   if(tupleIdStart+nbOfTupleToWrite>thisNt)
2528     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues : invalid number range of values to write !");
2529   const double *valsSrc=a->getConstPointer();
2530   for(const int *tuple=tuplesSelec->begin();tuple!=tuplesSelec->end();tuple++,valsToSet+=nbOfComp)
2531     {
2532       if(*tuple>=0 && *tuple<aNt)
2533         {
2534           std::copy(valsSrc+nbOfComp*(*tuple),valsSrc+nbOfComp*(*tuple+1),valsToSet);
2535         }
2536       else
2537         {
2538           std::ostringstream oss; oss << "DataArrayDouble::setContigPartOfSelectedValues : Tuple #" << std::distance(tuplesSelec->begin(),tuple);
2539           oss << " of 'tuplesSelec' request of tuple id #" << *tuple << " in 'a' ! It should be in [0," << aNt << ") !";
2540           throw INTERP_KERNEL::Exception(oss.str().c_str());
2541         }
2542     }
2543 }
2544
2545 /*!
2546  * Copy some tuples from another DataArrayDouble (\a a) into contiguous tuples
2547  * of \a this array. Textual data is not copied. Both arrays must have equal number of
2548  * components.
2549  * The tuples to copy are defined by three values similar to parameters of
2550  * the Python function \c range(\c start,\c stop,\c step).
2551  * The tuples to assign to are defined by index of the first tuple, and
2552  * their number is defined by number of tuples to copy.
2553  * All components of selected tuples are copied.
2554  *  \param [in] tupleIdStart - index of the first tuple of \a this array to assign
2555  *              values to.
2556  *  \param [in] a - the array to copy values from.
2557  *  \param [in] bg - index of the first tuple to copy of the array \a a.
2558  *  \param [in] end2 - index of the tuple of \a a before which the tuples to copy
2559  *              are located.
2560  *  \param [in] step - index increment to get index of the next tuple to copy.
2561  *  \throw If \a this is not allocated.
2562  *  \throw If \a a is NULL.
2563  *  \throw If \a a is not allocated.
2564  *  \throw If <em>this->getNumberOfComponents() != a->getNumberOfComponents()</em>.
2565  *  \throw If <em>tupleIdStart + len(range(bg,end2,step)) > this->getNumberOfTuples().</em>
2566  *  \throw If parameters specifying tuples to copy, do not give a
2567  *            non-empty range of increasing indices or indices are out of a valid range
2568  *            for the array \a a.
2569  */
2570 void DataArrayDouble::setContigPartOfSelectedValues2(int tupleIdStart, const DataArrayDouble *a, int bg, int end2, int step) throw(INTERP_KERNEL::Exception)
2571 {
2572   if(!a)
2573     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues2 : input DataArrayDouble is NULL !");
2574   checkAllocated();
2575   a->checkAllocated();
2576   int nbOfComp=getNumberOfComponents();
2577   const char msg[]="DataArrayDouble::setContigPartOfSelectedValues2";
2578   int nbOfTupleToWrite=DataArray::GetNumberOfItemGivenBES(bg,end2,step,msg);
2579   if(nbOfComp!=a->getNumberOfComponents())
2580     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues2 : This and a do not have the same number of components !");
2581   int thisNt=getNumberOfTuples();
2582   int aNt=a->getNumberOfTuples();
2583   double *valsToSet=getPointer()+tupleIdStart*nbOfComp;
2584   if(tupleIdStart+nbOfTupleToWrite>thisNt)
2585     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues2 : invalid number range of values to write !");
2586   if(end2>aNt)
2587     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues2 : invalid range of values to read !");
2588   const double *valsSrc=a->getConstPointer()+bg*nbOfComp;
2589   for(int i=0;i<nbOfTupleToWrite;i++,valsToSet+=nbOfComp,valsSrc+=step*nbOfComp)
2590     {
2591       std::copy(valsSrc,valsSrc+nbOfComp,valsToSet);
2592     }
2593 }
2594
2595 /*!
2596  * Returns a value located at specified tuple and component.
2597  * This method is equivalent to DataArrayDouble::getIJ() except that validity of
2598  * parameters is checked. So this method is safe but expensive if used to go through
2599  * all values of \a this.
2600  *  \param [in] tupleId - index of tuple of interest.
2601  *  \param [in] compoId - index of component of interest.
2602  *  \return double - value located by \a tupleId and \a compoId.
2603  *  \throw If \a this is not allocated.
2604  *  \throw If condition <em>( 0 <= tupleId < this->getNumberOfTuples() )</em> is violated.
2605  *  \throw If condition <em>( 0 <= compoId < this->getNumberOfComponents() )</em> is violated.
2606  */
2607 double DataArrayDouble::getIJSafe(int tupleId, int compoId) const throw(INTERP_KERNEL::Exception)
2608 {
2609   checkAllocated();
2610   if(tupleId<0 || tupleId>=getNumberOfTuples())
2611     {
2612       std::ostringstream oss; oss << "DataArrayDouble::getIJSafe : request for tupleId " << tupleId << " should be in [0," << getNumberOfTuples() << ") !";
2613       throw INTERP_KERNEL::Exception(oss.str().c_str());
2614     }
2615   if(compoId<0 || compoId>=getNumberOfComponents())
2616     {
2617       std::ostringstream oss; oss << "DataArrayDouble::getIJSafe : request for compoId " << compoId << " should be in [0," << getNumberOfComponents() << ") !";
2618       throw INTERP_KERNEL::Exception(oss.str().c_str());
2619     }
2620   return _mem[tupleId*_info_on_compo.size()+compoId];
2621 }
2622
2623 /*!
2624  * Returns the last value of \a this. 
2625  *  \return double - the last value of \a this array.
2626  *  \throw If \a this is not allocated.
2627  *  \throw If \a this->getNumberOfComponents() != 1.
2628  *  \throw If \a this->getNumberOfTuples() < 1.
2629  */
2630 double DataArrayDouble::back() const throw(INTERP_KERNEL::Exception)
2631 {
2632   checkAllocated();
2633   if(getNumberOfComponents()!=1)
2634     throw INTERP_KERNEL::Exception("DataArrayDouble::back : number of components not equal to one !");
2635   int nbOfTuples=getNumberOfTuples();
2636   if(nbOfTuples<1)
2637     throw INTERP_KERNEL::Exception("DataArrayDouble::back : number of tuples must be >= 1 !");
2638   return *(getConstPointer()+nbOfTuples-1);
2639 }
2640
2641 void DataArrayDouble::SetArrayIn(DataArrayDouble *newArray, DataArrayDouble* &arrayToSet)
2642 {
2643   if(newArray!=arrayToSet)
2644     {
2645       if(arrayToSet)
2646         arrayToSet->decrRef();
2647       arrayToSet=newArray;
2648       if(arrayToSet)
2649         arrayToSet->incrRef();
2650     }
2651 }
2652
2653 /*!
2654  * Sets a C array to be used as raw data of \a this. The previously set info
2655  *  of components is retained and re-sized. 
2656  * For more info see \ref MEDCouplingArraySteps1.
2657  *  \param [in] array - the C array to be used as raw data of \a this.
2658  *  \param [in] ownership - if \a true, \a array will be deallocated at destruction of \a this.
2659  *  \param [in] type - specifies how to deallocate \a array. If \a type == ParaMEDMEM::CPP_DEALLOC,
2660  *                     \c delete [] \c array; will be called. If \a type == ParaMEDMEM::C_DEALLOC,
2661  *                     \c free(\c array ) will be called.
2662  *  \param [in] nbOfTuple - new number of tuples in \a this.
2663  *  \param [in] nbOfCompo - new number of components in \a this.
2664  */
2665 void DataArrayDouble::useArray(const double *array, bool ownership, DeallocType type, int nbOfTuple, int nbOfCompo) throw(INTERP_KERNEL::Exception)
2666 {
2667   _info_on_compo.resize(nbOfCompo);
2668   _mem.useArray(array,ownership,type,(std::size_t)nbOfTuple*nbOfCompo);
2669   declareAsNew();
2670 }
2671
2672 void DataArrayDouble::useExternalArrayWithRWAccess(const double *array, int nbOfTuple, int nbOfCompo) throw(INTERP_KERNEL::Exception)
2673 {
2674   _info_on_compo.resize(nbOfCompo);
2675   _mem.useExternalArrayWithRWAccess(array,(std::size_t)nbOfTuple*nbOfCompo);
2676   declareAsNew();
2677 }
2678
2679 /*!
2680  * Checks if 0.0 value is present in \a this array. If it is the case, an exception
2681  * is thrown.
2682  * \throw If zero is found in \a this array.
2683  */
2684 void DataArrayDouble::checkNoNullValues() const throw(INTERP_KERNEL::Exception)
2685 {
2686   const double *tmp=getConstPointer();
2687   std::size_t nbOfElems=getNbOfElems();
2688   const double *where=std::find(tmp,tmp+nbOfElems,0.);
2689   if(where!=tmp+nbOfElems)
2690     throw INTERP_KERNEL::Exception("A value 0.0 have been detected !");
2691 }
2692
2693 /*!
2694  * Computes minimal and maximal value in each component. An output array is filled
2695  * with \c 2 * \a this->getNumberOfComponents() values, so the caller is to allocate
2696  * enough memory before calling this method.
2697  *  \param [out] bounds - array of size at least 2 *\a this->getNumberOfComponents().
2698  *               It is filled as follows:<br>
2699  *               \a bounds[0] = \c min_of_component_0 <br>
2700  *               \a bounds[1] = \c max_of_component_0 <br>
2701  *               \a bounds[2] = \c min_of_component_1 <br>
2702  *               \a bounds[3] = \c max_of_component_1 <br>
2703  *               ...
2704  */
2705 void DataArrayDouble::getMinMaxPerComponent(double *bounds) const throw(INTERP_KERNEL::Exception)
2706 {
2707   checkAllocated();
2708   int dim=getNumberOfComponents();
2709   for (int idim=0; idim<dim; idim++)
2710     {
2711       bounds[idim*2]=std::numeric_limits<double>::max();
2712       bounds[idim*2+1]=-std::numeric_limits<double>::max();
2713     } 
2714   const double *ptr=getConstPointer();
2715   int nbOfTuples=getNumberOfTuples();
2716   for(int i=0;i<nbOfTuples;i++)
2717     {
2718       for(int idim=0;idim<dim;idim++)
2719         {
2720           if(bounds[idim*2]>ptr[i*dim+idim])
2721             {
2722               bounds[idim*2]=ptr[i*dim+idim];
2723             }
2724           if(bounds[idim*2+1]<ptr[i*dim+idim])
2725             {
2726               bounds[idim*2+1]=ptr[i*dim+idim];
2727             }
2728         }
2729     }
2730 }
2731
2732 /*!
2733  * This method retrieves a newly allocated DataArrayDouble instance having same number of tuples than \a this and twice number of components than \a this
2734  * to store both the min and max per component of each tuples. 
2735  * \param [in] epsilon the width of the bbox (identical in each direction) - 0.0 by default
2736  *
2737  * \return a newly created DataArrayDouble instance having \c this->getNumberOfTuples() tuples and 2 * \c this->getNumberOfComponent() components
2738  *
2739  * \throw If \a this is not allocated yet.
2740  */
2741 DataArrayDouble *DataArrayDouble::computeBBoxPerTuple(double epsilon)const throw(INTERP_KERNEL::Exception)
2742 {
2743   checkAllocated();
2744   const double *dataPtr=getConstPointer();
2745   int nbOfCompo=getNumberOfComponents();
2746   int nbTuples=getNumberOfTuples();
2747   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> bbox=DataArrayDouble::New();
2748   bbox->alloc(nbTuples,2*nbOfCompo);
2749   double *bboxPtr=bbox->getPointer();
2750   for(int i=0;i<nbTuples;i++)
2751     {
2752       for(int j=0;j<nbOfCompo;j++)
2753         {
2754           bboxPtr[2*nbOfCompo*i+2*j]=dataPtr[nbOfCompo*i+j]-epsilon;
2755           bboxPtr[2*nbOfCompo*i+2*j+1]=dataPtr[nbOfCompo*i+j]+epsilon;
2756         }
2757     }
2758   return bbox.retn();
2759 }
2760
2761 /*!
2762  * For each tuples **t** in \a other, this method retrieves tuples in \a this that are equal to **t**.
2763  * Two tuples are considered equal if the euclidian distance between the two tuples is lower than \a eps.
2764  * 
2765  * \param [in] other a DataArrayDouble having same number of components than \a this.
2766  * \param [in] eps absolute precision representing distance (using infinite norm) between 2 tuples behind which 2 tuples are considered equal.
2767  * \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.
2768  *             \a cI allows to extract information in \a c.
2769  * \param [out] cI is an indirection array that allows to extract the data contained in \a c.
2770  *
2771  * \throw In case of:
2772  *  - \a this is not allocated
2773  *  - \a other is not allocated or null
2774  *  - \a this and \a other do not have the same number of components
2775  *  - if number of components of \a this is not in [1,2,3]
2776  *
2777  * \sa MEDCouplingPointSet::getNodeIdsNearPoints, DataArrayDouble::getDifferentValues
2778  */
2779 void DataArrayDouble::computeTupleIdsNearTuples(const DataArrayDouble *other, double eps, DataArrayInt *& c, DataArrayInt *& cI) const throw(INTERP_KERNEL::Exception)
2780 {
2781   if(!other)
2782     throw INTERP_KERNEL::Exception("DataArrayDouble::computeTupleIdsNearTuples : input pointer other is null !");
2783   checkAllocated();
2784   other->checkAllocated();
2785   int nbOfCompo=getNumberOfComponents();
2786   int otherNbOfCompo=other->getNumberOfComponents();
2787   if(nbOfCompo!=otherNbOfCompo)
2788     throw INTERP_KERNEL::Exception("DataArrayDouble::computeTupleIdsNearTuples : number of components should be equal between this and other !");
2789   int nbOfTuplesOther=other->getNumberOfTuples();
2790   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cArr(DataArrayInt::New()),cIArr(DataArrayInt::New()); cArr->alloc(0,1); cIArr->pushBackSilent(0);
2791   switch(nbOfCompo)
2792     {
2793     case 3:
2794       {
2795         BBTreePts<3,int> myTree(begin(),0,0,getNumberOfTuples(),eps);
2796         FindTupleIdsNearTuplesAlg<3>(myTree,other->getConstPointer(),nbOfTuplesOther,eps,cArr,cIArr);
2797         break;
2798       }
2799     case 2:
2800       {
2801         BBTreePts<2,int> myTree(begin(),0,0,getNumberOfTuples(),eps);
2802         FindTupleIdsNearTuplesAlg<2>(myTree,other->getConstPointer(),nbOfTuplesOther,eps,cArr,cIArr);
2803         break;
2804       }
2805     case 1:
2806       {
2807         BBTreePts<1,int> myTree(begin(),0,0,getNumberOfTuples(),eps);
2808         FindTupleIdsNearTuplesAlg<1>(myTree,other->getConstPointer(),nbOfTuplesOther,eps,cArr,cIArr);
2809         break;
2810       }
2811     default:
2812       throw INTERP_KERNEL::Exception("Unexpected spacedim of coords for computeTupleIdsNearTuples. Must be 1, 2 or 3.");
2813     }
2814   c=cArr.retn(); cI=cIArr.retn();
2815 }
2816
2817 /*!
2818  * 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
2819  * around origin of 'radius' 1.
2820  * 
2821  * \param [in] eps absolute epsilon. under that value of delta between max and min no scale is performed.
2822  */
2823 void DataArrayDouble::recenterForMaxPrecision(double eps) throw(INTERP_KERNEL::Exception)
2824 {
2825   checkAllocated();
2826   int dim=getNumberOfComponents();
2827   std::vector<double> bounds(2*dim);
2828   getMinMaxPerComponent(&bounds[0]);
2829   for(int i=0;i<dim;i++)
2830     {
2831       double delta=bounds[2*i+1]-bounds[2*i];
2832       double offset=(bounds[2*i]+bounds[2*i+1])/2.;
2833       if(delta>eps)
2834         applyLin(1./delta,-offset/delta,i);
2835       else
2836         applyLin(1.,-offset,i);
2837     }
2838 }
2839
2840 /*!
2841  * Returns the maximal value and its location within \a this one-dimensional array.
2842  *  \param [out] tupleId - index of the tuple holding the maximal value.
2843  *  \return double - the maximal value among all values of \a this array.
2844  *  \throw If \a this->getNumberOfComponents() != 1
2845  *  \throw If \a this->getNumberOfTuples() < 1
2846  */
2847 double DataArrayDouble::getMaxValue(int& tupleId) const throw(INTERP_KERNEL::Exception)
2848 {
2849   checkAllocated();
2850   if(getNumberOfComponents()!=1)
2851     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 !");
2852   int nbOfTuples=getNumberOfTuples();
2853   if(nbOfTuples<=0)
2854     throw INTERP_KERNEL::Exception("DataArrayDouble::getMaxValue : array exists but number of tuples must be > 0 !");
2855   const double *vals=getConstPointer();
2856   const double *loc=std::max_element(vals,vals+nbOfTuples);
2857   tupleId=(int)std::distance(vals,loc);
2858   return *loc;
2859 }
2860
2861 /*!
2862  * Returns the maximal value within \a this array that is allowed to have more than
2863  *  one component.
2864  *  \return double - the maximal value among all values of \a this array.
2865  *  \throw If \a this is not allocated.
2866  */
2867 double DataArrayDouble::getMaxValueInArray() const throw(INTERP_KERNEL::Exception)
2868 {
2869   checkAllocated();
2870   const double *loc=std::max_element(begin(),end());
2871   return *loc;
2872 }
2873
2874 /*!
2875  * Returns the maximal value and all its locations within \a this one-dimensional array.
2876  *  \param [out] tupleIds - a new instance of DataArrayInt containg indices of
2877  *               tuples holding the maximal value. The caller is to delete it using
2878  *               decrRef() as it is no more needed.
2879  *  \return double - the maximal value among all values of \a this array.
2880  *  \throw If \a this->getNumberOfComponents() != 1
2881  *  \throw If \a this->getNumberOfTuples() < 1
2882  */
2883 double DataArrayDouble::getMaxValue2(DataArrayInt*& tupleIds) const throw(INTERP_KERNEL::Exception)
2884 {
2885   int tmp;
2886   tupleIds=0;
2887   double ret=getMaxValue(tmp);
2888   tupleIds=getIdsInRange(ret,ret);
2889   return ret;
2890 }
2891
2892 /*!
2893  * Returns the minimal value and its location within \a this one-dimensional array.
2894  *  \param [out] tupleId - index of the tuple holding the minimal value.
2895  *  \return double - the minimal value among all values of \a this array.
2896  *  \throw If \a this->getNumberOfComponents() != 1
2897  *  \throw If \a this->getNumberOfTuples() < 1
2898  */
2899 double DataArrayDouble::getMinValue(int& tupleId) const throw(INTERP_KERNEL::Exception)
2900 {
2901   checkAllocated();
2902   if(getNumberOfComponents()!=1)
2903     throw INTERP_KERNEL::Exception("DataArrayDouble::getMinValue : must be applied on DataArrayDouble with only one component, you can call 'rearrange' method before call 'getMinValueInArray' method !");
2904   int nbOfTuples=getNumberOfTuples();
2905   if(nbOfTuples<=0)
2906     throw INTERP_KERNEL::Exception("DataArrayDouble::getMinValue : array exists but number of tuples must be > 0 !");
2907   const double *vals=getConstPointer();
2908   const double *loc=std::min_element(vals,vals+nbOfTuples);
2909   tupleId=(int)std::distance(vals,loc);
2910   return *loc;
2911 }
2912
2913 /*!
2914  * Returns the minimal value within \a this array that is allowed to have more than
2915  *  one component.
2916  *  \return double - the minimal value among all values of \a this array.
2917  *  \throw If \a this is not allocated.
2918  */
2919 double DataArrayDouble::getMinValueInArray() const throw(INTERP_KERNEL::Exception)
2920 {
2921   checkAllocated();
2922   const double *loc=std::min_element(begin(),end());
2923   return *loc;
2924 }
2925
2926 /*!
2927  * Returns the minimal value and all its locations within \a this one-dimensional array.
2928  *  \param [out] tupleIds - a new instance of DataArrayInt containg indices of
2929  *               tuples holding the minimal value. The caller is to delete it using
2930  *               decrRef() as it is no more needed.
2931  *  \return double - the minimal value among all values of \a this array.
2932  *  \throw If \a this->getNumberOfComponents() != 1
2933  *  \throw If \a this->getNumberOfTuples() < 1
2934  */
2935 double DataArrayDouble::getMinValue2(DataArrayInt*& tupleIds) const throw(INTERP_KERNEL::Exception)
2936 {
2937   int tmp;
2938   tupleIds=0;
2939   double ret=getMinValue(tmp);
2940   tupleIds=getIdsInRange(ret,ret);
2941   return ret;
2942 }
2943
2944 /*!
2945  * Returns the average value of \a this one-dimensional array.
2946  *  \return double - the average value over all values of \a this array.
2947  *  \throw If \a this->getNumberOfComponents() != 1
2948  *  \throw If \a this->getNumberOfTuples() < 1
2949  */
2950 double DataArrayDouble::getAverageValue() const throw(INTERP_KERNEL::Exception)
2951 {
2952   if(getNumberOfComponents()!=1)
2953     throw INTERP_KERNEL::Exception("DataArrayDouble::getAverageValue : must be applied on DataArrayDouble with only one component, you can call 'rearrange' method before !");
2954   int nbOfTuples=getNumberOfTuples();
2955   if(nbOfTuples<=0)
2956     throw INTERP_KERNEL::Exception("DataArrayDouble::getAverageValue : array exists but number of tuples must be > 0 !");
2957   const double *vals=getConstPointer();
2958   double ret=std::accumulate(vals,vals+nbOfTuples,0.);
2959   return ret/nbOfTuples;
2960 }
2961
2962 /*!
2963  * Returns the Euclidean norm of the vector defined by \a this array.
2964  *  \return double - the value of the Euclidean norm, i.e.
2965  *          the square root of the inner product of vector.
2966  *  \throw If \a this is not allocated.
2967  */
2968 double DataArrayDouble::norm2() const throw(INTERP_KERNEL::Exception)
2969 {
2970   checkAllocated();
2971   double ret=0.;
2972   std::size_t nbOfElems=getNbOfElems();
2973   const double *pt=getConstPointer();
2974   for(std::size_t i=0;i<nbOfElems;i++,pt++)
2975     ret+=(*pt)*(*pt);
2976   return sqrt(ret);
2977 }
2978
2979 /*!
2980  * Returns the maximum norm of the vector defined by \a this array.
2981  *  \return double - the value of the maximum norm, i.e.
2982  *          the maximal absolute value among values of \a this array.
2983  *  \throw If \a this is not allocated.
2984  */
2985 double DataArrayDouble::normMax() const throw(INTERP_KERNEL::Exception)
2986 {
2987   checkAllocated();
2988   double ret=-1.;
2989   std::size_t nbOfElems=getNbOfElems();
2990   const double *pt=getConstPointer();
2991   for(std::size_t i=0;i<nbOfElems;i++,pt++)
2992     {
2993       double val=std::abs(*pt);
2994       if(val>ret)
2995         ret=val;
2996     }
2997   return ret;
2998 }
2999
3000 /*!
3001  * Accumulates values of each component of \a this array.
3002  *  \param [out] res - an array of length \a this->getNumberOfComponents(), allocated 
3003  *         by the caller, that is filled by this method with sum value for each
3004  *         component.
3005  *  \throw If \a this is not allocated.
3006  */
3007 void DataArrayDouble::accumulate(double *res) const throw(INTERP_KERNEL::Exception)
3008 {
3009   checkAllocated();
3010   const double *ptr=getConstPointer();
3011   int nbTuple=getNumberOfTuples();
3012   int nbComps=getNumberOfComponents();
3013   std::fill(res,res+nbComps,0.);
3014   for(int i=0;i<nbTuple;i++)
3015     std::transform(ptr+i*nbComps,ptr+(i+1)*nbComps,res,res,std::plus<double>());
3016 }
3017
3018 /*!
3019  * This method returns the min distance from an external tuple defined by [ \a tupleBg , \a tupleEnd ) to \a this and
3020  * the first tuple in \a this that matches the returned distance. If there is no tuples in \a this an exception will be thrown.
3021  *
3022  *
3023  * \a this is expected to be allocated and expected to have a number of components equal to the distance from \a tupleBg to
3024  * \a tupleEnd. If not an exception will be thrown.
3025  *
3026  * \param [in] tupleBg start pointer (included) of input external tuple
3027  * \param [in] tupleEnd end pointer (not included) of input external tuple
3028  * \param [out] tupleId the tuple id in \a this that matches the min of distance between \a this and input external tuple
3029  * \return the min distance.
3030  * \sa MEDCouplingUMesh::distanceToPoint
3031  */
3032 double DataArrayDouble::distanceToTuple(const double *tupleBg, const double *tupleEnd, int& tupleId) const throw(INTERP_KERNEL::Exception)
3033 {
3034   checkAllocated();
3035   int nbTuple=getNumberOfTuples();
3036   int nbComps=getNumberOfComponents();
3037   if(nbComps!=(int)std::distance(tupleBg,tupleEnd))
3038     { 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()); }
3039   if(nbTuple==0)
3040     throw INTERP_KERNEL::Exception("DataArrayDouble::distanceToTuple : no tuple in this ! No distance to compute !");
3041   double ret0=std::numeric_limits<double>::max();
3042   tupleId=-1;
3043   const double *work=getConstPointer();
3044   for(int i=0;i<nbTuple;i++)
3045     {
3046       double val=0.;
3047       for(int j=0;j<nbComps;j++,work++) 
3048         val+=(*work-tupleBg[j])*((*work-tupleBg[j]));
3049       if(val>=ret0)
3050         continue;
3051       else
3052         { ret0=val; tupleId=i; }
3053     }
3054   return sqrt(ret0);
3055 }
3056
3057 /*!
3058  * Accumulate values of the given component of \a this array.
3059  *  \param [in] compId - the index of the component of interest.
3060  *  \return double - a sum value of \a compId-th component.
3061  *  \throw If \a this is not allocated.
3062  *  \throw If \a the condition ( 0 <= \a compId < \a this->getNumberOfComponents() ) is
3063  *         not respected.
3064  */
3065 double DataArrayDouble::accumulate(int compId) const throw(INTERP_KERNEL::Exception)
3066 {
3067   checkAllocated();
3068   const double *ptr=getConstPointer();
3069   int nbTuple=getNumberOfTuples();
3070   int nbComps=getNumberOfComponents();
3071   if(compId<0 || compId>=nbComps)
3072     throw INTERP_KERNEL::Exception("DataArrayDouble::accumulate : Invalid compId specified : No such nb of components !");
3073   double ret=0.;
3074   for(int i=0;i<nbTuple;i++)
3075     ret+=ptr[i*nbComps+compId];
3076   return ret;
3077 }
3078
3079 /*!
3080  * Converts each 2D point defined by the tuple of \a this array from the Polar to the
3081  * Cartesian coordinate system. The two components of the tuple of \a this array are 
3082  * considered to contain (1) radius and (2) angle of the point in the Polar CS.
3083  *  \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
3084  *          contains X and Y coordinates of the point in the Cartesian CS. The caller
3085  *          is to delete this array using decrRef() as it is no more needed. The array
3086  *          does not contain any textual info on components.
3087  *  \throw If \a this->getNumberOfComponents() != 2.
3088  */
3089 DataArrayDouble *DataArrayDouble::fromPolarToCart() const throw(INTERP_KERNEL::Exception)
3090 {
3091   checkAllocated();
3092   int nbOfComp=getNumberOfComponents();
3093   if(nbOfComp!=2)
3094     throw INTERP_KERNEL::Exception("DataArrayDouble::fromPolarToCart : must be an array with exactly 2 components !");
3095   int nbOfTuple=getNumberOfTuples();
3096   DataArrayDouble *ret=DataArrayDouble::New();
3097   ret->alloc(nbOfTuple,2);
3098   double *w=ret->getPointer();
3099   const double *wIn=getConstPointer();
3100   for(int i=0;i<nbOfTuple;i++,w+=2,wIn+=2)
3101     {
3102       w[0]=wIn[0]*cos(wIn[1]);
3103       w[1]=wIn[0]*sin(wIn[1]);
3104     }
3105   return ret;
3106 }
3107
3108 /*!
3109  * Converts each 3D point defined by the tuple of \a this array from the Cylindrical to
3110  * the Cartesian coordinate system. The three components of the tuple of \a this array 
3111  * are considered to contain (1) radius, (2) azimuth and (3) altitude of the point in
3112  * the Cylindrical CS.
3113  *  \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
3114  *          contains X, Y and Z coordinates of the point in the Cartesian CS. The info
3115  *          on the third component is copied from \a this array. The caller
3116  *          is to delete this array using decrRef() as it is no more needed. 
3117  *  \throw If \a this->getNumberOfComponents() != 3.
3118  */
3119 DataArrayDouble *DataArrayDouble::fromCylToCart() const throw(INTERP_KERNEL::Exception)
3120 {
3121   checkAllocated();
3122   int nbOfComp=getNumberOfComponents();
3123   if(nbOfComp!=3)
3124     throw INTERP_KERNEL::Exception("DataArrayDouble::fromCylToCart : must be an array with exactly 3 components !");
3125   int nbOfTuple=getNumberOfTuples();
3126   DataArrayDouble *ret=DataArrayDouble::New();
3127   ret->alloc(getNumberOfTuples(),3);
3128   double *w=ret->getPointer();
3129   const double *wIn=getConstPointer();
3130   for(int i=0;i<nbOfTuple;i++,w+=3,wIn+=3)
3131     {
3132       w[0]=wIn[0]*cos(wIn[1]);
3133       w[1]=wIn[0]*sin(wIn[1]);
3134       w[2]=wIn[2];
3135     }
3136   ret->setInfoOnComponent(2,getInfoOnComponent(2).c_str());
3137   return ret;
3138 }
3139
3140 /*!
3141  * Converts each 3D point defined by the tuple of \a this array from the Spherical to
3142  * the Cartesian coordinate system. The three components of the tuple of \a this array 
3143  * are considered to contain (1) radius, (2) polar angle and (3) azimuthal angle of the
3144  * point in the Cylindrical CS.
3145  *  \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
3146  *          contains X, Y and Z coordinates of the point in the Cartesian CS. The info
3147  *          on the third component is copied from \a this array. The caller
3148  *          is to delete this array using decrRef() as it is no more needed.
3149  *  \throw If \a this->getNumberOfComponents() != 3.
3150  */
3151 DataArrayDouble *DataArrayDouble::fromSpherToCart() const throw(INTERP_KERNEL::Exception)
3152 {
3153   checkAllocated();
3154   int nbOfComp=getNumberOfComponents();
3155   if(nbOfComp!=3)
3156     throw INTERP_KERNEL::Exception("DataArrayDouble::fromSpherToCart : must be an array with exactly 3 components !");
3157   int nbOfTuple=getNumberOfTuples();
3158   DataArrayDouble *ret=DataArrayDouble::New();
3159   ret->alloc(getNumberOfTuples(),3);
3160   double *w=ret->getPointer();
3161   const double *wIn=getConstPointer();
3162   for(int i=0;i<nbOfTuple;i++,w+=3,wIn+=3)
3163     {
3164       w[0]=wIn[0]*cos(wIn[2])*sin(wIn[1]);
3165       w[1]=wIn[0]*sin(wIn[2])*sin(wIn[1]);
3166       w[2]=wIn[0]*cos(wIn[1]);
3167     }
3168   return ret;
3169 }
3170
3171 /*!
3172  * Computes the doubly contracted product of every tensor defined by the tuple of \a this
3173  * array contating 6 components.
3174  *  \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
3175  *          is calculated from the tuple <em>(t)</em> of \a this array as follows:
3176  *          \f$ t[0]^2+t[1]^2+t[2]^2+2*t[3]^2+2*t[4]^2+2*t[5]^2\f$.
3177  *         The caller is to delete this result array using decrRef() as it is no more needed. 
3178  *  \throw If \a this->getNumberOfComponents() != 6.
3179  */
3180 DataArrayDouble *DataArrayDouble::doublyContractedProduct() const throw(INTERP_KERNEL::Exception)
3181 {
3182   checkAllocated();
3183   int nbOfComp=getNumberOfComponents();
3184   if(nbOfComp!=6)
3185     throw INTERP_KERNEL::Exception("DataArrayDouble::doublyContractedProduct : must be an array with exactly 6 components !");
3186   DataArrayDouble *ret=DataArrayDouble::New();
3187   int nbOfTuple=getNumberOfTuples();
3188   ret->alloc(nbOfTuple,1);
3189   const double *src=getConstPointer();
3190   double *dest=ret->getPointer();
3191   for(int i=0;i<nbOfTuple;i++,dest++,src+=6)
3192     *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];
3193   return ret;
3194 }
3195
3196 /*!
3197  * Computes the determinant of every square matrix defined by the tuple of \a this
3198  * array, which contains either 4, 6 or 9 components. The case of 6 components
3199  * corresponds to that of the upper triangular matrix.
3200  *  \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
3201  *          is the determinant of matrix of the corresponding tuple of \a this array.
3202  *          The caller is to delete this result array using decrRef() as it is no more
3203  *          needed. 
3204  *  \throw If \a this->getNumberOfComponents() is not in [4,6,9].
3205  */
3206 DataArrayDouble *DataArrayDouble::determinant() const throw(INTERP_KERNEL::Exception)
3207 {
3208   checkAllocated();
3209   DataArrayDouble *ret=DataArrayDouble::New();
3210   int nbOfTuple=getNumberOfTuples();
3211   ret->alloc(nbOfTuple,1);
3212   const double *src=getConstPointer();
3213   double *dest=ret->getPointer();
3214   switch(getNumberOfComponents())
3215     {
3216     case 6:
3217       for(int i=0;i<nbOfTuple;i++,dest++,src+=6)
3218         *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];
3219       return ret;
3220     case 4:
3221       for(int i=0;i<nbOfTuple;i++,dest++,src+=4)
3222         *dest=src[0]*src[3]-src[1]*src[2];
3223       return ret;
3224     case 9:
3225       for(int i=0;i<nbOfTuple;i++,dest++,src+=9)
3226         *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];
3227       return ret;
3228     default:
3229       ret->decrRef();
3230       throw INTERP_KERNEL::Exception("DataArrayDouble::determinant : Invalid number of components ! must be in 4,6,9 !");
3231     }
3232 }
3233
3234 /*!
3235  * Computes 3 eigenvalues of every upper triangular matrix defined by the tuple of
3236  * \a this array, which contains 6 components.
3237  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing 3
3238  *          components, whose each tuple contains the eigenvalues of the matrix of
3239  *          corresponding tuple of \a this array. 
3240  *          The caller is to delete this result array using decrRef() as it is no more
3241  *          needed. 
3242  *  \throw If \a this->getNumberOfComponents() != 6.
3243  */
3244 DataArrayDouble *DataArrayDouble::eigenValues() const throw(INTERP_KERNEL::Exception)
3245 {
3246   checkAllocated();
3247   int nbOfComp=getNumberOfComponents();
3248   if(nbOfComp!=6)
3249     throw INTERP_KERNEL::Exception("DataArrayDouble::eigenValues : must be an array with exactly 6 components !");
3250   DataArrayDouble *ret=DataArrayDouble::New();
3251   int nbOfTuple=getNumberOfTuples();
3252   ret->alloc(nbOfTuple,3);
3253   const double *src=getConstPointer();
3254   double *dest=ret->getPointer();
3255   for(int i=0;i<nbOfTuple;i++,dest+=3,src+=6)
3256     INTERP_KERNEL::computeEigenValues6(src,dest);
3257   return ret;
3258 }
3259
3260 /*!
3261  * Computes 3 eigenvectors of every upper triangular matrix defined by the tuple of
3262  * \a this array, which contains 6 components.
3263  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing 9
3264  *          components, whose each tuple contains 3 eigenvectors of the matrix of
3265  *          corresponding tuple of \a this array.
3266  *          The caller is to delete this result array using decrRef() as it is no more
3267  *          needed.
3268  *  \throw If \a this->getNumberOfComponents() != 6.
3269  */
3270 DataArrayDouble *DataArrayDouble::eigenVectors() const throw(INTERP_KERNEL::Exception)
3271 {
3272   checkAllocated();
3273   int nbOfComp=getNumberOfComponents();
3274   if(nbOfComp!=6)
3275     throw INTERP_KERNEL::Exception("DataArrayDouble::eigenVectors : must be an array with exactly 6 components !");
3276   DataArrayDouble *ret=DataArrayDouble::New();
3277   int nbOfTuple=getNumberOfTuples();
3278   ret->alloc(nbOfTuple,9);
3279   const double *src=getConstPointer();
3280   double *dest=ret->getPointer();
3281   for(int i=0;i<nbOfTuple;i++,src+=6)
3282     {
3283       double tmp[3];
3284       INTERP_KERNEL::computeEigenValues6(src,tmp);
3285       for(int j=0;j<3;j++,dest+=3)
3286         INTERP_KERNEL::computeEigenVectorForEigenValue6(src,tmp[j],1e-12,dest);
3287     }
3288   return ret;
3289 }
3290
3291 /*!
3292  * Computes the inverse matrix of every matrix defined by the tuple of \a this
3293  * array, which contains either 4, 6 or 9 components. The case of 6 components
3294  * corresponds to that of the upper triangular matrix.
3295  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
3296  *          same number of components as \a this one, whose each tuple is the inverse
3297  *          matrix of the matrix of corresponding tuple of \a this array. 
3298  *          The caller is to delete this result array using decrRef() as it is no more
3299  *          needed. 
3300  *  \throw If \a this->getNumberOfComponents() is not in [4,6,9].
3301  */
3302 DataArrayDouble *DataArrayDouble::inverse() const throw(INTERP_KERNEL::Exception)
3303 {
3304   checkAllocated();
3305   int nbOfComp=getNumberOfComponents();
3306   if(nbOfComp!=6 && nbOfComp!=9 && nbOfComp!=4)
3307     throw INTERP_KERNEL::Exception("DataArrayDouble::inversion : must be an array with 4,6 or 9 components !");
3308   DataArrayDouble *ret=DataArrayDouble::New();
3309   int nbOfTuple=getNumberOfTuples();
3310   ret->alloc(nbOfTuple,nbOfComp);
3311   const double *src=getConstPointer();
3312   double *dest=ret->getPointer();
3313 if(nbOfComp==6)
3314     for(int i=0;i<nbOfTuple;i++,dest+=6,src+=6)
3315       {
3316         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];
3317         dest[0]=(src[1]*src[2]-src[4]*src[4])/det;
3318         dest[1]=(src[0]*src[2]-src[5]*src[5])/det;
3319         dest[2]=(src[0]*src[1]-src[3]*src[3])/det;
3320         dest[3]=(src[5]*src[4]-src[3]*src[2])/det;
3321         dest[4]=(src[5]*src[3]-src[0]*src[4])/det;
3322         dest[5]=(src[3]*src[4]-src[1]*src[5])/det;
3323       }
3324   else if(nbOfComp==4)
3325     for(int i=0;i<nbOfTuple;i++,dest+=4,src+=4)
3326       {
3327         double det=src[0]*src[3]-src[1]*src[2];
3328         dest[0]=src[3]/det;
3329         dest[1]=-src[1]/det;
3330         dest[2]=-src[2]/det;
3331         dest[3]=src[0]/det;
3332       }
3333   else
3334     for(int i=0;i<nbOfTuple;i++,dest+=9,src+=9)
3335       {
3336         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];
3337         dest[0]=(src[4]*src[8]-src[7]*src[5])/det;
3338         dest[1]=(src[7]*src[2]-src[1]*src[8])/det;
3339         dest[2]=(src[1]*src[5]-src[4]*src[2])/det;
3340         dest[3]=(src[6]*src[5]-src[3]*src[8])/det;
3341         dest[4]=(src[0]*src[8]-src[6]*src[2])/det;
3342         dest[5]=(src[2]*src[3]-src[0]*src[5])/det;
3343         dest[6]=(src[3]*src[7]-src[6]*src[4])/det;
3344         dest[7]=(src[6]*src[1]-src[0]*src[7])/det;
3345         dest[8]=(src[0]*src[4]-src[1]*src[3])/det;
3346       }
3347   return ret;
3348 }
3349
3350 /*!
3351  * Computes the trace of every matrix defined by the tuple of \a this
3352  * array, which contains either 4, 6 or 9 components. The case of 6 components
3353  * corresponds to that of the upper triangular matrix.
3354  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing 
3355  *          1 component, whose each tuple is the trace of
3356  *          the matrix of corresponding tuple of \a this array. 
3357  *          The caller is to delete this result array using decrRef() as it is no more
3358  *          needed. 
3359  *  \throw If \a this->getNumberOfComponents() is not in [4,6,9].
3360  */
3361 DataArrayDouble *DataArrayDouble::trace() const throw(INTERP_KERNEL::Exception)
3362 {
3363   checkAllocated();
3364   int nbOfComp=getNumberOfComponents();
3365   if(nbOfComp!=6 && nbOfComp!=9 && nbOfComp!=4)
3366     throw INTERP_KERNEL::Exception("DataArrayDouble::trace : must be an array with 4,6 or 9 components !");
3367   DataArrayDouble *ret=DataArrayDouble::New();
3368   int nbOfTuple=getNumberOfTuples();
3369   ret->alloc(nbOfTuple,1);
3370   const double *src=getConstPointer();
3371   double *dest=ret->getPointer();
3372   if(nbOfComp==6)
3373     for(int i=0;i<nbOfTuple;i++,dest++,src+=6)
3374       *dest=src[0]+src[1]+src[2];
3375   else if(nbOfComp==4)
3376     for(int i=0;i<nbOfTuple;i++,dest++,src+=4)
3377       *dest=src[0]+src[3];
3378   else
3379     for(int i=0;i<nbOfTuple;i++,dest++,src+=9)
3380       *dest=src[0]+src[4]+src[8];
3381   return ret;
3382 }
3383
3384 /*!
3385  * Computes the stress deviator tensor of every stress tensor defined by the tuple of
3386  * \a this array, which contains 6 components.
3387  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
3388  *          same number of components and tuples as \a this array.
3389  *          The caller is to delete this result array using decrRef() as it is no more
3390  *          needed.
3391  *  \throw If \a this->getNumberOfComponents() != 6.
3392  */
3393 DataArrayDouble *DataArrayDouble::deviator() const throw(INTERP_KERNEL::Exception)
3394 {
3395   checkAllocated();
3396   int nbOfComp=getNumberOfComponents();
3397   if(nbOfComp!=6)
3398     throw INTERP_KERNEL::Exception("DataArrayDouble::deviator : must be an array with exactly 6 components !");
3399   DataArrayDouble *ret=DataArrayDouble::New();
3400   int nbOfTuple=getNumberOfTuples();
3401   ret->alloc(nbOfTuple,6);
3402   const double *src=getConstPointer();
3403   double *dest=ret->getPointer();
3404   for(int i=0;i<nbOfTuple;i++,dest+=6,src+=6)
3405     {
3406       double tr=(src[0]+src[1]+src[2])/3.;
3407       dest[0]=src[0]-tr;
3408       dest[1]=src[1]-tr;
3409       dest[2]=src[2]-tr;
3410       dest[3]=src[3];
3411       dest[4]=src[4];
3412       dest[5]=src[5];
3413     }
3414   return ret;
3415 }
3416
3417 /*!
3418  * Computes the magnitude of every vector defined by the tuple of
3419  * \a this array.
3420  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
3421  *          same number of tuples as \a this array and one component.
3422  *          The caller is to delete this result array using decrRef() as it is no more
3423  *          needed.
3424  *  \throw If \a this is not allocated.
3425  */
3426 DataArrayDouble *DataArrayDouble::magnitude() const throw(INTERP_KERNEL::Exception)
3427 {
3428   checkAllocated();
3429   int nbOfComp=getNumberOfComponents();
3430   DataArrayDouble *ret=DataArrayDouble::New();
3431   int nbOfTuple=getNumberOfTuples();
3432   ret->alloc(nbOfTuple,1);
3433   const double *src=getConstPointer();
3434   double *dest=ret->getPointer();
3435   for(int i=0;i<nbOfTuple;i++,dest++)
3436     {
3437       double sum=0.;
3438       for(int j=0;j<nbOfComp;j++,src++)
3439         sum+=(*src)*(*src);
3440       *dest=sqrt(sum);
3441     }
3442   return ret;
3443 }
3444
3445 /*!
3446  * Computes the maximal value within every tuple of \a this array.
3447  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
3448  *          same number of tuples as \a this array and one component.
3449  *          The caller is to delete this result array using decrRef() as it is no more
3450  *          needed.
3451  *  \throw If \a this is not allocated.
3452  */
3453 DataArrayDouble *DataArrayDouble::maxPerTuple() const throw(INTERP_KERNEL::Exception)
3454 {
3455   checkAllocated();
3456   int nbOfComp=getNumberOfComponents();
3457   DataArrayDouble *ret=DataArrayDouble::New();
3458   int nbOfTuple=getNumberOfTuples();
3459   ret->alloc(nbOfTuple,1);
3460   const double *src=getConstPointer();
3461   double *dest=ret->getPointer();
3462   for(int i=0;i<nbOfTuple;i++,dest++,src+=nbOfComp)
3463     *dest=*std::max_element(src,src+nbOfComp);
3464   return ret;
3465 }
3466
3467 /*!
3468  * This method returns a newly allocated DataArrayDouble instance having one component and \c this->getNumberOfTuples() * \c this->getNumberOfTuples() tuples.
3469  * \n This returned array contains the euclidian distance for each tuple in \a this. 
3470  * \n So the returned array can be seen as a dense symmetrical matrix whose diagonal elements are equal to 0.
3471  * \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)
3472  *
3473  * \warning use this method with care because it can leads to big amount of consumed memory !
3474  * 
3475  * \return A newly allocated (huge) ParaMEDMEM::DataArrayDouble instance that the caller should deal with.
3476  *
3477  * \throw If \a this is not allocated.
3478  *
3479  * \sa DataArrayDouble::buildEuclidianDistanceDenseMatrixWith
3480  */
3481 DataArrayDouble *DataArrayDouble::buildEuclidianDistanceDenseMatrix() const throw(INTERP_KERNEL::Exception)
3482 {
3483   checkAllocated();
3484   int nbOfComp=getNumberOfComponents();
3485   int nbOfTuples=getNumberOfTuples();
3486   const double *inData=getConstPointer();
3487   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
3488   ret->alloc(nbOfTuples*nbOfTuples,1);
3489   double *outData=ret->getPointer();
3490   for(int i=0;i<nbOfTuples;i++)
3491     {
3492       outData[i*nbOfTuples+i]=0.;
3493       for(int j=i+1;j<nbOfTuples;j++)
3494         {
3495           double dist=0.;
3496           for(int k=0;k<nbOfComp;k++)
3497             { double delta=inData[i*nbOfComp+k]-inData[j*nbOfComp+k]; dist+=delta*delta; }
3498           dist=sqrt(dist);
3499           outData[i*nbOfTuples+j]=dist;
3500           outData[j*nbOfTuples+i]=dist;
3501         }
3502     }
3503   return ret.retn();
3504 }
3505
3506 /*!
3507  * This method returns a newly allocated DataArrayDouble instance having one component and \c this->getNumberOfTuples() * \c other->getNumberOfTuples() tuples.
3508  * \n This returned array contains the euclidian distance for each tuple in \a other with each tuple in \a this. 
3509  * \n So the returned array can be seen as a dense rectangular matrix with \c other->getNumberOfTuples() rows and \c this->getNumberOfTuples() columns.
3510  * \n Output rectangular matrix is sorted along rows.
3511  * \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)
3512  *
3513  * \warning use this method with care because it can leads to big amount of consumed memory !
3514  * 
3515  * \param [in] other DataArrayDouble instance having same number of components than \a this.
3516  * \return A newly allocated (huge) ParaMEDMEM::DataArrayDouble instance that the caller should deal with.
3517  *
3518  * \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.
3519  *
3520  * \sa DataArrayDouble::buildEuclidianDistanceDenseMatrix
3521  */
3522 DataArrayDouble *DataArrayDouble::buildEuclidianDistanceDenseMatrixWith(const DataArrayDouble *other) const throw(INTERP_KERNEL::Exception)
3523 {
3524   if(!other)
3525     throw INTERP_KERNEL::Exception("DataArrayDouble::buildEuclidianDistanceDenseMatrixWith : input parameter is null !");
3526   checkAllocated();
3527   other->checkAllocated();
3528   int nbOfComp=getNumberOfComponents();
3529   int otherNbOfComp=other->getNumberOfComponents();
3530   if(nbOfComp!=otherNbOfComp)
3531     {
3532       std::ostringstream oss; oss << "DataArrayDouble::buildEuclidianDistanceDenseMatrixWith : this nb of compo=" << nbOfComp << " and other nb of compo=" << otherNbOfComp << ". It should match !";
3533       throw INTERP_KERNEL::Exception(oss.str().c_str());
3534     }
3535   int nbOfTuples=getNumberOfTuples();
3536   int otherNbOfTuples=other->getNumberOfTuples();
3537   const double *inData=getConstPointer();
3538   const double *inDataOther=other->getConstPointer();
3539   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
3540   ret->alloc(otherNbOfTuples*nbOfTuples,1);
3541   double *outData=ret->getPointer();
3542   for(int i=0;i<otherNbOfTuples;i++,inDataOther+=nbOfComp)
3543     {
3544       for(int j=0;j<nbOfTuples;j++)
3545         {
3546           double dist=0.;
3547           for(int k=0;k<nbOfComp;k++)
3548             { double delta=inDataOther[k]-inData[j*nbOfComp+k]; dist+=delta*delta; }
3549           dist=sqrt(dist);
3550           outData[i*nbOfTuples+j]=dist;
3551         }
3552     }
3553   return ret.retn();
3554 }
3555
3556 /*!
3557  * Sorts value within every tuple of \a this array.
3558  *  \param [in] asc - if \a true, the values are sorted in ascending order, else,
3559  *              in descending order.
3560  *  \throw If \a this is not allocated.
3561  */
3562 void DataArrayDouble::sortPerTuple(bool asc) throw(INTERP_KERNEL::Exception)
3563 {
3564   checkAllocated();
3565   double *pt=getPointer();
3566   int nbOfTuple=getNumberOfTuples();
3567   int nbOfComp=getNumberOfComponents();
3568   if(asc)
3569     for(int i=0;i<nbOfTuple;i++,pt+=nbOfComp)
3570       std::sort(pt,pt+nbOfComp);
3571   else
3572     for(int i=0;i<nbOfTuple;i++,pt+=nbOfComp)
3573       std::sort(pt,pt+nbOfComp,std::greater<double>());
3574   declareAsNew();
3575 }
3576
3577 /*!
3578  * Converts every value of \a this array to its absolute value.
3579  *  \throw If \a this is not allocated.
3580  */
3581 void DataArrayDouble::abs() throw(INTERP_KERNEL::Exception)
3582 {
3583   checkAllocated();
3584   double *ptr=getPointer();
3585   std::size_t nbOfElems=getNbOfElems();
3586   std::transform(ptr,ptr+nbOfElems,ptr,std::ptr_fun<double,double>(fabs));
3587   declareAsNew();
3588 }
3589
3590 /*!
3591  * Apply a liner function to a given component of \a this array, so that
3592  * an array element <em>(x)</em> becomes \f$ a * x + b \f$.
3593  *  \param [in] a - the first coefficient of the function.
3594  *  \param [in] b - the second coefficient of the function.
3595  *  \param [in] compoId - the index of component to modify.
3596  *  \throw If \a this is not allocated.
3597  */
3598 void DataArrayDouble::applyLin(double a, double b, int compoId) throw(INTERP_KERNEL::Exception)
3599 {
3600   checkAllocated();
3601   double *ptr=getPointer()+compoId;
3602   int nbOfComp=getNumberOfComponents();
3603   int nbOfTuple=getNumberOfTuples();
3604   for(int i=0;i<nbOfTuple;i++,ptr+=nbOfComp)
3605     *ptr=a*(*ptr)+b;
3606   declareAsNew();
3607 }
3608
3609 /*!
3610  * Apply a liner function to all elements of \a this array, so that
3611  * an element _x_ becomes \f$ a * x + b \f$.
3612  *  \param [in] a - the first coefficient of the function.
3613  *  \param [in] b - the second coefficient of the function.
3614  *  \throw If \a this is not allocated.
3615  */
3616 void DataArrayDouble::applyLin(double a, double b) throw(INTERP_KERNEL::Exception)
3617 {
3618   checkAllocated();
3619   double *ptr=getPointer();
3620   std::size_t nbOfElems=getNbOfElems();
3621   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
3622     *ptr=a*(*ptr)+b;
3623   declareAsNew();
3624 }
3625
3626 /*!
3627  * Modify all elements of \a this array, so that
3628  * an element _x_ becomes \f$ numerator / x \f$.
3629  *  \warning If an exception is thrown because of presence of 0.0 element in \a this 
3630  *           array, all elements processed before detection of the zero element remain
3631  *           modified.
3632  *  \param [in] numerator - the numerator used to modify array elements.
3633  *  \throw If \a this is not allocated.
3634  *  \throw If there is an element equal to 0.0 in \a this array.
3635  */
3636 void DataArrayDouble::applyInv(double numerator) throw(INTERP_KERNEL::Exception)
3637 {
3638   checkAllocated();
3639   double *ptr=getPointer();
3640   std::size_t nbOfElems=getNbOfElems();
3641   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
3642     {
3643       if(std::abs(*ptr)>std::numeric_limits<double>::min())
3644         {
3645           *ptr=numerator/(*ptr);
3646         }
3647       else
3648         {
3649           std::ostringstream oss; oss << "DataArrayDouble::applyInv : presence of null value in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
3650           oss << " !";
3651           throw INTERP_KERNEL::Exception(oss.str().c_str());
3652         }
3653     }
3654   declareAsNew();
3655 }
3656
3657 /*!
3658  * Returns a full copy of \a this array except that sign of all elements is reversed.
3659  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
3660  *          same number of tuples and component as \a this array.
3661  *          The caller is to delete this result array using decrRef() as it is no more
3662  *          needed.
3663  *  \throw If \a this is not allocated.
3664  */
3665 DataArrayDouble *DataArrayDouble::negate() const throw(INTERP_KERNEL::Exception)
3666 {
3667   checkAllocated();
3668   DataArrayDouble *newArr=DataArrayDouble::New();
3669   int nbOfTuples=getNumberOfTuples();
3670   int nbOfComp=getNumberOfComponents();
3671   newArr->alloc(nbOfTuples,nbOfComp);
3672   const double *cptr=getConstPointer();
3673   std::transform(cptr,cptr+nbOfTuples*nbOfComp,newArr->getPointer(),std::negate<double>());
3674   newArr->copyStringInfoFrom(*this);
3675   return newArr;
3676 }
3677
3678 /*!
3679  * Modify all elements of \a this array, so that
3680  * an element _x_ becomes <em> val ^ x </em>. Contrary to DataArrayInt::applyPow
3681  * all values in \a this have to be >= 0 if val is \b not integer.
3682  *  \param [in] val - the value used to apply pow on all array elements.
3683  *  \throw If \a this is not allocated.
3684  *  \warning If an exception is thrown because of presence of 0 element in \a this 
3685  *           array and \a val is \b not integer, all elements processed before detection of the zero element remain
3686  *           modified.
3687  */
3688 void DataArrayDouble::applyPow(double val) throw(INTERP_KERNEL::Exception)
3689 {
3690   checkAllocated();
3691   double *ptr=getPointer();
3692   std::size_t nbOfElems=getNbOfElems();
3693   int val2=(int)val;
3694   bool isInt=((double)val2)==val;
3695   if(!isInt)
3696     {
3697       for(std::size_t i=0;i<nbOfElems;i++,ptr++)
3698         {
3699           if(*ptr>=0)
3700             *ptr=pow(*ptr,val);
3701           else
3702             {
3703               std::ostringstream oss; oss << "DataArrayDouble::applyPow (double) : At elem # " << i << " value is " << *ptr << " ! must be >=0. !";
3704               throw INTERP_KERNEL::Exception(oss.str().c_str());
3705             }
3706         }
3707     }
3708   else
3709     {
3710       for(std::size_t i=0;i<nbOfElems;i++,ptr++)
3711         *ptr=pow(*ptr,val2);
3712     }
3713   declareAsNew();
3714 }
3715
3716 /*!
3717  * Modify all elements of \a this array, so that
3718  * an element _x_ becomes \f$ val ^ x \f$.
3719  *  \param [in] val - the value used to apply pow on all array elements.
3720  *  \throw If \a this is not allocated.
3721  *  \throw If \a val < 0.
3722  *  \warning If an exception is thrown because of presence of 0 element in \a this 
3723  *           array, all elements processed before detection of the zero element remain
3724  *           modified.
3725  */
3726 void DataArrayDouble::applyRPow(double val) throw(INTERP_KERNEL::Exception)
3727 {
3728   checkAllocated();
3729   if(val<0.)
3730     throw INTERP_KERNEL::Exception("DataArrayDouble::applyRPow : the input value has to be >= 0 !");
3731   double *ptr=getPointer();
3732   std::size_t nbOfElems=getNbOfElems();
3733   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
3734     *ptr=pow(val,*ptr);
3735   declareAsNew();
3736 }
3737
3738 /*!
3739  * Returns a new DataArrayDouble created from \a this one by applying \a
3740  * FunctionToEvaluate to every tuple of \a this array. Textual data is not copied.
3741  * For more info see \ref MEDCouplingArrayApplyFunc
3742  *  \param [in] nbOfComp - number of components in the result array.
3743  *  \param [in] func - the \a FunctionToEvaluate declared as 
3744  *              \c bool (*\a func)(\c const \c double *\a pos, \c double *\a res), 
3745  *              where \a pos points to the first component of a tuple of \a this array
3746  *              and \a res points to the first component of a tuple of the result array.
3747  *              Note that length (number of components) of \a pos can differ from
3748  *              that of \a res.
3749  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
3750  *          same number of tuples as \a this array.
3751  *          The caller is to delete this result array using decrRef() as it is no more
3752  *          needed.
3753  *  \throw If \a this is not allocated.
3754  *  \throw If \a func returns \a false.
3755  */
3756 DataArrayDouble *DataArrayDouble::applyFunc(int nbOfComp, FunctionToEvaluate func) const throw(INTERP_KERNEL::Exception)
3757 {
3758   checkAllocated();
3759   DataArrayDouble *newArr=DataArrayDouble::New();
3760   int nbOfTuples=getNumberOfTuples();
3761   int oldNbOfComp=getNumberOfComponents();
3762   newArr->alloc(nbOfTuples,nbOfComp);
3763   const double *ptr=getConstPointer();
3764   double *ptrToFill=newArr->getPointer();
3765   for(int i=0;i<nbOfTuples;i++)
3766     {
3767       if(!func(ptr+i*oldNbOfComp,ptrToFill+i*nbOfComp))
3768         {
3769           std::ostringstream oss; oss << "For tuple # " << i << " with value (";
3770           std::copy(ptr+oldNbOfComp*i,ptr+oldNbOfComp*(i+1),std::ostream_iterator<double>(oss,", "));
3771           oss << ") : Evaluation of function failed !";
3772           newArr->decrRef();
3773           throw INTERP_KERNEL::Exception(oss.str().c_str());
3774         }
3775     }
3776   return newArr;
3777 }
3778
3779 /*!
3780  * Returns a new DataArrayDouble created from \a this one by applying a function to every
3781  * tuple of \a this array. Textual data is not copied.
3782  * For more info see \ref MEDCouplingArrayApplyFunc1.
3783  *  \param [in] nbOfComp - number of components in the result array.
3784  *  \param [in] func - the expression defining how to transform a tuple of \a this array.
3785  *              Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
3786  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
3787  *          same number of tuples as \a this array and \a nbOfComp components.
3788  *          The caller is to delete this result array using decrRef() as it is no more
3789  *          needed.
3790  *  \throw If \a this is not allocated.
3791  *  \throw If computing \a func fails.
3792  */
3793 DataArrayDouble *DataArrayDouble::applyFunc(int nbOfComp, const char *func) const throw(INTERP_KERNEL::Exception)
3794 {
3795   checkAllocated();
3796   INTERP_KERNEL::ExprParser expr(func);
3797   expr.parse();
3798   std::set<std::string> vars;
3799   expr.getTrueSetOfVars(vars);
3800   int oldNbOfComp=getNumberOfComponents();
3801   if((int)vars.size()>oldNbOfComp)
3802     {
3803       std::ostringstream oss; oss << "The field has " << oldNbOfComp << " components and there are ";
3804       oss << vars.size() << " variables : ";
3805       std::copy(vars.begin(),vars.end(),std::ostream_iterator<std::string>(oss," "));
3806       throw INTERP_KERNEL::Exception(oss.str().c_str());
3807     }
3808   std::vector<std::string> varsV(vars.begin(),vars.end());
3809   expr.prepareExprEvaluation(varsV,oldNbOfComp,nbOfComp);
3810   //
3811   DataArrayDouble *newArr=DataArrayDouble::New();
3812   int nbOfTuples=getNumberOfTuples();
3813   newArr->alloc(nbOfTuples,nbOfComp);
3814   const double *ptr=getConstPointer();
3815   double *ptrToFill=newArr->getPointer();
3816   for(int i=0;i<nbOfTuples;i++)
3817     {
3818       try
3819         {
3820           expr.evaluateExpr(nbOfComp,ptr+i*oldNbOfComp,ptrToFill+i*nbOfComp);
3821         }
3822       catch(INTERP_KERNEL::Exception& e)
3823         {
3824           std::ostringstream oss; oss << "For tuple # " << i << " with value (";
3825           std::copy(ptr+oldNbOfComp*i,ptr+oldNbOfComp*(i+1),std::ostream_iterator<double>(oss,", "));
3826           oss << ") : Evaluation of function failed !" << e.what();
3827           newArr->decrRef();
3828           throw INTERP_KERNEL::Exception(oss.str().c_str());
3829         }
3830     }
3831   return newArr;
3832 }
3833
3834 /*!
3835  * Returns a new DataArrayDouble created from \a this one by applying a function to every
3836  * tuple of \a this array. Textual data is not copied.
3837  * For more info see \ref MEDCouplingArrayApplyFunc0.
3838  *  \param [in] func - the expression defining how to transform a tuple of \a this array.
3839  *              Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
3840  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
3841  *          same number of tuples and components as \a this array.
3842  *          The caller is to delete this result array using decrRef() as it is no more
3843  *          needed.
3844  *  \throw If \a this is not allocated.
3845  *  \throw If computing \a func fails.
3846  */
3847 DataArrayDouble *DataArrayDouble::applyFunc(const char *func) const throw(INTERP_KERNEL::Exception)
3848 {
3849   checkAllocated();
3850   INTERP_KERNEL::ExprParser expr(func);
3851   expr.parse();
3852   expr.prepareExprEvaluationVec();
3853   //
3854   DataArrayDouble *newArr=DataArrayDouble::New();
3855   int nbOfTuples=getNumberOfTuples();
3856   int nbOfComp=getNumberOfComponents();
3857   newArr->alloc(nbOfTuples,nbOfComp);
3858   const double *ptr=getConstPointer();
3859   double *ptrToFill=newArr->getPointer();
3860   for(int i=0;i<nbOfTuples;i++)
3861     {
3862       try
3863         {
3864           expr.evaluateExpr(nbOfComp,ptr+i*nbOfComp,ptrToFill+i*nbOfComp);
3865         }
3866       catch(INTERP_KERNEL::Exception& e)
3867         {
3868           std::ostringstream oss; oss << "For tuple # " << i << " with value (";
3869           std::copy(ptr+nbOfComp*i,ptr+nbOfComp*(i+1),std::ostream_iterator<double>(oss,", "));
3870           oss << ") : Evaluation of function failed ! " << e.what();
3871           newArr->decrRef();
3872           throw INTERP_KERNEL::Exception(oss.str().c_str());
3873         }
3874     }
3875   return newArr;
3876 }
3877
3878 /*!
3879  * Returns a new DataArrayDouble created from \a this one by applying a function to every
3880  * tuple of \a this array. Textual data is not copied.
3881  * For more info see \ref MEDCouplingArrayApplyFunc2.
3882  *  \param [in] nbOfComp - number of components in the result array.
3883  *  \param [in] func - the expression defining how to transform a tuple of \a this array.
3884  *              Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
3885  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
3886  *          same number of tuples as \a this array.
3887  *          The caller is to delete this result array using decrRef() as it is no more
3888  *          needed.
3889  *  \throw If \a this is not allocated.
3890  *  \throw If \a func contains vars that are not in \a this->getInfoOnComponent().
3891  *  \throw If computing \a func fails.
3892  */
3893 DataArrayDouble *DataArrayDouble::applyFunc2(int nbOfComp, const char *func) const throw(INTERP_KERNEL::Exception)
3894 {
3895   checkAllocated();
3896   INTERP_KERNEL::ExprParser expr(func);
3897   expr.parse();
3898   std::set<std::string> vars;
3899   expr.getTrueSetOfVars(vars);
3900   int oldNbOfComp=getNumberOfComponents();
3901   if((int)vars.size()>oldNbOfComp)
3902     {
3903       std::ostringstream oss; oss << "The field has " << oldNbOfComp << " components and there are ";
3904       oss << vars.size() << " variables : ";
3905       std::copy(vars.begin(),vars.end(),std::ostream_iterator<std::string>(oss," "));
3906       throw INTERP_KERNEL::Exception(oss.str().c_str());
3907     }
3908   expr.prepareExprEvaluation(getVarsOnComponent(),oldNbOfComp,nbOfComp);
3909   //
3910   DataArrayDouble *newArr=DataArrayDouble::New();
3911   int nbOfTuples=getNumberOfTuples();
3912   newArr->alloc(nbOfTuples,nbOfComp);
3913   const double *ptr=getConstPointer();
3914   double *ptrToFill=newArr->getPointer();
3915   for(int i=0;i<nbOfTuples;i++)
3916     {
3917       try
3918         {
3919           expr.evaluateExpr(nbOfComp,ptr+i*oldNbOfComp,ptrToFill+i*nbOfComp);
3920         }
3921       catch(INTERP_KERNEL::Exception& e)
3922         {
3923           std::ostringstream oss; oss << "For tuple # " << i << " with value (";
3924           std::copy(ptr+oldNbOfComp*i,ptr+oldNbOfComp*(i+1),std::ostream_iterator<double>(oss,", "));
3925           oss << ") : Evaluation of function failed !" << e.what();
3926           newArr->decrRef();
3927           throw INTERP_KERNEL::Exception(oss.str().c_str());
3928         }
3929     }
3930   return newArr;
3931 }
3932
3933 /*!
3934  * Returns a new DataArrayDouble created from \a this one by applying a function to every
3935  * tuple of \a this array. Textual data is not copied.
3936  * For more info see \ref MEDCouplingArrayApplyFunc3.
3937  *  \param [in] nbOfComp - number of components in the result array.
3938  *  \param [in] varsOrder - sequence of vars defining their order.
3939  *  \param [in] func - the expression defining how to transform a tuple of \a this array.
3940  *              Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
3941  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
3942  *          same number of tuples as \a this array.
3943  *          The caller is to delete this result array using decrRef() as it is no more
3944  *          needed.
3945  *  \throw If \a this is not allocated.
3946  *  \throw If \a func contains vars not in \a varsOrder.
3947  *  \throw If computing \a func fails.
3948  */
3949 DataArrayDouble *DataArrayDouble::applyFunc3(int nbOfComp, const std::vector<std::string>& varsOrder, const char *func) const throw(INTERP_KERNEL::Exception)
3950 {
3951   checkAllocated();
3952   INTERP_KERNEL::ExprParser expr(func);
3953   expr.parse();
3954   std::set<std::string> vars;
3955   expr.getTrueSetOfVars(vars);
3956   int oldNbOfComp=getNumberOfComponents();
3957   if((int)vars.size()>oldNbOfComp)
3958     {
3959       std::ostringstream oss; oss << "The field has " << oldNbOfComp << " components and there are ";
3960       oss << vars.size() << " variables : ";
3961       std::copy(vars.begin(),vars.end(),std::ostream_iterator<std::string>(oss," "));
3962       throw INTERP_KERNEL::Exception(oss.str().c_str());
3963     }
3964   expr.prepareExprEvaluation(varsOrder,oldNbOfComp,nbOfComp);
3965   //
3966   DataArrayDouble *newArr=DataArrayDouble::New();
3967   int nbOfTuples=getNumberOfTuples();
3968   newArr->alloc(nbOfTuples,nbOfComp);
3969   const double *ptr=getConstPointer();
3970   double *ptrToFill=newArr->getPointer();
3971   for(int i=0;i<nbOfTuples;i++)
3972     {
3973       try
3974         {
3975           expr.evaluateExpr(nbOfComp,ptr+i*oldNbOfComp,ptrToFill+i*nbOfComp);
3976         }
3977       catch(INTERP_KERNEL::Exception& e)
3978         {
3979           std::ostringstream oss; oss << "For tuple # " << i << " with value (";
3980           std::copy(ptr+oldNbOfComp*i,ptr+oldNbOfComp*(i+1),std::ostream_iterator<double>(oss,", "));
3981           oss << ") : Evaluation of function failed !" << e.what();
3982           newArr->decrRef();
3983           throw INTERP_KERNEL::Exception(oss.str().c_str());
3984         }
3985     }
3986   return newArr;
3987 }
3988
3989 void DataArrayDouble::applyFuncFast32(const char *func) throw(INTERP_KERNEL::Exception)
3990 {
3991   checkAllocated();
3992   INTERP_KERNEL::ExprParser expr(func);
3993   expr.parse();
3994   char *funcStr=expr.compileX86();
3995   MYFUNCPTR funcPtr;
3996   *((void **)&funcPtr)=funcStr;//he he...
3997   //
3998   double *ptr=getPointer();
3999   int nbOfComp=getNumberOfComponents();
4000   int nbOfTuples=getNumberOfTuples();
4001   int nbOfElems=nbOfTuples*nbOfComp;
4002   for(int i=0;i<nbOfElems;i++,ptr++)
4003     *ptr=funcPtr(*ptr);
4004   declareAsNew();
4005 }
4006
4007 void DataArrayDouble::applyFuncFast64(const char *func) throw(INTERP_KERNEL::Exception)
4008 {
4009   checkAllocated();
4010   INTERP_KERNEL::ExprParser expr(func);
4011   expr.parse();
4012   char *funcStr=expr.compileX86_64();
4013   MYFUNCPTR funcPtr;
4014   *((void **)&funcPtr)=funcStr;//he he...
4015   //
4016   double *ptr=getPointer();
4017   int nbOfComp=getNumberOfComponents();
4018   int nbOfTuples=getNumberOfTuples();
4019   int nbOfElems=nbOfTuples*nbOfComp;
4020   for(int i=0;i<nbOfElems;i++,ptr++)
4021     *ptr=funcPtr(*ptr);
4022   declareAsNew();
4023 }
4024
4025 DataArrayDoubleIterator *DataArrayDouble::iterator() throw(INTERP_KERNEL::Exception)
4026 {
4027   return new DataArrayDoubleIterator(this);
4028 }
4029
4030 /*!
4031  * Returns a new DataArrayInt contating indices of tuples of \a this one-dimensional
4032  * array whose values are within a given range. Textual data is not copied.
4033  *  \param [in] vmin - a lowest acceptable value.
4034  *  \param [in] vmax - a greatest acceptable value.
4035  *  \return DataArrayInt * - the new instance of DataArrayInt.
4036  *          The caller is to delete this result array using decrRef() as it is no more
4037  *          needed.
4038  *  \throw If \a this->getNumberOfComponents() != 1.
4039  *
4040  *  \ref cpp_mcdataarraydouble_getidsinrange "Here is a C++ example".<br>
4041  *  \ref py_mcdataarraydouble_getidsinrange "Here is a Python example".
4042  */
4043 DataArrayInt *DataArrayDouble::getIdsInRange(double vmin, double vmax) const throw(INTERP_KERNEL::Exception)
4044 {
4045   checkAllocated();
4046   if(getNumberOfComponents()!=1)
4047     throw INTERP_KERNEL::Exception("DataArrayDouble::getIdsInRange : this must have exactly one component !");
4048   const double *cptr=getConstPointer();
4049   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(0,1);
4050   int nbOfTuples=getNumberOfTuples();
4051   for(int i=0;i<nbOfTuples;i++,cptr++)
4052     if(*cptr>=vmin && *cptr<=vmax)
4053       ret->pushBackSilent(i);
4054   return ret.retn();
4055 }
4056
4057 /*!
4058  * Returns a new DataArrayDouble by concatenating two given arrays, so that (1) the number
4059  * of tuples in the result array is a sum of the number of tuples of given arrays and (2)
4060  * the number of component in the result array is same as that of each of given arrays.
4061  * Info on components is copied from the first of the given arrays. Number of components
4062  * in the given arrays must be  the same.
4063  *  \param [in] a1 - an array to include in the result array.
4064  *  \param [in] a2 - another array to include in the result array.
4065  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4066  *          The caller is to delete this result array using decrRef() as it is no more
4067  *          needed.
4068  *  \throw If both \a a1 and \a a2 are NULL.
4069  *  \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents().
4070  */
4071 DataArrayDouble *DataArrayDouble::Aggregate(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception)
4072 {
4073   std::vector<const DataArrayDouble *> tmp(2);
4074   tmp[0]=a1; tmp[1]=a2;
4075   return Aggregate(tmp);
4076 }
4077
4078 /*!
4079  * Returns a new DataArrayDouble by concatenating all given arrays, so that (1) the number
4080  * of tuples in the result array is a sum of the number of tuples of given arrays and (2)
4081  * the number of component in the result array is same as that of each of given arrays.
4082  * Info on components is copied from the first of the given arrays. Number of components
4083  * in the given arrays must be  the same.
4084  *  \param [in] arr - a sequence of arrays to include in the result array.
4085  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4086  *          The caller is to delete this result array using decrRef() as it is no more
4087  *          needed.
4088  *  \throw If all arrays within \a arr are NULL.
4089  *  \throw If getNumberOfComponents() of arrays within \a arr.
4090  */
4091 DataArrayDouble *DataArrayDouble::Aggregate(const std::vector<const DataArrayDouble *>& arr) throw(INTERP_KERNEL::Exception)
4092 {
4093   std::vector<const DataArrayDouble *> a;
4094   for(std::vector<const DataArrayDouble *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
4095     if(*it4)
4096       a.push_back(*it4);
4097   if(a.empty())
4098     throw INTERP_KERNEL::Exception("DataArrayDouble::Aggregate : input list must contain at least one NON EMPTY DataArrayDouble !");
4099   std::vector<const DataArrayDouble *>::const_iterator it=a.begin();
4100   int nbOfComp=(*it)->getNumberOfComponents();
4101   int nbt=(*it++)->getNumberOfTuples();
4102   for(int i=1;it!=a.end();it++,i++)
4103     {
4104       if((*it)->getNumberOfComponents()!=nbOfComp)
4105         throw INTERP_KERNEL::Exception("DataArrayDouble::Aggregate : Nb of components mismatch for array aggregation !");
4106       nbt+=(*it)->getNumberOfTuples();
4107     }
4108   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
4109   ret->alloc(nbt,nbOfComp);
4110   double *pt=ret->getPointer();
4111   for(it=a.begin();it!=a.end();it++)
4112     pt=std::copy((*it)->getConstPointer(),(*it)->getConstPointer()+(*it)->getNbOfElems(),pt);
4113   ret->copyStringInfoFrom(*(a[0]));
4114   return ret.retn();
4115 }
4116
4117 /*!
4118  * Returns a new DataArrayDouble by aggregating two given arrays, so that (1) the number
4119  * of components in the result array is a sum of the number of components of given arrays
4120  * and (2) the number of tuples in the result array is same as that of each of given
4121  * arrays. In other words the i-th tuple of result array includes all components of
4122  * i-th tuples of all given arrays.
4123  * Number of tuples in the given arrays must be  the same.
4124  *  \param [in] a1 - an array to include in the result array.
4125  *  \param [in] a2 - another array to include in the result array.
4126  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4127  *          The caller is to delete this result array using decrRef() as it is no more
4128  *          needed.
4129  *  \throw If both \a a1 and \a a2 are NULL.
4130  *  \throw If any given array is not allocated.
4131  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
4132  */
4133 DataArrayDouble *DataArrayDouble::Meld(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception)
4134 {
4135   std::vector<const DataArrayDouble *> arr(2);
4136   arr[0]=a1; arr[1]=a2;
4137   return Meld(arr);
4138 }
4139
4140 /*!
4141  * Returns a new DataArrayDouble by aggregating all given arrays, so that (1) the number
4142  * of components in the result array is a sum of the number of components of given arrays
4143  * and (2) the number of tuples in the result array is same as that of each of given
4144  * arrays. In other words the i-th tuple of result array includes all components of
4145  * i-th tuples of all given arrays.
4146  * Number of tuples in the given arrays must be  the same.
4147  *  \param [in] arr - a sequence of arrays to include in the result array.
4148  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4149  *          The caller is to delete this result array using decrRef() as it is no more
4150  *          needed.
4151  *  \throw If all arrays within \a arr are NULL.
4152  *  \throw If any given array is not allocated.
4153  *  \throw If getNumberOfTuples() of arrays within \a arr is different.
4154  */
4155 DataArrayDouble *DataArrayDouble::Meld(const std::vector<const DataArrayDouble *>& arr) throw(INTERP_KERNEL::Exception)
4156 {
4157   std::vector<const DataArrayDouble *> a;
4158   for(std::vector<const DataArrayDouble *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
4159     if(*it4)
4160       a.push_back(*it4);
4161   if(a.empty())
4162     throw INTERP_KERNEL::Exception("DataArrayDouble::Meld : input list must contain at least one NON EMPTY DataArrayDouble !");
4163   std::vector<const DataArrayDouble *>::const_iterator it;
4164   for(it=a.begin();it!=a.end();it++)
4165     (*it)->checkAllocated();
4166   it=a.begin();
4167   int nbOfTuples=(*it)->getNumberOfTuples();
4168   std::vector<int> nbc(a.size());
4169   std::vector<const double *> pts(a.size());
4170   nbc[0]=(*it)->getNumberOfComponents();
4171   pts[0]=(*it++)->getConstPointer();
4172   for(int i=1;it!=a.end();it++,i++)
4173     {
4174       if(nbOfTuples!=(*it)->getNumberOfTuples())
4175         throw INTERP_KERNEL::Exception("DataArrayDouble::Meld : mismatch of number of tuples !");
4176       nbc[i]=(*it)->getNumberOfComponents();
4177       pts[i]=(*it)->getConstPointer();
4178     }
4179   int totalNbOfComp=std::accumulate(nbc.begin(),nbc.end(),0);
4180   DataArrayDouble *ret=DataArrayDouble::New();
4181   ret->alloc(nbOfTuples,totalNbOfComp);
4182   double *retPtr=ret->getPointer();
4183   for(int i=0;i<nbOfTuples;i++)
4184     for(int j=0;j<(int)a.size();j++)
4185       {
4186         retPtr=std::copy(pts[j],pts[j]+nbc[j],retPtr);
4187         pts[j]+=nbc[j];
4188       }
4189   int k=0;
4190   for(int i=0;i<(int)a.size();i++)
4191     for(int j=0;j<nbc[i];j++,k++)
4192       ret->setInfoOnComponent(k,a[i]->getInfoOnComponent(j).c_str());
4193   return ret;
4194 }
4195
4196 /*!
4197  * Returns a new DataArrayDouble containing a dot product of two given arrays, so that
4198  * the i-th tuple of the result array is a sum of products of j-th components of i-th
4199  * tuples of given arrays (\f$ a_i = \sum_{j=1}^n a1_j * a2_j \f$).
4200  * Info on components and name is copied from the first of the given arrays.
4201  * Number of tuples and components in the given arrays must be the same.
4202  *  \param [in] a1 - a given array.
4203  *  \param [in] a2 - another given array.
4204  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4205  *          The caller is to delete this result array using decrRef() as it is no more
4206  *          needed.
4207  *  \throw If either \a a1 or \a a2 is NULL.
4208  *  \throw If any given array is not allocated.
4209  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
4210  *  \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents()
4211  */
4212 DataArrayDouble *DataArrayDouble::Dot(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception)
4213 {
4214   if(!a1 || !a2)
4215     throw INTERP_KERNEL::Exception("DataArrayDouble::Dot : input DataArrayDouble instance is NULL !");
4216   a1->checkAllocated();
4217   a2->checkAllocated();
4218   int nbOfComp=a1->getNumberOfComponents();
4219   if(nbOfComp!=a2->getNumberOfComponents())
4220     throw INTERP_KERNEL::Exception("Nb of components mismatch for array Dot !");
4221   int nbOfTuple=a1->getNumberOfTuples();
4222   if(nbOfTuple!=a2->getNumberOfTuples())
4223     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Dot !");
4224   DataArrayDouble *ret=DataArrayDouble::New();
4225   ret->alloc(nbOfTuple,1);
4226   double *retPtr=ret->getPointer();
4227   const double *a1Ptr=a1->getConstPointer();
4228   const double *a2Ptr=a2->getConstPointer();
4229   for(int i=0;i<nbOfTuple;i++)
4230     {
4231       double sum=0.;
4232       for(int j=0;j<nbOfComp;j++)
4233         sum+=a1Ptr[i*nbOfComp+j]*a2Ptr[i*nbOfComp+j];
4234       retPtr[i]=sum;
4235     }
4236   ret->setInfoOnComponent(0,a1->getInfoOnComponent(0).c_str());
4237   ret->setName(a1->getName().c_str());
4238   return ret;
4239 }
4240
4241 /*!
4242  * Returns a new DataArrayDouble containing a cross product of two given arrays, so that
4243  * the i-th tuple of the result array contains 3 components of a vector which is a cross
4244  * product of two vectors defined by the i-th tuples of given arrays.
4245  * Info on components is copied from the first of the given arrays.
4246  * Number of tuples in the given arrays must be the same.
4247  * Number of components in the given arrays must be 3.
4248  *  \param [in] a1 - a given array.
4249  *  \param [in] a2 - another given array.
4250  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4251  *          The caller is to delete this result array using decrRef() as it is no more
4252  *          needed.
4253  *  \throw If either \a a1 or \a a2 is NULL.
4254  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
4255  *  \throw If \a a1->getNumberOfComponents() != 3
4256  *  \throw If \a a2->getNumberOfComponents() != 3
4257  */
4258 DataArrayDouble *DataArrayDouble::CrossProduct(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception)
4259 {
4260   if(!a1 || !a2)
4261     throw INTERP_KERNEL::Exception("DataArrayDouble::CrossProduct : input DataArrayDouble instance is NULL !");
4262   int nbOfComp=a1->getNumberOfComponents();
4263   if(nbOfComp!=a2->getNumberOfComponents())
4264     throw INTERP_KERNEL::Exception("Nb of components mismatch for array crossProduct !");
4265   if(nbOfComp!=3)
4266     throw INTERP_KERNEL::Exception("Nb of components must be equal to 3 for array crossProduct !");
4267   int nbOfTuple=a1->getNumberOfTuples();
4268   if(nbOfTuple!=a2->getNumberOfTuples())
4269     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array crossProduct !");
4270   DataArrayDouble *ret=DataArrayDouble::New();
4271   ret->alloc(nbOfTuple,3);
4272   double *retPtr=ret->getPointer();
4273   const double *a1Ptr=a1->getConstPointer();
4274   const double *a2Ptr=a2->getConstPointer();
4275   for(int i=0;i<nbOfTuple;i++)
4276     {
4277       retPtr[3*i]=a1Ptr[3*i+1]*a2Ptr[3*i+2]-a1Ptr[3*i+2]*a2Ptr[3*i+1];
4278       retPtr[3*i+1]=a1Ptr[3*i+2]*a2Ptr[3*i]-a1Ptr[3*i]*a2Ptr[3*i+2];
4279       retPtr[3*i+2]=a1Ptr[3*i]*a2Ptr[3*i+1]-a1Ptr[3*i+1]*a2Ptr[3*i];
4280     }
4281   ret->copyStringInfoFrom(*a1);
4282   return ret;
4283 }
4284
4285 /*!
4286  * Returns a new DataArrayDouble containing maximal values of two given arrays.
4287  * Info on components is copied from the first of the given arrays.
4288  * Number of tuples and components in the given arrays must be the same.
4289  *  \param [in] a1 - an array to compare values with another one.
4290  *  \param [in] a2 - another array to compare values with the first one.
4291  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4292  *          The caller is to delete this result array using decrRef() as it is no more
4293  *          needed.
4294  *  \throw If either \a a1 or \a a2 is NULL.
4295  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
4296  *  \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents()
4297  */
4298 DataArrayDouble *DataArrayDouble::Max(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception)
4299 {
4300   if(!a1 || !a2)
4301     throw INTERP_KERNEL::Exception("DataArrayDouble::Max : input DataArrayDouble instance is NULL !");
4302   int nbOfComp=a1->getNumberOfComponents();
4303   if(nbOfComp!=a2->getNumberOfComponents())
4304     throw INTERP_KERNEL::Exception("Nb of components mismatch for array Max !");
4305   int nbOfTuple=a1->getNumberOfTuples();
4306   if(nbOfTuple!=a2->getNumberOfTuples())
4307     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Max !");
4308   DataArrayDouble *ret=DataArrayDouble::New();
4309   ret->alloc(nbOfTuple,nbOfComp);
4310   double *retPtr=ret->getPointer();
4311   const double *a1Ptr=a1->getConstPointer();
4312   const double *a2Ptr=a2->getConstPointer();
4313   int nbElem=nbOfTuple*nbOfComp;
4314   for(int i=0;i<nbElem;i++)
4315     retPtr[i]=std::max(a1Ptr[i],a2Ptr[i]);
4316   ret->copyStringInfoFrom(*a1);
4317   return ret;
4318 }
4319
4320 /*!
4321  * Returns a new DataArrayDouble containing minimal values of two given arrays.
4322  * Info on components is copied from the first of the given arrays.
4323  * Number of tuples and components in the given arrays must be the same.
4324  *  \param [in] a1 - an array to compare values with another one.
4325  *  \param [in] a2 - another array to compare values with the first one.
4326  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4327  *          The caller is to delete this result array using decrRef() as it is no more
4328  *          needed.
4329  *  \throw If either \a a1 or \a a2 is NULL.
4330  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
4331  *  \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents()
4332  */
4333 DataArrayDouble *DataArrayDouble::Min(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception)
4334 {
4335   if(!a1 || !a2)
4336     throw INTERP_KERNEL::Exception("DataArrayDouble::Min : input DataArrayDouble instance is NULL !");
4337   int nbOfComp=a1->getNumberOfComponents();
4338   if(nbOfComp!=a2->getNumberOfComponents())
4339     throw INTERP_KERNEL::Exception("Nb of components mismatch for array min !");
4340   int nbOfTuple=a1->getNumberOfTuples();
4341   if(nbOfTuple!=a2->getNumberOfTuples())
4342     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array min !");
4343   DataArrayDouble *ret=DataArrayDouble::New();
4344   ret->alloc(nbOfTuple,nbOfComp);
4345   double *retPtr=ret->getPointer();
4346   const double *a1Ptr=a1->getConstPointer();
4347   const double *a2Ptr=a2->getConstPointer();
4348   int nbElem=nbOfTuple*nbOfComp;
4349   for(int i=0;i<nbElem;i++)
4350     retPtr[i]=std::min(a1Ptr[i],a2Ptr[i]);
4351   ret->copyStringInfoFrom(*a1);
4352   return ret;
4353 }
4354
4355 /*!
4356  * Returns a new DataArrayDouble that is a sum of two given arrays. There are 3
4357  * valid cases.
4358  * 1.  The arrays have same number of tuples and components. Then each value of
4359  *   the result array (_a_) is a sum of the corresponding values of \a a1 and \a a2,
4360  *   i.e.: _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ i, j ].
4361  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
4362  *   component. Then
4363  *   _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ i, 0 ].
4364  * 3.  The arrays have same number of components and one array, say _a2_, has one
4365  *   tuple. Then
4366  *   _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ 0, j ].
4367  *
4368  * Info on components is copied either from the first array (in the first case) or from
4369  * the array with maximal number of elements (getNbOfElems()).
4370  *  \param [in] a1 - an array to sum up.
4371  *  \param [in] a2 - another array to sum up.
4372  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4373  *          The caller is to delete this result array using decrRef() as it is no more
4374  *          needed.
4375  *  \throw If either \a a1 or \a a2 is NULL.
4376  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
4377  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
4378  *         none of them has number of tuples or components equal to 1.
4379  */
4380 DataArrayDouble *DataArrayDouble::Add(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception)
4381 {
4382   if(!a1 || !a2)
4383     throw INTERP_KERNEL::Exception("DataArrayDouble::Add : input DataArrayDouble instance is NULL !");
4384   int nbOfTuple=a1->getNumberOfTuples();
4385   int nbOfTuple2=a2->getNumberOfTuples();
4386   int nbOfComp=a1->getNumberOfComponents();
4387   int nbOfComp2=a2->getNumberOfComponents();
4388   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=0;
4389   if(nbOfTuple==nbOfTuple2)
4390     {
4391       if(nbOfComp==nbOfComp2)
4392         {
4393           ret=DataArrayDouble::New();
4394           ret->alloc(nbOfTuple,nbOfComp);
4395           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::plus<double>());
4396           ret->copyStringInfoFrom(*a1);
4397         }
4398       else
4399         {
4400           int nbOfCompMin,nbOfCompMax;
4401           const DataArrayDouble *aMin, *aMax;
4402           if(nbOfComp>nbOfComp2)
4403             {
4404               nbOfCompMin=nbOfComp2; nbOfCompMax=nbOfComp;
4405               aMin=a2; aMax=a1;
4406             }
4407           else
4408             {
4409               nbOfCompMin=nbOfComp; nbOfCompMax=nbOfComp2;
4410               aMin=a1; aMax=a2;
4411             }
4412           if(nbOfCompMin==1)
4413             {
4414               ret=DataArrayDouble::New();
4415               ret->alloc(nbOfTuple,nbOfCompMax);
4416               const double *aMinPtr=aMin->getConstPointer();
4417               const double *aMaxPtr=aMax->getConstPointer();
4418               double *res=ret->getPointer();
4419               for(int i=0;i<nbOfTuple;i++)
4420                 res=std::transform(aMaxPtr+i*nbOfCompMax,aMaxPtr+(i+1)*nbOfCompMax,res,std::bind2nd(std::plus<double>(),aMinPtr[i]));
4421               ret->copyStringInfoFrom(*aMax);
4422             }
4423           else
4424             throw INTERP_KERNEL::Exception("Nb of components mismatch for array Add !");
4425         }
4426     }
4427   else if((nbOfTuple==1 && nbOfTuple2>1) || (nbOfTuple>1 && nbOfTuple2==1))
4428     {
4429       if(nbOfComp==nbOfComp2)
4430         {
4431           int nbOfTupleMax=std::max(nbOfTuple,nbOfTuple2);
4432           const DataArrayDouble *aMin=nbOfTuple>nbOfTuple2?a2:a1;
4433           const DataArrayDouble *aMax=nbOfTuple>nbOfTuple2?a1:a2;
4434           const double *aMinPtr=aMin->getConstPointer(),*aMaxPtr=aMax->getConstPointer();
4435           ret=DataArrayDouble::New();
4436           ret->alloc(nbOfTupleMax,nbOfComp);
4437           double *res=ret->getPointer();
4438           for(int i=0;i<nbOfTupleMax;i++)
4439             res=std::transform(aMaxPtr+i*nbOfComp,aMaxPtr+(i+1)*nbOfComp,aMinPtr,res,std::plus<double>());
4440           ret->copyStringInfoFrom(*aMax);
4441         }
4442       else
4443         throw INTERP_KERNEL::Exception("Nb of components mismatch for array Add !");
4444     }
4445   else
4446     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Add !");
4447   return ret.retn();
4448 }
4449
4450 /*!
4451  * Adds values of another DataArrayDouble to values of \a this one. There are 3
4452  * valid cases.
4453  * 1.  The arrays have same number of tuples and components. Then each value of
4454  *   \a other array is added to the corresponding value of \a this array, i.e.:
4455  *   _a_ [ i, j ] += _other_ [ i, j ].
4456  * 2.  The arrays have same number of tuples and \a other array has one component. Then
4457  *   _a_ [ i, j ] += _other_ [ i, 0 ].
4458  * 3.  The arrays have same number of components and \a other array has one tuple. Then
4459  *   _a_ [ i, j ] += _a2_ [ 0, j ].
4460  *
4461  *  \param [in] other - an array to add to \a this one.
4462  *  \throw If \a other is NULL.
4463  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
4464  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
4465  *         \a other has number of both tuples and components not equal to 1.
4466  */
4467 void DataArrayDouble::addEqual(const DataArrayDouble *other) throw(INTERP_KERNEL::Exception)
4468 {
4469   if(!other)
4470     throw INTERP_KERNEL::Exception("DataArrayDouble::addEqual : input DataArrayDouble instance is NULL !");
4471   const char *msg="Nb of tuples mismatch for DataArrayDouble::addEqual  !";
4472   checkAllocated();
4473   other->checkAllocated();
4474   int nbOfTuple=getNumberOfTuples();
4475   int nbOfTuple2=other->getNumberOfTuples();
4476   int nbOfComp=getNumberOfComponents();
4477   int nbOfComp2=other->getNumberOfComponents();
4478   if(nbOfTuple==nbOfTuple2)
4479     {
4480       if(nbOfComp==nbOfComp2)
4481         {
4482           std::transform(begin(),end(),other->begin(),getPointer(),std::plus<double>());
4483         }
4484       else if(nbOfComp2==1)
4485         {
4486           double *ptr=getPointer();
4487           const double *ptrc=other->getConstPointer();
4488           for(int i=0;i<nbOfTuple;i++)
4489             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::plus<double>(),*ptrc++));
4490         }
4491       else
4492         throw INTERP_KERNEL::Exception(msg);
4493     }
4494   else if(nbOfTuple2==1)
4495     {
4496       if(nbOfComp2==nbOfComp)
4497         {
4498           double *ptr=getPointer();
4499           const double *ptrc=other->getConstPointer();
4500           for(int i=0;i<nbOfTuple;i++)
4501             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::plus<double>());
4502         }
4503       else
4504         throw INTERP_KERNEL::Exception(msg);
4505     }
4506   else
4507     throw INTERP_KERNEL::Exception(msg);
4508   declareAsNew();
4509 }
4510
4511 /*!
4512  * Returns a new DataArrayDouble that is a subtraction of two given arrays. There are 3
4513  * valid cases.
4514  * 1.  The arrays have same number of tuples and components. Then each value of
4515  *   the result array (_a_) is a subtraction of the corresponding values of \a a1 and
4516  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ i, j ].
4517  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
4518  *   component. Then
4519  *   _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ i, 0 ].
4520  * 3.  The arrays have same number of components and one array, say _a2_, has one
4521  *   tuple. Then
4522  *   _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ 0, j ].
4523  *
4524  * Info on components is copied either from the first array (in the first case) or from
4525  * the array with maximal number of elements (getNbOfElems()).
4526  *  \param [in] a1 - an array to subtract from.
4527  *  \param [in] a2 - an array to subtract.
4528  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4529  *          The caller is to delete this result array using decrRef() as it is no more
4530  *          needed.
4531  *  \throw If either \a a1 or \a a2 is NULL.
4532  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
4533  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
4534  *         none of them has number of tuples or components equal to 1.
4535  */
4536 DataArrayDouble *DataArrayDouble::Substract(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception)
4537 {
4538   if(!a1 || !a2)
4539     throw INTERP_KERNEL::Exception("DataArrayDouble::Substract : input DataArrayDouble instance is NULL !");
4540   int nbOfTuple1=a1->getNumberOfTuples();
4541   int nbOfTuple2=a2->getNumberOfTuples();
4542   int nbOfComp1=a1->getNumberOfComponents();
4543   int nbOfComp2=a2->getNumberOfComponents();
4544   if(nbOfTuple2==nbOfTuple1)
4545     {
4546       if(nbOfComp1==nbOfComp2)
4547         {
4548           MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
4549           ret->alloc(nbOfTuple2,nbOfComp1);
4550           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::minus<double>());
4551           ret->copyStringInfoFrom(*a1);
4552           return ret.retn();
4553         }
4554       else if(nbOfComp2==1)
4555         {
4556           MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
4557           ret->alloc(nbOfTuple1,nbOfComp1);
4558           const double *a2Ptr=a2->getConstPointer();
4559           const double *a1Ptr=a1->getConstPointer();
4560           double *res=ret->getPointer();
4561           for(int i=0;i<nbOfTuple1;i++)
4562             res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::minus<double>(),a2Ptr[i]));
4563           ret->copyStringInfoFrom(*a1);
4564           return ret.retn();
4565         }
4566       else
4567         {
4568           a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Substract !");
4569           return 0;
4570         }
4571     }
4572   else if(nbOfTuple2==1)
4573     {
4574       a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Substract !");
4575       MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
4576       ret->alloc(nbOfTuple1,nbOfComp1);
4577       const double *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
4578       double *pt=ret->getPointer();
4579       for(int i=0;i<nbOfTuple1;i++)
4580         pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::minus<double>());
4581       ret->copyStringInfoFrom(*a1);
4582       return ret.retn();
4583     }
4584   else
4585     {
4586       a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Substract !");//will always throw an exception
4587       return 0;
4588     }
4589 }
4590
4591 /*!
4592  * Subtract values of another DataArrayDouble from values of \a this one. There are 3
4593  * valid cases.
4594  * 1.  The arrays have same number of tuples and components. Then each value of
4595  *   \a other array is subtracted from the corresponding value of \a this array, i.e.:
4596  *   _a_ [ i, j ] -= _other_ [ i, j ].
4597  * 2.  The arrays have same number of tuples and \a other array has one component. Then
4598  *   _a_ [ i, j ] -= _other_ [ i, 0 ].
4599  * 3.  The arrays have same number of components and \a other array has one tuple. Then
4600  *   _a_ [ i, j ] -= _a2_ [ 0, j ].
4601  *
4602  *  \param [in] other - an array to subtract from \a this one.
4603  *  \throw If \a other is NULL.
4604  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
4605  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
4606  *         \a other has number of both tuples and components not equal to 1.
4607  */
4608 void DataArrayDouble::substractEqual(const DataArrayDouble *other) throw(INTERP_KERNEL::Exception)
4609 {
4610   if(!other)
4611     throw INTERP_KERNEL::Exception("DataArrayDouble::substractEqual : input DataArrayDouble instance is NULL !");
4612   const char *msg="Nb of tuples mismatch for DataArrayDouble::substractEqual  !";
4613   checkAllocated();
4614   other->checkAllocated();
4615   int nbOfTuple=getNumberOfTuples();
4616   int nbOfTuple2=other->getNumberOfTuples();
4617   int nbOfComp=getNumberOfComponents();
4618   int nbOfComp2=other->getNumberOfComponents();
4619   if(nbOfTuple==nbOfTuple2)
4620     {
4621       if(nbOfComp==nbOfComp2)
4622         {
4623           std::transform(begin(),end(),other->begin(),getPointer(),std::minus<double>());
4624         }
4625       else if(nbOfComp2==1)
4626         {
4627           double *ptr=getPointer();
4628           const double *ptrc=other->getConstPointer();
4629           for(int i=0;i<nbOfTuple;i++)
4630             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::minus<double>(),*ptrc++)); 
4631         }
4632       else
4633         throw INTERP_KERNEL::Exception(msg);
4634     }
4635   else if(nbOfTuple2==1)
4636     {
4637       if(nbOfComp2==nbOfComp)
4638         {
4639           double *ptr=getPointer();
4640           const double *ptrc=other->getConstPointer();
4641           for(int i=0;i<nbOfTuple;i++)
4642             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::minus<double>());
4643         }
4644       else
4645         throw INTERP_KERNEL::Exception(msg);
4646     }
4647   else
4648     throw INTERP_KERNEL::Exception(msg);
4649   declareAsNew();
4650 }
4651
4652 /*!
4653  * Returns a new DataArrayDouble that is a product of two given arrays. There are 3
4654  * valid cases.
4655  * 1.  The arrays have same number of tuples and components. Then each value of
4656  *   the result array (_a_) is a product of the corresponding values of \a a1 and
4657  *   \a a2, i.e. _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ i, j ].
4658  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
4659  *   component. Then
4660  *   _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ i, 0 ].
4661  * 3.  The arrays have same number of components and one array, say _a2_, has one
4662  *   tuple. Then
4663  *   _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ 0, j ].
4664  *
4665  * Info on components is copied either from the first array (in the first case) or from
4666  * the array with maximal number of elements (getNbOfElems()).
4667  *  \param [in] a1 - a factor array.
4668  *  \param [in] a2 - another factor array.
4669  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4670  *          The caller is to delete this result array using decrRef() as it is no more
4671  *          needed.
4672  *  \throw If either \a a1 or \a a2 is NULL.
4673  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
4674  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
4675  *         none of them has number of tuples or components equal to 1.
4676  */
4677 DataArrayDouble *DataArrayDouble::Multiply(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception)
4678 {
4679   if(!a1 || !a2)
4680     throw INTERP_KERNEL::Exception("DataArrayDouble::Multiply : input DataArrayDouble instance is NULL !");
4681   int nbOfTuple=a1->getNumberOfTuples();
4682   int nbOfTuple2=a2->getNumberOfTuples();
4683   int nbOfComp=a1->getNumberOfComponents();
4684   int nbOfComp2=a2->getNumberOfComponents();
4685   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=0;
4686   if(nbOfTuple==nbOfTuple2)
4687     {
4688       if(nbOfComp==nbOfComp2)
4689         {
4690           ret=DataArrayDouble::New();
4691           ret->alloc(nbOfTuple,nbOfComp);
4692           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::multiplies<double>());
4693           ret->copyStringInfoFrom(*a1);
4694         }
4695       else
4696         {
4697           int nbOfCompMin,nbOfCompMax;
4698           const DataArrayDouble *aMin, *aMax;
4699           if(nbOfComp>nbOfComp2)
4700             {
4701               nbOfCompMin=nbOfComp2; nbOfCompMax=nbOfComp;
4702               aMin=a2; aMax=a1;
4703             }
4704           else
4705             {
4706               nbOfCompMin=nbOfComp; nbOfCompMax=nbOfComp2;
4707               aMin=a1; aMax=a2;
4708             }
4709           if(nbOfCompMin==1)
4710             {
4711               ret=DataArrayDouble::New();
4712               ret->alloc(nbOfTuple,nbOfCompMax);
4713               const double *aMinPtr=aMin->getConstPointer();
4714               const double *aMaxPtr=aMax->getConstPointer();
4715               double *res=ret->getPointer();
4716               for(int i=0;i<nbOfTuple;i++)
4717                 res=std::transform(aMaxPtr+i*nbOfCompMax,aMaxPtr+(i+1)*nbOfCompMax,res,std::bind2nd(std::multiplies<double>(),aMinPtr[i]));
4718               ret->copyStringInfoFrom(*aMax);
4719             }
4720           else
4721             throw INTERP_KERNEL::Exception("Nb of components mismatch for array Multiply !");
4722         }
4723     }
4724   else if((nbOfTuple==1 && nbOfTuple2>1) || (nbOfTuple>1 && nbOfTuple2==1))
4725     {
4726       if(nbOfComp==nbOfComp2)
4727         {
4728           int nbOfTupleMax=std::max(nbOfTuple,nbOfTuple2);
4729           const DataArrayDouble *aMin=nbOfTuple>nbOfTuple2?a2:a1;
4730           const DataArrayDouble *aMax=nbOfTuple>nbOfTuple2?a1:a2;
4731           const double *aMinPtr=aMin->getConstPointer(),*aMaxPtr=aMax->getConstPointer();
4732           ret=DataArrayDouble::New();
4733           ret->alloc(nbOfTupleMax,nbOfComp);
4734           double *res=ret->getPointer();
4735           for(int i=0;i<nbOfTupleMax;i++)
4736             res=std::transform(aMaxPtr+i*nbOfComp,aMaxPtr+(i+1)*nbOfComp,aMinPtr,res,std::multiplies<double>());
4737           ret->copyStringInfoFrom(*aMax);
4738         }
4739       else
4740         throw INTERP_KERNEL::Exception("Nb of components mismatch for array Multiply !");
4741     }
4742   else
4743     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Multiply !");
4744   return ret.retn();
4745 }
4746
4747 /*!
4748  * Multiply values of another DataArrayDouble to values of \a this one. There are 3
4749  * valid cases.
4750  * 1.  The arrays have same number of tuples and components. Then each value of
4751  *   \a other array is multiplied to the corresponding value of \a this array, i.e.
4752  *   _this_ [ i, j ] *= _other_ [ i, j ].
4753  * 2.  The arrays have same number of tuples and \a other array has one component. Then
4754  *   _this_ [ i, j ] *= _other_ [ i, 0 ].
4755  * 3.  The arrays have same number of components and \a other array has one tuple. Then
4756  *   _this_ [ i, j ] *= _a2_ [ 0, j ].
4757  *
4758  *  \param [in] other - an array to multiply to \a this one.
4759  *  \throw If \a other is NULL.
4760  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
4761  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
4762  *         \a other has number of both tuples and components not equal to 1.
4763  */
4764 void DataArrayDouble::multiplyEqual(const DataArrayDouble *other) throw(INTERP_KERNEL::Exception)
4765 {
4766   if(!other)
4767     throw INTERP_KERNEL::Exception("DataArrayDouble::multiplyEqual : input DataArrayDouble instance is NULL !");
4768   const char *msg="Nb of tuples mismatch for DataArrayDouble::multiplyEqual !";
4769   checkAllocated();
4770   other->checkAllocated();
4771   int nbOfTuple=getNumberOfTuples();
4772   int nbOfTuple2=other->getNumberOfTuples();
4773   int nbOfComp=getNumberOfComponents();
4774   int nbOfComp2=other->getNumberOfComponents();
4775   if(nbOfTuple==nbOfTuple2)
4776     {
4777       if(nbOfComp==nbOfComp2)
4778         {
4779           std::transform(begin(),end(),other->begin(),getPointer(),std::multiplies<double>());
4780         }
4781       else if(nbOfComp2==1)
4782         {
4783           double *ptr=getPointer();
4784           const double *ptrc=other->getConstPointer();
4785           for(int i=0;i<nbOfTuple;i++)
4786             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::multiplies<double>(),*ptrc++));
4787         }
4788       else
4789         throw INTERP_KERNEL::Exception(msg);
4790     }
4791   else if(nbOfTuple2==1)
4792     {
4793       if(nbOfComp2==nbOfComp)
4794         {
4795           double *ptr=getPointer();
4796           const double *ptrc=other->getConstPointer();
4797           for(int i=0;i<nbOfTuple;i++)
4798             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::multiplies<double>());
4799         }
4800       else
4801         throw INTERP_KERNEL::Exception(msg);
4802     }
4803   else
4804     throw INTERP_KERNEL::Exception(msg);
4805   declareAsNew();
4806 }
4807
4808 /*!
4809  * Returns a new DataArrayDouble that is a division of two given arrays. There are 3
4810  * valid cases.
4811  * 1.  The arrays have same number of tuples and components. Then each value of
4812  *   the result array (_a_) is a division of the corresponding values of \a a1 and
4813  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ i, j ].
4814  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
4815  *   component. Then
4816  *   _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ i, 0 ].
4817  * 3.  The arrays have same number of components and one array, say _a2_, has one
4818  *   tuple. Then
4819  *   _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ 0, j ].
4820  *
4821  * Info on components is copied either from the first array (in the first case) or from
4822  * the array with maximal number of elements (getNbOfElems()).
4823  *  \warning No check of division by zero is performed!
4824  *  \param [in] a1 - a numerator array.
4825  *  \param [in] a2 - a denominator array.
4826  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4827  *          The caller is to delete this result array using decrRef() as it is no more
4828  *          needed.
4829  *  \throw If either \a a1 or \a a2 is NULL.
4830  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
4831  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
4832  *         none of them has number of tuples or components equal to 1.
4833  */
4834 DataArrayDouble *DataArrayDouble::Divide(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception)
4835 {
4836   if(!a1 || !a2)
4837     throw INTERP_KERNEL::Exception("DataArrayDouble::Divide : input DataArrayDouble instance is NULL !");
4838   int nbOfTuple1=a1->getNumberOfTuples();
4839   int nbOfTuple2=a2->getNumberOfTuples();
4840   int nbOfComp1=a1->getNumberOfComponents();
4841   int nbOfComp2=a2->getNumberOfComponents();
4842   if(nbOfTuple2==nbOfTuple1)
4843     {
4844       if(nbOfComp1==nbOfComp2)
4845         {
4846           MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
4847           ret->alloc(nbOfTuple2,nbOfComp1);
4848           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::divides<double>());
4849           ret->copyStringInfoFrom(*a1);
4850           return ret.retn();
4851         }
4852       else if(nbOfComp2==1)
4853         {
4854           MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
4855           ret->alloc(nbOfTuple1,nbOfComp1);
4856           const double *a2Ptr=a2->getConstPointer();
4857           const double *a1Ptr=a1->getConstPointer();
4858           double *res=ret->getPointer();
4859           for(int i=0;i<nbOfTuple1;i++)
4860             res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::divides<double>(),a2Ptr[i]));
4861           ret->copyStringInfoFrom(*a1);
4862           return ret.retn();
4863         }
4864       else
4865         {
4866           a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Divide !");
4867           return 0;
4868         }
4869     }
4870   else if(nbOfTuple2==1)
4871     {
4872       a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Divide !");
4873       MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
4874       ret->alloc(nbOfTuple1,nbOfComp1);
4875       const double *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
4876       double *pt=ret->getPointer();
4877       for(int i=0;i<nbOfTuple1;i++)
4878         pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::divides<double>());
4879       ret->copyStringInfoFrom(*a1);
4880       return ret.retn();
4881     }
4882   else
4883     {
4884       a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Divide !");//will always throw an exception
4885       return 0;
4886     }
4887 }
4888
4889 /*!
4890  * Divide values of \a this array by values of another DataArrayDouble. There are 3
4891  * valid cases.
4892  * 1.  The arrays have same number of tuples and components. Then each value of
4893  *    \a this array is divided by the corresponding value of \a other one, i.e.:
4894  *   _a_ [ i, j ] /= _other_ [ i, j ].
4895  * 2.  The arrays have same number of tuples and \a other array has one component. Then
4896  *   _a_ [ i, j ] /= _other_ [ i, 0 ].
4897  * 3.  The arrays have same number of components and \a other array has one tuple. Then
4898  *   _a_ [ i, j ] /= _a2_ [ 0, j ].
4899  *
4900  *  \warning No check of division by zero is performed!
4901  *  \param [in] other - an array to divide \a this one by.
4902  *  \throw If \a other is NULL.
4903  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
4904  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
4905  *         \a other has number of both tuples and components not equal to 1.
4906  */
4907 void DataArrayDouble::divideEqual(const DataArrayDouble *other) throw(INTERP_KERNEL::Exception)
4908 {
4909   if(!other)
4910     throw INTERP_KERNEL::Exception("DataArrayDouble::divideEqual : input DataArrayDouble instance is NULL !");
4911   const char *msg="Nb of tuples mismatch for DataArrayDouble::divideEqual !";
4912   checkAllocated();
4913   other->checkAllocated();
4914   int nbOfTuple=getNumberOfTuples();
4915   int nbOfTuple2=other->getNumberOfTuples();
4916   int nbOfComp=getNumberOfComponents();
4917   int nbOfComp2=other->getNumberOfComponents();
4918   if(nbOfTuple==nbOfTuple2)
4919     {
4920       if(nbOfComp==nbOfComp2)
4921         {
4922           std::transform(begin(),end(),other->begin(),getPointer(),std::divides<double>());
4923         }
4924       else if(nbOfComp2==1)
4925         {
4926           double *ptr=getPointer();
4927           const double *ptrc=other->getConstPointer();
4928           for(int i=0;i<nbOfTuple;i++)
4929             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::divides<double>(),*ptrc++));
4930         }
4931       else
4932         throw INTERP_KERNEL::Exception(msg);
4933     }
4934   else if(nbOfTuple2==1)
4935     {
4936       if(nbOfComp2==nbOfComp)
4937         {
4938           double *ptr=getPointer();
4939           const double *ptrc=other->getConstPointer();
4940           for(int i=0;i<nbOfTuple;i++)
4941             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::divides<double>());
4942         }
4943       else
4944         throw INTERP_KERNEL::Exception(msg);
4945     }
4946   else
4947     throw INTERP_KERNEL::Exception(msg);
4948   declareAsNew();
4949 }
4950
4951 /*!
4952  * Returns a new DataArrayDouble that is the result of pow of two given arrays. There are 3
4953  * valid cases.
4954  *
4955  *  \param [in] a1 - an array to pow up.
4956  *  \param [in] a2 - another array to sum up.
4957  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4958  *          The caller is to delete this result array using decrRef() as it is no more
4959  *          needed.
4960  *  \throw If either \a a1 or \a a2 is NULL.
4961  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
4962  *  \throw If \a a1->getNumberOfComponents() != 1 or \a a2->getNumberOfComponents() != 1.
4963  *  \throw If there is a negative value in \a a1.
4964  */
4965 DataArrayDouble *DataArrayDouble::Pow(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception)
4966 {
4967   if(!a1 || !a2)
4968     throw INTERP_KERNEL::Exception("DataArrayDouble::Pow : at least one of input instances is null !");
4969   int nbOfTuple=a1->getNumberOfTuples();
4970   int nbOfTuple2=a2->getNumberOfTuples();
4971   int nbOfComp=a1->getNumberOfComponents();
4972   int nbOfComp2=a2->getNumberOfComponents();
4973   if(nbOfTuple!=nbOfTuple2)
4974     throw INTERP_KERNEL::Exception("DataArrayDouble::Pow : number of tuples mismatches !");
4975   if(nbOfComp!=1 || nbOfComp2!=1)
4976     throw INTERP_KERNEL::Exception("DataArrayDouble::Pow : number of components of both arrays must be equal to 1 !");
4977   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New(); ret->alloc(nbOfTuple,1);
4978   const double *ptr1(a1->begin()),*ptr2(a2->begin());
4979   double *ptr=ret->getPointer();
4980   for(int i=0;i<nbOfTuple;i++,ptr1++,ptr2++,ptr++)
4981     {
4982       if(*ptr1>=0)
4983         {
4984           *ptr=pow(*ptr1,*ptr2);
4985         }
4986       else
4987         {
4988           std::ostringstream oss; oss << "DataArrayDouble::Pow : on tuple #" << i << " of a1 value is < 0 (" << *ptr1 << ") !";
4989           throw INTERP_KERNEL::Exception(oss.str().c_str());
4990         }
4991     }
4992   return ret.retn();
4993 }
4994
4995 /*!
4996  * Apply pow on values of another DataArrayDouble to values of \a this one.
4997  *
4998  *  \param [in] other - an array to pow to \a this one.
4999  *  \throw If \a other is NULL.
5000  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples()
5001  *  \throw If \a this->getNumberOfComponents() != 1 or \a other->getNumberOfComponents() != 1
5002  *  \throw If there is a negative value in \a this.
5003  */
5004 void DataArrayDouble::powEqual(const DataArrayDouble *other) throw(INTERP_KERNEL::Exception)
5005 {
5006   if(!other)
5007     throw INTERP_KERNEL::Exception("DataArrayDouble::powEqual : input instance is null !");
5008   int nbOfTuple=getNumberOfTuples();
5009   int nbOfTuple2=other->getNumberOfTuples();
5010   int nbOfComp=getNumberOfComponents();
5011   int nbOfComp2=other->getNumberOfComponents();
5012   if(nbOfTuple!=nbOfTuple2)
5013     throw INTERP_KERNEL::Exception("DataArrayDouble::powEqual : number of tuples mismatches !");
5014   if(nbOfComp!=1 || nbOfComp2!=1)
5015     throw INTERP_KERNEL::Exception("DataArrayDouble::powEqual : number of components of both arrays must be equal to 1 !");
5016   double *ptr=getPointer();
5017   const double *ptrc=other->begin();
5018   for(int i=0;i<nbOfTuple;i++,ptrc++,ptr++)
5019     {
5020       if(*ptr>=0)
5021         *ptr=pow(*ptr,*ptrc);
5022       else
5023         {
5024           std::ostringstream oss; oss << "DataArrayDouble::powEqual : on tuple #" << i << " of this value is < 0 (" << *ptr << ") !";
5025           throw INTERP_KERNEL::Exception(oss.str().c_str());
5026         }
5027     }
5028   declareAsNew();
5029 }
5030
5031 /*!
5032  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
5033  * Server side.
5034  */
5035 void DataArrayDouble::getTinySerializationIntInformation(std::vector<int>& tinyInfo) const
5036 {
5037   tinyInfo.resize(2);
5038   if(isAllocated())
5039     {
5040       tinyInfo[0]=getNumberOfTuples();
5041       tinyInfo[1]=getNumberOfComponents();
5042     }
5043   else
5044     {
5045       tinyInfo[0]=-1;
5046       tinyInfo[1]=-1;
5047     }
5048 }
5049
5050 /*!
5051  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
5052  * Server side.
5053  */
5054 void DataArrayDouble::getTinySerializationStrInformation(std::vector<std::string>& tinyInfo) const
5055 {
5056   if(isAllocated())
5057     {
5058       int nbOfCompo=getNumberOfComponents();
5059       tinyInfo.resize(nbOfCompo+1);
5060       tinyInfo[0]=getName();
5061       for(int i=0;i<nbOfCompo;i++)
5062         tinyInfo[i+1]=getInfoOnComponent(i);
5063     }
5064   else
5065     {
5066       tinyInfo.resize(1);
5067       tinyInfo[0]=getName();
5068     }
5069 }
5070
5071 /*!
5072  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
5073  * This method returns if a feeding is needed.
5074  */
5075 bool DataArrayDouble::resizeForUnserialization(const std::vector<int>& tinyInfoI)
5076 {
5077   int nbOfTuple=tinyInfoI[0];
5078   int nbOfComp=tinyInfoI[1];
5079   if(nbOfTuple!=-1 || nbOfComp!=-1)
5080     {
5081       alloc(nbOfTuple,nbOfComp);
5082       return true;
5083     }
5084   return false;
5085 }
5086
5087 /*!
5088  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
5089  */
5090 void DataArrayDouble::finishUnserialization(const std::vector<int>& tinyInfoI, const std::vector<std::string>& tinyInfoS)
5091 {
5092   setName(tinyInfoS[0].c_str());
5093   if(isAllocated())
5094     {
5095       int nbOfCompo=getNumberOfComponents();
5096       for(int i=0;i<nbOfCompo;i++)
5097         setInfoOnComponent(i,tinyInfoS[i+1].c_str());
5098     }
5099 }
5100
5101 DataArrayDoubleIterator::DataArrayDoubleIterator(DataArrayDouble *da):_da(da),_tuple_id(0),_nb_comp(0),_nb_tuple(0)
5102 {
5103   if(_da)
5104     {
5105       _da->incrRef();
5106       if(_da->isAllocated())
5107         {
5108           _nb_comp=da->getNumberOfComponents();
5109           _nb_tuple=da->getNumberOfTuples();
5110           _pt=da->getPointer();
5111         }
5112     }
5113 }
5114
5115 DataArrayDoubleIterator::~DataArrayDoubleIterator()
5116 {
5117   if(_da)
5118     _da->decrRef();
5119 }
5120
5121 DataArrayDoubleTuple *DataArrayDoubleIterator::nextt() throw(INTERP_KERNEL::Exception)
5122 {
5123   if(_tuple_id<_nb_tuple)
5124     {
5125       _tuple_id++;
5126       DataArrayDoubleTuple *ret=new DataArrayDoubleTuple(_pt,_nb_comp);
5127       _pt+=_nb_comp;
5128       return ret;
5129     }
5130   else
5131     return 0;
5132 }
5133
5134 DataArrayDoubleTuple::DataArrayDoubleTuple(double *pt, int nbOfComp):_pt(pt),_nb_of_compo(nbOfComp)
5135 {
5136 }
5137
5138
5139 std::string DataArrayDoubleTuple::repr() const throw(INTERP_KERNEL::Exception)
5140 {
5141   std::ostringstream oss; oss.precision(17); oss << "(";
5142   for(int i=0;i<_nb_of_compo-1;i++)
5143     oss << _pt[i] << ", ";
5144   oss << _pt[_nb_of_compo-1] << ")";
5145   return oss.str();
5146 }
5147
5148 double DataArrayDoubleTuple::doubleValue() const throw(INTERP_KERNEL::Exception)
5149 {
5150   if(_nb_of_compo==1)
5151     return *_pt;
5152   throw INTERP_KERNEL::Exception("DataArrayDoubleTuple::doubleValue : DataArrayDoubleTuple instance has not exactly 1 component -> Not possible to convert it into a double precision float !");
5153 }
5154
5155 /*!
5156  * This method returns a newly allocated instance the caller should dealed with by a ParaMEDMEM::DataArrayDouble::decrRef.
5157  * This method performs \b no copy of data. The content is only referenced using ParaMEDMEM::DataArrayDouble::useArray with ownership set to \b false.
5158  * 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
5159  * \b nbOfCompo=1 and \bnbOfTuples==this->_nb_of_elem.
5160  */
5161 DataArrayDouble *DataArrayDoubleTuple::buildDADouble(int nbOfTuples, int nbOfCompo) const throw(INTERP_KERNEL::Exception)
5162 {
5163   if((_nb_of_compo==nbOfCompo && nbOfTuples==1) || (_nb_of_compo==nbOfTuples && nbOfCompo==1))
5164     {
5165       DataArrayDouble *ret=DataArrayDouble::New();
5166       ret->useExternalArrayWithRWAccess(_pt,nbOfTuples,nbOfCompo);
5167       return ret;
5168     }
5169   else
5170     {
5171       std::ostringstream oss; oss << "DataArrayDoubleTuple::buildDADouble : unable to build a requested DataArrayDouble instance with nbofTuple=" << nbOfTuples << " and nbOfCompo=" << nbOfCompo;
5172       oss << ".\nBecause the number of elements in this is " << _nb_of_compo << " !";
5173       throw INTERP_KERNEL::Exception(oss.str().c_str());
5174     }
5175 }
5176
5177 /*!
5178  * Returns a new instance of DataArrayInt. The caller is to delete this array
5179  * using decrRef() as it is no more needed. 
5180  */
5181 DataArrayInt *DataArrayInt::New()
5182 {
5183   return new DataArrayInt;
5184 }
5185
5186 /*!
5187  * Checks if raw data is allocated. Read more on the raw data
5188  * in \ref MEDCouplingArrayBasicsTuplesAndCompo "DataArrays infos" for more information.
5189  *  \return bool - \a true if the raw data is allocated, \a false else.
5190  */
5191 bool DataArrayInt::isAllocated() const throw(INTERP_KERNEL::Exception)
5192 {
5193   return getConstPointer()!=0;
5194 }
5195
5196 /*!
5197  * Checks if raw data is allocated and throws an exception if it is not the case.
5198  *  \throw If the raw data is not allocated.
5199  */
5200 void DataArrayInt::checkAllocated() const throw(INTERP_KERNEL::Exception)
5201 {
5202   if(!isAllocated())
5203     throw INTERP_KERNEL::Exception("DataArrayInt::checkAllocated : Array is defined but not allocated ! Call alloc or setValues method first !");
5204 }
5205
5206 std::size_t DataArrayInt::getHeapMemorySize() const
5207 {
5208   std::size_t sz=_mem.getNbOfElemAllocated();
5209   sz*=sizeof(int);
5210   return DataArray::getHeapMemorySize()+sz;
5211 }
5212
5213 /*!
5214  * Sets information on all components. This method can change number of components
5215  * at certain conditions; if the conditions are not respected, an exception is thrown.
5216  * The number of components can be changed provided that \a this is not allocated.
5217  *
5218  * To know more on format of the component information see
5219  * \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
5220  *  \param [in] info - a vector of component infos.
5221  *  \throw If \a this->getNumberOfComponents() != \a info.size() && \a this->isAllocated()
5222  */
5223 void DataArrayInt::setInfoAndChangeNbOfCompo(const std::vector<std::string>& info) throw(INTERP_KERNEL::Exception)
5224 {
5225   if(getNumberOfComponents()!=(int)info.size())
5226     {
5227       if(!isAllocated())
5228         _info_on_compo=info;
5229       else
5230         {
5231           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 !";
5232           throw INTERP_KERNEL::Exception(oss.str().c_str());
5233         }
5234     }
5235   else
5236     _info_on_compo=info;
5237 }
5238
5239 /*!
5240  * Returns the only one value in \a this, if and only if number of elements
5241  * (nb of tuples * nb of components) is equal to 1, and that \a this is allocated.
5242  *  \return double - the sole value stored in \a this array.
5243  *  \throw If at least one of conditions stated above is not fulfilled.
5244  */
5245 int DataArrayInt::intValue() const throw(INTERP_KERNEL::Exception)
5246 {
5247   if(isAllocated())
5248     {
5249       if(getNbOfElems()==1)
5250         {
5251           return *getConstPointer();
5252         }
5253       else
5254         throw INTERP_KERNEL::Exception("DataArrayInt::intValue : DataArrayInt instance is allocated but number of elements is not equal to 1 !");
5255     }
5256   else
5257     throw INTERP_KERNEL::Exception("DataArrayInt::intValue : DataArrayInt instance is not allocated !");
5258 }
5259
5260 /*!
5261  * Returns an integer value characterizing \a this array, which is useful for a quick
5262  * comparison of many instances of DataArrayInt.
5263  *  \return int - the hash value.
5264  *  \throw If \a this is not allocated.
5265  */
5266 int DataArrayInt::getHashCode() const throw(INTERP_KERNEL::Exception)
5267 {
5268   checkAllocated();
5269   std::size_t nbOfElems=getNbOfElems();
5270   int ret=nbOfElems*65536;
5271   int delta=3;
5272   if(nbOfElems>48)
5273     delta=nbOfElems/8;
5274   int ret0=0;
5275   const int *pt=begin();
5276   for(std::size_t i=0;i<nbOfElems;i+=delta)
5277     ret0+=pt[i] & 0x1FFF;
5278   return ret+ret0;
5279 }
5280
5281 /*!
5282  * Checks the number of tuples.
5283  *  \return bool - \a true if getNumberOfTuples() == 0, \a false else.
5284  *  \throw If \a this is not allocated.
5285  */
5286 bool DataArrayInt::empty() const throw(INTERP_KERNEL::Exception)
5287 {
5288   checkAllocated();
5289   return getNumberOfTuples()==0;
5290 }
5291
5292 /*!
5293  * Returns a full copy of \a this. For more info on copying data arrays see
5294  * \ref MEDCouplingArrayBasicsCopyDeep.
5295  *  \return DataArrayInt * - a new instance of DataArrayInt.
5296  */
5297 DataArrayInt *DataArrayInt::deepCpy() const throw(INTERP_KERNEL::Exception)
5298 {
5299   return new DataArrayInt(*this);
5300 }
5301
5302 /*!
5303  * Returns either a \a deep or \a shallow copy of this array. For more info see
5304  * \ref MEDCouplingArrayBasicsCopyDeep and \ref MEDCouplingArrayBasicsCopyShallow.
5305  *  \param [in] dCpy - if \a true, a deep copy is returned, else, a shallow one.
5306  *  \return DataArrayInt * - either a new instance of DataArrayInt (if \a dCpy
5307  *          == \a true) or \a this instance (if \a dCpy == \a false).
5308  */
5309 DataArrayInt *DataArrayInt::performCpy(bool dCpy) const throw(INTERP_KERNEL::Exception)
5310 {
5311   if(dCpy)
5312     return deepCpy();
5313   else
5314     {
5315       incrRef();
5316       return const_cast<DataArrayInt *>(this);
5317     }
5318 }
5319
5320 /*!
5321  * Copies all the data from another DataArrayInt. For more info see
5322  * \ref MEDCouplingArrayBasicsCopyDeepAssign.
5323  *  \param [in] other - another instance of DataArrayInt to copy data from.
5324  *  \throw If the \a other is not allocated.
5325  */
5326 void DataArrayInt::cpyFrom(const DataArrayInt& other) throw(INTERP_KERNEL::Exception)
5327 {
5328   other.checkAllocated();
5329   int nbOfTuples=other.getNumberOfTuples();
5330   int nbOfComp=other.getNumberOfComponents();
5331   allocIfNecessary(nbOfTuples,nbOfComp);
5332   std::size_t nbOfElems=(std::size_t)nbOfTuples*nbOfComp;
5333   int *pt=getPointer();
5334   const int *ptI=other.getConstPointer();
5335   for(std::size_t i=0;i<nbOfElems;i++)
5336     pt[i]=ptI[i];
5337   copyStringInfoFrom(other);
5338 }
5339
5340 /*!
5341  * This method reserve nbOfElems elements in memory ( nbOfElems*4 bytes ) \b without impacting the number of tuples in \a this.
5342  * 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.
5343  * If \a this has not already been allocated, number of components is set to one.
5344  * This method allows to reduce number of reallocations on invokation of DataArrayInt::pushBackSilent and DataArrayInt::pushBackValsSilent on \a this.
5345  * 
5346  * \sa DataArrayInt::pack, DataArrayInt::pushBackSilent, DataArrayInt::pushBackValsSilent
5347  */
5348 void DataArrayInt::reserve(std::size_t nbOfElems) throw(INTERP_KERNEL::Exception)
5349 {
5350   int nbCompo=getNumberOfComponents();
5351   if(nbCompo==1)
5352     {
5353       _mem.reserve(nbOfElems);
5354     }
5355   else if(nbCompo==0)
5356     {
5357       _mem.reserve(nbOfElems);
5358       _info_on_compo.resize(1);
5359     }
5360   else
5361     throw INTERP_KERNEL::Exception("DataArrayInt::reserve : not available for DataArrayInt with number of components different than 1 !");
5362 }
5363
5364 /*!
5365  * 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
5366  * of counter. So the caller is expected to call TimeLabel::declareAsNew on \a this at the end of the push session.
5367  *
5368  * \param [in] val the value to be added in \a this
5369  * \throw If \a this has already been allocated with number of components different from one.
5370  * \sa DataArrayInt::pushBackValsSilent
5371  */
5372 void DataArrayInt::pushBackSilent(int val) throw(INTERP_KERNEL::Exception)
5373 {
5374   int nbCompo=getNumberOfComponents();
5375   if(nbCompo==1)
5376     _mem.pushBack(val);
5377   else if(nbCompo==0)
5378     {
5379       _info_on_compo.resize(1);
5380       _mem.pushBack(val);
5381     }
5382   else
5383     throw INTERP_KERNEL::Exception("DataArrayInt::pushBackSilent : not available for DataArrayInt with number of components different than 1 !");
5384 }
5385
5386 /*!
5387  * 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
5388  * of counter. So the caller is expected to call TimeLabel::declareAsNew on \a this at the end of the push session.
5389  *
5390  *  \param [in] valsBg - an array of values to push at the end of \this.
5391  *  \param [in] valsEnd - specifies the end of the array \a valsBg, so that
5392  *              the last value of \a valsBg is \a valsEnd[ -1 ].
5393  * \throw If \a this has already been allocated with number of components different from one.
5394  * \sa DataArrayInt::pushBackSilent
5395  */
5396 void DataArrayInt::pushBackValsSilent(const int *valsBg, const int *valsEnd) throw(INTERP_KERNEL::Exception)
5397 {
5398   int nbCompo=getNumberOfComponents();
5399   if(nbCompo==1)
5400     _mem.insertAtTheEnd(valsBg,valsEnd);
5401   else if(nbCompo==0)
5402     {
5403       _info_on_compo.resize(1);
5404       _mem.insertAtTheEnd(valsBg,valsEnd);
5405     }
5406   else
5407     throw INTERP_KERNEL::Exception("DataArrayInt::pushBackValsSilent : not available for DataArrayInt with number of components different than 1 !");
5408 }
5409
5410 /*!
5411  * This method returns silently ( without updating time label in \a this ) the last value, if any and suppress it.
5412  * \throw If \a this is already empty.
5413  * \throw If \a this has number of components different from one.
5414  */
5415 int DataArrayInt::popBackSilent() throw(INTERP_KERNEL::Exception)
5416 {
5417   if(getNumberOfComponents()==1)
5418     return _mem.popBack();
5419   else
5420     throw INTERP_KERNEL::Exception("DataArrayInt::popBackSilent : not available for DataArrayInt with number of components different than 1 !");
5421 }
5422
5423 /*!
5424  * 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.
5425  *
5426  * \sa DataArrayInt::getHeapMemorySize, DataArrayInt::reserve
5427  */
5428 void DataArrayInt::pack() const throw(INTERP_KERNEL::Exception)
5429 {
5430   _mem.pack();
5431 }
5432
5433 /*!
5434  * Allocates the raw data in memory. If exactly as same memory as needed already
5435  * allocated, it is not re-allocated.
5436  *  \param [in] nbOfTuple - number of tuples of data to allocate.
5437  *  \param [in] nbOfCompo - number of components of data to allocate.
5438  *  \throw If \a nbOfTuple < 0 or \a nbOfCompo < 0.
5439  */
5440 void DataArrayInt::allocIfNecessary(int nbOfTuple, int nbOfCompo) throw(INTERP_KERNEL::Exception)
5441 {
5442   if(isAllocated())
5443     {
5444       if(nbOfTuple!=getNumberOfTuples() || nbOfCompo!=getNumberOfComponents())
5445         alloc(nbOfTuple,nbOfCompo);
5446     }
5447   else
5448     alloc(nbOfTuple,nbOfCompo);
5449 }
5450
5451 /*!
5452  * Allocates the raw data in memory. If the memory was already allocated, then it is
5453  * freed and re-allocated. See an example of this method use
5454  * \ref MEDCouplingArraySteps1WC "here".
5455  *  \param [in] nbOfTuple - number of tuples of data to allocate.
5456  *  \param [in] nbOfCompo - number of components of data to allocate.
5457  *  \throw If \a nbOfTuple < 0 or \a nbOfCompo < 0.
5458  */
5459 void DataArrayInt::alloc(int nbOfTuple, int nbOfCompo) throw(INTERP_KERNEL::Exception)
5460 {
5461   if(nbOfTuple<0 || nbOfCompo<0)
5462     throw INTERP_KERNEL::Exception("DataArrayInt::alloc : request for negative length of data !");
5463   _info_on_compo.resize(nbOfCompo);
5464   _mem.alloc(nbOfCompo*(std::size_t)nbOfTuple);
5465   declareAsNew();
5466 }
5467
5468 /*!
5469  * Assign zero to all values in \a this array. To know more on filling arrays see
5470  * \ref MEDCouplingArrayFill.
5471  * \throw If \a this is not allocated.
5472  */
5473 void DataArrayInt::fillWithZero() throw(INTERP_KERNEL::Exception)
5474 {
5475   checkAllocated();
5476   _mem.fillWithValue(0);
5477   declareAsNew();
5478 }
5479
5480 /*!
5481  * Assign \a val to all values in \a this array. To know more on filling arrays see
5482  * \ref MEDCouplingArrayFill.
5483  *  \param [in] val - the value to fill with.
5484  *  \throw If \a this is not allocated.
5485  */
5486 void DataArrayInt::fillWithValue(int val) throw(INTERP_KERNEL::Exception)
5487 {
5488   checkAllocated();
5489   _mem.fillWithValue(val);
5490   declareAsNew();
5491 }
5492
5493 /*!
5494  * Set all values in \a this array so that the i-th element equals to \a init + i
5495  * (i starts from zero). To know more on filling arrays see \ref MEDCouplingArrayFill.
5496  *  \param [in] init - value to assign to the first element of array.
5497  *  \throw If \a this->getNumberOfComponents() != 1
5498  *  \throw If \a this is not allocated.
5499  */
5500 void DataArrayInt::iota(int init) throw(INTERP_KERNEL::Exception)
5501 {
5502   checkAllocated();
5503   if(getNumberOfComponents()!=1)
5504     throw INTERP_KERNEL::Exception("DataArrayInt::iota : works only for arrays with only one component, you can call 'rearrange' method before !");
5505   int *ptr=getPointer();
5506   int ntuples=getNumberOfTuples();
5507   for(int i=0;i<ntuples;i++)
5508     ptr[i]=init+i;
5509   declareAsNew();
5510 }
5511
5512 /*!
5513  * Returns a textual and human readable representation of \a this instance of
5514  * DataArrayInt. This text is shown when a DataArrayInt is printed in Python.
5515  *  \return std::string - text describing \a this DataArrayInt.
5516  */
5517 std::string DataArrayInt::repr() const throw(INTERP_KERNEL::Exception)
5518 {
5519   std::ostringstream ret;
5520   reprStream(ret);
5521   return ret.str();
5522 }
5523
5524 std::string DataArrayInt::reprZip() const throw(INTERP_KERNEL::Exception)
5525 {
5526   std::ostringstream ret;
5527   reprZipStream(ret);
5528   return ret.str();
5529 }
5530
5531 void DataArrayInt::writeVTK(std::ostream& ofs, int indent, const char *type, const char *nameInFile) const throw(INTERP_KERNEL::Exception)
5532 {
5533   checkAllocated();
5534   std::string idt(indent,' ');
5535   ofs << idt << "<DataArray type=\"" << type << "\" Name=\"" << nameInFile << "\" NumberOfComponents=\"" << getNumberOfComponents() << "\"";
5536   ofs << " format=\"ascii\" RangeMin=\"" << getMinValueInArray() << "\" RangeMax=\"" << getMaxValueInArray() << "\">\n" << idt;
5537   std::copy(begin(),end(),std::ostream_iterator<int>(ofs," "));
5538   ofs << std::endl << idt << "</DataArray>\n";
5539 }
5540
5541 void DataArrayInt::reprStream(std::ostream& stream) const throw(INTERP_KERNEL::Exception)
5542 {
5543   stream << "Name of int array : \"" << _name << "\"\n";
5544   reprWithoutNameStream(stream);
5545 }
5546
5547 void DataArrayInt::reprZipStream(std::ostream& stream) const throw(INTERP_KERNEL::Exception)
5548 {
5549   stream << "Name of int array : \"" << _name << "\"\n";
5550   reprZipWithoutNameStream(stream);
5551 }
5552
5553 void DataArrayInt::reprWithoutNameStream(std::ostream& stream) const throw(INTERP_KERNEL::Exception)
5554 {
5555   DataArray::reprWithoutNameStream(stream);
5556   _mem.repr(getNumberOfComponents(),stream);
5557 }
5558
5559 void DataArrayInt::reprZipWithoutNameStream(std::ostream& stream) const throw(INTERP_KERNEL::Exception)
5560 {
5561   DataArray::reprWithoutNameStream(stream);
5562   _mem.reprZip(getNumberOfComponents(),stream);
5563 }
5564
5565 void DataArrayInt::reprCppStream(const char *varName, std::ostream& stream) const throw(INTERP_KERNEL::Exception)
5566 {
5567   int nbTuples=getNumberOfTuples(),nbComp=getNumberOfComponents();
5568   const int *data=getConstPointer();
5569   stream << "DataArrayInt *" << varName << "=DataArrayInt::New();" << std::endl;
5570   if(nbTuples*nbComp>=1)
5571     {
5572       stream << "const int " << varName << "Data[" << nbTuples*nbComp << "]={";
5573       std::copy(data,data+nbTuples*nbComp-1,std::ostream_iterator<int>(stream,","));
5574       stream << data[nbTuples*nbComp-1] << "};" << std::endl;
5575       stream << varName << "->useArray(" << varName << "Data,false,CPP_DEALLOC," << nbTuples << "," << nbComp << ");" << std::endl;
5576     }
5577   else
5578     stream << varName << "->alloc(" << nbTuples << "," << nbComp << ");" << std::endl;
5579   stream << varName << "->setName(\"" << getName() << "\");" << std::endl;
5580 }
5581
5582 /*!
5583  * Method that gives a quick overvien of \a this for python.
5584  */
5585 void DataArrayInt::reprQuickOverview(std::ostream& stream) const throw(INTERP_KERNEL::Exception)
5586 {
5587   static const std::size_t MAX_NB_OF_BYTE_IN_REPR=300;
5588   stream << "DataArrayInt C++ instance at " << this << ". ";
5589   if(isAllocated())
5590     {
5591       int nbOfCompo=(int)_info_on_compo.size();
5592       if(nbOfCompo>=1)
5593         {
5594           int nbOfTuples=getNumberOfTuples();
5595           stream << "Number of tuples : " << nbOfTuples << ". Number of components : " << nbOfCompo << "." << std::endl;
5596           reprQuickOverviewData(stream,MAX_NB_OF_BYTE_IN_REPR);
5597         }
5598       else
5599         stream << "Number of components : 0.";
5600     }
5601   else
5602     stream << "*** No data allocated ****";
5603 }
5604
5605 void DataArrayInt::reprQuickOverviewData(std::ostream& stream, std::size_t maxNbOfByteInRepr) const throw(INTERP_KERNEL::Exception)
5606 {
5607   const int *data=begin();
5608   int nbOfTuples=getNumberOfTuples();
5609   int nbOfCompo=(int)_info_on_compo.size();
5610   std::ostringstream oss2; oss2 << "[";
5611   std::string oss2Str(oss2.str());
5612   bool isFinished=true;
5613   for(int i=0;i<nbOfTuples && isFinished;i++)
5614     {
5615       if(nbOfCompo>1)
5616         {
5617           oss2 << "(";
5618           for(int j=0;j<nbOfCompo;j++,data++)
5619             {
5620               oss2 << *data;
5621               if(j!=nbOfCompo-1) oss2 << ", ";
5622             }
5623           oss2 << ")";
5624         }
5625       else
5626         oss2 << *data++;
5627       if(i!=nbOfTuples-1) oss2 << ", ";
5628       std::string oss3Str(oss2.str());
5629       if(oss3Str.length()<maxNbOfByteInRepr)
5630         oss2Str=oss3Str;
5631       else
5632         isFinished=false;
5633     }
5634   stream << oss2Str;
5635   if(!isFinished)
5636     stream << "... ";
5637   stream << "]";
5638 }
5639
5640 /*!
5641  * Modifies \a this one-dimensional array so that each value \a v = \a indArrBg[ \a v ],
5642  * i.e. a current value is used as in index to get a new value from \a indArrBg.
5643  *  \param [in] indArrBg - pointer to the first element of array of new values to assign
5644  *         to \a this array.
5645  *  \param [in] indArrEnd - specifies the end of the array \a indArrBg, so that
5646  *              the last value of \a indArrBg is \a indArrEnd[ -1 ].
5647  *  \throw If \a this->getNumberOfComponents() != 1
5648  *  \throw If any value of \a this can't be used as a valid index for 
5649  *         [\a indArrBg, \a indArrEnd).
5650  */
5651 void DataArrayInt::transformWithIndArr(const int *indArrBg, const int *indArrEnd) throw(INTERP_KERNEL::Exception)
5652 {
5653   checkAllocated();
5654   if(getNumberOfComponents()!=1)
5655     throw INTERP_KERNEL::Exception("Call transformWithIndArr method on DataArrayInt with only one component, you can call 'rearrange' method before !");
5656   int nbElemsIn=(int)std::distance(indArrBg,indArrEnd);
5657   int nbOfTuples=getNumberOfTuples();
5658   int *pt=getPointer();
5659   for(int i=0;i<nbOfTuples;i++,pt++)
5660     {
5661       if(*pt>=0 && *pt<nbElemsIn)
5662         *pt=indArrBg[*pt];
5663       else
5664         {
5665           std::ostringstream oss; oss << "DataArrayInt::transformWithIndArr : error on tuple #" << i << " value is " << *pt << " and indirectionnal array as a size equal to " << nbElemsIn;
5666           throw INTERP_KERNEL::Exception(oss.str().c_str());
5667         }
5668     }
5669   declareAsNew();
5670 }
5671
5672 /*!
5673  * Computes distribution of values of \a this one-dimensional array between given value
5674  * ranges (casts). This method is typically useful for entity number spliting by types,
5675  * for example. 
5676  *  \warning The values contained in \a arrBg should be sorted ascendently. No
5677  *           check of this is be done. If not, the result is not warranted. 
5678  *  \param [in] arrBg - the array of ascending values defining the value ranges. The i-th
5679  *         value of \a arrBg (\a arrBg[ i ]) gives the lowest value of the i-th range,
5680  *         and the greatest value of the i-th range equals to \a arrBg[ i+1 ] - 1. \a
5681  *         arrBg containing \a n values defines \a n-1 ranges. The last value of \a arrBg
5682  *         should be more than every value in \a this array.
5683  *  \param [in] arrEnd - specifies the end of the array \a arrBg, so that
5684  *              the last value of \a arrBg is \a arrEnd[ -1 ].
5685  *  \param [out] castArr - a new instance of DataArrayInt, of same size as \a this array
5686  *         (same number of tuples and components), the caller is to delete 
5687  *         using decrRef() as it is no more needed.
5688  *         This array contains indices of ranges for every value of \a this array. I.e.
5689  *         the i-th value of \a castArr gives the index of range the i-th value of \a this
5690  *         belongs to. Or, in other words, this parameter contains for each tuple in \a
5691  *         this in which cast it holds.
5692  *  \param [out] rankInsideCast - a new instance of DataArrayInt, of same size as \a this
5693  *         array, the caller is to delete using decrRef() as it is no more needed.
5694  *         This array contains ranks of values of \a this array within ranges
5695  *         they belongs to. I.e. the i-th value of \a rankInsideCast gives the rank of
5696  *         the i-th value of \a this array within the \a castArr[ i ]-th range, to which
5697  *         the i-th value of \a this belongs to. Or, in other words, this param contains 
5698  *         for each tuple its rank inside its cast. The rank is computed as difference
5699  *         between the value and the lowest value of range.
5700  *  \param [out] castsPresent - a new instance of DataArrayInt, containing indices of
5701  *         ranges (casts) to which at least one value of \a this array belongs.
5702  *         Or, in other words, this param contains the casts that \a this contains.
5703  *         The caller is to delete this array using decrRef() as it is no more needed.
5704  *
5705  * \b Example: If \a this contains [6,5,0,3,2,7,8,1,4] and \a arrBg contains [0,4,9] then
5706  *            the output of this method will be : 
5707  * - \a castArr       : [1,1,0,0,0,1,1,0,1]
5708  * - \a rankInsideCast: [2,1,0,3,2,3,4,1,0]
5709  * - \a castsPresent  : [0,1]
5710  *
5711  * I.e. values of \a this array belong to 2 ranges: #0 and #1. Value 6 belongs to the
5712  * range #1 and its rank within this range is 2; etc.
5713  *
5714  *  \throw If \a this->getNumberOfComponents() != 1.
5715  *  \throw If \a arrEnd - arrBg < 2.
5716  *  \throw If any value of \a this is not less than \a arrEnd[-1].
5717  */
5718 void DataArrayInt::splitByValueRange(const int *arrBg, const int *arrEnd,
5719                                      DataArrayInt *& castArr, DataArrayInt *& rankInsideCast, DataArrayInt *& castsPresent) const throw(INTERP_KERNEL::Exception)
5720 {
5721   checkAllocated();
5722   if(getNumberOfComponents()!=1)
5723     throw INTERP_KERNEL::Exception("Call splitByValueRange  method on DataArrayInt with only one component, you can call 'rearrange' method before !");
5724   int nbOfTuples=getNumberOfTuples();
5725   std::size_t nbOfCast=std::distance(arrBg,arrEnd);
5726   if(nbOfCast<2)
5727     throw INTERP_KERNEL::Exception("DataArrayInt::splitByValueRange : The input array giving the cast range values should be of size >=2 !");
5728   nbOfCast--;
5729   const int *work=getConstPointer();
5730   typedef std::reverse_iterator<const int *> rintstart;
5731   rintstart bg(arrEnd);//OK no problem because size of 'arr' is greater or equal 2
5732   rintstart end2(arrBg);
5733   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret1=DataArrayInt::New();
5734   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret2=DataArrayInt::New();
5735   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret3=DataArrayInt::New();
5736   ret1->alloc(nbOfTuples,1);
5737   ret2->alloc(nbOfTuples,1);
5738   int *ret1Ptr=ret1->getPointer();
5739   int *ret2Ptr=ret2->getPointer();
5740   std::set<std::size_t> castsDetected;
5741   for(int i=0;i<nbOfTuples;i++)
5742     {
5743       rintstart res=std::find_if(bg,end2,std::bind2nd(std::less_equal<int>(), work[i]));
5744       std::size_t pos=std::distance(bg,res);
5745       std::size_t pos2=nbOfCast-pos;
5746       if(pos2<nbOfCast)
5747         {
5748           ret1Ptr[i]=(int)pos2;
5749           ret2Ptr[i]=work[i]-arrBg[pos2];
5750           castsDetected.insert(pos2);
5751         }
5752       else
5753         {
5754           std::ostringstream oss; oss << "DataArrayInt::splitByValueRange : At rank #" << i << " the value is " << work[i] << " whereas the last value is " << *bg;
5755           throw INTERP_KERNEL::Exception(oss.str().c_str());
5756         }
5757     }
5758   ret3->alloc((int)castsDetected.size(),1);
5759   std::copy(castsDetected.begin(),castsDetected.end(),ret3->getPointer());
5760   castArr=ret1.retn();
5761   rankInsideCast=ret2.retn();
5762   castsPresent=ret3.retn();
5763 }
5764
5765 /*!
5766  * Creates a one-dimensional DataArrayInt (\a res) whose contents are computed from 
5767  * values of \a this (\a a) and the given (\a indArr) arrays as follows:
5768  * \a res[ \a indArr[ \a a[ i ]]] = i. I.e. for each value in place i \a v = \a a[ i ],
5769  * new value in place \a indArr[ \a v ] is i.
5770  *  \param [in] indArrBg - the array holding indices within the result array to assign
5771  *         indices of values of \a this array pointing to values of \a indArrBg.
5772  *  \param [in] indArrEnd - specifies the end of the array \a indArrBg, so that
5773  *              the last value of \a indArrBg is \a indArrEnd[ -1 ].
5774  *  \return DataArrayInt * - the new instance of DataArrayInt.
5775  *          The caller is to delete this result array using decrRef() as it is no more
5776  *          needed.
5777  *  \throw If \a this->getNumberOfComponents() != 1.
5778  *  \throw If any value of \a this array is not a valid index for \a indArrBg array.
5779  *  \throw If any value of \a indArrBg is not a valid index for \a this array.
5780  */
5781 DataArrayInt *DataArrayInt::transformWithIndArrR(const int *indArrBg, const int *indArrEnd) const throw(INTERP_KERNEL::Exception)
5782 {
5783   checkAllocated();
5784   if(getNumberOfComponents()!=1)
5785     throw INTERP_KERNEL::Exception("Call transformWithIndArrR method on DataArrayInt with only one component, you can call 'rearrange' method before !");
5786   int nbElemsIn=(int)std::distance(indArrBg,indArrEnd);
5787   int nbOfTuples=getNumberOfTuples();
5788   const int *pt=getConstPointer();
5789   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
5790   ret->alloc(nbOfTuples,1);
5791   ret->fillWithValue(-1);
5792   int *tmp=ret->getPointer();
5793   for(int i=0;i<nbOfTuples;i++,pt++)
5794     {
5795       if(*pt>=0 && *pt<nbElemsIn)
5796         {
5797           int pos=indArrBg[*pt];
5798           if(pos>=0 && pos<nbOfTuples)
5799             tmp[pos]=i;
5800           else
5801             {
5802               std::ostringstream oss; oss << "DataArrayInt::transformWithIndArrR : error on tuple #" << i << " value of new pos is " << pos << " ( indArrBg[" << *pt << "]) ! Should be in [0," << nbOfTuples << ") !";
5803               throw INTERP_KERNEL::Exception(oss.str().c_str());
5804             }
5805         }
5806       else
5807         {
5808           std::ostringstream oss; oss << "DataArrayInt::transformWithIndArrR : error on tuple #" << i << " value is " << *pt << " and indirectionnal array as a size equal to " << nbElemsIn << " !";
5809           throw INTERP_KERNEL::Exception(oss.str().c_str());
5810         }
5811     }
5812   return ret.retn();
5813 }
5814
5815 /*!
5816  * Creates a one-dimensional DataArrayInt of given length, whose contents are computed
5817  * from values of \a this array, which is supposed to contain a renumbering map in 
5818  * "Old to New" mode. The result array contains a renumbering map in "New to Old" mode.
5819  * To know how to use the renumbering maps see \ref MEDCouplingArrayRenumbering.
5820  *  \param [in] newNbOfElem - the number of tuples in the result array.
5821  *  \return DataArrayInt * - the new instance of DataArrayInt.
5822  *          The caller is to delete this result array using decrRef() as it is no more
5823  *          needed.
5824  * 
5825  *  \ref cpp_mcdataarrayint_invertarrayo2n2n2o "Here is a C++ example".<br>
5826  *  \ref py_mcdataarrayint_invertarrayo2n2n2o  "Here is a Python example".
5827  */
5828 DataArrayInt *DataArrayInt::invertArrayO2N2N2O(int newNbOfElem) const
5829 {
5830   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
5831   ret->alloc(newNbOfElem,1);
5832   int nbOfOldNodes=getNumberOfTuples();
5833   const int *old2New=getConstPointer();
5834   int *pt=ret->getPointer();
5835   for(int i=0;i!=nbOfOldNodes;i++)
5836     if(old2New[i]!=-1)
5837       pt[old2New[i]]=i;
5838   return ret.retn();
5839 }
5840
5841 /*!
5842  * This method is similar to DataArrayInt::invertArrayO2N2N2O except that 
5843  * 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]
5844  */
5845 DataArrayInt *DataArrayInt::invertArrayO2N2N2OBis(int newNbOfElem) const throw(INTERP_KERNEL::Exception)
5846 {
5847   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
5848   ret->alloc(newNbOfElem,1);
5849   int nbOfOldNodes=getNumberOfTuples();
5850   const int *old2New=getConstPointer();
5851   int *pt=ret->getPointer();
5852   for(int i=nbOfOldNodes-1;i>=0;i--)
5853     if(old2New[i]!=-1)
5854       pt[old2New[i]]=i;
5855   return ret.retn();
5856 }
5857
5858 /*!
5859  * Creates a one-dimensional DataArrayInt of given length, whose contents are computed
5860  * from values of \a this array, which is supposed to contain a renumbering map in 
5861  * "New to Old" mode. The result array contains a renumbering map in "Old to New" mode.
5862  * To know how to use the renumbering maps see \ref MEDCouplingArrayRenumbering.
5863  *  \param [in] newNbOfElem - the number of tuples in the result array.
5864  *  \return DataArrayInt * - the new instance of DataArrayInt.
5865  *          The caller is to delete this result array using decrRef() as it is no more
5866  *          needed.
5867  * 
5868  *  \ref cpp_mcdataarrayint_invertarrayn2o2o2n "Here is a C++ example".
5869  *
5870  *  \ref py_mcdataarrayint_invertarrayn2o2o2n "Here is a Python example".
5871  */
5872 DataArrayInt *DataArrayInt::invertArrayN2O2O2N(int oldNbOfElem) const
5873 {
5874   checkAllocated();
5875   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
5876   ret->alloc(oldNbOfElem,1);
5877   const int *new2Old=getConstPointer();
5878   int *pt=ret->getPointer();
5879   std::fill(pt,pt+oldNbOfElem,-1);
5880   int nbOfNewElems=getNumberOfTuples();
5881   for(int i=0;i<nbOfNewElems;i++)
5882     pt[new2Old[i]]=i;
5883   return ret.retn();
5884 }
5885
5886 /*!
5887  * Equivalent to DataArrayInt::isEqual except that if false the reason of
5888  * mismatch is given.
5889  * 
5890  * \param [in] other the instance to be compared with \a this
5891  * \param [out] reason In case of inequality returns the reason.
5892  * \sa DataArrayInt::isEqual
5893  */
5894 bool DataArrayInt::isEqualIfNotWhy(const DataArrayInt& other, std::string& reason) const throw(INTERP_KERNEL::Exception)
5895 {
5896   if(!areInfoEqualsIfNotWhy(other,reason))
5897     return false;
5898   return _mem.isEqual(other._mem,0,reason);
5899 }
5900
5901 /*!
5902  * Checks if \a this and another DataArrayInt are fully equal. For more info see
5903  * \ref MEDCouplingArrayBasicsCompare.
5904  *  \param [in] other - an instance of DataArrayInt to compare with \a this one.
5905  *  \return bool - \a true if the two arrays are equal, \a false else.
5906  */
5907 bool DataArrayInt::isEqual(const DataArrayInt& other) const throw(INTERP_KERNEL::Exception)
5908 {
5909   std::string tmp;
5910   return isEqualIfNotWhy(other,tmp);
5911 }
5912
5913 /*!
5914  * Checks if values of \a this and another DataArrayInt are equal. For more info see
5915  * \ref MEDCouplingArrayBasicsCompare.
5916  *  \param [in] other - an instance of DataArrayInt to compare with \a this one.
5917  *  \return bool - \a true if the values of two arrays are equal, \a false else.
5918  */
5919 bool DataArrayInt::isEqualWithoutConsideringStr(const DataArrayInt& other) const throw(INTERP_KERNEL::Exception)
5920 {
5921   std::string tmp;
5922   return _mem.isEqual(other._mem,0,tmp);
5923 }
5924
5925 /*!
5926  * Checks if values of \a this and another DataArrayInt are equal. Comparison is
5927  * performed on sorted value sequences.
5928  * For more info see\ref MEDCouplingArrayBasicsCompare.
5929  *  \param [in] other - an instance of DataArrayInt to compare with \a this one.
5930  *  \return bool - \a true if the sorted values of two arrays are equal, \a false else.
5931  */
5932 bool DataArrayInt::isEqualWithoutConsideringStrAndOrder(const DataArrayInt& other) const throw(INTERP_KERNEL::Exception)
5933 {
5934   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> a=deepCpy();
5935   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> b=other.deepCpy();
5936   a->sort();
5937   b->sort();
5938   return a->isEqualWithoutConsideringStr(*b);
5939 }
5940
5941 /*!
5942  * Sorts values of the array.
5943  *  \param [in] asc - \a true means ascending order, \a false, descending.
5944  *  \throw If \a this is not allocated.
5945  *  \throw If \a this->getNumberOfComponents() != 1.
5946  */
5947 void DataArrayInt::sort(bool asc) throw(INTERP_KERNEL::Exception)
5948 {
5949   checkAllocated();
5950   if(getNumberOfComponents()!=1)
5951     throw INTERP_KERNEL::Exception("DataArrayInt::sort : only supported with 'this' array with ONE component !");
5952   _mem.sort(asc);
5953   declareAsNew();
5954 }
5955
5956 /*!
5957  * Reverse the array values.
5958  *  \throw If \a this->getNumberOfComponents() < 1.
5959  *  \throw If \a this is not allocated.
5960  */
5961 void DataArrayInt::reverse() throw(INTERP_KERNEL::Exception)
5962 {
5963   checkAllocated();
5964   _mem.reverse(getNumberOfComponents());
5965   declareAsNew();
5966 }
5967
5968 /*!
5969  * Checks that \a this array is consistently **increasing** or **decreasing** in value.
5970  * If not an exception is thrown.
5971  *  \param [in] increasing - if \a true, the array values should be increasing.
5972  *  \throw If sequence of values is not strictly monotonic in agreement with \a
5973  *         increasing arg.
5974  *  \throw If \a this->getNumberOfComponents() != 1.
5975  *  \throw If \a this is not allocated.
5976  */
5977 void DataArrayInt::checkMonotonic(bool increasing) const throw(INTERP_KERNEL::Exception)
5978 {
5979   if(!isMonotonic(increasing))
5980     {
5981       if (increasing)
5982         throw INTERP_KERNEL::Exception("DataArrayInt::checkMonotonic : 'this' is not INCREASING monotonic !");
5983       else
5984         throw INTERP_KERNEL::Exception("DataArrayInt::checkMonotonic : 'this' is not DECREASING monotonic !");
5985     }
5986 }
5987
5988 /*!
5989  * Checks that \a this array is consistently **increasing** or **decreasing** in value.
5990  *  \param [in] increasing - if \a true, array values should be increasing.
5991  *  \return bool - \a true if values change in accordance with \a increasing arg.
5992  *  \throw If \a this->getNumberOfComponents() != 1.
5993  *  \throw If \a this is not allocated.
5994  */
5995 bool DataArrayInt::isMonotonic(bool increasing) const throw(INTERP_KERNEL::Exception)
5996 {
5997   checkAllocated();
5998   if(getNumberOfComponents()!=1)
5999     throw INTERP_KERNEL::Exception("DataArrayInt::isMonotonic : only supported with 'this' array with ONE component !");
6000   int nbOfElements=getNumberOfTuples();
6001   const int *ptr=getConstPointer();
6002   if(nbOfElements==0)
6003     return true;
6004   int ref=ptr[0];
6005   if(increasing)
6006     {
6007       for(int i=1;i<nbOfElements;i++)
6008         {
6009           if(ptr[i]>=ref)
6010             ref=ptr[i];
6011           else
6012             return false;
6013         }
6014     }
6015   else
6016     {
6017       for(int i=1;i<nbOfElements;i++)
6018         {
6019           if(ptr[i]<=ref)
6020             ref=ptr[i];
6021           else
6022             return false;
6023         }
6024     }
6025   return true;
6026 }
6027
6028 /*!
6029  * This method check that array consistently INCREASING or DECREASING in value.
6030  */
6031 bool DataArrayInt::isStrictlyMonotonic(bool increasing) const throw(INTERP_KERNEL::Exception)
6032 {
6033   checkAllocated();
6034   if(getNumberOfComponents()!=1)
6035     throw INTERP_KERNEL::Exception("DataArrayInt::isStrictlyMonotonic : only supported with 'this' array with ONE component !");
6036   int nbOfElements=getNumberOfTuples();
6037   const int *ptr=getConstPointer();
6038   if(nbOfElements==0)
6039     return true;
6040   int ref=ptr[0];
6041   if(increasing)
6042     {
6043       for(int i=1;i<nbOfElements;i++)
6044         {
6045           if(ptr[i]>ref)
6046             ref=ptr[i];
6047           else
6048             return false;
6049         }
6050     }
6051   else
6052     {
6053       for(int i=1;i<nbOfElements;i++)
6054         {
6055           if(ptr[i]<ref)
6056             ref=ptr[i];
6057           else
6058             return false;
6059         }
6060     }
6061   return true;
6062 }
6063
6064 /*!
6065  * This method check that array consistently INCREASING or DECREASING in value.
6066  */
6067 void DataArrayInt::checkStrictlyMonotonic(bool increasing) const throw(INTERP_KERNEL::Exception)
6068 {
6069   if(!isStrictlyMonotonic(increasing))
6070     {
6071       if (increasing)
6072         throw INTERP_KERNEL::Exception("DataArrayInt::checkStrictlyMonotonic : 'this' is not strictly INCREASING monotonic !");
6073       else
6074         throw INTERP_KERNEL::Exception("DataArrayInt::checkStrictlyMonotonic : 'this' is not strictly DECREASING monotonic !");
6075     }
6076 }
6077
6078 /*!
6079  * Creates a new one-dimensional DataArrayInt of the same size as \a this and a given
6080  * one-dimensional arrays that must be of the same length. The result array describes
6081  * correspondence between \a this and \a other arrays, so that 
6082  * <em> other.getIJ(i,0) == this->getIJ(ret->getIJ(i),0)</em>. If such a permutation is
6083  * not possible because some element in \a other is not in \a this, an exception is thrown.
6084  *  \param [in] other - an array to compute permutation to.
6085  *  \return DataArrayInt * - a new instance of DataArrayInt, which is a permutation array
6086  * from \a this to \a other. The caller is to delete this array using decrRef() as it is
6087  * no more needed.
6088  *  \throw If \a this->getNumberOfComponents() != 1.
6089  *  \throw If \a other->getNumberOfComponents() != 1.
6090  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples().
6091  *  \throw If \a other includes a value which is not in \a this array.
6092  * 
6093  *  \ref cpp_mcdataarrayint_buildpermutationarr "Here is a C++ example".
6094  *
6095  *  \ref py_mcdataarrayint_buildpermutationarr "Here is a Python example".
6096  */
6097 DataArrayInt *DataArrayInt::buildPermutationArr(const DataArrayInt& other) const throw(INTERP_KERNEL::Exception)
6098 {
6099   checkAllocated();
6100   if(getNumberOfComponents()!=1 || other.getNumberOfComponents()!=1)
6101     throw INTERP_KERNEL::Exception("DataArrayInt::buildPermutationArr : 'this' and 'other' have to have exactly ONE component !");
6102   int nbTuple=getNumberOfTuples();
6103   other.checkAllocated();
6104   if(nbTuple!=other.getNumberOfTuples())
6105     throw INTERP_KERNEL::Exception("DataArrayInt::buildPermutationArr : 'this' and 'other' must have the same number of tuple !");
6106   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6107   ret->alloc(nbTuple,1);
6108   ret->fillWithValue(-1);
6109   const int *pt=getConstPointer();
6110   std::map<int,int> mm;
6111   for(int i=0;i<nbTuple;i++)
6112     mm[pt[i]]=i;
6113   pt=other.getConstPointer();
6114   int *retToFill=ret->getPointer();
6115   for(int i=0;i<nbTuple;i++)
6116     {
6117       std::map<int,int>::const_iterator it=mm.find(pt[i]);
6118       if(it==mm.end())
6119         {
6120           std::ostringstream oss; oss << "DataArrayInt::buildPermutationArr : Arrays mismatch : element (" << pt[i] << ") in 'other' not findable in 'this' !";
6121           throw INTERP_KERNEL::Exception(oss.str().c_str());
6122         }
6123       retToFill[i]=(*it).second;
6124     }
6125   return ret.retn();
6126 }
6127
6128 /*!
6129  * Sets a C array to be used as raw data of \a this. The previously set info
6130  *  of components is retained and re-sized. 
6131  * For more info see \ref MEDCouplingArraySteps1.
6132  *  \param [in] array - the C array to be used as raw data of \a this.
6133  *  \param [in] ownership - if \a true, \a array will be deallocated at destruction of \a this.
6134  *  \param [in] type - specifies how to deallocate \a array. If \a type == ParaMEDMEM::CPP_DEALLOC,
6135  *                     \c delete [] \c array; will be called. If \a type == ParaMEDMEM::C_DEALLOC,
6136  *                     \c free(\c array ) will be called.
6137  *  \param [in] nbOfTuple - new number of tuples in \a this.
6138  *  \param [in] nbOfCompo - new number of components in \a this.
6139  */
6140 void DataArrayInt::useArray(const int *array, bool ownership,  DeallocType type, int nbOfTuple, int nbOfCompo) throw(INTERP_KERNEL::Exception)
6141 {
6142   _info_on_compo.resize(nbOfCompo);
6143   _mem.useArray(array,ownership,type,nbOfTuple*nbOfCompo);
6144   declareAsNew();
6145 }
6146
6147 void DataArrayInt::useExternalArrayWithRWAccess(const int *array, int nbOfTuple, int nbOfCompo) throw(INTERP_KERNEL::Exception)
6148 {
6149   _info_on_compo.resize(nbOfCompo);
6150   _mem.useExternalArrayWithRWAccess(array,nbOfTuple*nbOfCompo);
6151   declareAsNew();
6152 }
6153
6154 /*!
6155  * Returns a new DataArrayInt holding the same values as \a this array but differently
6156  * arranged in memory. If \a this array holds 2 components of 3 values:
6157  * \f$ x_0,x_1,x_2,y_0,y_1,y_2 \f$, then the result array holds these values arranged
6158  * as follows: \f$ x_0,y_0,x_1,y_1,x_2,y_2 \f$.
6159  *  \warning Do not confuse this method with transpose()!
6160  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
6161  *          is to delete using decrRef() as it is no more needed.
6162  *  \throw If \a this is not allocated.
6163  */
6164 DataArrayInt *DataArrayInt::fromNoInterlace() const throw(INTERP_KERNEL::Exception)
6165 {
6166   checkAllocated();
6167   if(_mem.isNull())
6168     throw INTERP_KERNEL::Exception("DataArrayInt::fromNoInterlace : Not defined array !");
6169   int *tab=_mem.fromNoInterlace(getNumberOfComponents());
6170   DataArrayInt *ret=DataArrayInt::New();
6171   ret->useArray(tab,true,CPP_DEALLOC,getNumberOfTuples(),getNumberOfComponents());
6172   return ret;
6173 }
6174
6175 /*!
6176  * Returns a new DataArrayInt holding the same values as \a this array but differently
6177  * arranged in memory. If \a this array holds 2 components of 3 values:
6178  * \f$ x_0,y_0,x_1,y_1,x_2,y_2 \f$, then the result array holds these values arranged
6179  * as follows: \f$ x_0,x_1,x_2,y_0,y_1,y_2 \f$.
6180  *  \warning Do not confuse this method with transpose()!
6181  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
6182  *          is to delete using decrRef() as it is no more needed.
6183  *  \throw If \a this is not allocated.
6184  */
6185 DataArrayInt *DataArrayInt::toNoInterlace() const throw(INTERP_KERNEL::Exception)
6186 {
6187   checkAllocated();
6188   if(_mem.isNull())
6189     throw INTERP_KERNEL::Exception("DataArrayInt::toNoInterlace : Not defined array !");
6190   int *tab=_mem.toNoInterlace(getNumberOfComponents());
6191   DataArrayInt *ret=DataArrayInt::New();
6192   ret->useArray(tab,true,CPP_DEALLOC,getNumberOfTuples(),getNumberOfComponents());
6193   return ret;
6194 }
6195
6196 /*!
6197  * Permutes values of \a this array as required by \a old2New array. The values are
6198  * permuted so that \c new[ \a old2New[ i ]] = \c old[ i ]. Number of tuples remains
6199  * the same as in \this one.
6200  * If a permutation reduction is needed, substr() or selectByTupleId() should be used.
6201  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
6202  *  \param [in] old2New - C array of length equal to \a this->getNumberOfTuples()
6203  *     giving a new position for i-th old value.
6204  */
6205 void DataArrayInt::renumberInPlace(const int *old2New) throw(INTERP_KERNEL::Exception)
6206 {
6207   checkAllocated();
6208   int nbTuples=getNumberOfTuples();
6209   int nbOfCompo=getNumberOfComponents();
6210   int *tmp=new int[nbTuples*nbOfCompo];
6211   const int *iptr=getConstPointer();
6212   for(int i=0;i<nbTuples;i++)
6213     std::copy(iptr+nbOfCompo*i,iptr+nbOfCompo*(i+1),tmp+nbOfCompo*old2New[i]);
6214   std::copy(tmp,tmp+nbTuples*nbOfCompo,getPointer());
6215   delete [] tmp;
6216   declareAsNew();
6217 }
6218
6219 /*!
6220  * Permutes values of \a this array as required by \a new2Old array. The values are
6221  * permuted so that \c new[ i ] = \c old[ \a new2Old[ i ]]. Number of tuples remains
6222  * the same as in \this one.
6223  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
6224  *  \param [in] new2Old - C array of length equal to \a this->getNumberOfTuples()
6225  *     giving a previous position of i-th new value.
6226  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
6227  *          is to delete using decrRef() as it is no more needed.
6228  */
6229 void DataArrayInt::renumberInPlaceR(const int *new2Old) throw(INTERP_KERNEL::Exception)
6230 {
6231   checkAllocated();
6232   int nbTuples=getNumberOfTuples();
6233   int nbOfCompo=getNumberOfComponents();
6234   int *tmp=new int[nbTuples*nbOfCompo];
6235   const int *iptr=getConstPointer();
6236   for(int i=0;i<nbTuples;i++)
6237     std::copy(iptr+nbOfCompo*new2Old[i],iptr+nbOfCompo*(new2Old[i]+1),tmp+nbOfCompo*i);
6238   std::copy(tmp,tmp+nbTuples*nbOfCompo,getPointer());
6239   delete [] tmp;
6240   declareAsNew();
6241 }
6242
6243 /*!
6244  * Returns a copy of \a this array with values permuted as required by \a old2New array.
6245  * The values are permuted so that  \c new[ \a old2New[ i ]] = \c old[ i ].
6246  * Number of tuples in the result array remains the same as in \this one.
6247  * If a permutation reduction is needed, renumberAndReduce() should be used.
6248  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
6249  *  \param [in] old2New - C array of length equal to \a this->getNumberOfTuples()
6250  *          giving a new position for i-th old value.
6251  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
6252  *          is to delete using decrRef() as it is no more needed.
6253  *  \throw If \a this is not allocated.
6254  */
6255 DataArrayInt *DataArrayInt::renumber(const int *old2New) const throw(INTERP_KERNEL::Exception)
6256 {
6257   checkAllocated();
6258   int nbTuples=getNumberOfTuples();
6259   int nbOfCompo=getNumberOfComponents();
6260   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6261   ret->alloc(nbTuples,nbOfCompo);
6262   ret->copyStringInfoFrom(*this);
6263   const int *iptr=getConstPointer();
6264   int *optr=ret->getPointer();
6265   for(int i=0;i<nbTuples;i++)
6266     std::copy(iptr+nbOfCompo*i,iptr+nbOfCompo*(i+1),optr+nbOfCompo*old2New[i]);
6267   ret->copyStringInfoFrom(*this);
6268   return ret.retn();
6269 }
6270
6271 /*!
6272  * Returns a copy of \a this array with values permuted as required by \a new2Old array.
6273  * The values are permuted so that  \c new[ i ] = \c old[ \a new2Old[ i ]]. Number of
6274  * tuples in the result array remains the same as in \this one.
6275  * If a permutation reduction is needed, substr() or selectByTupleId() should be used.
6276  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
6277  *  \param [in] new2Old - C array of length equal to \a this->getNumberOfTuples()
6278  *     giving a previous position of i-th new value.
6279  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
6280  *          is to delete using decrRef() as it is no more needed.
6281  */
6282 DataArrayInt *DataArrayInt::renumberR(const int *new2Old) const throw(INTERP_KERNEL::Exception)
6283 {
6284   checkAllocated();
6285   int nbTuples=getNumberOfTuples();
6286   int nbOfCompo=getNumberOfComponents();
6287   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6288   ret->alloc(nbTuples,nbOfCompo);
6289   ret->copyStringInfoFrom(*this);
6290   const int *iptr=getConstPointer();
6291   int *optr=ret->getPointer();
6292   for(int i=0;i<nbTuples;i++)
6293     std::copy(iptr+nbOfCompo*new2Old[i],iptr+nbOfCompo*(new2Old[i]+1),optr+nbOfCompo*i);
6294   ret->copyStringInfoFrom(*this);
6295   return ret.retn();
6296 }
6297
6298 /*!
6299  * Returns a shorten and permuted copy of \a this array. The new DataArrayInt is
6300  * of size \a newNbOfTuple and it's values are permuted as required by \a old2New array.
6301  * The values are permuted so that  \c new[ \a old2New[ i ]] = \c old[ i ] for all
6302  * \a old2New[ i ] >= 0. In other words every i-th tuple in \a this array, for which 
6303  * \a old2New[ i ] is negative, is missing from the result array.
6304  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
6305  *  \param [in] old2New - C array of length equal to \a this->getNumberOfTuples()
6306  *     giving a new position for i-th old tuple and giving negative position for
6307  *     for i-th old tuple that should be omitted.
6308  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
6309  *          is to delete using decrRef() as it is no more needed.
6310  */
6311 DataArrayInt *DataArrayInt::renumberAndReduce(const int *old2New, int newNbOfTuple) const throw(INTERP_KERNEL::Exception)
6312 {
6313   checkAllocated();
6314   int nbTuples=getNumberOfTuples();
6315   int nbOfCompo=getNumberOfComponents();
6316   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6317   ret->alloc(newNbOfTuple,nbOfCompo);
6318   const int *iptr=getConstPointer();
6319   int *optr=ret->getPointer();
6320   for(int i=0;i<nbTuples;i++)
6321     {
6322       int w=old2New[i];
6323       if(w>=0)
6324         std::copy(iptr+i*nbOfCompo,iptr+(i+1)*nbOfCompo,optr+w*nbOfCompo);
6325     }
6326   ret->copyStringInfoFrom(*this);
6327   return ret.retn();
6328 }
6329
6330 /*!
6331  * Returns a shorten and permuted copy of \a this array. The new DataArrayInt is
6332  * of size \a new2OldEnd - \a new2OldBg and it's values are permuted as required by
6333  * \a new2OldBg array.
6334  * The values are permuted so that  \c new[ i ] = \c old[ \a new2OldBg[ i ]].
6335  * This method is equivalent to renumberAndReduce() except that convention in input is
6336  * \c new2old and \b not \c old2new.
6337  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
6338  *  \param [in] new2OldBg - pointer to the beginning of a permutation array that gives a
6339  *              tuple index in \a this array to fill the i-th tuple in the new array.
6340  *  \param [in] new2OldEnd - specifies the end of the permutation array that starts at
6341  *              \a new2OldBg, so that pointer to a tuple index (\a pi) varies as this:
6342  *              \a new2OldBg <= \a pi < \a new2OldEnd.
6343  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
6344  *          is to delete using decrRef() as it is no more needed.
6345  */
6346 DataArrayInt *DataArrayInt::selectByTupleId(const int *new2OldBg, const int *new2OldEnd) const
6347 {
6348   checkAllocated();
6349   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6350   int nbComp=getNumberOfComponents();
6351   ret->alloc((int)std::distance(new2OldBg,new2OldEnd),nbComp);
6352   ret->copyStringInfoFrom(*this);
6353   int *pt=ret->getPointer();
6354   const int *srcPt=getConstPointer();
6355   int i=0;
6356   for(const int *w=new2OldBg;w!=new2OldEnd;w++,i++)
6357     std::copy(srcPt+(*w)*nbComp,srcPt+((*w)+1)*nbComp,pt+i*nbComp);
6358   ret->copyStringInfoFrom(*this);
6359   return ret.retn();
6360 }
6361
6362 /*!
6363  * Returns a shorten and permuted copy of \a this array. The new DataArrayInt is
6364  * of size \a new2OldEnd - \a new2OldBg and it's values are permuted as required by
6365  * \a new2OldBg array.
6366  * The values are permuted so that  \c new[ i ] = \c old[ \a new2OldBg[ i ]].
6367  * This method is equivalent to renumberAndReduce() except that convention in input is
6368  * \c new2old and \b not \c old2new.
6369  * This method is equivalent to selectByTupleId() except that it prevents coping data
6370  * from behind the end of \a this array.
6371  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
6372  *  \param [in] new2OldBg - pointer to the beginning of a permutation array that gives a
6373  *              tuple index in \a this array to fill the i-th tuple in the new array.
6374  *  \param [in] new2OldEnd - specifies the end of the permutation array that starts at
6375  *              \a new2OldBg, so that pointer to a tuple index (\a pi) varies as this:
6376  *              \a new2OldBg <= \a pi < \a new2OldEnd.
6377  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
6378  *          is to delete using decrRef() as it is no more needed.
6379  *  \throw If \a new2OldEnd - \a new2OldBg > \a this->getNumberOfTuples().
6380  */
6381 DataArrayInt *DataArrayInt::selectByTupleIdSafe(const int *new2OldBg, const int *new2OldEnd) const throw(INTERP_KERNEL::Exception)
6382 {
6383   checkAllocated();
6384   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6385   int nbComp=getNumberOfComponents();
6386   int oldNbOfTuples=getNumberOfTuples();
6387   ret->alloc((int)std::distance(new2OldBg,new2OldEnd),nbComp);
6388   ret->copyStringInfoFrom(*this);
6389   int *pt=ret->getPointer();
6390   const int *srcPt=getConstPointer();
6391   int i=0;
6392   for(const int *w=new2OldBg;w!=new2OldEnd;w++,i++)
6393     if(*w>=0 && *w<oldNbOfTuples)
6394       std::copy(srcPt+(*w)*nbComp,srcPt+((*w)+1)*nbComp,pt+i*nbComp);
6395     else
6396       throw INTERP_KERNEL::Exception("DataArrayInt::selectByTupleIdSafe : some ids has been detected to be out of [0,this->getNumberOfTuples) !");
6397   ret->copyStringInfoFrom(*this);
6398   return ret.retn();
6399 }
6400
6401 /*!
6402  * Returns a shorten copy of \a this array. The new DataArrayInt contains every
6403  * (\a bg + \c i * \a step)-th tuple of \a this array located before the \a end2-th
6404  * tuple. Indices of the selected tuples are the same as ones returned by the Python
6405  * command \c range( \a bg, \a end2, \a step ).
6406  * This method is equivalent to selectByTupleIdSafe() except that the input array is
6407  * not constructed explicitly.
6408  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
6409  *  \param [in] bg - index of the first tuple to copy from \a this array.
6410  *  \param [in] end2 - index of the tuple before which the tuples to copy are located.
6411  *  \param [in] step - index increment to get index of the next tuple to copy.
6412  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
6413  *          is to delete using decrRef() as it is no more needed.
6414  *  \sa DataArrayInt::substr.
6415  */
6416 DataArrayInt *DataArrayInt::selectByTupleId2(int bg, int end2, int step) const throw(INTERP_KERNEL::Exception)
6417 {
6418   checkAllocated();
6419   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6420   int nbComp=getNumberOfComponents();
6421   int newNbOfTuples=GetNumberOfItemGivenBESRelative(bg,end2,step,"DataArrayInt::selectByTupleId2 : ");
6422   ret->alloc(newNbOfTuples,nbComp);
6423   int *pt=ret->getPointer();
6424   const int *srcPt=getConstPointer()+bg*nbComp;
6425   for(int i=0;i<newNbOfTuples;i++,srcPt+=step*nbComp)
6426     std::copy(srcPt,srcPt+nbComp,pt+i*nbComp);
6427   ret->copyStringInfoFrom(*this);
6428   return ret.retn();
6429 }
6430
6431 /*!
6432  * Returns a shorten copy of \a this array. The new DataArrayInt contains ranges
6433  * of tuples specified by \a ranges parameter.
6434  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
6435  *  \param [in] ranges - std::vector of std::pair's each of which defines a range
6436  *              of tuples in [\c begin,\c end) format.
6437  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
6438  *          is to delete using decrRef() as it is no more needed.
6439  *  \throw If \a end < \a begin.
6440  *  \throw If \a end > \a this->getNumberOfTuples().
6441  *  \throw If \a this is not allocated.
6442  */
6443 DataArrayInt *DataArrayInt::selectByTupleRanges(const std::vector<std::pair<int,int> >& ranges) const throw(INTERP_KERNEL::Exception)
6444 {
6445   checkAllocated();
6446   int nbOfComp=getNumberOfComponents();
6447   int nbOfTuplesThis=getNumberOfTuples();
6448   if(ranges.empty())
6449     {
6450       MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6451       ret->alloc(0,nbOfComp);
6452       ret->copyStringInfoFrom(*this);
6453       return ret.retn();
6454     }
6455   int ref=ranges.front().first;
6456   int nbOfTuples=0;
6457   bool isIncreasing=true;
6458   for(std::vector<std::pair<int,int> >::const_iterator it=ranges.begin();it!=ranges.end();it++)
6459     {
6460       if((*it).first<=(*it).second)
6461         {
6462           if((*it).first>=0 && (*it).second<=nbOfTuplesThis)
6463             {
6464               nbOfTuples+=(*it).second-(*it).first;
6465               if(isIncreasing)
6466                 isIncreasing=ref<=(*it).first;
6467               ref=(*it).second;
6468             }
6469           else
6470             {
6471               std::ostringstream oss; oss << "DataArrayInt::selectByTupleRanges : on range #" << std::distance(ranges.begin(),it);
6472               oss << " (" << (*it).first << "," << (*it).second << ") is greater than number of tuples of this :" << nbOfTuples << " !";
6473               throw INTERP_KERNEL::Exception(oss.str().c_str());
6474             }
6475         }
6476       else
6477         {
6478           std::ostringstream oss; oss << "DataArrayInt::selectByTupleRanges : on range #" << std::distance(ranges.begin(),it);
6479           oss << " (" << (*it).first << "," << (*it).second << ") end is before begin !";
6480           throw INTERP_KERNEL::Exception(oss.str().c_str());
6481         }
6482     }
6483   if(isIncreasing && nbOfTuplesThis==nbOfTuples)
6484     return deepCpy();
6485   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6486   ret->alloc(nbOfTuples,nbOfComp);
6487   ret->copyStringInfoFrom(*this);
6488   const int *src=getConstPointer();
6489   int *work=ret->getPointer();
6490   for(std::vector<std::pair<int,int> >::const_iterator it=ranges.begin();it!=ranges.end();it++)
6491     work=std::copy(src+(*it).first*nbOfComp,src+(*it).second*nbOfComp,work);
6492   return ret.retn();
6493 }
6494
6495 /*!
6496  * Returns a new DataArrayInt containing a renumbering map in "Old to New" mode.
6497  * This map, if applied to \a this array, would make it sorted. For example, if
6498  * \a this array contents are [9,10,0,6,4,11,3,7] then the contents of the result array
6499  * are [5,6,0,3,2,7,1,4]; if this result array (\a res) is used as an argument in call
6500  * \a this->renumber(\a res) then the returned array contains [0,3,4,6,7,9,10,11].
6501  * This method is useful for renumbering (in MED file for example). For more info
6502  * on renumbering see \ref MEDCouplingArrayRenumbering.
6503  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
6504  *          array using decrRef() as it is no more needed.
6505  *  \throw If \a this is not allocated.
6506  *  \throw If \a this->getNumberOfComponents() != 1.
6507  *  \throw If there are equal values in \a this array.
6508  */
6509 DataArrayInt *DataArrayInt::checkAndPreparePermutation() const throw(INTERP_KERNEL::Exception)
6510 {
6511   checkAllocated();
6512   if(getNumberOfComponents()!=1)
6513     throw INTERP_KERNEL::Exception("DataArrayInt::checkAndPreparePermutation : number of components must == 1 !");
6514   int nbTuples=getNumberOfTuples();
6515   const int *pt=getConstPointer();
6516   int *pt2=CheckAndPreparePermutation(pt,pt+nbTuples);
6517   DataArrayInt *ret=DataArrayInt::New();
6518   ret->useArray(pt2,true,CPP_DEALLOC,nbTuples,1);
6519   return ret;
6520 }
6521
6522 /*!
6523  * Returns two arrays describing a surjective mapping from \a this set of values (\a A)
6524  * onto a set of values of size \a targetNb (\a B). The surjective function is 
6525  * \a B[ \a A[ i ]] = i. That is to say that for each \a id in [0,\a targetNb), where \a
6526  * targetNb < \a this->getNumberOfTuples(), there exists at least one tupleId (\a tid) so
6527  * that <em> this->getIJ( tid, 0 ) == id</em>. <br>
6528  * The first of out arrays returns indices of elements of \a this array, grouped by their
6529  * place in the set \a B. The second out array is the index of the first one; it shows how
6530  * many elements of \a A are mapped into each element of \a B. <br>
6531  * For more info on
6532  * mapping and its usage in renumbering see \ref MEDCouplingArrayRenumbering. <br>
6533  * \b Example:
6534  * - \a this: [0,3,2,3,2,2,1,2]
6535  * - \a targetNb: 4
6536  * - \a arr:  [0,  6,  2,4,5,7,  1,3]
6537  * - \a arrI: [0,1,2,6,8]
6538  *
6539  * This result means: <br>
6540  * the element of \a B 0 encounters within \a A once (\a arrI[ 0+1 ] - \a arrI[ 0 ]) and
6541  * its index within \a A is 0 ( \a arr[ 0:1 ] == \a arr[ \a arrI[ 0 ] : \a arrI[ 0+1 ]]);<br>
6542  * the element of \a B 2 encounters within \a A 4 times (\a arrI[ 2+1 ] - \a arrI[ 2 ]) and
6543  * its indices within \a A are [2,4,5,7] ( \a arr[ 2:6 ] == \a arr[ \a arrI[ 2 ] : 
6544  * \a arrI[ 2+1 ]]); <br> etc.
6545  *  \param [in] targetNb - the size of the set \a B. \a targetNb must be equal or more
6546  *         than the maximal value of \a A.
6547  *  \param [out] arr - a new instance of DataArrayInt returning indices of
6548  *         elements of \a this, grouped by their place in the set \a B. The caller is to delete
6549  *         this array using decrRef() as it is no more needed.
6550  *  \param [out] arrI - a new instance of DataArrayInt returning size of groups of equal
6551  *         elements of \a this. The caller is to delete this array using decrRef() as it
6552  *         is no more needed.
6553  *  \throw If \a this is not allocated.
6554  *  \throw If \a this->getNumberOfComponents() != 1.
6555  *  \throw If any value in \a this is more or equal to \a targetNb.
6556  */
6557 void DataArrayInt::changeSurjectiveFormat(int targetNb, DataArrayInt *&arr, DataArrayInt *&arrI) const throw(INTERP_KERNEL::Exception)
6558 {
6559   checkAllocated();
6560   if(getNumberOfComponents()!=1)
6561     throw INTERP_KERNEL::Exception("DataArrayInt::changeSurjectiveFormat : number of components must == 1 !");
6562   int nbOfTuples=getNumberOfTuples();
6563   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New());
6564   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> retI(DataArrayInt::New());
6565   retI->alloc(targetNb+1,1);
6566   const int *input=getConstPointer();
6567   std::vector< std::vector<int> > tmp(targetNb);
6568   for(int i=0;i<nbOfTuples;i++)
6569     {
6570       int tmp2=input[i];
6571       if(tmp2>=0 && tmp2<targetNb)
6572         tmp[tmp2].push_back(i);
6573       else
6574         {
6575           std::ostringstream oss; oss << "DataArrayInt::changeSurjectiveFormat : At pos " << i << " presence of element " << tmp2 << " ! should be in [0," << targetNb << ") !";
6576           throw INTERP_KERNEL::Exception(oss.str().c_str());
6577         }
6578     }
6579   int *retIPtr=retI->getPointer();
6580   *retIPtr=0;
6581   for(std::vector< std::vector<int> >::const_iterator it1=tmp.begin();it1!=tmp.end();it1++,retIPtr++)
6582     retIPtr[1]=retIPtr[0]+(int)((*it1).size());
6583   if(nbOfTuples!=retI->getIJ(targetNb,0))
6584     throw INTERP_KERNEL::Exception("DataArrayInt::changeSurjectiveFormat : big problem should never happen !");
6585   ret->alloc(nbOfTuples,1);
6586   int *retPtr=ret->getPointer();
6587   for(std::vector< std::vector<int> >::const_iterator it1=tmp.begin();it1!=tmp.end();it1++)
6588     retPtr=std::copy((*it1).begin(),(*it1).end(),retPtr);
6589   arr=ret.retn();
6590   arrI=retI.retn();
6591 }
6592
6593
6594 /*!
6595  * Returns a new DataArrayInt containing a renumbering map in "Old to New" mode computed
6596  * from a zip representation of a surjective format (returned e.g. by
6597  * \ref ParaMEDMEM::DataArrayDouble::findCommonTuples() "DataArrayDouble::findCommonTuples()"
6598  * for example). The result array minimizes the permutation. <br>
6599  * For more info on renumbering see \ref MEDCouplingArrayRenumbering. <br>
6600  * \b Example: <br>
6601  * - \a nbOfOldTuples: 10 
6602  * - \a arr          : [0,3, 5,7,9]
6603  * - \a arrIBg       : [0,2,5]
6604  * - \a newNbOfTuples: 7
6605  * - result array    : [0,1,2,0,3,4,5,4,6,4]
6606  *
6607  *  \param [in] nbOfOldTuples - number of tuples in the initial array \a arr.
6608  *  \param [in] arr - the array of tuple indices grouped by \a arrIBg array.
6609  *  \param [in] arrIBg - the array dividing all indices stored in \a arr into groups of
6610  *         (indices of) equal values. Its every element (except the last one) points to
6611  *         the first element of a group of equal values.
6612  *  \param [in] arrIEnd - specifies the end of \a arrIBg, so that the last element of \a
6613  *          arrIBg is \a arrIEnd[ -1 ].
6614  *  \param [out] newNbOfTuples - number of tuples after surjection application.
6615  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
6616  *          array using decrRef() as it is no more needed.
6617  *  \throw If any value of \a arr breaks condition ( 0 <= \a arr[ i ] < \a nbOfOldTuples ).
6618  */
6619 DataArrayInt *DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2(int nbOfOldTuples, const int *arr, const int *arrIBg, const int *arrIEnd, int &newNbOfTuples) throw(INTERP_KERNEL::Exception)
6620 {
6621   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6622   ret->alloc(nbOfOldTuples,1);
6623   int *pt=ret->getPointer();
6624   std::fill(pt,pt+nbOfOldTuples,-1);
6625   int nbOfGrps=((int)std::distance(arrIBg,arrIEnd))-1;
6626   const int *cIPtr=arrIBg;
6627   for(int i=0;i<nbOfGrps;i++)
6628     pt[arr[cIPtr[i]]]=-(i+2);
6629   int newNb=0;
6630   for(int iNode=0;iNode<nbOfOldTuples;iNode++)
6631     {
6632       if(pt[iNode]<0)
6633         {
6634           if(pt[iNode]==-1)
6635             pt[iNode]=newNb++;
6636           else
6637             {
6638               int grpId=-(pt[iNode]+2);
6639               for(int j=cIPtr[grpId];j<cIPtr[grpId+1];j++)
6640                 {
6641                   if(arr[j]>=0 && arr[j]<nbOfOldTuples)
6642                     pt[arr[j]]=newNb;
6643                   else
6644                     {
6645                       std::ostringstream oss; oss << "DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2 : With element #" << j << " value is " << arr[j] << " should be in [0," << nbOfOldTuples << ") !";
6646                       throw INTERP_KERNEL::Exception(oss.str().c_str());
6647                     }
6648                 }
6649               newNb++;
6650             }
6651         }
6652     }
6653   newNbOfTuples=newNb;
6654   return ret.retn();
6655 }
6656
6657 /*!
6658  * Returns a new DataArrayInt containing a renumbering map in "New to Old" mode,
6659  * which if applied to \a this array would make it sorted ascendingly.
6660  * For more info on renumbering see \ref MEDCouplingArrayRenumbering. <br>
6661  * \b Example: <br>
6662  * - \a this: [2,0,1,1,0,1,2,0,1,1,0,0]
6663  * - result: [10,0,5,6,1,7,11,2,8,9,3,4]
6664  * - after applying result to \a this: [0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2] 
6665  *
6666  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
6667  *          array using decrRef() as it is no more needed.
6668  *  \throw If \a this is not allocated.
6669  *  \throw If \a this->getNumberOfComponents() != 1.
6670  */
6671 DataArrayInt *DataArrayInt::buildPermArrPerLevel() const throw(INTERP_KERNEL::Exception)
6672 {
6673   checkAllocated();
6674   if(getNumberOfComponents()!=1)
6675     throw INTERP_KERNEL::Exception("DataArrayInt::buildPermArrPerLevel : number of components must == 1 !");
6676   int nbOfTuples=getNumberOfTuples();
6677   const int *pt=getConstPointer();
6678   std::map<int,int> m;
6679   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6680   ret->alloc(nbOfTuples,1);
6681   int *opt=ret->getPointer();
6682   for(int i=0;i<nbOfTuples;i++,pt++,opt++)
6683     {
6684       int val=*pt;
6685       std::map<int,int>::iterator it=m.find(val);
6686       if(it!=m.end())
6687         {
6688           *opt=(*it).second;
6689           (*it).second++;
6690         }
6691       else
6692         {
6693           *opt=0;
6694           m.insert(std::pair<int,int>(val,1));
6695         }
6696     }
6697   int sum=0;
6698   for(std::map<int,int>::iterator it=m.begin();it!=m.end();it++)
6699     {
6700       int vt=(*it).second;
6701       (*it).second=sum;
6702       sum+=vt;
6703     }
6704   pt=getConstPointer();
6705   opt=ret->getPointer();
6706   for(int i=0;i<nbOfTuples;i++,pt++,opt++)
6707     *opt+=m[*pt];
6708   //
6709   return ret.retn();
6710 }
6711
6712 /*!
6713  * Checks if contents of \a this array are equal to that of an array filled with
6714  * iota(). This method is particularly useful for DataArrayInt instances that represent
6715  * a renumbering array to check the real need in renumbering. 
6716  *  \return bool - \a true if \a this array contents == \a range( \a this->getNumberOfTuples())
6717  *  \throw If \a this is not allocated.
6718  *  \throw If \a this->getNumberOfComponents() != 1.
6719  */
6720 bool DataArrayInt::isIdentity() const throw(INTERP_KERNEL::Exception)
6721 {
6722   checkAllocated();
6723   if(getNumberOfComponents()!=1)
6724     return false;
6725   int nbOfTuples=getNumberOfTuples();
6726   const int *pt=getConstPointer();
6727   for(int i=0;i<nbOfTuples;i++,pt++)
6728     if(*pt!=i)
6729       return false;
6730   return true;
6731 }
6732
6733 /*!
6734  * Checks if all values in \a this array are equal to \a val.
6735  *  \param [in] val - value to check equality of array values to.
6736  *  \return bool - \a true if all values are \a val.
6737  *  \throw If \a this is not allocated.
6738  *  \throw If \a this->getNumberOfComponents() != 1
6739  */
6740 bool DataArrayInt::isUniform(int val) const throw(INTERP_KERNEL::Exception)
6741 {
6742   checkAllocated();
6743   if(getNumberOfComponents()!=1)
6744     throw INTERP_KERNEL::Exception("DataArrayInt::isUniform : must be applied on DataArrayInt with only one component, you can call 'rearrange' method before !");
6745   int nbOfTuples=getNumberOfTuples();
6746   const int *w=getConstPointer();
6747   const int *end2=w+nbOfTuples;
6748   for(;w!=end2;w++)
6749     if(*w!=val)
6750       return false;
6751   return true;
6752 }
6753
6754 /*!
6755  * Creates a new DataArrayDouble and assigns all (textual and numerical) data of \a this
6756  * array to the new one.
6757  *  \return DataArrayDouble * - the new instance of DataArrayInt.
6758  */
6759 DataArrayDouble *DataArrayInt::convertToDblArr() const
6760 {
6761   checkAllocated();
6762   DataArrayDouble *ret=DataArrayDouble::New();
6763   ret->alloc(getNumberOfTuples(),getNumberOfComponents());
6764   std::size_t nbOfVals=getNbOfElems();
6765   const int *src=getConstPointer();
6766   double *dest=ret->getPointer();
6767   std::copy(src,src+nbOfVals,dest);
6768   ret->copyStringInfoFrom(*this);
6769   return ret;
6770 }
6771
6772 /*!
6773  * Returns a shorten copy of \a this array. The new DataArrayInt contains all
6774  * tuples starting from the \a tupleIdBg-th tuple and including all tuples located before
6775  * the \a tupleIdEnd-th one. This methods has a similar behavior as std::string::substr().
6776  * This method is a specialization of selectByTupleId2().
6777  *  \param [in] tupleIdBg - index of the first tuple to copy from \a this array.
6778  *  \param [in] tupleIdEnd - index of the tuple before which the tuples to copy are located.
6779  *          If \a tupleIdEnd == -1, all the tuples till the end of \a this array are copied.
6780  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
6781  *          is to delete using decrRef() as it is no more needed.
6782  *  \throw If \a tupleIdBg < 0.
6783  *  \throw If \a tupleIdBg > \a this->getNumberOfTuples().
6784     \throw If \a tupleIdEnd != -1 && \a tupleIdEnd < \a this->getNumberOfTuples().
6785  *  \sa DataArrayInt::selectByTupleId2
6786  */
6787 DataArrayInt *DataArrayInt::substr(int tupleIdBg, int tupleIdEnd) const throw(INTERP_KERNEL::Exception)
6788 {
6789   checkAllocated();
6790   int nbt=getNumberOfTuples();
6791   if(tupleIdBg<0)
6792     throw INTERP_KERNEL::Exception("DataArrayInt::substr : The tupleIdBg parameter must be greater than 0 !");
6793   if(tupleIdBg>nbt)
6794     throw INTERP_KERNEL::Exception("DataArrayInt::substr : The tupleIdBg parameter is greater than number of tuples !");
6795   int trueEnd=tupleIdEnd;
6796   if(tupleIdEnd!=-1)
6797     {
6798       if(tupleIdEnd>nbt)
6799         throw INTERP_KERNEL::Exception("DataArrayInt::substr : The tupleIdBg parameter is greater or equal than number of tuples !");
6800     }
6801   else
6802     trueEnd=nbt;
6803   int nbComp=getNumberOfComponents();
6804   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6805   ret->alloc(trueEnd-tupleIdBg,nbComp);
6806   ret->copyStringInfoFrom(*this);
6807   std::copy(getConstPointer()+tupleIdBg*nbComp,getConstPointer()+trueEnd*nbComp,ret->getPointer());
6808   return ret.retn();
6809 }
6810
6811 /*!
6812  * Changes the number of components within \a this array so that its raw data **does
6813  * not** change, instead splitting this data into tuples changes.
6814  *  \warning This method erases all (name and unit) component info set before!
6815  *  \param [in] newNbOfComp - number of components for \a this array to have.
6816  *  \throw If \a this is not allocated
6817  *  \throw If getNbOfElems() % \a newNbOfCompo != 0.
6818  *  \throw If \a newNbOfCompo is lower than 1.
6819  *  \throw If the rearrange method would lead to a number of tuples higher than 2147483647 (maximal capacity of int32 !).
6820  *  \warning This method erases all (name and unit) component info set before!
6821  */
6822 void DataArrayInt::rearrange(int newNbOfCompo) throw(INTERP_KERNEL::Exception)
6823 {
6824   checkAllocated();
6825   if(newNbOfCompo<1)
6826     throw INTERP_KERNEL::Exception("DataArrayInt::rearrange : input newNbOfCompo must be > 0 !");
6827   std::size_t nbOfElems=getNbOfElems();
6828   if(nbOfElems%newNbOfCompo!=0)
6829     throw INTERP_KERNEL::Exception("DataArrayInt::rearrange : nbOfElems%newNbOfCompo!=0 !");
6830   if(nbOfElems/newNbOfCompo>(std::size_t)std::numeric_limits<int>::max())
6831     throw INTERP_KERNEL::Exception("DataArrayInt::rearrange : the rearrangement leads to too high number of tuples (> 2147483647) !");
6832   _info_on_compo.clear();
6833   _info_on_compo.resize(newNbOfCompo);
6834   declareAsNew();
6835 }
6836
6837 /*!
6838  * Changes the number of components within \a this array to be equal to its number
6839  * of tuples, and inversely its number of tuples to become equal to its number of 
6840  * components. So that its raw data **does not** change, instead splitting this
6841  * data into tuples changes.
6842  *  \warning This method erases all (name and unit) component info set before!
6843  *  \warning Do not confuse this method with fromNoInterlace() and toNoInterlace()!
6844  *  \throw If \a this is not allocated.
6845  *  \sa rearrange()
6846  */
6847 void DataArrayInt::transpose() throw(INTERP_KERNEL::Exception)
6848 {
6849   checkAllocated();
6850   int nbOfTuples=getNumberOfTuples();
6851   rearrange(nbOfTuples);
6852 }
6853
6854 /*!
6855  * Returns a shorten or extended copy of \a this array. If \a newNbOfComp is less
6856  * than \a this->getNumberOfComponents() then the result array is shorten as each tuple
6857  * is truncated to have \a newNbOfComp components, keeping first components. If \a
6858  * newNbOfComp is more than \a this->getNumberOfComponents() then the result array is
6859  * expanded as each tuple is populated with \a dftValue to have \a newNbOfComp
6860  * components.  
6861  *  \param [in] newNbOfComp - number of components for the new array to have.
6862  *  \param [in] dftValue - value assigned to new values added to the new array.
6863  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
6864  *          is to delete using decrRef() as it is no more needed.
6865  *  \throw If \a this is not allocated.
6866  */
6867 DataArrayInt *DataArrayInt::changeNbOfComponents(int newNbOfComp, int dftValue) const throw(INTERP_KERNEL::Exception)
6868 {
6869   checkAllocated();
6870   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6871   ret->alloc(getNumberOfTuples(),newNbOfComp);
6872   const int *oldc=getConstPointer();
6873   int *nc=ret->getPointer();
6874   int nbOfTuples=getNumberOfTuples();
6875   int oldNbOfComp=getNumberOfComponents();
6876   int dim=std::min(oldNbOfComp,newNbOfComp);
6877   for(int i=0;i<nbOfTuples;i++)
6878     {
6879       int j=0;
6880       for(;j<dim;j++)
6881         nc[newNbOfComp*i+j]=oldc[i*oldNbOfComp+j];
6882       for(;j<newNbOfComp;j++)
6883         nc[newNbOfComp*i+j]=dftValue;
6884     }
6885   ret->setName(getName().c_str());
6886   for(int i=0;i<dim;i++)
6887     ret->setInfoOnComponent(i,getInfoOnComponent(i).c_str());
6888   ret->setName(getName().c_str());
6889   return ret.retn();
6890 }
6891
6892 /*!
6893  * Changes number of tuples in the array. If the new number of tuples is smaller
6894  * than the current number the array is truncated, otherwise the array is extended.
6895  *  \param [in] nbOfTuples - new number of tuples. 
6896  *  \throw If \a this is not allocated.
6897  */
6898 void DataArrayInt::reAlloc(int nbOfTuples) throw(INTERP_KERNEL::Exception)
6899 {
6900   checkAllocated();
6901   _mem.reAlloc(getNumberOfComponents()*(std::size_t)nbOfTuples);
6902   declareAsNew();
6903 }
6904
6905
6906 /*!
6907  * Returns a copy of \a this array composed of selected components.
6908  * The new DataArrayInt has the same number of tuples but includes components
6909  * specified by \a compoIds parameter. So that getNbOfElems() of the result array
6910  * can be either less, same or more than \a this->getNbOfElems().
6911  *  \param [in] compoIds - sequence of zero based indices of components to include
6912  *              into the new array.
6913  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
6914  *          is to delete using decrRef() as it is no more needed.
6915  *  \throw If \a this is not allocated.
6916  *  \throw If a component index (\a i) is not valid: 
6917  *         \a i < 0 || \a i >= \a this->getNumberOfComponents().
6918  *
6919  *  \ref py_mcdataarrayint_keepselectedcomponents "Here is a Python example".
6920  */
6921 DataArrayInt *DataArrayInt::keepSelectedComponents(const std::vector<int>& compoIds) const throw(INTERP_KERNEL::Exception)
6922 {
6923   checkAllocated();
6924   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New());
6925   int newNbOfCompo=(int)compoIds.size();
6926   int oldNbOfCompo=getNumberOfComponents();
6927   for(std::vector<int>::const_iterator it=compoIds.begin();it!=compoIds.end();it++)
6928     DataArray::CheckValueInRange(oldNbOfCompo,(*it),"keepSelectedComponents invalid requested component");
6929   int nbOfTuples=getNumberOfTuples();
6930   ret->alloc(nbOfTuples,newNbOfCompo);
6931   ret->copyPartOfStringInfoFrom(*this,compoIds);
6932   const int *oldc=getConstPointer();
6933   int *nc=ret->getPointer();
6934   for(int i=0;i<nbOfTuples;i++)
6935     for(int j=0;j<newNbOfCompo;j++,nc++)
6936       *nc=oldc[i*oldNbOfCompo+compoIds[j]];
6937   return ret.retn();
6938 }
6939
6940 /*!
6941  * Appends components of another array to components of \a this one, tuple by tuple.
6942  * So that the number of tuples of \a this array remains the same and the number of 
6943  * components increases.
6944  *  \param [in] other - the DataArrayInt to append to \a this one.
6945  *  \throw If \a this is not allocated.
6946  *  \throw If \a this and \a other arrays have different number of tuples.
6947  *
6948  *  \ref cpp_mcdataarrayint_meldwith "Here is a C++ example".
6949  *
6950  *  \ref py_mcdataarrayint_meldwith "Here is a Python example".
6951  */
6952 void DataArrayInt::meldWith(const DataArrayInt *other) throw(INTERP_KERNEL::Exception)
6953 {
6954   if(!other)
6955     throw INTERP_KERNEL::Exception("DataArrayInt::meldWith : DataArrayInt pointer in input is NULL !");
6956   checkAllocated();
6957   other->checkAllocated();
6958   int nbOfTuples=getNumberOfTuples();
6959   if(nbOfTuples!=other->getNumberOfTuples())
6960     throw INTERP_KERNEL::Exception("DataArrayInt::meldWith : mismatch of number of tuples !");
6961   int nbOfComp1=getNumberOfComponents();
6962   int nbOfComp2=other->getNumberOfComponents();
6963   int *newArr=new int[nbOfTuples*(nbOfComp1+nbOfComp2)];
6964   int *w=newArr;
6965   const int *inp1=getConstPointer();
6966   const int *inp2=other->getConstPointer();
6967   for(int i=0;i<nbOfTuples;i++,inp1+=nbOfComp1,inp2+=nbOfComp2)
6968     {
6969       w=std::copy(inp1,inp1+nbOfComp1,w);
6970       w=std::copy(inp2,inp2+nbOfComp2,w);
6971     }
6972   useArray(newArr,true,CPP_DEALLOC,nbOfTuples,nbOfComp1+nbOfComp2);
6973   std::vector<int> compIds(nbOfComp2);
6974   for(int i=0;i<nbOfComp2;i++)
6975     compIds[i]=nbOfComp1+i;
6976   copyPartOfStringInfoFrom2(compIds,*other);
6977 }
6978
6979 /*!
6980  * Copy all components in a specified order from another DataArrayInt.
6981  * The specified components become the first ones in \a this array.
6982  * Both numerical and textual data is copied. The number of tuples in \a this and
6983  * the other array can be different.
6984  *  \param [in] a - the array to copy data from.
6985  *  \param [in] compoIds - sequence of zero based indices of components, data of which is
6986  *              to be copied.
6987  *  \throw If \a a is NULL.
6988  *  \throw If \a compoIds.size() != \a a->getNumberOfComponents().
6989  *  \throw If \a compoIds[i] < 0 or \a compoIds[i] > \a this->getNumberOfComponents().
6990  *
6991  *  \ref py_mcdataarrayint_setselectedcomponents "Here is a Python example".
6992  */
6993 void DataArrayInt::setSelectedComponents(const DataArrayInt *a, const std::vector<int>& compoIds) throw(INTERP_KERNEL::Exception)
6994 {
6995   if(!a)
6996     throw INTERP_KERNEL::Exception("DataArrayInt::setSelectedComponents : input DataArrayInt is NULL !");
6997   checkAllocated();
6998   a->checkAllocated();
6999   copyPartOfStringInfoFrom2(compoIds,*a);
7000   std::size_t partOfCompoSz=compoIds.size();
7001   int nbOfCompo=getNumberOfComponents();
7002   int nbOfTuples=std::min(getNumberOfTuples(),a->getNumberOfTuples());
7003   const int *ac=a->getConstPointer();
7004   int *nc=getPointer();
7005   for(int i=0;i<nbOfTuples;i++)
7006     for(std::size_t j=0;j<partOfCompoSz;j++,ac++)
7007       nc[nbOfCompo*i+compoIds[j]]=*ac;
7008 }
7009
7010 /*!
7011  * Copy all values from another DataArrayInt into specified tuples and components
7012  * of \a this array. Textual data is not copied.
7013  * The tree parameters defining set of indices of tuples and components are similar to
7014  * the tree parameters of the Python function \c range(\c start,\c stop,\c step).
7015  *  \param [in] a - the array to copy values from.
7016  *  \param [in] bgTuples - index of the first tuple of \a this array to assign values to.
7017  *  \param [in] endTuples - index of the tuple before which the tuples to assign to
7018  *              are located.
7019  *  \param [in] stepTuples - index increment to get index of the next tuple to assign to.
7020  *  \param [in] bgComp - index of the first component of \a this array to assign values to.
7021  *  \param [in] endComp - index of the component before which the components to assign
7022  *              to are located.
7023  *  \param [in] stepComp - index increment to get index of the next component to assign to.
7024  *  \param [in] strictCompoCompare - if \a true (by default), then \a a->getNumberOfComponents() 
7025  *              must be equal to the number of columns to assign to, else an
7026  *              exception is thrown; if \a false, then it is only required that \a
7027  *              a->getNbOfElems() equals to number of values to assign to (this condition
7028  *              must be respected even if \a strictCompoCompare is \a true). The number of 
7029  *              values to assign to is given by following Python expression:
7030  *              \a nbTargetValues = 
7031  *              \c len(\c range(\a bgTuples,\a endTuples,\a stepTuples)) *
7032  *              \c len(\c range(\a bgComp,\a endComp,\a stepComp)).
7033  *  \throw If \a a is NULL.
7034  *  \throw If \a a is not allocated.
7035  *  \throw If \a this is not allocated.
7036  *  \throw If parameters specifying tuples and components to assign to do not give a
7037  *            non-empty range of increasing indices.
7038  *  \throw If \a a->getNbOfElems() != \a nbTargetValues.
7039  *  \throw If \a strictCompoCompare == \a true && \a a->getNumberOfComponents() !=
7040  *            \c len(\c range(\a bgComp,\a endComp,\a stepComp)).
7041  *
7042  *  \ref py_mcdataarrayint_setpartofvalues1 "Here is a Python example".
7043  */
7044 void DataArrayInt::setPartOfValues1(const DataArrayInt *a, int bgTuples, int endTuples, int stepTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare) throw(INTERP_KERNEL::Exception)
7045 {
7046   if(!a)
7047     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValues1 : DataArrayInt pointer in input is NULL !");
7048   const char msg[]="DataArrayInt::setPartOfValues1";
7049   checkAllocated();
7050   a->checkAllocated();
7051   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
7052   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
7053   int nbComp=getNumberOfComponents();
7054   int nbOfTuples=getNumberOfTuples();
7055   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
7056   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
7057   bool assignTech=true;
7058   if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
7059     {
7060       if(strictCompoCompare)
7061         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
7062     }
7063   else
7064     {
7065       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
7066       assignTech=false;
7067     }
7068   int *pt=getPointer()+bgTuples*nbComp+bgComp;
7069   const int *srcPt=a->getConstPointer();
7070   if(assignTech)
7071     {
7072       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
7073         for(int j=0;j<newNbOfComp;j++,srcPt++)
7074           pt[j*stepComp]=*srcPt;
7075     }
7076   else
7077     {
7078       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
7079         {
7080           const int *srcPt2=srcPt;
7081           for(int j=0;j<newNbOfComp;j++,srcPt2++)
7082             pt[j*stepComp]=*srcPt2;
7083         }
7084     }
7085 }
7086
7087 /*!
7088  * Assign a given value to values at specified tuples and components of \a this array.
7089  * The tree parameters defining set of indices of tuples and components are similar to
7090  * the tree parameters of the Python function \c range(\c start,\c stop,\c step)..
7091  *  \param [in] a - the value to assign.
7092  *  \param [in] bgTuples - index of the first tuple of \a this array to assign to.
7093  *  \param [in] endTuples - index of the tuple before which the tuples to assign to
7094  *              are located.
7095  *  \param [in] stepTuples - index increment to get index of the next tuple to assign to.
7096  *  \param [in] bgComp - index of the first component of \a this array to assign to.
7097  *  \param [in] endComp - index of the component before which the components to assign
7098  *              to are located.
7099  *  \param [in] stepComp - index increment to get index of the next component to assign to.
7100  *  \throw If \a this is not allocated.
7101  *  \throw If parameters specifying tuples and components to assign to, do not give a
7102  *            non-empty range of increasing indices or indices are out of a valid range
7103  *            for \this array.
7104  *
7105  *  \ref py_mcdataarrayint_setpartofvaluessimple1 "Here is a Python example".
7106  */
7107 void DataArrayInt::setPartOfValuesSimple1(int a, int bgTuples, int endTuples, int stepTuples, int bgComp, int endComp, int stepComp) throw(INTERP_KERNEL::Exception)
7108 {
7109   const char msg[]="DataArrayInt::setPartOfValuesSimple1";
7110   checkAllocated();
7111   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
7112   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
7113   int nbComp=getNumberOfComponents();
7114   int nbOfTuples=getNumberOfTuples();
7115   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
7116   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
7117   int *pt=getPointer()+bgTuples*nbComp+bgComp;
7118   for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
7119     for(int j=0;j<newNbOfComp;j++)
7120       pt[j*stepComp]=a;
7121 }
7122
7123
7124 /*!
7125  * Copy all values from another DataArrayInt (\a a) into specified tuples and 
7126  * components of \a this array. Textual data is not copied.
7127  * The tuples and components to assign to are defined by C arrays of indices.
7128  * There are two *modes of usage*:
7129  * - If \a a->getNbOfElems() equals to number of values to assign to, then every value
7130  *   of \a a is assigned to its own location within \a this array. 
7131  * - If \a a includes one tuple, then all values of \a a are assigned to the specified
7132  *   components of every specified tuple of \a this array. In this mode it is required
7133  *   that \a a->getNumberOfComponents() equals to the number of specified components.
7134  * 
7135  *  \param [in] a - the array to copy values from.
7136  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
7137  *              assign values of \a a to.
7138  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
7139  *              pointer to a tuple index <em>(pi)</em> varies as this: 
7140  *              \a bgTuples <= \a pi < \a endTuples.
7141  *  \param [in] bgComp - pointer to an array of component indices of \a this array to
7142  *              assign values of \a a to.
7143  *  \param [in] endComp - specifies the end of the array \a bgTuples, so that
7144  *              pointer to a component index <em>(pi)</em> varies as this: 
7145  *              \a bgComp <= \a pi < \a endComp.
7146  *  \param [in] strictCompoCompare - this parameter is checked only if the
7147  *               *mode of usage* is the first; if it is \a true (default), 
7148  *               then \a a->getNumberOfComponents() must be equal 
7149  *               to the number of specified columns, else this is not required.
7150  *  \throw If \a a is NULL.
7151  *  \throw If \a a is not allocated.
7152  *  \throw If \a this is not allocated.
7153  *  \throw If any index of tuple/component given by <em>bgTuples / bgComp</em> is
7154  *         out of a valid range for \a this array.
7155  *  \throw In the first *mode of usage*, if <em>strictCompoCompare == true </em> and
7156  *         if <em> a->getNumberOfComponents() != (endComp - bgComp) </em>.
7157  *  \throw In the second *mode of usage*, if \a a->getNumberOfTuples() != 1 or
7158  *         <em> a->getNumberOfComponents() != (endComp - bgComp)</em>.
7159  *
7160  *  \ref py_mcdataarrayint_setpartofvalues2 "Here is a Python example".
7161  */
7162 void DataArrayInt::setPartOfValues2(const DataArrayInt *a, const int *bgTuples, const int *endTuples, const int *bgComp, const int *endComp, bool strictCompoCompare) throw(INTERP_KERNEL::Exception)
7163 {
7164   if(!a)
7165     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValues2 : DataArrayInt pointer in input is NULL !");
7166   const char msg[]="DataArrayInt::setPartOfValues2";
7167   checkAllocated();
7168   a->checkAllocated();
7169   int nbComp=getNumberOfComponents();
7170   int nbOfTuples=getNumberOfTuples();
7171   for(const int *z=bgComp;z!=endComp;z++)
7172     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
7173   int newNbOfTuples=(int)std::distance(bgTuples,endTuples);
7174   int newNbOfComp=(int)std::distance(bgComp,endComp);
7175   bool assignTech=true;
7176   if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
7177     {
7178       if(strictCompoCompare)
7179         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
7180     }
7181   else
7182     {
7183       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
7184       assignTech=false;
7185     }
7186   int *pt=getPointer();
7187   const int *srcPt=a->getConstPointer();
7188   if(assignTech)
7189     {    
7190       for(const int *w=bgTuples;w!=endTuples;w++)
7191         {
7192           DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
7193           for(const int *z=bgComp;z!=endComp;z++,srcPt++)
7194             {    
7195               pt[(std::size_t)(*w)*nbComp+(*z)]=*srcPt;
7196             }
7197         }
7198     }
7199   else
7200     {
7201       for(const int *w=bgTuples;w!=endTuples;w++)
7202         {
7203           const int *srcPt2=srcPt;
7204           DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
7205           for(const int *z=bgComp;z!=endComp;z++,srcPt2++)
7206             {    
7207               pt[(std::size_t)(*w)*nbComp+(*z)]=*srcPt2;
7208             }
7209         }
7210     }
7211 }
7212
7213 /*!
7214  * Assign a given value to values at specified tuples and components of \a this array.
7215  * The tuples and components to assign to are defined by C arrays of indices.
7216  *  \param [in] a - the value to assign.
7217  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
7218  *              assign \a a to.
7219  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
7220  *              pointer to a tuple index (\a pi) varies as this: 
7221  *              \a bgTuples <= \a pi < \a endTuples.
7222  *  \param [in] bgComp - pointer to an array of component indices of \a this array to
7223  *              assign \a a to.
7224  *  \param [in] endComp - specifies the end of the array \a bgTuples, so that
7225  *              pointer to a component index (\a pi) varies as this: 
7226  *              \a bgComp <= \a pi < \a endComp.
7227  *  \throw If \a this is not allocated.
7228  *  \throw If any index of tuple/component given by <em>bgTuples / bgComp</em> is
7229  *         out of a valid range for \a this array.
7230  *
7231  *  \ref py_mcdataarrayint_setpartofvaluessimple2 "Here is a Python example".
7232  */
7233 void DataArrayInt::setPartOfValuesSimple2(int a, const int *bgTuples, const int *endTuples, const int *bgComp, const int *endComp) throw(INTERP_KERNEL::Exception)
7234 {
7235   checkAllocated();
7236   int nbComp=getNumberOfComponents();
7237   int nbOfTuples=getNumberOfTuples();
7238   for(const int *z=bgComp;z!=endComp;z++)
7239     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
7240   int *pt=getPointer();
7241   for(const int *w=bgTuples;w!=endTuples;w++)
7242     for(const int *z=bgComp;z!=endComp;z++)
7243       {
7244         DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
7245         pt[(std::size_t)(*w)*nbComp+(*z)]=a;
7246       }
7247 }
7248
7249 /*!
7250  * Copy all values from another DataArrayInt (\a a) into specified tuples and 
7251  * components of \a this array. Textual data is not copied.
7252  * The tuples to assign to are defined by a C array of indices.
7253  * The components to assign to are defined by three values similar to parameters of
7254  * the Python function \c range(\c start,\c stop,\c step).
7255  * There are two *modes of usage*:
7256  * - If \a a->getNbOfElems() equals to number of values to assign to, then every value
7257  *   of \a a is assigned to its own location within \a this array. 
7258  * - If \a a includes one tuple, then all values of \a a are assigned to the specified
7259  *   components of every specified tuple of \a this array. In this mode it is required
7260  *   that \a a->getNumberOfComponents() equals to the number of specified components.
7261  *
7262  *  \param [in] a - the array to copy values from.
7263  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
7264  *              assign values of \a a to.
7265  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
7266  *              pointer to a tuple index <em>(pi)</em> varies as this: 
7267  *              \a bgTuples <= \a pi < \a endTuples.
7268  *  \param [in] bgComp - index of the first component of \a this array to assign to.
7269  *  \param [in] endComp - index of the component before which the components to assign
7270  *              to are located.
7271  *  \param [in] stepComp - index increment to get index of the next component to assign to.
7272  *  \param [in] strictCompoCompare - this parameter is checked only in the first
7273  *               *mode of usage*; if \a strictCompoCompare is \a true (default), 
7274  *               then \a a->getNumberOfComponents() must be equal 
7275  *               to the number of specified columns, else this is not required.
7276  *  \throw If \a a is NULL.
7277  *  \throw If \a a is not allocated.
7278  *  \throw If \a this is not allocated.
7279  *  \throw If any index of tuple given by \a bgTuples is out of a valid range for 
7280  *         \a this array.
7281  *  \throw In the first *mode of usage*, if <em>strictCompoCompare == true </em> and
7282  *         if <em> a->getNumberOfComponents()</em> is unequal to the number of components
7283  *         defined by <em>(bgComp,endComp,stepComp)</em>.
7284  *  \throw In the second *mode of usage*, if \a a->getNumberOfTuples() != 1 or
7285  *         <em> a->getNumberOfComponents()</em> is unequal to the number of components
7286  *         defined by <em>(bgComp,endComp,stepComp)</em>.
7287  *  \throw If parameters specifying components to assign to, do not give a
7288  *            non-empty range of increasing indices or indices are out of a valid range
7289  *            for \this array.
7290  *
7291  *  \ref py_mcdataarrayint_setpartofvalues3 "Here is a Python example".
7292  */
7293 void DataArrayInt::setPartOfValues3(const DataArrayInt *a, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare) throw(INTERP_KERNEL::Exception)
7294 {
7295   if(!a)
7296     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValues3 : DataArrayInt pointer in input is NULL !");
7297   const char msg[]="DataArrayInt::setPartOfValues3";
7298   checkAllocated();
7299   a->checkAllocated();
7300   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
7301   int nbComp=getNumberOfComponents();
7302   int nbOfTuples=getNumberOfTuples();
7303   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
7304   int newNbOfTuples=(int)std::distance(bgTuples,endTuples);
7305   bool assignTech=true;
7306   if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
7307     {
7308       if(strictCompoCompare)
7309         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
7310     }
7311   else
7312     {
7313       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
7314       assignTech=false;
7315     }
7316   int *pt=getPointer()+bgComp;
7317   const int *srcPt=a->getConstPointer();
7318   if(assignTech)
7319     {
7320       for(const int *w=bgTuples;w!=endTuples;w++)
7321         for(int j=0;j<newNbOfComp;j++,srcPt++)
7322           {
7323             DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
7324             pt[(std::size_t)(*w)*nbComp+j*stepComp]=*srcPt;
7325           }
7326     }
7327   else
7328     {
7329       for(const int *w=bgTuples;w!=endTuples;w++)
7330         {
7331           const int *srcPt2=srcPt;
7332           for(int j=0;j<newNbOfComp;j++,srcPt2++)
7333             {
7334               DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
7335               pt[(std::size_t)(*w)*nbComp+j*stepComp]=*srcPt2;
7336             }
7337         }
7338     }
7339 }
7340
7341 /*!
7342  * Assign a given value to values at specified tuples and components of \a this array.
7343  * The tuples to assign to are defined by a C array of indices.
7344  * The components to assign to are defined by three values similar to parameters of
7345  * the Python function \c range(\c start,\c stop,\c step).
7346  *  \param [in] a - the value to assign.
7347  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
7348  *              assign \a a to.
7349  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
7350  *              pointer to a tuple index <em>(pi)</em> varies as this: 
7351  *              \a bgTuples <= \a pi < \a endTuples.
7352  *  \param [in] bgComp - index of the first component of \a this array to assign to.
7353  *  \param [in] endComp - index of the component before which the components to assign
7354  *              to are located.
7355  *  \param [in] stepComp - index increment to get index of the next component to assign to.
7356  *  \throw If \a this is not allocated.
7357  *  \throw If any index of tuple given by \a bgTuples is out of a valid range for 
7358  *         \a this array.
7359  *  \throw If parameters specifying components to assign to, do not give a
7360  *            non-empty range of increasing indices or indices are out of a valid range
7361  *            for \this array.
7362  *
7363  *  \ref py_mcdataarrayint_setpartofvaluessimple3 "Here is a Python example".
7364  */
7365 void DataArrayInt::setPartOfValuesSimple3(int a, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp) throw(INTERP_KERNEL::Exception)
7366 {
7367   const char msg[]="DataArrayInt::setPartOfValuesSimple3";
7368   checkAllocated();
7369   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
7370   int nbComp=getNumberOfComponents();
7371   int nbOfTuples=getNumberOfTuples();
7372   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
7373   int *pt=getPointer()+bgComp;
7374   for(const int *w=bgTuples;w!=endTuples;w++)
7375     for(int j=0;j<newNbOfComp;j++)
7376       {
7377         DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
7378         pt[(std::size_t)(*w)*nbComp+j*stepComp]=a;
7379       }
7380 }
7381
7382 void DataArrayInt::setPartOfValues4(const DataArrayInt *a, int bgTuples, int endTuples, int stepTuples, const int *bgComp, const int *endComp, bool strictCompoCompare) throw(INTERP_KERNEL::Exception)
7383 {
7384   if(!a)
7385     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValues4 : input DataArrayInt is NULL !");
7386   const char msg[]="DataArrayInt::setPartOfValues4";
7387   checkAllocated();
7388   a->checkAllocated();
7389   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
7390   int newNbOfComp=(int)std::distance(bgComp,endComp);
7391   int nbComp=getNumberOfComponents();
7392   for(const int *z=bgComp;z!=endComp;z++)
7393     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
7394   int nbOfTuples=getNumberOfTuples();
7395   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
7396   bool assignTech=true;
7397   if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
7398     {
7399       if(strictCompoCompare)
7400         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
7401     }
7402   else
7403     {
7404       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
7405       assignTech=false;
7406     }
7407   const int *srcPt=a->getConstPointer();
7408   int *pt=getPointer()+bgTuples*nbComp;
7409   if(assignTech)
7410     {
7411       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
7412         for(const int *z=bgComp;z!=endComp;z++,srcPt++)
7413           pt[*z]=*srcPt;
7414     }
7415   else
7416     {
7417       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
7418         {
7419           const int *srcPt2=srcPt;
7420           for(const int *z=bgComp;z!=endComp;z++,srcPt2++)
7421             pt[*z]=*srcPt2;
7422         }
7423     }
7424 }
7425
7426 void DataArrayInt::setPartOfValuesSimple4(int a, int bgTuples, int endTuples, int stepTuples, const int *bgComp, const int *endComp) throw(INTERP_KERNEL::Exception)
7427 {
7428   const char msg[]="DataArrayInt::setPartOfValuesSimple4";
7429   checkAllocated();
7430   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
7431   int nbComp=getNumberOfComponents();
7432   for(const int *z=bgComp;z!=endComp;z++)
7433     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
7434   int nbOfTuples=getNumberOfTuples();
7435   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
7436   int *pt=getPointer()+bgTuples*nbComp;
7437   for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
7438     for(const int *z=bgComp;z!=endComp;z++)
7439       pt[*z]=a;
7440 }
7441
7442 /*!
7443  * Copy some tuples from another DataArrayInt into specified tuples
7444  * of \a this array. Textual data is not copied. Both arrays must have equal number of
7445  * components.
7446  * Both the tuples to assign and the tuples to assign to are defined by a DataArrayInt.
7447  * All components of selected tuples are copied.
7448  *  \param [in] a - the array to copy values from.
7449  *  \param [in] tuplesSelec - the array specifying both source tuples of \a a and
7450  *              target tuples of \a this. \a tuplesSelec has two components, and the
7451  *              first component specifies index of the source tuple and the second
7452  *              one specifies index of the target tuple.
7453  *  \throw If \a this is not allocated.
7454  *  \throw If \a a is NULL.
7455  *  \throw If \a a is not allocated.
7456  *  \throw If \a tuplesSelec is NULL.
7457  *  \throw If \a tuplesSelec is not allocated.
7458  *  \throw If <em>this->getNumberOfComponents() != a->getNumberOfComponents()</em>.
7459  *  \throw If \a tuplesSelec->getNumberOfComponents() != 2.
7460  *  \throw If any tuple index given by \a tuplesSelec is out of a valid range for 
7461  *         the corresponding (\a this or \a a) array.
7462  */
7463 void DataArrayInt::setPartOfValuesAdv(const DataArrayInt *a, const DataArrayInt *tuplesSelec) throw(INTERP_KERNEL::Exception)
7464 {
7465   if(!a || !tuplesSelec)
7466     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValuesAdv : DataArrayInt pointer in input is NULL !");
7467   checkAllocated();
7468   a->checkAllocated();
7469   tuplesSelec->checkAllocated();
7470   int nbOfComp=getNumberOfComponents();
7471   if(nbOfComp!=a->getNumberOfComponents())
7472     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValuesAdv : This and a do not have the same number of components !");
7473   if(tuplesSelec->getNumberOfComponents()!=2)
7474     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValuesAdv : Expecting to have a tuple selector DataArrayInt instance with exactly 2 components !");
7475   int thisNt=getNumberOfTuples();
7476   int aNt=a->getNumberOfTuples();
7477   int *valsToSet=getPointer();
7478   const int *valsSrc=a->getConstPointer();
7479   for(const int *tuple=tuplesSelec->begin();tuple!=tuplesSelec->end();tuple+=2)
7480     {
7481       if(tuple[1]>=0 && tuple[1]<aNt)
7482         {
7483           if(tuple[0]>=0 && tuple[0]<thisNt)
7484             std::copy(valsSrc+nbOfComp*tuple[1],valsSrc+nbOfComp*(tuple[1]+1),valsToSet+nbOfComp*tuple[0]);
7485           else
7486             {
7487               std::ostringstream oss; oss << "DataArrayInt::setPartOfValuesAdv : Tuple #" << std::distance(tuplesSelec->begin(),tuple)/2;
7488               oss << " of 'tuplesSelec' request of tuple id #" << tuple[0] << " in 'this' ! It should be in [0," << thisNt << ") !";
7489               throw INTERP_KERNEL::Exception(oss.str().c_str());
7490             }
7491         }
7492       else
7493         {
7494           std::ostringstream oss; oss << "DataArrayInt::setPartOfValuesAdv : Tuple #" << std::distance(tuplesSelec->begin(),tuple)/2;
7495           oss << " of 'tuplesSelec' request of tuple id #" << tuple[1] << " in 'a' ! It should be in [0," << aNt << ") !";
7496           throw INTERP_KERNEL::Exception(oss.str().c_str());
7497         }
7498     }
7499 }
7500
7501 /*!
7502  * Copy some tuples from another DataArrayInt (\a a) into contiguous tuples
7503  * of \a this array. Textual data is not copied. Both arrays must have equal number of
7504  * components.
7505  * The tuples to assign to are defined by index of the first tuple, and
7506  * their number is defined by \a tuplesSelec->getNumberOfTuples().
7507  * The tuples to copy are defined by values of a DataArrayInt.
7508  * All components of selected tuples are copied.
7509  *  \param [in] tupleIdStart - index of the first tuple of \a this array to assign
7510  *              values to.
7511  *  \param [in] a - the array to copy values from.
7512  *  \param [in] tuplesSelec - the array specifying tuples of \a a to copy.
7513  *  \throw If \a this is not allocated.
7514  *  \throw If \a a is NULL.
7515  *  \throw If \a a is not allocated.
7516  *  \throw If \a tuplesSelec is NULL.
7517  *  \throw If \a tuplesSelec is not allocated.
7518  *  \throw If <em>this->getNumberOfComponents() != a->getNumberOfComponents()</em>.
7519  *  \throw If \a tuplesSelec->getNumberOfComponents() != 1.
7520  *  \throw If <em>tupleIdStart + tuplesSelec->getNumberOfTuples() > this->getNumberOfTuples().</em>
7521  *  \throw If any tuple index given by \a tuplesSelec is out of a valid range for 
7522  *         \a a array.
7523  */
7524 void DataArrayInt::setContigPartOfSelectedValues(int tupleIdStart, const DataArrayInt*a, const DataArrayInt *tuplesSelec) throw(INTERP_KERNEL::Exception)
7525 {
7526   checkAllocated();
7527   a->checkAllocated();
7528   tuplesSelec->checkAllocated();
7529   int nbOfComp=getNumberOfComponents();
7530   if(nbOfComp!=a->getNumberOfComponents())
7531     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues : This and a do not have the same number of components !");
7532   if(tuplesSelec->getNumberOfComponents()!=1)
7533     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues : Expecting to have a tuple selector DataArrayInt instance with exactly 1 component !");
7534   int thisNt=getNumberOfTuples();
7535   int aNt=a->getNumberOfTuples();
7536   int nbOfTupleToWrite=tuplesSelec->getNumberOfTuples();
7537   int *valsToSet=getPointer()+tupleIdStart*nbOfComp;
7538   if(tupleIdStart+nbOfTupleToWrite>thisNt)
7539     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues : invalid number range of values to write !");
7540   const int *valsSrc=a->getConstPointer();
7541   for(const int *tuple=tuplesSelec->begin();tuple!=tuplesSelec->end();tuple++,valsToSet+=nbOfComp)
7542     {
7543       if(*tuple>=0 && *tuple<aNt)
7544         {
7545           std::copy(valsSrc+nbOfComp*(*tuple),valsSrc+nbOfComp*(*tuple+1),valsToSet);
7546         }
7547       else
7548         {
7549           std::ostringstream oss; oss << "DataArrayInt::setContigPartOfSelectedValues : Tuple #" << std::distance(tuplesSelec->begin(),tuple);
7550           oss << " of 'tuplesSelec' request of tuple id #" << *tuple << " in 'a' ! It should be in [0," << aNt << ") !";
7551           throw INTERP_KERNEL::Exception(oss.str().c_str());
7552         }
7553     }
7554 }
7555
7556 /*!
7557  * Copy some tuples from another DataArrayInt (\a a) into contiguous tuples
7558  * of \a this array. Textual data is not copied. Both arrays must have equal number of
7559  * components.
7560  * The tuples to copy are defined by three values similar to parameters of
7561  * the Python function \c range(\c start,\c stop,\c step).
7562  * The tuples to assign to are defined by index of the first tuple, and
7563  * their number is defined by number of tuples to copy.
7564  * All components of selected tuples are copied.
7565  *  \param [in] tupleIdStart - index of the first tuple of \a this array to assign
7566  *              values to.
7567  *  \param [in] a - the array to copy values from.
7568  *  \param [in] bg - index of the first tuple to copy of the array \a a.
7569  *  \param [in] end2 - index of the tuple of \a a before which the tuples to copy
7570  *              are located.
7571  *  \param [in] step - index increment to get index of the next tuple to copy.
7572  *  \throw If \a this is not allocated.
7573  *  \throw If \a a is NULL.
7574  *  \throw If \a a is not allocated.
7575  *  \throw If <em>this->getNumberOfComponents() != a->getNumberOfComponents()</em>.
7576  *  \throw If <em>tupleIdStart + len(range(bg,end2,step)) > this->getNumberOfTuples().</em>
7577  *  \throw If parameters specifying tuples to copy, do not give a
7578  *            non-empty range of increasing indices or indices are out of a valid range
7579  *            for the array \a a.
7580  */
7581 void DataArrayInt::setContigPartOfSelectedValues2(int tupleIdStart, const DataArrayInt *a, int bg, int end2, int step) throw(INTERP_KERNEL::Exception)
7582 {
7583   checkAllocated();
7584   a->checkAllocated();
7585   int nbOfComp=getNumberOfComponents();
7586   const char msg[]="DataArrayInt::setContigPartOfSelectedValues2";
7587   int nbOfTupleToWrite=DataArray::GetNumberOfItemGivenBES(bg,end2,step,msg);
7588   if(nbOfComp!=a->getNumberOfComponents())
7589     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues2 : This and a do not have the same number of components !");
7590   int thisNt=getNumberOfTuples();
7591   int aNt=a->getNumberOfTuples();
7592   int *valsToSet=getPointer()+tupleIdStart*nbOfComp;
7593   if(tupleIdStart+nbOfTupleToWrite>thisNt)
7594     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues2 : invalid number range of values to write !");
7595   if(end2>aNt)
7596     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues2 : invalid range of values to read !");
7597   const int *valsSrc=a->getConstPointer()+bg*nbOfComp;
7598   for(int i=0;i<nbOfTupleToWrite;i++,valsToSet+=nbOfComp,valsSrc+=step*nbOfComp)
7599     {
7600       std::copy(valsSrc,valsSrc+nbOfComp,valsToSet);
7601     }
7602 }
7603
7604 /*!
7605  * Returns a value located at specified tuple and component.
7606  * This method is equivalent to DataArrayInt::getIJ() except that validity of
7607  * parameters is checked. So this method is safe but expensive if used to go through
7608  * all values of \a this.
7609  *  \param [in] tupleId - index of tuple of interest.
7610  *  \param [in] compoId - index of component of interest.
7611  *  \return double - value located by \a tupleId and \a compoId.
7612  *  \throw If \a this is not allocated.
7613  *  \throw If condition <em>( 0 <= tupleId < this->getNumberOfTuples() )</em> is violated.
7614  *  \throw If condition <em>( 0 <= compoId < this->getNumberOfComponents() )</em> is violated.
7615  */
7616 int DataArrayInt::getIJSafe(int tupleId, int compoId) const throw(INTERP_KERNEL::Exception)
7617 {
7618   checkAllocated();
7619   if(tupleId<0 || tupleId>=getNumberOfTuples())
7620     {
7621       std::ostringstream oss; oss << "DataArrayInt::getIJSafe : request for tupleId " << tupleId << " should be in [0," << getNumberOfTuples() << ") !";
7622       throw INTERP_KERNEL::Exception(oss.str().c_str());
7623     }
7624   if(compoId<0 || compoId>=getNumberOfComponents())
7625     {
7626       std::ostringstream oss; oss << "DataArrayInt::getIJSafe : request for compoId " << compoId << " should be in [0," << getNumberOfComponents() << ") !";
7627       throw INTERP_KERNEL::Exception(oss.str().c_str());
7628     }
7629   return _mem[tupleId*_info_on_compo.size()+compoId];
7630 }
7631
7632 /*!
7633  * Returns the last value of \a this. 
7634  *  \return double - the last value of \a this array.
7635  *  \throw If \a this is not allocated.
7636  *  \throw If \a this->getNumberOfComponents() != 1.
7637  *  \throw If \a this->getNumberOfTuples() < 1.
7638  */
7639 int DataArrayInt::back() const throw(INTERP_KERNEL::Exception)
7640 {
7641   checkAllocated();
7642   if(getNumberOfComponents()!=1)
7643     throw INTERP_KERNEL::Exception("DataArrayInt::back : number of components not equal to one !");
7644   int nbOfTuples=getNumberOfTuples();
7645   if(nbOfTuples<1)
7646     throw INTERP_KERNEL::Exception("DataArrayInt::back : number of tuples must be >= 1 !");
7647   return *(getConstPointer()+nbOfTuples-1);
7648 }
7649
7650 /*!
7651  * Assign pointer to one array to a pointer to another appay. Reference counter of
7652  * \a arrayToSet is incremented / decremented.
7653  *  \param [in] newArray - the pointer to array to assign to \a arrayToSet.
7654  *  \param [in,out] arrayToSet - the pointer to array to assign to.
7655  */
7656 void DataArrayInt::SetArrayIn(DataArrayInt *newArray, DataArrayInt* &arrayToSet)
7657 {
7658   if(newArray!=arrayToSet)
7659     {
7660       if(arrayToSet)
7661         arrayToSet->decrRef();
7662       arrayToSet=newArray;
7663       if(arrayToSet)
7664         arrayToSet->incrRef();
7665     }
7666 }
7667
7668 DataArrayIntIterator *DataArrayInt::iterator() throw(INTERP_KERNEL::Exception)
7669 {
7670   return new DataArrayIntIterator(this);
7671 }
7672
7673 /*!
7674  * Creates a new DataArrayInt containing IDs (indices) of tuples holding value equal to a
7675  * given one.
7676  *  \param [in] val - the value to find within \a this.
7677  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
7678  *          array using decrRef() as it is no more needed.
7679  *  \throw If \a this is not allocated.
7680  *  \throw If \a this->getNumberOfComponents() != 1.
7681  */
7682 DataArrayInt *DataArrayInt::getIdsEqual(int val) const throw(INTERP_KERNEL::Exception)
7683 {
7684   checkAllocated();
7685   if(getNumberOfComponents()!=1)
7686     throw INTERP_KERNEL::Exception("DataArrayInt::getIdsEqual : the array must have only one component, you can call 'rearrange' method before !");
7687   const int *cptr=getConstPointer();
7688   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
7689   int nbOfTuples=getNumberOfTuples();
7690   for(int i=0;i<nbOfTuples;i++,cptr++)
7691     if(*cptr==val)
7692       ret->pushBackSilent(i);
7693   return ret.retn();
7694 }
7695
7696 /*!
7697  * Creates a new DataArrayInt containing IDs (indices) of tuples holding value \b not
7698  * equal to a given one. 
7699  *  \param [in] val - the value to ignore within \a this.
7700  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
7701  *          array using decrRef() as it is no more needed.
7702  *  \throw If \a this is not allocated.
7703  *  \throw If \a this->getNumberOfComponents() != 1.
7704  */
7705 DataArrayInt *DataArrayInt::getIdsNotEqual(int val) const throw(INTERP_KERNEL::Exception)
7706 {
7707   checkAllocated();
7708   if(getNumberOfComponents()!=1)
7709     throw INTERP_KERNEL::Exception("DataArrayInt::getIdsNotEqual : the array must have only one component, you can call 'rearrange' method before !");
7710   const int *cptr=getConstPointer();
7711   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
7712   int nbOfTuples=getNumberOfTuples();
7713   for(int i=0;i<nbOfTuples;i++,cptr++)
7714     if(*cptr!=val)
7715       ret->pushBackSilent(i);
7716   return ret.retn();
7717 }
7718
7719
7720 /*!
7721  * Assigns \a newValue to all elements holding \a oldValue within \a this
7722  * one-dimensional array.
7723  *  \param [in] oldValue - the value to replace.
7724  *  \param [in] newValue - the value to assign.
7725  *  \return int - number of replacements performed.
7726  *  \throw If \a this is not allocated.
7727  *  \throw If \a this->getNumberOfComponents() != 1.
7728  */
7729 int DataArrayInt::changeValue(int oldValue, int newValue) throw(INTERP_KERNEL::Exception)
7730 {
7731   checkAllocated();
7732   if(getNumberOfComponents()!=1)
7733     throw INTERP_KERNEL::Exception("DataArrayInt::changeValue : the array must have only one component, you can call 'rearrange' method before !");
7734   int *start=getPointer();
7735   int *end2=start+getNbOfElems();
7736   int ret=0;
7737   for(int *val=start;val!=end2;val++)
7738     {
7739       if(*val==oldValue)
7740         {
7741           *val=newValue;
7742           ret++;
7743         }
7744     }
7745   return ret;
7746 }
7747
7748 /*!
7749  * Creates a new DataArrayInt containing IDs (indices) of tuples holding value equal to
7750  * one of given values.
7751  *  \param [in] valsBg - an array of values to find within \a this array.
7752  *  \param [in] valsEnd - specifies the end of the array \a valsBg, so that
7753  *              the last value of \a valsBg is \a valsEnd[ -1 ].
7754  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
7755  *          array using decrRef() as it is no more needed.
7756  *  \throw If \a this->getNumberOfComponents() != 1.
7757  */
7758 DataArrayInt *DataArrayInt::getIdsEqualList(const int *valsBg, const int *valsEnd) const throw(INTERP_KERNEL::Exception)
7759 {
7760   if(getNumberOfComponents()!=1)
7761     throw INTERP_KERNEL::Exception("DataArrayInt::getIdsEqualList : the array must have only one component, you can call 'rearrange' method before !");
7762   std::set<int> vals2(valsBg,valsEnd);
7763   const int *cptr=getConstPointer();
7764   std::vector<int> res;
7765   int nbOfTuples=getNumberOfTuples();
7766   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
7767   for(int i=0;i<nbOfTuples;i++,cptr++)
7768     if(vals2.find(*cptr)!=vals2.end())
7769       ret->pushBackSilent(i);
7770   return ret.retn();
7771 }
7772
7773 /*!
7774  * Creates a new DataArrayInt containing IDs (indices) of tuples holding values \b not
7775  * equal to any of given values.
7776  *  \param [in] valsBg - an array of values to ignore within \a this array.
7777  *  \param [in] valsEnd - specifies the end of the array \a valsBg, so that
7778  *              the last value of \a valsBg is \a valsEnd[ -1 ].
7779  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
7780  *          array using decrRef() as it is no more needed.
7781  *  \throw If \a this->getNumberOfComponents() != 1.
7782  */
7783 DataArrayInt *DataArrayInt::getIdsNotEqualList(const int *valsBg, const int *valsEnd) const throw(INTERP_KERNEL::Exception)
7784 {
7785   if(getNumberOfComponents()!=1)
7786     throw INTERP_KERNEL::Exception("DataArrayInt::getIdsNotEqualList : the array must have only one component, you can call 'rearrange' method before !");
7787   std::set<int> vals2(valsBg,valsEnd);
7788   const int *cptr=getConstPointer();
7789   std::vector<int> res;
7790   int nbOfTuples=getNumberOfTuples();
7791   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
7792   for(int i=0;i<nbOfTuples;i++,cptr++)
7793     if(vals2.find(*cptr)==vals2.end())
7794       ret->pushBackSilent(i);
7795   return ret.retn();
7796 }
7797
7798 /*!
7799  * This method is an extension of DataArrayInt::locateValue method because this method works for DataArrayInt with
7800  * any number of components excepted 0 (an INTERP_KERNEL::Exception is thrown in this case).
7801  * This method searches in \b this is there is a tuple that matched the input parameter \b tupl.
7802  * If any the tuple id is returned. If not -1 is returned.
7803  * 
7804  * This method throws an INTERP_KERNEL::Exception if the number of components in \b this mismatches with the size of
7805  * the input vector. An INTERP_KERNEL::Exception is thrown too if \b this is not allocated.
7806  *
7807  * \return tuple id where \b tupl is. -1 if no such tuple exists in \b this.
7808  * \sa DataArrayInt::search, DataArrayInt::presenceOfTuple.
7809  */
7810 int DataArrayInt::locateTuple(const std::vector<int>& tupl) const throw(INTERP_KERNEL::Exception)
7811 {
7812   checkAllocated();
7813   int nbOfCompo=getNumberOfComponents();
7814   if(nbOfCompo==0)
7815     throw INTERP_KERNEL::Exception("DataArrayInt::locateTuple : 0 components in 'this' !");
7816   if(nbOfCompo!=(int)tupl.size())
7817     {
7818       std::ostringstream oss; oss << "DataArrayInt::locateTuple : 'this' contains " << nbOfCompo << " components and searching for a tuple of length " << tupl.size() << " !";
7819       throw INTERP_KERNEL::Exception(oss.str().c_str());
7820     }
7821   const int *cptr=getConstPointer();
7822   std::size_t nbOfVals=getNbOfElems();
7823   for(const int *work=cptr;work!=cptr+nbOfVals;)
7824     {
7825       work=std::search(work,cptr+nbOfVals,tupl.begin(),tupl.end());
7826       if(work!=cptr+nbOfVals)
7827         {
7828           if(std::distance(cptr,work)%nbOfCompo!=0)
7829             work++;
7830           else
7831             return std::distance(cptr,work)/nbOfCompo;
7832         }
7833     }
7834   return -1;
7835 }
7836
7837 /*!
7838  * This method searches the sequence specified in input parameter \b vals in \b this.
7839  * This works only for DataArrayInt having number of components equal to one (if not an INTERP_KERNEL::Exception will be thrown).
7840  * This method differs from DataArrayInt::locateTuple in that the position is internal raw data is not considered here contrary to DataArrayInt::locateTuple.
7841  * \sa DataArrayInt::locateTuple
7842  */
7843 int DataArrayInt::search(const std::vector<int>& vals) const throw(INTERP_KERNEL::Exception)
7844 {
7845   checkAllocated();
7846   int nbOfCompo=getNumberOfComponents();
7847   if(nbOfCompo!=1)
7848     throw INTERP_KERNEL::Exception("DataArrayInt::search : works only for DataArrayInt instance with one component !");
7849   const int *cptr=getConstPointer();
7850   std::size_t nbOfVals=getNbOfElems();
7851   const int *loc=std::search(cptr,cptr+nbOfVals,vals.begin(),vals.end());
7852   if(loc!=cptr+nbOfVals)
7853     return std::distance(cptr,loc);
7854   return -1;
7855 }
7856
7857 /*!
7858  * This method expects to be called when number of components of this is equal to one.
7859  * This method returns the tuple id, if it exists, of the first tuple equal to \b value.
7860  * If not any tuple contains \b value -1 is returned.
7861  * \sa DataArrayInt::presenceOfValue
7862  */
7863 int DataArrayInt::locateValue(int value) const throw(INTERP_KERNEL::Exception)
7864 {
7865   checkAllocated();
7866   if(getNumberOfComponents()!=1)
7867     throw INTERP_KERNEL::Exception("DataArrayInt::presenceOfValue : the array must have only one component, you can call 'rearrange' method before !");
7868   const int *cptr=getConstPointer();
7869   int nbOfTuples=getNumberOfTuples();
7870   const int *ret=std::find(cptr,cptr+nbOfTuples,value);
7871   if(ret!=cptr+nbOfTuples)
7872     return std::distance(cptr,ret);
7873   return -1;
7874 }
7875
7876 /*!
7877  * This method expects to be called when number of components of this is equal to one.
7878  * This method returns the tuple id, if it exists, of the first tuple so that the value is contained in \b vals.
7879  * If not any tuple contains one of the values contained in 'vals' false is returned.
7880  * \sa DataArrayInt::presenceOfValue
7881  */
7882 int DataArrayInt::locateValue(const std::vector<int>& vals) const throw(INTERP_KERNEL::Exception)
7883 {
7884   checkAllocated();
7885   if(getNumberOfComponents()!=1)
7886     throw INTERP_KERNEL::Exception("DataArrayInt::presenceOfValue : the array must have only one component, you can call 'rearrange' method before !");
7887   std::set<int> vals2(vals.begin(),vals.end());
7888   const int *cptr=getConstPointer();
7889   int nbOfTuples=getNumberOfTuples();
7890   for(const int *w=cptr;w!=cptr+nbOfTuples;w++)
7891     if(vals2.find(*w)!=vals2.end())
7892       return std::distance(cptr,w);
7893   return -1;
7894 }
7895
7896 /*!
7897  * This method is an extension of DataArrayInt::presenceOfValue method because this method works for DataArrayInt with
7898  * any number of components excepted 0 (an INTERP_KERNEL::Exception is thrown in this case).
7899  * This method searches in \b this is there is a tuple that matched the input parameter \b tupl.
7900  * This method throws an INTERP_KERNEL::Exception if the number of components in \b this mismatches with the size of
7901  * the input vector. An INTERP_KERNEL::Exception is thrown too if \b this is not allocated.
7902  * \sa DataArrayInt::locateTuple
7903  */
7904 bool DataArrayInt::presenceOfTuple(const std::vector<int>& tupl) const throw(INTERP_KERNEL::Exception)
7905 {
7906   return locateTuple(tupl)!=-1;
7907 }
7908
7909
7910 /*!
7911  * Returns \a true if a given value is present within \a this one-dimensional array.
7912  *  \param [in] value - the value to find within \a this array.
7913  *  \return bool - \a true in case if \a value is present within \a this array.
7914  *  \throw If \a this is not allocated.
7915  *  \throw If \a this->getNumberOfComponents() != 1.
7916  *  \sa locateValue()
7917  */
7918 bool DataArrayInt::presenceOfValue(int value) const throw(INTERP_KERNEL::Exception)
7919 {
7920   return locateValue(value)!=-1;
7921 }
7922
7923 /*!
7924  * This method expects to be called when number of components of this is equal to one.
7925  * This method returns true if it exists a tuple so that the value is contained in \b vals.
7926  * If not any tuple contains one of the values contained in 'vals' false is returned.
7927  * \sa DataArrayInt::locateValue
7928  */
7929 bool DataArrayInt::presenceOfValue(const std::vector<int>& vals) const throw(INTERP_KERNEL::Exception)
7930 {
7931   return locateValue(vals)!=-1;
7932 }
7933
7934 /*!
7935  * Accumulates values of each component of \a this array.
7936  *  \param [out] res - an array of length \a this->getNumberOfComponents(), allocated 
7937  *         by the caller, that is filled by this method with sum value for each
7938  *         component.
7939  *  \throw If \a this is not allocated.
7940  */
7941 void DataArrayInt::accumulate(int *res) const throw(INTERP_KERNEL::Exception)
7942 {
7943   checkAllocated();
7944   const int *ptr=getConstPointer();
7945   int nbTuple=getNumberOfTuples();
7946   int nbComps=getNumberOfComponents();
7947   std::fill(res,res+nbComps,0);
7948   for(int i=0;i<nbTuple;i++)
7949     std::transform(ptr+i*nbComps,ptr+(i+1)*nbComps,res,res,std::plus<int>());
7950 }
7951
7952 int DataArrayInt::accumulate(int compId) const throw(INTERP_KERNEL::Exception)
7953 {
7954   checkAllocated();
7955   const int *ptr=getConstPointer();
7956   int nbTuple=getNumberOfTuples();
7957   int nbComps=getNumberOfComponents();
7958   if(compId<0 || compId>=nbComps)
7959     throw INTERP_KERNEL::Exception("DataArrayInt::accumulate : Invalid compId specified : No such nb of components !");
7960   int ret=0;
7961   for(int i=0;i<nbTuple;i++)
7962     ret+=ptr[i*nbComps+compId];
7963   return ret;
7964 }
7965
7966 /*!
7967  * Returns a new DataArrayInt by concatenating two given arrays, so that (1) the number
7968  * of tuples in the result array is <em> a1->getNumberOfTuples() + a2->getNumberOfTuples() -
7969  * offsetA2</em> and (2)
7970  * the number of component in the result array is same as that of each of given arrays.
7971  * First \a offsetA2 tuples of \a a2 are skipped and thus are missing from the result array.
7972  * Info on components is copied from the first of the given arrays. Number of components
7973  * in the given arrays must be the same.
7974  *  \param [in] a1 - an array to include in the result array.
7975  *  \param [in] a2 - another array to include in the result array.
7976  *  \param [in] offsetA2 - number of tuples of \a a2 to skip.
7977  *  \return DataArrayInt * - the new instance of DataArrayInt.
7978  *          The caller is to delete this result array using decrRef() as it is no more
7979  *          needed.
7980  *  \throw If either \a a1 or \a a2 is NULL.
7981  *  \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents().
7982  */
7983 DataArrayInt *DataArrayInt::Aggregate(const DataArrayInt *a1, const DataArrayInt *a2, int offsetA2)
7984 {
7985   if(!a1 || !a2)
7986     throw INTERP_KERNEL::Exception("DataArrayInt::Aggregate : input DataArrayInt instance is NULL !");
7987   int nbOfComp=a1->getNumberOfComponents();
7988   if(nbOfComp!=a2->getNumberOfComponents())
7989     throw INTERP_KERNEL::Exception("Nb of components mismatch for array Aggregation !");
7990   int nbOfTuple1=a1->getNumberOfTuples();
7991   int nbOfTuple2=a2->getNumberOfTuples();
7992   DataArrayInt *ret=DataArrayInt::New();
7993   ret->alloc(nbOfTuple1+nbOfTuple2-offsetA2,nbOfComp);
7994   int *pt=std::copy(a1->getConstPointer(),a1->getConstPointer()+nbOfTuple1*nbOfComp,ret->getPointer());
7995   std::copy(a2->getConstPointer()+offsetA2*nbOfComp,a2->getConstPointer()+nbOfTuple2*nbOfComp,pt);
7996   ret->copyStringInfoFrom(*a1);
7997   return ret;
7998 }
7999
8000 /*!
8001  * Returns a new DataArrayInt by concatenating all given arrays, so that (1) the number
8002  * of tuples in the result array is a sum of the number of tuples of given arrays and (2)
8003  * the number of component in the result array is same as that of each of given arrays.
8004  * Info on components is copied from the first of the given arrays. Number of components
8005  * in the given arrays must be  the same.
8006  *  \param [in] arr - a sequence of arrays to include in the result array.
8007  *  \return DataArrayInt * - the new instance of DataArrayInt.
8008  *          The caller is to delete this result array using decrRef() as it is no more
8009  *          needed.
8010  *  \throw If all arrays within \a arr are NULL.
8011  *  \throw If getNumberOfComponents() of arrays within \a arr.
8012  */
8013 DataArrayInt *DataArrayInt::Aggregate(const std::vector<const DataArrayInt *>& arr) throw(INTERP_KERNEL::Exception)
8014 {
8015   std::vector<const DataArrayInt *> a;
8016   for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
8017     if(*it4)
8018       a.push_back(*it4);
8019   if(a.empty())
8020     throw INTERP_KERNEL::Exception("DataArrayInt::Aggregate : input list must be NON EMPTY !");
8021   std::vector<const DataArrayInt *>::const_iterator it=a.begin();
8022   int nbOfComp=(*it)->getNumberOfComponents();
8023   int nbt=(*it++)->getNumberOfTuples();
8024   for(int i=1;it!=a.end();it++,i++)
8025     {
8026       if((*it)->getNumberOfComponents()!=nbOfComp)
8027         throw INTERP_KERNEL::Exception("DataArrayInt::Aggregate : Nb of components mismatch for array aggregation !");
8028       nbt+=(*it)->getNumberOfTuples();
8029     }
8030   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
8031   ret->alloc(nbt,nbOfComp);
8032   int *pt=ret->getPointer();
8033   for(it=a.begin();it!=a.end();it++)
8034     pt=std::copy((*it)->getConstPointer(),(*it)->getConstPointer()+(*it)->getNbOfElems(),pt);
8035   ret->copyStringInfoFrom(*(a[0]));
8036   return ret.retn();
8037 }
8038
8039 /*!
8040  * Returns the maximal value and its location within \a this one-dimensional array.
8041  *  \param [out] tupleId - index of the tuple holding the maximal value.
8042  *  \return double - the maximal value among all values of \a this array.
8043  *  \throw If \a this->getNumberOfComponents() != 1
8044  *  \throw If \a this->getNumberOfTuples() < 1
8045  */
8046 int DataArrayInt::getMaxValue(int& tupleId) const throw(INTERP_KERNEL::Exception)
8047 {
8048   checkAllocated();
8049   if(getNumberOfComponents()!=1)
8050     throw INTERP_KERNEL::Exception("DataArrayInt::getMaxValue : must be applied on DataArrayInt with only one component !");
8051   int nbOfTuples=getNumberOfTuples();
8052   if(nbOfTuples<=0)
8053     throw INTERP_KERNEL::Exception("DataArrayInt::getMaxValue : array exists but number of tuples must be > 0 !");
8054   const int *vals=getConstPointer();
8055   const int *loc=std::max_element(vals,vals+nbOfTuples);
8056   tupleId=(int)std::distance(vals,loc);
8057   return *loc;
8058 }
8059
8060 /*!
8061  * Returns the maximal value within \a this array that is allowed to have more than
8062  *  one component.
8063  *  \return int - the maximal value among all values of \a this array.
8064  *  \throw If \a this is not allocated.
8065  */
8066 int DataArrayInt::getMaxValueInArray() const throw(INTERP_KERNEL::Exception)
8067 {
8068   checkAllocated();
8069   const int *loc=std::max_element(begin(),end());
8070   return *loc;
8071 }
8072
8073 /*!
8074  * Returns the minimal value and its location within \a this one-dimensional array.
8075  *  \param [out] tupleId - index of the tuple holding the minimal value.
8076  *  \return int - the minimal value among all values of \a this array.
8077  *  \throw If \a this->getNumberOfComponents() != 1
8078  *  \throw If \a this->getNumberOfTuples() < 1
8079  */
8080 int DataArrayInt::getMinValue(int& tupleId) const throw(INTERP_KERNEL::Exception)
8081 {
8082   checkAllocated();
8083   if(getNumberOfComponents()!=1)
8084     throw INTERP_KERNEL::Exception("DataArrayInt::getMaxValue : must be applied on DataArrayInt with only one component !");
8085   int nbOfTuples=getNumberOfTuples();
8086   if(nbOfTuples<=0)
8087     throw INTERP_KERNEL::Exception("DataArrayInt::getMaxValue : array exists but number of tuples must be > 0 !");
8088   const int *vals=getConstPointer();
8089   const int *loc=std::min_element(vals,vals+nbOfTuples);
8090   tupleId=(int)std::distance(vals,loc);
8091   return *loc;
8092 }
8093
8094 /*!
8095  * Returns the minimal value within \a this array that is allowed to have more than
8096  *  one component.
8097  *  \return int - the minimal value among all values of \a this array.
8098  *  \throw If \a this is not allocated.
8099  */
8100 int DataArrayInt::getMinValueInArray() const throw(INTERP_KERNEL::Exception)
8101 {
8102   checkAllocated();
8103   const int *loc=std::min_element(begin(),end());
8104   return *loc;
8105 }
8106
8107 /*!
8108  * Converts every value of \a this array to its absolute value.
8109  *  \throw If \a this is not allocated.
8110  */
8111 void DataArrayInt::abs() throw(INTERP_KERNEL::Exception)
8112 {
8113   checkAllocated();
8114   int *ptr=getPointer();
8115   std::size_t nbOfElems=getNbOfElems();
8116   std::transform(ptr,ptr+nbOfElems,ptr,std::ptr_fun<int,int>(std::abs));
8117   declareAsNew();
8118 }
8119
8120 /*!
8121  * Apply a liner function to a given component of \a this array, so that
8122  * an array element <em>(x)</em> becomes \f$ a * x + b \f$.
8123  *  \param [in] a - the first coefficient of the function.
8124  *  \param [in] b - the second coefficient of the function.
8125  *  \param [in] compoId - the index of component to modify.
8126  *  \throw If \a this is not allocated.
8127  */
8128 void DataArrayInt::applyLin(int a, int b, int compoId) throw(INTERP_KERNEL::Exception)
8129 {
8130   checkAllocated();
8131   int *ptr=getPointer()+compoId;
8132   int nbOfComp=getNumberOfComponents();
8133   int nbOfTuple=getNumberOfTuples();
8134   for(int i=0;i<nbOfTuple;i++,ptr+=nbOfComp)
8135     *ptr=a*(*ptr)+b;
8136   declareAsNew();
8137 }
8138
8139 /*!
8140  * Apply a liner function to all elements of \a this array, so that
8141  * an element _x_ becomes \f$ a * x + b \f$.
8142  *  \param [in] a - the first coefficient of the function.
8143  *  \param [in] b - the second coefficient of the function.
8144  *  \throw If \a this is not allocated.
8145  */
8146 void DataArrayInt::applyLin(int a, int b) throw(INTERP_KERNEL::Exception)
8147 {
8148   checkAllocated();
8149   int *ptr=getPointer();
8150   std::size_t nbOfElems=getNbOfElems();
8151   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
8152     *ptr=a*(*ptr)+b;
8153   declareAsNew();
8154 }
8155
8156 /*!
8157  * Returns a full copy of \a this array except that sign of all elements is reversed.
8158  *  \return DataArrayInt * - the new instance of DataArrayInt containing the
8159  *          same number of tuples and component as \a this array.
8160  *          The caller is to delete this result array using decrRef() as it is no more
8161  *          needed.
8162  *  \throw If \a this is not allocated.
8163  */
8164 DataArrayInt *DataArrayInt::negate() const throw(INTERP_KERNEL::Exception)
8165 {
8166   checkAllocated();
8167   DataArrayInt *newArr=DataArrayInt::New();
8168   int nbOfTuples=getNumberOfTuples();
8169   int nbOfComp=getNumberOfComponents();
8170   newArr->alloc(nbOfTuples,nbOfComp);
8171   const int *cptr=getConstPointer();
8172   std::transform(cptr,cptr+nbOfTuples*nbOfComp,newArr->getPointer(),std::negate<int>());
8173   newArr->copyStringInfoFrom(*this);
8174   return newArr;
8175 }
8176
8177 /*!
8178  * Modify all elements of \a this array, so that
8179  * an element _x_ becomes \f$ numerator / x \f$.
8180  *  \warning If an exception is thrown because of presence of 0 element in \a this 
8181  *           array, all elements processed before detection of the zero element remain
8182  *           modified.
8183  *  \param [in] numerator - the numerator used to modify array elements.
8184  *  \throw If \a this is not allocated.
8185  *  \throw If there is an element equal to 0 in \a this array.
8186  */
8187 void DataArrayInt::applyInv(int numerator) throw(INTERP_KERNEL::Exception)
8188 {
8189   checkAllocated();
8190   int *ptr=getPointer();
8191   std::size_t nbOfElems=getNbOfElems();
8192   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
8193     {
8194       if(*ptr!=0)
8195         {
8196           *ptr=numerator/(*ptr);
8197         }
8198       else
8199         {
8200           std::ostringstream oss; oss << "DataArrayInt::applyInv : presence of null value in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
8201           oss << " !";
8202           throw INTERP_KERNEL::Exception(oss.str().c_str());
8203         }
8204     }
8205   declareAsNew();
8206 }
8207
8208 /*!
8209  * Modify all elements of \a this array, so that
8210  * an element _x_ becomes \f$ x / val \f$.
8211  *  \param [in] val - the denominator used to modify array elements.
8212  *  \throw If \a this is not allocated.
8213  *  \throw If \a val == 0.
8214  */
8215 void DataArrayInt::applyDivideBy(int val) throw(INTERP_KERNEL::Exception)
8216 {
8217   if(val==0)
8218     throw INTERP_KERNEL::Exception("DataArrayInt::applyDivideBy : Trying to divide by 0 !");
8219   checkAllocated();
8220   int *ptr=getPointer();
8221   std::size_t nbOfElems=getNbOfElems();
8222   std::transform(ptr,ptr+nbOfElems,ptr,std::bind2nd(std::divides<int>(),val));
8223   declareAsNew();
8224 }
8225
8226 /*!
8227  * Modify all elements of \a this array, so that
8228  * an element _x_ becomes  <em> x % val </em>.
8229  *  \param [in] val - the divisor used to modify array elements.
8230  *  \throw If \a this is not allocated.
8231  *  \throw If \a val <= 0.
8232  */
8233 void DataArrayInt::applyModulus(int val) throw(INTERP_KERNEL::Exception)
8234 {
8235   if(val<=0)
8236     throw INTERP_KERNEL::Exception("DataArrayInt::applyDivideBy : Trying to operate modulus on value <= 0 !");
8237   checkAllocated();
8238   int *ptr=getPointer();
8239   std::size_t nbOfElems=getNbOfElems();
8240   std::transform(ptr,ptr+nbOfElems,ptr,std::bind2nd(std::modulus<int>(),val));
8241   declareAsNew();
8242 }
8243
8244 /*!
8245  * This method works only on data array with one component.
8246  * This method returns a newly allocated array storing stored ascendantly tuple ids in \b this so that
8247  * this[*id] in [\b vmin,\b vmax)
8248  * 
8249  * \param [in] vmin begin of range. This value is included in range.
8250  * \param [out] vmax end of range. This value is \b not included in range.
8251  * \return a newly allocated data array that the caller should deal with.
8252  */
8253 DataArrayInt *DataArrayInt::getIdsInRange(int vmin, int vmax) const throw(INTERP_KERNEL::Exception)
8254 {
8255   checkAllocated();
8256   if(getNumberOfComponents()!=1)
8257     throw INTERP_KERNEL::Exception("DataArrayInt::getIdsInRange : this must have exactly one component !");
8258   const int *cptr=getConstPointer();
8259   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(0,1);
8260   int nbOfTuples=getNumberOfTuples();
8261   for(int i=0;i<nbOfTuples;i++,cptr++)
8262     if(*cptr>=vmin && *cptr<vmax)
8263       ret->pushBackSilent(i);
8264   return ret.retn();
8265 }
8266
8267 /*!
8268  * Modify all elements of \a this array, so that
8269  * an element _x_ becomes <em> val % x </em>.
8270  *  \warning If an exception is thrown because of presence of an element <= 0 in \a this 
8271  *           array, all elements processed before detection of the zero element remain
8272  *           modified.
8273  *  \param [in] val - the divident used to modify array elements.
8274  *  \throw If \a this is not allocated.
8275  *  \throw If there is an element equal to or less than 0 in \a this array.
8276  */
8277 void DataArrayInt::applyRModulus(int val) throw(INTERP_KERNEL::Exception)
8278 {
8279   checkAllocated();
8280   int *ptr=getPointer();
8281   std::size_t nbOfElems=getNbOfElems();
8282   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
8283     {
8284       if(*ptr>0)
8285         {
8286           *ptr=val%(*ptr);
8287         }
8288       else
8289         {
8290           std::ostringstream oss; oss << "DataArrayInt::applyRModulus : presence of value <=0 in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
8291           oss << " !";
8292           throw INTERP_KERNEL::Exception(oss.str().c_str());
8293         }
8294     }
8295   declareAsNew();
8296 }
8297
8298 /*!
8299  * Modify all elements of \a this array, so that
8300  * an element _x_ becomes <em> val ^ x </em>.
8301  *  \param [in] val - the value used to apply pow on all array elements.
8302  *  \throw If \a this is not allocated.
8303  *  \throw If \a val < 0.
8304  */
8305 void DataArrayInt::applyPow(int val) throw(INTERP_KERNEL::Exception)
8306 {
8307   checkAllocated();
8308   if(val<0)
8309     throw INTERP_KERNEL::Exception("DataArrayInt::applyPow : input pow in < 0 !");
8310   int *ptr=getPointer();
8311   std::size_t nbOfElems=getNbOfElems();
8312   if(val==0)
8313     {
8314       std::fill(ptr,ptr+nbOfElems,1.);
8315       return ;
8316     }
8317   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
8318     {
8319       int tmp=1;
8320       for(int j=0;j<val;j++)
8321         tmp*=*ptr;
8322       *ptr=tmp;
8323     }
8324   declareAsNew();
8325 }
8326
8327 /*!
8328  * Modify all elements of \a this array, so that
8329  * an element _x_ becomes \f$ val ^ x \f$.
8330  *  \param [in] val - the value used to apply pow on all array elements.
8331  *  \throw If \a this is not allocated.
8332  *  \throw If there is an element < 0 in \a this array.
8333  *  \warning If an exception is thrown because of presence of 0 element in \a this 
8334  *           array, all elements processed before detection of the zero element remain
8335  *           modified.
8336  */
8337 void DataArrayInt::applyRPow(int val) throw(INTERP_KERNEL::Exception)
8338 {
8339   checkAllocated();
8340   int *ptr=getPointer();
8341   std::size_t nbOfElems=getNbOfElems();
8342   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
8343     {
8344       if(*ptr>=0)
8345         {
8346           int tmp=1;
8347           for(int j=0;j<*ptr;j++)
8348             tmp*=val;
8349           *ptr=tmp;
8350         }
8351       else
8352         {
8353           std::ostringstream oss; oss << "DataArrayInt::applyRPow : presence of negative value in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
8354           oss << " !";
8355           throw INTERP_KERNEL::Exception(oss.str().c_str());
8356         }
8357     }
8358   declareAsNew();
8359 }
8360
8361 /*!
8362  * Returns a new DataArrayInt by aggregating two given arrays, so that (1) the number
8363  * of components in the result array is a sum of the number of components of given arrays
8364  * and (2) the number of tuples in the result array is same as that of each of given
8365  * arrays. In other words the i-th tuple of result array includes all components of
8366  * i-th tuples of all given arrays.
8367  * Number of tuples in the given arrays must be the same.
8368  *  \param [in] a1 - an array to include in the result array.
8369  *  \param [in] a2 - another array to include in the result array.
8370  *  \return DataArrayInt * - the new instance of DataArrayInt.
8371  *          The caller is to delete this result array using decrRef() as it is no more
8372  *          needed.
8373  *  \throw If both \a a1 and \a a2 are NULL.
8374  *  \throw If any given array is not allocated.
8375  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
8376  */
8377 DataArrayInt *DataArrayInt::Meld(const DataArrayInt *a1, const DataArrayInt *a2) throw(INTERP_KERNEL::Exception)
8378 {
8379   std::vector<const DataArrayInt *> arr(2);
8380   arr[0]=a1; arr[1]=a2;
8381   return Meld(arr);
8382 }
8383
8384 /*!
8385  * Returns a new DataArrayInt by aggregating all given arrays, so that (1) the number
8386  * of components in the result array is a sum of the number of components of given arrays
8387  * and (2) the number of tuples in the result array is same as that of each of given
8388  * arrays. In other words the i-th tuple of result array includes all components of
8389  * i-th tuples of all given arrays.
8390  * Number of tuples in the given arrays must be  the same.
8391  *  \param [in] arr - a sequence of arrays to include in the result array.
8392  *  \return DataArrayInt * - the new instance of DataArrayInt.
8393  *          The caller is to delete this result array using decrRef() as it is no more
8394  *          needed.
8395  *  \throw If all arrays within \a arr are NULL.
8396  *  \throw If any given array is not allocated.
8397  *  \throw If getNumberOfTuples() of arrays within \a arr is different.
8398  */
8399 DataArrayInt *DataArrayInt::Meld(const std::vector<const DataArrayInt *>& arr) throw(INTERP_KERNEL::Exception)
8400 {
8401   std::vector<const DataArrayInt *> a;
8402   for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
8403     if(*it4)
8404       a.push_back(*it4);
8405   if(a.empty())
8406     throw INTERP_KERNEL::Exception("DataArrayInt::Meld : array must be NON empty !");
8407   std::vector<const DataArrayInt *>::const_iterator it;
8408   for(it=a.begin();it!=a.end();it++)
8409     (*it)->checkAllocated();
8410   it=a.begin();
8411   int nbOfTuples=(*it)->getNumberOfTuples();
8412   std::vector<int> nbc(a.size());
8413   std::vector<const int *> pts(a.size());
8414   nbc[0]=(*it)->getNumberOfComponents();
8415   pts[0]=(*it++)->getConstPointer();
8416   for(int i=1;it!=a.end();it++,i++)
8417     {
8418       if(nbOfTuples!=(*it)->getNumberOfTuples())
8419         throw INTERP_KERNEL::Exception("DataArrayInt::meld : mismatch of number of tuples !");
8420       nbc[i]=(*it)->getNumberOfComponents();
8421       pts[i]=(*it)->getConstPointer();
8422     }
8423   int totalNbOfComp=std::accumulate(nbc.begin(),nbc.end(),0);
8424   DataArrayInt *ret=DataArrayInt::New();
8425   ret->alloc(nbOfTuples,totalNbOfComp);
8426   int *retPtr=ret->getPointer();
8427   for(int i=0;i<nbOfTuples;i++)
8428     for(int j=0;j<(int)a.size();j++)
8429       {
8430         retPtr=std::copy(pts[j],pts[j]+nbc[j],retPtr);
8431         pts[j]+=nbc[j];
8432       }
8433   int k=0;
8434   for(int i=0;i<(int)a.size();i++)
8435     for(int j=0;j<nbc[i];j++,k++)
8436       ret->setInfoOnComponent(k,a[i]->getInfoOnComponent(j).c_str());
8437   return ret;
8438 }
8439
8440 /*!
8441  * Returns a new DataArrayInt which is a minimal partition of elements of \a groups.
8442  * The i-th item of the result array is an ID of a set of elements belonging to a
8443  * unique set of groups, which the i-th element is a part of. This set of elements
8444  * belonging to a unique set of groups is called \a family, so the result array contains
8445  * IDs of families each element belongs to.
8446  *
8447  * \b Example: if we have two groups of elements: \a group1 [0,4] and \a group2 [ 0,1,2 ],
8448  * then there are 3 families:
8449  * - \a family1 (with ID 1) contains element [0] belonging to ( \a group1 + \a group2 ),
8450  * - \a family2 (with ID 2) contains elements [4] belonging to ( \a group1 ),
8451  * - \a family3 (with ID 3) contains element [1,2] belonging to ( \a group2 ), <br>
8452  * and the result array contains IDs of families [ 1,3,3,0,2 ]. <br> Note a family ID 0 which
8453  * stands for the element #3 which is in none of groups.
8454  *
8455  *  \param [in] groups - sequence of groups of element IDs.
8456  *  \param [in] newNb - total number of elements; it must be more than max ID of element
8457  *         in \a groups.
8458  *  \param [out] fidsOfGroups - IDs of families the elements of each group belong to.
8459  *  \return DataArrayInt * - a new instance of DataArrayInt containing IDs of families
8460  *         each element with ID from range [0, \a newNb ) belongs to. The caller is to
8461  *         delete this array using decrRef() as it is no more needed.
8462  *  \throw If any element ID in \a groups violates condition ( 0 <= ID < \a newNb ).
8463  */
8464 DataArrayInt *DataArrayInt::MakePartition(const std::vector<const DataArrayInt *>& groups, int newNb, std::vector< std::vector<int> >& fidsOfGroups) throw(INTERP_KERNEL::Exception)
8465 {
8466   std::vector<const DataArrayInt *> groups2;
8467   for(std::vector<const DataArrayInt *>::const_iterator it4=groups.begin();it4!=groups.end();it4++)
8468     if(*it4)
8469       groups2.push_back(*it4);
8470   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
8471   ret->alloc(newNb,1);
8472   int *retPtr=ret->getPointer();
8473   std::fill(retPtr,retPtr+newNb,0);
8474   int fid=1;
8475   for(std::vector<const DataArrayInt *>::const_iterator iter=groups2.begin();iter!=groups2.end();iter++)
8476     {
8477       const int *ptr=(*iter)->getConstPointer();
8478       std::size_t nbOfElem=(*iter)->getNbOfElems();
8479       int sfid=fid;
8480       for(int j=0;j<sfid;j++)
8481         {
8482           bool found=false;
8483           for(std::size_t i=0;i<nbOfElem;i++)
8484             {
8485               if(ptr[i]>=0 && ptr[i]<newNb)
8486                 {
8487                   if(retPtr[ptr[i]]==j)
8488                     {
8489                       retPtr[ptr[i]]=fid;
8490                       found=true;
8491                     }
8492                 }
8493               else
8494                 {
8495                   std::ostringstream oss; oss << "DataArrayInt::MakePartition : In group \"" << (*iter)->getName() << "\" in tuple #" << i << " value = " << ptr[i] << " ! Should be in [0," << newNb;
8496                   oss << ") !";
8497                   throw INTERP_KERNEL::Exception(oss.str().c_str());
8498                 }
8499             }
8500           if(found)
8501             fid++;
8502         }
8503     }
8504   fidsOfGroups.clear();
8505   fidsOfGroups.resize(groups2.size());
8506   int grId=0;
8507   for(std::vector<const DataArrayInt *>::const_iterator iter=groups2.begin();iter!=groups2.end();iter++,grId++)
8508     {
8509       std::set<int> tmp;
8510       const int *ptr=(*iter)->getConstPointer();
8511       std::size_t nbOfElem=(*iter)->getNbOfElems();
8512       for(const int *p=ptr;p!=ptr+nbOfElem;p++)
8513         tmp.insert(retPtr[*p]);
8514       fidsOfGroups[grId].insert(fidsOfGroups[grId].end(),tmp.begin(),tmp.end());
8515     }
8516   return ret.retn();
8517 }
8518
8519 /*!
8520  * Returns a new DataArrayInt which contains all elements of given one-dimensional
8521  * not negative arrays. The result array does not contain any duplicates and its values
8522  * are sorted in ascending order.
8523  *  \param [in] arr - sequence of DataArrayInt's to unite.
8524  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
8525  *         array using decrRef() as it is no more needed.
8526  *  \throw If any \a arr[i] is not allocated.
8527  *  \throw If \a arr[i]->getNumberOfComponents() != 1.
8528  *  \throw If any value of \a arr[i] is negative.
8529  */
8530 DataArrayInt *DataArrayInt::BuildUnion(const std::vector<const DataArrayInt *>& arr) throw(INTERP_KERNEL::Exception)
8531 {
8532   std::vector<const DataArrayInt *> a;
8533   for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
8534     if(*it4)
8535       a.push_back(*it4);
8536   int valm=std::numeric_limits<int>::max();
8537   for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
8538     {
8539       (*it)->checkAllocated();
8540       if((*it)->getNumberOfComponents()!=1)
8541         throw INTERP_KERNEL::Exception("DataArrayInt::BuildUnion : only single component allowed !");
8542       int tmp1;
8543       valm=std::min((*it)->getMinValue(tmp1),valm);
8544     }
8545   if(valm<0)
8546     throw INTERP_KERNEL::Exception("DataArrayInt::BuildUnion : a negative value has been detected !");
8547   //
8548   std::set<int> r;
8549   for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
8550     {
8551       const int *pt=(*it)->getConstPointer();
8552       int nbOfTuples=(*it)->getNumberOfTuples();
8553       r.insert(pt,pt+nbOfTuples);
8554     }
8555   DataArrayInt *ret=DataArrayInt::New();
8556   ret->alloc((int)r.size(),1);
8557   std::copy(r.begin(),r.end(),ret->getPointer());
8558   return ret;
8559 }
8560
8561 /*!
8562  * Returns a new DataArrayInt which contains elements present in each of given one-dimensional
8563  * not negative arrays. The result array does not contain any duplicates and its values
8564  * are sorted in ascending order.
8565  *  \param [in] arr - sequence of DataArrayInt's to intersect.
8566  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
8567  *         array using decrRef() as it is no more needed.
8568  *  \throw If any \a arr[i] is not allocated.
8569  *  \throw If \a arr[i]->getNumberOfComponents() != 1.
8570  *  \throw If any value of \a arr[i] < 0.
8571  */
8572 DataArrayInt *DataArrayInt::BuildIntersection(const std::vector<const DataArrayInt *>& arr) throw(INTERP_KERNEL::Exception)
8573 {
8574   std::vector<const DataArrayInt *> a;
8575   for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
8576     if(*it4)
8577       a.push_back(*it4);
8578   int valm=std::numeric_limits<int>::max();
8579   for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
8580     {
8581       (*it)->checkAllocated();
8582       if((*it)->getNumberOfComponents()!=1)
8583         throw INTERP_KERNEL::Exception("DataArrayInt::BuildIntersection : only single component allowed !");
8584       int tmp1;
8585       valm=std::min((*it)->getMinValue(tmp1),valm);
8586     }
8587   if(valm<0)
8588     throw INTERP_KERNEL::Exception("DataArrayInt::BuildIntersection : a negative value has been detected !");
8589   //
8590   std::set<int> r;
8591   for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
8592     {
8593       const int *pt=(*it)->getConstPointer();
8594       int nbOfTuples=(*it)->getNumberOfTuples();
8595       std::set<int> s1(pt,pt+nbOfTuples);
8596       if(it!=a.begin())
8597         {
8598           std::set<int> r2;
8599           std::set_intersection(r.begin(),r.end(),s1.begin(),s1.end(),inserter(r2,r2.end()));
8600           r=r2;
8601         }
8602       else
8603         r=s1;
8604     }
8605   DataArrayInt *ret=DataArrayInt::New();
8606   ret->alloc((int)r.size(),1);
8607   std::copy(r.begin(),r.end(),ret->getPointer());
8608   return ret;
8609 }
8610
8611 /*!
8612  * Returns a new DataArrayInt which contains a complement of elements of \a this
8613  * one-dimensional array. I.e. the result array contains all elements from the range [0,
8614  * \a nbOfElement) not present in \a this array.
8615  *  \param [in] nbOfElement - maximal size of the result array.
8616  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
8617  *         array using decrRef() as it is no more needed.
8618  *  \throw If \a this is not allocated.
8619  *  \throw If \a this->getNumberOfComponents() != 1.
8620  *  \throw If any element \a x of \a this array violates condition ( 0 <= \a x < \a
8621  *         nbOfElement ).
8622  */
8623 DataArrayInt *DataArrayInt::buildComplement(int nbOfElement) const throw(INTERP_KERNEL::Exception)
8624 {
8625    checkAllocated();
8626    if(getNumberOfComponents()!=1)
8627      throw INTERP_KERNEL::Exception("DataArrayInt::buildComplement : only single component allowed !");
8628    std::vector<bool> tmp(nbOfElement);
8629    const int *pt=getConstPointer();
8630    int nbOfTuples=getNumberOfTuples();
8631    for(const int *w=pt;w!=pt+nbOfTuples;w++)
8632      if(*w>=0 && *w<nbOfElement)
8633        tmp[*w]=true;
8634      else
8635        throw INTERP_KERNEL::Exception("DataArrayInt::buildComplement : an element is not in valid range : [0,nbOfElement) !");
8636    int nbOfRetVal=(int)std::count(tmp.begin(),tmp.end(),false);
8637    DataArrayInt *ret=DataArrayInt::New();
8638    ret->alloc(nbOfRetVal,1);
8639    int j=0;
8640    int *retPtr=ret->getPointer();
8641    for(int i=0;i<nbOfElement;i++)
8642      if(!tmp[i])
8643        retPtr[j++]=i;
8644    return ret;
8645 }
8646
8647 /*!
8648  * Returns a new DataArrayInt containing elements of \a this one-dimensional missing
8649  * from an \a other one-dimensional array.
8650  *  \param [in] other - a DataArrayInt containing elements not to include in the result array.
8651  *  \return DataArrayInt * - a new instance of DataArrayInt with one component. The
8652  *         caller is to delete this array using decrRef() as it is no more needed.
8653  *  \throw If \a other is NULL.
8654  *  \throw If \a other is not allocated.
8655  *  \throw If \a other->getNumberOfComponents() != 1.
8656  *  \throw If \a this is not allocated.
8657  *  \throw If \a this->getNumberOfComponents() != 1.
8658  *  \sa DataArrayInt::buildSubstractionOptimized()
8659  */
8660 DataArrayInt *DataArrayInt::buildSubstraction(const DataArrayInt *other) const throw(INTERP_KERNEL::Exception)
8661 {
8662   if(!other)
8663     throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstraction : DataArrayInt pointer in input is NULL !");
8664   checkAllocated();
8665   other->checkAllocated();
8666   if(getNumberOfComponents()!=1)
8667      throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstraction : only single component allowed !");
8668   if(other->getNumberOfComponents()!=1)
8669      throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstraction : only single component allowed for other type !");
8670   const int *pt=getConstPointer();
8671   int nbOfTuples=getNumberOfTuples();
8672   std::set<int> s1(pt,pt+nbOfTuples);
8673   pt=other->getConstPointer();
8674   nbOfTuples=other->getNumberOfTuples();
8675   std::set<int> s2(pt,pt+nbOfTuples);
8676   std::vector<int> r;
8677   std::set_difference(s1.begin(),s1.end(),s2.begin(),s2.end(),std::back_insert_iterator< std::vector<int> >(r));
8678   DataArrayInt *ret=DataArrayInt::New();
8679   ret->alloc((int)r.size(),1);
8680   std::copy(r.begin(),r.end(),ret->getPointer());
8681   return ret;
8682 }
8683
8684 /*!
8685  * \a this is expected to have one component and to be sorted ascendingly (as for \a other).
8686  * \a other is expected to be a part of \a this. If not DataArrayInt::buildSubstraction should be called instead.
8687  * 
8688  * \param [in] other an array with one component and expected to be sorted ascendingly.
8689  * \ret list of ids in \a this but not in \a other.
8690  * \sa DataArrayInt::buildSubstraction
8691  */
8692 DataArrayInt *DataArrayInt::buildSubstractionOptimized(const DataArrayInt *other) const throw(INTERP_KERNEL::Exception)
8693 {
8694   static const char *MSG="DataArrayInt::buildSubstractionOptimized : only single component allowed !";
8695   if(!other) throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstractionOptimized : NULL input array !");
8696   checkAllocated(); other->checkAllocated();
8697   if(getNumberOfComponents()!=1) throw INTERP_KERNEL::Exception(MSG);
8698   if(other->getNumberOfComponents()!=1) throw INTERP_KERNEL::Exception(MSG);
8699   const int *pt1Bg(begin()),*pt1End(end()),*pt2Bg(other->begin()),*pt2End(other->end()),*work1(pt1Bg),*work2(pt2Bg);
8700   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
8701   for(;work1!=pt1End;work1++)
8702     {
8703       if(work2!=pt2End && *work1==*work2)
8704         work2++;
8705       else
8706         ret->pushBackSilent(*work1);
8707     }
8708   return ret.retn();
8709 }
8710
8711
8712 /*!
8713  * Returns a new DataArrayInt which contains all elements of \a this and a given
8714  * one-dimensional not negative arrays. The result array does not contain any duplicates
8715  * and its values are sorted in ascending order.
8716  *  \param [in] other - an array to unite with \a this one.
8717  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
8718  *         array using decrRef() as it is no more needed.
8719  *  \throw If \a this or \a other is not allocated.
8720  *  \throw If \a this->getNumberOfComponents() != 1.
8721  *  \throw If \a other->getNumberOfComponents() != 1.
8722  *  \throw If any value of \a this or \a other is negative.
8723  */
8724 DataArrayInt *DataArrayInt::buildUnion(const DataArrayInt *other) const throw(INTERP_KERNEL::Exception)
8725 {
8726   std::vector<const DataArrayInt *>arrs(2);
8727   arrs[0]=this; arrs[1]=other;
8728   return BuildUnion(arrs);
8729 }
8730
8731
8732 /*!
8733  * Returns a new DataArrayInt which contains elements present in both \a this and a given
8734  * one-dimensional not negative arrays. The result array does not contain any duplicates
8735  * and its values are sorted in ascending order.
8736  *  \param [in] other - an array to intersect with \a this one.
8737  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
8738  *         array using decrRef() as it is no more needed.
8739  *  \throw If \a this or \a other is not allocated.
8740  *  \throw If \a this->getNumberOfComponents() != 1.
8741  *  \throw If \a other->getNumberOfComponents() != 1.
8742  *  \throw If any value of \a this or \a other is negative.
8743  */
8744 DataArrayInt *DataArrayInt::buildIntersection(const DataArrayInt *other) const throw(INTERP_KERNEL::Exception)
8745 {
8746   std::vector<const DataArrayInt *>arrs(2);
8747   arrs[0]=this; arrs[1]=other;
8748   return BuildIntersection(arrs);
8749 }
8750
8751 /*!
8752  * This method can be applied on allocated with one component DataArrayInt instance.
8753  * This method is typically relevant for sorted arrays. All consecutive duplicated items in \a this will appear only once in returned DataArrayInt instance.
8754  * 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]
8755  * 
8756  * \return a newly allocated array that contain the result of the unique operation applied on \a this.
8757  * \throw if \a this is not allocated or if \a this has not exactly one component.
8758  */
8759 DataArrayInt *DataArrayInt::buildUnique() const throw(INTERP_KERNEL::Exception)
8760 {
8761   checkAllocated();
8762   if(getNumberOfComponents()!=1)
8763      throw INTERP_KERNEL::Exception("DataArrayInt::buildUnique : only single component allowed !");
8764   int nbOfTuples=getNumberOfTuples();
8765   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp=deepCpy();
8766   int *data=tmp->getPointer();
8767   int *last=std::unique(data,data+nbOfTuples);
8768   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
8769   ret->alloc(std::distance(data,last),1);
8770   std::copy(data,last,ret->getPointer());
8771   return ret.retn();
8772 }
8773
8774 /*!
8775  * Returns a new DataArrayInt which contains size of every of groups described by \a this
8776  * "index" array. Such "index" array is returned for example by 
8777  * \ref ParaMEDMEM::MEDCouplingUMesh::buildDescendingConnectivity
8778  * "MEDCouplingUMesh::buildDescendingConnectivity" and
8779  * \ref ParaMEDMEM::MEDCouplingUMesh::getNodalConnectivityIndex
8780  * "MEDCouplingUMesh::getNodalConnectivityIndex" etc.
8781  *  \return DataArrayInt * - a new instance of DataArrayInt, whose number of tuples
8782  *          equals to \a this->getNumberOfComponents() - 1, and number of components is 1.
8783  *          The caller is to delete this array using decrRef() as it is no more needed. 
8784  *  \throw If \a this is not allocated.
8785  *  \throw If \a this->getNumberOfComponents() != 1.
8786  *  \throw If \a this->getNumberOfTuples() < 2.
8787  *
8788  *  \b Example: <br> 
8789  *         - this contains [1,3,6,7,7,9,15]
8790  *         - result array contains [2,3,1,0,2,6],
8791  *          where 2 = 3 - 1, 3 = 6 - 3, 1 = 7 - 6 etc.
8792  */
8793 DataArrayInt *DataArrayInt::deltaShiftIndex() const throw(INTERP_KERNEL::Exception)
8794 {
8795   checkAllocated();
8796   if(getNumberOfComponents()!=1)
8797      throw INTERP_KERNEL::Exception("DataArrayInt::deltaShiftIndex : only single component allowed !");
8798   int nbOfTuples=getNumberOfTuples();
8799   if(nbOfTuples<2)
8800     throw INTERP_KERNEL::Exception("DataArrayInt::deltaShiftIndex : 1 tuple at least must be present in 'this' !");
8801   const int *ptr=getConstPointer();
8802   DataArrayInt *ret=DataArrayInt::New();
8803   ret->alloc(nbOfTuples-1,1);
8804   int *out=ret->getPointer();
8805   std::transform(ptr+1,ptr+nbOfTuples,ptr,out,std::minus<int>());
8806   return ret;
8807 }
8808
8809 /*!
8810  * Modifies \a this one-dimensional array so that value of each element \a x
8811  * of \a this array (\a a) is computed as \f$ x_i = \sum_{j=0}^{i-1} a[ j ] \f$.
8812  * Or: for each i>0 new[i]=new[i-1]+old[i-1] for i==0 new[i]=0. Number of tuples
8813  * and components remains the same.<br>
8814  * This method is useful for allToAllV in MPI with contiguous policy. This method
8815  * differs from computeOffsets2() in that the number of tuples is \b not changed by
8816  * this one.
8817  *  \throw If \a this is not allocated.
8818  *  \throw If \a this->getNumberOfComponents() != 1.
8819  *
8820  *  \b Example: <br>
8821  *          - Before \a this contains [3,5,1,2,0,8]
8822  *          - After \a this contains  [0,3,8,9,11,11]<br>
8823  *          Note that the last element 19 = 11 + 8 is missing because size of \a this
8824  *          array is retained and thus there is no space to store the last element.
8825  */
8826 void DataArrayInt::computeOffsets() throw(INTERP_KERNEL::Exception)
8827 {
8828   checkAllocated();
8829   if(getNumberOfComponents()!=1)
8830      throw INTERP_KERNEL::Exception("DataArrayInt::computeOffsets : only single component allowed !");
8831   int nbOfTuples=getNumberOfTuples();
8832   if(nbOfTuples==0)
8833     return ;
8834   int *work=getPointer();
8835   int tmp=work[0];
8836   work[0]=0;
8837   for(int i=1;i<nbOfTuples;i++)
8838     {
8839       int tmp2=work[i];
8840       work[i]=work[i-1]+tmp;
8841       tmp=tmp2;
8842     }
8843   declareAsNew();
8844 }
8845
8846
8847 /*!
8848  * Modifies \a this one-dimensional array so that value of each element \a x
8849  * of \a this array (\a a) is computed as \f$ x_i = \sum_{j=0}^{i-1} a[ j ] \f$.
8850  * Or: for each i>0 new[i]=new[i-1]+old[i-1] for i==0 new[i]=0. Number
8851  * components remains the same and number of tuples is inceamented by one.<br>
8852  * This method is useful for allToAllV in MPI with contiguous policy. This method
8853  * differs from computeOffsets() in that the number of tuples is changed by this one.
8854  *  \throw If \a this is not allocated.
8855  *  \throw If \a this->getNumberOfComponents() != 1.
8856  *
8857  *  \b Example: <br>
8858  *          - Before \a this contains [3,5,1,2,0,8]
8859  *          - After \a this contains  [0,3,8,9,11,11,19]<br>
8860  */
8861 void DataArrayInt::computeOffsets2() throw(INTERP_KERNEL::Exception)
8862 {
8863   checkAllocated();
8864   if(getNumberOfComponents()!=1)
8865     throw INTERP_KERNEL::Exception("DataArrayInt::computeOffsets2 : only single component allowed !");
8866   int nbOfTuples=getNumberOfTuples();
8867   int *ret=new int[nbOfTuples+1];
8868   if(nbOfTuples==0)
8869     return ;
8870   const int *work=getConstPointer();
8871   ret[0]=0;
8872   for(int i=0;i<nbOfTuples;i++)
8873     ret[i+1]=work[i]+ret[i];
8874   useArray(ret,true,CPP_DEALLOC,nbOfTuples+1,1);
8875   declareAsNew();
8876 }
8877
8878 /*!
8879  * Returns two new DataArrayInt instances whose contents is computed from that of \a this and \a listOfIds arrays as follows.
8880  * \a this is expected to be an offset format ( as returned by DataArrayInt::computeOffsets2 ) that is to say with one component
8881  * and ** sorted strictly increasingly **. \a listOfIds is expected to be sorted ascendingly (not strictly needed for \a listOfIds).
8882  * This methods searches in \a this, considered as a set of contiguous \c this->getNumberOfComponents() ranges, all ids in \a listOfIds
8883  * filling completely one of the ranges in \a this.
8884  *
8885  * \param [in] listOfIds a list of ids that has to be sorted ascendingly.
8886  * \param [out] rangeIdsFetched the range ids fetched
8887  * \param [out] idsInInputListThatFetch contains the list of ids in \a listOfIds that are \b fully included in a range in \a this. So
8888  *              \a idsInInputListThatFetch is a part of input \a listOfIds.
8889  *
8890  * \sa DataArrayInt::computeOffsets2
8891  *
8892  *  \b Example: <br>
8893  *          - \a this : [0,3,7,9,15,18]
8894  *          - \a listOfIds contains  [0,1,2,3,7,8,15,16,17]
8895  *          - \a rangeIdsFetched result array: [0,2,4]
8896  *          - \a idsInInputListThatFetch result array: [0,1,2,7,8,15,16,17]
8897  * In this example id 3 in input \a listOfIds is alone so it do not appear in output \a idsInInputListThatFetch.
8898  * <br>
8899  */
8900 void DataArrayInt::searchRangesInListOfIds(const DataArrayInt *listOfIds, DataArrayInt *& rangeIdsFetched, DataArrayInt *& idsInInputListThatFetch) const throw(INTERP_KERNEL::Exception)
8901 {
8902   if(!listOfIds)
8903     throw INTERP_KERNEL::Exception("DataArrayInt::searchRangesInListOfIds : input list of ids is null !");
8904   listOfIds->checkAllocated(); checkAllocated();
8905   if(listOfIds->getNumberOfComponents()!=1)
8906     throw INTERP_KERNEL::Exception("DataArrayInt::searchRangesInListOfIds : input list of ids must have exactly one component !");
8907   if(getNumberOfComponents()!=1)
8908     throw INTERP_KERNEL::Exception("DataArrayInt::searchRangesInListOfIds : this must have exactly one component !");
8909   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret0=DataArrayInt::New(); ret0->alloc(0,1);
8910   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret1=DataArrayInt::New(); ret1->alloc(0,1);
8911   const int *tupEnd(listOfIds->end()),*offBg(begin()),*offEnd(end()-1);
8912   const int *tupPtr(listOfIds->begin()),*offPtr(offBg);
8913   while(tupPtr!=tupEnd && offPtr!=offEnd)
8914     {
8915       if(*tupPtr==*offPtr)
8916         {
8917           int i=offPtr[0];
8918           while(i<offPtr[1] && *tupPtr==i && tupPtr!=tupEnd) { i++; tupPtr++; }
8919           if(i==offPtr[1])
8920             {
8921               ret0->pushBackSilent((int)std::distance(offBg,offPtr));
8922               ret1->pushBackValsSilent(tupPtr-(offPtr[1]-offPtr[0]),tupPtr);
8923               offPtr++;
8924             }
8925         }
8926       else
8927         { if(*tupPtr<*offPtr) tupPtr++; else offPtr++; }
8928     }
8929   rangeIdsFetched=ret0.retn();
8930   idsInInputListThatFetch=ret1.retn();
8931 }
8932
8933 /*!
8934  * Returns a new DataArrayInt whose contents is computed from that of \a this and \a
8935  * offsets arrays as follows. \a offsets is a one-dimensional array considered as an
8936  * "index" array of a "iota" array, thus, whose each element gives an index of a group
8937  * beginning within the "iota" array. And \a this is a one-dimensional array
8938  * considered as a selector of groups described by \a offsets to include into the result array.
8939  *  \throw If \a offsets is NULL.
8940  *  \throw If \a offsets is not allocated.
8941  *  \throw If \a offsets->getNumberOfComponents() != 1.
8942  *  \throw If \a offsets is not monotonically increasing.
8943  *  \throw If \a this is not allocated.
8944  *  \throw If \a this->getNumberOfComponents() != 1.
8945  *  \throw If any element of \a this is not a valid index for \a offsets array.
8946  *
8947  *  \b Example: <br>
8948  *          - \a this: [0,2,3]
8949  *          - \a offsets: [0,3,6,10,14,20]
8950  *          - result array: [0,1,2,6,7,8,9,10,11,12,13] == <br>
8951  *            \c range(0,3) + \c range(6,10) + \c range(10,14) ==<br>
8952  *            \c range( \a offsets[ \a this[0] ], offsets[ \a this[0]+1 ]) + 
8953  *            \c range( \a offsets[ \a this[1] ], offsets[ \a this[1]+1 ]) + 
8954  *            \c range( \a offsets[ \a this[2] ], offsets[ \a this[2]+1 ])
8955  */
8956 DataArrayInt *DataArrayInt::buildExplicitArrByRanges(const DataArrayInt *offsets) const throw(INTERP_KERNEL::Exception)
8957 {
8958   if(!offsets)
8959     throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrByRanges : DataArrayInt pointer in input is NULL !");
8960   checkAllocated();
8961   if(getNumberOfComponents()!=1)
8962      throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrByRanges : only single component allowed !");
8963   offsets->checkAllocated();
8964   if(offsets->getNumberOfComponents()!=1)
8965      throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrByRanges : input array should have only single component !");
8966   int othNbTuples=offsets->getNumberOfTuples()-1;
8967   int nbOfTuples=getNumberOfTuples();
8968   int retNbOftuples=0;
8969   const int *work=getConstPointer();
8970   const int *offPtr=offsets->getConstPointer();
8971   for(int i=0;i<nbOfTuples;i++)
8972     {
8973       int val=work[i];
8974       if(val>=0 && val<othNbTuples)
8975         {
8976           int delta=offPtr[val+1]-offPtr[val];
8977           if(delta>=0)
8978             retNbOftuples+=delta;
8979           else
8980             {
8981               std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrByRanges : Tuple #" << val << " of offset array has a delta < 0 !";
8982               throw INTERP_KERNEL::Exception(oss.str().c_str());
8983             }
8984         }
8985       else
8986         {
8987           std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrByRanges : Tuple #" << i << " in this contains " << val;
8988           oss << " whereas offsets array is of size " << othNbTuples+1 << " !";
8989           throw INTERP_KERNEL::Exception(oss.str().c_str());
8990         }
8991     }
8992   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
8993   ret->alloc(retNbOftuples,1);
8994   int *retPtr=ret->getPointer();
8995   for(int i=0;i<nbOfTuples;i++)
8996     {
8997       int val=work[i];
8998       int start=offPtr[val];
8999       int off=offPtr[val+1]-start;
9000       for(int j=0;j<off;j++,retPtr++)
9001         *retPtr=start+j;
9002     }
9003   return ret.retn();
9004 }
9005
9006 /*!
9007  * 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.
9008  * 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
9009  * in tuple **i** of returned DataArrayInt.
9010  * If ranges overlapped (in theory it should not) this method do not detect it and always returns the first range.
9011  *
9012  * 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)]
9013  * The return DataArrayInt will contain : **[0,4,1,2,2,3]**
9014  * 
9015  * \param [in] ranges typically come from output of MEDCouplingUMesh::ComputeRangesFromTypeDistribution. Each range is specified like this : 1st component is
9016  *             for lower value included and 2nd component is the upper value of corresponding range **excluded**.
9017  * \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
9018  *        is thrown if no ranges in \a ranges contains value in \a this.
9019  * 
9020  * \sa DataArrayInt::findIdInRangeForEachTuple
9021  */
9022 DataArrayInt *DataArrayInt::findRangeIdForEachTuple(const DataArrayInt *ranges) const throw(INTERP_KERNEL::Exception)
9023 {
9024   if(!ranges)
9025     throw INTERP_KERNEL::Exception("DataArrayInt::findRangeIdForEachTuple : null input pointer !");
9026   if(ranges->getNumberOfComponents()!=2)
9027     throw INTERP_KERNEL::Exception("DataArrayInt::findRangeIdForEachTuple : input DataArrayInt instance should have 2 components !");
9028   checkAllocated();
9029   if(getNumberOfComponents()!=1)
9030     throw INTERP_KERNEL::Exception("DataArrayInt::findRangeIdForEachTuple : this should have only one component !");
9031   int nbTuples=getNumberOfTuples();
9032   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbTuples,1);
9033   int nbOfRanges=ranges->getNumberOfTuples();
9034   const int *rangesPtr=ranges->getConstPointer();
9035   int *retPtr=ret->getPointer();
9036   const int *inPtr=getConstPointer();
9037   for(int i=0;i<nbTuples;i++,retPtr++)
9038     {
9039       int val=inPtr[i];
9040       bool found=false;
9041       for(int j=0;j<nbOfRanges && !found;j++)
9042         if(val>=rangesPtr[2*j] && val<rangesPtr[2*j+1])
9043           { *retPtr=j; found=true; }
9044       if(found)
9045         continue;
9046       else
9047         {
9048           std::ostringstream oss; oss << "DataArrayInt::findRangeIdForEachTuple : tuple #" << i << " not found by any ranges !";
9049           throw INTERP_KERNEL::Exception(oss.str().c_str());
9050         }
9051     }
9052   return ret.retn();
9053 }
9054
9055 /*!
9056  * 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.
9057  * 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
9058  * in tuple **i** of returned DataArrayInt.
9059  * If ranges overlapped (in theory it should not) this method do not detect it and always returns the sub position of the first range.
9060  *
9061  * 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)]
9062  * The return DataArrayInt will contain : **[1,2,4,0,2,2]**
9063  * This method is often called in pair with DataArrayInt::findRangeIdForEachTuple method.
9064  * 
9065  * \param [in] ranges typically come from output of MEDCouplingUMesh::ComputeRangesFromTypeDistribution. Each range is specified like this : 1st component is
9066  *             for lower value included and 2nd component is the upper value of corresponding range **excluded**.
9067  * \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
9068  *        is thrown if no ranges in \a ranges contains value in \a this.
9069  * \sa DataArrayInt::findRangeIdForEachTuple
9070  */
9071 DataArrayInt *DataArrayInt::findIdInRangeForEachTuple(const DataArrayInt *ranges) const throw(INTERP_KERNEL::Exception)
9072 {
9073   if(!ranges)
9074     throw INTERP_KERNEL::Exception("DataArrayInt::findIdInRangeForEachTuple : null input pointer !");
9075   if(ranges->getNumberOfComponents()!=2)
9076     throw INTERP_KERNEL::Exception("DataArrayInt::findIdInRangeForEachTuple : input DataArrayInt instance should have 2 components !");
9077   checkAllocated();
9078   if(getNumberOfComponents()!=1)
9079     throw INTERP_KERNEL::Exception("DataArrayInt::findIdInRangeForEachTuple : this should have only one component !");
9080   int nbTuples=getNumberOfTuples();
9081   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbTuples,1);
9082   int nbOfRanges=ranges->getNumberOfTuples();
9083   const int *rangesPtr=ranges->getConstPointer();
9084   int *retPtr=ret->getPointer();
9085   const int *inPtr=getConstPointer();
9086   for(int i=0;i<nbTuples;i++,retPtr++)
9087     {
9088       int val=inPtr[i];
9089       bool found=false;
9090       for(int j=0;j<nbOfRanges && !found;j++)
9091         if(val>=rangesPtr[2*j] && val<rangesPtr[2*j+1])
9092           { *retPtr=val-rangesPtr[2*j]; found=true; }
9093       if(found)
9094         continue;
9095       else
9096         {
9097           std::ostringstream oss; oss << "DataArrayInt::findIdInRangeForEachTuple : tuple #" << i << " not found by any ranges !";
9098           throw INTERP_KERNEL::Exception(oss.str().c_str());
9099         }
9100     }
9101   return ret.retn();
9102 }
9103
9104 /*!
9105  * 
9106  * \param [in] nbTimes specifies the nb of times each tuples in \a this will be duplicated contiguouly in returned DataArrayInt instance.
9107  *             \a nbTimes  should be at least equal to 1.
9108  * \return a newly allocated DataArrayInt having one component and number of tuples equal to \a nbTimes * \c this->getNumberOfTuples.
9109  * \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.
9110  */
9111 DataArrayInt *DataArrayInt::duplicateEachTupleNTimes(int nbTimes) const throw(INTERP_KERNEL::Exception)
9112 {
9113   checkAllocated();
9114   if(getNumberOfComponents()!=1)
9115     throw INTERP_KERNEL::Exception("DataArrayInt::duplicateEachTupleNTimes : this should have only one component !");
9116   if(nbTimes<1)
9117     throw INTERP_KERNEL::Exception("DataArrayInt::duplicateEachTupleNTimes : nb times should be >= 1 !");
9118   int nbTuples=getNumberOfTuples();
9119   const int *inPtr=getConstPointer();
9120   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbTimes*nbTuples,1);
9121   int *retPtr=ret->getPointer();
9122   for(int i=0;i<nbTuples;i++,inPtr++)
9123     {
9124       int val=*inPtr;
9125       for(int j=0;j<nbTimes;j++,retPtr++)
9126         *retPtr=val;
9127     }
9128   ret->copyStringInfoFrom(*this);
9129   return ret.retn();
9130 }
9131
9132 /*!
9133  * This method returns all different values found in \a this. This method throws if \a this has not been allocated.
9134  * But the number of components can be different from one.
9135  * \return a newly allocated array (that should be dealt by the caller) containing different values in \a this.
9136  */
9137 DataArrayInt *DataArrayInt::getDifferentValues() const throw(INTERP_KERNEL::Exception)
9138 {
9139   checkAllocated();
9140   std::set<int> ret;
9141   ret.insert(begin(),end());
9142   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret2=DataArrayInt::New(); ret2->alloc((int)ret.size(),1);
9143   std::copy(ret.begin(),ret.end(),ret2->getPointer());
9144   return ret2.retn();
9145 }
9146
9147 /*!
9148  * This method is a refinement of DataArrayInt::getDifferentValues because it returns not only different values in \a this but also, for each of
9149  * them it tells which tuple id have this id.
9150  * This method works only on arrays with one component (if it is not the case call DataArrayInt::rearrange(1) ).
9151  * This method returns two arrays having same size.
9152  * 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.
9153  * 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]]
9154  */
9155 std::vector<DataArrayInt *> DataArrayInt::partitionByDifferentValues(std::vector<int>& differentIds) const throw(INTERP_KERNEL::Exception)
9156 {
9157   checkAllocated();
9158   if(getNumberOfComponents()!=1)
9159     throw INTERP_KERNEL::Exception("DataArrayInt::partitionByDifferentValues : this should have only one component !");
9160   int id=0;
9161   std::map<int,int> m,m2,m3;
9162   for(const int *w=begin();w!=end();w++)
9163     m[*w]++;
9164   differentIds.resize(m.size());
9165   std::vector<DataArrayInt *> ret(m.size());
9166   std::vector<int *> retPtr(m.size());
9167   for(std::map<int,int>::const_iterator it=m.begin();it!=m.end();it++,id++)
9168     {
9169       m2[(*it).first]=id;
9170       ret[id]=DataArrayInt::New();
9171       ret[id]->alloc((*it).second,1);
9172       retPtr[id]=ret[id]->getPointer();
9173       differentIds[id]=(*it).first;
9174     }
9175   id=0;
9176   for(const int *w=begin();w!=end();w++,id++)
9177     {
9178       retPtr[m2[*w]][m3[*w]++]=id;
9179     }
9180   return ret;
9181 }
9182
9183 /*!
9184  * Returns a new DataArrayInt that is a sum of two given arrays. There are 3
9185  * valid cases.
9186  * 1.  The arrays have same number of tuples and components. Then each value of
9187  *   the result array (_a_) is a sum of the corresponding values of \a a1 and \a a2,
9188  *   i.e.: _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ i, j ].
9189  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
9190  *   component. Then
9191  *   _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ i, 0 ].
9192  * 3.  The arrays have same number of components and one array, say _a2_, has one
9193  *   tuple. Then
9194  *   _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ 0, j ].
9195  *
9196  * Info on components is copied either from the first array (in the first case) or from
9197  * the array with maximal number of elements (getNbOfElems()).
9198  *  \param [in] a1 - an array to sum up.
9199  *  \param [in] a2 - another array to sum up.
9200  *  \return DataArrayInt * - the new instance of DataArrayInt.
9201  *          The caller is to delete this result array using decrRef() as it is no more
9202  *          needed.
9203  *  \throw If either \a a1 or \a a2 is NULL.
9204  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
9205  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
9206  *         none of them has number of tuples or components equal to 1.
9207  */
9208 DataArrayInt *DataArrayInt::Add(const DataArrayInt *a1, const DataArrayInt *a2) throw(INTERP_KERNEL::Exception)
9209 {
9210   if(!a1 || !a2)
9211     throw INTERP_KERNEL::Exception("DataArrayInt::Add : input DataArrayInt instance is NULL !");
9212   int nbOfTuple=a1->getNumberOfTuples();
9213   int nbOfTuple2=a2->getNumberOfTuples();
9214   int nbOfComp=a1->getNumberOfComponents();
9215   int nbOfComp2=a2->getNumberOfComponents();
9216   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=0;
9217   if(nbOfTuple==nbOfTuple2)
9218     {
9219       if(nbOfComp==nbOfComp2)
9220         {
9221           ret=DataArrayInt::New();
9222           ret->alloc(nbOfTuple,nbOfComp);
9223           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::plus<int>());
9224           ret->copyStringInfoFrom(*a1);
9225         }
9226       else
9227         {
9228           int nbOfCompMin,nbOfCompMax;
9229           const DataArrayInt *aMin, *aMax;
9230           if(nbOfComp>nbOfComp2)
9231             {
9232               nbOfCompMin=nbOfComp2; nbOfCompMax=nbOfComp;
9233               aMin=a2; aMax=a1;
9234             }
9235           else
9236             {
9237               nbOfCompMin=nbOfComp; nbOfCompMax=nbOfComp2;
9238               aMin=a1; aMax=a2;
9239             }
9240           if(nbOfCompMin==1)
9241             {
9242               ret=DataArrayInt::New();
9243               ret->alloc(nbOfTuple,nbOfCompMax);
9244               const int *aMinPtr=aMin->getConstPointer();
9245               const int *aMaxPtr=aMax->getConstPointer();
9246               int *res=ret->getPointer();
9247               for(int i=0;i<nbOfTuple;i++)
9248                 res=std::transform(aMaxPtr+i*nbOfCompMax,aMaxPtr+(i+1)*nbOfCompMax,res,std::bind2nd(std::plus<int>(),aMinPtr[i]));
9249               ret->copyStringInfoFrom(*aMax);
9250             }
9251           else
9252             throw INTERP_KERNEL::Exception("Nb of components mismatch for array Add !");
9253         }
9254     }
9255   else if((nbOfTuple==1 && nbOfTuple2>1) || (nbOfTuple>1 && nbOfTuple2==1))
9256     {
9257       if(nbOfComp==nbOfComp2)
9258         {
9259           int nbOfTupleMax=std::max(nbOfTuple,nbOfTuple2);
9260           const DataArrayInt *aMin=nbOfTuple>nbOfTuple2?a2:a1;
9261           const DataArrayInt *aMax=nbOfTuple>nbOfTuple2?a1:a2;
9262           const int *aMinPtr=aMin->getConstPointer(),*aMaxPtr=aMax->getConstPointer();
9263           ret=DataArrayInt::New();
9264           ret->alloc(nbOfTupleMax,nbOfComp);
9265           int *res=ret->getPointer();
9266           for(int i=0;i<nbOfTupleMax;i++)
9267             res=std::transform(aMaxPtr+i*nbOfComp,aMaxPtr+(i+1)*nbOfComp,aMinPtr,res,std::plus<int>());
9268           ret->copyStringInfoFrom(*aMax);
9269         }
9270       else
9271         throw INTERP_KERNEL::Exception("Nb of components mismatch for array Add !");
9272     }
9273   else
9274     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Add !");
9275   return ret.retn();
9276 }
9277
9278 /*!
9279  * Adds values of another DataArrayInt to values of \a this one. There are 3
9280  * valid cases.
9281  * 1.  The arrays have same number of tuples and components. Then each value of
9282  *   \a other array is added to the corresponding value of \a this array, i.e.:
9283  *   _a_ [ i, j ] += _other_ [ i, j ].
9284  * 2.  The arrays have same number of tuples and \a other array has one component. Then
9285  *   _a_ [ i, j ] += _other_ [ i, 0 ].
9286  * 3.  The arrays have same number of components and \a other array has one tuple. Then
9287  *   _a_ [ i, j ] += _a2_ [ 0, j ].
9288  *
9289  *  \param [in] other - an array to add to \a this one.
9290  *  \throw If \a other is NULL.
9291  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
9292  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
9293  *         \a other has number of both tuples and components not equal to 1.
9294  */
9295 void DataArrayInt::addEqual(const DataArrayInt *other) throw(INTERP_KERNEL::Exception)
9296 {
9297   if(!other)
9298     throw INTERP_KERNEL::Exception("DataArrayInt::addEqual : input DataArrayInt instance is NULL !");
9299   const char *msg="Nb of tuples mismatch for DataArrayInt::addEqual  !";
9300   checkAllocated(); other->checkAllocated();
9301   int nbOfTuple=getNumberOfTuples();
9302   int nbOfTuple2=other->getNumberOfTuples();
9303   int nbOfComp=getNumberOfComponents();
9304   int nbOfComp2=other->getNumberOfComponents();
9305   if(nbOfTuple==nbOfTuple2)
9306     {
9307       if(nbOfComp==nbOfComp2)
9308         {
9309           std::transform(begin(),end(),other->begin(),getPointer(),std::plus<int>());
9310         }
9311       else if(nbOfComp2==1)
9312         {
9313           int *ptr=getPointer();
9314           const int *ptrc=other->getConstPointer();
9315           for(int i=0;i<nbOfTuple;i++)
9316             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::plus<int>(),*ptrc++));
9317         }
9318       else
9319         throw INTERP_KERNEL::Exception(msg);
9320     }
9321   else if(nbOfTuple2==1)
9322     {
9323       if(nbOfComp2==nbOfComp)
9324         {
9325           int *ptr=getPointer();
9326           const int *ptrc=other->getConstPointer();
9327           for(int i=0;i<nbOfTuple;i++)
9328             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::plus<int>());
9329         }
9330       else
9331         throw INTERP_KERNEL::Exception(msg);
9332     }
9333   else
9334     throw INTERP_KERNEL::Exception(msg);
9335   declareAsNew();
9336 }
9337
9338 /*!
9339  * Returns a new DataArrayInt that is a subtraction of two given arrays. There are 3
9340  * valid cases.
9341  * 1.  The arrays have same number of tuples and components. Then each value of
9342  *   the result array (_a_) is a subtraction of the corresponding values of \a a1 and
9343  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ i, j ].
9344  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
9345  *   component. Then
9346  *   _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ i, 0 ].
9347  * 3.  The arrays have same number of components and one array, say _a2_, has one
9348  *   tuple. Then
9349  *   _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ 0, j ].
9350  *
9351  * Info on components is copied either from the first array (in the first case) or from
9352  * the array with maximal number of elements (getNbOfElems()).
9353  *  \param [in] a1 - an array to subtract from.
9354  *  \param [in] a2 - an array to subtract.
9355  *  \return DataArrayInt * - the new instance of DataArrayInt.
9356  *          The caller is to delete this result array using decrRef() as it is no more
9357  *          needed.
9358  *  \throw If either \a a1 or \a a2 is NULL.
9359  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
9360  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
9361  *         none of them has number of tuples or components equal to 1.
9362  */
9363 DataArrayInt *DataArrayInt::Substract(const DataArrayInt *a1, const DataArrayInt *a2) throw(INTERP_KERNEL::Exception)
9364 {
9365   if(!a1 || !a2)
9366     throw INTERP_KERNEL::Exception("DataArrayInt::Substract : input DataArrayInt instance is NULL !");
9367   int nbOfTuple1=a1->getNumberOfTuples();
9368   int nbOfTuple2=a2->getNumberOfTuples();
9369   int nbOfComp1=a1->getNumberOfComponents();
9370   int nbOfComp2=a2->getNumberOfComponents();
9371   if(nbOfTuple2==nbOfTuple1)
9372     {
9373       if(nbOfComp1==nbOfComp2)
9374         {
9375           MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
9376           ret->alloc(nbOfTuple2,nbOfComp1);
9377           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::minus<int>());
9378           ret->copyStringInfoFrom(*a1);
9379           return ret.retn();
9380         }
9381       else if(nbOfComp2==1)
9382         {
9383           MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
9384           ret->alloc(nbOfTuple1,nbOfComp1);
9385           const int *a2Ptr=a2->getConstPointer();
9386           const int *a1Ptr=a1->getConstPointer();
9387           int *res=ret->getPointer();
9388           for(int i=0;i<nbOfTuple1;i++)
9389             res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::minus<int>(),a2Ptr[i]));
9390           ret->copyStringInfoFrom(*a1);
9391           return ret.retn();
9392         }
9393       else
9394         {
9395           a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Substract !");
9396           return 0;
9397         }
9398     }
9399   else if(nbOfTuple2==1)
9400     {
9401       a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Substract !");
9402       MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
9403       ret->alloc(nbOfTuple1,nbOfComp1);
9404       const int *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
9405       int *pt=ret->getPointer();
9406       for(int i=0;i<nbOfTuple1;i++)
9407         pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::minus<int>());
9408       ret->copyStringInfoFrom(*a1);
9409       return ret.retn();
9410     }
9411   else
9412     {
9413       a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Substract !");//will always throw an exception
9414       return 0;
9415     }
9416 }
9417
9418 /*!
9419  * Subtract values of another DataArrayInt from values of \a this one. There are 3
9420  * valid cases.
9421  * 1.  The arrays have same number of tuples and components. Then each value of
9422  *   \a other array is subtracted from the corresponding value of \a this array, i.e.:
9423  *   _a_ [ i, j ] -= _other_ [ i, j ].
9424  * 2.  The arrays have same number of tuples and \a other array has one component. Then
9425  *   _a_ [ i, j ] -= _other_ [ i, 0 ].
9426  * 3.  The arrays have same number of components and \a other array has one tuple. Then
9427  *   _a_ [ i, j ] -= _a2_ [ 0, j ].
9428  *
9429  *  \param [in] other - an array to subtract from \a this one.
9430  *  \throw If \a other is NULL.
9431  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
9432  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
9433  *         \a other has number of both tuples and components not equal to 1.
9434  */
9435 void DataArrayInt::substractEqual(const DataArrayInt *other) throw(INTERP_KERNEL::Exception)
9436 {
9437   if(!other)
9438     throw INTERP_KERNEL::Exception("DataArrayInt::substractEqual : input DataArrayInt instance is NULL !");
9439   const char *msg="Nb of tuples mismatch for DataArrayInt::substractEqual  !";
9440   checkAllocated(); other->checkAllocated();
9441   int nbOfTuple=getNumberOfTuples();
9442   int nbOfTuple2=other->getNumberOfTuples();
9443   int nbOfComp=getNumberOfComponents();
9444   int nbOfComp2=other->getNumberOfComponents();
9445   if(nbOfTuple==nbOfTuple2)
9446     {
9447       if(nbOfComp==nbOfComp2)
9448         {
9449           std::transform(begin(),end(),other->begin(),getPointer(),std::minus<int>());
9450         }
9451       else if(nbOfComp2==1)
9452         {
9453           int *ptr=getPointer();
9454           const int *ptrc=other->getConstPointer();
9455           for(int i=0;i<nbOfTuple;i++)
9456             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::minus<int>(),*ptrc++));
9457         }
9458       else
9459         throw INTERP_KERNEL::Exception(msg);
9460     }
9461   else if(nbOfTuple2==1)
9462     {
9463       int *ptr=getPointer();
9464       const int *ptrc=other->getConstPointer();
9465       for(int i=0;i<nbOfTuple;i++)
9466         std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::minus<int>());
9467     }
9468   else
9469     throw INTERP_KERNEL::Exception(msg);
9470   declareAsNew();
9471 }
9472
9473 /*!
9474  * Returns a new DataArrayInt that is a product of two given arrays. There are 3
9475  * valid cases.
9476  * 1.  The arrays have same number of tuples and components. Then each value of
9477  *   the result array (_a_) is a product of the corresponding values of \a a1 and
9478  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ i, j ].
9479  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
9480  *   component. Then
9481  *   _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ i, 0 ].
9482  * 3.  The arrays have same number of components and one array, say _a2_, has one
9483  *   tuple. Then
9484  *   _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ 0, j ].
9485  *
9486  * Info on components is copied either from the first array (in the first case) or from
9487  * the array with maximal number of elements (getNbOfElems()).
9488  *  \param [in] a1 - a factor array.
9489  *  \param [in] a2 - another factor array.
9490  *  \return DataArrayInt * - the new instance of DataArrayInt.
9491  *          The caller is to delete this result array using decrRef() as it is no more
9492  *          needed.
9493  *  \throw If either \a a1 or \a a2 is NULL.
9494  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
9495  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
9496  *         none of them has number of tuples or components equal to 1.
9497  */
9498 DataArrayInt *DataArrayInt::Multiply(const DataArrayInt *a1, const DataArrayInt *a2) throw(INTERP_KERNEL::Exception)
9499 {
9500   if(!a1 || !a2)
9501     throw INTERP_KERNEL::Exception("DataArrayInt::Multiply : input DataArrayInt instance is NULL !");
9502   int nbOfTuple=a1->getNumberOfTuples();
9503   int nbOfTuple2=a2->getNumberOfTuples();
9504   int nbOfComp=a1->getNumberOfComponents();
9505   int nbOfComp2=a2->getNumberOfComponents();
9506   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=0;
9507   if(nbOfTuple==nbOfTuple2)
9508     {
9509       if(nbOfComp==nbOfComp2)
9510         {
9511           ret=DataArrayInt::New();
9512           ret->alloc(nbOfTuple,nbOfComp);
9513           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::multiplies<int>());
9514           ret->copyStringInfoFrom(*a1);
9515         }
9516       else
9517         {
9518           int nbOfCompMin,nbOfCompMax;
9519           const DataArrayInt *aMin, *aMax;
9520           if(nbOfComp>nbOfComp2)
9521             {
9522               nbOfCompMin=nbOfComp2; nbOfCompMax=nbOfComp;
9523               aMin=a2; aMax=a1;
9524             }
9525           else
9526             {
9527               nbOfCompMin=nbOfComp; nbOfCompMax=nbOfComp2;
9528               aMin=a1; aMax=a2;
9529             }
9530           if(nbOfCompMin==1)
9531             {
9532               ret=DataArrayInt::New();
9533               ret->alloc(nbOfTuple,nbOfCompMax);
9534               const int *aMinPtr=aMin->getConstPointer();
9535               const int *aMaxPtr=aMax->getConstPointer();
9536               int *res=ret->getPointer();
9537               for(int i=0;i<nbOfTuple;i++)
9538                 res=std::transform(aMaxPtr+i*nbOfCompMax,aMaxPtr+(i+1)*nbOfCompMax,res,std::bind2nd(std::multiplies<int>(),aMinPtr[i]));
9539               ret->copyStringInfoFrom(*aMax);
9540             }
9541           else
9542             throw INTERP_KERNEL::Exception("Nb of components mismatch for array Multiply !");
9543         }
9544     }
9545   else if((nbOfTuple==1 && nbOfTuple2>1) || (nbOfTuple>1 && nbOfTuple2==1))
9546     {
9547       if(nbOfComp==nbOfComp2)
9548         {
9549           int nbOfTupleMax=std::max(nbOfTuple,nbOfTuple2);
9550           const DataArrayInt *aMin=nbOfTuple>nbOfTuple2?a2:a1;
9551           const DataArrayInt *aMax=nbOfTuple>nbOfTuple2?a1:a2;
9552           const int *aMinPtr=aMin->getConstPointer(),*aMaxPtr=aMax->getConstPointer();
9553           ret=DataArrayInt::New();
9554           ret->alloc(nbOfTupleMax,nbOfComp);
9555           int *res=ret->getPointer();
9556           for(int i=0;i<nbOfTupleMax;i++)
9557             res=std::transform(aMaxPtr+i*nbOfComp,aMaxPtr+(i+1)*nbOfComp,aMinPtr,res,std::multiplies<int>());
9558           ret->copyStringInfoFrom(*aMax);
9559         }
9560       else
9561         throw INTERP_KERNEL::Exception("Nb of components mismatch for array Multiply !");
9562     }
9563   else
9564     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Multiply !");
9565   return ret.retn();
9566 }
9567
9568
9569 /*!
9570  * Multiply values of another DataArrayInt to values of \a this one. There are 3
9571  * valid cases.
9572  * 1.  The arrays have same number of tuples and components. Then each value of
9573  *   \a other array is multiplied to the corresponding value of \a this array, i.e.:
9574  *   _a_ [ i, j ] *= _other_ [ i, j ].
9575  * 2.  The arrays have same number of tuples and \a other array has one component. Then
9576  *   _a_ [ i, j ] *= _other_ [ i, 0 ].
9577  * 3.  The arrays have same number of components and \a other array has one tuple. Then
9578  *   _a_ [ i, j ] *= _a2_ [ 0, j ].
9579  *
9580  *  \param [in] other - an array to multiply to \a this one.
9581  *  \throw If \a other is NULL.
9582  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
9583  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
9584  *         \a other has number of both tuples and components not equal to 1.
9585  */
9586 void DataArrayInt::multiplyEqual(const DataArrayInt *other) throw(INTERP_KERNEL::Exception)
9587 {
9588   if(!other)
9589     throw INTERP_KERNEL::Exception("DataArrayInt::multiplyEqual : input DataArrayInt instance is NULL !");
9590   const char *msg="Nb of tuples mismatch for DataArrayInt::multiplyEqual !";
9591   checkAllocated(); other->checkAllocated();
9592   int nbOfTuple=getNumberOfTuples();
9593   int nbOfTuple2=other->getNumberOfTuples();
9594   int nbOfComp=getNumberOfComponents();
9595   int nbOfComp2=other->getNumberOfComponents();
9596   if(nbOfTuple==nbOfTuple2)
9597     {
9598       if(nbOfComp==nbOfComp2)
9599         {
9600           std::transform(begin(),end(),other->begin(),getPointer(),std::multiplies<int>());
9601         }
9602       else if(nbOfComp2==1)
9603         {
9604           int *ptr=getPointer();
9605           const int *ptrc=other->getConstPointer();
9606           for(int i=0;i<nbOfTuple;i++)
9607             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::multiplies<int>(),*ptrc++));    
9608         }
9609       else
9610         throw INTERP_KERNEL::Exception(msg);
9611     }
9612   else if(nbOfTuple2==1)
9613     {
9614       if(nbOfComp2==nbOfComp)
9615         {
9616           int *ptr=getPointer();
9617           const int *ptrc=other->getConstPointer();
9618           for(int i=0;i<nbOfTuple;i++)
9619             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::multiplies<int>());
9620         }
9621       else
9622         throw INTERP_KERNEL::Exception(msg);
9623     }
9624   else
9625     throw INTERP_KERNEL::Exception(msg);
9626   declareAsNew();
9627 }
9628
9629
9630 /*!
9631  * Returns a new DataArrayInt that is a division of two given arrays. There are 3
9632  * valid cases.
9633  * 1.  The arrays have same number of tuples and components. Then each value of
9634  *   the result array (_a_) is a division of the corresponding values of \a a1 and
9635  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ i, j ].
9636  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
9637  *   component. Then
9638  *   _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ i, 0 ].
9639  * 3.  The arrays have same number of components and one array, say _a2_, has one
9640  *   tuple. Then
9641  *   _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ 0, j ].
9642  *
9643  * Info on components is copied either from the first array (in the first case) or from
9644  * the array with maximal number of elements (getNbOfElems()).
9645  *  \warning No check of division by zero is performed!
9646  *  \param [in] a1 - a numerator array.
9647  *  \param [in] a2 - a denominator array.
9648  *  \return DataArrayInt * - the new instance of DataArrayInt.
9649  *          The caller is to delete this result array using decrRef() as it is no more
9650  *          needed.
9651  *  \throw If either \a a1 or \a a2 is NULL.
9652  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
9653  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
9654  *         none of them has number of tuples or components equal to 1.
9655  */
9656 DataArrayInt *DataArrayInt::Divide(const DataArrayInt *a1, const DataArrayInt *a2) throw(INTERP_KERNEL::Exception)
9657 {
9658   if(!a1 || !a2)
9659     throw INTERP_KERNEL::Exception("DataArrayInt::Divide : input DataArrayInt instance is NULL !");
9660   int nbOfTuple1=a1->getNumberOfTuples();
9661   int nbOfTuple2=a2->getNumberOfTuples();
9662   int nbOfComp1=a1->getNumberOfComponents();
9663   int nbOfComp2=a2->getNumberOfComponents();
9664   if(nbOfTuple2==nbOfTuple1)
9665     {
9666       if(nbOfComp1==nbOfComp2)
9667         {
9668           MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
9669           ret->alloc(nbOfTuple2,nbOfComp1);
9670           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::divides<int>());
9671           ret->copyStringInfoFrom(*a1);
9672           return ret.retn();
9673         }
9674       else if(nbOfComp2==1)
9675         {
9676           MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
9677           ret->alloc(nbOfTuple1,nbOfComp1);
9678           const int *a2Ptr=a2->getConstPointer();
9679           const int *a1Ptr=a1->getConstPointer();
9680           int *res=ret->getPointer();
9681           for(int i=0;i<nbOfTuple1;i++)
9682             res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::divides<int>(),a2Ptr[i]));
9683           ret->copyStringInfoFrom(*a1);
9684           return ret.retn();
9685         }
9686       else
9687         {
9688           a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Divide !");
9689           return 0;
9690         }
9691     }
9692   else if(nbOfTuple2==1)
9693     {
9694       a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Divide !");
9695       MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
9696       ret->alloc(nbOfTuple1,nbOfComp1);
9697       const int *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
9698       int *pt=ret->getPointer();
9699       for(int i=0;i<nbOfTuple1;i++)
9700         pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::divides<int>());
9701       ret->copyStringInfoFrom(*a1);
9702       return ret.retn();
9703     }
9704   else
9705     {
9706       a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Divide !");//will always throw an exception
9707       return 0;
9708     }
9709 }
9710
9711 /*!
9712  * Divide values of \a this array by values of another DataArrayInt. There are 3
9713  * valid cases.
9714  * 1.  The arrays have same number of tuples and components. Then each value of
9715  *    \a this array is divided by the corresponding value of \a other one, i.e.:
9716  *   _a_ [ i, j ] /= _other_ [ i, j ].
9717  * 2.  The arrays have same number of tuples and \a other array has one component. Then
9718  *   _a_ [ i, j ] /= _other_ [ i, 0 ].
9719  * 3.  The arrays have same number of components and \a other array has one tuple. Then
9720  *   _a_ [ i, j ] /= _a2_ [ 0, j ].
9721  *
9722  *  \warning No check of division by zero is performed!
9723  *  \param [in] other - an array to divide \a this one by.
9724  *  \throw If \a other is NULL.
9725  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
9726  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
9727  *         \a other has number of both tuples and components not equal to 1.
9728  */
9729 void DataArrayInt::divideEqual(const DataArrayInt *other) throw(INTERP_KERNEL::Exception)
9730 {
9731   if(!other)
9732     throw INTERP_KERNEL::Exception("DataArrayInt::divideEqual : input DataArrayInt instance is NULL !");
9733   const char *msg="Nb of tuples mismatch for DataArrayInt::divideEqual !";
9734   checkAllocated(); other->checkAllocated();
9735   int nbOfTuple=getNumberOfTuples();
9736   int nbOfTuple2=other->getNumberOfTuples();
9737   int nbOfComp=getNumberOfComponents();
9738   int nbOfComp2=other->getNumberOfComponents();
9739   if(nbOfTuple==nbOfTuple2)
9740     {
9741       if(nbOfComp==nbOfComp2)
9742         {
9743           std::transform(begin(),end(),other->begin(),getPointer(),std::divides<int>());
9744         }
9745       else if(nbOfComp2==1)
9746         {
9747           int *ptr=getPointer();
9748           const int *ptrc=other->getConstPointer();
9749           for(int i=0;i<nbOfTuple;i++)
9750             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::divides<int>(),*ptrc++));
9751         }
9752       else
9753         throw INTERP_KERNEL::Exception(msg);
9754     }
9755   else if(nbOfTuple2==1)
9756     {
9757       if(nbOfComp2==nbOfComp)
9758         {
9759           int *ptr=getPointer();
9760           const int *ptrc=other->getConstPointer();
9761           for(int i=0;i<nbOfTuple;i++)
9762             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::divides<int>());
9763         }
9764       else
9765         throw INTERP_KERNEL::Exception(msg);
9766     }
9767   else
9768     throw INTERP_KERNEL::Exception(msg);
9769   declareAsNew();
9770 }
9771
9772
9773 /*!
9774  * Returns a new DataArrayInt that is a modulus of two given arrays. There are 3
9775  * valid cases.
9776  * 1.  The arrays have same number of tuples and components. Then each value of
9777  *   the result array (_a_) is a division of the corresponding values of \a a1 and
9778  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] % _a2_ [ i, j ].
9779  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
9780  *   component. Then
9781  *   _a_ [ i, j ] = _a1_ [ i, j ] % _a2_ [ i, 0 ].
9782  * 3.  The arrays have same number of components and one array, say _a2_, has one
9783  *   tuple. Then
9784  *   _a_ [ i, j ] = _a1_ [ i, j ] % _a2_ [ 0, j ].
9785  *
9786  * Info on components is copied either from the first array (in the first case) or from
9787  * the array with maximal number of elements (getNbOfElems()).
9788  *  \warning No check of division by zero is performed!
9789  *  \param [in] a1 - a dividend array.
9790  *  \param [in] a2 - a divisor array.
9791  *  \return DataArrayInt * - the new instance of DataArrayInt.
9792  *          The caller is to delete this result array using decrRef() as it is no more
9793  *          needed.
9794  *  \throw If either \a a1 or \a a2 is NULL.
9795  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
9796  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
9797  *         none of them has number of tuples or components equal to 1.
9798  */
9799 DataArrayInt *DataArrayInt::Modulus(const DataArrayInt *a1, const DataArrayInt *a2) throw(INTERP_KERNEL::Exception)
9800 {
9801     if(!a1 || !a2)
9802     throw INTERP_KERNEL::Exception("DataArrayInt::Modulus : input DataArrayInt instance is NULL !");
9803   int nbOfTuple1=a1->getNumberOfTuples();
9804   int nbOfTuple2=a2->getNumberOfTuples();
9805   int nbOfComp1=a1->getNumberOfComponents();
9806   int nbOfComp2=a2->getNumberOfComponents();
9807   if(nbOfTuple2==nbOfTuple1)
9808     {
9809       if(nbOfComp1==nbOfComp2)
9810         {
9811           MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
9812           ret->alloc(nbOfTuple2,nbOfComp1);
9813           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::modulus<int>());
9814           ret->copyStringInfoFrom(*a1);
9815           return ret.retn();
9816         }
9817       else if(nbOfComp2==1)
9818         {
9819           MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
9820           ret->alloc(nbOfTuple1,nbOfComp1);
9821           const int *a2Ptr=a2->getConstPointer();
9822           const int *a1Ptr=a1->getConstPointer();
9823           int *res=ret->getPointer();
9824           for(int i=0;i<nbOfTuple1;i++)
9825             res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::modulus<int>(),a2Ptr[i]));
9826           ret->copyStringInfoFrom(*a1);
9827           return ret.retn();
9828         }
9829       else
9830         {
9831           a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Modulus !");
9832           return 0;
9833         }
9834     }
9835   else if(nbOfTuple2==1)
9836     {
9837       a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Modulus !");
9838       MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
9839       ret->alloc(nbOfTuple1,nbOfComp1);
9840       const int *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
9841       int *pt=ret->getPointer();
9842       for(int i=0;i<nbOfTuple1;i++)
9843         pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::modulus<int>());
9844       ret->copyStringInfoFrom(*a1);
9845       return ret.retn();
9846     }
9847   else
9848     {
9849       a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Modulus !");//will always throw an exception
9850       return 0;
9851     }
9852 }
9853
9854 /*!
9855  * Modify \a this array so that each value becomes a modulus of division of this value by
9856  * a value of another DataArrayInt. There are 3 valid cases.
9857  * 1.  The arrays have same number of tuples and components. Then each value of
9858  *    \a this array is divided by the corresponding value of \a other one, i.e.:
9859  *   _a_ [ i, j ] %= _other_ [ i, j ].
9860  * 2.  The arrays have same number of tuples and \a other array has one component. Then
9861  *   _a_ [ i, j ] %= _other_ [ i, 0 ].
9862  * 3.  The arrays have same number of components and \a other array has one tuple. Then
9863  *   _a_ [ i, j ] %= _a2_ [ 0, j ].
9864  *
9865  *  \warning No check of division by zero is performed!
9866  *  \param [in] other - a divisor array.
9867  *  \throw If \a other is NULL.
9868  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
9869  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
9870  *         \a other has number of both tuples and components not equal to 1.
9871  */
9872 void DataArrayInt::modulusEqual(const DataArrayInt *other) throw(INTERP_KERNEL::Exception)
9873 {
9874   if(!other)
9875     throw INTERP_KERNEL::Exception("DataArrayInt::modulusEqual : input DataArrayInt instance is NULL !");
9876   const char *msg="Nb of tuples mismatch for DataArrayInt::modulusEqual !";
9877   checkAllocated(); other->checkAllocated();
9878   int nbOfTuple=getNumberOfTuples();
9879   int nbOfTuple2=other->getNumberOfTuples();
9880   int nbOfComp=getNumberOfComponents();
9881   int nbOfComp2=other->getNumberOfComponents();
9882   if(nbOfTuple==nbOfTuple2)
9883     {
9884       if(nbOfComp==nbOfComp2)
9885         {
9886           std::transform(begin(),end(),other->begin(),getPointer(),std::modulus<int>());
9887         }
9888       else if(nbOfComp2==1)
9889         {
9890           if(nbOfComp2==nbOfComp)
9891             {
9892               int *ptr=getPointer();
9893               const int *ptrc=other->getConstPointer();
9894               for(int i=0;i<nbOfTuple;i++)
9895                 std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::modulus<int>(),*ptrc++));
9896             }
9897           else
9898             throw INTERP_KERNEL::Exception(msg);
9899         }
9900       else
9901         throw INTERP_KERNEL::Exception(msg);
9902     }
9903   else if(nbOfTuple2==1)
9904     {
9905       int *ptr=getPointer();
9906       const int *ptrc=other->getConstPointer();
9907       for(int i=0;i<nbOfTuple;i++)
9908         std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::modulus<int>());
9909     }
9910   else
9911     throw INTERP_KERNEL::Exception(msg);
9912   declareAsNew();
9913 }
9914
9915 /*!
9916  * Returns a new DataArrayInt that is the result of pow of two given arrays. There are 3
9917  * valid cases.
9918  *
9919  *  \param [in] a1 - an array to pow up.
9920  *  \param [in] a2 - another array to sum up.
9921  *  \return DataArrayInt * - the new instance of DataArrayInt.
9922  *          The caller is to delete this result array using decrRef() as it is no more
9923  *          needed.
9924  *  \throw If either \a a1 or \a a2 is NULL.
9925  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
9926  *  \throw If \a a1->getNumberOfComponents() != 1 or \a a2->getNumberOfComponents() != 1.
9927  *  \throw If there is a negative value in \a a2.
9928  */
9929 DataArrayInt *DataArrayInt::Pow(const DataArrayInt *a1, const DataArrayInt *a2) throw(INTERP_KERNEL::Exception)
9930 {
9931   if(!a1 || !a2)
9932     throw INTERP_KERNEL::Exception("DataArrayInt::Pow : at least one of input instances is null !");
9933   int nbOfTuple=a1->getNumberOfTuples();
9934   int nbOfTuple2=a2->getNumberOfTuples();
9935   int nbOfComp=a1->getNumberOfComponents();
9936   int nbOfComp2=a2->getNumberOfComponents();
9937   if(nbOfTuple!=nbOfTuple2)
9938     throw INTERP_KERNEL::Exception("DataArrayInt::Pow : number of tuples mismatches !");
9939   if(nbOfComp!=1 || nbOfComp2!=1)
9940     throw INTERP_KERNEL::Exception("DataArrayInt::Pow : number of components of both arrays must be equal to 1 !");
9941   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbOfTuple,1);
9942   const int *ptr1(a1->begin()),*ptr2(a2->begin());
9943   int *ptr=ret->getPointer();
9944   for(int i=0;i<nbOfTuple;i++,ptr1++,ptr2++,ptr++)
9945     {
9946       if(*ptr2>=0)
9947         {
9948           int tmp=1;
9949           for(int j=0;j<*ptr2;j++)
9950             tmp*=*ptr1;
9951           *ptr=tmp;
9952         }
9953       else
9954         {
9955           std::ostringstream oss; oss << "DataArrayInt::Pow : on tuple #" << i << " of a2 value is < 0 (" << *ptr2 << ") !";
9956           throw INTERP_KERNEL::Exception(oss.str().c_str());
9957         }
9958     }
9959   return ret.retn();
9960 }
9961
9962 /*!
9963  * Apply pow on values of another DataArrayInt to values of \a this one.
9964  *
9965  *  \param [in] other - an array to pow to \a this one.
9966  *  \throw If \a other is NULL.
9967  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples()
9968  *  \throw If \a this->getNumberOfComponents() != 1 or \a other->getNumberOfComponents() != 1
9969  *  \throw If there is a negative value in \a other.
9970  */
9971 void DataArrayInt::powEqual(const DataArrayInt *other) throw(INTERP_KERNEL::Exception)
9972 {
9973   if(!other)
9974     throw INTERP_KERNEL::Exception("DataArrayInt::powEqual : input instance is null !");
9975   int nbOfTuple=getNumberOfTuples();
9976   int nbOfTuple2=other->getNumberOfTuples();
9977   int nbOfComp=getNumberOfComponents();
9978   int nbOfComp2=other->getNumberOfComponents();
9979   if(nbOfTuple!=nbOfTuple2)
9980     throw INTERP_KERNEL::Exception("DataArrayInt::powEqual : number of tuples mismatches !");
9981   if(nbOfComp!=1 || nbOfComp2!=1)
9982     throw INTERP_KERNEL::Exception("DataArrayInt::powEqual : number of components of both arrays must be equal to 1 !");
9983   int *ptr=getPointer();
9984   const int *ptrc=other->begin();
9985   for(int i=0;i<nbOfTuple;i++,ptrc++,ptr++)
9986     {
9987       if(*ptrc>=0)
9988         {
9989           int tmp=1;
9990           for(int j=0;j<*ptrc;j++)
9991             tmp*=*ptr;
9992           *ptr=tmp;
9993         }
9994       else
9995         {
9996           std::ostringstream oss; oss << "DataArrayInt::powEqual : on tuple #" << i << " of other value is < 0 (" << *ptrc << ") !";
9997           throw INTERP_KERNEL::Exception(oss.str().c_str());
9998         }
9999     }
10000   declareAsNew();
10001 }
10002
10003 /*!
10004  * Returns a C array which is a renumbering map in "Old to New" mode for the input array.
10005  * This map, if applied to \a start array, would make it sorted. For example, if
10006  * \a start array contents are [9,10,0,6,4,11,3,7] then the contents of the result array is
10007  * [5,6,0,3,2,7,1,4].
10008  *  \param [in] start - pointer to the first element of the array for which the
10009  *         permutation map is computed.
10010  *  \param [in] end - pointer specifying the end of the array \a start, so that
10011  *         the last value of \a start is \a end[ -1 ].
10012  *  \return int * - the result permutation array that the caller is to delete as it is no
10013  *         more needed.
10014  *  \throw If there are equal values in the input array.
10015  */
10016 int *DataArrayInt::CheckAndPreparePermutation(const int *start, const int *end)
10017 {
10018   std::size_t sz=std::distance(start,end);
10019   int *ret=new int[sz];
10020   int *work=new int[sz];
10021   std::copy(start,end,work);
10022   std::sort(work,work+sz);
10023   if(std::unique(work,work+sz)!=work+sz)
10024     {
10025       delete [] work;
10026       delete [] ret;
10027       throw INTERP_KERNEL::Exception("Some elements are equals in the specified array !");
10028     }
10029   int *iter2=ret;
10030   for(const int *iter=start;iter!=end;iter++,iter2++)
10031     *iter2=(int)std::distance(work,std::find(work,work+sz,*iter));
10032   delete [] work;
10033   return ret;
10034 }
10035
10036 /*!
10037  * Returns a new DataArrayInt containing an arithmetic progression
10038  * that is equal to the sequence returned by Python \c range(\a begin,\a  end,\a  step )
10039  * function.
10040  *  \param [in] begin - the start value of the result sequence.
10041  *  \param [in] end - limiting value, so that every value of the result array is less than
10042  *              \a end.
10043  *  \param [in] step - specifies the increment or decrement.
10044  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
10045  *          array using decrRef() as it is no more needed.
10046  *  \throw If \a step == 0.
10047  *  \throw If \a end < \a begin && \a step > 0.
10048  *  \throw If \a end > \a begin && \a step < 0.
10049  */
10050 DataArrayInt *DataArrayInt::Range(int begin, int end, int step) throw(INTERP_KERNEL::Exception)
10051 {
10052   int nbOfTuples=GetNumberOfItemGivenBESRelative(begin,end,step,"DataArrayInt::Range");
10053   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
10054   ret->alloc(nbOfTuples,1);
10055   int *ptr=ret->getPointer();
10056   if(step>0)
10057     {
10058       for(int i=begin;i<end;i+=step,ptr++)
10059         *ptr=i;
10060     }
10061   else
10062     {
10063       for(int i=begin;i>end;i+=step,ptr++)
10064         *ptr=i;
10065     }
10066   return ret.retn();
10067 }
10068
10069 /*!
10070  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
10071  * Server side.
10072  */
10073 void DataArrayInt::getTinySerializationIntInformation(std::vector<int>& tinyInfo) const
10074 {
10075   tinyInfo.resize(2);
10076   if(isAllocated())
10077     {
10078       tinyInfo[0]=getNumberOfTuples();
10079       tinyInfo[1]=getNumberOfComponents();
10080     }
10081   else
10082     {
10083       tinyInfo[0]=-1;
10084       tinyInfo[1]=-1;
10085     }
10086 }
10087
10088 /*!
10089  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
10090  * Server side.
10091  */
10092 void DataArrayInt::getTinySerializationStrInformation(std::vector<std::string>& tinyInfo) const
10093 {
10094   if(isAllocated())
10095     {
10096       int nbOfCompo=getNumberOfComponents();
10097       tinyInfo.resize(nbOfCompo+1);
10098       tinyInfo[0]=getName();
10099       for(int i=0;i<nbOfCompo;i++)
10100         tinyInfo[i+1]=getInfoOnComponent(i);
10101     }
10102   else
10103     {
10104       tinyInfo.resize(1);
10105       tinyInfo[0]=getName();
10106     }
10107 }
10108
10109 /*!
10110  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
10111  * This method returns if a feeding is needed.
10112  */
10113 bool DataArrayInt::resizeForUnserialization(const std::vector<int>& tinyInfoI)
10114 {
10115   int nbOfTuple=tinyInfoI[0];
10116   int nbOfComp=tinyInfoI[1];
10117   if(nbOfTuple!=-1 || nbOfComp!=-1)
10118     {
10119       alloc(nbOfTuple,nbOfComp);
10120       return true;
10121     }
10122   return false;
10123 }
10124
10125 /*!
10126  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
10127  * This method returns if a feeding is needed.
10128  */
10129 void DataArrayInt::finishUnserialization(const std::vector<int>& tinyInfoI, const std::vector<std::string>& tinyInfoS)
10130 {
10131   setName(tinyInfoS[0].c_str());
10132   if(isAllocated())
10133     {
10134       int nbOfCompo=getNumberOfComponents();
10135       for(int i=0;i<nbOfCompo;i++)
10136         setInfoOnComponent(i,tinyInfoS[i+1].c_str());
10137     }
10138 }
10139
10140 DataArrayIntIterator::DataArrayIntIterator(DataArrayInt *da):_da(da),_pt(0),_tuple_id(0),_nb_comp(0),_nb_tuple(0)
10141 {
10142   if(_da)
10143     {
10144       _da->incrRef();
10145       if(_da->isAllocated())
10146         {
10147           _nb_comp=da->getNumberOfComponents();
10148           _nb_tuple=da->getNumberOfTuples();
10149           _pt=da->getPointer();
10150         }
10151     }
10152 }
10153
10154 DataArrayIntIterator::~DataArrayIntIterator()
10155 {
10156   if(_da)
10157     _da->decrRef();
10158 }
10159
10160 DataArrayIntTuple *DataArrayIntIterator::nextt() throw(INTERP_KERNEL::Exception)
10161 {
10162   if(_tuple_id<_nb_tuple)
10163     {
10164       _tuple_id++;
10165       DataArrayIntTuple *ret=new DataArrayIntTuple(_pt,_nb_comp);
10166       _pt+=_nb_comp;
10167       return ret;
10168     }
10169   else
10170     return 0;
10171 }
10172
10173 DataArrayIntTuple::DataArrayIntTuple(int *pt, int nbOfComp):_pt(pt),_nb_of_compo(nbOfComp)
10174 {
10175 }
10176
10177 std::string DataArrayIntTuple::repr() const throw(INTERP_KERNEL::Exception)
10178 {
10179   std::ostringstream oss; oss << "(";
10180   for(int i=0;i<_nb_of_compo-1;i++)
10181     oss << _pt[i] << ", ";
10182   oss << _pt[_nb_of_compo-1] << ")";
10183   return oss.str();
10184 }
10185
10186 int DataArrayIntTuple::intValue() const throw(INTERP_KERNEL::Exception)
10187 {
10188   if(_nb_of_compo==1)
10189     return *_pt;
10190   throw INTERP_KERNEL::Exception("DataArrayIntTuple::intValue : DataArrayIntTuple instance has not exactly 1 component -> Not possible to convert it into an integer !");
10191 }
10192
10193 /*!
10194  * This method returns a newly allocated instance the caller should dealed with by a ParaMEDMEM::DataArrayInt::decrRef.
10195  * This method performs \b no copy of data. The content is only referenced using ParaMEDMEM::DataArrayInt::useArray with ownership set to \b false.
10196  * 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
10197  * \b nbOfCompo=1 and \bnbOfTuples==this->_nb_of_elem.
10198  */
10199 DataArrayInt *DataArrayIntTuple::buildDAInt(int nbOfTuples, int nbOfCompo) const throw(INTERP_KERNEL::Exception)
10200 {
10201   if((_nb_of_compo==nbOfCompo && nbOfTuples==1) || (_nb_of_compo==nbOfTuples && nbOfCompo==1))
10202     {
10203       DataArrayInt *ret=DataArrayInt::New();
10204       ret->useExternalArrayWithRWAccess(_pt,nbOfTuples,nbOfCompo);
10205       return ret;
10206     }
10207   else
10208     {
10209       std::ostringstream oss; oss << "DataArrayIntTuple::buildDAInt : unable to build a requested DataArrayInt instance with nbofTuple=" << nbOfTuples << " and nbOfCompo=" << nbOfCompo;
10210       oss << ".\nBecause the number of elements in this is " << _nb_of_compo << " !";
10211       throw INTERP_KERNEL::Exception(oss.str().c_str());
10212     }
10213 }