Salome HOME
fc3e9e8629c7d597f1bd89bf47ae2f89eba98ddf
[tools/medcoupling.git] / src / MEDCoupling / MEDCouplingMemArray.cxx
1 // Copyright (C) 2007-2012  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   BBTree<SPACEDIM,int> myTree(bbox,0,0,nbNodes,prec/10);
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 BBTree<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  *  \param [in] i - the index (zero based) of the component of interest.
387  *  \param [in] info - the string containing the information.
388  *  \throw If \a i is not a valid component index.
389  *  \warning Don't pass NULL as \a info!
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(int 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=(std::size_t)_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.
659  */
660 DataArrayDouble *DataArrayDouble::deepCpy() const throw(INTERP_KERNEL::Exception)
661 {
662   return new DataArrayDouble(*this);
663 }
664
665 /*!
666  * Returns either a \a deep or \a shallow copy of this array. For more info see
667  * \ref MEDCouplingArrayBasicsCopyDeep and \ref MEDCouplingArrayBasicsCopyShallow.
668  *  \param [in] dCpy - if \a true, a deep copy is returned, else, a shallow one.
669  *  \return DataArrayDouble * - either a new instance of DataArrayDouble (if \a dCpy
670  *          == \a true) or \a this instance (if \a dCpy == \a false).
671  */
672 DataArrayDouble *DataArrayDouble::performCpy(bool dCpy) const throw(INTERP_KERNEL::Exception)
673 {
674   if(dCpy)
675     return deepCpy();
676   else
677     {
678       incrRef();
679       return const_cast<DataArrayDouble *>(this);
680     }
681 }
682
683 /*!
684  * Copies all the data from another DataArrayDouble. For more info see
685  * \ref MEDCouplingArrayBasicsCopyDeepAssign.
686  *  \param [in] other - another instance of DataArrayDouble to copy data from.
687  *  \throw If the \a other is not allocated.
688  */
689 void DataArrayDouble::cpyFrom(const DataArrayDouble& other) throw(INTERP_KERNEL::Exception)
690 {
691   other.checkAllocated();
692   int nbOfTuples=other.getNumberOfTuples();
693   int nbOfComp=other.getNumberOfComponents();
694   allocIfNecessary(nbOfTuples,nbOfComp);
695   int nbOfElems=nbOfTuples*nbOfComp;
696   double *pt=getPointer();
697   const double *ptI=other.getConstPointer();
698   for(int i=0;i<nbOfElems;i++)
699     pt[i]=ptI[i];
700   copyStringInfoFrom(other);
701 }
702
703 /*!
704  * This method reserve nbOfElems elements in memory ( nbOfElems*8 bytes ) \b without impacting the number of tuples in \a this.
705  * 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.
706  * If \a this has not already been allocated, number of components is set to one.
707  * This method allows to reduce number of reallocations on invokation of DataArrayDouble::pushBackSilent and DataArrayDouble::pushBackValsSilent on \a this.
708  * 
709  * \sa DataArrayDouble::pack, DataArrayDouble::pushBackSilent, DataArrayDouble::pushBackValsSilent
710  */
711 void DataArrayDouble::reserve(int nbOfElems) throw(INTERP_KERNEL::Exception)
712 {
713   int nbCompo=getNumberOfComponents();
714   if(nbCompo==1)
715     {
716       _mem.reserve(nbOfElems);
717     }
718   else if(nbCompo==0)
719     {
720       _mem.reserve(nbOfElems);
721       _info_on_compo.resize(1);
722     }
723   else
724     throw INTERP_KERNEL::Exception("DataArrayDouble::reserve : not available for DataArrayDouble with number of components different than 1 !");
725 }
726
727 /*!
728  * 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
729  * of counter. So the caller is expected to call TimeLabel::declareAsNew on \a this at the end of the push session.
730  *
731  * \param [in] val the value to be added in \a this
732  * \throw If \a this has already been allocated with number of components different from one.
733  * \sa DataArrayDouble::pushBackValsSilent
734  */
735 void DataArrayDouble::pushBackSilent(double val) throw(INTERP_KERNEL::Exception)
736 {
737   int nbCompo=getNumberOfComponents();
738   if(nbCompo==1)
739     _mem.pushBack(val);
740   else if(nbCompo==0)
741     {
742       _info_on_compo.resize(1);
743       _mem.pushBack(val);
744     }
745   else
746     throw INTERP_KERNEL::Exception("DataArrayDouble::pushBackSilent : not available for DataArrayDouble with number of components different than 1 !");
747 }
748
749 /*!
750  * 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
751  * of counter. So the caller is expected to call TimeLabel::declareAsNew on \a this at the end of the push session.
752  *
753  *  \param [in] valsBg - an array of values to push at the end of \this.
754  *  \param [in] valsEnd - specifies the end of the array \a valsBg, so that
755  *              the last value of \a valsBg is \a valsEnd[ -1 ].
756  * \throw If \a this has already been allocated with number of components different from one.
757  * \sa DataArrayDouble::pushBackSilent
758  */
759 void DataArrayDouble::pushBackValsSilent(const double *valsBg, const double *valsEnd) throw(INTERP_KERNEL::Exception)
760 {
761   int nbCompo=getNumberOfComponents();
762   if(nbCompo==1)
763     _mem.insertAtTheEnd(valsBg,valsEnd);
764   else if(nbCompo==0)
765     {
766       _info_on_compo.resize(1);
767       _mem.insertAtTheEnd(valsBg,valsEnd);
768     }
769   else
770     throw INTERP_KERNEL::Exception("DataArrayDouble::pushBackValsSilent : not available for DataArrayDouble with number of components different than 1 !");
771 }
772
773 /*!
774  * This method returns silently ( without updating time label in \a this ) the last value, if any and suppress it.
775  * \throw If \a this is already empty.
776  * \throw If \a this has number of components different from one.
777  */
778 double DataArrayDouble::popBackSilent() throw(INTERP_KERNEL::Exception)
779 {
780   if(getNumberOfComponents()==1)
781     return _mem.popBack();
782   else
783     throw INTERP_KERNEL::Exception("DataArrayDouble::popBackSilent : not available for DataArrayDouble with number of components different than 1 !");
784 }
785
786 /*!
787  * 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.
788  *
789  * \sa DataArrayDouble::getHeapMemorySize, DataArrayDouble::reserve
790  */
791 void DataArrayDouble::pack() const throw(INTERP_KERNEL::Exception)
792 {
793   _mem.pack();
794 }
795
796 /*!
797  * Allocates the raw data in memory. If exactly same memory as needed already
798  * allocated, it is not re-allocated.
799  *  \param [in] nbOfTuple - number of tuples of data to allocate.
800  *  \param [in] nbOfCompo - number of components of data to allocate.
801  *  \throw If \a nbOfTuple < 0 or \a nbOfCompo < 0.
802  */
803 void DataArrayDouble::allocIfNecessary(int nbOfTuple, int nbOfCompo) throw(INTERP_KERNEL::Exception)
804 {
805   if(isAllocated())
806     {
807       if(nbOfTuple!=getNumberOfTuples() || nbOfCompo!=getNumberOfComponents())
808         alloc(nbOfTuple,nbOfCompo);
809     }
810   else
811     alloc(nbOfTuple,nbOfCompo);
812 }
813
814 /*!
815  * Allocates the raw data in memory. If the memory was already allocated, then it is
816  * freed and re-allocated. See an example of this method use
817  * \ref MEDCouplingArraySteps1WC "here".
818  *  \param [in] nbOfTuple - number of tuples of data to allocate.
819  *  \param [in] nbOfCompo - number of components of data to allocate.
820  *  \throw If \a nbOfTuple < 0 or \a nbOfCompo < 0.
821  */
822 void DataArrayDouble::alloc(int nbOfTuple, int nbOfCompo) throw(INTERP_KERNEL::Exception)
823 {
824   if(nbOfTuple<0 || nbOfCompo<0)
825     throw INTERP_KERNEL::Exception("DataArrayDouble::alloc : request for negative length of data !");
826   _info_on_compo.resize(nbOfCompo);
827   _mem.alloc(nbOfCompo*nbOfTuple);
828   declareAsNew();
829 }
830
831 /*!
832  * Assign zero to all values in \a this array. To know more on filling arrays see
833  * \ref MEDCouplingArrayFill.
834  * \throw If \a this is not allocated.
835  */
836 void DataArrayDouble::fillWithZero() throw(INTERP_KERNEL::Exception)
837 {
838   checkAllocated();
839   _mem.fillWithValue(0.);
840   declareAsNew();
841 }
842
843 /*!
844  * Assign \a val to all values in \a this array. To know more on filling arrays see
845  * \ref MEDCouplingArrayFill.
846  *  \param [in] val - the value to fill with.
847  *  \throw If \a this is not allocated.
848  */
849 void DataArrayDouble::fillWithValue(double val) throw(INTERP_KERNEL::Exception)
850 {
851   checkAllocated();
852   _mem.fillWithValue(val);
853   declareAsNew();
854 }
855
856 /*!
857  * Set all values in \a this array so that the i-th element equals to \a init + i
858  * (i starts from zero). To know more on filling arrays see \ref MEDCouplingArrayFill.
859  *  \param [in] init - value to assign to the first element of array.
860  *  \throw If \a this->getNumberOfComponents() != 1
861  *  \throw If \a this is not allocated.
862  */
863 void DataArrayDouble::iota(double init) throw(INTERP_KERNEL::Exception)
864 {
865   checkAllocated();
866   if(getNumberOfComponents()!=1)
867     throw INTERP_KERNEL::Exception("DataArrayDouble::iota : works only for arrays with only one component, you can call 'rearrange' method before !");
868   double *ptr=getPointer();
869   int ntuples=getNumberOfTuples();
870   for(int i=0;i<ntuples;i++)
871     ptr[i]=init+double(i);
872   declareAsNew();
873 }
874
875 /*!
876  * Checks if all values in \a this array are equal to \a val at precision \a eps.
877  *  \param [in] val - value to check equality of array values to.
878  *  \param [in] eps - precision to check the equality.
879  *  \return bool - \a true if all values are in range (_val_ - _eps_; _val_ + _eps_),
880  *                 \a false else.
881  *  \throw If \a this->getNumberOfComponents() != 1
882  *  \throw If \a this is not allocated.
883  */
884 bool DataArrayDouble::isUniform(double val, double eps) const throw(INTERP_KERNEL::Exception)
885 {
886   checkAllocated();
887   if(getNumberOfComponents()!=1)
888     throw INTERP_KERNEL::Exception("DataArrayDouble::isUniform : must be applied on DataArrayDouble with only one component, you can call 'rearrange' method before !");
889   int nbOfTuples=getNumberOfTuples();
890   const double *w=getConstPointer();
891   const double *end2=w+nbOfTuples;
892   const double vmin=val-eps;
893   const double vmax=val+eps;
894   for(;w!=end2;w++)
895     if(*w<vmin || *w>vmax)
896       return false;
897   return true;
898 }
899
900 /*!
901  * Sorts values of the array.
902  *  \param [in] asc - \a true means ascending order, \a false, descending.
903  *  \throw If \a this is not allocated.
904  *  \throw If \a this->getNumberOfComponents() != 1.
905  */
906 void DataArrayDouble::sort(bool asc) throw(INTERP_KERNEL::Exception)
907 {
908   checkAllocated();
909   if(getNumberOfComponents()!=1)
910     throw INTERP_KERNEL::Exception("DataArrayDouble::sort : only supported with 'this' array with ONE component !");
911   _mem.sort(asc);
912 }
913
914 /*!
915  * Reverse the array values.
916  *  \throw If \a this->getNumberOfComponents() != 1.
917  *  \throw If \a this is not allocated.
918  */
919 void DataArrayDouble::reverse() throw(INTERP_KERNEL::Exception)
920 {
921   checkAllocated();
922   if(getNumberOfComponents()!=1)
923     throw INTERP_KERNEL::Exception("DataArrayDouble::reverse : only supported with 'this' array with ONE component !");
924   _mem.reverse();
925 }
926
927 /*!
928  * Checks that \a this array is consistently **increasing** or **decreasing** in value,
929  * with at least absolute difference value of |\a eps| at each step.
930  * If not an exception is thrown.
931  *  \param [in] increasing - if \a true, the array values should be increasing.
932  *  \param [in] eps - minimal absolute difference between the neighbor values at which 
933  *                    the values are considered different.
934  *  \throw If sequence of values is not strictly monotonic in agreement with \a
935  *         increasing arg.
936  *  \throw If \a this->getNumberOfComponents() != 1.
937  *  \throw If \a this is not allocated.
938  */
939 void DataArrayDouble::checkMonotonic(bool increasing, double eps) const throw(INTERP_KERNEL::Exception)
940 {
941   if(!isMonotonic(increasing,eps))
942     {
943       if (increasing)
944         throw INTERP_KERNEL::Exception("DataArrayDouble::checkMonotonic : 'this' is not INCREASING monotonic !");
945       else
946         throw INTERP_KERNEL::Exception("DataArrayDouble::checkMonotonic : 'this' is not DECREASING monotonic !");
947     }
948 }
949
950 /*!
951  * Checks that \a this array is consistently **increasing** or **decreasing** in value,
952  * with at least absolute difference value of |\a eps| at each step.
953  *  \param [in] increasing - if \a true, array values should be increasing.
954  *  \param [in] eps - minimal absolute difference between the neighbor values at which 
955  *                    the values are considered different.
956  *  \return bool - \a true if values change in accordance with \a increasing arg.
957  *  \throw If \a this->getNumberOfComponents() != 1.
958  *  \throw If \a this is not allocated.
959  */
960 bool DataArrayDouble::isMonotonic(bool increasing, double eps) const throw(INTERP_KERNEL::Exception)
961 {
962   checkAllocated();
963   if(getNumberOfComponents()!=1)
964     throw INTERP_KERNEL::Exception("DataArrayDouble::isMonotonic : only supported with 'this' array with ONE component !");
965   int nbOfElements=getNumberOfTuples();
966   const double *ptr=getConstPointer();
967   if(nbOfElements==0)
968     return true;
969   double ref=ptr[0];
970   double absEps=fabs(eps);
971   if(increasing)
972     {
973       for(int i=1;i<nbOfElements;i++)
974         {
975           if(ptr[i]<(ref+absEps))
976             return false;
977           ref=ptr[i];
978         }
979       return true;
980     }
981   else
982     {
983       for(int i=1;i<nbOfElements;i++)
984         {
985           if(ptr[i]>(ref-absEps))
986             return false;
987           ref=ptr[i];
988         }
989       return true;
990     }
991 }
992
993 /*!
994  * Returns a textual and human readable representation of \a this instance of
995  * DataArrayDouble. This text is shown when a DataArrayDouble is printed in Python.
996  *  \return std::string - text describing \a this DataArrayDouble.
997  */
998 std::string DataArrayDouble::repr() const throw(INTERP_KERNEL::Exception)
999 {
1000   std::ostringstream ret;
1001   reprStream(ret);
1002   return ret.str();
1003 }
1004
1005 std::string DataArrayDouble::reprZip() const throw(INTERP_KERNEL::Exception)
1006 {
1007   std::ostringstream ret;
1008   reprZipStream(ret);
1009   return ret.str();
1010 }
1011
1012 void DataArrayDouble::writeVTK(std::ostream& ofs, int indent, const char *nameInFile) const throw(INTERP_KERNEL::Exception)
1013 {
1014   std::string idt(indent,' ');
1015   ofs.precision(17);
1016   ofs << idt << "<DataArray type=\"Float32\" Name=\"" << nameInFile << "\" NumberOfComponents=\"" << getNumberOfComponents() << "\"";
1017   ofs << " format=\"ascii\" RangeMin=\"" << getMinValueInArray() << "\" RangeMax=\"" << getMaxValueInArray() << "\">\n" << idt;
1018   std::copy(begin(),end(),std::ostream_iterator<double>(ofs," "));
1019   ofs << std::endl << idt << "</DataArray>\n";
1020 }
1021
1022 void DataArrayDouble::reprStream(std::ostream& stream) const throw(INTERP_KERNEL::Exception)
1023 {
1024   stream << "Name of double array : \"" << _name << "\"\n";
1025   reprWithoutNameStream(stream);
1026 }
1027
1028 void DataArrayDouble::reprZipStream(std::ostream& stream) const throw(INTERP_KERNEL::Exception)
1029 {
1030   stream << "Name of double array : \"" << _name << "\"\n";
1031   reprZipWithoutNameStream(stream);
1032 }
1033
1034 void DataArrayDouble::reprWithoutNameStream(std::ostream& stream) const throw(INTERP_KERNEL::Exception)
1035 {
1036   DataArray::reprWithoutNameStream(stream);
1037   stream.precision(17);
1038   _mem.repr(getNumberOfComponents(),stream);
1039 }
1040
1041 void DataArrayDouble::reprZipWithoutNameStream(std::ostream& stream) const throw(INTERP_KERNEL::Exception)
1042 {
1043   DataArray::reprWithoutNameStream(stream);
1044   stream.precision(17);
1045   _mem.reprZip(getNumberOfComponents(),stream);
1046 }
1047
1048 void DataArrayDouble::reprCppStream(const char *varName, std::ostream& stream) const throw(INTERP_KERNEL::Exception)
1049 {
1050   int nbTuples=getNumberOfTuples(),nbComp=getNumberOfComponents();
1051   const double *data=getConstPointer();
1052   stream.precision(17);
1053   stream << "DataArrayDouble *" << varName << "=DataArrayDouble::New();" << std::endl;
1054   if(nbTuples*nbComp>=1)
1055     {
1056       stream << "const double " << varName << "Data[" << nbTuples*nbComp << "]={";
1057       std::copy(data,data+nbTuples*nbComp-1,std::ostream_iterator<double>(stream,","));
1058       stream << data[nbTuples*nbComp-1] << "};" << std::endl;
1059       stream << varName << "->useArray(" << varName << "Data,false,CPP_DEALLOC," << nbTuples << "," << nbComp << ");" << std::endl;
1060     }
1061   else
1062     stream << varName << "->alloc(" << nbTuples << "," << nbComp << ");" << std::endl;
1063   stream << varName << "->setName(\"" << getName() << "\");" << std::endl;
1064 }
1065
1066 /*!
1067  * Equivalent to DataArrayDouble::isEqual except that if false the reason of
1068  * mismatch is given.
1069  * 
1070  * \param [in] other the instance to be compared with \a this
1071  * \param [in] prec the precision to compare numeric data of the arrays.
1072  * \param [out] reason In case of inequality returns the reason.
1073  * \sa DataArrayDouble::isEqual
1074  */
1075 bool DataArrayDouble::isEqualIfNotWhy(const DataArrayDouble& other, double prec, std::string& reason) const throw(INTERP_KERNEL::Exception)
1076 {
1077   if(!areInfoEqualsIfNotWhy(other,reason))
1078     return false;
1079   return _mem.isEqual(other._mem,prec,reason);
1080 }
1081
1082 /*!
1083  * Checks if \a this and another DataArrayDouble are fully equal. For more info see
1084  * \ref MEDCouplingArrayBasicsCompare.
1085  *  \param [in] other - an instance of DataArrayDouble to compare with \a this one.
1086  *  \param [in] prec - precision value to compare numeric data of the arrays.
1087  *  \return bool - \a true if the two arrays are equal, \a false else.
1088  */
1089 bool DataArrayDouble::isEqual(const DataArrayDouble& other, double prec) const throw(INTERP_KERNEL::Exception)
1090 {
1091   std::string tmp;
1092   return isEqualIfNotWhy(other,prec,tmp);
1093 }
1094
1095 /*!
1096  * Checks if values of \a this and another DataArrayDouble are equal. For more info see
1097  * \ref MEDCouplingArrayBasicsCompare.
1098  *  \param [in] other - an instance of DataArrayDouble to compare with \a this one.
1099  *  \param [in] prec - precision value to compare numeric data of the arrays.
1100  *  \return bool - \a true if the values of two arrays are equal, \a false else.
1101  */
1102 bool DataArrayDouble::isEqualWithoutConsideringStr(const DataArrayDouble& other, double prec) const throw(INTERP_KERNEL::Exception)
1103 {
1104   std::string tmp;
1105   return _mem.isEqual(other._mem,prec,tmp);
1106 }
1107
1108 /*!
1109  * Changes number of tuples in the array. If the new number of tuples is smaller
1110  * than the current number the array is truncated, otherwise the array is extended.
1111  *  \param [in] nbOfTuples - new number of tuples. 
1112  *  \throw If \a this is not allocated.
1113  */
1114 void DataArrayDouble::reAlloc(int nbOfTuples) throw(INTERP_KERNEL::Exception)
1115 {
1116   checkAllocated();
1117   _mem.reAlloc(getNumberOfComponents()*nbOfTuples);
1118   declareAsNew();
1119 }
1120
1121 /*!
1122  * Creates a new DataArrayInt and assigns all (textual and numerical) data of \a this
1123  * array to the new one.
1124  *  \return DataArrayInt * - the new instance of DataArrayInt.
1125  */
1126 DataArrayInt *DataArrayDouble::convertToIntArr() const
1127 {
1128   DataArrayInt *ret=DataArrayInt::New();
1129   ret->alloc(getNumberOfTuples(),getNumberOfComponents());
1130   int nbOfVals=getNbOfElems();
1131   const double *src=getConstPointer();
1132   int *dest=ret->getPointer();
1133   std::copy(src,src+nbOfVals,dest);
1134   ret->copyStringInfoFrom(*this);
1135   return ret;
1136 }
1137
1138 /*!
1139  * Returns a new DataArrayDouble holding the same values as \a this array but differently
1140  * arranged in memory. If \a this array holds 2 components of 3 values:
1141  * \f$ x_0,x_1,x_2,y_0,y_1,y_2 \f$, then the result array holds these values arranged
1142  * as follows: \f$ x_0,y_0,x_1,y_1,x_2,y_2 \f$.
1143  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1144  *          is to delete using decrRef() as it is no more needed.
1145  *  \throw If \a this is not allocated.
1146  *  \warning Do not confuse this method with transpose()!
1147  */
1148 DataArrayDouble *DataArrayDouble::fromNoInterlace() const throw(INTERP_KERNEL::Exception)
1149 {
1150   if(_mem.isNull())
1151     throw INTERP_KERNEL::Exception("DataArrayDouble::fromNoInterlace : Not defined array !");
1152   double *tab=_mem.fromNoInterlace(getNumberOfComponents());
1153   DataArrayDouble *ret=DataArrayDouble::New();
1154   ret->useArray(tab,true,CPP_DEALLOC,getNumberOfTuples(),getNumberOfComponents());
1155   return ret;
1156 }
1157
1158 /*!
1159  * Returns a new DataArrayDouble holding the same values as \a this array but differently
1160  * arranged in memory. If \a this array holds 2 components of 3 values:
1161  * \f$ x_0,y_0,x_1,y_1,x_2,y_2 \f$, then the result array holds these values arranged
1162  * as follows: \f$ x_0,x_1,x_2,y_0,y_1,y_2 \f$.
1163  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1164  *          is to delete using decrRef() as it is no more needed.
1165  *  \throw If \a this is not allocated.
1166  *  \warning Do not confuse this method with transpose()!
1167  */
1168 DataArrayDouble *DataArrayDouble::toNoInterlace() const throw(INTERP_KERNEL::Exception)
1169 {
1170   if(_mem.isNull())
1171     throw INTERP_KERNEL::Exception("DataArrayDouble::toNoInterlace : Not defined array !");
1172   double *tab=_mem.toNoInterlace(getNumberOfComponents());
1173   DataArrayDouble *ret=DataArrayDouble::New();
1174   ret->useArray(tab,true,CPP_DEALLOC,getNumberOfTuples(),getNumberOfComponents());
1175   return ret;
1176 }
1177
1178 /*!
1179  * Permutes values of \a this array as required by \a old2New array. The values are
1180  * permuted so that \c new[ \a old2New[ i ]] = \c old[ i ]. Number of tuples remains
1181  * the same as in \this one.
1182  * If a permutation reduction is needed, substr() or selectByTupleId() should be used.
1183  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
1184  *  \param [in] old2New - C array of length equal to \a this->getNumberOfTuples()
1185  *     giving a new position for i-th old value.
1186  */
1187 void DataArrayDouble::renumberInPlace(const int *old2New) throw(INTERP_KERNEL::Exception)
1188 {
1189   checkAllocated();
1190   int nbTuples=getNumberOfTuples();
1191   int nbOfCompo=getNumberOfComponents();
1192   double *tmp=new double[nbTuples*nbOfCompo];
1193   const double *iptr=getConstPointer();
1194   for(int i=0;i<nbTuples;i++)
1195     std::copy(iptr+nbOfCompo*i,iptr+nbOfCompo*(i+1),tmp+nbOfCompo*old2New[i]);
1196   std::copy(tmp,tmp+nbTuples*nbOfCompo,getPointer());
1197   delete [] tmp;
1198   declareAsNew();
1199 }
1200
1201 /*!
1202  * Permutes values of \a this array as required by \a new2Old array. The values are
1203  * permuted so that \c new[ i ] = \c old[ \a new2Old[ i ]]. Number of tuples remains
1204  * the same as in \this one.
1205  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
1206  *  \param [in] new2Old - C array of length equal to \a this->getNumberOfTuples()
1207  *     giving a previous position of i-th new value.
1208  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1209  *          is to delete using decrRef() as it is no more needed.
1210  */
1211 void DataArrayDouble::renumberInPlaceR(const int *new2Old) throw(INTERP_KERNEL::Exception)
1212 {
1213   checkAllocated();
1214   int nbTuples=getNumberOfTuples();
1215   int nbOfCompo=getNumberOfComponents();
1216   double *tmp=new double[nbTuples*nbOfCompo];
1217   const double *iptr=getConstPointer();
1218   for(int i=0;i<nbTuples;i++)
1219     std::copy(iptr+nbOfCompo*new2Old[i],iptr+nbOfCompo*(new2Old[i]+1),tmp+nbOfCompo*i);
1220   std::copy(tmp,tmp+nbTuples*nbOfCompo,getPointer());
1221   delete [] tmp;
1222   declareAsNew();
1223 }
1224
1225 /*!
1226  * Returns a copy of \a this array with values permuted as required by \a old2New array.
1227  * The values are permuted so that  \c new[ \a old2New[ i ]] = \c old[ i ].
1228  * Number of tuples in the result array remains the same as in \this one.
1229  * If a permutation reduction is needed, renumberAndReduce() should be used.
1230  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
1231  *  \param [in] old2New - C array of length equal to \a this->getNumberOfTuples()
1232  *          giving a new position for i-th old value.
1233  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1234  *          is to delete using decrRef() as it is no more needed.
1235  *  \throw If \a this is not allocated.
1236  */
1237 DataArrayDouble *DataArrayDouble::renumber(const int *old2New) const throw(INTERP_KERNEL::Exception)
1238 {
1239   checkAllocated();
1240   int nbTuples=getNumberOfTuples();
1241   int nbOfCompo=getNumberOfComponents();
1242   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
1243   ret->alloc(nbTuples,nbOfCompo);
1244   ret->copyStringInfoFrom(*this);
1245   const double *iptr=getConstPointer();
1246   double *optr=ret->getPointer();
1247   for(int i=0;i<nbTuples;i++)
1248     std::copy(iptr+nbOfCompo*i,iptr+nbOfCompo*(i+1),optr+nbOfCompo*old2New[i]);
1249   ret->copyStringInfoFrom(*this);
1250   return ret.retn();
1251 }
1252
1253 /*!
1254  * Returns a copy of \a this array with values permuted as required by \a new2Old array.
1255  * The values are permuted so that  \c new[ i ] = \c old[ \a new2Old[ i ]]. Number of
1256  * tuples in the result array remains the same as in \this one.
1257  * If a permutation reduction is needed, substr() or selectByTupleId() should be used.
1258  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
1259  *  \param [in] new2Old - C array of length equal to \a this->getNumberOfTuples()
1260  *     giving a previous position of i-th new value.
1261  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1262  *          is to delete using decrRef() as it is no more needed.
1263  */
1264 DataArrayDouble *DataArrayDouble::renumberR(const int *new2Old) const throw(INTERP_KERNEL::Exception)
1265 {
1266   checkAllocated();
1267   int nbTuples=getNumberOfTuples();
1268   int nbOfCompo=getNumberOfComponents();
1269   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
1270   ret->alloc(nbTuples,nbOfCompo);
1271   ret->copyStringInfoFrom(*this);
1272   const double *iptr=getConstPointer();
1273   double *optr=ret->getPointer();
1274   for(int i=0;i<nbTuples;i++)
1275     std::copy(iptr+nbOfCompo*new2Old[i],iptr+nbOfCompo*(new2Old[i]+1),optr+i*nbOfCompo);
1276   ret->copyStringInfoFrom(*this);
1277   return ret.retn();
1278 }
1279
1280 /*!
1281  * Returns a shorten and permuted copy of \a this array. The new DataArrayDouble is
1282  * of size \a newNbOfTuple and it's values are permuted as required by \a old2New array.
1283  * The values are permuted so that  \c new[ \a old2New[ i ]] = \c old[ i ] for all
1284  * \a old2New[ i ] >= 0. In other words every i-th tuple in \a this array, for which 
1285  * \a old2New[ i ] is negative, is missing from the result array.
1286  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
1287  *  \param [in] old2New - C array of length equal to \a this->getNumberOfTuples()
1288  *     giving a new position for i-th old tuple and giving negative position for
1289  *     for i-th old tuple that should be omitted.
1290  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1291  *          is to delete using decrRef() as it is no more needed.
1292  */
1293 DataArrayDouble *DataArrayDouble::renumberAndReduce(const int *old2New, int newNbOfTuple) const throw(INTERP_KERNEL::Exception)
1294 {
1295   checkAllocated();
1296   int nbTuples=getNumberOfTuples();
1297   int nbOfCompo=getNumberOfComponents();
1298   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
1299   ret->alloc(newNbOfTuple,nbOfCompo);
1300   const double *iptr=getConstPointer();
1301   double *optr=ret->getPointer();
1302   for(int i=0;i<nbTuples;i++)
1303     {
1304       int w=old2New[i];
1305       if(w>=0)
1306         std::copy(iptr+i*nbOfCompo,iptr+(i+1)*nbOfCompo,optr+w*nbOfCompo);
1307     }
1308   ret->copyStringInfoFrom(*this);
1309   return ret.retn();
1310 }
1311
1312 /*!
1313  * Returns a shorten and permuted copy of \a this array. The new DataArrayDouble is
1314  * of size \a new2OldEnd - \a new2OldBg and it's values are permuted as required by
1315  * \a new2OldBg array.
1316  * The values are permuted so that  \c new[ i ] = \c old[ \a new2OldBg[ i ]].
1317  * This method is equivalent to renumberAndReduce() except that convention in input is
1318  * \c new2old and \b not \c old2new.
1319  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
1320  *  \param [in] new2OldBg - pointer to the beginning of a permutation array that gives a
1321  *              tuple index in \a this array to fill the i-th tuple in the new array.
1322  *  \param [in] new2OldEnd - specifies the end of the permutation array that starts at
1323  *              \a new2OldBg, so that pointer to a tuple index (\a pi) varies as this:
1324  *              \a new2OldBg <= \a pi < \a new2OldEnd.
1325  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1326  *          is to delete using decrRef() as it is no more needed.
1327  */
1328 DataArrayDouble *DataArrayDouble::selectByTupleId(const int *new2OldBg, const int *new2OldEnd) const
1329 {
1330   checkAllocated();
1331   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
1332   int nbComp=getNumberOfComponents();
1333   ret->alloc((int)std::distance(new2OldBg,new2OldEnd),nbComp);
1334   ret->copyStringInfoFrom(*this);
1335   double *pt=ret->getPointer();
1336   const double *srcPt=getConstPointer();
1337   int i=0;
1338   for(const int *w=new2OldBg;w!=new2OldEnd;w++,i++)
1339     std::copy(srcPt+(*w)*nbComp,srcPt+((*w)+1)*nbComp,pt+i*nbComp);
1340   ret->copyStringInfoFrom(*this);
1341   return ret.retn();
1342 }
1343
1344 /*!
1345  * Returns a shorten and permuted copy of \a this array. The new DataArrayDouble is
1346  * of size \a new2OldEnd - \a new2OldBg and it's values are permuted as required by
1347  * \a new2OldBg array.
1348  * The values are permuted so that  \c new[ i ] = \c old[ \a new2OldBg[ i ]].
1349  * This method is equivalent to renumberAndReduce() except that convention in input is
1350  * \c new2old and \b not \c old2new.
1351  * This method is equivalent to selectByTupleId() except that it prevents coping data
1352  * from behind the end of \a this array.
1353  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
1354  *  \param [in] new2OldBg - pointer to the beginning of a permutation array that gives a
1355  *              tuple index in \a this array to fill the i-th tuple in the new array.
1356  *  \param [in] new2OldEnd - specifies the end of the permutation array that starts at
1357  *              \a new2OldBg, so that pointer to a tuple index (\a pi) varies as this:
1358  *              \a new2OldBg <= \a pi < \a new2OldEnd.
1359  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1360  *          is to delete using decrRef() as it is no more needed.
1361  *  \throw If \a new2OldEnd - \a new2OldBg > \a this->getNumberOfTuples().
1362  */
1363 DataArrayDouble *DataArrayDouble::selectByTupleIdSafe(const int *new2OldBg, const int *new2OldEnd) const throw(INTERP_KERNEL::Exception)
1364 {
1365   checkAllocated();
1366   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
1367   int nbComp=getNumberOfComponents();
1368   int oldNbOfTuples=getNumberOfTuples();
1369   ret->alloc((int)std::distance(new2OldBg,new2OldEnd),nbComp);
1370   ret->copyStringInfoFrom(*this);
1371   double *pt=ret->getPointer();
1372   const double *srcPt=getConstPointer();
1373   int i=0;
1374   for(const int *w=new2OldBg;w!=new2OldEnd;w++,i++)
1375     if(*w>=0 && *w<oldNbOfTuples)
1376       std::copy(srcPt+(*w)*nbComp,srcPt+((*w)+1)*nbComp,pt+i*nbComp);
1377     else
1378       throw INTERP_KERNEL::Exception("DataArrayInt::selectByTupleIdSafe : some ids has been detected to be out of [0,this->getNumberOfTuples) !");
1379   ret->copyStringInfoFrom(*this);
1380   return ret.retn();
1381 }
1382
1383 /*!
1384  * Returns a shorten copy of \a this array. The new DataArrayDouble contains every
1385  * (\a bg + \c i * \a step)-th tuple of \a this array located before the \a end2-th
1386  * tuple. Indices of the selected tuples are the same as ones returned by the Python
1387  * command \c range( \a bg, \a end2, \a step ).
1388  * This method is equivalent to selectByTupleIdSafe() except that the input array is
1389  * not constructed explicitly.
1390  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
1391  *  \param [in] bg - index of the first tuple to copy from \a this array.
1392  *  \param [in] end2 - index of the tuple before which the tuples to copy are located.
1393  *  \param [in] step - index increment to get index of the next tuple to copy.
1394  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1395  *          is to delete using decrRef() as it is no more needed.
1396  *  \throw If (\a end2 < \a bg) or (\a step <= 0).
1397  *  \sa DataArrayDouble::substr.
1398  */
1399 DataArrayDouble *DataArrayDouble::selectByTupleId2(int bg, int end2, int step) const throw(INTERP_KERNEL::Exception)
1400 {
1401   checkAllocated();
1402   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
1403   int nbComp=getNumberOfComponents();
1404   int newNbOfTuples=GetNumberOfItemGivenBES(bg,end2,step,"DataArrayDouble::selectByTupleId2 : ");
1405   ret->alloc(newNbOfTuples,nbComp);
1406   double *pt=ret->getPointer();
1407   const double *srcPt=getConstPointer()+bg*nbComp;
1408   for(int i=0;i<newNbOfTuples;i++,srcPt+=step*nbComp)
1409     std::copy(srcPt,srcPt+nbComp,pt+i*nbComp);
1410   ret->copyStringInfoFrom(*this);
1411   return ret.retn();
1412 }
1413
1414 /*!
1415  * Returns a shorten copy of \a this array. The new DataArrayDouble contains ranges
1416  * of tuples specified by \a ranges parameter.
1417  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
1418  *  \param [in] ranges - std::vector of std::pair's each of which defines a range
1419  *              of tuples in [\c begin,\c end) format.
1420  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1421  *          is to delete using decrRef() as it is no more needed.
1422  *  \throw If \a end < \a begin.
1423  *  \throw If \a end > \a this->getNumberOfTuples().
1424  *  \throw If \a this is not allocated.
1425  */
1426 DataArrayDouble *DataArrayDouble::selectByTupleRanges(const std::vector<std::pair<int,int> >& ranges) const throw(INTERP_KERNEL::Exception)
1427 {
1428   checkAllocated();
1429   int nbOfComp=getNumberOfComponents();
1430   int nbOfTuplesThis=getNumberOfTuples();
1431   if(ranges.empty())
1432     {
1433       DataArrayDouble *ret=DataArrayDouble::New();
1434       ret->alloc(0,nbOfComp);
1435       ret->copyStringInfoFrom(*this);
1436       return ret;
1437     }
1438   int ref=ranges.front().first;
1439   int nbOfTuples=0;
1440   bool isIncreasing=true;
1441   for(std::vector<std::pair<int,int> >::const_iterator it=ranges.begin();it!=ranges.end();it++)
1442     {
1443       if((*it).first<=(*it).second)
1444         {
1445           if((*it).first>=0 && (*it).second<=nbOfTuplesThis)
1446             {
1447               nbOfTuples+=(*it).second-(*it).first;
1448               if(isIncreasing)
1449                 isIncreasing=ref<=(*it).first;
1450               ref=(*it).second;
1451             }
1452           else
1453             {
1454               std::ostringstream oss; oss << "DataArrayDouble::selectByTupleRanges : on range #" << std::distance(ranges.begin(),it);
1455               oss << " (" << (*it).first << "," << (*it).second << ") is greater than number of tuples of this :" << nbOfTuples << " !";
1456               throw INTERP_KERNEL::Exception(oss.str().c_str());
1457             }
1458         }
1459       else
1460         {
1461           std::ostringstream oss; oss << "DataArrayDouble::selectByTupleRanges : on range #" << std::distance(ranges.begin(),it);
1462           oss << " (" << (*it).first << "," << (*it).second << ") end is before begin !";
1463           throw INTERP_KERNEL::Exception(oss.str().c_str());
1464         }
1465     }
1466   if(isIncreasing && nbOfTuplesThis==nbOfTuples)
1467     return deepCpy();
1468   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
1469   ret->alloc(nbOfTuples,nbOfComp);
1470   ret->copyStringInfoFrom(*this);
1471   const double *src=getConstPointer();
1472   double *work=ret->getPointer();
1473   for(std::vector<std::pair<int,int> >::const_iterator it=ranges.begin();it!=ranges.end();it++)
1474     work=std::copy(src+(*it).first*nbOfComp,src+(*it).second*nbOfComp,work);
1475   return ret.retn();
1476 }
1477
1478 /*!
1479  * Returns a shorten copy of \a this array. The new DataArrayDouble contains all
1480  * tuples starting from the \a tupleIdBg-th tuple and including all tuples located before
1481  * the \a tupleIdEnd-th one. This methods has a similar behavior as std::string::substr().
1482  * This method is a specialization of selectByTupleId2().
1483  *  \param [in] tupleIdBg - index of the first tuple to copy from \a this array.
1484  *  \param [in] tupleIdEnd - index of the tuple before which the tuples to copy are located.
1485  *          If \a tupleIdEnd == -1, all the tuples till the end of \a this array are copied.
1486  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1487  *          is to delete using decrRef() as it is no more needed.
1488  *  \throw If \a tupleIdBg < 0.
1489  *  \throw If \a tupleIdBg > \a this->getNumberOfTuples().
1490     \throw If \a tupleIdEnd != -1 && \a tupleIdEnd < \a this->getNumberOfTuples().
1491  *  \sa DataArrayDouble::selectByTupleId2
1492  */
1493 DataArrayDouble *DataArrayDouble::substr(int tupleIdBg, int tupleIdEnd) const throw(INTERP_KERNEL::Exception)
1494 {
1495   checkAllocated();
1496   int nbt=getNumberOfTuples();
1497   if(tupleIdBg<0)
1498     throw INTERP_KERNEL::Exception("DataArrayDouble::substr : The tupleIdBg parameter must be greater than 0 !");
1499   if(tupleIdBg>nbt)
1500     throw INTERP_KERNEL::Exception("DataArrayDouble::substr : The tupleIdBg parameter is greater than number of tuples !");
1501   int trueEnd=tupleIdEnd;
1502   if(tupleIdEnd!=-1)
1503     {
1504       if(tupleIdEnd>nbt)
1505         throw INTERP_KERNEL::Exception("DataArrayDouble::substr : The tupleIdBg parameter is greater or equal than number of tuples !");
1506     }
1507   else
1508     trueEnd=nbt;
1509   int nbComp=getNumberOfComponents();
1510   DataArrayDouble *ret=DataArrayDouble::New();
1511   ret->alloc(trueEnd-tupleIdBg,nbComp);
1512   ret->copyStringInfoFrom(*this);
1513   std::copy(getConstPointer()+tupleIdBg*nbComp,getConstPointer()+trueEnd*nbComp,ret->getPointer());
1514   return ret;
1515 }
1516
1517 /*!
1518  * Returns a shorten or extended copy of \a this array. If \a newNbOfComp is less
1519  * than \a this->getNumberOfComponents() then the result array is shorten as each tuple
1520  * is truncated to have \a newNbOfComp components, keeping first components. If \a
1521  * newNbOfComp is more than \a this->getNumberOfComponents() then the result array is
1522  * expanded as each tuple is populated with \a dftValue to have \a newNbOfComp
1523  * components.  
1524  *  \param [in] newNbOfComp - number of components for the new array to have.
1525  *  \param [in] dftValue - value assigned to new values added to the new array.
1526  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1527  *          is to delete using decrRef() as it is no more needed.
1528  *  \throw If \a this is not allocated.
1529  */
1530 DataArrayDouble *DataArrayDouble::changeNbOfComponents(int newNbOfComp, double dftValue) const throw(INTERP_KERNEL::Exception)
1531 {
1532   checkAllocated();
1533   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
1534   ret->alloc(getNumberOfTuples(),newNbOfComp);
1535   const double *oldc=getConstPointer();
1536   double *nc=ret->getPointer();
1537   int nbOfTuples=getNumberOfTuples();
1538   int oldNbOfComp=getNumberOfComponents();
1539   int dim=std::min(oldNbOfComp,newNbOfComp);
1540   for(int i=0;i<nbOfTuples;i++)
1541     {
1542       int j=0;
1543       for(;j<dim;j++)
1544         nc[newNbOfComp*i+j]=oldc[i*oldNbOfComp+j];
1545       for(;j<newNbOfComp;j++)
1546         nc[newNbOfComp*i+j]=dftValue;
1547     }
1548   ret->setName(getName().c_str());
1549   for(int i=0;i<dim;i++)
1550     ret->setInfoOnComponent(i,getInfoOnComponent(i).c_str());
1551   ret->setName(getName().c_str());
1552   return ret.retn();
1553 }
1554
1555 /*!
1556  * Changes the number of components within \a this array so that its raw data **does
1557  * not** change, instead splitting this data into tuples changes.
1558  *  \param [in] newNbOfComp - number of components for \a this array to have.
1559  *  \throw If \a this is not allocated
1560  *  \throw If getNbOfElems() % \a newNbOfCompo != 0.
1561  *  \warning This method erases all (name and unit) component info set before!
1562  */
1563 void DataArrayDouble::rearrange(int newNbOfCompo) throw(INTERP_KERNEL::Exception)
1564 {
1565   checkAllocated();
1566   int nbOfElems=getNbOfElems();
1567   if(nbOfElems%newNbOfCompo!=0)
1568     throw INTERP_KERNEL::Exception("DataArrayDouble::rearrange : nbOfElems%newNbOfCompo!=0 !");
1569   _info_on_compo.clear();
1570   _info_on_compo.resize(newNbOfCompo);
1571   declareAsNew();
1572 }
1573
1574 /*!
1575  * Changes the number of components within \a this array to be equal to its number
1576  * of tuples, and inversely its number of tuples to become equal to its number of 
1577  * components. So that its raw data **does not** change, instead splitting this
1578  * data into tuples changes.
1579  *  \throw If \a this is not allocated.
1580  *  \warning This method erases all (name and unit) component info set before!
1581  *  \warning Do not confuse this method with fromNoInterlace() and toNoInterlace()!
1582  *  \sa rearrange()
1583  */
1584 void DataArrayDouble::transpose() throw(INTERP_KERNEL::Exception)
1585 {
1586   checkAllocated();
1587   int nbOfTuples=getNumberOfTuples();
1588   rearrange(nbOfTuples);
1589 }
1590
1591 /*!
1592  * Returns a copy of \a this array composed of selected components.
1593  * The new DataArrayDouble has the same number of tuples but includes components
1594  * specified by \a compoIds parameter. So that getNbOfElems() of the result array
1595  * can be either less, same or more than \a this->getNbOfElems().
1596  *  \param [in] compoIds - sequence of zero based indices of components to include
1597  *              into the new array.
1598  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1599  *          is to delete using decrRef() as it is no more needed.
1600  *  \throw If \a this is not allocated.
1601  *  \throw If a component index (\a i) is not valid: 
1602  *         \a i < 0 || \a i >= \a this->getNumberOfComponents().
1603  *
1604  *  \ref cpp_mcdataarraydouble_keepselectedcomponents "Here is a Python example".
1605  */
1606 DataArrayDouble *DataArrayDouble::keepSelectedComponents(const std::vector<int>& compoIds) const throw(INTERP_KERNEL::Exception)
1607 {
1608   checkAllocated();
1609   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret(DataArrayDouble::New());
1610   std::size_t newNbOfCompo=compoIds.size();
1611   int oldNbOfCompo=getNumberOfComponents();
1612   for(std::vector<int>::const_iterator it=compoIds.begin();it!=compoIds.end();it++)
1613     if((*it)<0 || (*it)>=oldNbOfCompo)
1614       {
1615         std::ostringstream oss; oss << "DataArrayDouble::keepSelectedComponents : invalid requested component : " << *it << " whereas it should be in [0," << oldNbOfCompo << ") !";
1616         throw INTERP_KERNEL::Exception(oss.str().c_str());
1617       }
1618   int nbOfTuples=getNumberOfTuples();
1619   ret->alloc(nbOfTuples,(int)newNbOfCompo);
1620   ret->copyPartOfStringInfoFrom(*this,compoIds);
1621   const double *oldc=getConstPointer();
1622   double *nc=ret->getPointer();
1623   for(int i=0;i<nbOfTuples;i++)
1624     for(std::size_t j=0;j<newNbOfCompo;j++,nc++)
1625       *nc=oldc[i*oldNbOfCompo+compoIds[j]];
1626   return ret.retn();
1627 }
1628
1629 /*!
1630  * Appends components of another array to components of \a this one, tuple by tuple.
1631  * So that the number of tuples of \a this array remains the same and the number of 
1632  * components increases.
1633  *  \param [in] other - the DataArrayDouble to append to \a this one.
1634  *  \throw If \a this is not allocated.
1635  *  \throw If \a this and \a other arrays have different number of tuples.
1636  *
1637  *  \ref cpp_mcdataarraydouble_meldwith "Here is a C++ example".
1638  *
1639  *  \ref py_mcdataarraydouble_meldwith "Here is a Python example".
1640  */
1641 void DataArrayDouble::meldWith(const DataArrayDouble *other) throw(INTERP_KERNEL::Exception)
1642 {
1643   checkAllocated();
1644   other->checkAllocated();
1645   int nbOfTuples=getNumberOfTuples();
1646   if(nbOfTuples!=other->getNumberOfTuples())
1647     throw INTERP_KERNEL::Exception("DataArrayDouble::meldWith : mismatch of number of tuples !");
1648   int nbOfComp1=getNumberOfComponents();
1649   int nbOfComp2=other->getNumberOfComponents();
1650   double *newArr=new double[nbOfTuples*(nbOfComp1+nbOfComp2)];
1651   double *w=newArr;
1652   const double *inp1=getConstPointer();
1653   const double *inp2=other->getConstPointer();
1654   for(int i=0;i<nbOfTuples;i++,inp1+=nbOfComp1,inp2+=nbOfComp2)
1655     {
1656       w=std::copy(inp1,inp1+nbOfComp1,w);
1657       w=std::copy(inp2,inp2+nbOfComp2,w);
1658     }
1659   useArray(newArr,true,CPP_DEALLOC,nbOfTuples,nbOfComp1+nbOfComp2);
1660   std::vector<int> compIds(nbOfComp2);
1661   for(int i=0;i<nbOfComp2;i++)
1662     compIds[i]=nbOfComp1+i;
1663   copyPartOfStringInfoFrom2(compIds,*other);
1664 }
1665
1666 /*!
1667  * Searches for tuples coincident within \a prec tolerance. Each tuple is considered
1668  * as coordinates of a point in getNumberOfComponents()-dimensional space. The
1669  * distance is computed using norm2.
1670  *
1671  * Indices of coincident tuples are stored in output arrays.
1672  * A pair of arrays (\a comm, \a commIndex) is called "Surjective Format 2".
1673  *
1674  * This method is typically used by MEDCouplingPointSet::findCommonNodes() and
1675  * MEDCouplingUMesh::mergeNodes().
1676  *  \param [in] prec - minimal absolute distance between two tuples at which they are
1677  *              considered not coincident.
1678  *  \param [in] limitTupleId - limit tuple id. Tuples with id strictly lower than \a 
1679  *              limitTupleId are not considered.
1680  *  \param [out] comm - the array holding ids (== indices) of coincident tuples. 
1681  *               \a comm->getNumberOfComponents() == 1. 
1682  *               \a comm->getNumberOfTuples() == \a commIndex->back().
1683  *  \param [out] commIndex - the array dividing all indices stored in \a comm into
1684  *               groups of (indices of) coincident tuples. Its every value is a tuple
1685  *               index where a next group of tuples begins. For example the second
1686  *               group of tuples in \a comm is described by following range of indices:
1687  *               [ \a commIndex[1], \a commIndex[2] ). \a commIndex->getNumberOfTuples()-1
1688  *               gives the number of groups of coincident tuples.
1689  *  \throw If \a this is not allocated.
1690  *  \throw If the number of components is not in [1,2,3].
1691  *
1692  *  \ref cpp_mcdataarraydouble_findcommontuples "Here is a C++ example".
1693  *
1694  *  \ref py_mcdataarraydouble_findcommontuples  "Here is a Python example".
1695  *  \sa DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2().
1696  */
1697 void DataArrayDouble::findCommonTuples(double prec, int limitTupleId, DataArrayInt *&comm, DataArrayInt *&commIndex) const throw(INTERP_KERNEL::Exception)
1698 {
1699   checkAllocated();
1700   int nbOfCompo=getNumberOfComponents();
1701   if ((nbOfCompo<1) || (nbOfCompo>3)) //test before work
1702     throw INTERP_KERNEL::Exception("DataArrayDouble::findCommonTuples : Unexpected spacedim of coords. Must be 1, 2 or 3.");
1703   
1704   int nbOfTuples=getNumberOfTuples();
1705   //
1706   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> bbox=computeBBoxPerTuple(prec);
1707   //
1708   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> c(DataArrayInt::New()),cI(DataArrayInt::New()); c->alloc(0,1); cI->pushBackSilent(0);
1709   switch(nbOfCompo)
1710     {
1711     case 3:
1712       findCommonTuplesAlg<3>(bbox->getConstPointer(),nbOfTuples,limitTupleId,prec,c,cI);
1713       break;
1714     case 2:
1715       findCommonTuplesAlg<2>(bbox->getConstPointer(),nbOfTuples,limitTupleId,prec,c,cI);
1716       break;
1717     case 1:
1718       findCommonTuplesAlg<1>(bbox->getConstPointer(),nbOfTuples,limitTupleId,prec,c,cI);
1719       break;
1720     default:
1721       throw INTERP_KERNEL::Exception("DataArrayDouble::findCommonTuples : nb of components managed are 1,2 and 3 ! not implemented for other number of components !");
1722     }
1723   comm=c.retn();
1724   commIndex=cI.retn();
1725 }
1726
1727 /*!
1728  * 
1729  * \param [in] nbTimes specifies the nb of times each tuples in \a this will be duplicated contiguouly in returned DataArrayDouble instance.
1730  *             \a nbTimes  should be at least equal to 1.
1731  * \return a newly allocated DataArrayDouble having one component and number of tuples equal to \a nbTimes * \c this->getNumberOfTuples.
1732  * \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.
1733  */
1734 DataArrayDouble *DataArrayDouble::duplicateEachTupleNTimes(int nbTimes) const throw(INTERP_KERNEL::Exception)
1735 {
1736   checkAllocated();
1737   if(getNumberOfComponents()!=1)
1738     throw INTERP_KERNEL::Exception("DataArrayDouble::duplicateEachTupleNTimes : this should have only one component !");
1739   if(nbTimes<1)
1740     throw INTERP_KERNEL::Exception("DataArrayDouble::duplicateEachTupleNTimes : nb times should be >= 1 !");
1741   int nbTuples=getNumberOfTuples();
1742   const double *inPtr=getConstPointer();
1743   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New(); ret->alloc(nbTimes*nbTuples,1);
1744   double *retPtr=ret->getPointer();
1745   for(int i=0;i<nbTuples;i++,inPtr++)
1746     {
1747       double val=*inPtr;
1748       for(int j=0;j<nbTimes;j++,retPtr++)
1749         *retPtr=val;
1750     }
1751   ret->copyStringInfoFrom(*this);
1752   return ret.retn();
1753 }
1754
1755 /*!
1756  * This methods returns the minimal distance between the two set of points \a this and \a other.
1757  * So \a this and \a other have to have the same number of components. If not an INTERP_KERNEL::Exception will be thrown.
1758  * This method works only if number of components of \a this (equal to those of \a other) is in 1, 2 or 3.
1759  *
1760  * \param [out] thisTupleId the tuple id in \a this corresponding to the returned minimal distance
1761  * \param [out] otherTupleId the tuple id in \a other corresponding to the returned minimal distance
1762  * \return the minimal distance between the two set of points \a this and \a other.
1763  * \sa DataArrayDouble::findClosestTupleId
1764  */
1765 double DataArrayDouble::minimalDistanceTo(const DataArrayDouble *other, int& thisTupleId, int& otherTupleId) const throw(INTERP_KERNEL::Exception)
1766 {
1767   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> part1=findClosestTupleId(other);
1768   int nbOfCompo(getNumberOfComponents());
1769   int otherNbTuples(other->getNumberOfTuples());
1770   const double *thisPt(begin()),*otherPt(other->begin());
1771   const int *part1Pt(part1->begin());
1772   double ret=std::numeric_limits<double>::max();
1773   for(int i=0;i<otherNbTuples;i++,part1Pt++,otherPt+=nbOfCompo)
1774     {
1775       double tmp(0.);
1776       for(int j=0;j<nbOfCompo;j++)
1777         tmp+=(otherPt[j]-thisPt[nbOfCompo*(*part1Pt)+j])*(otherPt[j]-thisPt[nbOfCompo*(*part1Pt)+j]);
1778       if(tmp<ret)
1779         { ret=tmp; thisTupleId=*part1Pt; otherTupleId=i; }
1780     }
1781   return sqrt(ret);
1782 }
1783
1784 /*!
1785  * This methods returns for each tuple in \a other which tuple in \a this is the closest.
1786  * So \a this and \a other have to have the same number of components. If not an INTERP_KERNEL::Exception will be thrown.
1787  * This method works only if number of components of \a this (equal to those of \a other) is in 1, 2 or 3.
1788  *
1789  * \return a newly allocated (new object to be dealt by the caller) DataArrayInt having \c other->getNumberOfTuples() tuples and one components.
1790  * \sa DataArrayDouble::minimalDistanceTo
1791  */
1792 DataArrayInt *DataArrayDouble::findClosestTupleId(const DataArrayDouble *other) const throw(INTERP_KERNEL::Exception)
1793 {
1794   if(!other)
1795     throw INTERP_KERNEL::Exception("DataArrayDouble::findClosestTupleId : other instance is NULL !");
1796   checkAllocated(); other->checkAllocated();
1797   int nbOfCompo=getNumberOfComponents();
1798   if(nbOfCompo!=other->getNumberOfComponents())
1799     {
1800       std::ostringstream oss; oss << "DataArrayDouble::findClosestTupleId : number of components in this is " << nbOfCompo;
1801       oss << ", whereas number of components in other is " << other->getNumberOfComponents() << "! Should be equal !";
1802       throw INTERP_KERNEL::Exception(oss.str().c_str());
1803     }
1804   int nbOfTuples=other->getNumberOfTuples();
1805   int thisNbOfTuples=getNumberOfTuples();
1806   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbOfTuples,1);
1807   double bounds[6];
1808   getMinMaxPerComponent(bounds);
1809   switch(nbOfCompo)
1810     {
1811     case 3:
1812       {
1813         double xDelta(fabs(bounds[1]-bounds[0])),yDelta(fabs(bounds[3]-bounds[2])),zDelta(fabs(bounds[5]-bounds[4]));
1814         double delta=std::max(xDelta,yDelta); delta=std::max(delta,zDelta);
1815         double characSize=pow((delta*delta*delta)/((double)thisNbOfTuples),1./3.);
1816         BBTreePts<3,int> myTree(begin(),0,0,getNumberOfTuples(),characSize*1e-12);
1817         FindClosestTupleIdAlg<3>(myTree,3.*characSize*characSize,other->begin(),nbOfTuples,begin(),thisNbOfTuples,ret->getPointer());
1818         break;
1819       }
1820     case 2:
1821       {
1822         double xDelta(fabs(bounds[1]-bounds[0])),yDelta(fabs(bounds[3]-bounds[2]));
1823         double delta=std::max(xDelta,yDelta);
1824         double characSize=sqrt(delta/(double)thisNbOfTuples);
1825         BBTreePts<2,int> myTree(begin(),0,0,getNumberOfTuples(),characSize*1e-12);
1826         FindClosestTupleIdAlg<2>(myTree,2.*characSize*characSize,other->begin(),nbOfTuples,begin(),thisNbOfTuples,ret->getPointer());
1827         break;
1828       }
1829     case 1:
1830       {
1831         double characSize=fabs(bounds[1]-bounds[0])/thisNbOfTuples;
1832         BBTreePts<1,int> myTree(begin(),0,0,getNumberOfTuples(),characSize*1e-12);
1833         FindClosestTupleIdAlg<1>(myTree,1.*characSize*characSize,other->begin(),nbOfTuples,begin(),thisNbOfTuples,ret->getPointer());
1834         break;
1835       }
1836     default:
1837       throw INTERP_KERNEL::Exception("Unexpected spacedim of coords for findClosestTupleId. Must be 1, 2 or 3.");
1838     }
1839   return ret.retn();
1840 }
1841
1842 /*!
1843  * Returns a copy of \a this array by excluding coincident tuples. Each tuple is
1844  * considered as coordinates of a point in getNumberOfComponents()-dimensional
1845  * space. The distance between tuples is computed using norm2. If several tuples are
1846  * not far each from other than \a prec, only one of them remains in the result
1847  * array. The order of tuples in the result array is same as in \a this one except
1848  * that coincident tuples are excluded.
1849  *  \param [in] prec - minimal absolute distance between two tuples at which they are
1850  *              considered not coincident.
1851  *  \param [in] limitTupleId - limit tuple id. Tuples with id strictly lower than \a 
1852  *              limiTupleId are not considered and thus not excluded.
1853  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1854  *          is to delete using decrRef() as it is no more needed.
1855  *  \throw If \a this is not allocated.
1856  *  \throw If the number of components is not in [1,2,3].
1857  *
1858  *  \ref cpp_mcdataarraydouble_getdifferentvalues "Here is a Python example".
1859  */
1860 DataArrayDouble *DataArrayDouble::getDifferentValues(double prec, int limitTupleId) const throw(INTERP_KERNEL::Exception)
1861 {
1862   checkAllocated();
1863   DataArrayInt *c0=0,*cI0=0;
1864   findCommonTuples(prec,limitTupleId,c0,cI0);
1865   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> c(c0),cI(cI0);
1866   int newNbOfTuples=-1;
1867   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> o2n=DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2(getNumberOfTuples(),c0->begin(),cI0->begin(),cI0->end(),newNbOfTuples);
1868   return renumberAndReduce(o2n->getConstPointer(),newNbOfTuples);
1869 }
1870
1871 /*!
1872  * Copy all components in a specified order from another DataArrayDouble.
1873  * The specified components become the first ones in \a this array.
1874  * Both numerical and textual data is copied. The number of tuples in \a this and
1875  * the other array can be different.
1876  *  \param [in] a - the array to copy data from.
1877  *  \param [in] compoIds - sequence of zero based indices of components, data of which is
1878  *              to be copied.
1879  *  \throw If \a a is NULL.
1880  *  \throw If \a compoIds.size() != \a a->getNumberOfComponents().
1881  *  \throw If \a compoIds[i] < 0 or \a compoIds[i] > \a this->getNumberOfComponents().
1882  *
1883  *  \ref cpp_mcdataarraydouble_setselectedcomponents "Here is a Python example".
1884  */
1885 void DataArrayDouble::setSelectedComponents(const DataArrayDouble *a, const std::vector<int>& compoIds) throw(INTERP_KERNEL::Exception)
1886 {
1887   if(!a)
1888     throw INTERP_KERNEL::Exception("DataArrayDouble::setSelectedComponents : input DataArrayDouble is NULL !");
1889   checkAllocated();
1890   copyPartOfStringInfoFrom2(compoIds,*a);
1891   std::size_t partOfCompoSz=compoIds.size();
1892   int nbOfCompo=getNumberOfComponents();
1893   int nbOfTuples=std::min(getNumberOfTuples(),a->getNumberOfTuples());
1894   const double *ac=a->getConstPointer();
1895   double *nc=getPointer();
1896   for(int i=0;i<nbOfTuples;i++)
1897     for(std::size_t j=0;j<partOfCompoSz;j++,ac++)
1898       nc[nbOfCompo*i+compoIds[j]]=*ac;
1899 }
1900
1901 /*!
1902  * Copy all values from another DataArrayDouble into specified tuples and components
1903  * of \a this array. Textual data is not copied.
1904  * The tree parameters defining set of indices of tuples and components are similar to
1905  * the tree parameters of the Python function \c range(\c start,\c stop,\c step).
1906  *  \param [in] a - the array to copy values from.
1907  *  \param [in] bgTuples - index of the first tuple of \a this array to assign values to.
1908  *  \param [in] endTuples - index of the tuple before which the tuples to assign to
1909  *              are located.
1910  *  \param [in] stepTuples - index increment to get index of the next tuple to assign to.
1911  *  \param [in] bgComp - index of the first component of \a this array to assign values to.
1912  *  \param [in] endComp - index of the component before which the components to assign
1913  *              to are located.
1914  *  \param [in] stepComp - index increment to get index of the next component to assign to.
1915  *  \param [in] strictCompoCompare - if \a true (by default), then \a a->getNumberOfComponents() 
1916  *              must be equal to the number of columns to assign to, else an
1917  *              exception is thrown; if \a false, then it is only required that \a
1918  *              a->getNbOfElems() equals to number of values to assign to (this condition
1919  *              must be respected even if \a strictCompoCompare is \a true). The number of 
1920  *              values to assign to is given by following Python expression:
1921  *              \a nbTargetValues = 
1922  *              \c len(\c range(\a bgTuples,\a endTuples,\a stepTuples)) *
1923  *              \c len(\c range(\a bgComp,\a endComp,\a stepComp)).
1924  *  \throw If \a a is NULL.
1925  *  \throw If \a a is not allocated.
1926  *  \throw If \a this is not allocated.
1927  *  \throw If parameters specifying tuples and components to assign to do not give a
1928  *            non-empty range of increasing indices.
1929  *  \throw If \a a->getNbOfElems() != \a nbTargetValues.
1930  *  \throw If \a strictCompoCompare == \a true && \a a->getNumberOfComponents() !=
1931  *            \c len(\c range(\a bgComp,\a endComp,\a stepComp)).
1932  *
1933  *  \ref cpp_mcdataarraydouble_setpartofvalues1 "Here is a Python example".
1934  */
1935 void DataArrayDouble::setPartOfValues1(const DataArrayDouble *a, int bgTuples, int endTuples, int stepTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare) throw(INTERP_KERNEL::Exception)
1936 {
1937   if(!a)
1938     throw INTERP_KERNEL::Exception("DataArrayDouble::setPartOfValues1 : input DataArrayDouble is NULL !");
1939   const char msg[]="DataArrayDouble::setPartOfValues1";
1940   checkAllocated();
1941   a->checkAllocated();
1942   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
1943   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
1944   int nbComp=getNumberOfComponents();
1945   int nbOfTuples=getNumberOfTuples();
1946   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
1947   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
1948   bool assignTech=true;
1949   if(a->getNbOfElems()==newNbOfTuples*newNbOfComp)
1950     {
1951       if(strictCompoCompare)
1952         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
1953     }
1954   else
1955     {
1956       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
1957       assignTech=false;
1958     }
1959   const double *srcPt=a->getConstPointer();
1960   double *pt=getPointer()+bgTuples*nbComp+bgComp;
1961   if(assignTech)
1962     {
1963       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
1964         for(int j=0;j<newNbOfComp;j++,srcPt++)
1965           pt[j*stepComp]=*srcPt;
1966     }
1967   else
1968     {
1969       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
1970         {
1971           const double *srcPt2=srcPt;
1972           for(int j=0;j<newNbOfComp;j++,srcPt2++)
1973             pt[j*stepComp]=*srcPt2;
1974         }
1975     }
1976 }
1977
1978 /*!
1979  * Assign a given value to values at specified tuples and components of \a this array.
1980  * The tree parameters defining set of indices of tuples and components are similar to
1981  * the tree parameters of the Python function \c range(\c start,\c stop,\c step)..
1982  *  \param [in] a - the value to assign.
1983  *  \param [in] bgTuples - index of the first tuple of \a this array to assign to.
1984  *  \param [in] endTuples - index of the tuple before which the tuples to assign to
1985  *              are located.
1986  *  \param [in] stepTuples - index increment to get index of the next tuple to assign to.
1987  *  \param [in] bgComp - index of the first component of \a this array to assign to.
1988  *  \param [in] endComp - index of the component before which the components to assign
1989  *              to are located.
1990  *  \param [in] stepComp - index increment to get index of the next component to assign to.
1991  *  \throw If \a this is not allocated.
1992  *  \throw If parameters specifying tuples and components to assign to, do not give a
1993  *            non-empty range of increasing indices or indices are out of a valid range
1994  *            for \this array.
1995  *
1996  *  \ref cpp_mcdataarraydouble_setpartofvaluessimple1 "Here is a Python example".
1997  */
1998 void DataArrayDouble::setPartOfValuesSimple1(double a, int bgTuples, int endTuples, int stepTuples, int bgComp, int endComp, int stepComp) throw(INTERP_KERNEL::Exception)
1999 {
2000   const char msg[]="DataArrayDouble::setPartOfValuesSimple1";
2001   checkAllocated();
2002   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
2003   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
2004   int nbComp=getNumberOfComponents();
2005   int nbOfTuples=getNumberOfTuples();
2006   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
2007   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
2008   double *pt=getPointer()+bgTuples*nbComp+bgComp;
2009   for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
2010     for(int j=0;j<newNbOfComp;j++)
2011       pt[j*stepComp]=a;
2012 }
2013
2014 /*!
2015  * Copy all values from another DataArrayDouble (\a a) into specified tuples and 
2016  * components of \a this array. Textual data is not copied.
2017  * The tuples and components to assign to are defined by C arrays of indices.
2018  * There are two *modes of usage*:
2019  * - If \a a->getNbOfElems() equals to number of values to assign to, then every value
2020  *   of \a a is assigned to its own location within \a this array. 
2021  * - If \a a includes one tuple, then all values of \a a are assigned to the specified
2022  *   components of every specified tuple of \a this array. In this mode it is required
2023  *   that \a a->getNumberOfComponents() equals to the number of specified components.
2024  *
2025  *  \param [in] a - the array to copy values from.
2026  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
2027  *              assign values of \a a to.
2028  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
2029  *              pointer to a tuple index <em>(pi)</em> varies as this: 
2030  *              \a bgTuples <= \a pi < \a endTuples.
2031  *  \param [in] bgComp - pointer to an array of component indices of \a this array to
2032  *              assign values of \a a to.
2033  *  \param [in] endComp - specifies the end of the array \a bgTuples, so that
2034  *              pointer to a component index <em>(pi)</em> varies as this: 
2035  *              \a bgComp <= \a pi < \a endComp.
2036  *  \param [in] strictCompoCompare - this parameter is checked only if the
2037  *               *mode of usage* is the first; if it is \a true (default), 
2038  *               then \a a->getNumberOfComponents() must be equal 
2039  *               to the number of specified columns, else this is not required.
2040  *  \throw If \a a is NULL.
2041  *  \throw If \a a is not allocated.
2042  *  \throw If \a this is not allocated.
2043  *  \throw If any index of tuple/component given by <em>bgTuples / bgComp</em> is
2044  *         out of a valid range for \a this array.
2045  *  \throw In the first *mode of usage*, if <em>strictCompoCompare == true </em> and
2046  *         if <em> a->getNumberOfComponents() != (endComp - bgComp) </em>.
2047  *  \throw In the second *mode of usage*, if \a a->getNumberOfTuples() != 1 or
2048  *         <em> a->getNumberOfComponents() != (endComp - bgComp)</em>.
2049  *
2050  *  \ref cpp_mcdataarraydouble_setpartofvalues2 "Here is a Python example".
2051  */
2052 void DataArrayDouble::setPartOfValues2(const DataArrayDouble *a, const int *bgTuples, const int *endTuples, const int *bgComp, const int *endComp, bool strictCompoCompare) throw(INTERP_KERNEL::Exception)
2053 {
2054   if(!a)
2055     throw INTERP_KERNEL::Exception("DataArrayDouble::setPartOfValues2 : input DataArrayDouble is NULL !");
2056   const char msg[]="DataArrayDouble::setPartOfValues2";
2057   checkAllocated();
2058   a->checkAllocated();
2059   int nbComp=getNumberOfComponents();
2060   int nbOfTuples=getNumberOfTuples();
2061   for(const int *z=bgComp;z!=endComp;z++)
2062     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
2063   int newNbOfTuples=(int)std::distance(bgTuples,endTuples);
2064   int newNbOfComp=(int)std::distance(bgComp,endComp);
2065   bool assignTech=true;
2066   if(a->getNbOfElems()==newNbOfTuples*newNbOfComp)
2067     {
2068       if(strictCompoCompare)
2069         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
2070     }
2071   else
2072     {
2073       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
2074       assignTech=false;
2075     }
2076   double *pt=getPointer();
2077   const double *srcPt=a->getConstPointer();
2078   if(assignTech)
2079     {    
2080       for(const int *w=bgTuples;w!=endTuples;w++)
2081         {
2082           DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
2083           for(const int *z=bgComp;z!=endComp;z++,srcPt++)
2084             {    
2085               pt[(*w)*nbComp+(*z)]=*srcPt;
2086             }
2087         }
2088     }
2089   else
2090     {
2091       for(const int *w=bgTuples;w!=endTuples;w++)
2092         {
2093           const double *srcPt2=srcPt;
2094           DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
2095           for(const int *z=bgComp;z!=endComp;z++,srcPt2++)
2096             {    
2097               pt[(*w)*nbComp+(*z)]=*srcPt2;
2098             }
2099         }
2100     }
2101 }
2102
2103 /*!
2104  * Assign a given value to values at specified tuples and components of \a this array.
2105  * The tuples and components to assign to are defined by C arrays of indices.
2106  *  \param [in] a - the value to assign.
2107  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
2108  *              assign \a a to.
2109  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
2110  *              pointer to a tuple index (\a pi) varies as this: 
2111  *              \a bgTuples <= \a pi < \a endTuples.
2112  *  \param [in] bgComp - pointer to an array of component indices of \a this array to
2113  *              assign \a a to.
2114  *  \param [in] endComp - specifies the end of the array \a bgTuples, so that
2115  *              pointer to a component index (\a pi) varies as this: 
2116  *              \a bgComp <= \a pi < \a endComp.
2117  *  \throw If \a this is not allocated.
2118  *  \throw If any index of tuple/component given by <em>bgTuples / bgComp</em> is
2119  *         out of a valid range for \a this array.
2120  *
2121  *  \ref cpp_mcdataarraydouble_setpartofvaluessimple2 "Here is a Python example".
2122  */
2123 void DataArrayDouble::setPartOfValuesSimple2(double a, const int *bgTuples, const int *endTuples, const int *bgComp, const int *endComp) throw(INTERP_KERNEL::Exception)
2124 {
2125   checkAllocated();
2126   int nbComp=getNumberOfComponents();
2127   int nbOfTuples=getNumberOfTuples();
2128   for(const int *z=bgComp;z!=endComp;z++)
2129     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
2130   double *pt=getPointer();
2131   for(const int *w=bgTuples;w!=endTuples;w++)
2132     for(const int *z=bgComp;z!=endComp;z++)
2133       {
2134         DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
2135         pt[(*w)*nbComp+(*z)]=a;
2136       }
2137 }
2138
2139 /*!
2140  * Copy all values from another DataArrayDouble (\a a) into specified tuples and 
2141  * components of \a this array. Textual data is not copied.
2142  * The tuples to assign to are defined by a C array of indices.
2143  * The components to assign to are defined by three values similar to parameters of
2144  * the Python function \c range(\c start,\c stop,\c step).
2145  * There are two *modes of usage*:
2146  * - If \a a->getNbOfElems() equals to number of values to assign to, then every value
2147  *   of \a a is assigned to its own location within \a this array. 
2148  * - If \a a includes one tuple, then all values of \a a are assigned to the specified
2149  *   components of every specified tuple of \a this array. In this mode it is required
2150  *   that \a a->getNumberOfComponents() equals to the number of specified components.
2151  *
2152  *  \param [in] a - the array to copy values from.
2153  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
2154  *              assign values of \a a to.
2155  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
2156  *              pointer to a tuple index <em>(pi)</em> varies as this: 
2157  *              \a bgTuples <= \a pi < \a endTuples.
2158  *  \param [in] bgComp - index of the first component of \a this array to assign to.
2159  *  \param [in] endComp - index of the component before which the components to assign
2160  *              to are located.
2161  *  \param [in] stepComp - index increment to get index of the next component to assign to.
2162  *  \param [in] strictCompoCompare - this parameter is checked only in the first
2163  *               *mode of usage*; if \a strictCompoCompare is \a true (default), 
2164  *               then \a a->getNumberOfComponents() must be equal 
2165  *               to the number of specified columns, else this is not required.
2166  *  \throw If \a a is NULL.
2167  *  \throw If \a a is not allocated.
2168  *  \throw If \a this is not allocated.
2169  *  \throw If any index of tuple given by \a bgTuples is out of a valid range for 
2170  *         \a this array.
2171  *  \throw In the first *mode of usage*, if <em>strictCompoCompare == true </em> and
2172  *         if <em> a->getNumberOfComponents()</em> is unequal to the number of components
2173  *         defined by <em>(bgComp,endComp,stepComp)</em>.
2174  *  \throw In the second *mode of usage*, if \a a->getNumberOfTuples() != 1 or
2175  *         <em> a->getNumberOfComponents()</em> is unequal to the number of components
2176  *         defined by <em>(bgComp,endComp,stepComp)</em>.
2177  *  \throw If parameters specifying components to assign to, do not give a
2178  *            non-empty range of increasing indices or indices are out of a valid range
2179  *            for \this array.
2180  *
2181  *  \ref cpp_mcdataarraydouble_setpartofvalues3 "Here is a Python example".
2182  */
2183 void DataArrayDouble::setPartOfValues3(const DataArrayDouble *a, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare) throw(INTERP_KERNEL::Exception)
2184 {
2185   if(!a)
2186     throw INTERP_KERNEL::Exception("DataArrayDouble::setPartOfValues3 : input DataArrayDouble is NULL !");
2187   const char msg[]="DataArrayDouble::setPartOfValues3";
2188   checkAllocated();
2189   a->checkAllocated();
2190   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
2191   int nbComp=getNumberOfComponents();
2192   int nbOfTuples=getNumberOfTuples();
2193   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
2194   int newNbOfTuples=(int)std::distance(bgTuples,endTuples);
2195   bool assignTech=true;
2196   if(a->getNbOfElems()==newNbOfTuples*newNbOfComp)
2197     {
2198       if(strictCompoCompare)
2199         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
2200     }
2201   else
2202     {
2203       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
2204       assignTech=false;
2205     }
2206   double *pt=getPointer()+bgComp;
2207   const double *srcPt=a->getConstPointer();
2208   if(assignTech)
2209     {
2210       for(const int *w=bgTuples;w!=endTuples;w++)
2211         for(int j=0;j<newNbOfComp;j++,srcPt++)
2212           {
2213             DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
2214             pt[(*w)*nbComp+j*stepComp]=*srcPt;
2215           }
2216     }
2217   else
2218     {
2219       for(const int *w=bgTuples;w!=endTuples;w++)
2220         {
2221           const double *srcPt2=srcPt;
2222           for(int j=0;j<newNbOfComp;j++,srcPt2++)
2223             {
2224               DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
2225               pt[(*w)*nbComp+j*stepComp]=*srcPt2;
2226             }
2227         }
2228     }
2229 }
2230
2231 /*!
2232  * Assign a given value to values at specified tuples and components of \a this array.
2233  * The tuples to assign to are defined by a C array of indices.
2234  * The components to assign to are defined by three values similar to parameters of
2235  * the Python function \c range(\c start,\c stop,\c step).
2236  *  \param [in] a - the value to assign.
2237  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
2238  *              assign \a a to.
2239  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
2240  *              pointer to a tuple index <em>(pi)</em> varies as this: 
2241  *              \a bgTuples <= \a pi < \a endTuples.
2242  *  \param [in] bgComp - index of the first component of \a this array to assign to.
2243  *  \param [in] endComp - index of the component before which the components to assign
2244  *              to are located.
2245  *  \param [in] stepComp - index increment to get index of the next component to assign to.
2246  *  \throw If \a this is not allocated.
2247  *  \throw If any index of tuple given by \a bgTuples is out of a valid range for 
2248  *         \a this array.
2249  *  \throw If parameters specifying components to assign to, do not give a
2250  *            non-empty range of increasing indices or indices are out of a valid range
2251  *            for \this array.
2252  *
2253  *  \ref cpp_mcdataarraydouble_setpartofvaluessimple3 "Here is a Python example".
2254  */
2255 void DataArrayDouble::setPartOfValuesSimple3(double a, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp) throw(INTERP_KERNEL::Exception)
2256 {
2257   const char msg[]="DataArrayDouble::setPartOfValuesSimple3";
2258   checkAllocated();
2259   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
2260   int nbComp=getNumberOfComponents();
2261   int nbOfTuples=getNumberOfTuples();
2262   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
2263   double *pt=getPointer()+bgComp;
2264   for(const int *w=bgTuples;w!=endTuples;w++)
2265     for(int j=0;j<newNbOfComp;j++)
2266       {
2267         DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
2268         pt[(*w)*nbComp+j*stepComp]=a;
2269       }
2270 }
2271
2272 /*!
2273  * Copy all values from another DataArrayDouble into specified tuples and components
2274  * of \a this array. Textual data is not copied.
2275  * The tree parameters defining set of indices of tuples and components are similar to
2276  * the tree parameters of the Python function \c range(\c start,\c stop,\c step).
2277  *  \param [in] a - the array to copy values from.
2278  *  \param [in] bgTuples - index of the first tuple of \a this array to assign values to.
2279  *  \param [in] endTuples - index of the tuple before which the tuples to assign to
2280  *              are located.
2281  *  \param [in] stepTuples - index increment to get index of the next tuple to assign to.
2282  *  \param [in] bgComp - pointer to an array of component indices of \a this array to
2283  *              assign \a a to.
2284  *  \param [in] endComp - specifies the end of the array \a bgTuples, so that
2285  *              pointer to a component index (\a pi) varies as this: 
2286  *              \a bgComp <= \a pi < \a endComp.
2287  *  \param [in] strictCompoCompare - if \a true (by default), then \a a->getNumberOfComponents() 
2288  *              must be equal to the number of columns to assign to, else an
2289  *              exception is thrown; if \a false, then it is only required that \a
2290  *              a->getNbOfElems() equals to number of values to assign to (this condition
2291  *              must be respected even if \a strictCompoCompare is \a true). The number of 
2292  *              values to assign to is given by following Python expression:
2293  *              \a nbTargetValues = 
2294  *              \c len(\c range(\a bgTuples,\a endTuples,\a stepTuples)) *
2295  *              \c len(\c range(\a bgComp,\a endComp,\a stepComp)).
2296  *  \throw If \a a is NULL.
2297  *  \throw If \a a is not allocated.
2298  *  \throw If \a this is not allocated.
2299  *  \throw If parameters specifying tuples and components to assign to do not give a
2300  *            non-empty range of increasing indices.
2301  *  \throw If \a a->getNbOfElems() != \a nbTargetValues.
2302  *  \throw If \a strictCompoCompare == \a true && \a a->getNumberOfComponents() !=
2303  *            \c len(\c range(\a bgComp,\a endComp,\a stepComp)).
2304  *
2305  */
2306 void DataArrayDouble::setPartOfValues4(const DataArrayDouble *a, int bgTuples, int endTuples, int stepTuples, const int *bgComp, const int *endComp, bool strictCompoCompare) throw(INTERP_KERNEL::Exception)
2307 {
2308   if(!a)
2309     throw INTERP_KERNEL::Exception("DataArrayDouble::setPartOfValues4 : input DataArrayDouble is NULL !");
2310   const char msg[]="DataArrayDouble::setPartOfValues4";
2311   checkAllocated();
2312   a->checkAllocated();
2313   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
2314   int newNbOfComp=(int)std::distance(bgComp,endComp);
2315   int nbComp=getNumberOfComponents();
2316   for(const int *z=bgComp;z!=endComp;z++)
2317     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
2318   int nbOfTuples=getNumberOfTuples();
2319   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
2320   bool assignTech=true;
2321   if(a->getNbOfElems()==newNbOfTuples*newNbOfComp)
2322     {
2323       if(strictCompoCompare)
2324         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
2325     }
2326   else
2327     {
2328       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
2329       assignTech=false;
2330     }
2331   const double *srcPt=a->getConstPointer();
2332   double *pt=getPointer()+bgTuples*nbComp;
2333   if(assignTech)
2334     {
2335       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
2336         for(const int *z=bgComp;z!=endComp;z++,srcPt++)
2337           pt[*z]=*srcPt;
2338     }
2339   else
2340     {
2341       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
2342         {
2343           const double *srcPt2=srcPt;
2344           for(const int *z=bgComp;z!=endComp;z++,srcPt2++)
2345             pt[*z]=*srcPt2;
2346         }
2347     }
2348 }
2349
2350 void DataArrayDouble::setPartOfValuesSimple4(double a, int bgTuples, int endTuples, int stepTuples, const int *bgComp, const int *endComp) throw(INTERP_KERNEL::Exception)
2351 {
2352   const char msg[]="DataArrayDouble::setPartOfValuesSimple4";
2353   checkAllocated();
2354   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
2355   int nbComp=getNumberOfComponents();
2356   for(const int *z=bgComp;z!=endComp;z++)
2357     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
2358   int nbOfTuples=getNumberOfTuples();
2359   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
2360   double *pt=getPointer()+bgTuples*nbComp;
2361   for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
2362     for(const int *z=bgComp;z!=endComp;z++)
2363       pt[*z]=a;
2364 }
2365
2366 /*!
2367  * Copy some tuples from another DataArrayDouble into specified tuples
2368  * of \a this array. Textual data is not copied. Both arrays must have equal number of
2369  * components.
2370  * Both the tuples to assign and the tuples to assign to are defined by a DataArrayInt.
2371  * All components of selected tuples are copied.
2372  *  \param [in] a - the array to copy values from.
2373  *  \param [in] tuplesSelec - the array specifying both source tuples of \a a and
2374  *              target tuples of \a this. \a tuplesSelec has two components, and the
2375  *              first component specifies index of the source tuple and the second
2376  *              one specifies index of the target tuple.
2377  *  \throw If \a this is not allocated.
2378  *  \throw If \a a is NULL.
2379  *  \throw If \a a is not allocated.
2380  *  \throw If \a tuplesSelec is NULL.
2381  *  \throw If \a tuplesSelec is not allocated.
2382  *  \throw If <em>this->getNumberOfComponents() != a->getNumberOfComponents()</em>.
2383  *  \throw If \a tuplesSelec->getNumberOfComponents() != 2.
2384  *  \throw If any tuple index given by \a tuplesSelec is out of a valid range for 
2385  *         the corresponding (\a this or \a a) array.
2386  */
2387 void DataArrayDouble::setPartOfValuesAdv(const DataArrayDouble *a, const DataArrayInt *tuplesSelec) throw(INTERP_KERNEL::Exception)
2388 {
2389   if(!a || !tuplesSelec)
2390     throw INTERP_KERNEL::Exception("DataArrayDouble::setPartOfValuesAdv : input DataArrayDouble is NULL !");
2391   checkAllocated();
2392   a->checkAllocated();
2393   tuplesSelec->checkAllocated();
2394   int nbOfComp=getNumberOfComponents();
2395   if(nbOfComp!=a->getNumberOfComponents())
2396     throw INTERP_KERNEL::Exception("DataArrayDouble::setPartOfValuesAdv : This and a do not have the same number of components !");
2397   if(tuplesSelec->getNumberOfComponents()!=2)
2398     throw INTERP_KERNEL::Exception("DataArrayDouble::setPartOfValuesAdv : Expecting to have a tuple selector DataArrayInt instance with exactly 2 components !");
2399   int thisNt=getNumberOfTuples();
2400   int aNt=a->getNumberOfTuples();
2401   double *valsToSet=getPointer();
2402   const double *valsSrc=a->getConstPointer();
2403   for(const int *tuple=tuplesSelec->begin();tuple!=tuplesSelec->end();tuple+=2)
2404     {
2405       if(tuple[1]>=0 && tuple[1]<aNt)
2406         {
2407           if(tuple[0]>=0 && tuple[0]<thisNt)
2408             std::copy(valsSrc+nbOfComp*tuple[1],valsSrc+nbOfComp*(tuple[1]+1),valsToSet+nbOfComp*tuple[0]);
2409           else
2410             {
2411               std::ostringstream oss; oss << "DataArrayDouble::setPartOfValuesAdv : Tuple #" << std::distance(tuplesSelec->begin(),tuple)/2;
2412               oss << " of 'tuplesSelec' request of tuple id #" << tuple[0] << " in 'this' ! It should be in [0," << thisNt << ") !";
2413               throw INTERP_KERNEL::Exception(oss.str().c_str());
2414             }
2415         }
2416       else
2417         {
2418           std::ostringstream oss; oss << "DataArrayDouble::setPartOfValuesAdv : Tuple #" << std::distance(tuplesSelec->begin(),tuple)/2;
2419           oss << " of 'tuplesSelec' request of tuple id #" << tuple[1] << " in 'a' ! It should be in [0," << aNt << ") !";
2420           throw INTERP_KERNEL::Exception(oss.str().c_str());
2421         }
2422     }
2423 }
2424
2425 /*!
2426  * Copy some tuples from another DataArrayDouble (\a a) into contiguous tuples
2427  * of \a this array. Textual data is not copied. Both arrays must have equal number of
2428  * components.
2429  * The tuples to assign to are defined by index of the first tuple, and
2430  * their number is defined by \a tuplesSelec->getNumberOfTuples().
2431  * The tuples to copy are defined by values of a DataArrayInt.
2432  * All components of selected tuples are copied.
2433  *  \param [in] tupleIdStart - index of the first tuple of \a this array to assign
2434  *              values to.
2435  *  \param [in] a - the array to copy values from.
2436  *  \param [in] tuplesSelec - the array specifying tuples of \a a to copy.
2437  *  \throw If \a this is not allocated.
2438  *  \throw If \a a is NULL.
2439  *  \throw If \a a is not allocated.
2440  *  \throw If \a tuplesSelec is NULL.
2441  *  \throw If \a tuplesSelec is not allocated.
2442  *  \throw If <em>this->getNumberOfComponents() != a->getNumberOfComponents()</em>.
2443  *  \throw If \a tuplesSelec->getNumberOfComponents() != 1.
2444  *  \throw If <em>tupleIdStart + tuplesSelec->getNumberOfTuples() > this->getNumberOfTuples().</em>
2445  *  \throw If any tuple index given by \a tuplesSelec is out of a valid range for 
2446  *         \a a array.
2447  */
2448 void DataArrayDouble::setContigPartOfSelectedValues(int tupleIdStart, const DataArrayDouble *a, const DataArrayInt *tuplesSelec) throw(INTERP_KERNEL::Exception)
2449 {
2450   if(!a || !tuplesSelec)
2451     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues : input DataArray is NULL !");
2452   checkAllocated();
2453   a->checkAllocated();
2454   tuplesSelec->checkAllocated();
2455   int nbOfComp=getNumberOfComponents();
2456   if(nbOfComp!=a->getNumberOfComponents())
2457     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues : This and a do not have the same number of components !");
2458   if(tuplesSelec->getNumberOfComponents()!=1)
2459     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues : Expecting to have a tuple selector DataArrayInt instance with exactly 1 component !");
2460   int thisNt=getNumberOfTuples();
2461   int aNt=a->getNumberOfTuples();
2462   int nbOfTupleToWrite=tuplesSelec->getNumberOfTuples();
2463   double *valsToSet=getPointer()+tupleIdStart*nbOfComp;
2464   if(tupleIdStart+nbOfTupleToWrite>thisNt)
2465     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues : invalid number range of values to write !");
2466   const double *valsSrc=a->getConstPointer();
2467   for(const int *tuple=tuplesSelec->begin();tuple!=tuplesSelec->end();tuple++,valsToSet+=nbOfComp)
2468     {
2469       if(*tuple>=0 && *tuple<aNt)
2470         {
2471           std::copy(valsSrc+nbOfComp*(*tuple),valsSrc+nbOfComp*(*tuple+1),valsToSet);
2472         }
2473       else
2474         {
2475           std::ostringstream oss; oss << "DataArrayDouble::setContigPartOfSelectedValues : Tuple #" << std::distance(tuplesSelec->begin(),tuple);
2476           oss << " of 'tuplesSelec' request of tuple id #" << *tuple << " in 'a' ! It should be in [0," << aNt << ") !";
2477           throw INTERP_KERNEL::Exception(oss.str().c_str());
2478         }
2479     }
2480 }
2481
2482 /*!
2483  * Copy some tuples from another DataArrayDouble (\a a) into contiguous tuples
2484  * of \a this array. Textual data is not copied. Both arrays must have equal number of
2485  * components.
2486  * The tuples to copy are defined by three values similar to parameters of
2487  * the Python function \c range(\c start,\c stop,\c step).
2488  * The tuples to assign to are defined by index of the first tuple, and
2489  * their number is defined by number of tuples to copy.
2490  * All components of selected tuples are copied.
2491  *  \param [in] tupleIdStart - index of the first tuple of \a this array to assign
2492  *              values to.
2493  *  \param [in] a - the array to copy values from.
2494  *  \param [in] bg - index of the first tuple to copy of the array \a a.
2495  *  \param [in] end2 - index of the tuple of \a a before which the tuples to copy
2496  *              are located.
2497  *  \param [in] step - index increment to get index of the next tuple to copy.
2498  *  \throw If \a this is not allocated.
2499  *  \throw If \a a is NULL.
2500  *  \throw If \a a is not allocated.
2501  *  \throw If <em>this->getNumberOfComponents() != a->getNumberOfComponents()</em>.
2502  *  \throw If <em>tupleIdStart + len(range(bg,end2,step)) > this->getNumberOfTuples().</em>
2503  *  \throw If parameters specifying tuples to copy, do not give a
2504  *            non-empty range of increasing indices or indices are out of a valid range
2505  *            for the array \a a.
2506  */
2507 void DataArrayDouble::setContigPartOfSelectedValues2(int tupleIdStart, const DataArrayDouble *a, int bg, int end2, int step) throw(INTERP_KERNEL::Exception)
2508 {
2509   if(!a)
2510     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues2 : input DataArrayDouble is NULL !");
2511   checkAllocated();
2512   a->checkAllocated();
2513   int nbOfComp=getNumberOfComponents();
2514   const char msg[]="DataArrayDouble::setContigPartOfSelectedValues2";
2515   int nbOfTupleToWrite=DataArray::GetNumberOfItemGivenBES(bg,end2,step,msg);
2516   if(nbOfComp!=a->getNumberOfComponents())
2517     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues2 : This and a do not have the same number of components !");
2518   int thisNt=getNumberOfTuples();
2519   int aNt=a->getNumberOfTuples();
2520   double *valsToSet=getPointer()+tupleIdStart*nbOfComp;
2521   if(tupleIdStart+nbOfTupleToWrite>thisNt)
2522     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues2 : invalid number range of values to write !");
2523   if(end2>aNt)
2524     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues2 : invalid range of values to read !");
2525   const double *valsSrc=a->getConstPointer()+bg*nbOfComp;
2526   for(int i=0;i<nbOfTupleToWrite;i++,valsToSet+=nbOfComp,valsSrc+=step*nbOfComp)
2527     {
2528       std::copy(valsSrc,valsSrc+nbOfComp,valsToSet);
2529     }
2530 }
2531
2532 /*!
2533  * Returns a value located at specified tuple and component.
2534  * This method is equivalent to DataArrayDouble::getIJ() except that validity of
2535  * parameters is checked. So this method is safe but expensive if used to go through
2536  * all values of \a this.
2537  *  \param [in] tupleId - index of tuple of interest.
2538  *  \param [in] compoId - index of component of interest.
2539  *  \return double - value located by \a tupleId and \a compoId.
2540  *  \throw If \a this is not allocated.
2541  *  \throw If condition <em>( 0 <= tupleId < this->getNumberOfTuples() )</em> is violated.
2542  *  \throw If condition <em>( 0 <= compoId < this->getNumberOfComponents() )</em> is violated.
2543  */
2544 double DataArrayDouble::getIJSafe(int tupleId, int compoId) const throw(INTERP_KERNEL::Exception)
2545 {
2546   checkAllocated();
2547   if(tupleId<0 || tupleId>=getNumberOfTuples())
2548     {
2549       std::ostringstream oss; oss << "DataArrayDouble::getIJSafe : request for tupleId " << tupleId << " should be in [0," << getNumberOfTuples() << ") !";
2550       throw INTERP_KERNEL::Exception(oss.str().c_str());
2551     }
2552   if(compoId<0 || compoId>=getNumberOfComponents())
2553     {
2554       std::ostringstream oss; oss << "DataArrayDouble::getIJSafe : request for compoId " << compoId << " should be in [0," << getNumberOfComponents() << ") !";
2555       throw INTERP_KERNEL::Exception(oss.str().c_str());
2556     }
2557   return _mem[tupleId*((int)_info_on_compo.size())+compoId];
2558 }
2559
2560 /*!
2561  * Returns the last value of \a this. 
2562  *  \return double - the last value of \a this array.
2563  *  \throw If \a this is not allocated.
2564  *  \throw If \a this->getNumberOfComponents() != 1.
2565  *  \throw If \a this->getNumberOfTuples() < 1.
2566  */
2567 double DataArrayDouble::back() const throw(INTERP_KERNEL::Exception)
2568 {
2569   checkAllocated();
2570   if(getNumberOfComponents()!=1)
2571     throw INTERP_KERNEL::Exception("DataArrayDouble::back : number of components not equal to one !");
2572   int nbOfTuples=getNumberOfTuples();
2573   if(nbOfTuples<1)
2574     throw INTERP_KERNEL::Exception("DataArrayDouble::back : number of tuples must be >= 1 !");
2575   return *(getConstPointer()+nbOfTuples-1);
2576 }
2577
2578 void DataArrayDouble::SetArrayIn(DataArrayDouble *newArray, DataArrayDouble* &arrayToSet)
2579 {
2580   if(newArray!=arrayToSet)
2581     {
2582       if(arrayToSet)
2583         arrayToSet->decrRef();
2584       arrayToSet=newArray;
2585       if(arrayToSet)
2586         arrayToSet->incrRef();
2587     }
2588 }
2589
2590 /*!
2591  * Sets a C array to be used as raw data of \a this. The previously set info
2592  *  of components is retained and re-sized. 
2593  * For more info see \ref MEDCouplingArraySteps1.
2594  *  \param [in] array - the C array to be used as raw data of \a this.
2595  *  \param [in] ownership - if \a true, \a array will be deallocated at destruction of \a this.
2596  *  \param [in] type - specifies how to deallocate \a array. If \a type == ParaMEDMEM::CPP_DEALLOC,
2597  *                     \c delete [] \c array; will be called. If \a type == ParaMEDMEM::C_DEALLOC,
2598  *                     \c free(\c array ) will be called.
2599  *  \param [in] nbOfTuple - new number of tuples in \a this.
2600  *  \param [in] nbOfCompo - new number of components in \a this.
2601  */
2602 void DataArrayDouble::useArray(const double *array, bool ownership, DeallocType type, int nbOfTuple, int nbOfCompo) throw(INTERP_KERNEL::Exception)
2603 {
2604   _info_on_compo.resize(nbOfCompo);
2605   _mem.useArray(array,ownership,type,nbOfTuple*nbOfCompo);
2606   declareAsNew();
2607 }
2608
2609 void DataArrayDouble::useExternalArrayWithRWAccess(const double *array, int nbOfTuple, int nbOfCompo) throw(INTERP_KERNEL::Exception)
2610 {
2611   _info_on_compo.resize(nbOfCompo);
2612   _mem.useExternalArrayWithRWAccess(array,nbOfTuple*nbOfCompo);
2613   declareAsNew();
2614 }
2615
2616 /*!
2617  * Checks if 0.0 value is present in \a this array. If it is the case, an exception
2618  * is thrown.
2619  * \throw If zero is found in \a this array.
2620  */
2621 void DataArrayDouble::checkNoNullValues() const throw(INTERP_KERNEL::Exception)
2622 {
2623   const double *tmp=getConstPointer();
2624   int nbOfElems=getNbOfElems();
2625   const double *where=std::find(tmp,tmp+nbOfElems,0.);
2626   if(where!=tmp+nbOfElems)
2627     throw INTERP_KERNEL::Exception("A value 0.0 have been detected !");
2628 }
2629
2630 /*!
2631  * Computes minimal and maximal value in each component. An output array is filled
2632  * with \c 2 * \a this->getNumberOfComponents() values, so the caller is to allocate
2633  * enough memory before calling this method.
2634  *  \param [out] bounds - array of size at least 2 *\a this->getNumberOfComponents().
2635  *               It is filled as follows:<br>
2636  *               \a bounds[0] = \c min_of_component_0 <br>
2637  *               \a bounds[1] = \c max_of_component_0 <br>
2638  *               \a bounds[2] = \c min_of_component_1 <br>
2639  *               \a bounds[3] = \c max_of_component_1 <br>
2640  *               ...
2641  */
2642 void DataArrayDouble::getMinMaxPerComponent(double *bounds) const throw(INTERP_KERNEL::Exception)
2643 {
2644   checkAllocated();
2645   int dim=getNumberOfComponents();
2646   for (int idim=0; idim<dim; idim++)
2647     {
2648       bounds[idim*2]=std::numeric_limits<double>::max();
2649       bounds[idim*2+1]=-std::numeric_limits<double>::max();
2650     } 
2651   const double *ptr=getConstPointer();
2652   int nbOfTuples=getNumberOfTuples();
2653   for(int i=0;i<nbOfTuples;i++)
2654     {
2655       for(int idim=0;idim<dim;idim++)
2656         {
2657           if(bounds[idim*2]>ptr[i*dim+idim])
2658             {
2659               bounds[idim*2]=ptr[i*dim+idim];
2660             }
2661           if(bounds[idim*2+1]<ptr[i*dim+idim])
2662             {
2663               bounds[idim*2+1]=ptr[i*dim+idim];
2664             }
2665         }
2666     }
2667 }
2668
2669 /*!
2670  * This method retrieves a newly allocated DataArrayDouble instance having same number of tuples than \a this and twice number of components than \a this
2671  * to store both the min and max per component of each tuples. 
2672  * \param [in] epsilon the width of the bbox (identical in each direction) - 0.0 by default
2673  *
2674  * \return a newly created DataArrayDouble instance having \c this->getNumberOfTuples() tuples and 2 * \c this->getNumberOfComponent() components
2675  *
2676  * \throw If \a this is not allocated yet.
2677  */
2678 DataArrayDouble *DataArrayDouble::computeBBoxPerTuple(double epsilon)const throw(INTERP_KERNEL::Exception)
2679 {
2680   checkAllocated();
2681   const double *dataPtr=getConstPointer();
2682   int nbOfCompo=getNumberOfComponents();
2683   int nbTuples=getNumberOfTuples();
2684   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> bbox=DataArrayDouble::New();
2685   bbox->alloc(nbTuples,2*nbOfCompo);
2686   double *bboxPtr=bbox->getPointer();
2687   for(int i=0;i<nbTuples;i++)
2688     {
2689       for(int j=0;j<nbOfCompo;j++)
2690         {
2691           bboxPtr[2*nbOfCompo*i+2*j]=dataPtr[nbOfCompo*i+j]-epsilon;
2692           bboxPtr[2*nbOfCompo*i+2*j+1]=dataPtr[nbOfCompo*i+j]+epsilon;
2693         }
2694     }
2695   return bbox.retn();
2696 }
2697
2698 /*!
2699  * For each tuples **t** in \a other, this method retrieves tuples in \a this that are equal to **t**.
2700  * Two tuples are considered equal if the euclidian distance between the two tuples is lower than \a eps.
2701  * 
2702  * \param [in] other a DataArrayDouble having same number of components than \a this.
2703  * \param [in] eps absolute precision representing euclidian distance between 2 tuples behind which 2 tuples are considered equal.
2704  * \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.
2705  *             \a cI allows to extract information in \a c.
2706  * \param [out] cI is an indirection array that allows to extract the data contained in \a c.
2707  *
2708  * \throw In case of:
2709  *  - \a this is not allocated
2710  *  - \a other is not allocated or null
2711  *  - \a this and \a other do not have the same number of components
2712  *  - if number of components of \a this is not in [1,2,3]
2713  *
2714  * \sa MEDCouplingPointSet::getNodeIdsNearPoints, DataArrayDouble::getDifferentValues
2715  */
2716 void DataArrayDouble::computeTupleIdsNearTuples(const DataArrayDouble *other, double eps, DataArrayInt *& c, DataArrayInt *& cI) const throw(INTERP_KERNEL::Exception)
2717 {
2718   if(!other)
2719     throw INTERP_KERNEL::Exception("DataArrayDouble::computeTupleIdsNearTuples : input pointer other is null !");
2720   checkAllocated();
2721   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> bbox=computeBBoxPerTuple(eps);
2722   other->checkAllocated();
2723   int nbOfCompo=getNumberOfComponents();
2724   int otherNbOfCompo=other->getNumberOfComponents();
2725   if(nbOfCompo!=otherNbOfCompo)
2726     throw INTERP_KERNEL::Exception("DataArrayDouble::computeTupleIdsNearTuples : number of components should be equal between this and other !");
2727   int nbOfTuplesOther=other->getNumberOfTuples();
2728   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cArr(DataArrayInt::New()),cIArr(DataArrayInt::New()); cArr->alloc(0,1); cIArr->pushBackSilent(0);
2729   switch(nbOfCompo)
2730     {
2731     case 3:
2732       {
2733         BBTree<3,int> myTree(bbox->getConstPointer(),0,0,getNumberOfTuples(),eps/10);
2734         FindTupleIdsNearTuplesAlg<3>(myTree,other->getConstPointer(),nbOfTuplesOther,eps,cArr,cIArr);
2735         break;
2736       }
2737     case 2:
2738       {
2739         BBTree<2,int> myTree(bbox->getConstPointer(),0,0,getNumberOfTuples(),eps/10);
2740         FindTupleIdsNearTuplesAlg<2>(myTree,other->getConstPointer(),nbOfTuplesOther,eps,cArr,cIArr);
2741         break;
2742       }
2743     case 1:
2744       {
2745         BBTree<1,int> myTree(bbox->getConstPointer(),0,0,getNumberOfTuples(),eps/10);
2746         FindTupleIdsNearTuplesAlg<1>(myTree,other->getConstPointer(),nbOfTuplesOther,eps,cArr,cIArr);
2747         break;
2748       }
2749     default:
2750       throw INTERP_KERNEL::Exception("Unexpected spacedim of coords for computeTupleIdsNearTuples. Must be 1, 2 or 3.");
2751     }
2752   c=cArr.retn(); cI=cIArr.retn();
2753 }
2754
2755 /*!
2756  * 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
2757  * around origin of 'radius' 1.
2758  * 
2759  * \param [in] eps absolute epsilon. under that value of delta between max and min no scale is performed.
2760  */
2761 void DataArrayDouble::recenterForMaxPrecision(double eps) throw(INTERP_KERNEL::Exception)
2762 {
2763   checkAllocated();
2764   int dim=getNumberOfComponents();
2765   std::vector<double> bounds(2*dim);
2766   getMinMaxPerComponent(&bounds[0]);
2767   for(int i=0;i<dim;i++)
2768     {
2769       double delta=bounds[2*i+1]-bounds[2*i];
2770       double offset=(bounds[2*i]+bounds[2*i+1])/2.;
2771       if(delta>eps)
2772         applyLin(1./delta,-offset/delta,i);
2773       else
2774         applyLin(1.,-offset,i);
2775     }
2776 }
2777
2778 /*!
2779  * Returns the maximal value and its location within \a this one-dimensional array.
2780  *  \param [out] tupleId - index of the tuple holding the maximal value.
2781  *  \return double - the maximal value among all values of \a this array.
2782  *  \throw If \a this->getNumberOfComponents() != 1
2783  *  \throw If \a this->getNumberOfTuples() < 1
2784  */
2785 double DataArrayDouble::getMaxValue(int& tupleId) const throw(INTERP_KERNEL::Exception)
2786 {
2787   checkAllocated();
2788   if(getNumberOfComponents()!=1)
2789     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 !");
2790   int nbOfTuples=getNumberOfTuples();
2791   if(nbOfTuples<=0)
2792     throw INTERP_KERNEL::Exception("DataArrayDouble::getMaxValue : array exists but number of tuples must be > 0 !");
2793   const double *vals=getConstPointer();
2794   const double *loc=std::max_element(vals,vals+nbOfTuples);
2795   tupleId=(int)std::distance(vals,loc);
2796   return *loc;
2797 }
2798
2799 /*!
2800  * Returns the maximal value within \a this array that is allowed to have more than
2801  *  one component.
2802  *  \return double - the maximal value among all values of \a this array.
2803  *  \throw If \a this is not allocated.
2804  */
2805 double DataArrayDouble::getMaxValueInArray() const throw(INTERP_KERNEL::Exception)
2806 {
2807   checkAllocated();
2808   const double *loc=std::max_element(begin(),end());
2809   return *loc;
2810 }
2811
2812 /*!
2813  * Returns the maximal value and all its locations within \a this one-dimensional array.
2814  *  \param [out] tupleIds - a new instance of DataArrayInt containg indices of
2815  *               tuples holding the maximal value. The caller is to delete it using
2816  *               decrRef() as it is no more needed.
2817  *  \return double - the maximal value among all values of \a this array.
2818  *  \throw If \a this->getNumberOfComponents() != 1
2819  *  \throw If \a this->getNumberOfTuples() < 1
2820  */
2821 double DataArrayDouble::getMaxValue2(DataArrayInt*& tupleIds) const throw(INTERP_KERNEL::Exception)
2822 {
2823   int tmp;
2824   tupleIds=0;
2825   double ret=getMaxValue(tmp);
2826   tupleIds=getIdsInRange(ret,ret);
2827   return ret;
2828 }
2829
2830 /*!
2831  * Returns the minimal value and its location within \a this one-dimensional array.
2832  *  \param [out] tupleId - index of the tuple holding the minimal value.
2833  *  \return double - the minimal value among all values of \a this array.
2834  *  \throw If \a this->getNumberOfComponents() != 1
2835  *  \throw If \a this->getNumberOfTuples() < 1
2836  */
2837 double DataArrayDouble::getMinValue(int& tupleId) const throw(INTERP_KERNEL::Exception)
2838 {
2839   checkAllocated();
2840   if(getNumberOfComponents()!=1)
2841     throw INTERP_KERNEL::Exception("DataArrayDouble::getMinValue : must be applied on DataArrayDouble with only one component, you can call 'rearrange' method before call 'getMinValueInArray' method !");
2842   int nbOfTuples=getNumberOfTuples();
2843   if(nbOfTuples<=0)
2844     throw INTERP_KERNEL::Exception("DataArrayDouble::getMinValue : array exists but number of tuples must be > 0 !");
2845   const double *vals=getConstPointer();
2846   const double *loc=std::min_element(vals,vals+nbOfTuples);
2847   tupleId=(int)std::distance(vals,loc);
2848   return *loc;
2849 }
2850
2851 /*!
2852  * Returns the minimal value within \a this array that is allowed to have more than
2853  *  one component.
2854  *  \return double - the minimal value among all values of \a this array.
2855  *  \throw If \a this is not allocated.
2856  */
2857 double DataArrayDouble::getMinValueInArray() const throw(INTERP_KERNEL::Exception)
2858 {
2859   checkAllocated();
2860   const double *loc=std::min_element(begin(),end());
2861   return *loc;
2862 }
2863
2864 /*!
2865  * Returns the minimal value and all its locations within \a this one-dimensional array.
2866  *  \param [out] tupleIds - a new instance of DataArrayInt containg indices of
2867  *               tuples holding the minimal value. The caller is to delete it using
2868  *               decrRef() as it is no more needed.
2869  *  \return double - the minimal value among all values of \a this array.
2870  *  \throw If \a this->getNumberOfComponents() != 1
2871  *  \throw If \a this->getNumberOfTuples() < 1
2872  */
2873 double DataArrayDouble::getMinValue2(DataArrayInt*& tupleIds) const throw(INTERP_KERNEL::Exception)
2874 {
2875   int tmp;
2876   tupleIds=0;
2877   double ret=getMinValue(tmp);
2878   tupleIds=getIdsInRange(ret,ret);
2879   return ret;
2880 }
2881
2882 /*!
2883  * Returns the average value of \a this one-dimensional array.
2884  *  \return double - the average value over all values of \a this array.
2885  *  \throw If \a this->getNumberOfComponents() != 1
2886  *  \throw If \a this->getNumberOfTuples() < 1
2887  */
2888 double DataArrayDouble::getAverageValue() const throw(INTERP_KERNEL::Exception)
2889 {
2890   if(getNumberOfComponents()!=1)
2891     throw INTERP_KERNEL::Exception("DataArrayDouble::getAverageValue : must be applied on DataArrayDouble with only one component, you can call 'rearrange' method before !");
2892   int nbOfTuples=getNumberOfTuples();
2893   if(nbOfTuples<=0)
2894     throw INTERP_KERNEL::Exception("DataArrayDouble::getAverageValue : array exists but number of tuples must be > 0 !");
2895   const double *vals=getConstPointer();
2896   double ret=std::accumulate(vals,vals+nbOfTuples,0.);
2897   return ret/nbOfTuples;
2898 }
2899
2900 /*!
2901  * Returns the Euclidean norm of the vector defined by \a this array.
2902  *  \return double - the value of the Euclidean norm, i.e.
2903  *          the square root of the inner product of vector.
2904  *  \throw If \a this is not allocated.
2905  */
2906 double DataArrayDouble::norm2() const throw(INTERP_KERNEL::Exception)
2907 {
2908   checkAllocated();
2909   double ret=0.;
2910   int nbOfElems=getNbOfElems();
2911   const double *pt=getConstPointer();
2912   for(int i=0;i<nbOfElems;i++,pt++)
2913     ret+=(*pt)*(*pt);
2914   return sqrt(ret);
2915 }
2916
2917 /*!
2918  * Returns the maximum norm of the vector defined by \a this array.
2919  *  \return double - the value of the maximum norm, i.e.
2920  *          the maximal absolute value among values of \a this array.
2921  *  \throw If \a this is not allocated.
2922  */
2923 double DataArrayDouble::normMax() const throw(INTERP_KERNEL::Exception)
2924 {
2925   checkAllocated();
2926   double ret=-1.;
2927   int nbOfElems=getNbOfElems();
2928   const double *pt=getConstPointer();
2929   for(int i=0;i<nbOfElems;i++,pt++)
2930     {
2931       double val=std::abs(*pt);
2932       if(val>ret)
2933         ret=val;
2934     }
2935   return ret;
2936 }
2937
2938 /*!
2939  * Accumulates values of each component of \a this array.
2940  *  \param [out] res - an array of length \a this->getNumberOfComponents(), allocated 
2941  *         by the caller, that is filled by this method with sum value for each
2942  *         component.
2943  *  \throw If \a this is not allocated.
2944  */
2945 void DataArrayDouble::accumulate(double *res) const throw(INTERP_KERNEL::Exception)
2946 {
2947   checkAllocated();
2948   const double *ptr=getConstPointer();
2949   int nbTuple=getNumberOfTuples();
2950   int nbComps=getNumberOfComponents();
2951   std::fill(res,res+nbComps,0.);
2952   for(int i=0;i<nbTuple;i++)
2953     std::transform(ptr+i*nbComps,ptr+(i+1)*nbComps,res,res,std::plus<double>());
2954 }
2955
2956 /*!
2957  * This method returns the min distance from an external tuple defined by [ \a tupleBg , \a tupleEnd ) to \a this and
2958  * the first tuple in \a this that matches the returned distance. If there is no tuples in \a this an exception will be thrown.
2959  *
2960  *
2961  * \a this is expected to be allocated and expected to have a number of components equal to the distance from \a tupleBg to
2962  * \a tupleEnd. If not an exception will be thrown.
2963  *
2964  * \param [in] tupleBg start pointer (included) of input external tuple
2965  * \param [in] tupleEnd end pointer (not included) of input external tuple
2966  * \param [out] tupleId the tuple id in \a this that matches the min of distance between \a this and input external tuple
2967  * \return the min distance.
2968  * \sa MEDCouplingUMesh::distanceToPoint
2969  */
2970 double DataArrayDouble::distanceToTuple(const double *tupleBg, const double *tupleEnd, int& tupleId) const throw(INTERP_KERNEL::Exception)
2971 {
2972   checkAllocated();
2973   int nbTuple=getNumberOfTuples();
2974   int nbComps=getNumberOfComponents();
2975   if(nbComps!=(int)std::distance(tupleBg,tupleEnd))
2976     { 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()); }
2977   if(nbTuple==0)
2978     throw INTERP_KERNEL::Exception("DataArrayDouble::distanceToTuple : no tuple in this ! No distance to compute !");
2979   double ret0=std::numeric_limits<double>::max();
2980   tupleId=-1;
2981   const double *work=getConstPointer();
2982   for(int i=0;i<nbTuple;i++)
2983     {
2984       double val=0.;
2985       for(int j=0;j<nbComps;j++,work++) 
2986         val+=(*work-tupleBg[j])*((*work-tupleBg[j]));
2987       if(val>=ret0)
2988         continue;
2989       else
2990         { ret0=val; tupleId=i; }
2991     }
2992   return sqrt(ret0);
2993 }
2994
2995 /*!
2996  * Accumulate values of the given component of \a this array.
2997  *  \param [in] compId - the index of the component of interest.
2998  *  \return double - a sum value of \a compId-th component.
2999  *  \throw If \a this is not allocated.
3000  *  \throw If \a the condition ( 0 <= \a compId < \a this->getNumberOfComponents() ) is
3001  *         not respected.
3002  */
3003 double DataArrayDouble::accumulate(int compId) const throw(INTERP_KERNEL::Exception)
3004 {
3005   checkAllocated();
3006   const double *ptr=getConstPointer();
3007   int nbTuple=getNumberOfTuples();
3008   int nbComps=getNumberOfComponents();
3009   if(compId<0 || compId>=nbComps)
3010     throw INTERP_KERNEL::Exception("DataArrayDouble::accumulate : Invalid compId specified : No such nb of components !");
3011   double ret=0.;
3012   for(int i=0;i<nbTuple;i++)
3013     ret+=ptr[i*nbComps+compId];
3014   return ret;
3015 }
3016
3017 /*!
3018  * Converts each 2D point defined by the tuple of \a this array from the Polar to the
3019  * Cartesian coordinate system. The two components of the tuple of \a this array are 
3020  * considered to contain (1) radius and (2) angle of the point in the Polar CS.
3021  *  \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
3022  *          contains X and Y coordinates of the point in the Cartesian CS. The caller
3023  *          is to delete this array using decrRef() as it is no more needed. The array
3024  *          does not contain any textual info on components.
3025  *  \throw If \a this->getNumberOfComponents() != 2.
3026  */
3027 DataArrayDouble *DataArrayDouble::fromPolarToCart() const throw(INTERP_KERNEL::Exception)
3028 {
3029   checkAllocated();
3030   int nbOfComp=getNumberOfComponents();
3031   if(nbOfComp!=2)
3032     throw INTERP_KERNEL::Exception("DataArrayDouble::fromPolarToCart : must be an array with exactly 2 components !");
3033   int nbOfTuple=getNumberOfTuples();
3034   DataArrayDouble *ret=DataArrayDouble::New();
3035   ret->alloc(nbOfTuple,2);
3036   double *w=ret->getPointer();
3037   const double *wIn=getConstPointer();
3038   for(int i=0;i<nbOfTuple;i++,w+=2,wIn+=2)
3039     {
3040       w[0]=wIn[0]*cos(wIn[1]);
3041       w[1]=wIn[0]*sin(wIn[1]);
3042     }
3043   return ret;
3044 }
3045
3046 /*!
3047  * Converts each 3D point defined by the tuple of \a this array from the Cylindrical to
3048  * the Cartesian coordinate system. The three components of the tuple of \a this array 
3049  * are considered to contain (1) radius, (2) azimuth and (3) altitude of the point in
3050  * the Cylindrical CS.
3051  *  \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
3052  *          contains X, Y and Z coordinates of the point in the Cartesian CS. The info
3053  *          on the third component is copied from \a this array. The caller
3054  *          is to delete this array using decrRef() as it is no more needed. 
3055  *  \throw If \a this->getNumberOfComponents() != 3.
3056  */
3057 DataArrayDouble *DataArrayDouble::fromCylToCart() const throw(INTERP_KERNEL::Exception)
3058 {
3059   checkAllocated();
3060   int nbOfComp=getNumberOfComponents();
3061   if(nbOfComp!=3)
3062     throw INTERP_KERNEL::Exception("DataArrayDouble::fromCylToCart : must be an array with exactly 3 components !");
3063   int nbOfTuple=getNumberOfTuples();
3064   DataArrayDouble *ret=DataArrayDouble::New();
3065   ret->alloc(getNumberOfTuples(),3);
3066   double *w=ret->getPointer();
3067   const double *wIn=getConstPointer();
3068   for(int i=0;i<nbOfTuple;i++,w+=3,wIn+=3)
3069     {
3070       w[0]=wIn[0]*cos(wIn[1]);
3071       w[1]=wIn[0]*sin(wIn[1]);
3072       w[2]=wIn[2];
3073     }
3074   ret->setInfoOnComponent(2,getInfoOnComponent(2).c_str());
3075   return ret;
3076 }
3077
3078 /*!
3079  * Converts each 3D point defined by the tuple of \a this array from the Spherical to
3080  * the Cartesian coordinate system. The three components of the tuple of \a this array 
3081  * are considered to contain (1) radius, (2) polar angle and (3) azimuthal angle of the
3082  * point in the Cylindrical CS.
3083  *  \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
3084  *          contains X, Y and Z coordinates of the point in the Cartesian CS. The info
3085  *          on the third component is copied from \a this array. The caller
3086  *          is to delete this array using decrRef() as it is no more needed.
3087  *  \throw If \a this->getNumberOfComponents() != 3.
3088  */
3089 DataArrayDouble *DataArrayDouble::fromSpherToCart() const throw(INTERP_KERNEL::Exception)
3090 {
3091   checkAllocated();
3092   int nbOfComp=getNumberOfComponents();
3093   if(nbOfComp!=3)
3094     throw INTERP_KERNEL::Exception("DataArrayDouble::fromSpherToCart : must be an array with exactly 3 components !");
3095   int nbOfTuple=getNumberOfTuples();
3096   DataArrayDouble *ret=DataArrayDouble::New();
3097   ret->alloc(getNumberOfTuples(),3);
3098   double *w=ret->getPointer();
3099   const double *wIn=getConstPointer();
3100   for(int i=0;i<nbOfTuple;i++,w+=3,wIn+=3)
3101     {
3102       w[0]=wIn[0]*cos(wIn[2])*sin(wIn[1]);
3103       w[1]=wIn[0]*sin(wIn[2])*sin(wIn[1]);
3104       w[2]=wIn[0]*cos(wIn[1]);
3105     }
3106   return ret;
3107 }
3108
3109 /*!
3110  * Computes the doubly contracted product of every tensor defined by the tuple of \a this
3111  * array contating 6 components.
3112  *  \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
3113  *          is calculated from the tuple <em>(t)</em> of \a this array as follows:
3114  *          \f$ t[0]^2+t[1]^2+t[2]^2+2*t[3]^2+2*t[4]^2+2*t[5]^2\f$.
3115  *         The caller is to delete this result array using decrRef() as it is no more needed. 
3116  *  \throw If \a this->getNumberOfComponents() != 6.
3117  */
3118 DataArrayDouble *DataArrayDouble::doublyContractedProduct() const throw(INTERP_KERNEL::Exception)
3119 {
3120   checkAllocated();
3121   int nbOfComp=getNumberOfComponents();
3122   if(nbOfComp!=6)
3123     throw INTERP_KERNEL::Exception("DataArrayDouble::doublyContractedProduct : must be an array with exactly 6 components !");
3124   DataArrayDouble *ret=DataArrayDouble::New();
3125   int nbOfTuple=getNumberOfTuples();
3126   ret->alloc(nbOfTuple,1);
3127   const double *src=getConstPointer();
3128   double *dest=ret->getPointer();
3129   for(int i=0;i<nbOfTuple;i++,dest++,src+=6)
3130     *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];
3131   return ret;
3132 }
3133
3134 /*!
3135  * Computes the determinant of every square matrix defined by the tuple of \a this
3136  * array, which contains either 4, 6 or 9 components. The case of 6 components
3137  * corresponds to that of the upper triangular matrix.
3138  *  \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
3139  *          is the determinant of matrix of the corresponding tuple of \a this array.
3140  *          The caller is to delete this result array using decrRef() as it is no more
3141  *          needed. 
3142  *  \throw If \a this->getNumberOfComponents() is not in [4,6,9].
3143  */
3144 DataArrayDouble *DataArrayDouble::determinant() const throw(INTERP_KERNEL::Exception)
3145 {
3146   checkAllocated();
3147   DataArrayDouble *ret=DataArrayDouble::New();
3148   int nbOfTuple=getNumberOfTuples();
3149   ret->alloc(nbOfTuple,1);
3150   const double *src=getConstPointer();
3151   double *dest=ret->getPointer();
3152   switch(getNumberOfComponents())
3153     {
3154     case 6:
3155       for(int i=0;i<nbOfTuple;i++,dest++,src+=6)
3156         *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];
3157       return ret;
3158     case 4:
3159       for(int i=0;i<nbOfTuple;i++,dest++,src+=4)
3160         *dest=src[0]*src[3]-src[1]*src[2];
3161       return ret;
3162     case 9:
3163       for(int i=0;i<nbOfTuple;i++,dest++,src+=9)
3164         *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];
3165       return ret;
3166     default:
3167       ret->decrRef();
3168       throw INTERP_KERNEL::Exception("DataArrayDouble::determinant : Invalid number of components ! must be in 4,6,9 !");
3169     }
3170 }
3171
3172 /*!
3173  * Computes 3 eigenvalues of every upper triangular matrix defined by the tuple of
3174  * \a this array, which contains 6 components.
3175  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing 3
3176  *          components, whose each tuple contains the eigenvalues of the matrix of
3177  *          corresponding tuple of \a this array. 
3178  *          The caller is to delete this result array using decrRef() as it is no more
3179  *          needed. 
3180  *  \throw If \a this->getNumberOfComponents() != 6.
3181  */
3182 DataArrayDouble *DataArrayDouble::eigenValues() const throw(INTERP_KERNEL::Exception)
3183 {
3184   checkAllocated();
3185   int nbOfComp=getNumberOfComponents();
3186   if(nbOfComp!=6)
3187     throw INTERP_KERNEL::Exception("DataArrayDouble::eigenValues : must be an array with exactly 6 components !");
3188   DataArrayDouble *ret=DataArrayDouble::New();
3189   int nbOfTuple=getNumberOfTuples();
3190   ret->alloc(nbOfTuple,3);
3191   const double *src=getConstPointer();
3192   double *dest=ret->getPointer();
3193   for(int i=0;i<nbOfTuple;i++,dest+=3,src+=6)
3194     INTERP_KERNEL::computeEigenValues6(src,dest);
3195   return ret;
3196 }
3197
3198 /*!
3199  * Computes 3 eigenvectors of every upper triangular matrix defined by the tuple of
3200  * \a this array, which contains 6 components.
3201  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing 9
3202  *          components, whose each tuple contains 3 eigenvectors of the matrix of
3203  *          corresponding tuple of \a this array.
3204  *          The caller is to delete this result array using decrRef() as it is no more
3205  *          needed.
3206  *  \throw If \a this->getNumberOfComponents() != 6.
3207  */
3208 DataArrayDouble *DataArrayDouble::eigenVectors() const throw(INTERP_KERNEL::Exception)
3209 {
3210   checkAllocated();
3211   int nbOfComp=getNumberOfComponents();
3212   if(nbOfComp!=6)
3213     throw INTERP_KERNEL::Exception("DataArrayDouble::eigenVectors : must be an array with exactly 6 components !");
3214   DataArrayDouble *ret=DataArrayDouble::New();
3215   int nbOfTuple=getNumberOfTuples();
3216   ret->alloc(nbOfTuple,9);
3217   const double *src=getConstPointer();
3218   double *dest=ret->getPointer();
3219   for(int i=0;i<nbOfTuple;i++,src+=6)
3220     {
3221       double tmp[3];
3222       INTERP_KERNEL::computeEigenValues6(src,tmp);
3223       for(int j=0;j<3;j++,dest+=3)
3224         INTERP_KERNEL::computeEigenVectorForEigenValue6(src,tmp[j],1e-12,dest);
3225     }
3226   return ret;
3227 }
3228
3229 /*!
3230  * Computes the inverse matrix of every matrix defined by the tuple of \a this
3231  * array, which contains either 4, 6 or 9 components. The case of 6 components
3232  * corresponds to that of the upper triangular matrix.
3233  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
3234  *          same number of components as \a this one, whose each tuple is the inverse
3235  *          matrix of the matrix of corresponding tuple of \a this array. 
3236  *          The caller is to delete this result array using decrRef() as it is no more
3237  *          needed. 
3238  *  \throw If \a this->getNumberOfComponents() is not in [4,6,9].
3239  */
3240 DataArrayDouble *DataArrayDouble::inverse() const throw(INTERP_KERNEL::Exception)
3241 {
3242   checkAllocated();
3243   int nbOfComp=getNumberOfComponents();
3244   if(nbOfComp!=6 && nbOfComp!=9 && nbOfComp!=4)
3245     throw INTERP_KERNEL::Exception("DataArrayDouble::inversion : must be an array with 4,6 or 9 components !");
3246   DataArrayDouble *ret=DataArrayDouble::New();
3247   int nbOfTuple=getNumberOfTuples();
3248   ret->alloc(nbOfTuple,nbOfComp);
3249   const double *src=getConstPointer();
3250   double *dest=ret->getPointer();
3251 if(nbOfComp==6)
3252     for(int i=0;i<nbOfTuple;i++,dest+=6,src+=6)
3253       {
3254         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];
3255         dest[0]=(src[1]*src[2]-src[4]*src[4])/det;
3256         dest[1]=(src[0]*src[2]-src[5]*src[5])/det;
3257         dest[2]=(src[0]*src[1]-src[3]*src[3])/det;
3258         dest[3]=(src[5]*src[4]-src[3]*src[2])/det;
3259         dest[4]=(src[5]*src[3]-src[0]*src[4])/det;
3260         dest[5]=(src[3]*src[4]-src[1]*src[5])/det;
3261       }
3262   else if(nbOfComp==4)
3263     for(int i=0;i<nbOfTuple;i++,dest+=4,src+=4)
3264       {
3265         double det=src[0]*src[3]-src[1]*src[2];
3266         dest[0]=src[3]/det;
3267         dest[1]=-src[1]/det;
3268         dest[2]=-src[2]/det;
3269         dest[3]=src[0]/det;
3270       }
3271   else
3272     for(int i=0;i<nbOfTuple;i++,dest+=9,src+=9)
3273       {
3274         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];
3275         dest[0]=(src[4]*src[8]-src[7]*src[5])/det;
3276         dest[1]=(src[7]*src[2]-src[1]*src[8])/det;
3277         dest[2]=(src[1]*src[5]-src[4]*src[2])/det;
3278         dest[3]=(src[6]*src[5]-src[3]*src[8])/det;
3279         dest[4]=(src[0]*src[8]-src[6]*src[2])/det;
3280         dest[5]=(src[2]*src[3]-src[0]*src[5])/det;
3281         dest[6]=(src[3]*src[7]-src[6]*src[4])/det;
3282         dest[7]=(src[6]*src[1]-src[0]*src[7])/det;
3283         dest[8]=(src[0]*src[4]-src[1]*src[3])/det;
3284       }
3285   return ret;
3286 }
3287
3288 /*!
3289  * Computes the trace of every matrix defined by the tuple of \a this
3290  * array, which contains either 4, 6 or 9 components. The case of 6 components
3291  * corresponds to that of the upper triangular matrix.
3292  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing 
3293  *          1 component, whose each tuple is the trace of
3294  *          the matrix of corresponding tuple of \a this array. 
3295  *          The caller is to delete this result array using decrRef() as it is no more
3296  *          needed. 
3297  *  \throw If \a this->getNumberOfComponents() is not in [4,6,9].
3298  */
3299 DataArrayDouble *DataArrayDouble::trace() const throw(INTERP_KERNEL::Exception)
3300 {
3301   checkAllocated();
3302   int nbOfComp=getNumberOfComponents();
3303   if(nbOfComp!=6 && nbOfComp!=9 && nbOfComp!=4)
3304     throw INTERP_KERNEL::Exception("DataArrayDouble::trace : must be an array with 4,6 or 9 components !");
3305   DataArrayDouble *ret=DataArrayDouble::New();
3306   int nbOfTuple=getNumberOfTuples();
3307   ret->alloc(nbOfTuple,1);
3308   const double *src=getConstPointer();
3309   double *dest=ret->getPointer();
3310   if(nbOfComp==6)
3311     for(int i=0;i<nbOfTuple;i++,dest++,src+=6)
3312       *dest=src[0]+src[1]+src[2];
3313   else if(nbOfComp==4)
3314     for(int i=0;i<nbOfTuple;i++,dest++,src+=4)
3315       *dest=src[0]+src[3];
3316   else
3317     for(int i=0;i<nbOfTuple;i++,dest++,src+=9)
3318       *dest=src[0]+src[4]+src[8];
3319   return ret;
3320 }
3321
3322 /*!
3323  * Computes the stress deviator tensor of every stress tensor defined by the tuple of
3324  * \a this array, which contains 6 components.
3325  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
3326  *          same number of components and tuples as \a this array.
3327  *          The caller is to delete this result array using decrRef() as it is no more
3328  *          needed.
3329  *  \throw If \a this->getNumberOfComponents() != 6.
3330  */
3331 DataArrayDouble *DataArrayDouble::deviator() const throw(INTERP_KERNEL::Exception)
3332 {
3333   checkAllocated();
3334   int nbOfComp=getNumberOfComponents();
3335   if(nbOfComp!=6)
3336     throw INTERP_KERNEL::Exception("DataArrayDouble::deviator : must be an array with exactly 6 components !");
3337   DataArrayDouble *ret=DataArrayDouble::New();
3338   int nbOfTuple=getNumberOfTuples();
3339   ret->alloc(nbOfTuple,6);
3340   const double *src=getConstPointer();
3341   double *dest=ret->getPointer();
3342   for(int i=0;i<nbOfTuple;i++,dest+=6,src+=6)
3343     {
3344       double tr=(src[0]+src[1]+src[2])/3.;
3345       dest[0]=src[0]-tr;
3346       dest[1]=src[1]-tr;
3347       dest[2]=src[2]-tr;
3348       dest[3]=src[3];
3349       dest[4]=src[4];
3350       dest[5]=src[5];
3351     }
3352   return ret;
3353 }
3354
3355 /*!
3356  * Computes the magnitude of every vector defined by the tuple of
3357  * \a this array.
3358  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
3359  *          same number of tuples as \a this array and one component.
3360  *          The caller is to delete this result array using decrRef() as it is no more
3361  *          needed.
3362  *  \throw If \a this is not allocated.
3363  */
3364 DataArrayDouble *DataArrayDouble::magnitude() const throw(INTERP_KERNEL::Exception)
3365 {
3366   checkAllocated();
3367   int nbOfComp=getNumberOfComponents();
3368   DataArrayDouble *ret=DataArrayDouble::New();
3369   int nbOfTuple=getNumberOfTuples();
3370   ret->alloc(nbOfTuple,1);
3371   const double *src=getConstPointer();
3372   double *dest=ret->getPointer();
3373   for(int i=0;i<nbOfTuple;i++,dest++)
3374     {
3375       double sum=0.;
3376       for(int j=0;j<nbOfComp;j++,src++)
3377         sum+=(*src)*(*src);
3378       *dest=sqrt(sum);
3379     }
3380   return ret;
3381 }
3382
3383 /*!
3384  * Computes the maximal value within every tuple of \a this array.
3385  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
3386  *          same number of tuples as \a this array and one component.
3387  *          The caller is to delete this result array using decrRef() as it is no more
3388  *          needed.
3389  *  \throw If \a this is not allocated.
3390  */
3391 DataArrayDouble *DataArrayDouble::maxPerTuple() const throw(INTERP_KERNEL::Exception)
3392 {
3393   checkAllocated();
3394   int nbOfComp=getNumberOfComponents();
3395   DataArrayDouble *ret=DataArrayDouble::New();
3396   int nbOfTuple=getNumberOfTuples();
3397   ret->alloc(nbOfTuple,1);
3398   const double *src=getConstPointer();
3399   double *dest=ret->getPointer();
3400   for(int i=0;i<nbOfTuple;i++,dest++,src+=nbOfComp)
3401     *dest=*std::max_element(src,src+nbOfComp);
3402   return ret;
3403 }
3404
3405 /*!
3406  * This method returns a newly allocated DataArrayDouble instance having one component and \c this->getNumberOfTuples() * \c this->getNumberOfTuples() tuples.
3407  * \n This returned array contains the euclidian distance for each tuple in \a this. 
3408  * \n So the returned array can be seen as a dense symmetrical matrix whose diagonal elements are equal to 0.
3409  * \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)
3410  *
3411  * \warning use this method with care because it can leads to big amount of consumed memory !
3412  * 
3413  * \return A newly allocated (huge) ParaMEDMEM::DataArrayDouble instance that the caller should deal with.
3414  *
3415  * \throw If \a this is not allocated.
3416  *
3417  * \sa DataArrayDouble::buildEuclidianDistanceDenseMatrixWith
3418  */
3419 DataArrayDouble *DataArrayDouble::buildEuclidianDistanceDenseMatrix() const throw(INTERP_KERNEL::Exception)
3420 {
3421   checkAllocated();
3422   int nbOfComp=getNumberOfComponents();
3423   int nbOfTuples=getNumberOfTuples();
3424   const double *inData=getConstPointer();
3425   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
3426   ret->alloc(nbOfTuples*nbOfTuples,1);
3427   double *outData=ret->getPointer();
3428   for(int i=0;i<nbOfTuples;i++)
3429     {
3430       outData[i*nbOfTuples+i]=0.;
3431       for(int j=i+1;j<nbOfTuples;j++)
3432         {
3433           double dist=0.;
3434           for(int k=0;k<nbOfComp;k++)
3435             { double delta=inData[i*nbOfComp+k]-inData[j*nbOfComp+k]; dist+=delta*delta; }
3436           dist=sqrt(dist);
3437           outData[i*nbOfTuples+j]=dist;
3438           outData[j*nbOfTuples+i]=dist;
3439         }
3440     }
3441   return ret.retn();
3442 }
3443
3444 /*!
3445  * This method returns a newly allocated DataArrayDouble instance having one component and \c this->getNumberOfTuples() * \c other->getNumberOfTuples() tuples.
3446  * \n This returned array contains the euclidian distance for each tuple in \a other with each tuple in \a this. 
3447  * \n So the returned array can be seen as a dense rectangular matrix with \c other->getNumberOfTuples() rows and \c this->getNumberOfTuples() columns.
3448  * \n Output rectangular matrix is sorted along rows.
3449  * \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)
3450  *
3451  * \warning use this method with care because it can leads to big amount of consumed memory !
3452  * 
3453  * \param [in] other DataArrayDouble instance having same number of components than \a this.
3454  * \return A newly allocated (huge) ParaMEDMEM::DataArrayDouble instance that the caller should deal with.
3455  *
3456  * \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.
3457  *
3458  * \sa DataArrayDouble::buildEuclidianDistanceDenseMatrix
3459  */
3460 DataArrayDouble *DataArrayDouble::buildEuclidianDistanceDenseMatrixWith(const DataArrayDouble *other) const throw(INTERP_KERNEL::Exception)
3461 {
3462   if(!other)
3463     throw INTERP_KERNEL::Exception("DataArrayDouble::buildEuclidianDistanceDenseMatrixWith : input parameter is null !");
3464   checkAllocated();
3465   other->checkAllocated();
3466   int nbOfComp=getNumberOfComponents();
3467   int otherNbOfComp=other->getNumberOfComponents();
3468   if(nbOfComp!=otherNbOfComp)
3469     {
3470       std::ostringstream oss; oss << "DataArrayDouble::buildEuclidianDistanceDenseMatrixWith : this nb of compo=" << nbOfComp << " and other nb of compo=" << otherNbOfComp << ". It should match !";
3471       throw INTERP_KERNEL::Exception(oss.str().c_str());
3472     }
3473   int nbOfTuples=getNumberOfTuples();
3474   int otherNbOfTuples=other->getNumberOfTuples();
3475   const double *inData=getConstPointer();
3476   const double *inDataOther=other->getConstPointer();
3477   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
3478   ret->alloc(otherNbOfTuples*nbOfTuples,1);
3479   double *outData=ret->getPointer();
3480   for(int i=0;i<otherNbOfTuples;i++,inDataOther+=nbOfComp)
3481     {
3482       for(int j=0;j<nbOfTuples;j++)
3483         {
3484           double dist=0.;
3485           for(int k=0;k<nbOfComp;k++)
3486             { double delta=inDataOther[k]-inData[j*nbOfComp+k]; dist+=delta*delta; }
3487           dist=sqrt(dist);
3488           outData[i*nbOfTuples+j]=dist;
3489         }
3490     }
3491   return ret.retn();
3492 }
3493
3494 /*!
3495  * Sorts value within every tuple of \a this array.
3496  *  \param [in] asc - if \a true, the values are sorted in ascending order, else,
3497  *              in descending order.
3498  *  \throw If \a this is not allocated.
3499  */
3500 void DataArrayDouble::sortPerTuple(bool asc) throw(INTERP_KERNEL::Exception)
3501 {
3502   checkAllocated();
3503   double *pt=getPointer();
3504   int nbOfTuple=getNumberOfTuples();
3505   int nbOfComp=getNumberOfComponents();
3506   if(asc)
3507     for(int i=0;i<nbOfTuple;i++,pt+=nbOfComp)
3508       std::sort(pt,pt+nbOfComp);
3509   else
3510     for(int i=0;i<nbOfTuple;i++,pt+=nbOfComp)
3511       std::sort(pt,pt+nbOfComp,std::greater<double>());
3512   declareAsNew();
3513 }
3514
3515 /*!
3516  * Converts every value of \a this array to its absolute value.
3517  *  \throw If \a this is not allocated.
3518  */
3519 void DataArrayDouble::abs() throw(INTERP_KERNEL::Exception)
3520 {
3521   checkAllocated();
3522   double *ptr=getPointer();
3523   int nbOfElems=getNbOfElems();
3524   std::transform(ptr,ptr+nbOfElems,ptr,std::ptr_fun<double,double>(fabs));
3525   declareAsNew();
3526 }
3527
3528 /*!
3529  * Apply a liner function to a given component of \a this array, so that
3530  * an array element <em>(x)</em> becomes \f$ a * x + b \f$.
3531  *  \param [in] a - the first coefficient of the function.
3532  *  \param [in] b - the second coefficient of the function.
3533  *  \param [in] compoId - the index of component to modify.
3534  *  \throw If \a this is not allocated.
3535  */
3536 void DataArrayDouble::applyLin(double a, double b, int compoId) throw(INTERP_KERNEL::Exception)
3537 {
3538   checkAllocated();
3539   double *ptr=getPointer()+compoId;
3540   int nbOfComp=getNumberOfComponents();
3541   int nbOfTuple=getNumberOfTuples();
3542   for(int i=0;i<nbOfTuple;i++,ptr+=nbOfComp)
3543     *ptr=a*(*ptr)+b;
3544   declareAsNew();
3545 }
3546
3547 /*!
3548  * Apply a liner function to all elements of \a this array, so that
3549  * an element _x_ becomes \f$ a * x + b \f$.
3550  *  \param [in] a - the first coefficient of the function.
3551  *  \param [in] b - the second coefficient of the function.
3552  *  \throw If \a this is not allocated.
3553  */
3554 void DataArrayDouble::applyLin(double a, double b) throw(INTERP_KERNEL::Exception)
3555 {
3556   checkAllocated();
3557   double *ptr=getPointer();
3558   int nbOfElems=getNbOfElems();
3559   for(int i=0;i<nbOfElems;i++,ptr++)
3560     *ptr=a*(*ptr)+b;
3561   declareAsNew();
3562 }
3563
3564 /*!
3565  * Modify all elements of \a this array, so that
3566  * an element _x_ becomes \f$ numerator / x \f$.
3567  *  \param [in] numerator - the numerator used to modify array elements.
3568  *  \throw If \a this is not allocated.
3569  *  \throw If there is an element equal to 0.0 in \a this array.
3570  *  \warning If an exception is thrown because of presence of 0.0 element in \a this 
3571  *           array, all elements processed before detection of the zero element remain
3572  *           modified.
3573  */
3574 void DataArrayDouble::applyInv(double numerator) throw(INTERP_KERNEL::Exception)
3575 {
3576   checkAllocated();
3577   double *ptr=getPointer();
3578   int nbOfElems=getNbOfElems();
3579   for(int i=0;i<nbOfElems;i++,ptr++)
3580     {
3581       if(std::abs(*ptr)>std::numeric_limits<double>::min())
3582         {
3583           *ptr=numerator/(*ptr);
3584         }
3585       else
3586         {
3587           std::ostringstream oss; oss << "DataArrayDouble::applyInv : presence of null value in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
3588           oss << " !";
3589           throw INTERP_KERNEL::Exception(oss.str().c_str());
3590         }
3591     }
3592   declareAsNew();
3593 }
3594
3595 /*!
3596  * Returns a full copy of \a this array except that sign of all elements is reversed.
3597  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
3598  *          same number of tuples and component as \a this array.
3599  *          The caller is to delete this result array using decrRef() as it is no more
3600  *          needed.
3601  *  \throw If \a this is not allocated.
3602  */
3603 DataArrayDouble *DataArrayDouble::negate() const throw(INTERP_KERNEL::Exception)
3604 {
3605   checkAllocated();
3606   DataArrayDouble *newArr=DataArrayDouble::New();
3607   int nbOfTuples=getNumberOfTuples();
3608   int nbOfComp=getNumberOfComponents();
3609   newArr->alloc(nbOfTuples,nbOfComp);
3610   const double *cptr=getConstPointer();
3611   std::transform(cptr,cptr+nbOfTuples*nbOfComp,newArr->getPointer(),std::negate<double>());
3612   newArr->copyStringInfoFrom(*this);
3613   return newArr;
3614 }
3615
3616 /*!
3617  * Returns a new DataArrayDouble created from \a this one by applying \a
3618  * FunctionToEvaluate to every tuple of \a this array. Textual data is not copied.
3619  * For more info see \ref MEDCouplingArrayApplyFunc
3620  *  \param [in] nbOfComp - number of components in the result array.
3621  *  \param [in] func - the \a FunctionToEvaluate declared as 
3622  *              \c bool (*\a func)(\c const \c double *\a pos, \c double *\a res), 
3623  *              where \a pos points to the first component of a tuple of \a this array
3624  *              and \a res points to the first component of a tuple of the result array.
3625  *              Note that length (number of components) of \a pos can differ from
3626  *              that of \a res.
3627  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
3628  *          same number of tuples as \a this array.
3629  *          The caller is to delete this result array using decrRef() as it is no more
3630  *          needed.
3631  *  \throw If \a this is not allocated.
3632  *  \throw If \a func returns \a false.
3633  */
3634 DataArrayDouble *DataArrayDouble::applyFunc(int nbOfComp, FunctionToEvaluate func) const throw(INTERP_KERNEL::Exception)
3635 {
3636   checkAllocated();
3637   DataArrayDouble *newArr=DataArrayDouble::New();
3638   int nbOfTuples=getNumberOfTuples();
3639   int oldNbOfComp=getNumberOfComponents();
3640   newArr->alloc(nbOfTuples,nbOfComp);
3641   const double *ptr=getConstPointer();
3642   double *ptrToFill=newArr->getPointer();
3643   for(int i=0;i<nbOfTuples;i++)
3644     {
3645       if(!func(ptr+i*oldNbOfComp,ptrToFill+i*nbOfComp))
3646         {
3647           std::ostringstream oss; oss << "For tuple # " << i << " with value (";
3648           std::copy(ptr+oldNbOfComp*i,ptr+oldNbOfComp*(i+1),std::ostream_iterator<double>(oss,", "));
3649           oss << ") : Evaluation of function failed !";
3650           newArr->decrRef();
3651           throw INTERP_KERNEL::Exception(oss.str().c_str());
3652         }
3653     }
3654   return newArr;
3655 }
3656
3657 /*!
3658  * Returns a new DataArrayDouble created from \a this one by applying a function to every
3659  * tuple of \a this array. Textual data is not copied.
3660  * For more info see \ref MEDCouplingArrayApplyFunc1.
3661  *  \param [in] nbOfComp - number of components in the result array.
3662  *  \param [in] func - the expression defining how to transform a tuple of \a this array.
3663  *              Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
3664  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
3665  *          same number of tuples as \a this array and \a nbOfComp components.
3666  *          The caller is to delete this result array using decrRef() as it is no more
3667  *          needed.
3668  *  \throw If \a this is not allocated.
3669  *  \throw If computing \a func fails.
3670  */
3671 DataArrayDouble *DataArrayDouble::applyFunc(int nbOfComp, const char *func) const throw(INTERP_KERNEL::Exception)
3672 {
3673   checkAllocated();
3674   INTERP_KERNEL::ExprParser expr(func);
3675   expr.parse();
3676   std::set<std::string> vars;
3677   expr.getTrueSetOfVars(vars);
3678   int oldNbOfComp=getNumberOfComponents();
3679   if((int)vars.size()>oldNbOfComp)
3680     {
3681       std::ostringstream oss; oss << "The field has " << oldNbOfComp << " components and there are ";
3682       oss << vars.size() << " variables : ";
3683       std::copy(vars.begin(),vars.end(),std::ostream_iterator<std::string>(oss," "));
3684       throw INTERP_KERNEL::Exception(oss.str().c_str());
3685     }
3686   std::vector<std::string> varsV(vars.begin(),vars.end());
3687   expr.prepareExprEvaluation(varsV,oldNbOfComp,nbOfComp);
3688   //
3689   DataArrayDouble *newArr=DataArrayDouble::New();
3690   int nbOfTuples=getNumberOfTuples();
3691   newArr->alloc(nbOfTuples,nbOfComp);
3692   const double *ptr=getConstPointer();
3693   double *ptrToFill=newArr->getPointer();
3694   for(int i=0;i<nbOfTuples;i++)
3695     {
3696       try
3697         {
3698           expr.evaluateExpr(nbOfComp,ptr+i*oldNbOfComp,ptrToFill+i*nbOfComp);
3699         }
3700       catch(INTERP_KERNEL::Exception& e)
3701         {
3702           std::ostringstream oss; oss << "For tuple # " << i << " with value (";
3703           std::copy(ptr+oldNbOfComp*i,ptr+oldNbOfComp*(i+1),std::ostream_iterator<double>(oss,", "));
3704           oss << ") : Evaluation of function failed !" << e.what();
3705           newArr->decrRef();
3706           throw INTERP_KERNEL::Exception(oss.str().c_str());
3707         }
3708     }
3709   return newArr;
3710 }
3711
3712 /*!
3713  * Returns a new DataArrayDouble created from \a this one by applying a function to every
3714  * tuple of \a this array. Textual data is not copied.
3715  * For more info see \ref MEDCouplingArrayApplyFunc0.
3716  *  \param [in] func - the expression defining how to transform a tuple of \a this array.
3717  *              Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
3718  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
3719  *          same number of tuples and components as \a this array.
3720  *          The caller is to delete this result array using decrRef() as it is no more
3721  *          needed.
3722  *  \throw If \a this is not allocated.
3723  *  \throw If computing \a func fails.
3724  */
3725 DataArrayDouble *DataArrayDouble::applyFunc(const char *func) const throw(INTERP_KERNEL::Exception)
3726 {
3727   checkAllocated();
3728   INTERP_KERNEL::ExprParser expr(func);
3729   expr.parse();
3730   expr.prepareExprEvaluationVec();
3731   //
3732   DataArrayDouble *newArr=DataArrayDouble::New();
3733   int nbOfTuples=getNumberOfTuples();
3734   int nbOfComp=getNumberOfComponents();
3735   newArr->alloc(nbOfTuples,nbOfComp);
3736   const double *ptr=getConstPointer();
3737   double *ptrToFill=newArr->getPointer();
3738   for(int i=0;i<nbOfTuples;i++)
3739     {
3740       try
3741         {
3742           expr.evaluateExpr(nbOfComp,ptr+i*nbOfComp,ptrToFill+i*nbOfComp);
3743         }
3744       catch(INTERP_KERNEL::Exception& e)
3745         {
3746           std::ostringstream oss; oss << "For tuple # " << i << " with value (";
3747           std::copy(ptr+nbOfComp*i,ptr+nbOfComp*(i+1),std::ostream_iterator<double>(oss,", "));
3748           oss << ") : Evaluation of function failed ! " << e.what();
3749           newArr->decrRef();
3750           throw INTERP_KERNEL::Exception(oss.str().c_str());
3751         }
3752     }
3753   return newArr;
3754 }
3755
3756 /*!
3757  * Returns a new DataArrayDouble created from \a this one by applying a function to every
3758  * tuple of \a this array. Textual data is not copied.
3759  * For more info see \ref MEDCouplingArrayApplyFunc2.
3760  *  \param [in] nbOfComp - number of components in the result array.
3761  *  \param [in] func - the expression defining how to transform a tuple of \a this array.
3762  *              Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
3763  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
3764  *          same number of tuples as \a this array.
3765  *          The caller is to delete this result array using decrRef() as it is no more
3766  *          needed.
3767  *  \throw If \a this is not allocated.
3768  *  \throw If \a func contains vars that are not in \a this->getInfoOnComponent().
3769  *  \throw If computing \a func fails.
3770  */
3771 DataArrayDouble *DataArrayDouble::applyFunc2(int nbOfComp, const char *func) const throw(INTERP_KERNEL::Exception)
3772 {
3773   checkAllocated();
3774   INTERP_KERNEL::ExprParser expr(func);
3775   expr.parse();
3776   std::set<std::string> vars;
3777   expr.getTrueSetOfVars(vars);
3778   int oldNbOfComp=getNumberOfComponents();
3779   if((int)vars.size()>oldNbOfComp)
3780     {
3781       std::ostringstream oss; oss << "The field has " << oldNbOfComp << " components and there are ";
3782       oss << vars.size() << " variables : ";
3783       std::copy(vars.begin(),vars.end(),std::ostream_iterator<std::string>(oss," "));
3784       throw INTERP_KERNEL::Exception(oss.str().c_str());
3785     }
3786   expr.prepareExprEvaluation(getVarsOnComponent(),oldNbOfComp,nbOfComp);
3787   //
3788   DataArrayDouble *newArr=DataArrayDouble::New();
3789   int nbOfTuples=getNumberOfTuples();
3790   newArr->alloc(nbOfTuples,nbOfComp);
3791   const double *ptr=getConstPointer();
3792   double *ptrToFill=newArr->getPointer();
3793   for(int i=0;i<nbOfTuples;i++)
3794     {
3795       try
3796         {
3797           expr.evaluateExpr(nbOfComp,ptr+i*oldNbOfComp,ptrToFill+i*nbOfComp);
3798         }
3799       catch(INTERP_KERNEL::Exception& e)
3800         {
3801           std::ostringstream oss; oss << "For tuple # " << i << " with value (";
3802           std::copy(ptr+oldNbOfComp*i,ptr+oldNbOfComp*(i+1),std::ostream_iterator<double>(oss,", "));
3803           oss << ") : Evaluation of function failed !" << e.what();
3804           newArr->decrRef();
3805           throw INTERP_KERNEL::Exception(oss.str().c_str());
3806         }
3807     }
3808   return newArr;
3809 }
3810
3811 /*!
3812  * Returns a new DataArrayDouble created from \a this one by applying a function to every
3813  * tuple of \a this array. Textual data is not copied.
3814  * For more info see \ref MEDCouplingArrayApplyFunc3.
3815  *  \param [in] nbOfComp - number of components in the result array.
3816  *  \param [in] varsOrder - sequence of vars defining their order.
3817  *  \param [in] func - the expression defining how to transform a tuple of \a this array.
3818  *              Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
3819  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
3820  *          same number of tuples as \a this array.
3821  *          The caller is to delete this result array using decrRef() as it is no more
3822  *          needed.
3823  *  \throw If \a this is not allocated.
3824  *  \throw If \a func contains vars not in \a varsOrder.
3825  *  \throw If computing \a func fails.
3826  */
3827 DataArrayDouble *DataArrayDouble::applyFunc3(int nbOfComp, const std::vector<std::string>& varsOrder, const char *func) const throw(INTERP_KERNEL::Exception)
3828 {
3829   checkAllocated();
3830   INTERP_KERNEL::ExprParser expr(func);
3831   expr.parse();
3832   std::set<std::string> vars;
3833   expr.getTrueSetOfVars(vars);
3834   int oldNbOfComp=getNumberOfComponents();
3835   if((int)vars.size()>oldNbOfComp)
3836     {
3837       std::ostringstream oss; oss << "The field has " << oldNbOfComp << " components and there are ";
3838       oss << vars.size() << " variables : ";
3839       std::copy(vars.begin(),vars.end(),std::ostream_iterator<std::string>(oss," "));
3840       throw INTERP_KERNEL::Exception(oss.str().c_str());
3841     }
3842   expr.prepareExprEvaluation(varsOrder,oldNbOfComp,nbOfComp);
3843   //
3844   DataArrayDouble *newArr=DataArrayDouble::New();
3845   int nbOfTuples=getNumberOfTuples();
3846   newArr->alloc(nbOfTuples,nbOfComp);
3847   const double *ptr=getConstPointer();
3848   double *ptrToFill=newArr->getPointer();
3849   for(int i=0;i<nbOfTuples;i++)
3850     {
3851       try
3852         {
3853           expr.evaluateExpr(nbOfComp,ptr+i*oldNbOfComp,ptrToFill+i*nbOfComp);
3854         }
3855       catch(INTERP_KERNEL::Exception& e)
3856         {
3857           std::ostringstream oss; oss << "For tuple # " << i << " with value (";
3858           std::copy(ptr+oldNbOfComp*i,ptr+oldNbOfComp*(i+1),std::ostream_iterator<double>(oss,", "));
3859           oss << ") : Evaluation of function failed !" << e.what();
3860           newArr->decrRef();
3861           throw INTERP_KERNEL::Exception(oss.str().c_str());
3862         }
3863     }
3864   return newArr;
3865 }
3866
3867 void DataArrayDouble::applyFuncFast32(const char *func) throw(INTERP_KERNEL::Exception)
3868 {
3869   checkAllocated();
3870   INTERP_KERNEL::ExprParser expr(func);
3871   expr.parse();
3872   char *funcStr=expr.compileX86();
3873   MYFUNCPTR funcPtr;
3874   *((void **)&funcPtr)=funcStr;//he he...
3875   //
3876   double *ptr=getPointer();
3877   int nbOfComp=getNumberOfComponents();
3878   int nbOfTuples=getNumberOfTuples();
3879   int nbOfElems=nbOfTuples*nbOfComp;
3880   for(int i=0;i<nbOfElems;i++,ptr++)
3881     *ptr=funcPtr(*ptr);
3882   declareAsNew();
3883 }
3884
3885 void DataArrayDouble::applyFuncFast64(const char *func) throw(INTERP_KERNEL::Exception)
3886 {
3887   checkAllocated();
3888   INTERP_KERNEL::ExprParser expr(func);
3889   expr.parse();
3890   char *funcStr=expr.compileX86_64();
3891   MYFUNCPTR funcPtr;
3892   *((void **)&funcPtr)=funcStr;//he he...
3893   //
3894   double *ptr=getPointer();
3895   int nbOfComp=getNumberOfComponents();
3896   int nbOfTuples=getNumberOfTuples();
3897   int nbOfElems=nbOfTuples*nbOfComp;
3898   for(int i=0;i<nbOfElems;i++,ptr++)
3899     *ptr=funcPtr(*ptr);
3900   declareAsNew();
3901 }
3902
3903 DataArrayDoubleIterator *DataArrayDouble::iterator() throw(INTERP_KERNEL::Exception)
3904 {
3905   return new DataArrayDoubleIterator(this);
3906 }
3907
3908 /*!
3909  * Returns a new DataArrayInt contating indices of tuples of \a this one-dimensional
3910  * array whose values are within a given range. Textual data is not copied.
3911  *  \param [in] vmin - a lowest acceptable value.
3912  *  \param [in] vmax - a greatest acceptable value.
3913  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
3914  *          The caller is to delete this result array using decrRef() as it is no more
3915  *          needed.
3916  *  \throw If \a this->getNumberOfComponents() != 1
3917  *
3918  *  \ref cpp_mcdataarraydouble_getidsinrange "Here is a C++ example".
3919  *
3920  *  \ref py_mcdataarraydouble_getidsinrange "Here is a Python example".
3921  */
3922 DataArrayInt *DataArrayDouble::getIdsInRange(double vmin, double vmax) const throw(INTERP_KERNEL::Exception)
3923 {
3924   checkAllocated();
3925   if(getNumberOfComponents()!=1)
3926     throw INTERP_KERNEL::Exception("DataArrayDouble::getIdsInRange : this must have exactly one component !");
3927   const double *cptr=getConstPointer();
3928   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(0,1);
3929   int nbOfTuples=getNumberOfTuples();
3930   for(int i=0;i<nbOfTuples;i++,cptr++)
3931     if(*cptr>=vmin && *cptr<=vmax)
3932       ret->pushBackSilent(i);
3933   return ret.retn();
3934 }
3935
3936 /*!
3937  * Returns a new DataArrayDouble by concatenating two given arrays, so that (1) the number
3938  * of tuples in the result array is a sum of the number of tuples of given arrays and (2)
3939  * the number of component in the result array is same as that of each of given arrays.
3940  * Info on components is copied from the first of the given arrays. Number of components
3941  * in the given arrays must be  the same.
3942  *  \param [in] a1 - an array to include in the result array.
3943  *  \param [in] a2 - another array to include in the result array.
3944  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
3945  *          The caller is to delete this result array using decrRef() as it is no more
3946  *          needed.
3947  *  \throw If both \a a1 and \a a2 are NULL.
3948  *  \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents().
3949  */
3950 DataArrayDouble *DataArrayDouble::Aggregate(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception)
3951 {
3952   std::vector<const DataArrayDouble *> tmp(2);
3953   tmp[0]=a1; tmp[1]=a2;
3954   return Aggregate(tmp);
3955 }
3956
3957 /*!
3958  * Returns a new DataArrayDouble by concatenating all given arrays, so that (1) the number
3959  * of tuples in the result array is a sum of the number of tuples of given arrays and (2)
3960  * the number of component in the result array is same as that of each of given arrays.
3961  * Info on components is copied from the first of the given arrays. Number of components
3962  * in the given arrays must be  the same.
3963  *  \param [in] arr - a sequence of arrays to include in the result array.
3964  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
3965  *          The caller is to delete this result array using decrRef() as it is no more
3966  *          needed.
3967  *  \throw If all arrays within \a arr are NULL.
3968  *  \throw If getNumberOfComponents() of arrays within \a arr.
3969  */
3970 DataArrayDouble *DataArrayDouble::Aggregate(const std::vector<const DataArrayDouble *>& arr) throw(INTERP_KERNEL::Exception)
3971 {
3972   std::vector<const DataArrayDouble *> a;
3973   for(std::vector<const DataArrayDouble *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
3974     if(*it4)
3975       a.push_back(*it4);
3976   if(a.empty())
3977     throw INTERP_KERNEL::Exception("DataArrayDouble::Aggregate : input list must contain at least one NON EMPTY DataArrayDouble !");
3978   std::vector<const DataArrayDouble *>::const_iterator it=a.begin();
3979   int nbOfComp=(*it)->getNumberOfComponents();
3980   int nbt=(*it++)->getNumberOfTuples();
3981   for(int i=1;it!=a.end();it++,i++)
3982     {
3983       if((*it)->getNumberOfComponents()!=nbOfComp)
3984         throw INTERP_KERNEL::Exception("DataArrayDouble::Aggregate : Nb of components mismatch for array aggregation !");
3985       nbt+=(*it)->getNumberOfTuples();
3986     }
3987   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
3988   ret->alloc(nbt,nbOfComp);
3989   double *pt=ret->getPointer();
3990   for(it=a.begin();it!=a.end();it++)
3991     pt=std::copy((*it)->getConstPointer(),(*it)->getConstPointer()+(*it)->getNbOfElems(),pt);
3992   ret->copyStringInfoFrom(*(a[0]));
3993   return ret.retn();
3994 }
3995
3996 /*!
3997  * Returns a new DataArrayDouble by aggregating two given arrays, so that (1) the number
3998  * of components in the result array is a sum of the number of components of given arrays
3999  * and (2) the number of tuples in the result array is same as that of each of given
4000  * arrays. In other words the i-th tuple of result array includes all components of
4001  * i-th tuples of all given arrays.
4002  * Number of tuples in the given arrays must be  the same.
4003  *  \param [in] a1 - an array to include in the result array.
4004  *  \param [in] a2 - another array to include in the result array.
4005  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4006  *          The caller is to delete this result array using decrRef() as it is no more
4007  *          needed.
4008  *  \throw If both \a a1 and \a a2 are NULL.
4009  *  \throw If any given array is not allocated.
4010  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
4011  */
4012 DataArrayDouble *DataArrayDouble::Meld(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception)
4013 {
4014   std::vector<const DataArrayDouble *> arr(2);
4015   arr[0]=a1; arr[1]=a2;
4016   return Meld(arr);
4017 }
4018
4019 /*!
4020  * Returns a new DataArrayDouble by aggregating all given arrays, so that (1) the number
4021  * of components in the result array is a sum of the number of components of given arrays
4022  * and (2) the number of tuples in the result array is same as that of each of given
4023  * arrays. In other words the i-th tuple of result array includes all components of
4024  * i-th tuples of all given arrays.
4025  * Number of tuples in the given arrays must be  the same.
4026  *  \param [in] arr - a sequence of arrays to include in the result array.
4027  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4028  *          The caller is to delete this result array using decrRef() as it is no more
4029  *          needed.
4030  *  \throw If all arrays within \a arr are NULL.
4031  *  \throw If any given array is not allocated.
4032  *  \throw If getNumberOfTuples() of arrays within \a arr is different.
4033  */
4034 DataArrayDouble *DataArrayDouble::Meld(const std::vector<const DataArrayDouble *>& arr) throw(INTERP_KERNEL::Exception)
4035 {
4036   std::vector<const DataArrayDouble *> a;
4037   for(std::vector<const DataArrayDouble *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
4038     if(*it4)
4039       a.push_back(*it4);
4040   if(a.empty())
4041     throw INTERP_KERNEL::Exception("DataArrayDouble::Meld : input list must contain at least one NON EMPTY DataArrayDouble !");
4042   std::vector<const DataArrayDouble *>::const_iterator it;
4043   for(it=a.begin();it!=a.end();it++)
4044     (*it)->checkAllocated();
4045   it=a.begin();
4046   int nbOfTuples=(*it)->getNumberOfTuples();
4047   std::vector<int> nbc(a.size());
4048   std::vector<const double *> pts(a.size());
4049   nbc[0]=(*it)->getNumberOfComponents();
4050   pts[0]=(*it++)->getConstPointer();
4051   for(int i=1;it!=a.end();it++,i++)
4052     {
4053       if(nbOfTuples!=(*it)->getNumberOfTuples())
4054         throw INTERP_KERNEL::Exception("DataArrayDouble::Meld : mismatch of number of tuples !");
4055       nbc[i]=(*it)->getNumberOfComponents();
4056       pts[i]=(*it)->getConstPointer();
4057     }
4058   int totalNbOfComp=std::accumulate(nbc.begin(),nbc.end(),0);
4059   DataArrayDouble *ret=DataArrayDouble::New();
4060   ret->alloc(nbOfTuples,totalNbOfComp);
4061   double *retPtr=ret->getPointer();
4062   for(int i=0;i<nbOfTuples;i++)
4063     for(int j=0;j<(int)a.size();j++)
4064       {
4065         retPtr=std::copy(pts[j],pts[j]+nbc[j],retPtr);
4066         pts[j]+=nbc[j];
4067       }
4068   int k=0;
4069   for(int i=0;i<(int)a.size();i++)
4070     for(int j=0;j<nbc[i];j++,k++)
4071       ret->setInfoOnComponent(k,a[i]->getInfoOnComponent(j).c_str());
4072   return ret;
4073 }
4074
4075 /*!
4076  * Returns a new DataArrayDouble containing a dot product of two given arrays, so that
4077  * the i-th tuple of the result array is a sum of products of j-th components of i-th
4078  * tuples of given arrays (\f$ a_i = \sum_{j=1}^n a1_j * a2_j \f$).
4079  * Info on components and name is copied from the first of the given arrays.
4080  * Number of tuples and components in the given arrays must be the same.
4081  *  \param [in] a1 - a given array.
4082  *  \param [in] a2 - another given array.
4083  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4084  *          The caller is to delete this result array using decrRef() as it is no more
4085  *          needed.
4086  *  \throw If either \a a1 or \a a2 is NULL.
4087  *  \throw If any given array is not allocated.
4088  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
4089  *  \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents()
4090  */
4091 DataArrayDouble *DataArrayDouble::Dot(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception)
4092 {
4093   if(!a1 || !a2)
4094     throw INTERP_KERNEL::Exception("DataArrayDouble::Dot : input DataArrayDouble instance is NULL !");
4095   a1->checkAllocated();
4096   a2->checkAllocated();
4097   int nbOfComp=a1->getNumberOfComponents();
4098   if(nbOfComp!=a2->getNumberOfComponents())
4099     throw INTERP_KERNEL::Exception("Nb of components mismatch for array Dot !");
4100   int nbOfTuple=a1->getNumberOfTuples();
4101   if(nbOfTuple!=a2->getNumberOfTuples())
4102     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Dot !");
4103   DataArrayDouble *ret=DataArrayDouble::New();
4104   ret->alloc(nbOfTuple,1);
4105   double *retPtr=ret->getPointer();
4106   const double *a1Ptr=a1->getConstPointer();
4107   const double *a2Ptr=a2->getConstPointer();
4108   for(int i=0;i<nbOfTuple;i++)
4109     {
4110       double sum=0.;
4111       for(int j=0;j<nbOfComp;j++)
4112         sum+=a1Ptr[i*nbOfComp+j]*a2Ptr[i*nbOfComp+j];
4113       retPtr[i]=sum;
4114     }
4115   ret->setInfoOnComponent(0,a1->getInfoOnComponent(0).c_str());
4116   ret->setName(a1->getName().c_str());
4117   return ret;
4118 }
4119
4120 /*!
4121  * Returns a new DataArrayDouble containing a cross product of two given arrays, so that
4122  * the i-th tuple of the result array contains 3 components of a vector which is a cross
4123  * product of two vectors defined by the i-th tuples of given arrays.
4124  * Info on components is copied from the first of the given arrays.
4125  * Number of tuples in the given arrays must be the same.
4126  * Number of components in the given arrays must be 3.
4127  *  \param [in] a1 - a given array.
4128  *  \param [in] a2 - another given array.
4129  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4130  *          The caller is to delete this result array using decrRef() as it is no more
4131  *          needed.
4132  *  \throw If either \a a1 or \a a2 is NULL.
4133  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
4134  *  \throw If \a a1->getNumberOfComponents() != 3
4135  *  \throw If \a a2->getNumberOfComponents() != 3
4136  */
4137 DataArrayDouble *DataArrayDouble::CrossProduct(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception)
4138 {
4139   if(!a1 || !a2)
4140     throw INTERP_KERNEL::Exception("DataArrayDouble::CrossProduct : input DataArrayDouble instance is NULL !");
4141   int nbOfComp=a1->getNumberOfComponents();
4142   if(nbOfComp!=a2->getNumberOfComponents())
4143     throw INTERP_KERNEL::Exception("Nb of components mismatch for array crossProduct !");
4144   if(nbOfComp!=3)
4145     throw INTERP_KERNEL::Exception("Nb of components must be equal to 3 for array crossProduct !");
4146   int nbOfTuple=a1->getNumberOfTuples();
4147   if(nbOfTuple!=a2->getNumberOfTuples())
4148     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array crossProduct !");
4149   DataArrayDouble *ret=DataArrayDouble::New();
4150   ret->alloc(nbOfTuple,3);
4151   double *retPtr=ret->getPointer();
4152   const double *a1Ptr=a1->getConstPointer();
4153   const double *a2Ptr=a2->getConstPointer();
4154   for(int i=0;i<nbOfTuple;i++)
4155     {
4156       retPtr[3*i]=a1Ptr[3*i+1]*a2Ptr[3*i+2]-a1Ptr[3*i+2]*a2Ptr[3*i+1];
4157       retPtr[3*i+1]=a1Ptr[3*i+2]*a2Ptr[3*i]-a1Ptr[3*i]*a2Ptr[3*i+2];
4158       retPtr[3*i+2]=a1Ptr[3*i]*a2Ptr[3*i+1]-a1Ptr[3*i+1]*a2Ptr[3*i];
4159     }
4160   ret->copyStringInfoFrom(*a1);
4161   return ret;
4162 }
4163
4164 /*!
4165  * Returns a new DataArrayDouble containing maximal values of two given arrays.
4166  * Info on components is copied from the first of the given arrays.
4167  * Number of tuples and components in the given arrays must be the same.
4168  *  \param [in] a1 - an array to compare values with another one.
4169  *  \param [in] a2 - another array to compare values with the first one.
4170  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4171  *          The caller is to delete this result array using decrRef() as it is no more
4172  *          needed.
4173  *  \throw If either \a a1 or \a a2 is NULL.
4174  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
4175  *  \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents()
4176  */
4177 DataArrayDouble *DataArrayDouble::Max(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception)
4178 {
4179   if(!a1 || !a2)
4180     throw INTERP_KERNEL::Exception("DataArrayDouble::Max : input DataArrayDouble instance is NULL !");
4181   int nbOfComp=a1->getNumberOfComponents();
4182   if(nbOfComp!=a2->getNumberOfComponents())
4183     throw INTERP_KERNEL::Exception("Nb of components mismatch for array Max !");
4184   int nbOfTuple=a1->getNumberOfTuples();
4185   if(nbOfTuple!=a2->getNumberOfTuples())
4186     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Max !");
4187   DataArrayDouble *ret=DataArrayDouble::New();
4188   ret->alloc(nbOfTuple,nbOfComp);
4189   double *retPtr=ret->getPointer();
4190   const double *a1Ptr=a1->getConstPointer();
4191   const double *a2Ptr=a2->getConstPointer();
4192   int nbElem=nbOfTuple*nbOfComp;
4193   for(int i=0;i<nbElem;i++)
4194     retPtr[i]=std::max(a1Ptr[i],a2Ptr[i]);
4195   ret->copyStringInfoFrom(*a1);
4196   return ret;
4197 }
4198
4199 /*!
4200  * Returns a new DataArrayDouble containing minimal values of two given arrays.
4201  * Info on components is copied from the first of the given arrays.
4202  * Number of tuples and components in the given arrays must be the same.
4203  *  \param [in] a1 - an array to compare values with another one.
4204  *  \param [in] a2 - another array to compare values with the first one.
4205  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4206  *          The caller is to delete this result array using decrRef() as it is no more
4207  *          needed.
4208  *  \throw If either \a a1 or \a a2 is NULL.
4209  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
4210  *  \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents()
4211  */
4212 DataArrayDouble *DataArrayDouble::Min(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception)
4213 {
4214   if(!a1 || !a2)
4215     throw INTERP_KERNEL::Exception("DataArrayDouble::Min : input DataArrayDouble instance is NULL !");
4216   int nbOfComp=a1->getNumberOfComponents();
4217   if(nbOfComp!=a2->getNumberOfComponents())
4218     throw INTERP_KERNEL::Exception("Nb of components mismatch for array min !");
4219   int nbOfTuple=a1->getNumberOfTuples();
4220   if(nbOfTuple!=a2->getNumberOfTuples())
4221     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array min !");
4222   DataArrayDouble *ret=DataArrayDouble::New();
4223   ret->alloc(nbOfTuple,nbOfComp);
4224   double *retPtr=ret->getPointer();
4225   const double *a1Ptr=a1->getConstPointer();
4226   const double *a2Ptr=a2->getConstPointer();
4227   int nbElem=nbOfTuple*nbOfComp;
4228   for(int i=0;i<nbElem;i++)
4229     retPtr[i]=std::min(a1Ptr[i],a2Ptr[i]);
4230   ret->copyStringInfoFrom(*a1);
4231   return ret;
4232 }
4233
4234 /*!
4235  * Returns a new DataArrayDouble that is a sum of two given arrays. There are 3
4236  * valid cases.
4237  * 1.  The arrays have same number of tuples and components. Then each value of
4238  *   the result array (_a_) is a sum of the corresponding values of \a a1 and \a a2,
4239  *   i.e.: _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ i, j ].
4240  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
4241  *   component. Then
4242  *   _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ i, 0 ].
4243  * 3.  The arrays have same number of components and one array, say _a2_, has one
4244  *   tuple. Then
4245  *   _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ 0, j ].
4246  *
4247  * Info on components is copied either from the first array (in the first case) or from
4248  * the array with maximal number of elements (getNbOfElems()).
4249  *  \param [in] a1 - an array to sum up.
4250  *  \param [in] a2 - another array to sum up.
4251  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4252  *          The caller is to delete this result array using decrRef() as it is no more
4253  *          needed.
4254  *  \throw If either \a a1 or \a a2 is NULL.
4255  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
4256  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
4257  *         none of them has number of tuples or components equal to 1.
4258  */
4259 DataArrayDouble *DataArrayDouble::Add(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception)
4260 {
4261   if(!a1 || !a2)
4262     throw INTERP_KERNEL::Exception("DataArrayDouble::Add : input DataArrayDouble instance is NULL !");
4263   int nbOfTuple=a1->getNumberOfTuples();
4264   int nbOfTuple2=a2->getNumberOfTuples();
4265   int nbOfComp=a1->getNumberOfComponents();
4266   int nbOfComp2=a2->getNumberOfComponents();
4267   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=0;
4268   if(nbOfTuple==nbOfTuple2)
4269     {
4270       if(nbOfComp==nbOfComp2)
4271         {
4272           ret=DataArrayDouble::New();
4273           ret->alloc(nbOfTuple,nbOfComp);
4274           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::plus<double>());
4275           ret->copyStringInfoFrom(*a1);
4276         }
4277       else
4278         {
4279           int nbOfCompMin,nbOfCompMax;
4280           const DataArrayDouble *aMin, *aMax;
4281           if(nbOfComp>nbOfComp2)
4282             {
4283               nbOfCompMin=nbOfComp2; nbOfCompMax=nbOfComp;
4284               aMin=a2; aMax=a1;
4285             }
4286           else
4287             {
4288               nbOfCompMin=nbOfComp; nbOfCompMax=nbOfComp2;
4289               aMin=a1; aMax=a2;
4290             }
4291           if(nbOfCompMin==1)
4292             {
4293               ret=DataArrayDouble::New();
4294               ret->alloc(nbOfTuple,nbOfCompMax);
4295               const double *aMinPtr=aMin->getConstPointer();
4296               const double *aMaxPtr=aMax->getConstPointer();
4297               double *res=ret->getPointer();
4298               for(int i=0;i<nbOfTuple;i++)
4299                 res=std::transform(aMaxPtr+i*nbOfCompMax,aMaxPtr+(i+1)*nbOfCompMax,res,std::bind2nd(std::plus<double>(),aMinPtr[i]));
4300               ret->copyStringInfoFrom(*aMax);
4301             }
4302           else
4303             throw INTERP_KERNEL::Exception("Nb of components mismatch for array Add !");
4304         }
4305     }
4306   else if((nbOfTuple==1 && nbOfTuple2>1) || (nbOfTuple>1 && nbOfTuple2==1))
4307     {
4308       if(nbOfComp==nbOfComp2)
4309         {
4310           int nbOfTupleMax=std::max(nbOfTuple,nbOfTuple2);
4311           const DataArrayDouble *aMin=nbOfTuple>nbOfTuple2?a2:a1;
4312           const DataArrayDouble *aMax=nbOfTuple>nbOfTuple2?a1:a2;
4313           const double *aMinPtr=aMin->getConstPointer(),*aMaxPtr=aMax->getConstPointer();
4314           ret=DataArrayDouble::New();
4315           ret->alloc(nbOfTupleMax,nbOfComp);
4316           double *res=ret->getPointer();
4317           for(int i=0;i<nbOfTupleMax;i++)
4318             res=std::transform(aMaxPtr+i*nbOfComp,aMaxPtr+(i+1)*nbOfComp,aMinPtr,res,std::plus<double>());
4319           ret->copyStringInfoFrom(*aMax);
4320         }
4321       else
4322         throw INTERP_KERNEL::Exception("Nb of components mismatch for array Add !");
4323     }
4324   else
4325     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Add !");
4326   return ret.retn();
4327 }
4328
4329 /*!
4330  * Adds values of another DataArrayDouble to values of \a this one. There are 3
4331  * valid cases.
4332  * 1.  The arrays have same number of tuples and components. Then each value of
4333  *   \a other array is added to the corresponding value of \a this array, i.e.:
4334  *   _a_ [ i, j ] += _other_ [ i, j ].
4335  * 2.  The arrays have same number of tuples and \a other array has one component. Then
4336  *   _a_ [ i, j ] += _other_ [ i, 0 ].
4337  * 3.  The arrays have same number of components and \a other array has one tuple. Then
4338  *   _a_ [ i, j ] += _a2_ [ 0, j ].
4339  *
4340  *  \param [in] other - an array to add to \a this one.
4341  *  \throw If \a other is NULL.
4342  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
4343  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
4344  *         \a other has number of both tuples and components not equal to 1.
4345  */
4346 void DataArrayDouble::addEqual(const DataArrayDouble *other) throw(INTERP_KERNEL::Exception)
4347 {
4348   if(!other)
4349     throw INTERP_KERNEL::Exception("DataArrayDouble::addEqual : input DataArrayDouble instance is NULL !");
4350   const char *msg="Nb of tuples mismatch for DataArrayDouble::addEqual  !";
4351   checkAllocated();
4352   other->checkAllocated();
4353   int nbOfTuple=getNumberOfTuples();
4354   int nbOfTuple2=other->getNumberOfTuples();
4355   int nbOfComp=getNumberOfComponents();
4356   int nbOfComp2=other->getNumberOfComponents();
4357   if(nbOfTuple==nbOfTuple2)
4358     {
4359       if(nbOfComp==nbOfComp2)
4360         {
4361           std::transform(begin(),end(),other->begin(),getPointer(),std::plus<double>());
4362         }
4363       else if(nbOfComp2==1)
4364         {
4365           double *ptr=getPointer();
4366           const double *ptrc=other->getConstPointer();
4367           for(int i=0;i<nbOfTuple;i++)
4368             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::plus<double>(),*ptrc++));
4369         }
4370       else
4371         throw INTERP_KERNEL::Exception(msg);
4372     }
4373   else if(nbOfTuple2==1)
4374     {
4375       if(nbOfComp2==nbOfComp)
4376         {
4377           double *ptr=getPointer();
4378           const double *ptrc=other->getConstPointer();
4379           for(int i=0;i<nbOfTuple;i++)
4380             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::plus<double>());
4381         }
4382       else
4383         throw INTERP_KERNEL::Exception(msg);
4384     }
4385   else
4386     throw INTERP_KERNEL::Exception(msg);
4387   declareAsNew();
4388 }
4389
4390 /*!
4391  * Returns a new DataArrayDouble that is a subtraction of two given arrays. There are 3
4392  * valid cases.
4393  * 1.  The arrays have same number of tuples and components. Then each value of
4394  *   the result array (_a_) is a subtraction of the corresponding values of \a a1 and
4395  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ i, j ].
4396  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
4397  *   component. Then
4398  *   _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ i, 0 ].
4399  * 3.  The arrays have same number of components and one array, say _a2_, has one
4400  *   tuple. Then
4401  *   _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ 0, j ].
4402  *
4403  * Info on components is copied either from the first array (in the first case) or from
4404  * the array with maximal number of elements (getNbOfElems()).
4405  *  \param [in] a1 - an array to subtract from.
4406  *  \param [in] a2 - an array to subtract.
4407  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4408  *          The caller is to delete this result array using decrRef() as it is no more
4409  *          needed.
4410  *  \throw If either \a a1 or \a a2 is NULL.
4411  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
4412  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
4413  *         none of them has number of tuples or components equal to 1.
4414  */
4415 DataArrayDouble *DataArrayDouble::Substract(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception)
4416 {
4417   if(!a1 || !a2)
4418     throw INTERP_KERNEL::Exception("DataArrayDouble::Substract : input DataArrayDouble instance is NULL !");
4419   int nbOfTuple1=a1->getNumberOfTuples();
4420   int nbOfTuple2=a2->getNumberOfTuples();
4421   int nbOfComp1=a1->getNumberOfComponents();
4422   int nbOfComp2=a2->getNumberOfComponents();
4423   if(nbOfTuple2==nbOfTuple1)
4424     {
4425       if(nbOfComp1==nbOfComp2)
4426         {
4427           MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
4428           ret->alloc(nbOfTuple2,nbOfComp1);
4429           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::minus<double>());
4430           ret->copyStringInfoFrom(*a1);
4431           return ret.retn();
4432         }
4433       else if(nbOfComp2==1)
4434         {
4435           MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
4436           ret->alloc(nbOfTuple1,nbOfComp1);
4437           const double *a2Ptr=a2->getConstPointer();
4438           const double *a1Ptr=a1->getConstPointer();
4439           double *res=ret->getPointer();
4440           for(int i=0;i<nbOfTuple1;i++)
4441             res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::minus<double>(),a2Ptr[i]));
4442           ret->copyStringInfoFrom(*a1);
4443           return ret.retn();
4444         }
4445       else
4446         {
4447           a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Substract !");
4448           return 0;
4449         }
4450     }
4451   else if(nbOfTuple2==1)
4452     {
4453       a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Substract !");
4454       MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
4455       ret->alloc(nbOfTuple1,nbOfComp1);
4456       const double *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
4457       double *pt=ret->getPointer();
4458       for(int i=0;i<nbOfTuple1;i++)
4459         pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::minus<double>());
4460       ret->copyStringInfoFrom(*a1);
4461       return ret.retn();
4462     }
4463   else
4464     {
4465       a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Substract !");//will always throw an exception
4466       return 0;
4467     }
4468 }
4469
4470 /*!
4471  * Subtract values of another DataArrayDouble from values of \a this one. There are 3
4472  * valid cases.
4473  * 1.  The arrays have same number of tuples and components. Then each value of
4474  *   \a other array is subtracted from the corresponding value of \a this array, i.e.:
4475  *   _a_ [ i, j ] -= _other_ [ i, j ].
4476  * 2.  The arrays have same number of tuples and \a other array has one component. Then
4477  *   _a_ [ i, j ] -= _other_ [ i, 0 ].
4478  * 3.  The arrays have same number of components and \a other array has one tuple. Then
4479  *   _a_ [ i, j ] -= _a2_ [ 0, j ].
4480  *
4481  *  \param [in] other - an array to subtract from \a this one.
4482  *  \throw If \a other is NULL.
4483  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
4484  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
4485  *         \a other has number of both tuples and components not equal to 1.
4486  */
4487 void DataArrayDouble::substractEqual(const DataArrayDouble *other) throw(INTERP_KERNEL::Exception)
4488 {
4489   if(!other)
4490     throw INTERP_KERNEL::Exception("DataArrayDouble::substractEqual : input DataArrayDouble instance is NULL !");
4491   const char *msg="Nb of tuples mismatch for DataArrayDouble::substractEqual  !";
4492   checkAllocated();
4493   other->checkAllocated();
4494   int nbOfTuple=getNumberOfTuples();
4495   int nbOfTuple2=other->getNumberOfTuples();
4496   int nbOfComp=getNumberOfComponents();
4497   int nbOfComp2=other->getNumberOfComponents();
4498   if(nbOfTuple==nbOfTuple2)
4499     {
4500       if(nbOfComp==nbOfComp2)
4501         {
4502           std::transform(begin(),end(),other->begin(),getPointer(),std::minus<double>());
4503         }
4504       else if(nbOfComp2==1)
4505         {
4506           double *ptr=getPointer();
4507           const double *ptrc=other->getConstPointer();
4508           for(int i=0;i<nbOfTuple;i++)
4509             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::minus<double>(),*ptrc++)); 
4510         }
4511       else
4512         throw INTERP_KERNEL::Exception(msg);
4513     }
4514   else if(nbOfTuple2==1)
4515     {
4516       if(nbOfComp2==nbOfComp)
4517         {
4518           double *ptr=getPointer();
4519           const double *ptrc=other->getConstPointer();
4520           for(int i=0;i<nbOfTuple;i++)
4521             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::minus<double>());
4522         }
4523       else
4524         throw INTERP_KERNEL::Exception(msg);
4525     }
4526   else
4527     throw INTERP_KERNEL::Exception(msg);
4528   declareAsNew();
4529 }
4530
4531 /*!
4532  * Returns a new DataArrayDouble that is a product of two given arrays. There are 3
4533  * valid cases.
4534  * 1.  The arrays have same number of tuples and components. Then each value of
4535  *   the result array (_a_) is a product of the corresponding values of \a a1 and
4536  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ i, j ].
4537  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
4538  *   component. Then
4539  *   _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ i, 0 ].
4540  * 3.  The arrays have same number of components and one array, say _a2_, has one
4541  *   tuple. Then
4542  *   _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ 0, j ].
4543  *
4544  * Info on components is copied either from the first array (in the first case) or from
4545  * the array with maximal number of elements (getNbOfElems()).
4546  *  \param [in] a1 - a factor array.
4547  *  \param [in] a2 - another factor array.
4548  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4549  *          The caller is to delete this result array using decrRef() as it is no more
4550  *          needed.
4551  *  \throw If either \a a1 or \a a2 is NULL.
4552  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
4553  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
4554  *         none of them has number of tuples or components equal to 1.
4555  */
4556 DataArrayDouble *DataArrayDouble::Multiply(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception)
4557 {
4558   if(!a1 || !a2)
4559     throw INTERP_KERNEL::Exception("DataArrayDouble::Multiply : input DataArrayDouble instance is NULL !");
4560   int nbOfTuple=a1->getNumberOfTuples();
4561   int nbOfTuple2=a2->getNumberOfTuples();
4562   int nbOfComp=a1->getNumberOfComponents();
4563   int nbOfComp2=a2->getNumberOfComponents();
4564   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=0;
4565   if(nbOfTuple==nbOfTuple2)
4566     {
4567       if(nbOfComp==nbOfComp2)
4568         {
4569           ret=DataArrayDouble::New();
4570           ret->alloc(nbOfTuple,nbOfComp);
4571           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::multiplies<double>());
4572           ret->copyStringInfoFrom(*a1);
4573         }
4574       else
4575         {
4576           int nbOfCompMin,nbOfCompMax;
4577           const DataArrayDouble *aMin, *aMax;
4578           if(nbOfComp>nbOfComp2)
4579             {
4580               nbOfCompMin=nbOfComp2; nbOfCompMax=nbOfComp;
4581               aMin=a2; aMax=a1;
4582             }
4583           else
4584             {
4585               nbOfCompMin=nbOfComp; nbOfCompMax=nbOfComp2;
4586               aMin=a1; aMax=a2;
4587             }
4588           if(nbOfCompMin==1)
4589             {
4590               ret=DataArrayDouble::New();
4591               ret->alloc(nbOfTuple,nbOfCompMax);
4592               const double *aMinPtr=aMin->getConstPointer();
4593               const double *aMaxPtr=aMax->getConstPointer();
4594               double *res=ret->getPointer();
4595               for(int i=0;i<nbOfTuple;i++)
4596                 res=std::transform(aMaxPtr+i*nbOfCompMax,aMaxPtr+(i+1)*nbOfCompMax,res,std::bind2nd(std::multiplies<double>(),aMinPtr[i]));
4597               ret->copyStringInfoFrom(*aMax);
4598             }
4599           else
4600             throw INTERP_KERNEL::Exception("Nb of components mismatch for array Multiply !");
4601         }
4602     }
4603   else if((nbOfTuple==1 && nbOfTuple2>1) || (nbOfTuple>1 && nbOfTuple2==1))
4604     {
4605       if(nbOfComp==nbOfComp2)
4606         {
4607           int nbOfTupleMax=std::max(nbOfTuple,nbOfTuple2);
4608           const DataArrayDouble *aMin=nbOfTuple>nbOfTuple2?a2:a1;
4609           const DataArrayDouble *aMax=nbOfTuple>nbOfTuple2?a1:a2;
4610           const double *aMinPtr=aMin->getConstPointer(),*aMaxPtr=aMax->getConstPointer();
4611           ret=DataArrayDouble::New();
4612           ret->alloc(nbOfTupleMax,nbOfComp);
4613           double *res=ret->getPointer();
4614           for(int i=0;i<nbOfTupleMax;i++)
4615             res=std::transform(aMaxPtr+i*nbOfComp,aMaxPtr+(i+1)*nbOfComp,aMinPtr,res,std::multiplies<double>());
4616           ret->copyStringInfoFrom(*aMax);
4617         }
4618       else
4619         throw INTERP_KERNEL::Exception("Nb of components mismatch for array Multiply !");
4620     }
4621   else
4622     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Multiply !");
4623   return ret.retn();
4624 }
4625
4626 /*!
4627  * Multiply values of another DataArrayDouble to values of \a this one. There are 3
4628  * valid cases.
4629  * 1.  The arrays have same number of tuples and components. Then each value of
4630  *   \a other array is multiplied to the corresponding value of \a this array, i.e.:
4631  *   _a_ [ i, j ] *= _other_ [ i, j ].
4632  * 2.  The arrays have same number of tuples and \a other array has one component. Then
4633  *   _a_ [ i, j ] *= _other_ [ i, 0 ].
4634  * 3.  The arrays have same number of components and \a other array has one tuple. Then
4635  *   _a_ [ i, j ] *= _a2_ [ 0, j ].
4636  *
4637  *  \param [in] other - an array to multiply to \a this one.
4638  *  \throw If \a other is NULL.
4639  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
4640  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
4641  *         \a other has number of both tuples and components not equal to 1.
4642  */
4643 void DataArrayDouble::multiplyEqual(const DataArrayDouble *other) throw(INTERP_KERNEL::Exception)
4644 {
4645   if(!other)
4646     throw INTERP_KERNEL::Exception("DataArrayDouble::multiplyEqual : input DataArrayDouble instance is NULL !");
4647   const char *msg="Nb of tuples mismatch for DataArrayDouble::multiplyEqual !";
4648   checkAllocated();
4649   other->checkAllocated();
4650   int nbOfTuple=getNumberOfTuples();
4651   int nbOfTuple2=other->getNumberOfTuples();
4652   int nbOfComp=getNumberOfComponents();
4653   int nbOfComp2=other->getNumberOfComponents();
4654   if(nbOfTuple==nbOfTuple2)
4655     {
4656       if(nbOfComp==nbOfComp2)
4657         {
4658           std::transform(begin(),end(),other->begin(),getPointer(),std::multiplies<double>());
4659         }
4660       else if(nbOfComp2==1)
4661         {
4662           double *ptr=getPointer();
4663           const double *ptrc=other->getConstPointer();
4664           for(int i=0;i<nbOfTuple;i++)
4665             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::multiplies<double>(),*ptrc++));
4666         }
4667       else
4668         throw INTERP_KERNEL::Exception(msg);
4669     }
4670   else if(nbOfTuple2==1)
4671     {
4672       if(nbOfComp2==nbOfComp)
4673         {
4674           double *ptr=getPointer();
4675           const double *ptrc=other->getConstPointer();
4676           for(int i=0;i<nbOfTuple;i++)
4677             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::multiplies<double>());
4678         }
4679       else
4680         throw INTERP_KERNEL::Exception(msg);
4681     }
4682   else
4683     throw INTERP_KERNEL::Exception(msg);
4684   declareAsNew();
4685 }
4686
4687 /*!
4688  * Returns a new DataArrayDouble that is a division of two given arrays. There are 3
4689  * valid cases.
4690  * 1.  The arrays have same number of tuples and components. Then each value of
4691  *   the result array (_a_) is a division of the corresponding values of \a a1 and
4692  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ i, j ].
4693  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
4694  *   component. Then
4695  *   _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ i, 0 ].
4696  * 3.  The arrays have same number of components and one array, say _a2_, has one
4697  *   tuple. Then
4698  *   _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ 0, j ].
4699  *
4700  * Info on components is copied either from the first array (in the first case) or from
4701  * the array with maximal number of elements (getNbOfElems()).
4702  *  \param [in] a1 - a numerator array.
4703  *  \param [in] a2 - a denominator array.
4704  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4705  *          The caller is to delete this result array using decrRef() as it is no more
4706  *          needed.
4707  *  \throw If either \a a1 or \a a2 is NULL.
4708  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
4709  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
4710  *         none of them has number of tuples or components equal to 1.
4711  *  \warning No check of division by zero is performed!
4712  */
4713 DataArrayDouble *DataArrayDouble::Divide(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception)
4714 {
4715   if(!a1 || !a2)
4716     throw INTERP_KERNEL::Exception("DataArrayDouble::Divide : input DataArrayDouble instance is NULL !");
4717   int nbOfTuple1=a1->getNumberOfTuples();
4718   int nbOfTuple2=a2->getNumberOfTuples();
4719   int nbOfComp1=a1->getNumberOfComponents();
4720   int nbOfComp2=a2->getNumberOfComponents();
4721   if(nbOfTuple2==nbOfTuple1)
4722     {
4723       if(nbOfComp1==nbOfComp2)
4724         {
4725           MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
4726           ret->alloc(nbOfTuple2,nbOfComp1);
4727           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::divides<double>());
4728           ret->copyStringInfoFrom(*a1);
4729           return ret.retn();
4730         }
4731       else if(nbOfComp2==1)
4732         {
4733           MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
4734           ret->alloc(nbOfTuple1,nbOfComp1);
4735           const double *a2Ptr=a2->getConstPointer();
4736           const double *a1Ptr=a1->getConstPointer();
4737           double *res=ret->getPointer();
4738           for(int i=0;i<nbOfTuple1;i++)
4739             res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::divides<double>(),a2Ptr[i]));
4740           ret->copyStringInfoFrom(*a1);
4741           return ret.retn();
4742         }
4743       else
4744         {
4745           a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Divide !");
4746           return 0;
4747         }
4748     }
4749   else if(nbOfTuple2==1)
4750     {
4751       a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Divide !");
4752       MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
4753       ret->alloc(nbOfTuple1,nbOfComp1);
4754       const double *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
4755       double *pt=ret->getPointer();
4756       for(int i=0;i<nbOfTuple1;i++)
4757         pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::divides<double>());
4758       ret->copyStringInfoFrom(*a1);
4759       return ret.retn();
4760     }
4761   else
4762     {
4763       a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Divide !");//will always throw an exception
4764       return 0;
4765     }
4766 }
4767
4768 /*!
4769  * Divide values of \a this array by values of another DataArrayDouble. There are 3
4770  * valid cases.
4771  * 1.  The arrays have same number of tuples and components. Then each value of
4772  *    \a this array is divided by the corresponding value of \a other one, i.e.:
4773  *   _a_ [ i, j ] /= _other_ [ i, j ].
4774  * 2.  The arrays have same number of tuples and \a other array has one component. Then
4775  *   _a_ [ i, j ] /= _other_ [ i, 0 ].
4776  * 3.  The arrays have same number of components and \a other array has one tuple. Then
4777  *   _a_ [ i, j ] /= _a2_ [ 0, j ].
4778  *
4779  *  \param [in] other - an array to divide \a this one by.
4780  *  \throw If \a other is NULL.
4781  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
4782  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
4783  *         \a other has number of both tuples and components not equal to 1.
4784  *  \warning No check of division by zero is performed!
4785  */
4786 void DataArrayDouble::divideEqual(const DataArrayDouble *other) throw(INTERP_KERNEL::Exception)
4787 {
4788   if(!other)
4789     throw INTERP_KERNEL::Exception("DataArrayDouble::divideEqual : input DataArrayDouble instance is NULL !");
4790   const char *msg="Nb of tuples mismatch for DataArrayDouble::divideEqual !";
4791   checkAllocated();
4792   other->checkAllocated();
4793   int nbOfTuple=getNumberOfTuples();
4794   int nbOfTuple2=other->getNumberOfTuples();
4795   int nbOfComp=getNumberOfComponents();
4796   int nbOfComp2=other->getNumberOfComponents();
4797   if(nbOfTuple==nbOfTuple2)
4798     {
4799       if(nbOfComp==nbOfComp2)
4800         {
4801           std::transform(begin(),end(),other->begin(),getPointer(),std::divides<double>());
4802         }
4803       else if(nbOfComp2==1)
4804         {
4805           double *ptr=getPointer();
4806           const double *ptrc=other->getConstPointer();
4807           for(int i=0;i<nbOfTuple;i++)
4808             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::divides<double>(),*ptrc++));
4809         }
4810       else
4811         throw INTERP_KERNEL::Exception(msg);
4812     }
4813   else if(nbOfTuple2==1)
4814     {
4815       if(nbOfComp2==nbOfComp)
4816         {
4817           double *ptr=getPointer();
4818           const double *ptrc=other->getConstPointer();
4819           for(int i=0;i<nbOfTuple;i++)
4820             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::divides<double>());
4821         }
4822       else
4823         throw INTERP_KERNEL::Exception(msg);
4824     }
4825   else
4826     throw INTERP_KERNEL::Exception(msg);
4827   declareAsNew();
4828 }
4829
4830 /*!
4831  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
4832  * Server side.
4833  */
4834 void DataArrayDouble::getTinySerializationIntInformation(std::vector<int>& tinyInfo) const
4835 {
4836   tinyInfo.resize(2);
4837   if(isAllocated())
4838     {
4839       tinyInfo[0]=getNumberOfTuples();
4840       tinyInfo[1]=getNumberOfComponents();
4841     }
4842   else
4843     {
4844       tinyInfo[0]=-1;
4845       tinyInfo[1]=-1;
4846     }
4847 }
4848
4849 /*!
4850  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
4851  * Server side.
4852  */
4853 void DataArrayDouble::getTinySerializationStrInformation(std::vector<std::string>& tinyInfo) const
4854 {
4855   if(isAllocated())
4856     {
4857       int nbOfCompo=getNumberOfComponents();
4858       tinyInfo.resize(nbOfCompo+1);
4859       tinyInfo[0]=getName();
4860       for(int i=0;i<nbOfCompo;i++)
4861         tinyInfo[i+1]=getInfoOnComponent(i);
4862     }
4863   else
4864     {
4865       tinyInfo.resize(1);
4866       tinyInfo[0]=getName();
4867     }
4868 }
4869
4870 /*!
4871  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
4872  * This method returns if a feeding is needed.
4873  */
4874 bool DataArrayDouble::resizeForUnserialization(const std::vector<int>& tinyInfoI)
4875 {
4876   int nbOfTuple=tinyInfoI[0];
4877   int nbOfComp=tinyInfoI[1];
4878   if(nbOfTuple!=-1 || nbOfComp!=-1)
4879     {
4880       alloc(nbOfTuple,nbOfComp);
4881       return true;
4882     }
4883   return false;
4884 }
4885
4886 /*!
4887  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
4888  */
4889 void DataArrayDouble::finishUnserialization(const std::vector<int>& tinyInfoI, const std::vector<std::string>& tinyInfoS)
4890 {
4891   setName(tinyInfoS[0].c_str());
4892   if(isAllocated())
4893     {
4894       int nbOfCompo=getNumberOfComponents();
4895       for(int i=0;i<nbOfCompo;i++)
4896         setInfoOnComponent(i,tinyInfoS[i+1].c_str());
4897     }
4898 }
4899
4900 DataArrayDoubleIterator::DataArrayDoubleIterator(DataArrayDouble *da):_da(da),_tuple_id(0),_nb_comp(0),_nb_tuple(0)
4901 {
4902   if(_da)
4903     {
4904       _da->incrRef();
4905       if(_da->isAllocated())
4906         {
4907           _nb_comp=da->getNumberOfComponents();
4908           _nb_tuple=da->getNumberOfTuples();
4909           _pt=da->getPointer();
4910         }
4911     }
4912 }
4913
4914 DataArrayDoubleIterator::~DataArrayDoubleIterator()
4915 {
4916   if(_da)
4917     _da->decrRef();
4918 }
4919
4920 DataArrayDoubleTuple *DataArrayDoubleIterator::nextt() throw(INTERP_KERNEL::Exception)
4921 {
4922   if(_tuple_id<_nb_tuple)
4923     {
4924       _tuple_id++;
4925       DataArrayDoubleTuple *ret=new DataArrayDoubleTuple(_pt,_nb_comp);
4926       _pt+=_nb_comp;
4927       return ret;
4928     }
4929   else
4930     return 0;
4931 }
4932
4933 DataArrayDoubleTuple::DataArrayDoubleTuple(double *pt, int nbOfComp):_pt(pt),_nb_of_compo(nbOfComp)
4934 {
4935 }
4936
4937
4938 std::string DataArrayDoubleTuple::repr() const throw(INTERP_KERNEL::Exception)
4939 {
4940   std::ostringstream oss; oss.precision(17); oss << "(";
4941   for(int i=0;i<_nb_of_compo-1;i++)
4942     oss << _pt[i] << ", ";
4943   oss << _pt[_nb_of_compo-1] << ")";
4944   return oss.str();
4945 }
4946
4947 double DataArrayDoubleTuple::doubleValue() const throw(INTERP_KERNEL::Exception)
4948 {
4949   if(_nb_of_compo==1)
4950     return *_pt;
4951   throw INTERP_KERNEL::Exception("DataArrayDoubleTuple::doubleValue : DataArrayDoubleTuple instance has not exactly 1 component -> Not possible to convert it into a double precision float !");
4952 }
4953
4954 /*!
4955  * This method returns a newly allocated instance the caller should dealed with by a ParaMEDMEM::DataArrayDouble::decrRef.
4956  * This method performs \b no copy of data. The content is only referenced using ParaMEDMEM::DataArrayDouble::useArray with ownership set to \b false.
4957  * 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
4958  * \b nbOfCompo=1 and \bnbOfTuples==this->_nb_of_elem.
4959  */
4960 DataArrayDouble *DataArrayDoubleTuple::buildDADouble(int nbOfTuples, int nbOfCompo) const throw(INTERP_KERNEL::Exception)
4961 {
4962   if((_nb_of_compo==nbOfCompo && nbOfTuples==1) || (_nb_of_compo==nbOfTuples && nbOfCompo==1))
4963     {
4964       DataArrayDouble *ret=DataArrayDouble::New();
4965       ret->useExternalArrayWithRWAccess(_pt,nbOfTuples,nbOfCompo);
4966       return ret;
4967     }
4968   else
4969     {
4970       std::ostringstream oss; oss << "DataArrayDoubleTuple::buildDADouble : unable to build a requested DataArrayDouble instance with nbofTuple=" << nbOfTuples << " and nbOfCompo=" << nbOfCompo;
4971       oss << ".\nBecause the number of elements in this is " << _nb_of_compo << " !";
4972       throw INTERP_KERNEL::Exception(oss.str().c_str());
4973     }
4974 }
4975
4976 /*!
4977  * Returns a new instance of DataArrayInt. The caller is to delete this array
4978  * using decrRef() as it is no more needed. 
4979  */
4980 DataArrayInt *DataArrayInt::New()
4981 {
4982   return new DataArrayInt;
4983 }
4984
4985 /*!
4986  * Checks if raw data is allocated. Read more on the raw data
4987  * in \ref MEDCouplingArrayBasicsTuplesAndCompo "DataArrays infos" for more information.
4988  *  \return bool - \a true if the raw data is allocated, \a false else.
4989  */
4990 bool DataArrayInt::isAllocated() const throw(INTERP_KERNEL::Exception)
4991 {
4992   return getConstPointer()!=0;
4993 }
4994
4995 /*!
4996  * Checks if raw data is allocated and throws an exception if it is not the case.
4997  *  \throw If the raw data is not allocated.
4998  */
4999 void DataArrayInt::checkAllocated() const throw(INTERP_KERNEL::Exception)
5000 {
5001   if(!isAllocated())
5002     throw INTERP_KERNEL::Exception("DataArrayInt::checkAllocated : Array is defined but not allocated ! Call alloc or setValues method first !");
5003 }
5004
5005 std::size_t DataArrayInt::getHeapMemorySize() const
5006 {
5007   std::size_t sz=(std::size_t)_mem.getNbOfElemAllocated();
5008   sz*=sizeof(int);
5009   return DataArray::getHeapMemorySize()+sz;
5010 }
5011
5012 /*!
5013  * Sets information on all components. This method can change number of components
5014  * at certain conditions; if the conditions are not respected, an exception is thrown.
5015  * The number of components can be changed provided that \a this is not allocated.
5016  *
5017  * To know more on format of the component information see
5018  * \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
5019  *  \param [in] info - a vector of component infos.
5020  *  \throw If \a this->getNumberOfComponents() != \a info.size() && \a this->isAllocated()
5021  */
5022 void DataArrayInt::setInfoAndChangeNbOfCompo(const std::vector<std::string>& info) throw(INTERP_KERNEL::Exception)
5023 {
5024   if(getNumberOfComponents()!=(int)info.size())
5025     {
5026       if(!isAllocated())
5027         _info_on_compo=info;
5028       else
5029         {
5030           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 !";
5031           throw INTERP_KERNEL::Exception(oss.str().c_str());
5032         }
5033     }
5034   else
5035     _info_on_compo=info;
5036 }
5037
5038 /*!
5039  * Returns the only one value in \a this, if and only if number of elements
5040  * (nb of tuples * nb of components) is equal to 1, and that \a this is allocated.
5041  *  \return double - the sole value stored in \a this array.
5042  *  \throw If at least one of conditions stated above is not fulfilled.
5043  */
5044 int DataArrayInt::intValue() const throw(INTERP_KERNEL::Exception)
5045 {
5046   if(isAllocated())
5047     {
5048       if(getNbOfElems()==1)
5049         {
5050           return *getConstPointer();
5051         }
5052       else
5053         throw INTERP_KERNEL::Exception("DataArrayInt::intValue : DataArrayInt instance is allocated but number of elements is not equal to 1 !");
5054     }
5055   else
5056     throw INTERP_KERNEL::Exception("DataArrayInt::intValue : DataArrayInt instance is not allocated !");
5057 }
5058
5059 /*!
5060  * Returns an integer value characterizing \a this array, which is useful for a quick
5061  * comparison of many instances of DataArrayInt.
5062  *  \return int - the hash value.
5063  *  \throw If \a this is not allocated.
5064  */
5065 int DataArrayInt::getHashCode() const throw(INTERP_KERNEL::Exception)
5066 {
5067   checkAllocated();
5068   int nbOfElems=getNbOfElems();
5069   int ret=nbOfElems*65536;
5070   int delta=3;
5071   if(nbOfElems>48)
5072     delta=nbOfElems/8;
5073   int ret0=0;
5074   const int *pt=begin();
5075   for(int i=0;i<nbOfElems;i+=delta)
5076     ret0+=pt[i] & 0x1FFF;
5077   return ret+ret0;
5078 }
5079
5080 /*!
5081  * Checks the number of tuples.
5082  *  \return bool - \a true if getNumberOfTuples() == 0, \a false else.
5083  *  \throw If \a this is not allocated.
5084  */
5085 bool DataArrayInt::empty() const throw(INTERP_KERNEL::Exception)
5086 {
5087   checkAllocated();
5088   return getNumberOfTuples()==0;
5089 }
5090
5091 /*!
5092  * Returns a full copy of \a this. For more info on copying data arrays see
5093  * \ref MEDCouplingArrayBasicsCopyDeep.
5094  *  \return DataArrayInt * - a new instance of DataArrayInt.
5095  */
5096 DataArrayInt *DataArrayInt::deepCpy() const throw(INTERP_KERNEL::Exception)
5097 {
5098   return new DataArrayInt(*this);
5099 }
5100
5101 /*!
5102  * Returns either a \a deep or \a shallow copy of this array. For more info see
5103  * \ref MEDCouplingArrayBasicsCopyDeep and \ref MEDCouplingArrayBasicsCopyShallow.
5104  *  \param [in] dCpy - if \a true, a deep copy is returned, else, a shallow one.
5105  *  \return DataArrayInt * - either a new instance of DataArrayInt (if \a dCpy
5106  *          == \a true) or \a this instance (if \a dCpy == \a false).
5107  */
5108 DataArrayInt *DataArrayInt::performCpy(bool dCpy) const throw(INTERP_KERNEL::Exception)
5109 {
5110   if(dCpy)
5111     return deepCpy();
5112   else
5113     {
5114       incrRef();
5115       return const_cast<DataArrayInt *>(this);
5116     }
5117 }
5118
5119 /*!
5120  * Copies all the data from another DataArrayInt. For more info see
5121  * \ref MEDCouplingArrayBasicsCopyDeepAssign.
5122  *  \param [in] other - another instance of DataArrayInt to copy data from.
5123  *  \throw If the \a other is not allocated.
5124  */
5125 void DataArrayInt::cpyFrom(const DataArrayInt& other) throw(INTERP_KERNEL::Exception)
5126 {
5127   other.checkAllocated();
5128   int nbOfTuples=other.getNumberOfTuples();
5129   int nbOfComp=other.getNumberOfComponents();
5130   allocIfNecessary(nbOfTuples,nbOfComp);
5131   int nbOfElems=nbOfTuples*nbOfComp;
5132   int *pt=getPointer();
5133   const int *ptI=other.getConstPointer();
5134   for(int i=0;i<nbOfElems;i++)
5135     pt[i]=ptI[i];
5136   copyStringInfoFrom(other);
5137 }
5138
5139 /*!
5140  * This method reserve nbOfElems elements in memory ( nbOfElems*4 bytes ) \b without impacting the number of tuples in \a this.
5141  * 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.
5142  * If \a this has not already been allocated, number of components is set to one.
5143  * This method allows to reduce number of reallocations on invokation of DataArrayInt::pushBackSilent and DataArrayInt::pushBackValsSilent on \a this.
5144  * 
5145  * \sa DataArrayInt::pack, DataArrayInt::pushBackSilent, DataArrayInt::pushBackValsSilent
5146  */
5147 void DataArrayInt::reserve(int nbOfElems) throw(INTERP_KERNEL::Exception)
5148 {
5149   int nbCompo=getNumberOfComponents();
5150   if(nbCompo==1)
5151     {
5152       _mem.reserve(nbOfElems);
5153     }
5154   else if(nbCompo==0)
5155     {
5156       _mem.reserve(nbOfElems);
5157       _info_on_compo.resize(1);
5158     }
5159   else
5160     throw INTERP_KERNEL::Exception("DataArrayInt::reserve : not available for DataArrayInt with number of components different than 1 !");
5161 }
5162
5163 /*!
5164  * 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
5165  * of counter. So the caller is expected to call TimeLabel::declareAsNew on \a this at the end of the push session.
5166  *
5167  * \param [in] val the value to be added in \a this
5168  * \throw If \a this has already been allocated with number of components different from one.
5169  * \sa DataArrayInt::pushBackValsSilent
5170  */
5171 void DataArrayInt::pushBackSilent(int val) throw(INTERP_KERNEL::Exception)
5172 {
5173   int nbCompo=getNumberOfComponents();
5174   if(nbCompo==1)
5175     _mem.pushBack(val);
5176   else if(nbCompo==0)
5177     {
5178       _info_on_compo.resize(1);
5179       _mem.pushBack(val);
5180     }
5181   else
5182     throw INTERP_KERNEL::Exception("DataArrayInt::pushBackSilent : not available for DataArrayInt with number of components different than 1 !");
5183 }
5184
5185 /*!
5186  * 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
5187  * of counter. So the caller is expected to call TimeLabel::declareAsNew on \a this at the end of the push session.
5188  *
5189  *  \param [in] valsBg - an array of values to push at the end of \this.
5190  *  \param [in] valsEnd - specifies the end of the array \a valsBg, so that
5191  *              the last value of \a valsBg is \a valsEnd[ -1 ].
5192  * \throw If \a this has already been allocated with number of components different from one.
5193  * \sa DataArrayInt::pushBackSilent
5194  */
5195 void DataArrayInt::pushBackValsSilent(const int *valsBg, const int *valsEnd) throw(INTERP_KERNEL::Exception)
5196 {
5197   int nbCompo=getNumberOfComponents();
5198   if(nbCompo==1)
5199     _mem.insertAtTheEnd(valsBg,valsEnd);
5200   else if(nbCompo==0)
5201     {
5202       _info_on_compo.resize(1);
5203       _mem.insertAtTheEnd(valsBg,valsEnd);
5204     }
5205   else
5206     throw INTERP_KERNEL::Exception("DataArrayInt::pushBackValsSilent : not available for DataArrayInt with number of components different than 1 !");
5207 }
5208
5209 /*!
5210  * This method returns silently ( without updating time label in \a this ) the last value, if any and suppress it.
5211  * \throw If \a this is already empty.
5212  * \throw If \a this has number of components different from one.
5213  */
5214 int DataArrayInt::popBackSilent() throw(INTERP_KERNEL::Exception)
5215 {
5216   if(getNumberOfComponents()==1)
5217     return _mem.popBack();
5218   else
5219     throw INTERP_KERNEL::Exception("DataArrayInt::popBackSilent : not available for DataArrayInt with number of components different than 1 !");
5220 }
5221
5222 /*!
5223  * 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.
5224  *
5225  * \sa DataArrayInt::getHeapMemorySize, DataArrayInt::reserve
5226  */
5227 void DataArrayInt::pack() const throw(INTERP_KERNEL::Exception)
5228 {
5229   _mem.pack();
5230 }
5231
5232 /*!
5233  * Allocates the raw data in memory. If exactly as same memory as needed already
5234  * allocated, it is not re-allocated.
5235  *  \param [in] nbOfTuple - number of tuples of data to allocate.
5236  *  \param [in] nbOfCompo - number of components of data to allocate.
5237  *  \throw If \a nbOfTuple < 0 or \a nbOfCompo < 0.
5238  */
5239 void DataArrayInt::allocIfNecessary(int nbOfTuple, int nbOfCompo) throw(INTERP_KERNEL::Exception)
5240 {
5241   if(isAllocated())
5242     {
5243       if(nbOfTuple!=getNumberOfTuples() || nbOfCompo!=getNumberOfComponents())
5244         alloc(nbOfTuple,nbOfCompo);
5245     }
5246   else
5247     alloc(nbOfTuple,nbOfCompo);
5248 }
5249
5250 /*!
5251  * Allocates the raw data in memory. If the memory was already allocated, then it is
5252  * freed and re-allocated. See an example of this method use
5253  * \ref MEDCouplingArraySteps1WC "here".
5254  *  \param [in] nbOfTuple - number of tuples of data to allocate.
5255  *  \param [in] nbOfCompo - number of components of data to allocate.
5256  *  \throw If \a nbOfTuple < 0 or \a nbOfCompo < 0.
5257  */
5258 void DataArrayInt::alloc(int nbOfTuple, int nbOfCompo) throw(INTERP_KERNEL::Exception)
5259 {
5260   if(nbOfTuple<0 || nbOfCompo<0)
5261     throw INTERP_KERNEL::Exception("DataArrayInt::alloc : request for negative length of data !");
5262   _info_on_compo.resize(nbOfCompo);
5263   _mem.alloc(nbOfCompo*nbOfTuple);
5264   declareAsNew();
5265 }
5266
5267 /*!
5268  * Assign zero to all values in \a this array. To know more on filling arrays see
5269  * \ref MEDCouplingArrayFill.
5270  * \throw If \a this is not allocated.
5271  */
5272 void DataArrayInt::fillWithZero() throw(INTERP_KERNEL::Exception)
5273 {
5274   checkAllocated();
5275   _mem.fillWithValue(0);
5276   declareAsNew();
5277 }
5278
5279 /*!
5280  * Assign \a val to all values in \a this array. To know more on filling arrays see
5281  * \ref MEDCouplingArrayFill.
5282  *  \param [in] val - the value to fill with.
5283  *  \throw If \a this is not allocated.
5284  */
5285 void DataArrayInt::fillWithValue(int val) throw(INTERP_KERNEL::Exception)
5286 {
5287   checkAllocated();
5288   _mem.fillWithValue(val);
5289   declareAsNew();
5290 }
5291
5292 /*!
5293  * Set all values in \a this array so that the i-th element equals to \a init + i
5294  * (i starts from zero). To know more on filling arrays see \ref MEDCouplingArrayFill.
5295  *  \param [in] init - value to assign to the first element of array.
5296  *  \throw If \a this->getNumberOfComponents() != 1
5297  *  \throw If \a this is not allocated.
5298  */
5299 void DataArrayInt::iota(int init) throw(INTERP_KERNEL::Exception)
5300 {
5301   checkAllocated();
5302   if(getNumberOfComponents()!=1)
5303     throw INTERP_KERNEL::Exception("DataArrayInt::iota : works only for arrays with only one component, you can call 'rearrange' method before !");
5304   int *ptr=getPointer();
5305   int ntuples=getNumberOfTuples();
5306   for(int i=0;i<ntuples;i++)
5307     ptr[i]=init+i;
5308   declareAsNew();
5309 }
5310
5311 /*!
5312  * Returns a textual and human readable representation of \a this instance of
5313  * DataArrayInt. This text is shown when a DataArrayInt is printed in Python.
5314  *  \return std::string - text describing \a this DataArrayInt.
5315  */
5316 std::string DataArrayInt::repr() const throw(INTERP_KERNEL::Exception)
5317 {
5318   std::ostringstream ret;
5319   reprStream(ret);
5320   return ret.str();
5321 }
5322
5323 std::string DataArrayInt::reprZip() const throw(INTERP_KERNEL::Exception)
5324 {
5325   std::ostringstream ret;
5326   reprZipStream(ret);
5327   return ret.str();
5328 }
5329
5330 void DataArrayInt::writeVTK(std::ostream& ofs, int indent, const char *type, const char *nameInFile) const throw(INTERP_KERNEL::Exception)
5331 {
5332   checkAllocated();
5333   std::string idt(indent,' ');
5334   ofs << idt << "<DataArray type=\"" << type << "\" Name=\"" << nameInFile << "\" NumberOfComponents=\"" << getNumberOfComponents() << "\"";
5335   ofs << " format=\"ascii\" RangeMin=\"" << getMinValueInArray() << "\" RangeMax=\"" << getMaxValueInArray() << "\">\n" << idt;
5336   std::copy(begin(),end(),std::ostream_iterator<int>(ofs," "));
5337   ofs << std::endl << idt << "</DataArray>\n";
5338 }
5339
5340 void DataArrayInt::reprStream(std::ostream& stream) const throw(INTERP_KERNEL::Exception)
5341 {
5342   stream << "Name of int array : \"" << _name << "\"\n";
5343   reprWithoutNameStream(stream);
5344 }
5345
5346 void DataArrayInt::reprZipStream(std::ostream& stream) const throw(INTERP_KERNEL::Exception)
5347 {
5348   stream << "Name of int array : \"" << _name << "\"\n";
5349   reprZipWithoutNameStream(stream);
5350 }
5351
5352 void DataArrayInt::reprWithoutNameStream(std::ostream& stream) const throw(INTERP_KERNEL::Exception)
5353 {
5354   DataArray::reprWithoutNameStream(stream);
5355   _mem.repr(getNumberOfComponents(),stream);
5356 }
5357
5358 void DataArrayInt::reprZipWithoutNameStream(std::ostream& stream) const throw(INTERP_KERNEL::Exception)
5359 {
5360   DataArray::reprWithoutNameStream(stream);
5361   _mem.reprZip(getNumberOfComponents(),stream);
5362 }
5363
5364 void DataArrayInt::reprCppStream(const char *varName, std::ostream& stream) const throw(INTERP_KERNEL::Exception)
5365 {
5366   int nbTuples=getNumberOfTuples(),nbComp=getNumberOfComponents();
5367   const int *data=getConstPointer();
5368   stream << "DataArrayInt *" << varName << "=DataArrayInt::New();" << std::endl;
5369   if(nbTuples*nbComp>=1)
5370     {
5371       stream << "const int " << varName << "Data[" << nbTuples*nbComp << "]={";
5372       std::copy(data,data+nbTuples*nbComp-1,std::ostream_iterator<int>(stream,","));
5373       stream << data[nbTuples*nbComp-1] << "};" << std::endl;
5374       stream << varName << "->useArray(" << varName << "Data,false,CPP_DEALLOC," << nbTuples << "," << nbComp << ");" << std::endl;
5375     }
5376   else
5377     stream << varName << "->alloc(" << nbTuples << "," << nbComp << ");" << std::endl;
5378   stream << varName << "->setName(\"" << getName() << "\");" << std::endl;
5379 }
5380
5381 /*!
5382  * Modifies \a this one-dimensional array so that each value \a v = \a indArrBg[ \a v ],
5383  * i.e. a current value is used as in index to get a new value from \a indArrBg.
5384  *  \param [in] indArrBg - pointer to the first element of array of new values to assign
5385  *         to \a this array.
5386  *  \param [in] indArrEnd - specifies the end of the array \a indArrBg, so that
5387  *              the last value of \a indArrBg is \a indArrEnd[ -1 ].
5388  *  \throw If \a this->getNumberOfComponents() != 1
5389  *  \throw If any value of \a this can't be used as a valid index for 
5390  *         [\a indArrBg, \a indArrEnd).
5391  */
5392 void DataArrayInt::transformWithIndArr(const int *indArrBg, const int *indArrEnd) throw(INTERP_KERNEL::Exception)
5393 {
5394   checkAllocated();
5395   if(getNumberOfComponents()!=1)
5396     throw INTERP_KERNEL::Exception("Call transformWithIndArr method on DataArrayInt with only one component, you can call 'rearrange' method before !");
5397   int nbElemsIn=(int)std::distance(indArrBg,indArrEnd);
5398   int nbOfTuples=getNumberOfTuples();
5399   int *pt=getPointer();
5400   for(int i=0;i<nbOfTuples;i++,pt++)
5401     {
5402       if(*pt>=0 && *pt<nbElemsIn)
5403         *pt=indArrBg[*pt];
5404       else
5405         {
5406           std::ostringstream oss; oss << "DataArrayInt::transformWithIndArr : error on tuple #" << i << " value is " << *pt << " and indirectionnal array as a size equal to " << nbElemsIn;
5407           throw INTERP_KERNEL::Exception(oss.str().c_str());
5408         }
5409     }
5410   declareAsNew();
5411 }
5412
5413 /*!
5414  * Computes distribution of values of \a this one-dimensional array between given value
5415  * ranges (casts). This method is typically useful for entity number spliting by types,
5416  * for example. 
5417  *  \param [in] arrBg - the array of ascending values defining the value ranges. The i-th
5418  *         value of \a arrBg (\a arrBg[ i ]) gives the lowest value of the i-th range,
5419  *         and the greatest value of the i-th range equals to \a arrBg[ i+1 ] - 1. \a
5420  *         arrBg containing \a n values defines \a n-1 ranges. The last value of \a arrBg
5421  *         should be more than every value in \a this array.
5422  *  \param [in] arrEnd - specifies the end of the array \a arrBg, so that
5423  *              the last value of \a arrBg is \a arrEnd[ -1 ].
5424  *  \param [out] castArr - a new instance of DataArrayInt, of same size as \a this array
5425  *         (same number of tuples and components), the caller is to delete 
5426  *         using decrRef() as it is no more needed.
5427  *         This array contains indices of ranges for every value of \a this array. I.e.
5428  *         the i-th value of \a castArr gives the index of range the i-th value of \a this
5429  *         belongs to. Or, in other words, this parameter contains for each tuple in \a
5430  *         this in which cast it holds.
5431  *  \param [out] rankInsideCast - a new instance of DataArrayInt, of same size as \a this
5432  *         array, the caller is to delete using decrRef() as it is no more needed.
5433  *         This array contains ranks of values of \a this array within ranges
5434  *         they belongs to. I.e. the i-th value of \a rankInsideCast gives the rank of
5435  *         the i-th value of \a this array within the \a castArr[ i ]-th range, to which
5436  *         the i-th value of \a this belongs to. Or, in other words, this param contains 
5437  *         for each tuple its rank inside its cast. The rank is computed as difference
5438  *         between the value and the lowest value of range.
5439  *  \param [out] castsPresent - a new instance of DataArrayInt, containing indices of
5440  *         ranges (casts) to which at least one value of \a this array belongs.
5441  *         Or, in other words, this param contains the casts that \a this contains.
5442  *         The caller is to delete this array using decrRef() as it is no more needed.
5443  *
5444  * \b Example: If \a this contains [6,5,0,3,2,7,8,1,4] and \a arrBg contains [0,4,9] then
5445  *            the output of this method will be : 
5446  * - \a castArr       : [1,1,0,0,0,1,1,0,1]
5447  * - \a rankInsideCast: [2,1,0,3,2,3,4,1,0]
5448  * - \a castsPresent  : [0,1]
5449  *
5450  * I.e. values of \a this array belong to 2 ranges: #0 and #1. Value 6 belongs to the
5451  * range #1 and its rank within this range is 2; etc.
5452  *
5453  *  \throw If \a this->getNumberOfComponents() != 1.
5454  *  \throw If \a arrEnd - arrBg < 2.
5455  *  \throw If any value of \a this is not less than \a arrEnd[-1].
5456  *  \warning The values contained in \a arrBg should be sorted ascendently. No
5457  *           check of this is be done. If not, the result is not warranted. 
5458  * 
5459  */
5460 void DataArrayInt::splitByValueRange(const int *arrBg, const int *arrEnd,
5461                                      DataArrayInt *& castArr, DataArrayInt *& rankInsideCast, DataArrayInt *& castsPresent) const throw(INTERP_KERNEL::Exception)
5462 {
5463   checkAllocated();
5464   if(getNumberOfComponents()!=1)
5465     throw INTERP_KERNEL::Exception("Call splitByValueRange  method on DataArrayInt with only one component, you can call 'rearrange' method before !");
5466   int nbOfTuples=getNumberOfTuples();
5467   std::size_t nbOfCast=std::distance(arrBg,arrEnd);
5468   if(nbOfCast<2)
5469     throw INTERP_KERNEL::Exception("DataArrayInt::splitByValueRange : The input array giving the cast range values should be of size >=2 !");
5470   nbOfCast--;
5471   const int *work=getConstPointer();
5472   typedef std::reverse_iterator<const int *> rintstart;
5473   rintstart bg(arrEnd);//OK no problem because size of 'arr' is greater or equal 2
5474   rintstart end2(arrBg);
5475   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret1=DataArrayInt::New();
5476   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret2=DataArrayInt::New();
5477   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret3=DataArrayInt::New();
5478   ret1->alloc(nbOfTuples,1);
5479   ret2->alloc(nbOfTuples,1);
5480   int *ret1Ptr=ret1->getPointer();
5481   int *ret2Ptr=ret2->getPointer();
5482   std::set<std::size_t> castsDetected;
5483   for(int i=0;i<nbOfTuples;i++)
5484     {
5485       rintstart res=std::find_if(bg,end2,std::bind2nd(std::less_equal<int>(), work[i]));
5486       std::size_t pos=std::distance(bg,res);
5487       std::size_t pos2=nbOfCast-pos;
5488       if(pos2<nbOfCast)
5489         {
5490           ret1Ptr[i]=(int)pos2;
5491           ret2Ptr[i]=work[i]-arrBg[pos2];
5492           castsDetected.insert(pos2);
5493         }
5494       else
5495         {
5496           std::ostringstream oss; oss << "DataArrayInt::splitByValueRange : At rank #" << i << " the value is " << work[i] << " whereas the last value is " << *bg;
5497           throw INTERP_KERNEL::Exception(oss.str().c_str());
5498         }
5499     }
5500   ret3->alloc((int)castsDetected.size(),1);
5501   std::copy(castsDetected.begin(),castsDetected.end(),ret3->getPointer());
5502   castArr=ret1.retn();
5503   rankInsideCast=ret2.retn();
5504   castsPresent=ret3.retn();
5505 }
5506
5507 /*!
5508  * Creates a one-dimensional DataArrayInt (\a res) whose contents are computed from 
5509  * values of \a this (\a a) and the given (\a indArr) arrays as follows:
5510  * \a res[ \a indArr[ \a a[ i ]]] = i. I.e. for each value in place i \a v = \a a[ i ],
5511  * new value in place \a indArr[ \a v ] is i.
5512  *  \param [in] indArrBg - the array holding indices within the result array to assign
5513  *         indices of values of \a this array pointing to values of \a indArrBg.
5514  *  \param [in] indArrEnd - specifies the end of the array \a indArrBg, so that
5515  *              the last value of \a indArrBg is \a indArrEnd[ -1 ].
5516  *  \return DataArrayInt * - the new instance of DataArrayInt.
5517  *          The caller is to delete this result array using decrRef() as it is no more
5518  *          needed.
5519  *  \throw If \a this->getNumberOfComponents() != 1.
5520  *  \throw If any value of \a this array is not a valid index for \a indArrBg array.
5521  *  \throw If any value of \a indArrBg is not a valid index for \a this array.
5522  */
5523 DataArrayInt *DataArrayInt::transformWithIndArrR(const int *indArrBg, const int *indArrEnd) const throw(INTERP_KERNEL::Exception)
5524 {
5525   checkAllocated();
5526   if(getNumberOfComponents()!=1)
5527     throw INTERP_KERNEL::Exception("Call transformWithIndArrR method on DataArrayInt with only one component, you can call 'rearrange' method before !");
5528   int nbElemsIn=(int)std::distance(indArrBg,indArrEnd);
5529   int nbOfTuples=getNumberOfTuples();
5530   const int *pt=getConstPointer();
5531   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
5532   ret->alloc(nbOfTuples,1);
5533   ret->fillWithValue(-1);
5534   int *tmp=ret->getPointer();
5535   for(int i=0;i<nbOfTuples;i++,pt++)
5536     {
5537       if(*pt>=0 && *pt<nbElemsIn)
5538         {
5539           int pos=indArrBg[*pt];
5540           if(pos>=0 && pos<nbOfTuples)
5541             tmp[pos]=i;
5542           else
5543             {
5544               std::ostringstream oss; oss << "DataArrayInt::transformWithIndArrR : error on tuple #" << i << " value of new pos is " << pos << " ( indArrBg[" << *pt << "]) ! Should be in [0," << nbOfTuples << ") !";
5545               throw INTERP_KERNEL::Exception(oss.str().c_str());
5546             }
5547         }
5548       else
5549         {
5550           std::ostringstream oss; oss << "DataArrayInt::transformWithIndArrR : error on tuple #" << i << " value is " << *pt << " and indirectionnal array as a size equal to " << nbElemsIn << " !";
5551           throw INTERP_KERNEL::Exception(oss.str().c_str());
5552         }
5553     }
5554   return ret.retn();
5555 }
5556
5557 /*!
5558  * Creates a one-dimensional DataArrayInt of given length, whose contents are computed
5559  * from values of \a this array, which is supposed to contain a renumbering map in 
5560  * "Old to New" mode. The result array contains a renumbering map in "New to Old" mode.
5561  * To know how to use the renumbering maps see \ref MEDCouplingArrayRenumbering.
5562  *  \param [in] newNbOfElem - the number of tuples in the result array.
5563  *  \return DataArrayInt * - the new instance of DataArrayInt.
5564  *          The caller is to delete this result array using decrRef() as it is no more
5565  *          needed.
5566  * 
5567  *  \ref cpp_mcdataarrayint_invertarrayo2n2n2o "Here is a C++ example".<br>
5568  *  \ref py_mcdataarrayint_invertarrayo2n2n2o  "Here is a Python example".
5569  */
5570 DataArrayInt *DataArrayInt::invertArrayO2N2N2O(int newNbOfElem) const
5571 {
5572   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
5573   ret->alloc(newNbOfElem,1);
5574   int nbOfOldNodes=getNumberOfTuples();
5575   const int *old2New=getConstPointer();
5576   int *pt=ret->getPointer();
5577   for(int i=0;i!=nbOfOldNodes;i++)
5578     if(old2New[i]!=-1)
5579       pt[old2New[i]]=i;
5580   return ret.retn();
5581 }
5582
5583 /*!
5584  * This method is similar to DataArrayInt::invertArrayO2N2N2O except that 
5585  * 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]
5586  */
5587 DataArrayInt *DataArrayInt::invertArrayO2N2N2OBis(int newNbOfElem) const throw(INTERP_KERNEL::Exception)
5588 {
5589   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
5590   ret->alloc(newNbOfElem,1);
5591   int nbOfOldNodes=getNumberOfTuples();
5592   const int *old2New=getConstPointer();
5593   int *pt=ret->getPointer();
5594   for(int i=nbOfOldNodes-1;i>=0;i--)
5595     if(old2New[i]!=-1)
5596       pt[old2New[i]]=i;
5597   return ret.retn();
5598 }
5599
5600 /*!
5601  * Creates a one-dimensional DataArrayInt of given length, whose contents are computed
5602  * from values of \a this array, which is supposed to contain a renumbering map in 
5603  * "New to Old" mode. The result array contains a renumbering map in "Old to New" mode.
5604  * To know how to use the renumbering maps see \ref MEDCouplingArrayRenumbering.
5605  *  \param [in] newNbOfElem - the number of tuples in the result array.
5606  *  \return DataArrayInt * - the new instance of DataArrayInt.
5607  *          The caller is to delete this result array using decrRef() as it is no more
5608  *          needed.
5609  * 
5610  *  \ref cpp_mcdataarrayint_invertarrayn2o2o2n "Here is a C++ example".
5611  *
5612  *  \ref py_mcdataarrayint_invertarrayn2o2o2n "Here is a Python example".
5613  */
5614 DataArrayInt *DataArrayInt::invertArrayN2O2O2N(int oldNbOfElem) const
5615 {
5616   checkAllocated();
5617   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
5618   ret->alloc(oldNbOfElem,1);
5619   const int *new2Old=getConstPointer();
5620   int *pt=ret->getPointer();
5621   std::fill(pt,pt+oldNbOfElem,-1);
5622   int nbOfNewElems=getNumberOfTuples();
5623   for(int i=0;i<nbOfNewElems;i++)
5624     pt[new2Old[i]]=i;
5625   return ret.retn();
5626 }
5627
5628 /*!
5629  * Equivalent to DataArrayInt::isEqual except that if false the reason of
5630  * mismatch is given.
5631  * 
5632  * \param [in] other the instance to be compared with \a this
5633  * \param [out] reason In case of inequality returns the reason.
5634  * \sa DataArrayInt::isEqual
5635  */
5636 bool DataArrayInt::isEqualIfNotWhy(const DataArrayInt& other, std::string& reason) const throw(INTERP_KERNEL::Exception)
5637 {
5638   if(!areInfoEqualsIfNotWhy(other,reason))
5639     return false;
5640   return _mem.isEqual(other._mem,0,reason);
5641 }
5642
5643 /*!
5644  * Checks if \a this and another DataArrayInt are fully equal. For more info see
5645  * \ref MEDCouplingArrayBasicsCompare.
5646  *  \param [in] other - an instance of DataArrayInt to compare with \a this one.
5647  *  \return bool - \a true if the two arrays are equal, \a false else.
5648  */
5649 bool DataArrayInt::isEqual(const DataArrayInt& other) const throw(INTERP_KERNEL::Exception)
5650 {
5651   std::string tmp;
5652   return isEqualIfNotWhy(other,tmp);
5653 }
5654
5655 /*!
5656  * Checks if values of \a this and another DataArrayInt are equal. For more info see
5657  * \ref MEDCouplingArrayBasicsCompare.
5658  *  \param [in] other - an instance of DataArrayInt to compare with \a this one.
5659  *  \return bool - \a true if the values of two arrays are equal, \a false else.
5660  */
5661 bool DataArrayInt::isEqualWithoutConsideringStr(const DataArrayInt& other) const throw(INTERP_KERNEL::Exception)
5662 {
5663   std::string tmp;
5664   return _mem.isEqual(other._mem,0,tmp);
5665 }
5666
5667 /*!
5668  * Checks if values of \a this and another DataArrayInt are equal. Comparison is
5669  * performed on sorted value sequences.
5670  * For more info see\ref MEDCouplingArrayBasicsCompare.
5671  *  \param [in] other - an instance of DataArrayInt to compare with \a this one.
5672  *  \return bool - \a true if the sorted values of two arrays are equal, \a false else.
5673  */
5674 bool DataArrayInt::isEqualWithoutConsideringStrAndOrder(const DataArrayInt& other) const throw(INTERP_KERNEL::Exception)
5675 {
5676   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> a=deepCpy();
5677   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> b=other.deepCpy();
5678   a->sort();
5679   b->sort();
5680   return a->isEqualWithoutConsideringStr(*b);
5681 }
5682
5683 /*!
5684  * Sorts values of the array.
5685  *  \param [in] asc - \a true means ascending order, \a false, descending.
5686  *  \throw If \a this is not allocated.
5687  *  \throw If \a this->getNumberOfComponents() != 1.
5688  */
5689 void DataArrayInt::sort(bool asc) throw(INTERP_KERNEL::Exception)
5690 {
5691   checkAllocated();
5692   if(getNumberOfComponents()!=1)
5693     throw INTERP_KERNEL::Exception("DataArrayInt::sort : only supported with 'this' array with ONE component !");
5694   _mem.sort(asc);
5695 }
5696
5697 /*!
5698  * Reverse the array values.
5699  *  \throw If \a this->getNumberOfComponents() != 1.
5700  *  \throw If \a this is not allocated.
5701  */
5702 void DataArrayInt::reverse() throw(INTERP_KERNEL::Exception)
5703 {
5704   checkAllocated();
5705   if(getNumberOfComponents()!=1)
5706     throw INTERP_KERNEL::Exception("DataArrayInt::reverse : only supported with 'this' array with ONE component !");
5707   _mem.reverse();
5708 }
5709
5710 /*!
5711  * Checks that \a this array is consistently **increasing** or **decreasing** in value.
5712  * If not an exception is thrown.
5713  *  \param [in] increasing - if \a true, the array values should be increasing.
5714  *  \throw If sequence of values is not strictly monotonic in agreement with \a
5715  *         increasing arg.
5716  *  \throw If \a this->getNumberOfComponents() != 1.
5717  *  \throw If \a this is not allocated.
5718  */
5719 void DataArrayInt::checkMonotonic(bool increasing) const throw(INTERP_KERNEL::Exception)
5720 {
5721   if(!isMonotonic(increasing))
5722     {
5723       if (increasing)
5724         throw INTERP_KERNEL::Exception("DataArrayInt::checkMonotonic : 'this' is not INCREASING monotonic !");
5725       else
5726         throw INTERP_KERNEL::Exception("DataArrayInt::checkMonotonic : 'this' is not DECREASING monotonic !");
5727     }
5728 }
5729
5730 /*!
5731  * Checks that \a this array is consistently **increasing** or **decreasing** in value.
5732  *  \param [in] increasing - if \a true, array values should be increasing.
5733  *  \return bool - \a true if values change in accordance with \a increasing arg.
5734  *  \throw If \a this->getNumberOfComponents() != 1.
5735  *  \throw If \a this is not allocated.
5736  */
5737 bool DataArrayInt::isMonotonic(bool increasing) const throw(INTERP_KERNEL::Exception)
5738 {
5739   checkAllocated();
5740   if(getNumberOfComponents()!=1)
5741     throw INTERP_KERNEL::Exception("DataArrayInt::isMonotonic : only supported with 'this' array with ONE component !");
5742   int nbOfElements=getNumberOfTuples();
5743   const int *ptr=getConstPointer();
5744   if(nbOfElements==0)
5745     return true;
5746   int ref=ptr[0];
5747   if(increasing)
5748     {
5749       for(int i=1;i<nbOfElements;i++)
5750         {
5751           if(ptr[i]>=ref)
5752             ref=ptr[i];
5753           else
5754             return false;
5755         }
5756     }
5757   else
5758     {
5759       for(int i=1;i<nbOfElements;i++)
5760         {
5761           if(ptr[i]<=ref)
5762             ref=ptr[i];
5763           else
5764             return false;
5765         }
5766     }
5767   return true;
5768 }
5769
5770 /*!
5771  * This method check that array consistently INCREASING or DECREASING in value.
5772  */
5773 bool DataArrayInt::isStrictlyMonotonic(bool increasing) const throw(INTERP_KERNEL::Exception)
5774 {
5775   checkAllocated();
5776   if(getNumberOfComponents()!=1)
5777     throw INTERP_KERNEL::Exception("DataArrayInt::isStrictlyMonotonic : only supported with 'this' array with ONE component !");
5778   int nbOfElements=getNumberOfTuples();
5779   const int *ptr=getConstPointer();
5780   if(nbOfElements==0)
5781     return true;
5782   int ref=ptr[0];
5783   if(increasing)
5784     {
5785       for(int i=1;i<nbOfElements;i++)
5786         {
5787           if(ptr[i]>ref)
5788             ref=ptr[i];
5789           else
5790             return false;
5791         }
5792     }
5793   else
5794     {
5795       for(int i=1;i<nbOfElements;i++)
5796         {
5797           if(ptr[i]<ref)
5798             ref=ptr[i];
5799           else
5800             return false;
5801         }
5802     }
5803   return true;
5804 }
5805
5806 /*!
5807  * This method check that array consistently INCREASING or DECREASING in value.
5808  */
5809 void DataArrayInt::checkStrictlyMonotonic(bool increasing) const throw(INTERP_KERNEL::Exception)
5810 {
5811   if(!isStrictlyMonotonic(increasing))
5812     {
5813       if (increasing)
5814         throw INTERP_KERNEL::Exception("DataArrayInt::checkStrictlyMonotonic : 'this' is not strictly INCREASING monotonic !");
5815       else
5816         throw INTERP_KERNEL::Exception("DataArrayInt::checkStrictlyMonotonic : 'this' is not strictly DECREASING monotonic !");
5817     }
5818 }
5819
5820 /*!
5821  * Creates a new one-dimensional DataArrayInt of the same size as \a this and a given
5822  * one-dimensional arrays that must be of the same length. The result array describes
5823  * correspondence between \a this and \a other arrays, so that 
5824  * <em> other.getIJ(i,0) == this->getIJ(ret->getIJ(i),0)</em>. If such a permutation is
5825  * not possible because some element in \a other is not in \a this, an exception is thrown.
5826  *  \param [in] other - an array to compute permutation to.
5827  *  \return DataArrayInt * - a new instance of DataArrayInt, which is a permutation array
5828  * from \a this to \a other. The caller is to delete this array using decrRef() as it is
5829  * no more needed.
5830  *  \throw If \a this->getNumberOfComponents() != 1.
5831  *  \throw If \a other->getNumberOfComponents() != 1.
5832  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples().
5833  *  \throw If \a other includes a value which is not in \a this array.
5834  * 
5835  *  \ref cpp_mcdataarrayint_buildpermutationarr "Here is a C++ example".
5836  *
5837  *  \ref py_mcdataarrayint_buildpermutationarr "Here is a Python example".
5838  */
5839 DataArrayInt *DataArrayInt::buildPermutationArr(const DataArrayInt& other) const throw(INTERP_KERNEL::Exception)
5840 {
5841   checkAllocated();
5842   if(getNumberOfComponents()!=1 || other.getNumberOfComponents()!=1)
5843     throw INTERP_KERNEL::Exception("DataArrayInt::buildPermutationArr : 'this' and 'other' have to have exactly ONE component !");
5844   int nbTuple=getNumberOfTuples();
5845   other.checkAllocated();
5846   if(nbTuple!=other.getNumberOfTuples())
5847     throw INTERP_KERNEL::Exception("DataArrayInt::buildPermutationArr : 'this' and 'other' must have the same number of tuple !");
5848   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
5849   ret->alloc(nbTuple,1);
5850   ret->fillWithValue(-1);
5851   const int *pt=getConstPointer();
5852   std::map<int,int> mm;
5853   for(int i=0;i<nbTuple;i++)
5854     mm[pt[i]]=i;
5855   pt=other.getConstPointer();
5856   int *retToFill=ret->getPointer();
5857   for(int i=0;i<nbTuple;i++)
5858     {
5859       std::map<int,int>::const_iterator it=mm.find(pt[i]);
5860       if(it==mm.end())
5861         {
5862           std::ostringstream oss; oss << "DataArrayInt::buildPermutationArr : Arrays mismatch : element (" << pt[i] << ") in 'other' not findable in 'this' !";
5863           throw INTERP_KERNEL::Exception(oss.str().c_str());
5864         }
5865       retToFill[i]=(*it).second;
5866     }
5867   return ret.retn();
5868 }
5869
5870 /*!
5871  * Sets a C array to be used as raw data of \a this. The previously set info
5872  *  of components is retained and re-sized. 
5873  * For more info see \ref MEDCouplingArraySteps1.
5874  *  \param [in] array - the C array to be used as raw data of \a this.
5875  *  \param [in] ownership - if \a true, \a array will be deallocated at destruction of \a this.
5876  *  \param [in] type - specifies how to deallocate \a array. If \a type == ParaMEDMEM::CPP_DEALLOC,
5877  *                     \c delete [] \c array; will be called. If \a type == ParaMEDMEM::C_DEALLOC,
5878  *                     \c free(\c array ) will be called.
5879  *  \param [in] nbOfTuple - new number of tuples in \a this.
5880  *  \param [in] nbOfCompo - new number of components in \a this.
5881  */
5882 void DataArrayInt::useArray(const int *array, bool ownership,  DeallocType type, int nbOfTuple, int nbOfCompo) throw(INTERP_KERNEL::Exception)
5883 {
5884   _info_on_compo.resize(nbOfCompo);
5885   _mem.useArray(array,ownership,type,nbOfTuple*nbOfCompo);
5886   declareAsNew();
5887 }
5888
5889 void DataArrayInt::useExternalArrayWithRWAccess(const int *array, int nbOfTuple, int nbOfCompo) throw(INTERP_KERNEL::Exception)
5890 {
5891   _info_on_compo.resize(nbOfCompo);
5892   _mem.useExternalArrayWithRWAccess(array,nbOfTuple*nbOfCompo);
5893   declareAsNew();
5894 }
5895
5896 /*!
5897  * Returns a new DataArrayInt holding the same values as \a this array but differently
5898  * arranged in memory. If \a this array holds 2 components of 3 values:
5899  * \f$ x_0,x_1,x_2,y_0,y_1,y_2 \f$, then the result array holds these values arranged
5900  * as follows: \f$ x_0,y_0,x_1,y_1,x_2,y_2 \f$.
5901  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
5902  *          is to delete using decrRef() as it is no more needed.
5903  *  \throw If \a this is not allocated.
5904  *  \warning Do not confuse this method with transpose()!
5905  */
5906 DataArrayInt *DataArrayInt::fromNoInterlace() const throw(INTERP_KERNEL::Exception)
5907 {
5908   checkAllocated();
5909   if(_mem.isNull())
5910     throw INTERP_KERNEL::Exception("DataArrayInt::fromNoInterlace : Not defined array !");
5911   int *tab=_mem.fromNoInterlace(getNumberOfComponents());
5912   DataArrayInt *ret=DataArrayInt::New();
5913   ret->useArray(tab,true,CPP_DEALLOC,getNumberOfTuples(),getNumberOfComponents());
5914   return ret;
5915 }
5916
5917 /*!
5918  * Returns a new DataArrayInt holding the same values as \a this array but differently
5919  * arranged in memory. If \a this array holds 2 components of 3 values:
5920  * \f$ x_0,y_0,x_1,y_1,x_2,y_2 \f$, then the result array holds these values arranged
5921  * as follows: \f$ x_0,x_1,x_2,y_0,y_1,y_2 \f$.
5922  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
5923  *          is to delete using decrRef() as it is no more needed.
5924  *  \throw If \a this is not allocated.
5925  *  \warning Do not confuse this method with transpose()!
5926  */
5927 DataArrayInt *DataArrayInt::toNoInterlace() const throw(INTERP_KERNEL::Exception)
5928 {
5929   checkAllocated();
5930   if(_mem.isNull())
5931     throw INTERP_KERNEL::Exception("DataArrayInt::toNoInterlace : Not defined array !");
5932   int *tab=_mem.toNoInterlace(getNumberOfComponents());
5933   DataArrayInt *ret=DataArrayInt::New();
5934   ret->useArray(tab,true,CPP_DEALLOC,getNumberOfTuples(),getNumberOfComponents());
5935   return ret;
5936 }
5937
5938 /*!
5939  * Permutes values of \a this array as required by \a old2New array. The values are
5940  * permuted so that \c new[ \a old2New[ i ]] = \c old[ i ]. Number of tuples remains
5941  * the same as in \this one.
5942  * If a permutation reduction is needed, substr() or selectByTupleId() should be used.
5943  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
5944  *  \param [in] old2New - C array of length equal to \a this->getNumberOfTuples()
5945  *     giving a new position for i-th old value.
5946  */
5947 void DataArrayInt::renumberInPlace(const int *old2New) throw(INTERP_KERNEL::Exception)
5948 {
5949   checkAllocated();
5950   int nbTuples=getNumberOfTuples();
5951   int nbOfCompo=getNumberOfComponents();
5952   int *tmp=new int[nbTuples*nbOfCompo];
5953   const int *iptr=getConstPointer();
5954   for(int i=0;i<nbTuples;i++)
5955     std::copy(iptr+nbOfCompo*i,iptr+nbOfCompo*(i+1),tmp+nbOfCompo*old2New[i]);
5956   std::copy(tmp,tmp+nbTuples*nbOfCompo,getPointer());
5957   delete [] tmp;
5958   declareAsNew();
5959 }
5960
5961 /*!
5962  * Permutes values of \a this array as required by \a new2Old array. The values are
5963  * permuted so that \c new[ i ] = \c old[ \a new2Old[ i ]]. Number of tuples remains
5964  * the same as in \this one.
5965  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
5966  *  \param [in] new2Old - C array of length equal to \a this->getNumberOfTuples()
5967  *     giving a previous position of i-th new value.
5968  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
5969  *          is to delete using decrRef() as it is no more needed.
5970  */
5971 void DataArrayInt::renumberInPlaceR(const int *new2Old) throw(INTERP_KERNEL::Exception)
5972 {
5973   checkAllocated();
5974   int nbTuples=getNumberOfTuples();
5975   int nbOfCompo=getNumberOfComponents();
5976   int *tmp=new int[nbTuples*nbOfCompo];
5977   const int *iptr=getConstPointer();
5978   for(int i=0;i<nbTuples;i++)
5979     std::copy(iptr+nbOfCompo*new2Old[i],iptr+nbOfCompo*(new2Old[i]+1),tmp+nbOfCompo*i);
5980   std::copy(tmp,tmp+nbTuples*nbOfCompo,getPointer());
5981   delete [] tmp;
5982   declareAsNew();
5983 }
5984
5985 /*!
5986  * Returns a copy of \a this array with values permuted as required by \a old2New array.
5987  * The values are permuted so that  \c new[ \a old2New[ i ]] = \c old[ i ].
5988  * Number of tuples in the result array remains the same as in \this one.
5989  * If a permutation reduction is needed, renumberAndReduce() should be used.
5990  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
5991  *  \param [in] old2New - C array of length equal to \a this->getNumberOfTuples()
5992  *          giving a new position for i-th old value.
5993  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
5994  *          is to delete using decrRef() as it is no more needed.
5995  *  \throw If \a this is not allocated.
5996  */
5997 DataArrayInt *DataArrayInt::renumber(const int *old2New) const throw(INTERP_KERNEL::Exception)
5998 {
5999   checkAllocated();
6000   int nbTuples=getNumberOfTuples();
6001   int nbOfCompo=getNumberOfComponents();
6002   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6003   ret->alloc(nbTuples,nbOfCompo);
6004   ret->copyStringInfoFrom(*this);
6005   const int *iptr=getConstPointer();
6006   int *optr=ret->getPointer();
6007   for(int i=0;i<nbTuples;i++)
6008     std::copy(iptr+nbOfCompo*i,iptr+nbOfCompo*(i+1),optr+nbOfCompo*old2New[i]);
6009   ret->copyStringInfoFrom(*this);
6010   return ret.retn();
6011 }
6012
6013 /*!
6014  * Returns a copy of \a this array with values permuted as required by \a new2Old array.
6015  * The values are permuted so that  \c new[ i ] = \c old[ \a new2Old[ i ]]. Number of
6016  * tuples in the result array remains the same as in \this one.
6017  * If a permutation reduction is needed, substr() or selectByTupleId() should be used.
6018  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
6019  *  \param [in] new2Old - C array of length equal to \a this->getNumberOfTuples()
6020  *     giving a previous position of i-th new value.
6021  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
6022  *          is to delete using decrRef() as it is no more needed.
6023  */
6024 DataArrayInt *DataArrayInt::renumberR(const int *new2Old) const throw(INTERP_KERNEL::Exception)
6025 {
6026   checkAllocated();
6027   int nbTuples=getNumberOfTuples();
6028   int nbOfCompo=getNumberOfComponents();
6029   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6030   ret->alloc(nbTuples,nbOfCompo);
6031   ret->copyStringInfoFrom(*this);
6032   const int *iptr=getConstPointer();
6033   int *optr=ret->getPointer();
6034   for(int i=0;i<nbTuples;i++)
6035     std::copy(iptr+nbOfCompo*new2Old[i],iptr+nbOfCompo*(new2Old[i]+1),optr+nbOfCompo*i);
6036   ret->copyStringInfoFrom(*this);
6037   return ret.retn();
6038 }
6039
6040 /*!
6041  * Returns a shorten and permuted copy of \a this array. The new DataArrayInt is
6042  * of size \a newNbOfTuple and it's values are permuted as required by \a old2New array.
6043  * The values are permuted so that  \c new[ \a old2New[ i ]] = \c old[ i ] for all
6044  * \a old2New[ i ] >= 0. In other words every i-th tuple in \a this array, for which 
6045  * \a old2New[ i ] is negative, is missing from the result array.
6046  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
6047  *  \param [in] old2New - C array of length equal to \a this->getNumberOfTuples()
6048  *     giving a new position for i-th old tuple and giving negative position for
6049  *     for i-th old tuple that should be omitted.
6050  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
6051  *          is to delete using decrRef() as it is no more needed.
6052  */
6053 DataArrayInt *DataArrayInt::renumberAndReduce(const int *old2New, int newNbOfTuple) const throw(INTERP_KERNEL::Exception)
6054 {
6055   checkAllocated();
6056   int nbTuples=getNumberOfTuples();
6057   int nbOfCompo=getNumberOfComponents();
6058   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6059   ret->alloc(newNbOfTuple,nbOfCompo);
6060   const int *iptr=getConstPointer();
6061   int *optr=ret->getPointer();
6062   for(int i=0;i<nbTuples;i++)
6063     {
6064       int w=old2New[i];
6065       if(w>=0)
6066         std::copy(iptr+i*nbOfCompo,iptr+(i+1)*nbOfCompo,optr+w*nbOfCompo);
6067     }
6068   ret->copyStringInfoFrom(*this);
6069   return ret.retn();
6070 }
6071
6072 /*!
6073  * Returns a shorten and permuted copy of \a this array. The new DataArrayInt is
6074  * of size \a new2OldEnd - \a new2OldBg and it's values are permuted as required by
6075  * \a new2OldBg array.
6076  * The values are permuted so that  \c new[ i ] = \c old[ \a new2OldBg[ i ]].
6077  * This method is equivalent to renumberAndReduce() except that convention in input is
6078  * \c new2old and \b not \c old2new.
6079  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
6080  *  \param [in] new2OldBg - pointer to the beginning of a permutation array that gives a
6081  *              tuple index in \a this array to fill the i-th tuple in the new array.
6082  *  \param [in] new2OldEnd - specifies the end of the permutation array that starts at
6083  *              \a new2OldBg, so that pointer to a tuple index (\a pi) varies as this:
6084  *              \a new2OldBg <= \a pi < \a new2OldEnd.
6085  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
6086  *          is to delete using decrRef() as it is no more needed.
6087  */
6088 DataArrayInt *DataArrayInt::selectByTupleId(const int *new2OldBg, const int *new2OldEnd) const
6089 {
6090   checkAllocated();
6091   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6092   int nbComp=getNumberOfComponents();
6093   ret->alloc((int)std::distance(new2OldBg,new2OldEnd),nbComp);
6094   ret->copyStringInfoFrom(*this);
6095   int *pt=ret->getPointer();
6096   const int *srcPt=getConstPointer();
6097   int i=0;
6098   for(const int *w=new2OldBg;w!=new2OldEnd;w++,i++)
6099     std::copy(srcPt+(*w)*nbComp,srcPt+((*w)+1)*nbComp,pt+i*nbComp);
6100   ret->copyStringInfoFrom(*this);
6101   return ret.retn();
6102 }
6103
6104 /*!
6105  * Returns a shorten and permuted copy of \a this array. The new DataArrayInt is
6106  * of size \a new2OldEnd - \a new2OldBg and it's values are permuted as required by
6107  * \a new2OldBg array.
6108  * The values are permuted so that  \c new[ i ] = \c old[ \a new2OldBg[ i ]].
6109  * This method is equivalent to renumberAndReduce() except that convention in input is
6110  * \c new2old and \b not \c old2new.
6111  * This method is equivalent to selectByTupleId() except that it prevents coping data
6112  * from behind the end of \a this array.
6113  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
6114  *  \param [in] new2OldBg - pointer to the beginning of a permutation array that gives a
6115  *              tuple index in \a this array to fill the i-th tuple in the new array.
6116  *  \param [in] new2OldEnd - specifies the end of the permutation array that starts at
6117  *              \a new2OldBg, so that pointer to a tuple index (\a pi) varies as this:
6118  *              \a new2OldBg <= \a pi < \a new2OldEnd.
6119  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
6120  *          is to delete using decrRef() as it is no more needed.
6121  *  \throw If \a new2OldEnd - \a new2OldBg > \a this->getNumberOfTuples().
6122  */
6123 DataArrayInt *DataArrayInt::selectByTupleIdSafe(const int *new2OldBg, const int *new2OldEnd) const throw(INTERP_KERNEL::Exception)
6124 {
6125   checkAllocated();
6126   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6127   int nbComp=getNumberOfComponents();
6128   int oldNbOfTuples=getNumberOfTuples();
6129   ret->alloc((int)std::distance(new2OldBg,new2OldEnd),nbComp);
6130   ret->copyStringInfoFrom(*this);
6131   int *pt=ret->getPointer();
6132   const int *srcPt=getConstPointer();
6133   int i=0;
6134   for(const int *w=new2OldBg;w!=new2OldEnd;w++,i++)
6135     if(*w>=0 && *w<oldNbOfTuples)
6136       std::copy(srcPt+(*w)*nbComp,srcPt+((*w)+1)*nbComp,pt+i*nbComp);
6137     else
6138       throw INTERP_KERNEL::Exception("DataArrayInt::selectByTupleIdSafe : some ids has been detected to be out of [0,this->getNumberOfTuples) !");
6139   ret->copyStringInfoFrom(*this);
6140   return ret.retn();
6141 }
6142
6143 /*!
6144  * Returns a shorten copy of \a this array. The new DataArrayInt contains every
6145  * (\a bg + \c i * \a step)-th tuple of \a this array located before the \a end2-th
6146  * tuple. Indices of the selected tuples are the same as ones returned by the Python
6147  * command \c range( \a bg, \a end2, \a step ).
6148  * This method is equivalent to selectByTupleIdSafe() except that the input array is
6149  * not constructed explicitly.
6150  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
6151  *  \param [in] bg - index of the first tuple to copy from \a this array.
6152  *  \param [in] end2 - index of the tuple before which the tuples to copy are located.
6153  *  \param [in] step - index increment to get index of the next tuple to copy.
6154  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
6155  *          is to delete using decrRef() as it is no more needed.
6156  *  \throw If (\a end2 < \a bg) or (\a step <= 0).
6157  *  \sa DataArrayInt::substr.
6158  */
6159 DataArrayInt *DataArrayInt::selectByTupleId2(int bg, int end2, int step) const throw(INTERP_KERNEL::Exception)
6160 {
6161   checkAllocated();
6162   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6163   int nbComp=getNumberOfComponents();
6164   int newNbOfTuples=GetNumberOfItemGivenBES(bg,end2,step,"DataArrayInt::selectByTupleId2 : ");
6165   ret->alloc(newNbOfTuples,nbComp);
6166   int *pt=ret->getPointer();
6167   const int *srcPt=getConstPointer()+bg*nbComp;
6168   for(int i=0;i<newNbOfTuples;i++,srcPt+=step*nbComp)
6169     std::copy(srcPt,srcPt+nbComp,pt+i*nbComp);
6170   ret->copyStringInfoFrom(*this);
6171   return ret.retn();
6172 }
6173
6174 /*!
6175  * Returns a shorten copy of \a this array. The new DataArrayInt contains ranges
6176  * of tuples specified by \a ranges parameter.
6177  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
6178  *  \param [in] ranges - std::vector of std::pair's each of which defines a range
6179  *              of tuples in [\c begin,\c end) format.
6180  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
6181  *          is to delete using decrRef() as it is no more needed.
6182  *  \throw If \a end < \a begin.
6183  *  \throw If \a end > \a this->getNumberOfTuples().
6184  *  \throw If \a this is not allocated.
6185  */
6186 DataArrayInt *DataArrayInt::selectByTupleRanges(const std::vector<std::pair<int,int> >& ranges) const throw(INTERP_KERNEL::Exception)
6187 {
6188   checkAllocated();
6189   int nbOfComp=getNumberOfComponents();
6190   int nbOfTuplesThis=getNumberOfTuples();
6191   if(ranges.empty())
6192     {
6193       MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6194       ret->alloc(0,nbOfComp);
6195       ret->copyStringInfoFrom(*this);
6196       return ret.retn();
6197     }
6198   int ref=ranges.front().first;
6199   int nbOfTuples=0;
6200   bool isIncreasing=true;
6201   for(std::vector<std::pair<int,int> >::const_iterator it=ranges.begin();it!=ranges.end();it++)
6202     {
6203       if((*it).first<=(*it).second)
6204         {
6205           if((*it).first>=0 && (*it).second<=nbOfTuplesThis)
6206             {
6207               nbOfTuples+=(*it).second-(*it).first;
6208               if(isIncreasing)
6209                 isIncreasing=ref<=(*it).first;
6210               ref=(*it).second;
6211             }
6212           else
6213             {
6214               std::ostringstream oss; oss << "DataArrayInt::selectByTupleRanges : on range #" << std::distance(ranges.begin(),it);
6215               oss << " (" << (*it).first << "," << (*it).second << ") is greater than number of tuples of this :" << nbOfTuples << " !";
6216               throw INTERP_KERNEL::Exception(oss.str().c_str());
6217             }
6218         }
6219       else
6220         {
6221           std::ostringstream oss; oss << "DataArrayInt::selectByTupleRanges : on range #" << std::distance(ranges.begin(),it);
6222           oss << " (" << (*it).first << "," << (*it).second << ") end is before begin !";
6223           throw INTERP_KERNEL::Exception(oss.str().c_str());
6224         }
6225     }
6226   if(isIncreasing && nbOfTuplesThis==nbOfTuples)
6227     return deepCpy();
6228   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6229   ret->alloc(nbOfTuples,nbOfComp);
6230   ret->copyStringInfoFrom(*this);
6231   const int *src=getConstPointer();
6232   int *work=ret->getPointer();
6233   for(std::vector<std::pair<int,int> >::const_iterator it=ranges.begin();it!=ranges.end();it++)
6234     work=std::copy(src+(*it).first*nbOfComp,src+(*it).second*nbOfComp,work);
6235   return ret.retn();
6236 }
6237
6238 /*!
6239  * Returns a new DataArrayInt containing a renumbering map in "Old to New" mode.
6240  * This map, if applied to \a this array, would make it sorted. For example, if
6241  * \a this array contents are [9,10,0,6,4,11,3,7] then the contents of the result array
6242  * are [5,6,0,3,2,7,1,4]; if this result array (\a res) is used as an argument in call
6243  * \a this->renumber(\a res) then the returned array contains [0,3,4,6,7,9,10,11].
6244  * This method is useful for renumbering (in MED file for example). For more info
6245  * on renumbering see \ref MEDCouplingArrayRenumbering.
6246  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
6247  *          array using decrRef() as it is no more needed.
6248  *  \throw If \a this is not allocated.
6249  *  \throw If \a this->getNumberOfComponents() != 1.
6250  *  \throw If there are equal values in \a this array.
6251  */
6252 DataArrayInt *DataArrayInt::checkAndPreparePermutation() const throw(INTERP_KERNEL::Exception)
6253 {
6254   checkAllocated();
6255   if(getNumberOfComponents()!=1)
6256     throw INTERP_KERNEL::Exception("DataArrayInt::checkAndPreparePermutation : number of components must == 1 !");
6257   int nbTuples=getNumberOfTuples();
6258   const int *pt=getConstPointer();
6259   int *pt2=CheckAndPreparePermutation(pt,pt+nbTuples);
6260   DataArrayInt *ret=DataArrayInt::New();
6261   ret->useArray(pt2,true,CPP_DEALLOC,nbTuples,1);
6262   return ret;
6263 }
6264
6265 /*!
6266  * Returns two arrays describing a surjective mapping from \a this set of values (\a A)
6267  * onto a set of values of size \a targetNb (\a B). The surjective function is 
6268  * \a B[ \a A[ i ]] = i. That is to say that for each \a id in [0,\a targetNb), where \a
6269  * targetNb < \a this->getNumberOfTuples(), there exists at least one tupleId (\a tid) so
6270  * that <em> this->getIJ( tid, 0 ) == id</em>. <br>
6271  * The first of out arrays returns indices of elements of \a this array, grouped by their
6272  * place in the set \a B. The second out array is the index of the first one; it shows how
6273  * many elements of \a A are mapped into each element of \a B. <br>
6274  * For more info on
6275  * mapping and its usage in renumbering see \ref MEDCouplingArrayRenumbering. <br>
6276  * \b Example:
6277  * - \a this: [0,3,2,3,2,2,1,2]
6278  * - \a targetNb: 4
6279  * - \a arr:  [0,  6,  2,4,5,7,  1,3]
6280  * - \a arrI: [0,1,2,6,8]
6281  *
6282  * This result means: <br>
6283  * the element of \a B 0 encounters within \a A once (\a arrI[ 0+1 ] - \a arrI[ 0 ]) and
6284  * its index within \a A is 0 ( \a arr[ 0:1 ] == \a arr[ \a arrI[ 0 ] : \a arrI[ 0+1 ]]);<br>
6285  * the element of \a B 2 encounters within \a A 4 times (\a arrI[ 2+1 ] - \a arrI[ 2 ]) and
6286  * its indices within \a A are [2,4,5,7] ( \a arr[ 2:6 ] == \a arr[ \a arrI[ 2 ] : 
6287  * \a arrI[ 2+1 ]]); <br> etc.
6288  *  \param [in] targetNb - the size of the set \a B. \a targetNb must be equal or more
6289  *         than the maximal value of \a A.
6290  *  \param [out] arr - a new instance of DataArrayInt returning indices of
6291  *         elements of \a this, grouped by their place in the set \a B. The caller is to delete
6292  *         this array using decrRef() as it is no more needed.
6293  *  \param [out] arrI - a new instance of DataArrayInt returning size of groups of equal
6294  *         elements of \a this. The caller is to delete this array using decrRef() as it
6295  *         is no more needed.
6296  *  \throw If \a this is not allocated.
6297  *  \throw If \a this->getNumberOfComponents() != 1.
6298  *  \throw If any value in \a this is more or equal to \a targetNb.
6299  */
6300 void DataArrayInt::changeSurjectiveFormat(int targetNb, DataArrayInt *&arr, DataArrayInt *&arrI) const throw(INTERP_KERNEL::Exception)
6301 {
6302   checkAllocated();
6303   if(getNumberOfComponents()!=1)
6304     throw INTERP_KERNEL::Exception("DataArrayInt::changeSurjectiveFormat : number of components must == 1 !");
6305   int nbOfTuples=getNumberOfTuples();
6306   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New());
6307   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> retI(DataArrayInt::New());
6308   retI->alloc(targetNb+1,1);
6309   const int *input=getConstPointer();
6310   std::vector< std::vector<int> > tmp(targetNb);
6311   for(int i=0;i<nbOfTuples;i++)
6312     {
6313       int tmp2=input[i];
6314       if(tmp2>=0 && tmp2<targetNb)
6315         tmp[tmp2].push_back(i);
6316       else
6317         {
6318           std::ostringstream oss; oss << "DataArrayInt::changeSurjectiveFormat : At pos " << i << " presence of element " << tmp2 << " ! should be in [0," << targetNb << ") !";
6319           throw INTERP_KERNEL::Exception(oss.str().c_str());
6320         }
6321     }
6322   int *retIPtr=retI->getPointer();
6323   *retIPtr=0;
6324   for(std::vector< std::vector<int> >::const_iterator it1=tmp.begin();it1!=tmp.end();it1++,retIPtr++)
6325     retIPtr[1]=retIPtr[0]+(int)((*it1).size());
6326   if(nbOfTuples!=retI->getIJ(targetNb,0))
6327     throw INTERP_KERNEL::Exception("DataArrayInt::changeSurjectiveFormat : big problem should never happen !");
6328   ret->alloc(nbOfTuples,1);
6329   int *retPtr=ret->getPointer();
6330   for(std::vector< std::vector<int> >::const_iterator it1=tmp.begin();it1!=tmp.end();it1++)
6331     retPtr=std::copy((*it1).begin(),(*it1).end(),retPtr);
6332   arr=ret.retn();
6333   arrI=retI.retn();
6334 }
6335
6336
6337 /*!
6338  * Returns a new DataArrayInt containing a renumbering map in "Old to New" mode computed
6339  * from a zip representation of a surjective format (returned e.g. by
6340  * \ref ParaMEDMEM::DataArrayDouble::findCommonTuples() "DataArrayDouble::findCommonTuples()"
6341  * for example). The result array minimizes the permutation. <br>
6342  * For more info on renumbering see \ref MEDCouplingArrayRenumbering. <br>
6343  * \b Example: <br>
6344  * - \a nbOfOldTuples: 10 
6345  * - \a arr          : [0,3, 5,7,9]
6346  * - \a arrIBg       : [0,2,5]
6347  * - \a newNbOfTuples: 7
6348  * - result array    : [0,1,2,0,3,4,5,4,6,4]
6349  *
6350  *  \param [in] nbOfOldTuples - number of tuples in the initial array \a arr.
6351  *  \param [in] arr - the array of tuple indices grouped by \a arrIBg array.
6352  *  \param [in] arrIBg - the array dividing all indices stored in \a arr into groups of
6353  *         (indices of) equal values. Its every element (except the last one) points to
6354  *         the first element of a group of equal values.
6355  *  \param [in] arrIEnd - specifies the end of \a arrIBg, so that the last element of \a
6356  *          arrIBg is \a arrIEnd[ -1 ].
6357  *  \param [out] newNbOfTuples - number of tuples after surjection application.
6358  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
6359  *          array using decrRef() as it is no more needed.
6360  *  \throw If any value of \a arr breaks condition ( 0 <= \a arr[ i ] < \a nbOfOldTuples ).
6361  */
6362 DataArrayInt *DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2(int nbOfOldTuples, const int *arr, const int *arrIBg, const int *arrIEnd, int &newNbOfTuples) throw(INTERP_KERNEL::Exception)
6363 {
6364   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6365   ret->alloc(nbOfOldTuples,1);
6366   int *pt=ret->getPointer();
6367   std::fill(pt,pt+nbOfOldTuples,-1);
6368   int nbOfGrps=((int)std::distance(arrIBg,arrIEnd))-1;
6369   const int *cIPtr=arrIBg;
6370   for(int i=0;i<nbOfGrps;i++)
6371     pt[arr[cIPtr[i]]]=-(i+2);
6372   int newNb=0;
6373   for(int iNode=0;iNode<nbOfOldTuples;iNode++)
6374     {
6375       if(pt[iNode]<0)
6376         {
6377           if(pt[iNode]==-1)
6378             pt[iNode]=newNb++;
6379           else
6380             {
6381               int grpId=-(pt[iNode]+2);
6382               for(int j=cIPtr[grpId];j<cIPtr[grpId+1];j++)
6383                 {
6384                   if(arr[j]>=0 && arr[j]<nbOfOldTuples)
6385                     pt[arr[j]]=newNb;
6386                   else
6387                     {
6388                       std::ostringstream oss; oss << "DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2 : With element #" << j << " value is " << arr[j] << " should be in [0," << nbOfOldTuples << ") !";
6389                       throw INTERP_KERNEL::Exception(oss.str().c_str());
6390                     }
6391                 }
6392               newNb++;
6393             }
6394         }
6395     }
6396   newNbOfTuples=newNb;
6397   return ret.retn();
6398 }
6399
6400 /*!
6401  * Returns a new DataArrayInt containing a renumbering map in "New to Old" mode,
6402  * which if applied to \a this array would make it sorted ascendingly.
6403  * For more info on renumbering see \ref MEDCouplingArrayRenumbering. <br>
6404  * \b Example: <br>
6405  * - \a this: [2,0,1,1,0,1,2,0,1,1,0,0]
6406  * - result: [10,0,5,6,1,7,11,2,8,9,3,4]
6407  * - after applying result to \a this: [0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2] 
6408  *
6409  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
6410  *          array using decrRef() as it is no more needed.
6411  *  \throw If \a this is not allocated.
6412  *  \throw If \a this->getNumberOfComponents() != 1.
6413  */
6414 DataArrayInt *DataArrayInt::buildPermArrPerLevel() const throw(INTERP_KERNEL::Exception)
6415 {
6416   checkAllocated();
6417   if(getNumberOfComponents()!=1)
6418     throw INTERP_KERNEL::Exception("DataArrayInt::buildPermArrPerLevel : number of components must == 1 !");
6419   int nbOfTuples=getNumberOfTuples();
6420   const int *pt=getConstPointer();
6421   std::map<int,int> m;
6422   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6423   ret->alloc(nbOfTuples,1);
6424   int *opt=ret->getPointer();
6425   for(int i=0;i<nbOfTuples;i++,pt++,opt++)
6426     {
6427       int val=*pt;
6428       std::map<int,int>::iterator it=m.find(val);
6429       if(it!=m.end())
6430         {
6431           *opt=(*it).second;
6432           (*it).second++;
6433         }
6434       else
6435         {
6436           *opt=0;
6437           m.insert(std::pair<int,int>(val,1));
6438         }
6439     }
6440   int sum=0;
6441   for(std::map<int,int>::iterator it=m.begin();it!=m.end();it++)
6442     {
6443       int vt=(*it).second;
6444       (*it).second=sum;
6445       sum+=vt;
6446     }
6447   pt=getConstPointer();
6448   opt=ret->getPointer();
6449   for(int i=0;i<nbOfTuples;i++,pt++,opt++)
6450     *opt+=m[*pt];
6451   //
6452   return ret.retn();
6453 }
6454
6455 /*!
6456  * Checks if contents of \a this array are equal to that of an array filled with
6457  * iota(). This method is particularly useful for DataArrayInt instances that represent
6458  * a renumbering array to check the real need in renumbering. 
6459  *  \return bool - \a true if \a this array contents == \a range( \a this->getNumberOfTuples())
6460  *  \throw If \a this is not allocated.
6461  *  \throw If \a this->getNumberOfComponents() != 1.
6462  */
6463 bool DataArrayInt::isIdentity() const throw(INTERP_KERNEL::Exception)
6464 {
6465   checkAllocated();
6466   if(getNumberOfComponents()!=1)
6467     return false;
6468   int nbOfTuples=getNumberOfTuples();
6469   const int *pt=getConstPointer();
6470   for(int i=0;i<nbOfTuples;i++,pt++)
6471     if(*pt!=i)
6472       return false;
6473   return true;
6474 }
6475
6476 /*!
6477  * Checks if all values in \a this array are equal to \a val.
6478  *  \param [in] val - value to check equality of array values to.
6479  *  \return bool - \a true if all values are \a val.
6480  *  \throw If \a this is not allocated.
6481  *  \throw If \a this->getNumberOfComponents() != 1
6482  */
6483 bool DataArrayInt::isUniform(int val) const throw(INTERP_KERNEL::Exception)
6484 {
6485   checkAllocated();
6486   if(getNumberOfComponents()!=1)
6487     throw INTERP_KERNEL::Exception("DataArrayInt::isUniform : must be applied on DataArrayInt with only one component, you can call 'rearrange' method before !");
6488   int nbOfTuples=getNumberOfTuples();
6489   const int *w=getConstPointer();
6490   const int *end2=w+nbOfTuples;
6491   for(;w!=end2;w++)
6492     if(*w!=val)
6493       return false;
6494   return true;
6495 }
6496
6497 /*!
6498  * Creates a new DataArrayDouble and assigns all (textual and numerical) data of \a this
6499  * array to the new one.
6500  *  \return DataArrayDouble * - the new instance of DataArrayInt.
6501  */
6502 DataArrayDouble *DataArrayInt::convertToDblArr() const
6503 {
6504   checkAllocated();
6505   DataArrayDouble *ret=DataArrayDouble::New();
6506   ret->alloc(getNumberOfTuples(),getNumberOfComponents());
6507   int nbOfVals=getNbOfElems();
6508   const int *src=getConstPointer();
6509   double *dest=ret->getPointer();
6510   std::copy(src,src+nbOfVals,dest);
6511   ret->copyStringInfoFrom(*this);
6512   return ret;
6513 }
6514
6515 /*!
6516  * Returns a shorten copy of \a this array. The new DataArrayInt contains all
6517  * tuples starting from the \a tupleIdBg-th tuple and including all tuples located before
6518  * the \a tupleIdEnd-th one. This methods has a similar behavior as std::string::substr().
6519  * This method is a specialization of selectByTupleId2().
6520  *  \param [in] tupleIdBg - index of the first tuple to copy from \a this array.
6521  *  \param [in] tupleIdEnd - index of the tuple before which the tuples to copy are located.
6522  *          If \a tupleIdEnd == -1, all the tuples till the end of \a this array are copied.
6523  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
6524  *          is to delete using decrRef() as it is no more needed.
6525  *  \throw If \a tupleIdBg < 0.
6526  *  \throw If \a tupleIdBg > \a this->getNumberOfTuples().
6527     \throw If \a tupleIdEnd != -1 && \a tupleIdEnd < \a this->getNumberOfTuples().
6528  *  \sa DataArrayInt::selectByTupleId2
6529  */
6530 DataArrayInt *DataArrayInt::substr(int tupleIdBg, int tupleIdEnd) const throw(INTERP_KERNEL::Exception)
6531 {
6532   checkAllocated();
6533   int nbt=getNumberOfTuples();
6534   if(tupleIdBg<0)
6535     throw INTERP_KERNEL::Exception("DataArrayInt::substr : The tupleIdBg parameter must be greater than 0 !");
6536   if(tupleIdBg>nbt)
6537     throw INTERP_KERNEL::Exception("DataArrayInt::substr : The tupleIdBg parameter is greater than number of tuples !");
6538   int trueEnd=tupleIdEnd;
6539   if(tupleIdEnd!=-1)
6540     {
6541       if(tupleIdEnd>nbt)
6542         throw INTERP_KERNEL::Exception("DataArrayInt::substr : The tupleIdBg parameter is greater or equal than number of tuples !");
6543     }
6544   else
6545     trueEnd=nbt;
6546   int nbComp=getNumberOfComponents();
6547   DataArrayInt *ret=DataArrayInt::New();
6548   ret->alloc(trueEnd-tupleIdBg,nbComp);
6549   ret->copyStringInfoFrom(*this);
6550   std::copy(getConstPointer()+tupleIdBg*nbComp,getConstPointer()+trueEnd*nbComp,ret->getPointer());
6551   return ret;
6552 }
6553
6554 /*!
6555  * Changes the number of components within \a this array so that its raw data **does
6556  * not** change, instead splitting this data into tuples changes.
6557  *  \param [in] newNbOfComp - number of components for \a this array to have.
6558  *  \throw If \a this is not allocated
6559  *  \throw If getNbOfElems() % \a newNbOfCompo != 0.
6560  *  \warning This method erases all (name and unit) component info set before!
6561  */
6562 void DataArrayInt::rearrange(int newNbOfCompo) throw(INTERP_KERNEL::Exception)
6563 {
6564   checkAllocated();
6565   int nbOfElems=getNbOfElems();
6566   if(nbOfElems%newNbOfCompo!=0)
6567     throw INTERP_KERNEL::Exception("DataArrayInt::rearrange : nbOfElems%newNbOfCompo!=0 !");
6568   _info_on_compo.clear();
6569   _info_on_compo.resize(newNbOfCompo);
6570   declareAsNew();
6571 }
6572
6573 /*!
6574  * Changes the number of components within \a this array to be equal to its number
6575  * of tuples, and inversely its number of tuples to become equal to its number of 
6576  * components. So that its raw data **does not** change, instead splitting this
6577  * data into tuples changes.
6578  *  \throw If \a this is not allocated.
6579  *  \warning This method erases all (name and unit) component info set before!
6580  *  \warning Do not confuse this method with fromNoInterlace() and toNoInterlace()!
6581  *  \sa rearrange()
6582  */
6583 void DataArrayInt::transpose() throw(INTERP_KERNEL::Exception)
6584 {
6585   checkAllocated();
6586   int nbOfTuples=getNumberOfTuples();
6587   rearrange(nbOfTuples);
6588 }
6589
6590 /*!
6591  * Returns a shorten or extended copy of \a this array. If \a newNbOfComp is less
6592  * than \a this->getNumberOfComponents() then the result array is shorten as each tuple
6593  * is truncated to have \a newNbOfComp components, keeping first components. If \a
6594  * newNbOfComp is more than \a this->getNumberOfComponents() then the result array is
6595  * expanded as each tuple is populated with \a dftValue to have \a newNbOfComp
6596  * components.  
6597  *  \param [in] newNbOfComp - number of components for the new array to have.
6598  *  \param [in] dftValue - value assigned to new values added to the new array.
6599  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
6600  *          is to delete using decrRef() as it is no more needed.
6601  *  \throw If \a this is not allocated.
6602  */
6603 DataArrayInt *DataArrayInt::changeNbOfComponents(int newNbOfComp, int dftValue) const throw(INTERP_KERNEL::Exception)
6604 {
6605   checkAllocated();
6606   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6607   ret->alloc(getNumberOfTuples(),newNbOfComp);
6608   const int *oldc=getConstPointer();
6609   int *nc=ret->getPointer();
6610   int nbOfTuples=getNumberOfTuples();
6611   int oldNbOfComp=getNumberOfComponents();
6612   int dim=std::min(oldNbOfComp,newNbOfComp);
6613   for(int i=0;i<nbOfTuples;i++)
6614     {
6615       int j=0;
6616       for(;j<dim;j++)
6617         nc[newNbOfComp*i+j]=oldc[i*oldNbOfComp+j];
6618       for(;j<newNbOfComp;j++)
6619         nc[newNbOfComp*i+j]=dftValue;
6620     }
6621   ret->setName(getName().c_str());
6622   for(int i=0;i<dim;i++)
6623     ret->setInfoOnComponent(i,getInfoOnComponent(i).c_str());
6624   ret->setName(getName().c_str());
6625   return ret.retn();
6626 }
6627
6628 /*!
6629  * Changes number of tuples in the array. If the new number of tuples is smaller
6630  * than the current number the array is truncated, otherwise the array is extended.
6631  *  \param [in] nbOfTuples - new number of tuples. 
6632  *  \throw If \a this is not allocated.
6633  */
6634 void DataArrayInt::reAlloc(int nbOfTuples) throw(INTERP_KERNEL::Exception)
6635 {
6636   checkAllocated();
6637   _mem.reAlloc(getNumberOfComponents()*nbOfTuples);
6638   declareAsNew();
6639 }
6640
6641
6642 /*!
6643  * Returns a copy of \a this array composed of selected components.
6644  * The new DataArrayInt has the same number of tuples but includes components
6645  * specified by \a compoIds parameter. So that getNbOfElems() of the result array
6646  * can be either less, same or more than \a this->getNbOfElems().
6647  *  \param [in] compoIds - sequence of zero based indices of components to include
6648  *              into the new array.
6649  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
6650  *          is to delete using decrRef() as it is no more needed.
6651  *  \throw If \a this is not allocated.
6652  *  \throw If a component index (\a i) is not valid: 
6653  *         \a i < 0 || \a i >= \a this->getNumberOfComponents().
6654  *
6655  *  \ref cpp_mcdataarrayint_keepselectedcomponents "Here is a Python example".
6656  */
6657 DataArrayInt *DataArrayInt::keepSelectedComponents(const std::vector<int>& compoIds) const throw(INTERP_KERNEL::Exception)
6658 {
6659   checkAllocated();
6660   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New());
6661   int newNbOfCompo=(int)compoIds.size();
6662   int oldNbOfCompo=getNumberOfComponents();
6663   for(std::vector<int>::const_iterator it=compoIds.begin();it!=compoIds.end();it++)
6664     DataArray::CheckValueInRange(oldNbOfCompo,(*it),"keepSelectedComponents invalid requested component");
6665   int nbOfTuples=getNumberOfTuples();
6666   ret->alloc(nbOfTuples,newNbOfCompo);
6667   ret->copyPartOfStringInfoFrom(*this,compoIds);
6668   const int *oldc=getConstPointer();
6669   int *nc=ret->getPointer();
6670   for(int i=0;i<nbOfTuples;i++)
6671     for(int j=0;j<newNbOfCompo;j++,nc++)
6672       *nc=oldc[i*oldNbOfCompo+compoIds[j]];
6673   return ret.retn();
6674 }
6675
6676 /*!
6677  * Appends components of another array to components of \a this one, tuple by tuple.
6678  * So that the number of tuples of \a this array remains the same and the number of 
6679  * components increases.
6680  *  \param [in] other - the DataArrayInt to append to \a this one.
6681  *  \throw If \a this is not allocated.
6682  *  \throw If \a this and \a other arrays have different number of tuples.
6683  *
6684  *  \ref cpp_mcdataarrayint_meldwith "Here is a C++ example".
6685  *
6686  *  \ref py_mcdataarrayint_meldwith "Here is a Python example".
6687  */
6688 void DataArrayInt::meldWith(const DataArrayInt *other) throw(INTERP_KERNEL::Exception)
6689 {
6690   if(!other)
6691     throw INTERP_KERNEL::Exception("DataArrayInt::meldWith : DataArrayInt pointer in input is NULL !");
6692   checkAllocated();
6693   other->checkAllocated();
6694   int nbOfTuples=getNumberOfTuples();
6695   if(nbOfTuples!=other->getNumberOfTuples())
6696     throw INTERP_KERNEL::Exception("DataArrayInt::meldWith : mismatch of number of tuples !");
6697   int nbOfComp1=getNumberOfComponents();
6698   int nbOfComp2=other->getNumberOfComponents();
6699   int *newArr=new int[nbOfTuples*(nbOfComp1+nbOfComp2)];
6700   int *w=newArr;
6701   const int *inp1=getConstPointer();
6702   const int *inp2=other->getConstPointer();
6703   for(int i=0;i<nbOfTuples;i++,inp1+=nbOfComp1,inp2+=nbOfComp2)
6704     {
6705       w=std::copy(inp1,inp1+nbOfComp1,w);
6706       w=std::copy(inp2,inp2+nbOfComp2,w);
6707     }
6708   useArray(newArr,true,CPP_DEALLOC,nbOfTuples,nbOfComp1+nbOfComp2);
6709   std::vector<int> compIds(nbOfComp2);
6710   for(int i=0;i<nbOfComp2;i++)
6711     compIds[i]=nbOfComp1+i;
6712   copyPartOfStringInfoFrom2(compIds,*other);
6713 }
6714
6715 /*!
6716  * Copy all components in a specified order from another DataArrayInt.
6717  * The specified components become the first ones in \a this array.
6718  * Both numerical and textual data is copied. The number of tuples in \a this and
6719  * the other array can be different.
6720  *  \param [in] a - the array to copy data from.
6721  *  \param [in] compoIds - sequence of zero based indices of components, data of which is
6722  *              to be copied.
6723  *  \throw If \a a is NULL.
6724  *  \throw If \a compoIds.size() != \a a->getNumberOfComponents().
6725  *  \throw If \a compoIds[i] < 0 or \a compoIds[i] > \a this->getNumberOfComponents().
6726  *
6727  *  \ref cpp_mcdataarrayint_setselectedcomponents "Here is a Python example".
6728  */
6729 void DataArrayInt::setSelectedComponents(const DataArrayInt *a, const std::vector<int>& compoIds) throw(INTERP_KERNEL::Exception)
6730 {
6731   if(!a)
6732     throw INTERP_KERNEL::Exception("DataArrayInt::setSelectedComponents : input DataArrayInt is NULL !");
6733   checkAllocated();
6734   a->checkAllocated();
6735   copyPartOfStringInfoFrom2(compoIds,*a);
6736   std::size_t partOfCompoSz=compoIds.size();
6737   int nbOfCompo=getNumberOfComponents();
6738   int nbOfTuples=std::min(getNumberOfTuples(),a->getNumberOfTuples());
6739   const int *ac=a->getConstPointer();
6740   int *nc=getPointer();
6741   for(int i=0;i<nbOfTuples;i++)
6742     for(std::size_t j=0;j<partOfCompoSz;j++,ac++)
6743       nc[nbOfCompo*i+compoIds[j]]=*ac;
6744 }
6745
6746 /*!
6747  * Copy all values from another DataArrayInt into specified tuples and components
6748  * of \a this array. Textual data is not copied.
6749  * The tree parameters defining set of indices of tuples and components are similar to
6750  * the tree parameters of the Python function \c range(\c start,\c stop,\c step).
6751  *  \param [in] a - the array to copy values from.
6752  *  \param [in] bgTuples - index of the first tuple of \a this array to assign values to.
6753  *  \param [in] endTuples - index of the tuple before which the tuples to assign to
6754  *              are located.
6755  *  \param [in] stepTuples - index increment to get index of the next tuple to assign to.
6756  *  \param [in] bgComp - index of the first component of \a this array to assign values to.
6757  *  \param [in] endComp - index of the component before which the components to assign
6758  *              to are located.
6759  *  \param [in] stepComp - index increment to get index of the next component to assign to.
6760  *  \param [in] strictCompoCompare - if \a true (by default), then \a a->getNumberOfComponents() 
6761  *              must be equal to the number of columns to assign to, else an
6762  *              exception is thrown; if \a false, then it is only required that \a
6763  *              a->getNbOfElems() equals to number of values to assign to (this condition
6764  *              must be respected even if \a strictCompoCompare is \a true). The number of 
6765  *              values to assign to is given by following Python expression:
6766  *              \a nbTargetValues = 
6767  *              \c len(\c range(\a bgTuples,\a endTuples,\a stepTuples)) *
6768  *              \c len(\c range(\a bgComp,\a endComp,\a stepComp)).
6769  *  \throw If \a a is NULL.
6770  *  \throw If \a a is not allocated.
6771  *  \throw If \a this is not allocated.
6772  *  \throw If parameters specifying tuples and components to assign to do not give a
6773  *            non-empty range of increasing indices.
6774  *  \throw If \a a->getNbOfElems() != \a nbTargetValues.
6775  *  \throw If \a strictCompoCompare == \a true && \a a->getNumberOfComponents() !=
6776  *            \c len(\c range(\a bgComp,\a endComp,\a stepComp)).
6777  *
6778  *  \ref cpp_mcdataarrayint_setpartofvalues1 "Here is a Python example".
6779  */
6780 void DataArrayInt::setPartOfValues1(const DataArrayInt *a, int bgTuples, int endTuples, int stepTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare) throw(INTERP_KERNEL::Exception)
6781 {
6782   if(!a)
6783     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValues1 : DataArrayInt pointer in input is NULL !");
6784   const char msg[]="DataArrayInt::setPartOfValues1";
6785   checkAllocated();
6786   a->checkAllocated();
6787   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
6788   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
6789   int nbComp=getNumberOfComponents();
6790   int nbOfTuples=getNumberOfTuples();
6791   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
6792   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
6793   bool assignTech=true;
6794   if(a->getNbOfElems()==newNbOfTuples*newNbOfComp)
6795     {
6796       if(strictCompoCompare)
6797         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
6798     }
6799   else
6800     {
6801       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
6802       assignTech=false;
6803     }
6804   int *pt=getPointer()+bgTuples*nbComp+bgComp;
6805   const int *srcPt=a->getConstPointer();
6806   if(assignTech)
6807     {
6808       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
6809         for(int j=0;j<newNbOfComp;j++,srcPt++)
6810           pt[j*stepComp]=*srcPt;
6811     }
6812   else
6813     {
6814       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
6815         {
6816           const int *srcPt2=srcPt;
6817           for(int j=0;j<newNbOfComp;j++,srcPt2++)
6818             pt[j*stepComp]=*srcPt2;
6819         }
6820     }
6821 }
6822
6823 /*!
6824  * Assign a given value to values at specified tuples and components of \a this array.
6825  * The tree parameters defining set of indices of tuples and components are similar to
6826  * the tree parameters of the Python function \c range(\c start,\c stop,\c step)..
6827  *  \param [in] a - the value to assign.
6828  *  \param [in] bgTuples - index of the first tuple of \a this array to assign to.
6829  *  \param [in] endTuples - index of the tuple before which the tuples to assign to
6830  *              are located.
6831  *  \param [in] stepTuples - index increment to get index of the next tuple to assign to.
6832  *  \param [in] bgComp - index of the first component of \a this array to assign to.
6833  *  \param [in] endComp - index of the component before which the components to assign
6834  *              to are located.
6835  *  \param [in] stepComp - index increment to get index of the next component to assign to.
6836  *  \throw If \a this is not allocated.
6837  *  \throw If parameters specifying tuples and components to assign to, do not give a
6838  *            non-empty range of increasing indices or indices are out of a valid range
6839  *            for \this array.
6840  *
6841  *  \ref cpp_mcdataarrayint_setpartofvaluessimple1 "Here is a Python example".
6842  */
6843 void DataArrayInt::setPartOfValuesSimple1(int a, int bgTuples, int endTuples, int stepTuples, int bgComp, int endComp, int stepComp) throw(INTERP_KERNEL::Exception)
6844 {
6845   const char msg[]="DataArrayInt::setPartOfValuesSimple1";
6846   checkAllocated();
6847   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
6848   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
6849   int nbComp=getNumberOfComponents();
6850   int nbOfTuples=getNumberOfTuples();
6851   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
6852   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
6853   int *pt=getPointer()+bgTuples*nbComp+bgComp;
6854   for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
6855     for(int j=0;j<newNbOfComp;j++)
6856       pt[j*stepComp]=a;
6857 }
6858
6859
6860 /*!
6861  * Copy all values from another DataArrayInt (\a a) into specified tuples and 
6862  * components of \a this array. Textual data is not copied.
6863  * The tuples and components to assign to are defined by C arrays of indices.
6864  * There are two *modes of usage*:
6865  * - If \a a->getNbOfElems() equals to number of values to assign to, then every value
6866  *   of \a a is assigned to its own location within \a this array. 
6867  * - If \a a includes one tuple, then all values of \a a are assigned to the specified
6868  *   components of every specified tuple of \a this array. In this mode it is required
6869  *   that \a a->getNumberOfComponents() equals to the number of specified components.
6870  * 
6871  *  \param [in] a - the array to copy values from.
6872  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
6873  *              assign values of \a a to.
6874  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
6875  *              pointer to a tuple index <em>(pi)</em> varies as this: 
6876  *              \a bgTuples <= \a pi < \a endTuples.
6877  *  \param [in] bgComp - pointer to an array of component indices of \a this array to
6878  *              assign values of \a a to.
6879  *  \param [in] endComp - specifies the end of the array \a bgTuples, so that
6880  *              pointer to a component index <em>(pi)</em> varies as this: 
6881  *              \a bgComp <= \a pi < \a endComp.
6882  *  \param [in] strictCompoCompare - this parameter is checked only if the
6883  *               *mode of usage* is the first; if it is \a true (default), 
6884  *               then \a a->getNumberOfComponents() must be equal 
6885  *               to the number of specified columns, else this is not required.
6886  *  \throw If \a a is NULL.
6887  *  \throw If \a a is not allocated.
6888  *  \throw If \a this is not allocated.
6889  *  \throw If any index of tuple/component given by <em>bgTuples / bgComp</em> is
6890  *         out of a valid range for \a this array.
6891  *  \throw In the first *mode of usage*, if <em>strictCompoCompare == true </em> and
6892  *         if <em> a->getNumberOfComponents() != (endComp - bgComp) </em>.
6893  *  \throw In the second *mode of usage*, if \a a->getNumberOfTuples() != 1 or
6894  *         <em> a->getNumberOfComponents() != (endComp - bgComp)</em>.
6895  *
6896  *  \ref cpp_mcdataarrayint_setpartofvalues2 "Here is a Python example".
6897  */
6898 void DataArrayInt::setPartOfValues2(const DataArrayInt *a, const int *bgTuples, const int *endTuples, const int *bgComp, const int *endComp, bool strictCompoCompare) throw(INTERP_KERNEL::Exception)
6899 {
6900   if(!a)
6901     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValues2 : DataArrayInt pointer in input is NULL !");
6902   const char msg[]="DataArrayInt::setPartOfValues2";
6903   checkAllocated();
6904   a->checkAllocated();
6905   int nbComp=getNumberOfComponents();
6906   int nbOfTuples=getNumberOfTuples();
6907   for(const int *z=bgComp;z!=endComp;z++)
6908     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
6909   int newNbOfTuples=(int)std::distance(bgTuples,endTuples);
6910   int newNbOfComp=(int)std::distance(bgComp,endComp);
6911   bool assignTech=true;
6912   if(a->getNbOfElems()==newNbOfTuples*newNbOfComp)
6913     {
6914       if(strictCompoCompare)
6915         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
6916     }
6917   else
6918     {
6919       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
6920       assignTech=false;
6921     }
6922   int *pt=getPointer();
6923   const int *srcPt=a->getConstPointer();
6924   if(assignTech)
6925     {    
6926       for(const int *w=bgTuples;w!=endTuples;w++)
6927         {
6928           DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
6929           for(const int *z=bgComp;z!=endComp;z++,srcPt++)
6930             {    
6931               pt[(*w)*nbComp+(*z)]=*srcPt;
6932             }
6933         }
6934     }
6935   else
6936     {
6937       for(const int *w=bgTuples;w!=endTuples;w++)
6938         {
6939           const int *srcPt2=srcPt;
6940           DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
6941           for(const int *z=bgComp;z!=endComp;z++,srcPt2++)
6942             {    
6943               pt[(*w)*nbComp+(*z)]=*srcPt2;
6944             }
6945         }
6946     }
6947 }
6948
6949 /*!
6950  * Assign a given value to values at specified tuples and components of \a this array.
6951  * The tuples and components to assign to are defined by C arrays of indices.
6952  *  \param [in] a - the value to assign.
6953  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
6954  *              assign \a a to.
6955  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
6956  *              pointer to a tuple index (\a pi) varies as this: 
6957  *              \a bgTuples <= \a pi < \a endTuples.
6958  *  \param [in] bgComp - pointer to an array of component indices of \a this array to
6959  *              assign \a a to.
6960  *  \param [in] endComp - specifies the end of the array \a bgTuples, so that
6961  *              pointer to a component index (\a pi) varies as this: 
6962  *              \a bgComp <= \a pi < \a endComp.
6963  *  \throw If \a this is not allocated.
6964  *  \throw If any index of tuple/component given by <em>bgTuples / bgComp</em> is
6965  *         out of a valid range for \a this array.
6966  *
6967  *  \ref cpp_mcdataarrayint_setpartofvaluessimple2 "Here is a Python example".
6968  */
6969 void DataArrayInt::setPartOfValuesSimple2(int a, const int *bgTuples, const int *endTuples, const int *bgComp, const int *endComp) throw(INTERP_KERNEL::Exception)
6970 {
6971   checkAllocated();
6972   int nbComp=getNumberOfComponents();
6973   int nbOfTuples=getNumberOfTuples();
6974   for(const int *z=bgComp;z!=endComp;z++)
6975     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
6976   int *pt=getPointer();
6977   for(const int *w=bgTuples;w!=endTuples;w++)
6978     for(const int *z=bgComp;z!=endComp;z++)
6979       {
6980         DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
6981         pt[(*w)*nbComp+(*z)]=a;
6982       }
6983 }
6984
6985 /*!
6986  * Copy all values from another DataArrayInt (\a a) into specified tuples and 
6987  * components of \a this array. Textual data is not copied.
6988  * The tuples to assign to are defined by a C array of indices.
6989  * The components to assign to are defined by three values similar to parameters of
6990  * the Python function \c range(\c start,\c stop,\c step).
6991  * There are two *modes of usage*:
6992  * - If \a a->getNbOfElems() equals to number of values to assign to, then every value
6993  *   of \a a is assigned to its own location within \a this array. 
6994  * - If \a a includes one tuple, then all values of \a a are assigned to the specified
6995  *   components of every specified tuple of \a this array. In this mode it is required
6996  *   that \a a->getNumberOfComponents() equals to the number of specified components.
6997  *
6998  *  \param [in] a - the array to copy values from.
6999  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
7000  *              assign values of \a a to.
7001  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
7002  *              pointer to a tuple index <em>(pi)</em> varies as this: 
7003  *              \a bgTuples <= \a pi < \a endTuples.
7004  *  \param [in] bgComp - index of the first component of \a this array to assign to.
7005  *  \param [in] endComp - index of the component before which the components to assign
7006  *              to are located.
7007  *  \param [in] stepComp - index increment to get index of the next component to assign to.
7008  *  \param [in] strictCompoCompare - this parameter is checked only in the first
7009  *               *mode of usage*; if \a strictCompoCompare is \a true (default), 
7010  *               then \a a->getNumberOfComponents() must be equal 
7011  *               to the number of specified columns, else this is not required.
7012  *  \throw If \a a is NULL.
7013  *  \throw If \a a is not allocated.
7014  *  \throw If \a this is not allocated.
7015  *  \throw If any index of tuple given by \a bgTuples is out of a valid range for 
7016  *         \a this array.
7017  *  \throw In the first *mode of usage*, if <em>strictCompoCompare == true </em> and
7018  *         if <em> a->getNumberOfComponents()</em> is unequal to the number of components
7019  *         defined by <em>(bgComp,endComp,stepComp)</em>.
7020  *  \throw In the second *mode of usage*, if \a a->getNumberOfTuples() != 1 or
7021  *         <em> a->getNumberOfComponents()</em> is unequal to the number of components
7022  *         defined by <em>(bgComp,endComp,stepComp)</em>.
7023  *  \throw If parameters specifying components to assign to, do not give a
7024  *            non-empty range of increasing indices or indices are out of a valid range
7025  *            for \this array.
7026  *
7027  *  \ref cpp_mcdataarrayint_setpartofvalues3 "Here is a Python example".
7028  */
7029 void DataArrayInt::setPartOfValues3(const DataArrayInt *a, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare) throw(INTERP_KERNEL::Exception)
7030 {
7031   if(!a)
7032     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValues3 : DataArrayInt pointer in input is NULL !");
7033   const char msg[]="DataArrayInt::setPartOfValues3";
7034   checkAllocated();
7035   a->checkAllocated();
7036   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
7037   int nbComp=getNumberOfComponents();
7038   int nbOfTuples=getNumberOfTuples();
7039   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
7040   int newNbOfTuples=(int)std::distance(bgTuples,endTuples);
7041   bool assignTech=true;
7042   if(a->getNbOfElems()==newNbOfTuples*newNbOfComp)
7043     {
7044       if(strictCompoCompare)
7045         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
7046     }
7047   else
7048     {
7049       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
7050       assignTech=false;
7051     }
7052   int *pt=getPointer()+bgComp;
7053   const int *srcPt=a->getConstPointer();
7054   if(assignTech)
7055     {
7056       for(const int *w=bgTuples;w!=endTuples;w++)
7057         for(int j=0;j<newNbOfComp;j++,srcPt++)
7058           {
7059             DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
7060             pt[(*w)*nbComp+j*stepComp]=*srcPt;
7061           }
7062     }
7063   else
7064     {
7065       for(const int *w=bgTuples;w!=endTuples;w++)
7066         {
7067           const int *srcPt2=srcPt;
7068           for(int j=0;j<newNbOfComp;j++,srcPt2++)
7069             {
7070               DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
7071               pt[(*w)*nbComp+j*stepComp]=*srcPt2;
7072             }
7073         }
7074     }
7075 }
7076
7077 /*!
7078  * Assign a given value to values at specified tuples and components of \a this array.
7079  * The tuples to assign to are defined by a C array of indices.
7080  * The components to assign to are defined by three values similar to parameters of
7081  * the Python function \c range(\c start,\c stop,\c step).
7082  *  \param [in] a - the value to assign.
7083  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
7084  *              assign \a a to.
7085  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
7086  *              pointer to a tuple index <em>(pi)</em> varies as this: 
7087  *              \a bgTuples <= \a pi < \a endTuples.
7088  *  \param [in] bgComp - index of the first component of \a this array to assign to.
7089  *  \param [in] endComp - index of the component before which the components to assign
7090  *              to are located.
7091  *  \param [in] stepComp - index increment to get index of the next component to assign to.
7092  *  \throw If \a this is not allocated.
7093  *  \throw If any index of tuple given by \a bgTuples is out of a valid range for 
7094  *         \a this array.
7095  *  \throw If parameters specifying components to assign to, do not give a
7096  *            non-empty range of increasing indices or indices are out of a valid range
7097  *            for \this array.
7098  *
7099  *  \ref cpp_mcdataarrayint_setpartofvaluessimple3 "Here is a Python example".
7100  */
7101 void DataArrayInt::setPartOfValuesSimple3(int a, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp) throw(INTERP_KERNEL::Exception)
7102 {
7103   const char msg[]="DataArrayInt::setPartOfValuesSimple3";
7104   checkAllocated();
7105   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
7106   int nbComp=getNumberOfComponents();
7107   int nbOfTuples=getNumberOfTuples();
7108   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
7109   int *pt=getPointer()+bgComp;
7110   for(const int *w=bgTuples;w!=endTuples;w++)
7111     for(int j=0;j<newNbOfComp;j++)
7112       {
7113         DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
7114         pt[(*w)*nbComp+j*stepComp]=a;
7115       }
7116 }
7117
7118 void DataArrayInt::setPartOfValues4(const DataArrayInt *a, int bgTuples, int endTuples, int stepTuples, const int *bgComp, const int *endComp, bool strictCompoCompare) throw(INTERP_KERNEL::Exception)
7119 {
7120   if(!a)
7121     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValues4 : input DataArrayInt is NULL !");
7122   const char msg[]="DataArrayInt::setPartOfValues4";
7123   checkAllocated();
7124   a->checkAllocated();
7125   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
7126   int newNbOfComp=(int)std::distance(bgComp,endComp);
7127   int nbComp=getNumberOfComponents();
7128   for(const int *z=bgComp;z!=endComp;z++)
7129     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
7130   int nbOfTuples=getNumberOfTuples();
7131   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
7132   bool assignTech=true;
7133   if(a->getNbOfElems()==newNbOfTuples*newNbOfComp)
7134     {
7135       if(strictCompoCompare)
7136         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
7137     }
7138   else
7139     {
7140       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
7141       assignTech=false;
7142     }
7143   const int *srcPt=a->getConstPointer();
7144   int *pt=getPointer()+bgTuples*nbComp;
7145   if(assignTech)
7146     {
7147       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
7148         for(const int *z=bgComp;z!=endComp;z++,srcPt++)
7149           pt[*z]=*srcPt;
7150     }
7151   else
7152     {
7153       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
7154         {
7155           const int *srcPt2=srcPt;
7156           for(const int *z=bgComp;z!=endComp;z++,srcPt2++)
7157             pt[*z]=*srcPt2;
7158         }
7159     }
7160 }
7161
7162 void DataArrayInt::setPartOfValuesSimple4(int a, int bgTuples, int endTuples, int stepTuples, const int *bgComp, const int *endComp) throw(INTERP_KERNEL::Exception)
7163 {
7164   const char msg[]="DataArrayInt::setPartOfValuesSimple4";
7165   checkAllocated();
7166   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
7167   int nbComp=getNumberOfComponents();
7168   for(const int *z=bgComp;z!=endComp;z++)
7169     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
7170   int nbOfTuples=getNumberOfTuples();
7171   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
7172   int *pt=getPointer()+bgTuples*nbComp;
7173   for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
7174     for(const int *z=bgComp;z!=endComp;z++)
7175       pt[*z]=a;
7176 }
7177
7178 /*!
7179  * Copy some tuples from another DataArrayInt into specified tuples
7180  * of \a this array. Textual data is not copied. Both arrays must have equal number of
7181  * components.
7182  * Both the tuples to assign and the tuples to assign to are defined by a DataArrayInt.
7183  * All components of selected tuples are copied.
7184  *  \param [in] a - the array to copy values from.
7185  *  \param [in] tuplesSelec - the array specifying both source tuples of \a a and
7186  *              target tuples of \a this. \a tuplesSelec has two components, and the
7187  *              first component specifies index of the source tuple and the second
7188  *              one specifies index of the target tuple.
7189  *  \throw If \a this is not allocated.
7190  *  \throw If \a a is NULL.
7191  *  \throw If \a a is not allocated.
7192  *  \throw If \a tuplesSelec is NULL.
7193  *  \throw If \a tuplesSelec is not allocated.
7194  *  \throw If <em>this->getNumberOfComponents() != a->getNumberOfComponents()</em>.
7195  *  \throw If \a tuplesSelec->getNumberOfComponents() != 2.
7196  *  \throw If any tuple index given by \a tuplesSelec is out of a valid range for 
7197  *         the corresponding (\a this or \a a) array.
7198  */
7199 void DataArrayInt::setPartOfValuesAdv(const DataArrayInt *a, const DataArrayInt *tuplesSelec) throw(INTERP_KERNEL::Exception)
7200 {
7201   if(!a || !tuplesSelec)
7202     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValuesAdv : DataArrayInt pointer in input is NULL !");
7203   checkAllocated();
7204   a->checkAllocated();
7205   tuplesSelec->checkAllocated();
7206   int nbOfComp=getNumberOfComponents();
7207   if(nbOfComp!=a->getNumberOfComponents())
7208     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValuesAdv : This and a do not have the same number of components !");
7209   if(tuplesSelec->getNumberOfComponents()!=2)
7210     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValuesAdv : Expecting to have a tuple selector DataArrayInt instance with exactly 2 components !");
7211   int thisNt=getNumberOfTuples();
7212   int aNt=a->getNumberOfTuples();
7213   int *valsToSet=getPointer();
7214   const int *valsSrc=a->getConstPointer();
7215   for(const int *tuple=tuplesSelec->begin();tuple!=tuplesSelec->end();tuple+=2)
7216     {
7217       if(tuple[1]>=0 && tuple[1]<aNt)
7218         {
7219           if(tuple[0]>=0 && tuple[0]<thisNt)
7220             std::copy(valsSrc+nbOfComp*tuple[1],valsSrc+nbOfComp*(tuple[1]+1),valsToSet+nbOfComp*tuple[0]);
7221           else
7222             {
7223               std::ostringstream oss; oss << "DataArrayInt::setPartOfValuesAdv : Tuple #" << std::distance(tuplesSelec->begin(),tuple)/2;
7224               oss << " of 'tuplesSelec' request of tuple id #" << tuple[0] << " in 'this' ! It should be in [0," << thisNt << ") !";
7225               throw INTERP_KERNEL::Exception(oss.str().c_str());
7226             }
7227         }
7228       else
7229         {
7230           std::ostringstream oss; oss << "DataArrayInt::setPartOfValuesAdv : Tuple #" << std::distance(tuplesSelec->begin(),tuple)/2;
7231           oss << " of 'tuplesSelec' request of tuple id #" << tuple[1] << " in 'a' ! It should be in [0," << aNt << ") !";
7232           throw INTERP_KERNEL::Exception(oss.str().c_str());
7233         }
7234     }
7235 }
7236
7237 /*!
7238  * Copy some tuples from another DataArrayInt (\a a) into contiguous tuples
7239  * of \a this array. Textual data is not copied. Both arrays must have equal number of
7240  * components.
7241  * The tuples to assign to are defined by index of the first tuple, and
7242  * their number is defined by \a tuplesSelec->getNumberOfTuples().
7243  * The tuples to copy are defined by values of a DataArrayInt.
7244  * All components of selected tuples are copied.
7245  *  \param [in] tupleIdStart - index of the first tuple of \a this array to assign
7246  *              values to.
7247  *  \param [in] a - the array to copy values from.
7248  *  \param [in] tuplesSelec - the array specifying tuples of \a a to copy.
7249  *  \throw If \a this is not allocated.
7250  *  \throw If \a a is NULL.
7251  *  \throw If \a a is not allocated.
7252  *  \throw If \a tuplesSelec is NULL.
7253  *  \throw If \a tuplesSelec is not allocated.
7254  *  \throw If <em>this->getNumberOfComponents() != a->getNumberOfComponents()</em>.
7255  *  \throw If \a tuplesSelec->getNumberOfComponents() != 1.
7256  *  \throw If <em>tupleIdStart + tuplesSelec->getNumberOfTuples() > this->getNumberOfTuples().</em>
7257  *  \throw If any tuple index given by \a tuplesSelec is out of a valid range for 
7258  *         \a a array.
7259  */
7260 void DataArrayInt::setContigPartOfSelectedValues(int tupleIdStart, const DataArrayInt*a, const DataArrayInt *tuplesSelec) throw(INTERP_KERNEL::Exception)
7261 {
7262   checkAllocated();
7263   a->checkAllocated();
7264   tuplesSelec->checkAllocated();
7265   int nbOfComp=getNumberOfComponents();
7266   if(nbOfComp!=a->getNumberOfComponents())
7267     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues : This and a do not have the same number of components !");
7268   if(tuplesSelec->getNumberOfComponents()!=1)
7269     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues : Expecting to have a tuple selector DataArrayInt instance with exactly 1 component !");
7270   int thisNt=getNumberOfTuples();
7271   int aNt=a->getNumberOfTuples();
7272   int nbOfTupleToWrite=tuplesSelec->getNumberOfTuples();
7273   int *valsToSet=getPointer()+tupleIdStart*nbOfComp;
7274   if(tupleIdStart+nbOfTupleToWrite>thisNt)
7275     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues : invalid number range of values to write !");
7276   const int *valsSrc=a->getConstPointer();
7277   for(const int *tuple=tuplesSelec->begin();tuple!=tuplesSelec->end();tuple++,valsToSet+=nbOfComp)
7278     {
7279       if(*tuple>=0 && *tuple<aNt)
7280         {
7281           std::copy(valsSrc+nbOfComp*(*tuple),valsSrc+nbOfComp*(*tuple+1),valsToSet);
7282         }
7283       else
7284         {
7285           std::ostringstream oss; oss << "DataArrayInt::setContigPartOfSelectedValues : Tuple #" << std::distance(tuplesSelec->begin(),tuple);
7286           oss << " of 'tuplesSelec' request of tuple id #" << *tuple << " in 'a' ! It should be in [0," << aNt << ") !";
7287           throw INTERP_KERNEL::Exception(oss.str().c_str());
7288         }
7289     }
7290 }
7291
7292 /*!
7293  * Copy some tuples from another DataArrayInt (\a a) into contiguous tuples
7294  * of \a this array. Textual data is not copied. Both arrays must have equal number of
7295  * components.
7296  * The tuples to copy are defined by three values similar to parameters of
7297  * the Python function \c range(\c start,\c stop,\c step).
7298  * The tuples to assign to are defined by index of the first tuple, and
7299  * their number is defined by number of tuples to copy.
7300  * All components of selected tuples are copied.
7301  *  \param [in] tupleIdStart - index of the first tuple of \a this array to assign
7302  *              values to.
7303  *  \param [in] a - the array to copy values from.
7304  *  \param [in] bg - index of the first tuple to copy of the array \a a.
7305  *  \param [in] end2 - index of the tuple of \a a before which the tuples to copy
7306  *              are located.
7307  *  \param [in] step - index increment to get index of the next tuple to copy.
7308  *  \throw If \a this is not allocated.
7309  *  \throw If \a a is NULL.
7310  *  \throw If \a a is not allocated.
7311  *  \throw If <em>this->getNumberOfComponents() != a->getNumberOfComponents()</em>.
7312  *  \throw If <em>tupleIdStart + len(range(bg,end2,step)) > this->getNumberOfTuples().</em>
7313  *  \throw If parameters specifying tuples to copy, do not give a
7314  *            non-empty range of increasing indices or indices are out of a valid range
7315  *            for the array \a a.
7316  */
7317 void DataArrayInt::setContigPartOfSelectedValues2(int tupleIdStart, const DataArrayInt *a, int bg, int end2, int step) throw(INTERP_KERNEL::Exception)
7318 {
7319   checkAllocated();
7320   a->checkAllocated();
7321   int nbOfComp=getNumberOfComponents();
7322   const char msg[]="DataArrayInt::setContigPartOfSelectedValues2";
7323   int nbOfTupleToWrite=DataArray::GetNumberOfItemGivenBES(bg,end2,step,msg);
7324   if(nbOfComp!=a->getNumberOfComponents())
7325     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues2 : This and a do not have the same number of components !");
7326   int thisNt=getNumberOfTuples();
7327   int aNt=a->getNumberOfTuples();
7328   int *valsToSet=getPointer()+tupleIdStart*nbOfComp;
7329   if(tupleIdStart+nbOfTupleToWrite>thisNt)
7330     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues2 : invalid number range of values to write !");
7331   if(end2>aNt)
7332     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues2 : invalid range of values to read !");
7333   const int *valsSrc=a->getConstPointer()+bg*nbOfComp;
7334   for(int i=0;i<nbOfTupleToWrite;i++,valsToSet+=nbOfComp,valsSrc+=step*nbOfComp)
7335     {
7336       std::copy(valsSrc,valsSrc+nbOfComp,valsToSet);
7337     }
7338 }
7339
7340 /*!
7341  * Returns a value located at specified tuple and component.
7342  * This method is equivalent to DataArrayInt::getIJ() except that validity of
7343  * parameters is checked. So this method is safe but expensive if used to go through
7344  * all values of \a this.
7345  *  \param [in] tupleId - index of tuple of interest.
7346  *  \param [in] compoId - index of component of interest.
7347  *  \return double - value located by \a tupleId and \a compoId.
7348  *  \throw If \a this is not allocated.
7349  *  \throw If condition <em>( 0 <= tupleId < this->getNumberOfTuples() )</em> is violated.
7350  *  \throw If condition <em>( 0 <= compoId < this->getNumberOfComponents() )</em> is violated.
7351  */
7352 int DataArrayInt::getIJSafe(int tupleId, int compoId) const throw(INTERP_KERNEL::Exception)
7353 {
7354   checkAllocated();
7355   if(tupleId<0 || tupleId>=getNumberOfTuples())
7356     {
7357       std::ostringstream oss; oss << "DataArrayInt::getIJSafe : request for tupleId " << tupleId << " should be in [0," << getNumberOfTuples() << ") !";
7358       throw INTERP_KERNEL::Exception(oss.str().c_str());
7359     }
7360   if(compoId<0 || compoId>=getNumberOfComponents())
7361     {
7362       std::ostringstream oss; oss << "DataArrayInt::getIJSafe : request for compoId " << compoId << " should be in [0," << getNumberOfComponents() << ") !";
7363       throw INTERP_KERNEL::Exception(oss.str().c_str());
7364     }
7365   return _mem[tupleId*((int)_info_on_compo.size())+compoId];
7366 }
7367
7368 /*!
7369  * Returns the last value of \a this. 
7370  *  \return double - the last value of \a this array.
7371  *  \throw If \a this is not allocated.
7372  *  \throw If \a this->getNumberOfComponents() != 1.
7373  *  \throw If \a this->getNumberOfTuples() < 1.
7374  */
7375 int DataArrayInt::back() const throw(INTERP_KERNEL::Exception)
7376 {
7377   checkAllocated();
7378   if(getNumberOfComponents()!=1)
7379     throw INTERP_KERNEL::Exception("DataArrayInt::back : number of components not equal to one !");
7380   int nbOfTuples=getNumberOfTuples();
7381   if(nbOfTuples<1)
7382     throw INTERP_KERNEL::Exception("DataArrayInt::back : number of tuples must be >= 1 !");
7383   return *(getConstPointer()+nbOfTuples-1);
7384 }
7385
7386 /*!
7387  * Assign pointer to one array to a pointer to another appay. Reference counter of
7388  * \a arrayToSet is incremented / decremented.
7389  *  \param [in] newArray - the pointer to array to assign to \a arrayToSet.
7390  *  \param [in,out] arrayToSet - the pointer to array to assign to.
7391  */
7392 void DataArrayInt::SetArrayIn(DataArrayInt *newArray, DataArrayInt* &arrayToSet)
7393 {
7394   if(newArray!=arrayToSet)
7395     {
7396       if(arrayToSet)
7397         arrayToSet->decrRef();
7398       arrayToSet=newArray;
7399       if(arrayToSet)
7400         arrayToSet->incrRef();
7401     }
7402 }
7403
7404 DataArrayIntIterator *DataArrayInt::iterator() throw(INTERP_KERNEL::Exception)
7405 {
7406   return new DataArrayIntIterator(this);
7407 }
7408
7409 /*!
7410  * Creates a new DataArrayInt containing IDs (indices) of tuples holding value equal to a
7411  * given one.
7412  *  \param [in] val - the value to find within \a this.
7413  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
7414  *          array using decrRef() as it is no more needed.
7415  *  \throw If \a this is not allocated.
7416  *  \throw If \a this->getNumberOfComponents() != 1.
7417  */
7418 DataArrayInt *DataArrayInt::getIdsEqual(int val) const throw(INTERP_KERNEL::Exception)
7419 {
7420   checkAllocated();
7421   if(getNumberOfComponents()!=1)
7422     throw INTERP_KERNEL::Exception("DataArrayInt::getIdsEqual : the array must have only one component, you can call 'rearrange' method before !");
7423   const int *cptr=getConstPointer();
7424   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
7425   int nbOfTuples=getNumberOfTuples();
7426   for(int i=0;i<nbOfTuples;i++,cptr++)
7427     if(*cptr==val)
7428       ret->pushBackSilent(i);
7429   return ret.retn();
7430 }
7431
7432 /*!
7433  * Creates a new DataArrayInt containing IDs (indices) of tuples holding value \b not
7434  * equal to a given one. 
7435  *  \param [in] val - the value to ignore within \a this.
7436  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
7437  *          array using decrRef() as it is no more needed.
7438  *  \throw If \a this is not allocated.
7439  *  \throw If \a this->getNumberOfComponents() != 1.
7440  */
7441 DataArrayInt *DataArrayInt::getIdsNotEqual(int val) const throw(INTERP_KERNEL::Exception)
7442 {
7443   checkAllocated();
7444   if(getNumberOfComponents()!=1)
7445     throw INTERP_KERNEL::Exception("DataArrayInt::getIdsNotEqual : the array must have only one component, you can call 'rearrange' method before !");
7446   const int *cptr=getConstPointer();
7447   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
7448   int nbOfTuples=getNumberOfTuples();
7449   for(int i=0;i<nbOfTuples;i++,cptr++)
7450     if(*cptr!=val)
7451       ret->pushBackSilent(i);
7452   return ret.retn();
7453 }
7454
7455
7456 /*!
7457  * Assigns \a newValue to all elements holding \a oldValue within \a this
7458  * one-dimensional array.
7459  *  \param [in] oldValue - the value to replace.
7460  *  \param [in] newValue - the value to assign.
7461  *  \return int - number of replacements performed.
7462  *  \throw If \a this is not allocated.
7463  *  \throw If \a this->getNumberOfComponents() != 1.
7464  */
7465 int DataArrayInt::changeValue(int oldValue, int newValue) throw(INTERP_KERNEL::Exception)
7466 {
7467   checkAllocated();
7468   if(getNumberOfComponents()!=1)
7469     throw INTERP_KERNEL::Exception("DataArrayInt::changeValue : the array must have only one component, you can call 'rearrange' method before !");
7470   int *start=getPointer();
7471   int *end2=start+getNbOfElems();
7472   int ret=0;
7473   for(int *val=start;val!=end2;val++)
7474     {
7475       if(*val==oldValue)
7476         {
7477           *val=newValue;
7478           ret++;
7479         }
7480     }
7481   return ret;
7482 }
7483
7484 /*!
7485  * Creates a new DataArrayInt containing IDs (indices) of tuples holding value equal to
7486  * one of given values.
7487  *  \param [in] valsBg - an array of values to find within \a this array.
7488  *  \param [in] valsEnd - specifies the end of the array \a valsBg, so that
7489  *              the last value of \a valsBg is \a valsEnd[ -1 ].
7490  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
7491  *          array using decrRef() as it is no more needed.
7492  *  \throw If \a this->getNumberOfComponents() != 1.
7493  */
7494 DataArrayInt *DataArrayInt::getIdsEqualList(const int *valsBg, const int *valsEnd) const throw(INTERP_KERNEL::Exception)
7495 {
7496   if(getNumberOfComponents()!=1)
7497     throw INTERP_KERNEL::Exception("DataArrayInt::getIdsEqualList : the array must have only one component, you can call 'rearrange' method before !");
7498   std::set<int> vals2(valsBg,valsEnd);
7499   const int *cptr=getConstPointer();
7500   std::vector<int> res;
7501   int nbOfTuples=getNumberOfTuples();
7502   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
7503   for(int i=0;i<nbOfTuples;i++,cptr++)
7504     if(vals2.find(*cptr)!=vals2.end())
7505       ret->pushBackSilent(i);
7506   return ret.retn();
7507 }
7508
7509 /*!
7510  * Creates a new DataArrayInt containing IDs (indices) of tuples holding values \b not
7511  * equal to any of given values.
7512  *  \param [in] valsBg - an array of values to ignore within \a this array.
7513  *  \param [in] valsEnd - specifies the end of the array \a valsBg, so that
7514  *              the last value of \a valsBg is \a valsEnd[ -1 ].
7515  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
7516  *          array using decrRef() as it is no more needed.
7517  *  \throw If \a this->getNumberOfComponents() != 1.
7518  */
7519 DataArrayInt *DataArrayInt::getIdsNotEqualList(const int *valsBg, const int *valsEnd) const throw(INTERP_KERNEL::Exception)
7520 {
7521   if(getNumberOfComponents()!=1)
7522     throw INTERP_KERNEL::Exception("DataArrayInt::getIdsNotEqualList : the array must have only one component, you can call 'rearrange' method before !");
7523   std::set<int> vals2(valsBg,valsEnd);
7524   const int *cptr=getConstPointer();
7525   std::vector<int> res;
7526   int nbOfTuples=getNumberOfTuples();
7527   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
7528   for(int i=0;i<nbOfTuples;i++,cptr++)
7529     if(vals2.find(*cptr)==vals2.end())
7530       ret->pushBackSilent(i);
7531   return ret.retn();
7532 }
7533
7534 /*!
7535  * This method is an extension of DataArrayInt::locateValue method because this method works for DataArrayInt with
7536  * any number of components excepted 0 (an INTERP_KERNEL::Exception is thrown in this case).
7537  * This method searches in \b this is there is a tuple that matched the input parameter \b tupl.
7538  * If any the tuple id is returned. If not -1 is returned.
7539  * 
7540  * This method throws an INTERP_KERNEL::Exception if the number of components in \b this mismatches with the size of
7541  * the input vector. An INTERP_KERNEL::Exception is thrown too if \b this is not allocated.
7542  *
7543  * \return tuple id where \b tupl is. -1 if no such tuple exists in \b this.
7544  * \sa DataArrayInt::search, DataArrayInt::presenceOfTuple.
7545  */
7546 int DataArrayInt::locateTuple(const std::vector<int>& tupl) const throw(INTERP_KERNEL::Exception)
7547 {
7548   checkAllocated();
7549   int nbOfCompo=getNumberOfComponents();
7550   if(nbOfCompo==0)
7551     throw INTERP_KERNEL::Exception("DataArrayInt::locateTuple : 0 components in 'this' !");
7552   if(nbOfCompo!=(int)tupl.size())
7553     {
7554       std::ostringstream oss; oss << "DataArrayInt::locateTuple : 'this' contains " << nbOfCompo << " components and searching for a tuple of length " << tupl.size() << " !";
7555       throw INTERP_KERNEL::Exception(oss.str().c_str());
7556     }
7557   const int *cptr=getConstPointer();
7558   int nbOfVals=getNbOfElems();
7559   for(const int *work=cptr;work!=cptr+nbOfVals;)
7560     {
7561       work=std::search(work,cptr+nbOfVals,tupl.begin(),tupl.end());
7562       if(work!=cptr+nbOfVals)
7563         {
7564           if(std::distance(cptr,work)%nbOfCompo!=0)
7565             work++;
7566           else
7567             return std::distance(cptr,work)/nbOfCompo;
7568         }
7569     }
7570   return -1;
7571 }
7572
7573 /*!
7574  * This method searches the sequence specified in input parameter \b vals in \b this.
7575  * This works only for DataArrayInt having number of components equal to one (if not an INTERP_KERNEL::Exception will be thrown).
7576  * This method differs from DataArrayInt::locateTuple in that the position is internal raw data is not considered here contrary to DataArrayInt::locateTuple.
7577  * \sa DataArrayInt::locateTuple
7578  */
7579 int DataArrayInt::search(const std::vector<int>& vals) const throw(INTERP_KERNEL::Exception)
7580 {
7581   checkAllocated();
7582   int nbOfCompo=getNumberOfComponents();
7583   if(nbOfCompo!=1)
7584     throw INTERP_KERNEL::Exception("DataArrayInt::search : works only for DataArrayInt instance with one component !");
7585   const int *cptr=getConstPointer();
7586   int nbOfVals=getNbOfElems();
7587   const int *loc=std::search(cptr,cptr+nbOfVals,vals.begin(),vals.end());
7588   if(loc!=cptr+nbOfVals)
7589     return std::distance(cptr,loc);
7590   return -1;
7591 }
7592
7593 /*!
7594  * This method expects to be called when number of components of this is equal to one.
7595  * This method returns the tuple id, if it exists, of the first tuple equal to \b value.
7596  * If not any tuple contains \b value -1 is returned.
7597  * \sa DataArrayInt::presenceOfValue
7598  */
7599 int DataArrayInt::locateValue(int value) const throw(INTERP_KERNEL::Exception)
7600 {
7601   checkAllocated();
7602   if(getNumberOfComponents()!=1)
7603     throw INTERP_KERNEL::Exception("DataArrayInt::presenceOfValue : the array must have only one component, you can call 'rearrange' method before !");
7604   const int *cptr=getConstPointer();
7605   int nbOfTuples=getNumberOfTuples();
7606   const int *ret=std::find(cptr,cptr+nbOfTuples,value);
7607   if(ret!=cptr+nbOfTuples)
7608     return std::distance(cptr,ret);
7609   return -1;
7610 }
7611
7612 /*!
7613  * This method expects to be called when number of components of this is equal to one.
7614  * This method returns the tuple id, if it exists, of the first tuple so that the value is contained in \b vals.
7615  * If not any tuple contains one of the values contained in 'vals' false is returned.
7616  * \sa DataArrayInt::presenceOfValue
7617  */
7618 int DataArrayInt::locateValue(const std::vector<int>& vals) const throw(INTERP_KERNEL::Exception)
7619 {
7620   checkAllocated();
7621   if(getNumberOfComponents()!=1)
7622     throw INTERP_KERNEL::Exception("DataArrayInt::presenceOfValue : the array must have only one component, you can call 'rearrange' method before !");
7623   std::set<int> vals2(vals.begin(),vals.end());
7624   const int *cptr=getConstPointer();
7625   int nbOfTuples=getNumberOfTuples();
7626   for(const int *w=cptr;w!=cptr+nbOfTuples;w++)
7627     if(vals2.find(*w)!=vals2.end())
7628       return std::distance(cptr,w);
7629   return -1;
7630 }
7631
7632 /*!
7633  * This method is an extension of DataArrayInt::presenceOfValue method because this method works for DataArrayInt with
7634  * any number of components excepted 0 (an INTERP_KERNEL::Exception is thrown in this case).
7635  * This method searches in \b this is there is a tuple that matched the input parameter \b tupl.
7636  * This method throws an INTERP_KERNEL::Exception if the number of components in \b this mismatches with the size of
7637  * the input vector. An INTERP_KERNEL::Exception is thrown too if \b this is not allocated.
7638  * \sa DataArrayInt::locateTuple
7639  */
7640 bool DataArrayInt::presenceOfTuple(const std::vector<int>& tupl) const throw(INTERP_KERNEL::Exception)
7641 {
7642   return locateTuple(tupl)!=-1;
7643 }
7644
7645
7646 /*!
7647  * Returns \a true if a given value is present within \a this one-dimensional array.
7648  *  \param [in] value - the value to find within \a this array.
7649  *  \return bool - \a true in case if \a value is present within \a this array.
7650  *  \throw If \a this is not allocated.
7651  *  \throw If \a this->getNumberOfComponents() != 1.
7652  *  \sa locateValue()
7653  */
7654 bool DataArrayInt::presenceOfValue(int value) const throw(INTERP_KERNEL::Exception)
7655 {
7656   return locateValue(value)!=-1;
7657 }
7658
7659 /*!
7660  * This method expects to be called when number of components of this is equal to one.
7661  * This method returns true if it exists a tuple so that the value is contained in \b vals.
7662  * If not any tuple contains one of the values contained in 'vals' false is returned.
7663  * \sa DataArrayInt::locateValue
7664  */
7665 bool DataArrayInt::presenceOfValue(const std::vector<int>& vals) const throw(INTERP_KERNEL::Exception)
7666 {
7667   return locateValue(vals)!=-1;
7668 }
7669
7670 /*!
7671  * Accumulates values of each component of \a this array.
7672  *  \param [out] res - an array of length \a this->getNumberOfComponents(), allocated 
7673  *         by the caller, that is filled by this method with sum value for each
7674  *         component.
7675  *  \throw If \a this is not allocated.
7676  */
7677 void DataArrayInt::accumulate(int *res) const throw(INTERP_KERNEL::Exception)
7678 {
7679   checkAllocated();
7680   const int *ptr=getConstPointer();
7681   int nbTuple=getNumberOfTuples();
7682   int nbComps=getNumberOfComponents();
7683   std::fill(res,res+nbComps,0);
7684   for(int i=0;i<nbTuple;i++)
7685     std::transform(ptr+i*nbComps,ptr+(i+1)*nbComps,res,res,std::plus<int>());
7686 }
7687
7688 int DataArrayInt::accumulate(int compId) const throw(INTERP_KERNEL::Exception)
7689 {
7690   checkAllocated();
7691   const int *ptr=getConstPointer();
7692   int nbTuple=getNumberOfTuples();
7693   int nbComps=getNumberOfComponents();
7694   if(compId<0 || compId>=nbComps)
7695     throw INTERP_KERNEL::Exception("DataArrayInt::accumulate : Invalid compId specified : No such nb of components !");
7696   int ret=0;
7697   for(int i=0;i<nbTuple;i++)
7698     ret+=ptr[i*nbComps+compId];
7699   return ret;
7700 }
7701
7702 /*!
7703  * Returns a new DataArrayInt by concatenating two given arrays, so that (1) the number
7704  * of tuples in the result array is <em> a1->getNumberOfTuples() + a2->getNumberOfTuples() -
7705  * offsetA2</em> and (2)
7706  * the number of component in the result array is same as that of each of given arrays.
7707  * First \a offsetA2 tuples of \a a2 are skipped and thus are missing from the result array.
7708  * Info on components is copied from the first of the given arrays. Number of components
7709  * in the given arrays must be the same.
7710  *  \param [in] a1 - an array to include in the result array.
7711  *  \param [in] a2 - another array to include in the result array.
7712  *  \param [in] offsetA2 - number of tuples of \a a2 to skip.
7713  *  \return DataArrayInt * - the new instance of DataArrayInt.
7714  *          The caller is to delete this result array using decrRef() as it is no more
7715  *          needed.
7716  *  \throw If either \a a1 or \a a2 is NULL.
7717  *  \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents().
7718  */
7719 DataArrayInt *DataArrayInt::Aggregate(const DataArrayInt *a1, const DataArrayInt *a2, int offsetA2)
7720 {
7721   if(!a1 || !a2)
7722     throw INTERP_KERNEL::Exception("DataArrayInt::Aggregate : input DataArrayInt instance is NULL !");
7723   int nbOfComp=a1->getNumberOfComponents();
7724   if(nbOfComp!=a2->getNumberOfComponents())
7725     throw INTERP_KERNEL::Exception("Nb of components mismatch for array Aggregation !");
7726   int nbOfTuple1=a1->getNumberOfTuples();
7727   int nbOfTuple2=a2->getNumberOfTuples();
7728   DataArrayInt *ret=DataArrayInt::New();
7729   ret->alloc(nbOfTuple1+nbOfTuple2-offsetA2,nbOfComp);
7730   int *pt=std::copy(a1->getConstPointer(),a1->getConstPointer()+nbOfTuple1*nbOfComp,ret->getPointer());
7731   std::copy(a2->getConstPointer()+offsetA2*nbOfComp,a2->getConstPointer()+nbOfTuple2*nbOfComp,pt);
7732   ret->copyStringInfoFrom(*a1);
7733   return ret;
7734 }
7735
7736 /*!
7737  * Returns a new DataArrayInt by concatenating all given arrays, so that (1) the number
7738  * of tuples in the result array is a sum of the number of tuples of given arrays and (2)
7739  * the number of component in the result array is same as that of each of given arrays.
7740  * Info on components is copied from the first of the given arrays. Number of components
7741  * in the given arrays must be  the same.
7742  *  \param [in] arr - a sequence of arrays to include in the result array.
7743  *  \return DataArrayInt * - the new instance of DataArrayInt.
7744  *          The caller is to delete this result array using decrRef() as it is no more
7745  *          needed.
7746  *  \throw If all arrays within \a arr are NULL.
7747  *  \throw If getNumberOfComponents() of arrays within \a arr.
7748  */
7749 DataArrayInt *DataArrayInt::Aggregate(const std::vector<const DataArrayInt *>& arr) throw(INTERP_KERNEL::Exception)
7750 {
7751   std::vector<const DataArrayInt *> a;
7752   for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
7753     if(*it4)
7754       a.push_back(*it4);
7755   if(a.empty())
7756     throw INTERP_KERNEL::Exception("DataArrayInt::Aggregate : input list must be NON EMPTY !");
7757   std::vector<const DataArrayInt *>::const_iterator it=a.begin();
7758   int nbOfComp=(*it)->getNumberOfComponents();
7759   int nbt=(*it++)->getNumberOfTuples();
7760   for(int i=1;it!=a.end();it++,i++)
7761     {
7762       if((*it)->getNumberOfComponents()!=nbOfComp)
7763         throw INTERP_KERNEL::Exception("DataArrayInt::Aggregate : Nb of components mismatch for array aggregation !");
7764       nbt+=(*it)->getNumberOfTuples();
7765     }
7766   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
7767   ret->alloc(nbt,nbOfComp);
7768   int *pt=ret->getPointer();
7769   for(it=a.begin();it!=a.end();it++)
7770     pt=std::copy((*it)->getConstPointer(),(*it)->getConstPointer()+(*it)->getNbOfElems(),pt);
7771   ret->copyStringInfoFrom(*(a[0]));
7772   return ret.retn();
7773 }
7774
7775 /*!
7776  * Returns the maximal value and its location within \a this one-dimensional array.
7777  *  \param [out] tupleId - index of the tuple holding the maximal value.
7778  *  \return double - the maximal value among all values of \a this array.
7779  *  \throw If \a this->getNumberOfComponents() != 1
7780  *  \throw If \a this->getNumberOfTuples() < 1
7781  */
7782 int DataArrayInt::getMaxValue(int& tupleId) const throw(INTERP_KERNEL::Exception)
7783 {
7784   checkAllocated();
7785   if(getNumberOfComponents()!=1)
7786     throw INTERP_KERNEL::Exception("DataArrayInt::getMaxValue : must be applied on DataArrayInt with only one component !");
7787   int nbOfTuples=getNumberOfTuples();
7788   if(nbOfTuples<=0)
7789     throw INTERP_KERNEL::Exception("DataArrayInt::getMaxValue : array exists but number of tuples must be > 0 !");
7790   const int *vals=getConstPointer();
7791   const int *loc=std::max_element(vals,vals+nbOfTuples);
7792   tupleId=(int)std::distance(vals,loc);
7793   return *loc;
7794 }
7795
7796 /*!
7797  * Returns the maximal value within \a this array that is allowed to have more than
7798  *  one component.
7799  *  \return int - the maximal value among all values of \a this array.
7800  *  \throw If \a this is not allocated.
7801  */
7802 int DataArrayInt::getMaxValueInArray() const throw(INTERP_KERNEL::Exception)
7803 {
7804   checkAllocated();
7805   const int *loc=std::max_element(begin(),end());
7806   return *loc;
7807 }
7808
7809 /*!
7810  * Returns the minimal value and its location within \a this one-dimensional array.
7811  *  \param [out] tupleId - index of the tuple holding the minimal value.
7812  *  \return int - the minimal value among all values of \a this array.
7813  *  \throw If \a this->getNumberOfComponents() != 1
7814  *  \throw If \a this->getNumberOfTuples() < 1
7815  */
7816 int DataArrayInt::getMinValue(int& tupleId) const throw(INTERP_KERNEL::Exception)
7817 {
7818   checkAllocated();
7819   if(getNumberOfComponents()!=1)
7820     throw INTERP_KERNEL::Exception("DataArrayInt::getMaxValue : must be applied on DataArrayInt with only one component !");
7821   int nbOfTuples=getNumberOfTuples();
7822   if(nbOfTuples<=0)
7823     throw INTERP_KERNEL::Exception("DataArrayInt::getMaxValue : array exists but number of tuples must be > 0 !");
7824   const int *vals=getConstPointer();
7825   const int *loc=std::min_element(vals,vals+nbOfTuples);
7826   tupleId=(int)std::distance(vals,loc);
7827   return *loc;
7828 }
7829
7830 /*!
7831  * Returns the minimal value within \a this array that is allowed to have more than
7832  *  one component.
7833  *  \return int - the minimal value among all values of \a this array.
7834  *  \throw If \a this is not allocated.
7835  */
7836 int DataArrayInt::getMinValueInArray() const throw(INTERP_KERNEL::Exception)
7837 {
7838   checkAllocated();
7839   const int *loc=std::min_element(begin(),end());
7840   return *loc;
7841 }
7842
7843 /*!
7844  * Converts every value of \a this array to its absolute value.
7845  *  \throw If \a this is not allocated.
7846  */
7847 void DataArrayInt::abs() throw(INTERP_KERNEL::Exception)
7848 {
7849   checkAllocated();
7850   int *ptr=getPointer();
7851   int nbOfElems=getNbOfElems();
7852   std::transform(ptr,ptr+nbOfElems,ptr,std::ptr_fun<int,int>(std::abs));
7853   declareAsNew();
7854 }
7855
7856 /*!
7857  * Apply a liner function to a given component of \a this array, so that
7858  * an array element <em>(x)</em> becomes \f$ a * x + b \f$.
7859  *  \param [in] a - the first coefficient of the function.
7860  *  \param [in] b - the second coefficient of the function.
7861  *  \param [in] compoId - the index of component to modify.
7862  *  \throw If \a this is not allocated.
7863  */
7864 void DataArrayInt::applyLin(int a, int b, int compoId) throw(INTERP_KERNEL::Exception)
7865 {
7866   checkAllocated();
7867   int *ptr=getPointer()+compoId;
7868   int nbOfComp=getNumberOfComponents();
7869   int nbOfTuple=getNumberOfTuples();
7870   for(int i=0;i<nbOfTuple;i++,ptr+=nbOfComp)
7871     *ptr=a*(*ptr)+b;
7872   declareAsNew();
7873 }
7874
7875 /*!
7876  * Apply a liner function to all elements of \a this array, so that
7877  * an element _x_ becomes \f$ a * x + b \f$.
7878  *  \param [in] a - the first coefficient of the function.
7879  *  \param [in] b - the second coefficient of the function.
7880  *  \throw If \a this is not allocated.
7881  */
7882 void DataArrayInt::applyLin(int a, int b) throw(INTERP_KERNEL::Exception)
7883 {
7884   checkAllocated();
7885   int *ptr=getPointer();
7886   int nbOfElems=getNbOfElems();
7887   for(int i=0;i<nbOfElems;i++,ptr++)
7888     *ptr=a*(*ptr)+b;
7889   declareAsNew();
7890 }
7891
7892 /*!
7893  * Returns a full copy of \a this array except that sign of all elements is reversed.
7894  *  \return DataArrayInt * - the new instance of DataArrayInt containing the
7895  *          same number of tuples and component as \a this array.
7896  *          The caller is to delete this result array using decrRef() as it is no more
7897  *          needed.
7898  *  \throw If \a this is not allocated.
7899  */
7900 DataArrayInt *DataArrayInt::negate() const throw(INTERP_KERNEL::Exception)
7901 {
7902   checkAllocated();
7903   DataArrayInt *newArr=DataArrayInt::New();
7904   int nbOfTuples=getNumberOfTuples();
7905   int nbOfComp=getNumberOfComponents();
7906   newArr->alloc(nbOfTuples,nbOfComp);
7907   const int *cptr=getConstPointer();
7908   std::transform(cptr,cptr+nbOfTuples*nbOfComp,newArr->getPointer(),std::negate<int>());
7909   newArr->copyStringInfoFrom(*this);
7910   return newArr;
7911 }
7912
7913 /*!
7914  * Modify all elements of \a this array, so that
7915  * an element _x_ becomes \f$ numerator / x \f$.
7916  *  \param [in] numerator - the numerator used to modify array elements.
7917  *  \throw If \a this is not allocated.
7918  *  \throw If there is an element equal to 0 in \a this array.
7919  *  \warning If an exception is thrown because of presence of 0 element in \a this 
7920  *           array, all elements processed before detection of the zero element remain
7921  *           modified.
7922  */
7923 void DataArrayInt::applyInv(int numerator) throw(INTERP_KERNEL::Exception)
7924 {
7925   checkAllocated();
7926   int *ptr=getPointer();
7927   int nbOfElems=getNbOfElems();
7928   for(int i=0;i<nbOfElems;i++,ptr++)
7929     {
7930       if(*ptr!=0)
7931         {
7932           *ptr=numerator/(*ptr);
7933         }
7934       else
7935         {
7936           std::ostringstream oss; oss << "DataArrayInt::applyInv : presence of null value in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
7937           oss << " !";
7938           throw INTERP_KERNEL::Exception(oss.str().c_str());
7939         }
7940     }
7941   declareAsNew();
7942 }
7943
7944 /*!
7945  * Modify all elements of \a this array, so that
7946  * an element _x_ becomes \f$ x / val \f$.
7947  *  \param [in] val - the denominator used to modify array elements.
7948  *  \throw If \a this is not allocated.
7949  *  \throw If \a val == 0.
7950  */
7951 void DataArrayInt::applyDivideBy(int val) throw(INTERP_KERNEL::Exception)
7952 {
7953   if(val==0)
7954     throw INTERP_KERNEL::Exception("DataArrayInt::applyDivideBy : Trying to divide by 0 !");
7955   checkAllocated();
7956   int *ptr=getPointer();
7957   int nbOfElems=getNbOfElems();
7958   std::transform(ptr,ptr+nbOfElems,ptr,std::bind2nd(std::divides<int>(),val));
7959   declareAsNew();
7960 }
7961
7962 /*!
7963  * Modify all elements of \a this array, so that
7964  * an element _x_ becomes  <em> x % val </em>.
7965  *  \param [in] val - the divisor used to modify array elements.
7966  *  \throw If \a this is not allocated.
7967  *  \throw If \a val <= 0.
7968  */
7969 void DataArrayInt::applyModulus(int val) throw(INTERP_KERNEL::Exception)
7970 {
7971   if(val<=0)
7972     throw INTERP_KERNEL::Exception("DataArrayInt::applyDivideBy : Trying to operate modulus on value <= 0 !");
7973   checkAllocated();
7974   int *ptr=getPointer();
7975   int nbOfElems=getNbOfElems();
7976   std::transform(ptr,ptr+nbOfElems,ptr,std::bind2nd(std::modulus<int>(),val));
7977   declareAsNew();
7978 }
7979
7980 /*!
7981  * This method works only on data array with one component.
7982  * This method returns a newly allocated array storing stored ascendantly tuple ids in \b this so that
7983  * this[*id] in [\b vmin,\b vmax)
7984  * 
7985  * \param [in] vmin begin of range. This value is included in range.
7986  * \param [out] vmax end of range. This value is \b not included in range.
7987  * \return a newly allocated data array that the caller should deal with.
7988  */
7989 DataArrayInt *DataArrayInt::getIdsInRange(int vmin, int vmax) const throw(INTERP_KERNEL::Exception)
7990 {
7991   checkAllocated();
7992   if(getNumberOfComponents()!=1)
7993     throw INTERP_KERNEL::Exception("DataArrayInt::getIdsInRange : this must have exactly one component !");
7994   const int *cptr=getConstPointer();
7995   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(0,1);
7996   int nbOfTuples=getNumberOfTuples();
7997   for(int i=0;i<nbOfTuples;i++,cptr++)
7998     if(*cptr>=vmin && *cptr<vmax)
7999       ret->pushBackSilent(i);
8000   return ret.retn();
8001 }
8002
8003 /*!
8004  * Modify all elements of \a this array, so that
8005  * an element _x_ becomes <em> val % x </em>.
8006  *  \param [in] val - the divident used to modify array elements.
8007  *  \throw If \a this is not allocated.
8008  *  \throw If there is an element equal to or less than 0 in \a this array.
8009  *  \warning If an exception is thrown because of presence of an element <= 0 in \a this 
8010  *           array, all elements processed before detection of the zero element remain
8011  *           modified.
8012  */
8013 void DataArrayInt::applyRModulus(int val) throw(INTERP_KERNEL::Exception)
8014 {
8015   checkAllocated();
8016   int *ptr=getPointer();
8017   int nbOfElems=getNbOfElems();
8018   for(int i=0;i<nbOfElems;i++,ptr++)
8019     {
8020       if(*ptr>0)
8021         {
8022           *ptr=val%(*ptr);
8023         }
8024       else
8025         {
8026           std::ostringstream oss; oss << "DataArrayInt::applyRModulus : presence of value <=0 in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
8027           oss << " !";
8028           throw INTERP_KERNEL::Exception(oss.str().c_str());
8029         }
8030     }
8031   declareAsNew();
8032 }
8033
8034 /*!
8035  * Returns a new DataArrayInt by aggregating two given arrays, so that (1) the number
8036  * of components in the result array is a sum of the number of components of given arrays
8037  * and (2) the number of tuples in the result array is same as that of each of given
8038  * arrays. In other words the i-th tuple of result array includes all components of
8039  * i-th tuples of all given arrays.
8040  * Number of tuples in the given arrays must be the same.
8041  *  \param [in] a1 - an array to include in the result array.
8042  *  \param [in] a2 - another array to include in the result array.
8043  *  \return DataArrayInt * - the new instance of DataArrayInt.
8044  *          The caller is to delete this result array using decrRef() as it is no more
8045  *          needed.
8046  *  \throw If both \a a1 and \a a2 are NULL.
8047  *  \throw If any given array is not allocated.
8048  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
8049  */
8050 DataArrayInt *DataArrayInt::Meld(const DataArrayInt *a1, const DataArrayInt *a2) throw(INTERP_KERNEL::Exception)
8051 {
8052   std::vector<const DataArrayInt *> arr(2);
8053   arr[0]=a1; arr[1]=a2;
8054   return Meld(arr);
8055 }
8056
8057 /*!
8058  * Returns a new DataArrayInt by aggregating all given arrays, so that (1) the number
8059  * of components in the result array is a sum of the number of components of given arrays
8060  * and (2) the number of tuples in the result array is same as that of each of given
8061  * arrays. In other words the i-th tuple of result array includes all components of
8062  * i-th tuples of all given arrays.
8063  * Number of tuples in the given arrays must be  the same.
8064  *  \param [in] arr - a sequence of arrays to include in the result array.
8065  *  \return DataArrayInt * - the new instance of DataArrayInt.
8066  *          The caller is to delete this result array using decrRef() as it is no more
8067  *          needed.
8068  *  \throw If all arrays within \a arr are NULL.
8069  *  \throw If any given array is not allocated.
8070  *  \throw If getNumberOfTuples() of arrays within \a arr is different.
8071  */
8072 DataArrayInt *DataArrayInt::Meld(const std::vector<const DataArrayInt *>& arr) throw(INTERP_KERNEL::Exception)
8073 {
8074   std::vector<const DataArrayInt *> a;
8075   for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
8076     if(*it4)
8077       a.push_back(*it4);
8078   if(a.empty())
8079     throw INTERP_KERNEL::Exception("DataArrayInt::Meld : array must be NON empty !");
8080   std::vector<const DataArrayInt *>::const_iterator it;
8081   for(it=a.begin();it!=a.end();it++)
8082     (*it)->checkAllocated();
8083   it=a.begin();
8084   int nbOfTuples=(*it)->getNumberOfTuples();
8085   std::vector<int> nbc(a.size());
8086   std::vector<const int *> pts(a.size());
8087   nbc[0]=(*it)->getNumberOfComponents();
8088   pts[0]=(*it++)->getConstPointer();
8089   for(int i=1;it!=a.end();it++,i++)
8090     {
8091       if(nbOfTuples!=(*it)->getNumberOfTuples())
8092         throw INTERP_KERNEL::Exception("DataArrayInt::meld : mismatch of number of tuples !");
8093       nbc[i]=(*it)->getNumberOfComponents();
8094       pts[i]=(*it)->getConstPointer();
8095     }
8096   int totalNbOfComp=std::accumulate(nbc.begin(),nbc.end(),0);
8097   DataArrayInt *ret=DataArrayInt::New();
8098   ret->alloc(nbOfTuples,totalNbOfComp);
8099   int *retPtr=ret->getPointer();
8100   for(int i=0;i<nbOfTuples;i++)
8101     for(int j=0;j<(int)a.size();j++)
8102       {
8103         retPtr=std::copy(pts[j],pts[j]+nbc[j],retPtr);
8104         pts[j]+=nbc[j];
8105       }
8106   int k=0;
8107   for(int i=0;i<(int)a.size();i++)
8108     for(int j=0;j<nbc[i];j++,k++)
8109       ret->setInfoOnComponent(k,a[i]->getInfoOnComponent(j).c_str());
8110   return ret;
8111 }
8112
8113 /*!
8114  * Returns a new DataArrayInt which is a minimal partition of elements of \a groups.
8115  * The i-th item of the result array is an ID of a set of elements belonging to a
8116  * unique set of groups, which the i-th element is a part of. This set of elements
8117  * belonging to a unique set of groups is called \a family, so the result array contains
8118  * IDs of families each element belongs to.
8119  *
8120  * \b Example: if we have two groups of elements: \a group1 [0,4] and \a group2 [ 0,1,2 ],
8121  * then there are 3 families:
8122  * - \a family1 (with ID 1) contains element [0] belonging to ( \a group1 + \a group2 ),
8123  * - \a family2 (with ID 2) contains elements [4] belonging to ( \a group1 ),
8124  * - \a family3 (with ID 3) contains element [1,2] belonging to ( \a group2 ), <br>
8125  * and the result array contains IDs of families [ 1,3,3,0,2 ]. <br> Note a family ID 0 which
8126  * stands for the element #3 which is in none of groups.
8127  *
8128  *  \param [in] groups - sequence of groups of element IDs.
8129  *  \param [in] newNb - total number of elements; it must be more than max ID of element
8130  *         in \a groups.
8131  *  \param [out] fidsOfGroups - IDs of families the elements of each group belong to.
8132  *  \return DataArrayInt * - a new instance of DataArrayInt containing IDs of families
8133  *         each element with ID from range [0, \a newNb ) belongs to. The caller is to
8134  *         delete this array using decrRef() as it is no more needed.
8135  *  \throw If any element ID in \a groups violates condition ( 0 <= ID < \a newNb ).
8136  */
8137 DataArrayInt *DataArrayInt::MakePartition(const std::vector<const DataArrayInt *>& groups, int newNb, std::vector< std::vector<int> >& fidsOfGroups) throw(INTERP_KERNEL::Exception)
8138 {
8139   std::vector<const DataArrayInt *> groups2;
8140   for(std::vector<const DataArrayInt *>::const_iterator it4=groups.begin();it4!=groups.end();it4++)
8141     if(*it4)
8142       groups2.push_back(*it4);
8143   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
8144   ret->alloc(newNb,1);
8145   int *retPtr=ret->getPointer();
8146   std::fill(retPtr,retPtr+newNb,0);
8147   int fid=1;
8148   for(std::vector<const DataArrayInt *>::const_iterator iter=groups2.begin();iter!=groups2.end();iter++)
8149     {
8150       const int *ptr=(*iter)->getConstPointer();
8151       int nbOfElem=(*iter)->getNbOfElems();
8152       int sfid=fid;
8153       for(int j=0;j<sfid;j++)
8154         {
8155           bool found=false;
8156           for(int i=0;i<nbOfElem;i++)
8157             {
8158               if(ptr[i]>=0 && ptr[i]<newNb)
8159                 {
8160                   if(retPtr[ptr[i]]==j)
8161                     {
8162                       retPtr[ptr[i]]=fid;
8163                       found=true;
8164                     }
8165                 }
8166               else
8167                 {
8168                   std::ostringstream oss; oss << "DataArrayInt::MakePartition : In group \"" << (*iter)->getName() << "\" in tuple #" << i << " value = " << ptr[i] << " ! Should be in [0," << newNb;
8169                   oss << ") !";
8170                   throw INTERP_KERNEL::Exception(oss.str().c_str());
8171                 }
8172             }
8173           if(found)
8174             fid++;
8175         }
8176     }
8177   fidsOfGroups.clear();
8178   fidsOfGroups.resize(groups2.size());
8179   int grId=0;
8180   for(std::vector<const DataArrayInt *>::const_iterator iter=groups2.begin();iter!=groups2.end();iter++,grId++)
8181     {
8182       std::set<int> tmp;
8183       const int *ptr=(*iter)->getConstPointer();
8184       int nbOfElem=(*iter)->getNbOfElems();
8185       for(const int *p=ptr;p!=ptr+nbOfElem;p++)
8186         tmp.insert(retPtr[*p]);
8187       fidsOfGroups[grId].insert(fidsOfGroups[grId].end(),tmp.begin(),tmp.end());
8188     }
8189   return ret.retn();
8190 }
8191
8192 /*!
8193  * Returns a new DataArrayInt which contains all elements of given one-dimensional
8194  * not negative arrays. The result array does not contain any duplicates and its values
8195  * are sorted in ascending order.
8196  *  \param [in] arr - sequence of DataArrayInt's to unite.
8197  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
8198  *         array using decrRef() as it is no more needed.
8199  *  \throw If any \a arr[i] is not allocated.
8200  *  \throw If \a arr[i]->getNumberOfComponents() != 1.
8201  *  \throw If any value of \a arr[i] is negative.
8202  */
8203 DataArrayInt *DataArrayInt::BuildUnion(const std::vector<const DataArrayInt *>& arr) throw(INTERP_KERNEL::Exception)
8204 {
8205   std::vector<const DataArrayInt *> a;
8206   for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
8207     if(*it4)
8208       a.push_back(*it4);
8209   int valm=std::numeric_limits<int>::max();
8210   for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
8211     {
8212       (*it)->checkAllocated();
8213       if((*it)->getNumberOfComponents()!=1)
8214         throw INTERP_KERNEL::Exception("DataArrayInt::BuildUnion : only single component allowed !");
8215       int tmp1;
8216       valm=std::min((*it)->getMinValue(tmp1),valm);
8217     }
8218   if(valm<0)
8219     throw INTERP_KERNEL::Exception("DataArrayInt::BuildUnion : a negative value has been detected !");
8220   //
8221   std::set<int> r;
8222   for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
8223     {
8224       const int *pt=(*it)->getConstPointer();
8225       int nbOfTuples=(*it)->getNumberOfTuples();
8226       r.insert(pt,pt+nbOfTuples);
8227     }
8228   DataArrayInt *ret=DataArrayInt::New();
8229   ret->alloc((int)r.size(),1);
8230   std::copy(r.begin(),r.end(),ret->getPointer());
8231   return ret;
8232 }
8233
8234 /*!
8235  * Returns a new DataArrayInt which contains elements present in each of given one-dimensional
8236  * not negative arrays. The result array does not contain any duplicates and its values
8237  * are sorted in ascending order.
8238  *  \param [in] arr - sequence of DataArrayInt's to intersect.
8239  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
8240  *         array using decrRef() as it is no more needed.
8241  *  \throw If any \a arr[i] is not allocated.
8242  *  \throw If \a arr[i]->getNumberOfComponents() != 1.
8243  *  \throw If any value of \a arr[i] < 0.
8244  */
8245 DataArrayInt *DataArrayInt::BuildIntersection(const std::vector<const DataArrayInt *>& arr) throw(INTERP_KERNEL::Exception)
8246 {
8247   std::vector<const DataArrayInt *> a;
8248   for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
8249     if(*it4)
8250       a.push_back(*it4);
8251   int valm=std::numeric_limits<int>::max();
8252   for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
8253     {
8254       (*it)->checkAllocated();
8255       if((*it)->getNumberOfComponents()!=1)
8256         throw INTERP_KERNEL::Exception("DataArrayInt::BuildIntersection : only single component allowed !");
8257       int tmp1;
8258       valm=std::min((*it)->getMinValue(tmp1),valm);
8259     }
8260   if(valm<0)
8261     throw INTERP_KERNEL::Exception("DataArrayInt::BuildIntersection : a negative value has been detected !");
8262   //
8263   std::set<int> r;
8264   for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
8265     {
8266       const int *pt=(*it)->getConstPointer();
8267       int nbOfTuples=(*it)->getNumberOfTuples();
8268       std::set<int> s1(pt,pt+nbOfTuples);
8269       if(it!=a.begin())
8270         {
8271           std::set<int> r2;
8272           std::set_intersection(r.begin(),r.end(),s1.begin(),s1.end(),inserter(r2,r2.end()));
8273           r=r2;
8274         }
8275       else
8276         r=s1;
8277     }
8278   DataArrayInt *ret=DataArrayInt::New();
8279   ret->alloc((int)r.size(),1);
8280   std::copy(r.begin(),r.end(),ret->getPointer());
8281   return ret;
8282 }
8283
8284 /*!
8285  * Returns a new DataArrayInt which contains a complement of elements of \a this
8286  * one-dimensional array. I.e. the result array contains all elements from the range [0,
8287  * \a nbOfElement) not present in \a this array.
8288  *  \param [in] nbOfElement - maximal size of the result array.
8289  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
8290  *         array using decrRef() as it is no more needed.
8291  *  \throw If \a this is not allocated.
8292  *  \throw If \a this->getNumberOfComponents() != 1.
8293  *  \throw If any element \a x of \a this array violates condition ( 0 <= \a x < \a
8294  *         nbOfElement ).
8295  */
8296 DataArrayInt *DataArrayInt::buildComplement(int nbOfElement) const throw(INTERP_KERNEL::Exception)
8297 {
8298    checkAllocated();
8299    if(getNumberOfComponents()!=1)
8300      throw INTERP_KERNEL::Exception("DataArrayInt::buildComplement : only single component allowed !");
8301    std::vector<bool> tmp(nbOfElement);
8302    const int *pt=getConstPointer();
8303    int nbOfTuples=getNumberOfTuples();
8304    for(const int *w=pt;w!=pt+nbOfTuples;w++)
8305      if(*w>=0 && *w<nbOfElement)
8306        tmp[*w]=true;
8307      else
8308        throw INTERP_KERNEL::Exception("DataArrayInt::buildComplement : an element is not in valid range : [0,nbOfElement) !");
8309    int nbOfRetVal=(int)std::count(tmp.begin(),tmp.end(),false);
8310    DataArrayInt *ret=DataArrayInt::New();
8311    ret->alloc(nbOfRetVal,1);
8312    int j=0;
8313    int *retPtr=ret->getPointer();
8314    for(int i=0;i<nbOfElement;i++)
8315      if(!tmp[i])
8316        retPtr[j++]=i;
8317    return ret;
8318 }
8319
8320 /*!
8321  * Returns a new DataArrayInt containing elements of \a this one-dimensional missing
8322  * from an \a other one-dimensional array.
8323  *  \param [in] other - a DataArrayInt containing elements not to include in the result array.
8324  *  \return DataArrayInt * - a new instance of DataArrayInt with one component. The
8325  *         caller is to delete this array using decrRef() as it is no more needed.
8326  *  \throw If \a other is NULL.
8327  *  \throw If \a other is not allocated.
8328  *  \throw If \a other->getNumberOfComponents() != 1.
8329  *  \throw If \a this is not allocated.
8330  *  \throw If \a this->getNumberOfComponents() != 1.
8331  *  \sa DataArrayInt::buildSubstractionOptimized()
8332  */
8333 DataArrayInt *DataArrayInt::buildSubstraction(const DataArrayInt *other) const throw(INTERP_KERNEL::Exception)
8334 {
8335   if(!other)
8336     throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstraction : DataArrayInt pointer in input is NULL !");
8337   checkAllocated();
8338   other->checkAllocated();
8339   if(getNumberOfComponents()!=1)
8340      throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstraction : only single component allowed !");
8341   if(other->getNumberOfComponents()!=1)
8342      throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstraction : only single component allowed for other type !");
8343   const int *pt=getConstPointer();
8344   int nbOfTuples=getNumberOfTuples();
8345   std::set<int> s1(pt,pt+nbOfTuples);
8346   pt=other->getConstPointer();
8347   nbOfTuples=other->getNumberOfTuples();
8348   std::set<int> s2(pt,pt+nbOfTuples);
8349   std::vector<int> r;
8350   std::set_difference(s1.begin(),s1.end(),s2.begin(),s2.end(),std::back_insert_iterator< std::vector<int> >(r));
8351   DataArrayInt *ret=DataArrayInt::New();
8352   ret->alloc((int)r.size(),1);
8353   std::copy(r.begin(),r.end(),ret->getPointer());
8354   return ret;
8355 }
8356
8357 /*!
8358  * \a this is expected to have one component and to be sorted ascendingly (as for \a other).
8359  * \a other is expected to be a part of \a this. If not DataArrayInt::buildSubstraction should be called instead.
8360  * 
8361  * \param [in] other an array with one component and expected to be sorted ascendingly.
8362  * \ret list of ids in \a this but not in \a other.
8363  * \sa DataArrayInt::buildSubstraction
8364  */
8365 DataArrayInt *DataArrayInt::buildSubstractionOptimized(const DataArrayInt *other) const throw(INTERP_KERNEL::Exception)
8366 {
8367   static const char *MSG="DataArrayInt::buildSubstractionOptimized : only single component allowed !";
8368   if(!other) throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstractionOptimized : NULL input array !");
8369   checkAllocated(); other->checkAllocated();
8370   if(getNumberOfComponents()!=1) throw INTERP_KERNEL::Exception(MSG);
8371   if(other->getNumberOfComponents()!=1) throw INTERP_KERNEL::Exception(MSG);
8372   const int *pt1Bg(begin()),*pt1End(end()),*pt2Bg(other->begin()),*pt2End(other->end()),*work1(pt1Bg),*work2(pt2Bg);
8373   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
8374   for(;work1!=pt1End;work1++)
8375     {
8376       if(work2!=pt2End && *work1==*work2)
8377         work2++;
8378       else
8379         ret->pushBackSilent(*work1);
8380     }
8381   return ret.retn();
8382 }
8383
8384
8385 /*!
8386  * Returns a new DataArrayInt which contains all elements of \a this and a given
8387  * one-dimensional not negative arrays. The result array does not contain any duplicates
8388  * and its values are sorted in ascending order.
8389  *  \param [in] other - an array to unite with \a this one.
8390  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
8391  *         array using decrRef() as it is no more needed.
8392  *  \throw If \a this or \a other is not allocated.
8393  *  \throw If \a this->getNumberOfComponents() != 1.
8394  *  \throw If \a other->getNumberOfComponents() != 1.
8395  *  \throw If any value of \a this or \a other is negative.
8396  */
8397 DataArrayInt *DataArrayInt::buildUnion(const DataArrayInt *other) const throw(INTERP_KERNEL::Exception)
8398 {
8399   std::vector<const DataArrayInt *>arrs(2);
8400   arrs[0]=this; arrs[1]=other;
8401   return BuildUnion(arrs);
8402 }
8403
8404
8405 /*!
8406  * Returns a new DataArrayInt which contains elements present in both \a this and a given
8407  * one-dimensional not negative arrays. The result array does not contain any duplicates
8408  * and its values are sorted in ascending order.
8409  *  \param [in] other - an array to intersect with \a this one.
8410  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
8411  *         array using decrRef() as it is no more needed.
8412  *  \throw If \a this or \a other is not allocated.
8413  *  \throw If \a this->getNumberOfComponents() != 1.
8414  *  \throw If \a other->getNumberOfComponents() != 1.
8415  *  \throw If any value of \a this or \a other is negative.
8416  */
8417 DataArrayInt *DataArrayInt::buildIntersection(const DataArrayInt *other) const throw(INTERP_KERNEL::Exception)
8418 {
8419   std::vector<const DataArrayInt *>arrs(2);
8420   arrs[0]=this; arrs[1]=other;
8421   return BuildIntersection(arrs);
8422 }
8423
8424 /*!
8425  * This method can be applied on allocated with one component DataArrayInt instance.
8426  * This method is typically relevant for sorted arrays. All consecutive duplicated items in \a this will appear only once in returned DataArrayInt instance.
8427  * 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]
8428  * 
8429  * \return a newly allocated array that contain the result of the unique operation applied on \a this.
8430  * \throw if \a this is not allocated or if \a this has not exactly one component.
8431  */
8432 DataArrayInt *DataArrayInt::buildUnique() const throw(INTERP_KERNEL::Exception)
8433 {
8434   checkAllocated();
8435   if(getNumberOfComponents()!=1)
8436      throw INTERP_KERNEL::Exception("DataArrayInt::buildUnique : only single component allowed !");
8437   int nbOfTuples=getNumberOfTuples();
8438   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp=deepCpy();
8439   int *data=tmp->getPointer();
8440   int *last=std::unique(data,data+nbOfTuples);
8441   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
8442   ret->alloc(std::distance(data,last),1);
8443   std::copy(data,last,ret->getPointer());
8444   return ret.retn();
8445 }
8446
8447 /*!
8448  * Returns a new DataArrayInt which contains size of every of groups described by \a this
8449  * "index" array. Such "index" array is returned for example by 
8450  * \ref ParaMEDMEM::MEDCouplingUMesh::buildDescendingConnectivity
8451  * "MEDCouplingUMesh::buildDescendingConnectivity" and
8452  * \ref ParaMEDMEM::MEDCouplingUMesh::getNodalConnectivityIndex
8453  * "MEDCouplingUMesh::getNodalConnectivityIndex" etc.
8454  *  \return DataArrayInt * - a new instance of DataArrayInt, whose number of tuples
8455  *          equals to \a this->getNumberOfComponents() - 1, and number of components is 1.
8456  *          The caller is to delete this array using decrRef() as it is no more needed. 
8457  *  \throw If \a this is not allocated.
8458  *  \throw If \a this->getNumberOfComponents() != 1.
8459  *  \throw If \a this->getNumberOfTuples() < 2.
8460  *
8461  *  \b Example: <br> 
8462  *         - this contains [1,3,6,7,7,9,15]
8463  *         - result array contains [2,3,1,0,2,6],
8464  *          where 2 = 3 - 1, 3 = 6 - 3, 1 = 7 - 6 etc.
8465  */
8466 DataArrayInt *DataArrayInt::deltaShiftIndex() const throw(INTERP_KERNEL::Exception)
8467 {
8468   checkAllocated();
8469   if(getNumberOfComponents()!=1)
8470      throw INTERP_KERNEL::Exception("DataArrayInt::deltaShiftIndex : only single component allowed !");
8471   int nbOfTuples=getNumberOfTuples();
8472   if(nbOfTuples<2)
8473     throw INTERP_KERNEL::Exception("DataArrayInt::deltaShiftIndex : 1 tuple at least must be present in 'this' !");
8474   const int *ptr=getConstPointer();
8475   DataArrayInt *ret=DataArrayInt::New();
8476   ret->alloc(nbOfTuples-1,1);
8477   int *out=ret->getPointer();
8478   std::transform(ptr+1,ptr+nbOfTuples,ptr,out,std::minus<int>());
8479   return ret;
8480 }
8481
8482 /*!
8483  * Modifies \a this one-dimensional array so that value of each element \a x
8484  * of \a this array (\a a) is computed as \f$ x_i = \sum_{j=0}^{i-1} a[ j ] \f$.
8485  * Or: for each i>0 new[i]=new[i-1]+old[i-1] for i==0 new[i]=0. Number of tuples
8486  * and components remains the same.<br>
8487  * This method is useful for allToAllV in MPI with contiguous policy. This method
8488  * differs from computeOffsets2() in that the number of tuples is \b not changed by
8489  * this one.
8490  *  \throw If \a this is not allocated.
8491  *  \throw If \a this->getNumberOfComponents() != 1.
8492  *
8493  *  \b Example: <br>
8494  *          - Before \a this contains [3,5,1,2,0,8]
8495  *          - After \a this contains  [0,3,8,9,11,11]<br>
8496  *          Note that the last element 19 = 11 + 8 is missing because size of \a this
8497  *          array is retained and thus there is no space to store the last element.
8498  */
8499 void DataArrayInt::computeOffsets() throw(INTERP_KERNEL::Exception)
8500 {
8501   checkAllocated();
8502   if(getNumberOfComponents()!=1)
8503      throw INTERP_KERNEL::Exception("DataArrayInt::computeOffsets : only single component allowed !");
8504   int nbOfTuples=getNumberOfTuples();
8505   if(nbOfTuples==0)
8506     return ;
8507   int *work=getPointer();
8508   int tmp=work[0];
8509   work[0]=0;
8510   for(int i=1;i<nbOfTuples;i++)
8511     {
8512       int tmp2=work[i];
8513       work[i]=work[i-1]+tmp;
8514       tmp=tmp2;
8515     }
8516   declareAsNew();
8517 }
8518
8519
8520 /*!
8521  * Modifies \a this one-dimensional array so that value of each element \a x
8522  * of \a this array (\a a) is computed as \f$ x_i = \sum_{j=0}^{i-1} a[ j ] \f$.
8523  * Or: for each i>0 new[i]=new[i-1]+old[i-1] for i==0 new[i]=0. Number
8524  * components remains the same and number of tuples is inceamented by one.<br>
8525  * This method is useful for allToAllV in MPI with contiguous policy. This method
8526  * differs from computeOffsets() in that the number of tuples is changed by this one.
8527  *  \throw If \a this is not allocated.
8528  *  \throw If \a this->getNumberOfComponents() != 1.
8529  *
8530  *  \b Example: <br>
8531  *          - Before \a this contains [3,5,1,2,0,8]
8532  *          - After \a this contains  [0,3,8,9,11,11,19]<br>
8533  */
8534 void DataArrayInt::computeOffsets2() throw(INTERP_KERNEL::Exception)
8535 {
8536   checkAllocated();
8537   if(getNumberOfComponents()!=1)
8538     throw INTERP_KERNEL::Exception("DataArrayInt::computeOffsets2 : only single component allowed !");
8539   int nbOfTuples=getNumberOfTuples();
8540   int *ret=new int[nbOfTuples+1];
8541   if(nbOfTuples==0)
8542     return ;
8543   const int *work=getConstPointer();
8544   ret[0]=0;
8545   for(int i=0;i<nbOfTuples;i++)
8546     ret[i+1]=work[i]+ret[i];
8547   useArray(ret,true,CPP_DEALLOC,nbOfTuples+1,1);
8548   declareAsNew();
8549 }
8550
8551
8552 /*!
8553  * Returns a new DataArrayInt whose contents is computed from that of \a this and \a
8554  * offsets arrays as follows. \a offsets is a one-dimensional array considered as an
8555  * "index" array of a "iota" array, thus, whose each element gives an index of a group
8556  * beginning within the "iota" array. And \a this is a one-dimensional array
8557  * considered as a selector of groups described by \a offsets to include into the result array.
8558  *  \throw If \a offsets is NULL.
8559  *  \throw If \a offsets is not allocated.
8560  *  \throw If \a offsets->getNumberOfComponents() != 1.
8561  *  \throw If \a offsets is not monotonically increasing.
8562  *  \throw If \a this is not allocated.
8563  *  \throw If \a this->getNumberOfComponents() != 1.
8564  *  \throw If any element of \a this is not a valid index for \a offsets array.
8565  *
8566  *  \b Example: <br>
8567  *          - \a this: [0,2,3]
8568  *          - \a offsets: [0,3,6,10,14,20]
8569  *          - result array: [0,1,2,6,7,8,9,10,11,12,13] == <br>
8570  *            \c range(0,3) + \c range(6,10) + \c range(10,14) ==<br>
8571  *            \c range( \a offsets[ \a this[0] ], offsets[ \a this[0]+1 ]) + 
8572  *            \c range( \a offsets[ \a this[1] ], offsets[ \a this[1]+1 ]) + 
8573  *            \c range( \a offsets[ \a this[2] ], offsets[ \a this[2]+1 ])
8574  */
8575 DataArrayInt *DataArrayInt::buildExplicitArrByRanges(const DataArrayInt *offsets) const throw(INTERP_KERNEL::Exception)
8576 {
8577   if(!offsets)
8578     throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrByRanges : DataArrayInt pointer in input is NULL !");
8579   checkAllocated();
8580   if(getNumberOfComponents()!=1)
8581      throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrByRanges : only single component allowed !");
8582   offsets->checkAllocated();
8583   if(offsets->getNumberOfComponents()!=1)
8584      throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrByRanges : input array should have only single component !");
8585   int othNbTuples=offsets->getNumberOfTuples()-1;
8586   int nbOfTuples=getNumberOfTuples();
8587   int retNbOftuples=0;
8588   const int *work=getConstPointer();
8589   const int *offPtr=offsets->getConstPointer();
8590   for(int i=0;i<nbOfTuples;i++)
8591     {
8592       int val=work[i];
8593       if(val>=0 && val<othNbTuples)
8594         {
8595           int delta=offPtr[val+1]-offPtr[val];
8596           if(delta>=0)
8597             retNbOftuples+=delta;
8598           else
8599             {
8600               std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrByRanges : Tuple #" << val << " of offset array has a delta < 0 !";
8601               throw INTERP_KERNEL::Exception(oss.str().c_str());
8602             }
8603         }
8604       else
8605         {
8606           std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrByRanges : Tuple #" << i << " in this contains " << val;
8607           oss << " whereas offsets array is of size " << othNbTuples+1 << " !";
8608           throw INTERP_KERNEL::Exception(oss.str().c_str());
8609         }
8610     }
8611   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
8612   ret->alloc(retNbOftuples,1);
8613   int *retPtr=ret->getPointer();
8614   for(int i=0;i<nbOfTuples;i++)
8615     {
8616       int val=work[i];
8617       int start=offPtr[val];
8618       int off=offPtr[val+1]-start;
8619       for(int j=0;j<off;j++,retPtr++)
8620         *retPtr=start+j;
8621     }
8622   return ret.retn();
8623 }
8624
8625 /*!
8626  * 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.
8627  * 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
8628  * in tuple **i** of returned DataArrayInt.
8629  * If ranges overlapped (in theory it should not) this method do not detect it and always returns the first range.
8630  *
8631  * 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)]
8632  * The return DataArrayInt will contain : **[0,4,1,2,2,3]**
8633  * 
8634  * \param [in] ranges typically come from output of MEDCouplingUMesh::ComputeRangesFromTypeDistribution. Each range is specified like this : 1st component is
8635  *             for lower value included and 2nd component is the upper value of corresponding range **excluded**.
8636  * \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
8637  *        is thrown if no ranges in \a ranges contains value in \a this.
8638  * 
8639  * \sa DataArrayInt::findIdInRangeForEachTuple
8640  */
8641 DataArrayInt *DataArrayInt::findRangeIdForEachTuple(const DataArrayInt *ranges) const throw(INTERP_KERNEL::Exception)
8642 {
8643   if(!ranges)
8644     throw INTERP_KERNEL::Exception("DataArrayInt::findRangeIdForEachTuple : null input pointer !");
8645   if(ranges->getNumberOfComponents()!=2)
8646     throw INTERP_KERNEL::Exception("DataArrayInt::findRangeIdForEachTuple : input DataArrayInt instance should have 2 components !");
8647   checkAllocated();
8648   if(getNumberOfComponents()!=1)
8649     throw INTERP_KERNEL::Exception("DataArrayInt::findRangeIdForEachTuple : this should have only one component !");
8650   int nbTuples=getNumberOfTuples();
8651   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbTuples,1);
8652   int nbOfRanges=ranges->getNumberOfTuples();
8653   const int *rangesPtr=ranges->getConstPointer();
8654   int *retPtr=ret->getPointer();
8655   const int *inPtr=getConstPointer();
8656   for(int i=0;i<nbTuples;i++,retPtr++)
8657     {
8658       int val=inPtr[i];
8659       bool found=false;
8660       for(int j=0;j<nbOfRanges && !found;j++)
8661         if(val>=rangesPtr[2*j] && val<rangesPtr[2*j+1])
8662           { *retPtr=j; found=true; }
8663       if(found)
8664         continue;
8665       else
8666         {
8667           std::ostringstream oss; oss << "DataArrayInt::findRangeIdForEachTuple : tuple #" << i << " not found by any ranges !";
8668           throw INTERP_KERNEL::Exception(oss.str().c_str());
8669         }
8670     }
8671   return ret.retn();
8672 }
8673
8674 /*!
8675  * 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.
8676  * 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
8677  * in tuple **i** of returned DataArrayInt.
8678  * If ranges overlapped (in theory it should not) this method do not detect it and always returns the sub position of the first range.
8679  *
8680  * 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)]
8681  * The return DataArrayInt will contain : **[1,2,4,0,2,2]**
8682  * This method is often called in pair with DataArrayInt::findRangeIdForEachTuple method.
8683  * 
8684  * \param [in] ranges typically come from output of MEDCouplingUMesh::ComputeRangesFromTypeDistribution. Each range is specified like this : 1st component is
8685  *             for lower value included and 2nd component is the upper value of corresponding range **excluded**.
8686  * \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
8687  *        is thrown if no ranges in \a ranges contains value in \a this.
8688  * \sa DataArrayInt::findRangeIdForEachTuple
8689  */
8690 DataArrayInt *DataArrayInt::findIdInRangeForEachTuple(const DataArrayInt *ranges) const throw(INTERP_KERNEL::Exception)
8691 {
8692   if(!ranges)
8693     throw INTERP_KERNEL::Exception("DataArrayInt::findIdInRangeForEachTuple : null input pointer !");
8694   if(ranges->getNumberOfComponents()!=2)
8695     throw INTERP_KERNEL::Exception("DataArrayInt::findIdInRangeForEachTuple : input DataArrayInt instance should have 2 components !");
8696   checkAllocated();
8697   if(getNumberOfComponents()!=1)
8698     throw INTERP_KERNEL::Exception("DataArrayInt::findIdInRangeForEachTuple : this should have only one component !");
8699   int nbTuples=getNumberOfTuples();
8700   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbTuples,1);
8701   int nbOfRanges=ranges->getNumberOfTuples();
8702   const int *rangesPtr=ranges->getConstPointer();
8703   int *retPtr=ret->getPointer();
8704   const int *inPtr=getConstPointer();
8705   for(int i=0;i<nbTuples;i++,retPtr++)
8706     {
8707       int val=inPtr[i];
8708       bool found=false;
8709       for(int j=0;j<nbOfRanges && !found;j++)
8710         if(val>=rangesPtr[2*j] && val<rangesPtr[2*j+1])
8711           { *retPtr=val-rangesPtr[2*j]; found=true; }
8712       if(found)
8713         continue;
8714       else
8715         {
8716           std::ostringstream oss; oss << "DataArrayInt::findIdInRangeForEachTuple : tuple #" << i << " not found by any ranges !";
8717           throw INTERP_KERNEL::Exception(oss.str().c_str());
8718         }
8719     }
8720   return ret.retn();
8721 }
8722
8723 /*!
8724  * 
8725  * \param [in] nbTimes specifies the nb of times each tuples in \a this will be duplicated contiguouly in returned DataArrayInt instance.
8726  *             \a nbTimes  should be at least equal to 1.
8727  * \return a newly allocated DataArrayInt having one component and number of tuples equal to \a nbTimes * \c this->getNumberOfTuples.
8728  * \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.
8729  */
8730 DataArrayInt *DataArrayInt::duplicateEachTupleNTimes(int nbTimes) const throw(INTERP_KERNEL::Exception)
8731 {
8732   checkAllocated();
8733   if(getNumberOfComponents()!=1)
8734     throw INTERP_KERNEL::Exception("DataArrayInt::duplicateEachTupleNTimes : this should have only one component !");
8735   if(nbTimes<1)
8736     throw INTERP_KERNEL::Exception("DataArrayInt::duplicateEachTupleNTimes : nb times should be >= 1 !");
8737   int nbTuples=getNumberOfTuples();
8738   const int *inPtr=getConstPointer();
8739   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbTimes*nbTuples,1);
8740   int *retPtr=ret->getPointer();
8741   for(int i=0;i<nbTuples;i++,inPtr++)
8742     {
8743       int val=*inPtr;
8744       for(int j=0;j<nbTimes;j++,retPtr++)
8745         *retPtr=val;
8746     }
8747   ret->copyStringInfoFrom(*this);
8748   return ret.retn();
8749 }
8750
8751 /*!
8752  * This method returns all different values found in \a this. This method throws if \a this has not been allocated.
8753  * But the number of components can be different from one.
8754  * \return a newly allocated array (that should be dealt by the caller) containing different values in \a this.
8755  */
8756 DataArrayInt *DataArrayInt::getDifferentValues() const throw(INTERP_KERNEL::Exception)
8757 {
8758   checkAllocated();
8759   std::set<int> ret;
8760   ret.insert(begin(),end());
8761   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret2=DataArrayInt::New(); ret2->alloc((int)ret.size(),1);
8762   std::copy(ret.begin(),ret.end(),ret2->getPointer());
8763   return ret2.retn();
8764 }
8765
8766 /*!
8767  * This method is a refinement of DataArrayInt::getDifferentValues because it returns not only different values in \a this but also, for each of
8768  * them it tells which tuple id have this id.
8769  * This method works only on arrays with one component (if it is not the case call DataArrayInt::rearrange(1) ).
8770  * This method returns two arrays having same size.
8771  * 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.
8772  * 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]]
8773  */
8774 std::vector<DataArrayInt *> DataArrayInt::partitionByDifferentValues(std::vector<int>& differentIds) const throw(INTERP_KERNEL::Exception)
8775 {
8776   checkAllocated();
8777   if(getNumberOfComponents()!=1)
8778     throw INTERP_KERNEL::Exception("DataArrayInt::partitionByDifferentValues : this should have only one component !");
8779   int id=0;
8780   std::map<int,int> m,m2,m3;
8781   for(const int *w=begin();w!=end();w++)
8782     m[*w]++;
8783   differentIds.resize(m.size());
8784   std::vector<DataArrayInt *> ret(m.size());
8785   std::vector<int *> retPtr(m.size());
8786   for(std::map<int,int>::const_iterator it=m.begin();it!=m.end();it++,id++)
8787     {
8788       m2[(*it).first]=id;
8789       ret[id]=DataArrayInt::New();
8790       ret[id]->alloc((*it).second,1);
8791       retPtr[id]=ret[id]->getPointer();
8792       differentIds[id]=(*it).first;
8793     }
8794   id=0;
8795   for(const int *w=begin();w!=end();w++,id++)
8796     {
8797       retPtr[m2[*w]][m3[*w]++]=id;
8798     }
8799   return ret;
8800 }
8801
8802 /*!
8803  * Returns a new DataArrayInt that is a sum of two given arrays. There are 3
8804  * valid cases.
8805  * 1.  The arrays have same number of tuples and components. Then each value of
8806  *   the result array (_a_) is a sum of the corresponding values of \a a1 and \a a2,
8807  *   i.e.: _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ i, j ].
8808  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
8809  *   component. Then
8810  *   _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ i, 0 ].
8811  * 3.  The arrays have same number of components and one array, say _a2_, has one
8812  *   tuple. Then
8813  *   _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ 0, j ].
8814  *
8815  * Info on components is copied either from the first array (in the first case) or from
8816  * the array with maximal number of elements (getNbOfElems()).
8817  *  \param [in] a1 - an array to sum up.
8818  *  \param [in] a2 - another array to sum up.
8819  *  \return DataArrayInt * - the new instance of DataArrayInt.
8820  *          The caller is to delete this result array using decrRef() as it is no more
8821  *          needed.
8822  *  \throw If either \a a1 or \a a2 is NULL.
8823  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
8824  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
8825  *         none of them has number of tuples or components equal to 1.
8826  */
8827 DataArrayInt *DataArrayInt::Add(const DataArrayInt *a1, const DataArrayInt *a2) throw(INTERP_KERNEL::Exception)
8828 {
8829   if(!a1 || !a2)
8830     throw INTERP_KERNEL::Exception("DataArrayInt::Add : input DataArrayInt instance is NULL !");
8831   int nbOfTuple=a1->getNumberOfTuples();
8832   int nbOfTuple2=a2->getNumberOfTuples();
8833   int nbOfComp=a1->getNumberOfComponents();
8834   int nbOfComp2=a2->getNumberOfComponents();
8835   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=0;
8836   if(nbOfTuple==nbOfTuple2)
8837     {
8838       if(nbOfComp==nbOfComp2)
8839         {
8840           ret=DataArrayInt::New();
8841           ret->alloc(nbOfTuple,nbOfComp);
8842           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::plus<int>());
8843           ret->copyStringInfoFrom(*a1);
8844         }
8845       else
8846         {
8847           int nbOfCompMin,nbOfCompMax;
8848           const DataArrayInt *aMin, *aMax;
8849           if(nbOfComp>nbOfComp2)
8850             {
8851               nbOfCompMin=nbOfComp2; nbOfCompMax=nbOfComp;
8852               aMin=a2; aMax=a1;
8853             }
8854           else
8855             {
8856               nbOfCompMin=nbOfComp; nbOfCompMax=nbOfComp2;
8857               aMin=a1; aMax=a2;
8858             }
8859           if(nbOfCompMin==1)
8860             {
8861               ret=DataArrayInt::New();
8862               ret->alloc(nbOfTuple,nbOfCompMax);
8863               const int *aMinPtr=aMin->getConstPointer();
8864               const int *aMaxPtr=aMax->getConstPointer();
8865               int *res=ret->getPointer();
8866               for(int i=0;i<nbOfTuple;i++)
8867                 res=std::transform(aMaxPtr+i*nbOfCompMax,aMaxPtr+(i+1)*nbOfCompMax,res,std::bind2nd(std::plus<int>(),aMinPtr[i]));
8868               ret->copyStringInfoFrom(*aMax);
8869             }
8870           else
8871             throw INTERP_KERNEL::Exception("Nb of components mismatch for array Add !");
8872         }
8873     }
8874   else if((nbOfTuple==1 && nbOfTuple2>1) || (nbOfTuple>1 && nbOfTuple2==1))
8875     {
8876       if(nbOfComp==nbOfComp2)
8877         {
8878           int nbOfTupleMax=std::max(nbOfTuple,nbOfTuple2);
8879           const DataArrayInt *aMin=nbOfTuple>nbOfTuple2?a2:a1;
8880           const DataArrayInt *aMax=nbOfTuple>nbOfTuple2?a1:a2;
8881           const int *aMinPtr=aMin->getConstPointer(),*aMaxPtr=aMax->getConstPointer();
8882           ret=DataArrayInt::New();
8883           ret->alloc(nbOfTupleMax,nbOfComp);
8884           int *res=ret->getPointer();
8885           for(int i=0;i<nbOfTupleMax;i++)
8886             res=std::transform(aMaxPtr+i*nbOfComp,aMaxPtr+(i+1)*nbOfComp,aMinPtr,res,std::plus<int>());
8887           ret->copyStringInfoFrom(*aMax);
8888         }
8889       else
8890         throw INTERP_KERNEL::Exception("Nb of components mismatch for array Add !");
8891     }
8892   else
8893     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Add !");
8894   return ret.retn();
8895 }
8896
8897 /*!
8898  * Adds values of another DataArrayInt to values of \a this one. There are 3
8899  * valid cases.
8900  * 1.  The arrays have same number of tuples and components. Then each value of
8901  *   \a other array is added to the corresponding value of \a this array, i.e.:
8902  *   _a_ [ i, j ] += _other_ [ i, j ].
8903  * 2.  The arrays have same number of tuples and \a other array has one component. Then
8904  *   _a_ [ i, j ] += _other_ [ i, 0 ].
8905  * 3.  The arrays have same number of components and \a other array has one tuple. Then
8906  *   _a_ [ i, j ] += _a2_ [ 0, j ].
8907  *
8908  *  \param [in] other - an array to add to \a this one.
8909  *  \throw If \a other is NULL.
8910  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
8911  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
8912  *         \a other has number of both tuples and components not equal to 1.
8913  */
8914 void DataArrayInt::addEqual(const DataArrayInt *other) throw(INTERP_KERNEL::Exception)
8915 {
8916   if(!other)
8917     throw INTERP_KERNEL::Exception("DataArrayInt::addEqual : input DataArrayInt instance is NULL !");
8918   const char *msg="Nb of tuples mismatch for DataArrayInt::addEqual  !";
8919   checkAllocated(); other->checkAllocated();
8920   int nbOfTuple=getNumberOfTuples();
8921   int nbOfTuple2=other->getNumberOfTuples();
8922   int nbOfComp=getNumberOfComponents();
8923   int nbOfComp2=other->getNumberOfComponents();
8924   if(nbOfTuple==nbOfTuple2)
8925     {
8926       if(nbOfComp==nbOfComp2)
8927         {
8928           std::transform(begin(),end(),other->begin(),getPointer(),std::plus<int>());
8929         }
8930       else if(nbOfComp2==1)
8931         {
8932           int *ptr=getPointer();
8933           const int *ptrc=other->getConstPointer();
8934           for(int i=0;i<nbOfTuple;i++)
8935             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::plus<int>(),*ptrc++));
8936         }
8937       else
8938         throw INTERP_KERNEL::Exception(msg);
8939     }
8940   else if(nbOfTuple2==1)
8941     {
8942       if(nbOfComp2==nbOfComp)
8943         {
8944           int *ptr=getPointer();
8945           const int *ptrc=other->getConstPointer();
8946           for(int i=0;i<nbOfTuple;i++)
8947             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::plus<int>());
8948         }
8949       else
8950         throw INTERP_KERNEL::Exception(msg);
8951     }
8952   else
8953     throw INTERP_KERNEL::Exception(msg);
8954   declareAsNew();
8955 }
8956
8957 /*!
8958  * Returns a new DataArrayInt that is a subtraction of two given arrays. There are 3
8959  * valid cases.
8960  * 1.  The arrays have same number of tuples and components. Then each value of
8961  *   the result array (_a_) is a subtraction of the corresponding values of \a a1 and
8962  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ i, j ].
8963  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
8964  *   component. Then
8965  *   _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ i, 0 ].
8966  * 3.  The arrays have same number of components and one array, say _a2_, has one
8967  *   tuple. Then
8968  *   _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ 0, j ].
8969  *
8970  * Info on components is copied either from the first array (in the first case) or from
8971  * the array with maximal number of elements (getNbOfElems()).
8972  *  \param [in] a1 - an array to subtract from.
8973  *  \param [in] a2 - an array to subtract.
8974  *  \return DataArrayInt * - the new instance of DataArrayInt.
8975  *          The caller is to delete this result array using decrRef() as it is no more
8976  *          needed.
8977  *  \throw If either \a a1 or \a a2 is NULL.
8978  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
8979  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
8980  *         none of them has number of tuples or components equal to 1.
8981  */
8982 DataArrayInt *DataArrayInt::Substract(const DataArrayInt *a1, const DataArrayInt *a2) throw(INTERP_KERNEL::Exception)
8983 {
8984   if(!a1 || !a2)
8985     throw INTERP_KERNEL::Exception("DataArrayInt::Substract : input DataArrayInt instance is NULL !");
8986   int nbOfTuple1=a1->getNumberOfTuples();
8987   int nbOfTuple2=a2->getNumberOfTuples();
8988   int nbOfComp1=a1->getNumberOfComponents();
8989   int nbOfComp2=a2->getNumberOfComponents();
8990   if(nbOfTuple2==nbOfTuple1)
8991     {
8992       if(nbOfComp1==nbOfComp2)
8993         {
8994           MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
8995           ret->alloc(nbOfTuple2,nbOfComp1);
8996           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::minus<int>());
8997           ret->copyStringInfoFrom(*a1);
8998           return ret.retn();
8999         }
9000       else if(nbOfComp2==1)
9001         {
9002           MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
9003           ret->alloc(nbOfTuple1,nbOfComp1);
9004           const int *a2Ptr=a2->getConstPointer();
9005           const int *a1Ptr=a1->getConstPointer();
9006           int *res=ret->getPointer();
9007           for(int i=0;i<nbOfTuple1;i++)
9008             res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::minus<int>(),a2Ptr[i]));
9009           ret->copyStringInfoFrom(*a1);
9010           return ret.retn();
9011         }
9012       else
9013         {
9014           a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Substract !");
9015           return 0;
9016         }
9017     }
9018   else if(nbOfTuple2==1)
9019     {
9020       a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Substract !");
9021       MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
9022       ret->alloc(nbOfTuple1,nbOfComp1);
9023       const int *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
9024       int *pt=ret->getPointer();
9025       for(int i=0;i<nbOfTuple1;i++)
9026         pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::minus<int>());
9027       ret->copyStringInfoFrom(*a1);
9028       return ret.retn();
9029     }
9030   else
9031     {
9032       a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Substract !");//will always throw an exception
9033       return 0;
9034     }
9035 }
9036
9037 /*!
9038  * Subtract values of another DataArrayInt from values of \a this one. There are 3
9039  * valid cases.
9040  * 1.  The arrays have same number of tuples and components. Then each value of
9041  *   \a other array is subtracted from the corresponding value of \a this array, i.e.:
9042  *   _a_ [ i, j ] -= _other_ [ i, j ].
9043  * 2.  The arrays have same number of tuples and \a other array has one component. Then
9044  *   _a_ [ i, j ] -= _other_ [ i, 0 ].
9045  * 3.  The arrays have same number of components and \a other array has one tuple. Then
9046  *   _a_ [ i, j ] -= _a2_ [ 0, j ].
9047  *
9048  *  \param [in] other - an array to subtract from \a this one.
9049  *  \throw If \a other is NULL.
9050  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
9051  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
9052  *         \a other has number of both tuples and components not equal to 1.
9053  */
9054 void DataArrayInt::substractEqual(const DataArrayInt *other) throw(INTERP_KERNEL::Exception)
9055 {
9056   if(!other)
9057     throw INTERP_KERNEL::Exception("DataArrayInt::substractEqual : input DataArrayInt instance is NULL !");
9058   const char *msg="Nb of tuples mismatch for DataArrayInt::substractEqual  !";
9059   checkAllocated(); other->checkAllocated();
9060   int nbOfTuple=getNumberOfTuples();
9061   int nbOfTuple2=other->getNumberOfTuples();
9062   int nbOfComp=getNumberOfComponents();
9063   int nbOfComp2=other->getNumberOfComponents();
9064   if(nbOfTuple==nbOfTuple2)
9065     {
9066       if(nbOfComp==nbOfComp2)
9067         {
9068           std::transform(begin(),end(),other->begin(),getPointer(),std::minus<int>());
9069         }
9070       else if(nbOfComp2==1)
9071         {
9072           int *ptr=getPointer();
9073           const int *ptrc=other->getConstPointer();
9074           for(int i=0;i<nbOfTuple;i++)
9075             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::minus<int>(),*ptrc++));
9076         }
9077       else
9078         throw INTERP_KERNEL::Exception(msg);
9079     }
9080   else if(nbOfTuple2==1)
9081     {
9082       int *ptr=getPointer();
9083       const int *ptrc=other->getConstPointer();
9084       for(int i=0;i<nbOfTuple;i++)
9085         std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::minus<int>());
9086     }
9087   else
9088     throw INTERP_KERNEL::Exception(msg);
9089   declareAsNew();
9090 }
9091
9092 /*!
9093  * Returns a new DataArrayInt that is a product of two given arrays. There are 3
9094  * valid cases.
9095  * 1.  The arrays have same number of tuples and components. Then each value of
9096  *   the result array (_a_) is a product of the corresponding values of \a a1 and
9097  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ i, j ].
9098  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
9099  *   component. Then
9100  *   _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ i, 0 ].
9101  * 3.  The arrays have same number of components and one array, say _a2_, has one
9102  *   tuple. Then
9103  *   _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ 0, j ].
9104  *
9105  * Info on components is copied either from the first array (in the first case) or from
9106  * the array with maximal number of elements (getNbOfElems()).
9107  *  \param [in] a1 - a factor array.
9108  *  \param [in] a2 - another factor array.
9109  *  \return DataArrayInt * - the new instance of DataArrayInt.
9110  *          The caller is to delete this result array using decrRef() as it is no more
9111  *          needed.
9112  *  \throw If either \a a1 or \a a2 is NULL.
9113  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
9114  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
9115  *         none of them has number of tuples or components equal to 1.
9116  */
9117 DataArrayInt *DataArrayInt::Multiply(const DataArrayInt *a1, const DataArrayInt *a2) throw(INTERP_KERNEL::Exception)
9118 {
9119   if(!a1 || !a2)
9120     throw INTERP_KERNEL::Exception("DataArrayInt::Multiply : input DataArrayInt instance is NULL !");
9121   int nbOfTuple=a1->getNumberOfTuples();
9122   int nbOfTuple2=a2->getNumberOfTuples();
9123   int nbOfComp=a1->getNumberOfComponents();
9124   int nbOfComp2=a2->getNumberOfComponents();
9125   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=0;
9126   if(nbOfTuple==nbOfTuple2)
9127     {
9128       if(nbOfComp==nbOfComp2)
9129         {
9130           ret=DataArrayInt::New();
9131           ret->alloc(nbOfTuple,nbOfComp);
9132           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::multiplies<int>());
9133           ret->copyStringInfoFrom(*a1);
9134         }
9135       else
9136         {
9137           int nbOfCompMin,nbOfCompMax;
9138           const DataArrayInt *aMin, *aMax;
9139           if(nbOfComp>nbOfComp2)
9140             {
9141               nbOfCompMin=nbOfComp2; nbOfCompMax=nbOfComp;
9142               aMin=a2; aMax=a1;
9143             }
9144           else
9145             {
9146               nbOfCompMin=nbOfComp; nbOfCompMax=nbOfComp2;
9147               aMin=a1; aMax=a2;
9148             }
9149           if(nbOfCompMin==1)
9150             {
9151               ret=DataArrayInt::New();
9152               ret->alloc(nbOfTuple,nbOfCompMax);
9153               const int *aMinPtr=aMin->getConstPointer();
9154               const int *aMaxPtr=aMax->getConstPointer();
9155               int *res=ret->getPointer();
9156               for(int i=0;i<nbOfTuple;i++)
9157                 res=std::transform(aMaxPtr+i*nbOfCompMax,aMaxPtr+(i+1)*nbOfCompMax,res,std::bind2nd(std::multiplies<int>(),aMinPtr[i]));
9158               ret->copyStringInfoFrom(*aMax);
9159             }
9160           else
9161             throw INTERP_KERNEL::Exception("Nb of components mismatch for array Multiply !");
9162         }
9163     }
9164   else if((nbOfTuple==1 && nbOfTuple2>1) || (nbOfTuple>1 && nbOfTuple2==1))
9165     {
9166       if(nbOfComp==nbOfComp2)
9167         {
9168           int nbOfTupleMax=std::max(nbOfTuple,nbOfTuple2);
9169           const DataArrayInt *aMin=nbOfTuple>nbOfTuple2?a2:a1;
9170           const DataArrayInt *aMax=nbOfTuple>nbOfTuple2?a1:a2;
9171           const int *aMinPtr=aMin->getConstPointer(),*aMaxPtr=aMax->getConstPointer();
9172           ret=DataArrayInt::New();
9173           ret->alloc(nbOfTupleMax,nbOfComp);
9174           int *res=ret->getPointer();
9175           for(int i=0;i<nbOfTupleMax;i++)
9176             res=std::transform(aMaxPtr+i*nbOfComp,aMaxPtr+(i+1)*nbOfComp,aMinPtr,res,std::multiplies<int>());
9177           ret->copyStringInfoFrom(*aMax);
9178         }
9179       else
9180         throw INTERP_KERNEL::Exception("Nb of components mismatch for array Multiply !");
9181     }
9182   else
9183     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Multiply !");
9184   return ret.retn();
9185 }
9186
9187
9188 /*!
9189  * Multiply values of another DataArrayInt to values of \a this one. There are 3
9190  * valid cases.
9191  * 1.  The arrays have same number of tuples and components. Then each value of
9192  *   \a other array is multiplied to the corresponding value of \a this array, i.e.:
9193  *   _a_ [ i, j ] *= _other_ [ i, j ].
9194  * 2.  The arrays have same number of tuples and \a other array has one component. Then
9195  *   _a_ [ i, j ] *= _other_ [ i, 0 ].
9196  * 3.  The arrays have same number of components and \a other array has one tuple. Then
9197  *   _a_ [ i, j ] *= _a2_ [ 0, j ].
9198  *
9199  *  \param [in] other - an array to multiply to \a this one.
9200  *  \throw If \a other is NULL.
9201  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
9202  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
9203  *         \a other has number of both tuples and components not equal to 1.
9204  */
9205 void DataArrayInt::multiplyEqual(const DataArrayInt *other) throw(INTERP_KERNEL::Exception)
9206 {
9207   if(!other)
9208     throw INTERP_KERNEL::Exception("DataArrayInt::multiplyEqual : input DataArrayInt instance is NULL !");
9209   const char *msg="Nb of tuples mismatch for DataArrayInt::multiplyEqual !";
9210   checkAllocated(); other->checkAllocated();
9211   int nbOfTuple=getNumberOfTuples();
9212   int nbOfTuple2=other->getNumberOfTuples();
9213   int nbOfComp=getNumberOfComponents();
9214   int nbOfComp2=other->getNumberOfComponents();
9215   if(nbOfTuple==nbOfTuple2)
9216     {
9217       if(nbOfComp==nbOfComp2)
9218         {
9219           std::transform(begin(),end(),other->begin(),getPointer(),std::multiplies<int>());
9220         }
9221       else if(nbOfComp2==1)
9222         {
9223           int *ptr=getPointer();
9224           const int *ptrc=other->getConstPointer();
9225           for(int i=0;i<nbOfTuple;i++)
9226             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::multiplies<int>(),*ptrc++));    
9227         }
9228       else
9229         throw INTERP_KERNEL::Exception(msg);
9230     }
9231   else if(nbOfTuple2==1)
9232     {
9233       if(nbOfComp2==nbOfComp)
9234         {
9235           int *ptr=getPointer();
9236           const int *ptrc=other->getConstPointer();
9237           for(int i=0;i<nbOfTuple;i++)
9238             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::multiplies<int>());
9239         }
9240       else
9241         throw INTERP_KERNEL::Exception(msg);
9242     }
9243   else
9244     throw INTERP_KERNEL::Exception(msg);
9245   declareAsNew();
9246 }
9247
9248
9249 /*!
9250  * Returns a new DataArrayInt that is a division of two given arrays. There are 3
9251  * valid cases.
9252  * 1.  The arrays have same number of tuples and components. Then each value of
9253  *   the result array (_a_) is a division of the corresponding values of \a a1 and
9254  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ i, j ].
9255  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
9256  *   component. Then
9257  *   _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ i, 0 ].
9258  * 3.  The arrays have same number of components and one array, say _a2_, has one
9259  *   tuple. Then
9260  *   _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ 0, j ].
9261  *
9262  * Info on components is copied either from the first array (in the first case) or from
9263  * the array with maximal number of elements (getNbOfElems()).
9264  *  \param [in] a1 - a numerator array.
9265  *  \param [in] a2 - a denominator array.
9266  *  \return DataArrayInt * - the new instance of DataArrayInt.
9267  *          The caller is to delete this result array using decrRef() as it is no more
9268  *          needed.
9269  *  \throw If either \a a1 or \a a2 is NULL.
9270  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
9271  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
9272  *         none of them has number of tuples or components equal to 1.
9273  *  \warning No check of division by zero is performed!
9274  */
9275 DataArrayInt *DataArrayInt::Divide(const DataArrayInt *a1, const DataArrayInt *a2) throw(INTERP_KERNEL::Exception)
9276 {
9277   if(!a1 || !a2)
9278     throw INTERP_KERNEL::Exception("DataArrayInt::Divide : input DataArrayInt instance is NULL !");
9279   int nbOfTuple1=a1->getNumberOfTuples();
9280   int nbOfTuple2=a2->getNumberOfTuples();
9281   int nbOfComp1=a1->getNumberOfComponents();
9282   int nbOfComp2=a2->getNumberOfComponents();
9283   if(nbOfTuple2==nbOfTuple1)
9284     {
9285       if(nbOfComp1==nbOfComp2)
9286         {
9287           MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
9288           ret->alloc(nbOfTuple2,nbOfComp1);
9289           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::divides<int>());
9290           ret->copyStringInfoFrom(*a1);
9291           return ret.retn();
9292         }
9293       else if(nbOfComp2==1)
9294         {
9295           MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
9296           ret->alloc(nbOfTuple1,nbOfComp1);
9297           const int *a2Ptr=a2->getConstPointer();
9298           const int *a1Ptr=a1->getConstPointer();
9299           int *res=ret->getPointer();
9300           for(int i=0;i<nbOfTuple1;i++)
9301             res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::divides<int>(),a2Ptr[i]));
9302           ret->copyStringInfoFrom(*a1);
9303           return ret.retn();
9304         }
9305       else
9306         {
9307           a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Divide !");
9308           return 0;
9309         }
9310     }
9311   else if(nbOfTuple2==1)
9312     {
9313       a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Divide !");
9314       MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
9315       ret->alloc(nbOfTuple1,nbOfComp1);
9316       const int *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
9317       int *pt=ret->getPointer();
9318       for(int i=0;i<nbOfTuple1;i++)
9319         pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::divides<int>());
9320       ret->copyStringInfoFrom(*a1);
9321       return ret.retn();
9322     }
9323   else
9324     {
9325       a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Divide !");//will always throw an exception
9326       return 0;
9327     }
9328 }
9329
9330 /*!
9331  * Divide values of \a this array by values of another DataArrayInt. There are 3
9332  * valid cases.
9333  * 1.  The arrays have same number of tuples and components. Then each value of
9334  *    \a this array is divided by the corresponding value of \a other one, i.e.:
9335  *   _a_ [ i, j ] /= _other_ [ i, j ].
9336  * 2.  The arrays have same number of tuples and \a other array has one component. Then
9337  *   _a_ [ i, j ] /= _other_ [ i, 0 ].
9338  * 3.  The arrays have same number of components and \a other array has one tuple. Then
9339  *   _a_ [ i, j ] /= _a2_ [ 0, j ].
9340  *
9341  *  \param [in] other - an array to divide \a this one by.
9342  *  \throw If \a other is NULL.
9343  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
9344  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
9345  *         \a other has number of both tuples and components not equal to 1.
9346  *  \warning No check of division by zero is performed!
9347  */
9348 void DataArrayInt::divideEqual(const DataArrayInt *other) throw(INTERP_KERNEL::Exception)
9349 {
9350   if(!other)
9351     throw INTERP_KERNEL::Exception("DataArrayInt::divideEqual : input DataArrayInt instance is NULL !");
9352   const char *msg="Nb of tuples mismatch for DataArrayInt::divideEqual !";
9353   checkAllocated(); other->checkAllocated();
9354   int nbOfTuple=getNumberOfTuples();
9355   int nbOfTuple2=other->getNumberOfTuples();
9356   int nbOfComp=getNumberOfComponents();
9357   int nbOfComp2=other->getNumberOfComponents();
9358   if(nbOfTuple==nbOfTuple2)
9359     {
9360       if(nbOfComp==nbOfComp2)
9361         {
9362           std::transform(begin(),end(),other->begin(),getPointer(),std::divides<int>());
9363         }
9364       else if(nbOfComp2==1)
9365         {
9366           int *ptr=getPointer();
9367           const int *ptrc=other->getConstPointer();
9368           for(int i=0;i<nbOfTuple;i++)
9369             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::divides<int>(),*ptrc++));
9370         }
9371       else
9372         throw INTERP_KERNEL::Exception(msg);
9373     }
9374   else if(nbOfTuple2==1)
9375     {
9376       if(nbOfComp2==nbOfComp)
9377         {
9378           int *ptr=getPointer();
9379           const int *ptrc=other->getConstPointer();
9380           for(int i=0;i<nbOfTuple;i++)
9381             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::divides<int>());
9382         }
9383       else
9384         throw INTERP_KERNEL::Exception(msg);
9385     }
9386   else
9387     throw INTERP_KERNEL::Exception(msg);
9388   declareAsNew();
9389 }
9390
9391
9392 /*!
9393  * Returns a new DataArrayInt that is a modulus of two given arrays. There are 3
9394  * valid cases.
9395  * 1.  The arrays have same number of tuples and components. Then each value of
9396  *   the result array (_a_) is a division of the corresponding values of \a a1 and
9397  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] % _a2_ [ i, j ].
9398  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
9399  *   component. Then
9400  *   _a_ [ i, j ] = _a1_ [ i, j ] % _a2_ [ i, 0 ].
9401  * 3.  The arrays have same number of components and one array, say _a2_, has one
9402  *   tuple. Then
9403  *   _a_ [ i, j ] = _a1_ [ i, j ] % _a2_ [ 0, j ].
9404  *
9405  * Info on components is copied either from the first array (in the first case) or from
9406  * the array with maximal number of elements (getNbOfElems()).
9407  *  \param [in] a1 - a dividend array.
9408  *  \param [in] a2 - a divisor array.
9409  *  \return DataArrayInt * - the new instance of DataArrayInt.
9410  *          The caller is to delete this result array using decrRef() as it is no more
9411  *          needed.
9412  *  \throw If either \a a1 or \a a2 is NULL.
9413  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
9414  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
9415  *         none of them has number of tuples or components equal to 1.
9416  *  \warning No check of division by zero is performed!
9417  */
9418 DataArrayInt *DataArrayInt::Modulus(const DataArrayInt *a1, const DataArrayInt *a2) throw(INTERP_KERNEL::Exception)
9419 {
9420     if(!a1 || !a2)
9421     throw INTERP_KERNEL::Exception("DataArrayInt::Modulus : input DataArrayInt instance is NULL !");
9422   int nbOfTuple1=a1->getNumberOfTuples();
9423   int nbOfTuple2=a2->getNumberOfTuples();
9424   int nbOfComp1=a1->getNumberOfComponents();
9425   int nbOfComp2=a2->getNumberOfComponents();
9426   if(nbOfTuple2==nbOfTuple1)
9427     {
9428       if(nbOfComp1==nbOfComp2)
9429         {
9430           MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
9431           ret->alloc(nbOfTuple2,nbOfComp1);
9432           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::modulus<int>());
9433           ret->copyStringInfoFrom(*a1);
9434           return ret.retn();
9435         }
9436       else if(nbOfComp2==1)
9437         {
9438           MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
9439           ret->alloc(nbOfTuple1,nbOfComp1);
9440           const int *a2Ptr=a2->getConstPointer();
9441           const int *a1Ptr=a1->getConstPointer();
9442           int *res=ret->getPointer();
9443           for(int i=0;i<nbOfTuple1;i++)
9444             res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::modulus<int>(),a2Ptr[i]));
9445           ret->copyStringInfoFrom(*a1);
9446           return ret.retn();
9447         }
9448       else
9449         {
9450           a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Modulus !");
9451           return 0;
9452         }
9453     }
9454   else if(nbOfTuple2==1)
9455     {
9456       a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Modulus !");
9457       MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
9458       ret->alloc(nbOfTuple1,nbOfComp1);
9459       const int *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
9460       int *pt=ret->getPointer();
9461       for(int i=0;i<nbOfTuple1;i++)
9462         pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::modulus<int>());
9463       ret->copyStringInfoFrom(*a1);
9464       return ret.retn();
9465     }
9466   else
9467     {
9468       a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Modulus !");//will always throw an exception
9469       return 0;
9470     }
9471 }
9472
9473 /*!
9474  * Modify \a this array so that each value becomes a modulus of division of this value by
9475  * a value of another DataArrayInt. There are 3 valid cases.
9476  * 1.  The arrays have same number of tuples and components. Then each value of
9477  *    \a this array is divided by the corresponding value of \a other one, i.e.:
9478  *   _a_ [ i, j ] %= _other_ [ i, j ].
9479  * 2.  The arrays have same number of tuples and \a other array has one component. Then
9480  *   _a_ [ i, j ] %= _other_ [ i, 0 ].
9481  * 3.  The arrays have same number of components and \a other array has one tuple. Then
9482  *   _a_ [ i, j ] %= _a2_ [ 0, j ].
9483  *
9484  *  \param [in] other - a divisor array.
9485  *  \throw If \a other is NULL.
9486  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
9487  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
9488  *         \a other has number of both tuples and components not equal to 1.
9489  *  \warning No check of division by zero is performed!
9490  */
9491 void DataArrayInt::modulusEqual(const DataArrayInt *other) throw(INTERP_KERNEL::Exception)
9492 {
9493   if(!other)
9494     throw INTERP_KERNEL::Exception("DataArrayInt::modulusEqual : input DataArrayInt instance is NULL !");
9495   const char *msg="Nb of tuples mismatch for DataArrayInt::modulusEqual !";
9496   checkAllocated(); other->checkAllocated();
9497   int nbOfTuple=getNumberOfTuples();
9498   int nbOfTuple2=other->getNumberOfTuples();
9499   int nbOfComp=getNumberOfComponents();
9500   int nbOfComp2=other->getNumberOfComponents();
9501   if(nbOfTuple==nbOfTuple2)
9502     {
9503       if(nbOfComp==nbOfComp2)
9504         {
9505           std::transform(begin(),end(),other->begin(),getPointer(),std::modulus<int>());
9506         }
9507       else if(nbOfComp2==1)
9508         {
9509           if(nbOfComp2==nbOfComp)
9510             {
9511               int *ptr=getPointer();
9512               const int *ptrc=other->getConstPointer();
9513               for(int i=0;i<nbOfTuple;i++)
9514                 std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::modulus<int>(),*ptrc++));
9515             }
9516           else
9517             throw INTERP_KERNEL::Exception(msg);
9518         }
9519       else
9520         throw INTERP_KERNEL::Exception(msg);
9521     }
9522   else if(nbOfTuple2==1)
9523     {
9524       int *ptr=getPointer();
9525       const int *ptrc=other->getConstPointer();
9526       for(int i=0;i<nbOfTuple;i++)
9527         std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::modulus<int>());
9528     }
9529   else
9530     throw INTERP_KERNEL::Exception(msg);
9531   declareAsNew();
9532 }
9533
9534 /*!
9535  * Returns a C array which is a renumbering map in "Old to New" mode for the input array.
9536  * This map, if applied to \a start array, would make it sorted. For example, if
9537  * \a start array contents are [9,10,0,6,4,11,3,7] then the contents of the result array is
9538  * [5,6,0,3,2,7,1,4].
9539  *  \param [in] start - pointer to the first element of the array for which the
9540  *         permutation map is computed.
9541  *  \param [in] end - pointer specifying the end of the array \a start, so that
9542  *         the last value of \a start is \a end[ -1 ].
9543  *  \return int * - the result permutation array that the caller is to delete as it is no
9544  *         more needed.
9545  *  \throw If there are equal values in the input array.
9546  */
9547 int *DataArrayInt::CheckAndPreparePermutation(const int *start, const int *end)
9548 {
9549   std::size_t sz=std::distance(start,end);
9550   int *ret=new int[sz];
9551   int *work=new int[sz];
9552   std::copy(start,end,work);
9553   std::sort(work,work+sz);
9554   if(std::unique(work,work+sz)!=work+sz)
9555     {
9556       delete [] work;
9557       delete [] ret;
9558       throw INTERP_KERNEL::Exception("Some elements are equals in the specified array !");
9559     }
9560   int *iter2=ret;
9561   for(const int *iter=start;iter!=end;iter++,iter2++)
9562     *iter2=(int)std::distance(work,std::find(work,work+sz,*iter));
9563   delete [] work;
9564   return ret;
9565 }
9566
9567 /*!
9568  * Returns a new DataArrayInt containing an arithmetic progression
9569  * that is equal to the sequence returned by Python \c range(\a begin,\a  end,\a  step )
9570  * function.
9571  *  \param [in] begin - the start value of the result sequence.
9572  *  \param [in] end - limiting value, so that every value of the result array is less than
9573  *              \a end.
9574  *  \param [in] step - specifies the increment or decrement.
9575  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
9576  *          array using decrRef() as it is no more needed.
9577  *  \throw If \a step == 0.
9578  *  \throw If \a end < \a begin && \a step > 0.
9579  *  \throw If \a end > \a begin && \a step < 0.
9580  */
9581 DataArrayInt *DataArrayInt::Range(int begin, int end, int step) throw(INTERP_KERNEL::Exception)
9582 {
9583   int nbOfTuples=GetNumberOfItemGivenBESRelative(begin,end,step,"DataArrayInt::Range");
9584   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
9585   ret->alloc(nbOfTuples,1);
9586   int *ptr=ret->getPointer();
9587   if(step>0)
9588     {
9589       for(int i=begin;i<end;i+=step,ptr++)
9590         *ptr=i;
9591     }
9592   else
9593     {
9594       for(int i=begin;i>end;i+=step,ptr++)
9595         *ptr=i;
9596     }
9597   return ret.retn();
9598 }
9599
9600 /*!
9601  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
9602  * Server side.
9603  */
9604 void DataArrayInt::getTinySerializationIntInformation(std::vector<int>& tinyInfo) const
9605 {
9606   tinyInfo.resize(2);
9607   if(isAllocated())
9608     {
9609       tinyInfo[0]=getNumberOfTuples();
9610       tinyInfo[1]=getNumberOfComponents();
9611     }
9612   else
9613     {
9614       tinyInfo[0]=-1;
9615       tinyInfo[1]=-1;
9616     }
9617 }
9618
9619 /*!
9620  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
9621  * Server side.
9622  */
9623 void DataArrayInt::getTinySerializationStrInformation(std::vector<std::string>& tinyInfo) const
9624 {
9625   if(isAllocated())
9626     {
9627       int nbOfCompo=getNumberOfComponents();
9628       tinyInfo.resize(nbOfCompo+1);
9629       tinyInfo[0]=getName();
9630       for(int i=0;i<nbOfCompo;i++)
9631         tinyInfo[i+1]=getInfoOnComponent(i);
9632     }
9633   else
9634     {
9635       tinyInfo.resize(1);
9636       tinyInfo[0]=getName();
9637     }
9638 }
9639
9640 /*!
9641  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
9642  * This method returns if a feeding is needed.
9643  */
9644 bool DataArrayInt::resizeForUnserialization(const std::vector<int>& tinyInfoI)
9645 {
9646   int nbOfTuple=tinyInfoI[0];
9647   int nbOfComp=tinyInfoI[1];
9648   if(nbOfTuple!=-1 || nbOfComp!=-1)
9649     {
9650       alloc(nbOfTuple,nbOfComp);
9651       return true;
9652     }
9653   return false;
9654 }
9655
9656 /*!
9657  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
9658  * This method returns if a feeding is needed.
9659  */
9660 void DataArrayInt::finishUnserialization(const std::vector<int>& tinyInfoI, const std::vector<std::string>& tinyInfoS)
9661 {
9662   setName(tinyInfoS[0].c_str());
9663   if(isAllocated())
9664     {
9665       int nbOfCompo=getNumberOfComponents();
9666       for(int i=0;i<nbOfCompo;i++)
9667         setInfoOnComponent(i,tinyInfoS[i+1].c_str());
9668     }
9669 }
9670
9671 DataArrayIntIterator::DataArrayIntIterator(DataArrayInt *da):_da(da),_pt(0),_tuple_id(0),_nb_comp(0),_nb_tuple(0)
9672 {
9673   if(_da)
9674     {
9675       _da->incrRef();
9676       if(_da->isAllocated())
9677         {
9678           _nb_comp=da->getNumberOfComponents();
9679           _nb_tuple=da->getNumberOfTuples();
9680           _pt=da->getPointer();
9681         }
9682     }
9683 }
9684
9685 DataArrayIntIterator::~DataArrayIntIterator()
9686 {
9687   if(_da)
9688     _da->decrRef();
9689 }
9690
9691 DataArrayIntTuple *DataArrayIntIterator::nextt() throw(INTERP_KERNEL::Exception)
9692 {
9693   if(_tuple_id<_nb_tuple)
9694     {
9695       _tuple_id++;
9696       DataArrayIntTuple *ret=new DataArrayIntTuple(_pt,_nb_comp);
9697       _pt+=_nb_comp;
9698       return ret;
9699     }
9700   else
9701     return 0;
9702 }
9703
9704 DataArrayIntTuple::DataArrayIntTuple(int *pt, int nbOfComp):_pt(pt),_nb_of_compo(nbOfComp)
9705 {
9706 }
9707
9708 std::string DataArrayIntTuple::repr() const throw(INTERP_KERNEL::Exception)
9709 {
9710   std::ostringstream oss; oss << "(";
9711   for(int i=0;i<_nb_of_compo-1;i++)
9712     oss << _pt[i] << ", ";
9713   oss << _pt[_nb_of_compo-1] << ")";
9714   return oss.str();
9715 }
9716
9717 int DataArrayIntTuple::intValue() const throw(INTERP_KERNEL::Exception)
9718 {
9719   if(_nb_of_compo==1)
9720     return *_pt;
9721   throw INTERP_KERNEL::Exception("DataArrayIntTuple::intValue : DataArrayIntTuple instance has not exactly 1 component -> Not possible to convert it into an integer !");
9722 }
9723
9724 /*!
9725  * This method returns a newly allocated instance the caller should dealed with by a ParaMEDMEM::DataArrayInt::decrRef.
9726  * This method performs \b no copy of data. The content is only referenced using ParaMEDMEM::DataArrayInt::useArray with ownership set to \b false.
9727  * 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
9728  * \b nbOfCompo=1 and \bnbOfTuples==this->_nb_of_elem.
9729  */
9730 DataArrayInt *DataArrayIntTuple::buildDAInt(int nbOfTuples, int nbOfCompo) const throw(INTERP_KERNEL::Exception)
9731 {
9732   if((_nb_of_compo==nbOfCompo && nbOfTuples==1) || (_nb_of_compo==nbOfTuples && nbOfCompo==1))
9733     {
9734       DataArrayInt *ret=DataArrayInt::New();
9735       ret->useExternalArrayWithRWAccess(_pt,nbOfTuples,nbOfCompo);
9736       return ret;
9737     }
9738   else
9739     {
9740       std::ostringstream oss; oss << "DataArrayIntTuple::buildDAInt : unable to build a requested DataArrayInt instance with nbofTuple=" << nbOfTuples << " and nbOfCompo=" << nbOfCompo;
9741       oss << ".\nBecause the number of elements in this is " << _nb_of_compo << " !";
9742       throw INTERP_KERNEL::Exception(oss.str().c_str());
9743     }
9744 }