Salome HOME
Merge from V6_main 15/03/2013
[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
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
213 {
214   std::string tmp;
215   return areInfoEqualsIfNotWhy(other,tmp);
216 }
217
218 void DataArray::reprWithoutNameStream(std::ostream& stream) const
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
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
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
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
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
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)
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
999 {
1000   std::ostringstream ret;
1001   reprStream(ret);
1002   return ret.str();
1003 }
1004
1005 std::string DataArrayDouble::reprZip() const
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
1023 {
1024   stream << "Name of double array : \"" << _name << "\"\n";
1025   reprWithoutNameStream(stream);
1026 }
1027
1028 void DataArrayDouble::reprZipStream(std::ostream& stream) const
1029 {
1030   stream << "Name of double array : \"" << _name << "\"\n";
1031   reprZipWithoutNameStream(stream);
1032 }
1033
1034 void DataArrayDouble::reprWithoutNameStream(std::ostream& stream) const
1035 {
1036   DataArray::reprWithoutNameStream(stream);
1037   stream.precision(17);
1038   _mem.repr(getNumberOfComponents(),stream);
1039 }
1040
1041 void DataArrayDouble::reprZipWithoutNameStream(std::ostream& stream) const
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
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 bool DataArrayDouble::isEqualIfNotWhy(const DataArrayDouble& other, double prec, std::string& reason) const
1067 {
1068   if(!areInfoEqualsIfNotWhy(other,reason))
1069     return false;
1070   return _mem.isEqual(other._mem,prec,reason);
1071 }
1072
1073 /*!
1074  * Checks if \a this and another DataArrayDouble are fully equal. For more info see
1075  * \ref MEDCouplingArrayBasicsCompare.
1076  *  \param [in] other - an instance of DataArrayDouble to compare with \a this one.
1077  *  \param [in] prec - precision value to compare numeric data of the arrays.
1078  *  \return bool - \a true if the two arrays are equal, \a false else.
1079  */
1080 bool DataArrayDouble::isEqual(const DataArrayDouble& other, double prec) const
1081 {
1082   std::string tmp;
1083   return isEqualIfNotWhy(other,prec,tmp);
1084 }
1085
1086 /*!
1087  * Checks if values of \a this and another DataArrayDouble are equal. For more info see
1088  * \ref MEDCouplingArrayBasicsCompare.
1089  *  \param [in] other - an instance of DataArrayDouble to compare with \a this one.
1090  *  \param [in] prec - precision value to compare numeric data of the arrays.
1091  *  \return bool - \a true if the values of two arrays are equal, \a false else.
1092  */
1093 bool DataArrayDouble::isEqualWithoutConsideringStr(const DataArrayDouble& other, double prec) const
1094 {
1095   std::string tmp;
1096   return _mem.isEqual(other._mem,prec,tmp);
1097 }
1098
1099 /*!
1100  * Changes number of tuples in the array. If the new number of tuples is smaller
1101  * than the current number the array is truncated, otherwise the array is extended.
1102  *  \param [in] nbOfTuples - new number of tuples. 
1103  *  \throw If \a this is not allocated.
1104  */
1105 void DataArrayDouble::reAlloc(int nbOfTuples) throw(INTERP_KERNEL::Exception)
1106 {
1107   checkAllocated();
1108   _mem.reAlloc(getNumberOfComponents()*nbOfTuples);
1109   declareAsNew();
1110 }
1111
1112 /*!
1113  * Creates a new DataArrayInt and assigns all (textual and numerical) data of \a this
1114  * array to the new one.
1115  *  \return DataArrayInt * - the new instance of DataArrayInt.
1116  */
1117 DataArrayInt *DataArrayDouble::convertToIntArr() const
1118 {
1119   DataArrayInt *ret=DataArrayInt::New();
1120   ret->alloc(getNumberOfTuples(),getNumberOfComponents());
1121   int nbOfVals=getNbOfElems();
1122   const double *src=getConstPointer();
1123   int *dest=ret->getPointer();
1124   std::copy(src,src+nbOfVals,dest);
1125   ret->copyStringInfoFrom(*this);
1126   return ret;
1127 }
1128
1129 /*!
1130  * Returns a new DataArrayDouble holding the same values as \a this array but differently
1131  * arranged in memory. If \a this array holds 2 components of 3 values:
1132  * \f$ x_0,x_1,x_2,y_0,y_1,y_2 \f$, then the result array holds these values arranged
1133  * as follows: \f$ x_0,y_0,x_1,y_1,x_2,y_2 \f$.
1134  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1135  *          is to delete using decrRef() as it is no more needed.
1136  *  \throw If \a this is not allocated.
1137  *  \warning Do not confuse this method with transpose()!
1138  */
1139 DataArrayDouble *DataArrayDouble::fromNoInterlace() const throw(INTERP_KERNEL::Exception)
1140 {
1141   if(_mem.isNull())
1142     throw INTERP_KERNEL::Exception("DataArrayDouble::fromNoInterlace : Not defined array !");
1143   double *tab=_mem.fromNoInterlace(getNumberOfComponents());
1144   DataArrayDouble *ret=DataArrayDouble::New();
1145   ret->useArray(tab,true,CPP_DEALLOC,getNumberOfTuples(),getNumberOfComponents());
1146   return ret;
1147 }
1148
1149 /*!
1150  * Returns a new DataArrayDouble holding the same values as \a this array but differently
1151  * arranged in memory. If \a this array holds 2 components of 3 values:
1152  * \f$ x_0,y_0,x_1,y_1,x_2,y_2 \f$, then the result array holds these values arranged
1153  * as follows: \f$ x_0,x_1,x_2,y_0,y_1,y_2 \f$.
1154  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1155  *          is to delete using decrRef() as it is no more needed.
1156  *  \throw If \a this is not allocated.
1157  *  \warning Do not confuse this method with transpose()!
1158  */
1159 DataArrayDouble *DataArrayDouble::toNoInterlace() const throw(INTERP_KERNEL::Exception)
1160 {
1161   if(_mem.isNull())
1162     throw INTERP_KERNEL::Exception("DataArrayDouble::toNoInterlace : Not defined array !");
1163   double *tab=_mem.toNoInterlace(getNumberOfComponents());
1164   DataArrayDouble *ret=DataArrayDouble::New();
1165   ret->useArray(tab,true,CPP_DEALLOC,getNumberOfTuples(),getNumberOfComponents());
1166   return ret;
1167 }
1168
1169 /*!
1170  * Permutes values of \a this array as required by \a old2New array. The values are
1171  * permuted so that \c new[ \a old2New[ i ]] = \c old[ i ]. Number of tuples remains
1172  * the same as in \this one.
1173  * If a permutation reduction is needed, substr() or selectByTupleId() should be used.
1174  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
1175  *  \param [in] old2New - C array of length equal to \a this->getNumberOfTuples()
1176  *     giving a new position for i-th old value.
1177  */
1178 void DataArrayDouble::renumberInPlace(const int *old2New)
1179 {
1180   checkAllocated();
1181   int nbTuples=getNumberOfTuples();
1182   int nbOfCompo=getNumberOfComponents();
1183   double *tmp=new double[nbTuples*nbOfCompo];
1184   const double *iptr=getConstPointer();
1185   for(int i=0;i<nbTuples;i++)
1186     std::copy(iptr+nbOfCompo*i,iptr+nbOfCompo*(i+1),tmp+nbOfCompo*old2New[i]);
1187   std::copy(tmp,tmp+nbTuples*nbOfCompo,getPointer());
1188   delete [] tmp;
1189   declareAsNew();
1190 }
1191
1192 /*!
1193  * Permutes values of \a this array as required by \a new2Old array. The values are
1194  * permuted so that \c new[ i ] = \c old[ \a new2Old[ i ]]. Number of tuples remains
1195  * the same as in \this one.
1196  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
1197  *  \param [in] new2Old - C array of length equal to \a this->getNumberOfTuples()
1198  *     giving a previous position of i-th new value.
1199  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1200  *          is to delete using decrRef() as it is no more needed.
1201  */
1202 void DataArrayDouble::renumberInPlaceR(const int *new2Old)
1203 {
1204   checkAllocated();
1205   int nbTuples=getNumberOfTuples();
1206   int nbOfCompo=getNumberOfComponents();
1207   double *tmp=new double[nbTuples*nbOfCompo];
1208   const double *iptr=getConstPointer();
1209   for(int i=0;i<nbTuples;i++)
1210     std::copy(iptr+nbOfCompo*new2Old[i],iptr+nbOfCompo*(new2Old[i]+1),tmp+nbOfCompo*i);
1211   std::copy(tmp,tmp+nbTuples*nbOfCompo,getPointer());
1212   delete [] tmp;
1213   declareAsNew();
1214 }
1215
1216 /*!
1217  * Returns a copy of \a this array with values permuted as required by \a old2New array.
1218  * The values are permuted so that  \c new[ \a old2New[ i ]] = \c old[ i ].
1219  * Number of tuples in the result array remains the same as in \this one.
1220  * If a permutation reduction is needed, renumberAndReduce() should be used.
1221  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
1222  *  \param [in] old2New - C array of length equal to \a this->getNumberOfTuples()
1223  *          giving a new position for i-th old value.
1224  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1225  *          is to delete using decrRef() as it is no more needed.
1226  *  \throw If \a this is not allocated.
1227  */
1228 DataArrayDouble *DataArrayDouble::renumber(const int *old2New) const
1229 {
1230   checkAllocated();
1231   int nbTuples=getNumberOfTuples();
1232   int nbOfCompo=getNumberOfComponents();
1233   DataArrayDouble *ret=DataArrayDouble::New();
1234   ret->alloc(nbTuples,nbOfCompo);
1235   ret->copyStringInfoFrom(*this);
1236   const double *iptr=getConstPointer();
1237   double *optr=ret->getPointer();
1238   for(int i=0;i<nbTuples;i++)
1239     std::copy(iptr+nbOfCompo*i,iptr+nbOfCompo*(i+1),optr+nbOfCompo*old2New[i]);
1240   ret->copyStringInfoFrom(*this);
1241   return ret;
1242 }
1243
1244 /*!
1245  * Returns a copy of \a this array with values permuted as required by \a new2Old array.
1246  * The values are permuted so that  \c new[ i ] = \c old[ \a new2Old[ i ]]. Number of
1247  * tuples in the result array remains the same as in \this one.
1248  * If a permutation reduction is needed, substr() or selectByTupleId() should be used.
1249  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
1250  *  \param [in] new2Old - C array of length equal to \a this->getNumberOfTuples()
1251  *     giving a previous position of i-th new value.
1252  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1253  *          is to delete using decrRef() as it is no more needed.
1254  */
1255 DataArrayDouble *DataArrayDouble::renumberR(const int *new2Old) const
1256 {
1257   checkAllocated();
1258   int nbTuples=getNumberOfTuples();
1259   int nbOfCompo=getNumberOfComponents();
1260   DataArrayDouble *ret=DataArrayDouble::New();
1261   ret->alloc(nbTuples,nbOfCompo);
1262   ret->copyStringInfoFrom(*this);
1263   const double *iptr=getConstPointer();
1264   double *optr=ret->getPointer();
1265   for(int i=0;i<nbTuples;i++)
1266     std::copy(iptr+nbOfCompo*new2Old[i],iptr+nbOfCompo*(new2Old[i]+1),optr+i*nbOfCompo);
1267   ret->copyStringInfoFrom(*this);
1268   return ret;
1269 }
1270
1271 /*!
1272  * Returns a shorten and permuted copy of \a this array. The new DataArrayDouble is
1273  * of size \a newNbOfTuple and it's values are permuted as required by \a old2New array.
1274  * The values are permuted so that  \c new[ \a old2New[ i ]] = \c old[ i ] for all
1275  * \a old2New[ i ] >= 0. In other words every i-th tuple in \a this array, for which 
1276  * \a old2New[ i ] is negative, is missing from the result array.
1277  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
1278  *  \param [in] old2New - C array of length equal to \a this->getNumberOfTuples()
1279  *     giving a new position for i-th old tuple and giving negative position for
1280  *     for i-th old tuple that should be omitted.
1281  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1282  *          is to delete using decrRef() as it is no more needed.
1283  */
1284 DataArrayDouble *DataArrayDouble::renumberAndReduce(const int *old2New, int newNbOfTuple) const
1285 {
1286   checkAllocated();
1287   int nbTuples=getNumberOfTuples();
1288   int nbOfCompo=getNumberOfComponents();
1289   DataArrayDouble *ret=DataArrayDouble::New();
1290   ret->alloc(newNbOfTuple,nbOfCompo);
1291   const double *iptr=getConstPointer();
1292   double *optr=ret->getPointer();
1293   for(int i=0;i<nbTuples;i++)
1294     {
1295       int w=old2New[i];
1296       if(w>=0)
1297         std::copy(iptr+i*nbOfCompo,iptr+(i+1)*nbOfCompo,optr+w*nbOfCompo);
1298     }
1299   ret->copyStringInfoFrom(*this);
1300   return ret;
1301 }
1302
1303 /*!
1304  * Returns a shorten and permuted copy of \a this array. The new DataArrayDouble is
1305  * of size \a new2OldEnd - \a new2OldBg and it's values are permuted as required by
1306  * \a new2OldBg array.
1307  * The values are permuted so that  \c new[ i ] = \c old[ \a new2OldBg[ i ]].
1308  * This method is equivalent to renumberAndReduce() except that convention in input is
1309  * \c new2old and \b not \c old2new.
1310  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
1311  *  \param [in] new2OldBg - pointer to the beginning of a permutation array that gives a
1312  *              tuple index in \a this array to fill the i-th tuple in the new array.
1313  *  \param [in] new2OldEnd - specifies the end of the permutation array that starts at
1314  *              \a new2OldBg, so that pointer to a tuple index (\a pi) varies as this:
1315  *              \a new2OldBg <= \a pi < \a new2OldEnd.
1316  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1317  *          is to delete using decrRef() as it is no more needed.
1318  */
1319 DataArrayDouble *DataArrayDouble::selectByTupleId(const int *new2OldBg, const int *new2OldEnd) const
1320 {
1321   checkAllocated();
1322   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
1323   int nbComp=getNumberOfComponents();
1324   ret->alloc((int)std::distance(new2OldBg,new2OldEnd),nbComp);
1325   ret->copyStringInfoFrom(*this);
1326   double *pt=ret->getPointer();
1327   const double *srcPt=getConstPointer();
1328   int i=0;
1329   for(const int *w=new2OldBg;w!=new2OldEnd;w++,i++)
1330     std::copy(srcPt+(*w)*nbComp,srcPt+((*w)+1)*nbComp,pt+i*nbComp);
1331   ret->copyStringInfoFrom(*this);
1332   return ret.retn();
1333 }
1334
1335 /*!
1336  * Returns a shorten and permuted copy of \a this array. The new DataArrayDouble is
1337  * of size \a new2OldEnd - \a new2OldBg and it's values are permuted as required by
1338  * \a new2OldBg array.
1339  * The values are permuted so that  \c new[ i ] = \c old[ \a new2OldBg[ i ]].
1340  * This method is equivalent to renumberAndReduce() except that convention in input is
1341  * \c new2old and \b not \c old2new.
1342  * This method is equivalent to selectByTupleId() except that it prevents coping data
1343  * from behind the end of \a this array.
1344  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
1345  *  \param [in] new2OldBg - pointer to the beginning of a permutation array that gives a
1346  *              tuple index in \a this array to fill the i-th tuple in the new array.
1347  *  \param [in] new2OldEnd - specifies the end of the permutation array that starts at
1348  *              \a new2OldBg, so that pointer to a tuple index (\a pi) varies as this:
1349  *              \a new2OldBg <= \a pi < \a new2OldEnd.
1350  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1351  *          is to delete using decrRef() as it is no more needed.
1352  *  \throw If \a new2OldEnd - \a new2OldBg > \a this->getNumberOfTuples().
1353  */
1354 DataArrayDouble *DataArrayDouble::selectByTupleIdSafe(const int *new2OldBg, const int *new2OldEnd) const throw(INTERP_KERNEL::Exception)
1355 {
1356   checkAllocated();
1357   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
1358   int nbComp=getNumberOfComponents();
1359   int oldNbOfTuples=getNumberOfTuples();
1360   ret->alloc((int)std::distance(new2OldBg,new2OldEnd),nbComp);
1361   ret->copyStringInfoFrom(*this);
1362   double *pt=ret->getPointer();
1363   const double *srcPt=getConstPointer();
1364   int i=0;
1365   for(const int *w=new2OldBg;w!=new2OldEnd;w++,i++)
1366     if(*w>=0 && *w<oldNbOfTuples)
1367       std::copy(srcPt+(*w)*nbComp,srcPt+((*w)+1)*nbComp,pt+i*nbComp);
1368     else
1369       throw INTERP_KERNEL::Exception("DataArrayInt::selectByTupleIdSafe : some ids has been detected to be out of [0,this->getNumberOfTuples) !");
1370   ret->copyStringInfoFrom(*this);
1371   return ret.retn();
1372 }
1373
1374 /*!
1375  * Returns a shorten copy of \a this array. The new DataArrayDouble contains every
1376  * (\a bg + \c i * \a step)-th tuple of \a this array located before the \a end2-th
1377  * tuple. Indices of the selected tuples are the same as ones returned by the Python
1378  * command \c range( \a bg, \a end2, \a step ).
1379  * This method is equivalent to selectByTupleIdSafe() except that the input array is
1380  * not constructed explicitly.
1381  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
1382  *  \param [in] bg - index of the first tuple to copy from \a this array.
1383  *  \param [in] end2 - index of the tuple before which the tuples to copy are located.
1384  *  \param [in] step - index increment to get index of the next tuple to copy.
1385  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1386  *          is to delete using decrRef() as it is no more needed.
1387  *  \throw If (\a end2 < \a bg) or (\a step <= 0).
1388  *  \sa DataArrayDouble::substr.
1389  */
1390 DataArrayDouble *DataArrayDouble::selectByTupleId2(int bg, int end2, int step) const throw(INTERP_KERNEL::Exception)
1391 {
1392   checkAllocated();
1393   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
1394   int nbComp=getNumberOfComponents();
1395   int newNbOfTuples=GetNumberOfItemGivenBES(bg,end2,step,"DataArrayDouble::selectByTupleId2 : ");
1396   ret->alloc(newNbOfTuples,nbComp);
1397   double *pt=ret->getPointer();
1398   const double *srcPt=getConstPointer()+bg*nbComp;
1399   for(int i=0;i<newNbOfTuples;i++,srcPt+=step*nbComp)
1400     std::copy(srcPt,srcPt+nbComp,pt+i*nbComp);
1401   ret->copyStringInfoFrom(*this);
1402   return ret.retn();
1403 }
1404
1405 /*!
1406  * Returns a shorten copy of \a this array. The new DataArrayDouble contains ranges
1407  * of tuples specified by \a ranges parameter.
1408  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
1409  *  \param [in] ranges - std::vector of std::pair's each of which defines a range
1410  *              of tuples in [\c begin,\c end) format.
1411  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1412  *          is to delete using decrRef() as it is no more needed.
1413  *  \throw If \a end < \a begin.
1414  *  \throw If \a end > \a this->getNumberOfTuples().
1415  *  \throw If \a this is not allocated.
1416  */
1417 DataArrayDouble *DataArrayDouble::selectByTupleRanges(const std::vector<std::pair<int,int> >& ranges) const throw(INTERP_KERNEL::Exception)
1418 {
1419   checkAllocated();
1420   int nbOfComp=getNumberOfComponents();
1421   int nbOfTuplesThis=getNumberOfTuples();
1422   if(ranges.empty())
1423     {
1424       DataArrayDouble *ret=DataArrayDouble::New();
1425       ret->alloc(0,nbOfComp);
1426       ret->copyStringInfoFrom(*this);
1427       return ret;
1428     }
1429   int ref=ranges.front().first;
1430   int nbOfTuples=0;
1431   bool isIncreasing=true;
1432   for(std::vector<std::pair<int,int> >::const_iterator it=ranges.begin();it!=ranges.end();it++)
1433     {
1434       if((*it).first<=(*it).second)
1435         {
1436           if((*it).first>=0 && (*it).second<=nbOfTuplesThis)
1437             {
1438               nbOfTuples+=(*it).second-(*it).first;
1439               if(isIncreasing)
1440                 isIncreasing=ref<=(*it).first;
1441               ref=(*it).second;
1442             }
1443           else
1444             {
1445               std::ostringstream oss; oss << "DataArrayDouble::selectByTupleRanges : on range #" << std::distance(ranges.begin(),it);
1446               oss << " (" << (*it).first << "," << (*it).second << ") is greater than number of tuples of this :" << nbOfTuples << " !";
1447               throw INTERP_KERNEL::Exception(oss.str().c_str());
1448             }
1449         }
1450       else
1451         {
1452           std::ostringstream oss; oss << "DataArrayDouble::selectByTupleRanges : on range #" << std::distance(ranges.begin(),it);
1453           oss << " (" << (*it).first << "," << (*it).second << ") end is before begin !";
1454           throw INTERP_KERNEL::Exception(oss.str().c_str());
1455         }
1456     }
1457   if(isIncreasing && nbOfTuplesThis==nbOfTuples)
1458     return deepCpy();
1459   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
1460   ret->alloc(nbOfTuples,nbOfComp);
1461   ret->copyStringInfoFrom(*this);
1462   const double *src=getConstPointer();
1463   double *work=ret->getPointer();
1464   for(std::vector<std::pair<int,int> >::const_iterator it=ranges.begin();it!=ranges.end();it++)
1465     work=std::copy(src+(*it).first*nbOfComp,src+(*it).second*nbOfComp,work);
1466   return ret.retn();
1467 }
1468
1469 /*!
1470  * Returns a shorten copy of \a this array. The new DataArrayDouble contains all
1471  * tuples starting from the \a tupleIdBg-th tuple and including all tuples located before
1472  * the \a tupleIdEnd-th one. This methods has a similar behavior as std::string::substr().
1473  * This method is a specialization of selectByTupleId2().
1474  *  \param [in] tupleIdBg - index of the first tuple to copy from \a this array.
1475  *  \param [in] tupleIdEnd - index of the tuple before which the tuples to copy are located.
1476  *          If \a tupleIdEnd == -1, all the tuples till the end of \a this array are copied.
1477  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1478  *          is to delete using decrRef() as it is no more needed.
1479  *  \throw If \a tupleIdBg < 0.
1480  *  \throw If \a tupleIdBg > \a this->getNumberOfTuples().
1481     \throw If \a tupleIdEnd != -1 && \a tupleIdEnd < \a this->getNumberOfTuples().
1482  *  \sa DataArrayDouble::selectByTupleId2
1483  */
1484 DataArrayDouble *DataArrayDouble::substr(int tupleIdBg, int tupleIdEnd) const throw(INTERP_KERNEL::Exception)
1485 {
1486   checkAllocated();
1487   int nbt=getNumberOfTuples();
1488   if(tupleIdBg<0)
1489     throw INTERP_KERNEL::Exception("DataArrayDouble::substr : The tupleIdBg parameter must be greater than 0 !");
1490   if(tupleIdBg>nbt)
1491     throw INTERP_KERNEL::Exception("DataArrayDouble::substr : The tupleIdBg parameter is greater than number of tuples !");
1492   int trueEnd=tupleIdEnd;
1493   if(tupleIdEnd!=-1)
1494     {
1495       if(tupleIdEnd>nbt)
1496         throw INTERP_KERNEL::Exception("DataArrayDouble::substr : The tupleIdBg parameter is greater or equal than number of tuples !");
1497     }
1498   else
1499     trueEnd=nbt;
1500   int nbComp=getNumberOfComponents();
1501   DataArrayDouble *ret=DataArrayDouble::New();
1502   ret->alloc(trueEnd-tupleIdBg,nbComp);
1503   ret->copyStringInfoFrom(*this);
1504   std::copy(getConstPointer()+tupleIdBg*nbComp,getConstPointer()+trueEnd*nbComp,ret->getPointer());
1505   return ret;
1506 }
1507
1508 /*!
1509  * Returns a shorten or extended copy of \a this array. If \a newNbOfComp is less
1510  * than \a this->getNumberOfComponents() then the result array is shorten as each tuple
1511  * is truncated to have \a newNbOfComp components, keeping first components. If \a
1512  * newNbOfComp is more than \a this->getNumberOfComponents() then the result array is
1513  * expanded as each tuple is populated with \a dftValue to have \a newNbOfComp
1514  * components.  
1515  *  \param [in] newNbOfComp - number of components for the new array to have.
1516  *  \param [in] dftValue - value assigned to new values added to the new array.
1517  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1518  *          is to delete using decrRef() as it is no more needed.
1519  *  \throw If \a this is not allocated.
1520  */
1521 DataArrayDouble *DataArrayDouble::changeNbOfComponents(int newNbOfComp, double dftValue) const throw(INTERP_KERNEL::Exception)
1522 {
1523   checkAllocated();
1524   DataArrayDouble *ret=DataArrayDouble::New();
1525   ret->alloc(getNumberOfTuples(),newNbOfComp);
1526   const double *oldc=getConstPointer();
1527   double *nc=ret->getPointer();
1528   int nbOfTuples=getNumberOfTuples();
1529   int oldNbOfComp=getNumberOfComponents();
1530   int dim=std::min(oldNbOfComp,newNbOfComp);
1531   for(int i=0;i<nbOfTuples;i++)
1532     {
1533       int j=0;
1534       for(;j<dim;j++)
1535         nc[newNbOfComp*i+j]=oldc[i*oldNbOfComp+j];
1536       for(;j<newNbOfComp;j++)
1537         nc[newNbOfComp*i+j]=dftValue;
1538     }
1539   ret->setName(getName().c_str());
1540   for(int i=0;i<dim;i++)
1541     ret->setInfoOnComponent(i,getInfoOnComponent(i).c_str());
1542   ret->setName(getName().c_str());
1543   return ret;
1544 }
1545
1546 /*!
1547  * Changes the number of components within \a this array so that its raw data **does
1548  * not** change, instead splitting this data into tuples changes.
1549  *  \param [in] newNbOfComp - number of components for \a this array to have.
1550  *  \throw If \a this is not allocated
1551  *  \throw If getNbOfElems() % \a newNbOfCompo != 0.
1552  *  \warning This method erases all (name and unit) component info set before!
1553  */
1554 void DataArrayDouble::rearrange(int newNbOfCompo) throw(INTERP_KERNEL::Exception)
1555 {
1556   checkAllocated();
1557   int nbOfElems=getNbOfElems();
1558   if(nbOfElems%newNbOfCompo!=0)
1559     throw INTERP_KERNEL::Exception("DataArrayDouble::rearrange : nbOfElems%newNbOfCompo!=0 !");
1560   _info_on_compo.clear();
1561   _info_on_compo.resize(newNbOfCompo);
1562   declareAsNew();
1563 }
1564
1565 /*!
1566  * Changes the number of components within \a this array to be equal to its number
1567  * of tuples, and inversely its number of tuples to become equal to its number of 
1568  * components. So that its raw data **does not** change, instead splitting this
1569  * data into tuples changes.
1570  *  \throw If \a this is not allocated.
1571  *  \warning This method erases all (name and unit) component info set before!
1572  *  \warning Do not confuse this method with fromNoInterlace() and toNoInterlace()!
1573  *  \sa rearrange()
1574  */
1575 void DataArrayDouble::transpose() throw(INTERP_KERNEL::Exception)
1576 {
1577   checkAllocated();
1578   int nbOfTuples=getNumberOfTuples();
1579   rearrange(nbOfTuples);
1580 }
1581
1582 /*!
1583  * Returns a copy of \a this array composed of selected components.
1584  * The new DataArrayDouble has the same number of tuples but includes components
1585  * specified by \a compoIds parameter. So that getNbOfElems() of the result array
1586  * can be either less, same or more than \a this->getNbOfElems().
1587  *  \param [in] compoIds - sequence of zero based indices of components to include
1588  *              into the new array.
1589  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1590  *          is to delete using decrRef() as it is no more needed.
1591  *  \throw If \a this is not allocated.
1592  *  \throw If a component index (\a i) is not valid: 
1593  *         \a i < 0 || \a i >= \a this->getNumberOfComponents().
1594  *
1595  *  \ref cpp_mcdataarraydouble_keepselectedcomponents "Here is a Python example".
1596  */
1597 DataArrayDouble *DataArrayDouble::keepSelectedComponents(const std::vector<int>& compoIds) const throw(INTERP_KERNEL::Exception)
1598 {
1599   checkAllocated();
1600   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret(DataArrayDouble::New());
1601   std::size_t newNbOfCompo=compoIds.size();
1602   int oldNbOfCompo=getNumberOfComponents();
1603   for(std::vector<int>::const_iterator it=compoIds.begin();it!=compoIds.end();it++)
1604     if((*it)<0 || (*it)>=oldNbOfCompo)
1605       {
1606         std::ostringstream oss; oss << "DataArrayDouble::keepSelectedComponents : invalid requested component : " << *it << " whereas it should be in [0," << oldNbOfCompo << ") !";
1607         throw INTERP_KERNEL::Exception(oss.str().c_str());
1608       }
1609   int nbOfTuples=getNumberOfTuples();
1610   ret->alloc(nbOfTuples,(int)newNbOfCompo);
1611   ret->copyPartOfStringInfoFrom(*this,compoIds);
1612   const double *oldc=getConstPointer();
1613   double *nc=ret->getPointer();
1614   for(int i=0;i<nbOfTuples;i++)
1615     for(std::size_t j=0;j<newNbOfCompo;j++,nc++)
1616       *nc=oldc[i*oldNbOfCompo+compoIds[j]];
1617   return ret.retn();
1618 }
1619
1620 /*!
1621  * Appends components of another array to components of \a this one, tuple by tuple.
1622  * So that the number of tuples of \a this array remains the same and the number of 
1623  * components increases.
1624  *  \param [in] other - the DataArrayDouble to append to \a this one.
1625  *  \throw If \a this is not allocated.
1626  *  \throw If \a this and \a other arrays have different number of tuples.
1627  *
1628  *  \ref cpp_mcdataarraydouble_meldwith "Here is a C++ example".
1629  *
1630  *  \ref py_mcdataarraydouble_meldwith "Here is a Python example".
1631  */
1632 void DataArrayDouble::meldWith(const DataArrayDouble *other) throw(INTERP_KERNEL::Exception)
1633 {
1634   checkAllocated();
1635   other->checkAllocated();
1636   int nbOfTuples=getNumberOfTuples();
1637   if(nbOfTuples!=other->getNumberOfTuples())
1638     throw INTERP_KERNEL::Exception("DataArrayDouble::meldWith : mismatch of number of tuples !");
1639   int nbOfComp1=getNumberOfComponents();
1640   int nbOfComp2=other->getNumberOfComponents();
1641   double *newArr=new double[nbOfTuples*(nbOfComp1+nbOfComp2)];
1642   double *w=newArr;
1643   const double *inp1=getConstPointer();
1644   const double *inp2=other->getConstPointer();
1645   for(int i=0;i<nbOfTuples;i++,inp1+=nbOfComp1,inp2+=nbOfComp2)
1646     {
1647       w=std::copy(inp1,inp1+nbOfComp1,w);
1648       w=std::copy(inp2,inp2+nbOfComp2,w);
1649     }
1650   useArray(newArr,true,CPP_DEALLOC,nbOfTuples,nbOfComp1+nbOfComp2);
1651   std::vector<int> compIds(nbOfComp2);
1652   for(int i=0;i<nbOfComp2;i++)
1653     compIds[i]=nbOfComp1+i;
1654   copyPartOfStringInfoFrom2(compIds,*other);
1655 }
1656
1657 /*!
1658  * Searches for tuples coincident within \a prec tolerance. Each tuple is considered
1659  * as coordinates of a point in getNumberOfComponents()-dimensional space. The
1660  * distance is computed using norm2.
1661  *
1662  * Indices of coincident tuples are stored in output arrays.
1663  * A pair of arrays (\a comm, \a commIndex) is called "Surjective Format 2".
1664  *
1665  * This method is typically used by MEDCouplingPointSet::findCommonNodes() and
1666  * MEDCouplingUMesh::mergeNodes().
1667  *  \param [in] prec - minimal absolute distance between two tuples at which they are
1668  *              considered not coincident.
1669  *  \param [in] limitTupleId - limit tuple id. Tuples with id strictly lower than \a 
1670  *              limitTupleId are not considered.
1671  *  \param [out] comm - the array holding ids (== indices) of coincident tuples. 
1672  *               \a comm->getNumberOfComponents() == 1. 
1673  *               \a comm->getNumberOfTuples() == \a commIndex->back().
1674  *  \param [out] commIndex - the array dividing all indices stored in \a comm into
1675  *               groups of (indices of) coincident tuples. Its every value is a tuple
1676  *               index where a next group of tuples begins. For example the second
1677  *               group of tuples in \a comm is described by following range of indices:
1678  *               [ \a commIndex[1], \a commIndex[2] ). \a commIndex->getNumberOfTuples()-1
1679  *               gives the number of groups of coincident tuples.
1680  *  \throw If \a this is not allocated.
1681  *  \throw If \a this and \a other arrays have different number of tuples.
1682  *  \throw If the number of components is not in [1,2,3].
1683  *
1684  *  \ref cpp_mcdataarraydouble_findcommontuples "Here is a C++ example".
1685  *
1686  *  \ref py_mcdataarraydouble_findcommontuples  "Here is a Python example".
1687  *  \sa DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2().
1688  */
1689 void DataArrayDouble::findCommonTuples(double prec, int limitTupleId, DataArrayInt *&comm, DataArrayInt *&commIndex) const throw(INTERP_KERNEL::Exception)
1690 {
1691   checkAllocated();
1692   int nbOfCompo=getNumberOfComponents();
1693   if ((nbOfCompo<1) || (nbOfCompo>3)) //test before work
1694     throw INTERP_KERNEL::Exception("DataArrayDouble::findCommonTuples : Unexpected spacedim of coords. Must be 1, 2 or 3.");
1695   
1696   int nbOfTuples=getNumberOfTuples();
1697   //
1698   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> bbox=computeBBoxPerTuple(prec);
1699   //
1700   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> c(DataArrayInt::New()),cI(DataArrayInt::New()); c->alloc(0,1); cI->pushBackSilent(0);
1701   switch(nbOfCompo)
1702     {
1703     case 3:
1704       findCommonTuplesAlg<3>(bbox->getConstPointer(),nbOfTuples,limitTupleId,prec,c,cI);
1705       break;
1706     case 2:
1707       findCommonTuplesAlg<2>(bbox->getConstPointer(),nbOfTuples,limitTupleId,prec,c,cI);
1708       break;
1709     case 1:
1710       findCommonTuplesAlg<1>(bbox->getConstPointer(),nbOfTuples,limitTupleId,prec,c,cI);
1711       break;
1712     default:
1713       throw INTERP_KERNEL::Exception("DataArrayDouble::findCommonTuples : nb of components managed are 1,2 and 3 ! not implemented for other number of components !");
1714     }
1715   comm=c.retn();
1716   commIndex=cI.retn();
1717 }
1718
1719 /*!
1720  * 
1721  * \param [in] nbTimes specifies the nb of times each tuples in \a this will be duplicated contiguouly in returned DataArrayDouble instance.
1722  *             \a nbTimes  should be at least equal to 1.
1723  * \return a newly allocated DataArrayDouble having one component and number of tuples equal to \a nbTimes * \c this->getNumberOfTuples.
1724  * \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.
1725  */
1726 DataArrayDouble *DataArrayDouble::duplicateEachTupleNTimes(int nbTimes) const throw(INTERP_KERNEL::Exception)
1727 {
1728   checkAllocated();
1729   if(getNumberOfComponents()!=1)
1730     throw INTERP_KERNEL::Exception("DataArrayDouble::duplicateEachTupleNTimes : this should have only one component !");
1731   if(nbTimes<1)
1732     throw INTERP_KERNEL::Exception("DataArrayDouble::duplicateEachTupleNTimes : nb times should be >= 1 !");
1733   int nbTuples=getNumberOfTuples();
1734   const double *inPtr=getConstPointer();
1735   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New(); ret->alloc(nbTimes*nbTuples,1);
1736   double *retPtr=ret->getPointer();
1737   for(int i=0;i<nbTuples;i++,inPtr++)
1738     {
1739       double val=*inPtr;
1740       for(int j=0;j<nbTimes;j++,retPtr++)
1741         *retPtr=val;
1742     }
1743   ret->copyStringInfoFrom(*this);
1744   return ret.retn();
1745 }
1746
1747 /*!
1748  * This methods returns the minimal distance between the two set of points \a this and \a other.
1749  * So \a this and \a other have to have the same number of components. If not an INTERP_KERNEL::Exception will be thrown.
1750  * This method works only if number of components of \a this (equal to those of \a other) is in 1, 2 or 3.
1751  *
1752  * \param [out] thisTupleId the tuple id in \a this corresponding to the returned minimal distance
1753  * \param [out] otherTupleId the tuple id in \a other corresponding to the returned minimal distance
1754  * \return the minimal distance between the two set of points \a this and \a other.
1755  * \sa DataArrayDouble::findClosestTupleId
1756  */
1757 double DataArrayDouble::minimalDistanceTo(const DataArrayDouble *other, int& thisTupleId, int& otherTupleId) const throw(INTERP_KERNEL::Exception)
1758 {
1759   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> part1=findClosestTupleId(other);
1760   int nbOfCompo(getNumberOfComponents());
1761   int otherNbTuples(other->getNumberOfTuples());
1762   const double *thisPt(begin()),*otherPt(other->begin());
1763   const int *part1Pt(part1->begin());
1764   double ret=std::numeric_limits<double>::max();
1765   for(int i=0;i<otherNbTuples;i++,part1Pt++,otherPt+=nbOfCompo)
1766     {
1767       double tmp(0.);
1768       for(int j=0;j<nbOfCompo;j++)
1769         tmp+=(otherPt[j]-thisPt[nbOfCompo*(*part1Pt)+j])*(otherPt[j]-thisPt[nbOfCompo*(*part1Pt)+j]);
1770       if(tmp<ret)
1771         { ret=tmp; thisTupleId=*part1Pt; otherTupleId=i; }
1772     }
1773   return sqrt(ret);
1774 }
1775
1776 /*!
1777  * This methods returns for each tuple in \a other which tuple in \a this is the closest.
1778  * So \a this and \a other have to have the same number of components. If not an INTERP_KERNEL::Exception will be thrown.
1779  * This method works only if number of components of \a this (equal to those of \a other) is in 1, 2 or 3.
1780  *
1781  * \return a newly allocated (new object to be dealt by the caller) DataArrayInt having \c other->getNumberOfTuples() tuples and one components.
1782  * \sa DataArrayDouble::minimalDistanceTo
1783  */
1784 DataArrayInt *DataArrayDouble::findClosestTupleId(const DataArrayDouble *other) const throw(INTERP_KERNEL::Exception)
1785 {
1786   if(!other)
1787     throw INTERP_KERNEL::Exception("DataArrayDouble::findClosestTupleId : other instance is NULL !");
1788   checkAllocated(); other->checkAllocated();
1789   int nbOfCompo=getNumberOfComponents();
1790   if(nbOfCompo!=other->getNumberOfComponents())
1791     {
1792       std::ostringstream oss; oss << "DataArrayDouble::findClosestTupleId : number of components in this is " << nbOfCompo;
1793       oss << ", whereas number of components in other is " << other->getNumberOfComponents() << "! Should be equal !";
1794       throw INTERP_KERNEL::Exception(oss.str().c_str());
1795     }
1796   int nbOfTuples=other->getNumberOfTuples();
1797   int thisNbOfTuples=getNumberOfTuples();
1798   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbOfTuples,1);
1799   double bounds[6];
1800   getMinMaxPerComponent(bounds);
1801   switch(nbOfCompo)
1802     {
1803     case 3:
1804       {
1805         double xDelta(fabs(bounds[1]-bounds[0])),yDelta(fabs(bounds[3]-bounds[2])),zDelta(fabs(bounds[5]-bounds[4]));
1806         double delta=std::max(xDelta,yDelta); delta=std::max(delta,zDelta);
1807         double characSize=pow((delta*delta*delta)/((double)thisNbOfTuples),1./3.);
1808         BBTreePts<3,int> myTree(begin(),0,0,getNumberOfTuples(),characSize*1e-12);
1809         FindClosestTupleIdAlg<3>(myTree,3.*characSize*characSize,other->begin(),nbOfTuples,begin(),thisNbOfTuples,ret->getPointer());
1810         break;
1811       }
1812     case 2:
1813       {
1814         double xDelta(fabs(bounds[1]-bounds[0])),yDelta(fabs(bounds[3]-bounds[2]));
1815         double delta=std::max(xDelta,yDelta);
1816         double characSize=sqrt(delta/(double)thisNbOfTuples);
1817         BBTreePts<2,int> myTree(begin(),0,0,getNumberOfTuples(),characSize*1e-12);
1818         FindClosestTupleIdAlg<2>(myTree,2.*characSize*characSize,other->begin(),nbOfTuples,begin(),thisNbOfTuples,ret->getPointer());
1819         break;
1820       }
1821     case 1:
1822       {
1823         double characSize=fabs(bounds[1]-bounds[0])/thisNbOfTuples;
1824         BBTreePts<1,int> myTree(begin(),0,0,getNumberOfTuples(),characSize*1e-12);
1825         FindClosestTupleIdAlg<1>(myTree,1.*characSize*characSize,other->begin(),nbOfTuples,begin(),thisNbOfTuples,ret->getPointer());
1826         break;
1827       }
1828     default:
1829       throw INTERP_KERNEL::Exception("Unexpected spacedim of coords for findClosestTupleId. Must be 1, 2 or 3.");
1830     }
1831   return ret.retn();
1832 }
1833
1834 /*!
1835  * Returns a copy of \a this array by excluding coincident tuples. Each tuple is
1836  * considered as coordinates of a point in getNumberOfComponents()-dimensional
1837  * space. The distance between tuples is computed using norm2. If several tuples are
1838  * not far each from other than \a prec, only one of them remains in the result
1839  * array. The order of tuples in the result array is same as in \a this one except
1840  * that coincident tuples are excluded.
1841  *  \param [in] prec - minimal absolute distance between two tuples at which they are
1842  *              considered not coincident.
1843  *  \param [in] limitTupleId - limit tuple id. Tuples with id strictly lower than \a 
1844  *              limiTupleId are not considered and thus not excluded.
1845  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1846  *          is to delete using decrRef() as it is no more needed.
1847  *  \throw If \a this is not allocated.
1848  *  \throw If the number of components is not in [1,2,3].
1849  *
1850  *  \ref cpp_mcdataarraydouble_getdifferentvalues "Here is a Python example".
1851  */
1852 DataArrayDouble *DataArrayDouble::getDifferentValues(double prec, int limitTupleId) const throw(INTERP_KERNEL::Exception)
1853 {
1854   checkAllocated();
1855   DataArrayInt *c0=0,*cI0=0;
1856   findCommonTuples(prec,limitTupleId,c0,cI0);
1857   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> c(c0),cI(cI0);
1858   int newNbOfTuples=-1;
1859   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> o2n=DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2(getNumberOfTuples(),c0->begin(),cI0->begin(),cI0->end(),newNbOfTuples);
1860   return renumberAndReduce(o2n->getConstPointer(),newNbOfTuples);
1861 }
1862
1863 /*!
1864  * Copy all components in a specified order from another DataArrayDouble.
1865  * The specified components become the first ones in \a this array.
1866  * Both numerical and textual data is copied. The number of tuples in \a this and
1867  * the other array can be different.
1868  *  \param [in] a - the array to copy data from.
1869  *  \param [in] compoIds - sequence of zero based indices of components, data of which is
1870  *              to be copied.
1871  *  \throw If \a a is NULL.
1872  *  \throw If \a compoIds.size() != \a a->getNumberOfComponents().
1873  *  \throw If \a compoIds[i] < 0 or \a compoIds[i] > \a this->getNumberOfComponents().
1874  *
1875  *  \ref cpp_mcdataarraydouble_setselectedcomponents "Here is a Python example".
1876  */
1877 void DataArrayDouble::setSelectedComponents(const DataArrayDouble *a, const std::vector<int>& compoIds) throw(INTERP_KERNEL::Exception)
1878 {
1879   if(!a)
1880     throw INTERP_KERNEL::Exception("DataArrayDouble::setSelectedComponents : input DataArrayDouble is NULL !");
1881   checkAllocated();
1882   copyPartOfStringInfoFrom2(compoIds,*a);
1883   std::size_t partOfCompoSz=compoIds.size();
1884   int nbOfCompo=getNumberOfComponents();
1885   int nbOfTuples=std::min(getNumberOfTuples(),a->getNumberOfTuples());
1886   const double *ac=a->getConstPointer();
1887   double *nc=getPointer();
1888   for(int i=0;i<nbOfTuples;i++)
1889     for(std::size_t j=0;j<partOfCompoSz;j++,ac++)
1890       nc[nbOfCompo*i+compoIds[j]]=*ac;
1891 }
1892
1893 /*!
1894  * Copy all values from another DataArrayDouble into specified tuples and components
1895  * of \a this array. Textual data is not copied.
1896  * The tree parameters defining set of indices of tuples and components are similar to
1897  * the tree parameters of the Python function \c range(\c start,\c stop,\c step).
1898  *  \param [in] a - the array to copy values from.
1899  *  \param [in] bgTuples - index of the first tuple of \a this array to assign values to.
1900  *  \param [in] endTuples - index of the tuple before which the tuples to assign to
1901  *              are located.
1902  *  \param [in] stepTuples - index increment to get index of the next tuple to assign to.
1903  *  \param [in] bgComp - index of the first component of \a this array to assign values to.
1904  *  \param [in] endComp - index of the component before which the components to assign
1905  *              to are located.
1906  *  \param [in] stepComp - index increment to get index of the next component to assign to.
1907  *  \param [in] strictCompoCompare - if \a true (by default), then \a a->getNumberOfComponents() 
1908  *              must be equal to the number of columns to assign to, else an
1909  *              exception is thrown; if \a false, then it is only required that \a
1910  *              a->getNbOfElems() equals to number of values to assign to (this condition
1911  *              must be respected even if \a strictCompoCompare is \a true). The number of 
1912  *              values to assign to is given by following Python expression:
1913  *              \a nbTargetValues = 
1914  *              \c len(\c range(\a bgTuples,\a endTuples,\a stepTuples)) *
1915  *              \c len(\c range(\a bgComp,\a endComp,\a stepComp)).
1916  *  \throw If \a a is NULL.
1917  *  \throw If \a a is not allocated.
1918  *  \throw If \a this is not allocated.
1919  *  \throw If parameters specifying tuples and components to assign to do not give a
1920  *            non-empty range of increasing indices.
1921  *  \throw If \a a->getNbOfElems() != \a nbTargetValues.
1922  *  \throw If \a strictCompoCompare == \a true && \a a->getNumberOfComponents() !=
1923  *            \c len(\c range(\a bgComp,\a endComp,\a stepComp)).
1924  *
1925  *  \ref cpp_mcdataarraydouble_setpartofvalues1 "Here is a Python example".
1926  */
1927 void DataArrayDouble::setPartOfValues1(const DataArrayDouble *a, int bgTuples, int endTuples, int stepTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare) throw(INTERP_KERNEL::Exception)
1928 {
1929   if(!a)
1930     throw INTERP_KERNEL::Exception("DataArrayDouble::setPartOfValues1 : input DataArrayDouble is NULL !");
1931   const char msg[]="DataArrayDouble::setPartOfValues1";
1932   checkAllocated();
1933   a->checkAllocated();
1934   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
1935   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
1936   int nbComp=getNumberOfComponents();
1937   int nbOfTuples=getNumberOfTuples();
1938   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
1939   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
1940   bool assignTech=true;
1941   if(a->getNbOfElems()==newNbOfTuples*newNbOfComp)
1942     {
1943       if(strictCompoCompare)
1944         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
1945     }
1946   else
1947     {
1948       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
1949       assignTech=false;
1950     }
1951   const double *srcPt=a->getConstPointer();
1952   double *pt=getPointer()+bgTuples*nbComp+bgComp;
1953   if(assignTech)
1954     {
1955       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
1956         for(int j=0;j<newNbOfComp;j++,srcPt++)
1957           pt[j*stepComp]=*srcPt;
1958     }
1959   else
1960     {
1961       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
1962         {
1963           const double *srcPt2=srcPt;
1964           for(int j=0;j<newNbOfComp;j++,srcPt2++)
1965             pt[j*stepComp]=*srcPt2;
1966         }
1967     }
1968 }
1969
1970 /*!
1971  * Assign a given value to values at specified tuples and components of \a this array.
1972  * The tree parameters defining set of indices of tuples and components are similar to
1973  * the tree parameters of the Python function \c range(\c start,\c stop,\c step)..
1974  *  \param [in] a - the value to assign.
1975  *  \param [in] bgTuples - index of the first tuple of \a this array to assign to.
1976  *  \param [in] endTuples - index of the tuple before which the tuples to assign to
1977  *              are located.
1978  *  \param [in] stepTuples - index increment to get index of the next tuple to assign to.
1979  *  \param [in] bgComp - index of the first component of \a this array to assign to.
1980  *  \param [in] endComp - index of the component before which the components to assign
1981  *              to are located.
1982  *  \param [in] stepComp - index increment to get index of the next component to assign to.
1983  *  \throw If \a this is not allocated.
1984  *  \throw If parameters specifying tuples and components to assign to, do not give a
1985  *            non-empty range of increasing indices or indices are out of a valid range
1986  *            for \this array.
1987  *
1988  *  \ref cpp_mcdataarraydouble_setpartofvaluessimple1 "Here is a Python example".
1989  */
1990 void DataArrayDouble::setPartOfValuesSimple1(double a, int bgTuples, int endTuples, int stepTuples, int bgComp, int endComp, int stepComp) throw(INTERP_KERNEL::Exception)
1991 {
1992   const char msg[]="DataArrayDouble::setPartOfValuesSimple1";
1993   checkAllocated();
1994   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
1995   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
1996   int nbComp=getNumberOfComponents();
1997   int nbOfTuples=getNumberOfTuples();
1998   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
1999   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
2000   double *pt=getPointer()+bgTuples*nbComp+bgComp;
2001   for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
2002     for(int j=0;j<newNbOfComp;j++)
2003       pt[j*stepComp]=a;
2004 }
2005
2006 /*!
2007  * Copy all values from another DataArrayDouble (\a a) into specified tuples and 
2008  * components of \a this array. Textual data is not copied.
2009  * The tuples and components to assign to are defined by C arrays of indices.
2010  * There are two *modes of usage*:
2011  * - If \a a->getNbOfElems() equals to number of values to assign to, then every value
2012  *   of \a a is assigned to its own location within \a this array. 
2013  * - If \a a includes one tuple, then all values of \a a are assigned to the specified
2014  *   components of every specified tuple of \a this array. In this mode it is required
2015  *   that \a a->getNumberOfComponents() equals to the number of specified components.
2016  *
2017  *  \param [in] a - the array to copy values from.
2018  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
2019  *              assign values of \a a to.
2020  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
2021  *              pointer to a tuple index <em>(pi)</em> varies as this: 
2022  *              \a bgTuples <= \a pi < \a endTuples.
2023  *  \param [in] bgComp - pointer to an array of component indices of \a this array to
2024  *              assign values of \a a to.
2025  *  \param [in] endComp - specifies the end of the array \a bgTuples, so that
2026  *              pointer to a component index <em>(pi)</em> varies as this: 
2027  *              \a bgComp <= \a pi < \a endComp.
2028  *  \param [in] strictCompoCompare - this parameter is checked only if the
2029  *               *mode of usage* is the first; if it is \a true (default), 
2030  *               then \a a->getNumberOfComponents() must be equal 
2031  *               to the number of specified columns, else this is not required.
2032  *  \throw If \a a is NULL.
2033  *  \throw If \a a is not allocated.
2034  *  \throw If \a this is not allocated.
2035  *  \throw If any index of tuple/component given by <em>bgTuples / bgComp</em> is
2036  *         out of a valid range for \a this array.
2037  *  \throw In the first *mode of usage*, if <em>strictCompoCompare == true </em> and
2038  *         if <em> a->getNumberOfComponents() != (endComp - bgComp) </em>.
2039  *  \throw In the second *mode of usage*, if \a a->getNumberOfTuples() != 1 or
2040  *         <em> a->getNumberOfComponents() != (endComp - bgComp)</em>.
2041  *
2042  *  \ref cpp_mcdataarraydouble_setpartofvalues2 "Here is a Python example".
2043  */
2044 void DataArrayDouble::setPartOfValues2(const DataArrayDouble *a, const int *bgTuples, const int *endTuples, const int *bgComp, const int *endComp, bool strictCompoCompare) throw(INTERP_KERNEL::Exception)
2045 {
2046   if(!a)
2047     throw INTERP_KERNEL::Exception("DataArrayDouble::setPartOfValues2 : input DataArrayDouble is NULL !");
2048   const char msg[]="DataArrayDouble::setPartOfValues2";
2049   checkAllocated();
2050   a->checkAllocated();
2051   int nbComp=getNumberOfComponents();
2052   int nbOfTuples=getNumberOfTuples();
2053   for(const int *z=bgComp;z!=endComp;z++)
2054     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
2055   int newNbOfTuples=(int)std::distance(bgTuples,endTuples);
2056   int newNbOfComp=(int)std::distance(bgComp,endComp);
2057   bool assignTech=true;
2058   if(a->getNbOfElems()==newNbOfTuples*newNbOfComp)
2059     {
2060       if(strictCompoCompare)
2061         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
2062     }
2063   else
2064     {
2065       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
2066       assignTech=false;
2067     }
2068   double *pt=getPointer();
2069   const double *srcPt=a->getConstPointer();
2070   if(assignTech)
2071     {    
2072       for(const int *w=bgTuples;w!=endTuples;w++)
2073         {
2074           DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
2075           for(const int *z=bgComp;z!=endComp;z++,srcPt++)
2076             {    
2077               pt[(*w)*nbComp+(*z)]=*srcPt;
2078             }
2079         }
2080     }
2081   else
2082     {
2083       for(const int *w=bgTuples;w!=endTuples;w++)
2084         {
2085           const double *srcPt2=srcPt;
2086           DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
2087           for(const int *z=bgComp;z!=endComp;z++,srcPt2++)
2088             {    
2089               pt[(*w)*nbComp+(*z)]=*srcPt2;
2090             }
2091         }
2092     }
2093 }
2094
2095 /*!
2096  * Assign a given value to values at specified tuples and components of \a this array.
2097  * The tuples and components to assign to are defined by C arrays of indices.
2098  *  \param [in] a - the value to assign.
2099  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
2100  *              assign \a a to.
2101  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
2102  *              pointer to a tuple index (\a pi) varies as this: 
2103  *              \a bgTuples <= \a pi < \a endTuples.
2104  *  \param [in] bgComp - pointer to an array of component indices of \a this array to
2105  *              assign \a a to.
2106  *  \param [in] endComp - specifies the end of the array \a bgTuples, so that
2107  *              pointer to a component index (\a pi) varies as this: 
2108  *              \a bgComp <= \a pi < \a endComp.
2109  *  \throw If \a this is not allocated.
2110  *  \throw If any index of tuple/component given by <em>bgTuples / bgComp</em> is
2111  *         out of a valid range for \a this array.
2112  *
2113  *  \ref cpp_mcdataarraydouble_setpartofvaluessimple2 "Here is a Python example".
2114  */
2115 void DataArrayDouble::setPartOfValuesSimple2(double a, const int *bgTuples, const int *endTuples, const int *bgComp, const int *endComp) throw(INTERP_KERNEL::Exception)
2116 {
2117   checkAllocated();
2118   int nbComp=getNumberOfComponents();
2119   int nbOfTuples=getNumberOfTuples();
2120   for(const int *z=bgComp;z!=endComp;z++)
2121     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
2122   double *pt=getPointer();
2123   for(const int *w=bgTuples;w!=endTuples;w++)
2124     for(const int *z=bgComp;z!=endComp;z++)
2125       {
2126         DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
2127         pt[(*w)*nbComp+(*z)]=a;
2128       }
2129 }
2130
2131 /*!
2132  * Copy all values from another DataArrayDouble (\a a) into specified tuples and 
2133  * components of \a this array. Textual data is not copied.
2134  * The tuples to assign to are defined by a C array of indices.
2135  * The components to assign to are defined by three values similar to parameters of
2136  * the Python function \c range(\c start,\c stop,\c step).
2137  * There are two *modes of usage*:
2138  * - If \a a->getNbOfElems() equals to number of values to assign to, then every value
2139  *   of \a a is assigned to its own location within \a this array. 
2140  * - If \a a includes one tuple, then all values of \a a are assigned to the specified
2141  *   components of every specified tuple of \a this array. In this mode it is required
2142  *   that \a a->getNumberOfComponents() equals to the number of specified components.
2143  *
2144  *  \param [in] a - the array to copy values from.
2145  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
2146  *              assign values of \a a to.
2147  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
2148  *              pointer to a tuple index <em>(pi)</em> varies as this: 
2149  *              \a bgTuples <= \a pi < \a endTuples.
2150  *  \param [in] bgComp - index of the first component of \a this array to assign to.
2151  *  \param [in] endComp - index of the component before which the components to assign
2152  *              to are located.
2153  *  \param [in] stepComp - index increment to get index of the next component to assign to.
2154  *  \param [in] strictCompoCompare - this parameter is checked only in the first
2155  *               *mode of usage*; if \a strictCompoCompare is \a true (default), 
2156  *               then \a a->getNumberOfComponents() must be equal 
2157  *               to the number of specified columns, else this is not required.
2158  *  \throw If \a a is NULL.
2159  *  \throw If \a a is not allocated.
2160  *  \throw If \a this is not allocated.
2161  *  \throw If any index of tuple given by \a bgTuples is out of a valid range for 
2162  *         \a this array.
2163  *  \throw In the first *mode of usage*, if <em>strictCompoCompare == true </em> and
2164  *         if <em> a->getNumberOfComponents()</em> is unequal to the number of components
2165  *         defined by <em>(bgComp,endComp,stepComp)</em>.
2166  *  \throw In the second *mode of usage*, if \a a->getNumberOfTuples() != 1 or
2167  *         <em> a->getNumberOfComponents()</em> is unequal to the number of components
2168  *         defined by <em>(bgComp,endComp,stepComp)</em>.
2169  *  \throw If parameters specifying components to assign to, do not give a
2170  *            non-empty range of increasing indices or indices are out of a valid range
2171  *            for \this array.
2172  *
2173  *  \ref cpp_mcdataarraydouble_setpartofvalues3 "Here is a Python example".
2174  */
2175 void DataArrayDouble::setPartOfValues3(const DataArrayDouble *a, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare) throw(INTERP_KERNEL::Exception)
2176 {
2177   if(!a)
2178     throw INTERP_KERNEL::Exception("DataArrayDouble::setPartOfValues3 : input DataArrayDouble is NULL !");
2179   const char msg[]="DataArrayDouble::setPartOfValues3";
2180   checkAllocated();
2181   a->checkAllocated();
2182   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
2183   int nbComp=getNumberOfComponents();
2184   int nbOfTuples=getNumberOfTuples();
2185   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
2186   int newNbOfTuples=(int)std::distance(bgTuples,endTuples);
2187   bool assignTech=true;
2188   if(a->getNbOfElems()==newNbOfTuples*newNbOfComp)
2189     {
2190       if(strictCompoCompare)
2191         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
2192     }
2193   else
2194     {
2195       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
2196       assignTech=false;
2197     }
2198   double *pt=getPointer()+bgComp;
2199   const double *srcPt=a->getConstPointer();
2200   if(assignTech)
2201     {
2202       for(const int *w=bgTuples;w!=endTuples;w++)
2203         for(int j=0;j<newNbOfComp;j++,srcPt++)
2204           {
2205             DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
2206             pt[(*w)*nbComp+j*stepComp]=*srcPt;
2207           }
2208     }
2209   else
2210     {
2211       for(const int *w=bgTuples;w!=endTuples;w++)
2212         {
2213           const double *srcPt2=srcPt;
2214           for(int j=0;j<newNbOfComp;j++,srcPt2++)
2215             {
2216               DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
2217               pt[(*w)*nbComp+j*stepComp]=*srcPt2;
2218             }
2219         }
2220     }
2221 }
2222
2223 /*!
2224  * Assign a given value to values at specified tuples and components of \a this array.
2225  * The tuples to assign to are defined by a C array of indices.
2226  * The components to assign to are defined by three values similar to parameters of
2227  * the Python function \c range(\c start,\c stop,\c step).
2228  *  \param [in] a - the value to assign.
2229  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
2230  *              assign \a a to.
2231  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
2232  *              pointer to a tuple index <em>(pi)</em> varies as this: 
2233  *              \a bgTuples <= \a pi < \a endTuples.
2234  *  \param [in] bgComp - index of the first component of \a this array to assign to.
2235  *  \param [in] endComp - index of the component before which the components to assign
2236  *              to are located.
2237  *  \param [in] stepComp - index increment to get index of the next component to assign to.
2238  *  \throw If \a this is not allocated.
2239  *  \throw If any index of tuple given by \a bgTuples is out of a valid range for 
2240  *         \a this array.
2241  *  \throw If parameters specifying components to assign to, do not give a
2242  *            non-empty range of increasing indices or indices are out of a valid range
2243  *            for \this array.
2244  *
2245  *  \ref cpp_mcdataarraydouble_setpartofvaluessimple3 "Here is a Python example".
2246  */
2247 void DataArrayDouble::setPartOfValuesSimple3(double a, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp) throw(INTERP_KERNEL::Exception)
2248 {
2249   const char msg[]="DataArrayDouble::setPartOfValuesSimple3";
2250   checkAllocated();
2251   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
2252   int nbComp=getNumberOfComponents();
2253   int nbOfTuples=getNumberOfTuples();
2254   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
2255   double *pt=getPointer()+bgComp;
2256   for(const int *w=bgTuples;w!=endTuples;w++)
2257     for(int j=0;j<newNbOfComp;j++)
2258       {
2259         DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
2260         pt[(*w)*nbComp+j*stepComp]=a;
2261       }
2262 }
2263
2264 /*!
2265  * Copy all values from another DataArrayDouble into specified tuples and components
2266  * of \a this array. Textual data is not copied.
2267  * The tree parameters defining set of indices of tuples and components are similar to
2268  * the tree parameters of the Python function \c range(\c start,\c stop,\c step).
2269  *  \param [in] a - the array to copy values from.
2270  *  \param [in] bgTuples - index of the first tuple of \a this array to assign values to.
2271  *  \param [in] endTuples - index of the tuple before which the tuples to assign to
2272  *              are located.
2273  *  \param [in] stepTuples - index increment to get index of the next tuple to assign to.
2274  *  \param [in] bgComp - pointer to an array of component indices of \a this array to
2275  *              assign \a a to.
2276  *  \param [in] endComp - specifies the end of the array \a bgTuples, so that
2277  *              pointer to a component index (\a pi) varies as this: 
2278  *              \a bgComp <= \a pi < \a endComp.
2279  *  \param [in] strictCompoCompare - if \a true (by default), then \a a->getNumberOfComponents() 
2280  *              must be equal to the number of columns to assign to, else an
2281  *              exception is thrown; if \a false, then it is only required that \a
2282  *              a->getNbOfElems() equals to number of values to assign to (this condition
2283  *              must be respected even if \a strictCompoCompare is \a true). The number of 
2284  *              values to assign to is given by following Python expression:
2285  *              \a nbTargetValues = 
2286  *              \c len(\c range(\a bgTuples,\a endTuples,\a stepTuples)) *
2287  *              \c len(\c range(\a bgComp,\a endComp,\a stepComp)).
2288  *  \throw If \a a is NULL.
2289  *  \throw If \a a is not allocated.
2290  *  \throw If \a this is not allocated.
2291  *  \throw If parameters specifying tuples and components to assign to do not give a
2292  *            non-empty range of increasing indices.
2293  *  \throw If \a a->getNbOfElems() != \a nbTargetValues.
2294  *  \throw If \a strictCompoCompare == \a true && \a a->getNumberOfComponents() !=
2295  *            \c len(\c range(\a bgComp,\a endComp,\a stepComp)).
2296  *
2297  */
2298 void DataArrayDouble::setPartOfValues4(const DataArrayDouble *a, int bgTuples, int endTuples, int stepTuples, const int *bgComp, const int *endComp, bool strictCompoCompare) throw(INTERP_KERNEL::Exception)
2299 {
2300   if(!a)
2301     throw INTERP_KERNEL::Exception("DataArrayDouble::setPartOfValues4 : input DataArrayDouble is NULL !");
2302   const char msg[]="DataArrayDouble::setPartOfValues4";
2303   checkAllocated();
2304   a->checkAllocated();
2305   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
2306   int newNbOfComp=(int)std::distance(bgComp,endComp);
2307   int nbComp=getNumberOfComponents();
2308   for(const int *z=bgComp;z!=endComp;z++)
2309     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
2310   int nbOfTuples=getNumberOfTuples();
2311   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
2312   bool assignTech=true;
2313   if(a->getNbOfElems()==newNbOfTuples*newNbOfComp)
2314     {
2315       if(strictCompoCompare)
2316         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
2317     }
2318   else
2319     {
2320       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
2321       assignTech=false;
2322     }
2323   const double *srcPt=a->getConstPointer();
2324   double *pt=getPointer()+bgTuples*nbComp;
2325   if(assignTech)
2326     {
2327       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
2328         for(const int *z=bgComp;z!=endComp;z++,srcPt++)
2329           pt[*z]=*srcPt;
2330     }
2331   else
2332     {
2333       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
2334         {
2335           const double *srcPt2=srcPt;
2336           for(const int *z=bgComp;z!=endComp;z++,srcPt2++)
2337             pt[*z]=*srcPt2;
2338         }
2339     }
2340 }
2341
2342 void DataArrayDouble::setPartOfValuesSimple4(double a, int bgTuples, int endTuples, int stepTuples, const int *bgComp, const int *endComp) throw(INTERP_KERNEL::Exception)
2343 {
2344   const char msg[]="DataArrayDouble::setPartOfValuesSimple4";
2345   checkAllocated();
2346   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
2347   int nbComp=getNumberOfComponents();
2348   for(const int *z=bgComp;z!=endComp;z++)
2349     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
2350   int nbOfTuples=getNumberOfTuples();
2351   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
2352   double *pt=getPointer()+bgTuples*nbComp;
2353   for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
2354     for(const int *z=bgComp;z!=endComp;z++)
2355       pt[*z]=a;
2356 }
2357
2358 /*!
2359  * Copy some tuples from another DataArrayDouble into specified tuples
2360  * of \a this array. Textual data is not copied. Both arrays must have equal number of
2361  * components.
2362  * Both the tuples to assign and the tuples to assign to are defined by a DataArrayInt.
2363  * All components of selected tuples are copied.
2364  *  \param [in] a - the array to copy values from.
2365  *  \param [in] tuplesSelec - the array specifying both source tuples of \a a and
2366  *              target tuples of \a this. \a tuplesSelec has two components, and the
2367  *              first component specifies index of the source tuple and the second
2368  *              one specifies index of the target tuple.
2369  *  \throw If \a this is not allocated.
2370  *  \throw If \a a is NULL.
2371  *  \throw If \a a is not allocated.
2372  *  \throw If \a tuplesSelec is NULL.
2373  *  \throw If \a tuplesSelec is not allocated.
2374  *  \throw If <em>this->getNumberOfComponents() != a->getNumberOfComponents()</em>.
2375  *  \throw If \a tuplesSelec->getNumberOfComponents() != 2.
2376  *  \throw If any tuple index given by \a tuplesSelec is out of a valid range for 
2377  *         the corresponding (\a this or \a a) array.
2378  */
2379 void DataArrayDouble::setPartOfValuesAdv(const DataArrayDouble *a, const DataArrayInt *tuplesSelec) throw(INTERP_KERNEL::Exception)
2380 {
2381   if(!a || !tuplesSelec)
2382     throw INTERP_KERNEL::Exception("DataArrayDouble::setPartOfValuesAdv : input DataArrayDouble is NULL !");
2383   checkAllocated();
2384   a->checkAllocated();
2385   tuplesSelec->checkAllocated();
2386   int nbOfComp=getNumberOfComponents();
2387   if(nbOfComp!=a->getNumberOfComponents())
2388     throw INTERP_KERNEL::Exception("DataArrayDouble::setPartOfValuesAdv : This and a do not have the same number of components !");
2389   if(tuplesSelec->getNumberOfComponents()!=2)
2390     throw INTERP_KERNEL::Exception("DataArrayDouble::setPartOfValuesAdv : Expecting to have a tuple selector DataArrayInt instance with exactly 2 components !");
2391   int thisNt=getNumberOfTuples();
2392   int aNt=a->getNumberOfTuples();
2393   double *valsToSet=getPointer();
2394   const double *valsSrc=a->getConstPointer();
2395   for(const int *tuple=tuplesSelec->begin();tuple!=tuplesSelec->end();tuple+=2)
2396     {
2397       if(tuple[1]>=0 && tuple[1]<aNt)
2398         {
2399           if(tuple[0]>=0 && tuple[0]<thisNt)
2400             std::copy(valsSrc+nbOfComp*tuple[1],valsSrc+nbOfComp*(tuple[1]+1),valsToSet+nbOfComp*tuple[0]);
2401           else
2402             {
2403               std::ostringstream oss; oss << "DataArrayDouble::setPartOfValuesAdv : Tuple #" << std::distance(tuplesSelec->begin(),tuple)/2;
2404               oss << " of 'tuplesSelec' request of tuple id #" << tuple[0] << " in 'this' ! It should be in [0," << thisNt << ") !";
2405               throw INTERP_KERNEL::Exception(oss.str().c_str());
2406             }
2407         }
2408       else
2409         {
2410           std::ostringstream oss; oss << "DataArrayDouble::setPartOfValuesAdv : Tuple #" << std::distance(tuplesSelec->begin(),tuple)/2;
2411           oss << " of 'tuplesSelec' request of tuple id #" << tuple[1] << " in 'a' ! It should be in [0," << aNt << ") !";
2412           throw INTERP_KERNEL::Exception(oss.str().c_str());
2413         }
2414     }
2415 }
2416
2417 /*!
2418  * Copy some tuples from another DataArrayDouble (\a a) into contiguous tuples
2419  * of \a this array. Textual data is not copied. Both arrays must have equal number of
2420  * components.
2421  * The tuples to assign to are defined by index of the first tuple, and
2422  * their number is defined by \a tuplesSelec->getNumberOfTuples().
2423  * The tuples to copy are defined by values of a DataArrayInt.
2424  * All components of selected tuples are copied.
2425  *  \param [in] tupleIdStart - index of the first tuple of \a this array to assign
2426  *              values to.
2427  *  \param [in] a - the array to copy values from.
2428  *  \param [in] tuplesSelec - the array specifying tuples of \a a to copy.
2429  *  \throw If \a this is not allocated.
2430  *  \throw If \a a is NULL.
2431  *  \throw If \a a is not allocated.
2432  *  \throw If \a tuplesSelec is NULL.
2433  *  \throw If \a tuplesSelec is not allocated.
2434  *  \throw If <em>this->getNumberOfComponents() != a->getNumberOfComponents()</em>.
2435  *  \throw If \a tuplesSelec->getNumberOfComponents() != 1.
2436  *  \throw If <em>tupleIdStart + tuplesSelec->getNumberOfTuples() > this->getNumberOfTuples().</em>
2437  *  \throw If any tuple index given by \a tuplesSelec is out of a valid range for 
2438  *         \a a array.
2439  */
2440 void DataArrayDouble::setContigPartOfSelectedValues(int tupleIdStart, const DataArrayDouble *a, const DataArrayInt *tuplesSelec) throw(INTERP_KERNEL::Exception)
2441 {
2442   if(!a || !tuplesSelec)
2443     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues : input DataArray is NULL !");
2444   checkAllocated();
2445   a->checkAllocated();
2446   tuplesSelec->checkAllocated();
2447   int nbOfComp=getNumberOfComponents();
2448   if(nbOfComp!=a->getNumberOfComponents())
2449     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues : This and a do not have the same number of components !");
2450   if(tuplesSelec->getNumberOfComponents()!=1)
2451     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues : Expecting to have a tuple selector DataArrayInt instance with exactly 1 component !");
2452   int thisNt=getNumberOfTuples();
2453   int aNt=a->getNumberOfTuples();
2454   int nbOfTupleToWrite=tuplesSelec->getNumberOfTuples();
2455   double *valsToSet=getPointer()+tupleIdStart*nbOfComp;
2456   if(tupleIdStart+nbOfTupleToWrite>thisNt)
2457     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues : invalid number range of values to write !");
2458   const double *valsSrc=a->getConstPointer();
2459   for(const int *tuple=tuplesSelec->begin();tuple!=tuplesSelec->end();tuple++,valsToSet+=nbOfComp)
2460     {
2461       if(*tuple>=0 && *tuple<aNt)
2462         {
2463           std::copy(valsSrc+nbOfComp*(*tuple),valsSrc+nbOfComp*(*tuple+1),valsToSet);
2464         }
2465       else
2466         {
2467           std::ostringstream oss; oss << "DataArrayDouble::setContigPartOfSelectedValues : Tuple #" << std::distance(tuplesSelec->begin(),tuple);
2468           oss << " of 'tuplesSelec' request of tuple id #" << *tuple << " in 'a' ! It should be in [0," << aNt << ") !";
2469           throw INTERP_KERNEL::Exception(oss.str().c_str());
2470         }
2471     }
2472 }
2473
2474 /*!
2475  * Copy some tuples from another DataArrayDouble (\a a) into contiguous tuples
2476  * of \a this array. Textual data is not copied. Both arrays must have equal number of
2477  * components.
2478  * The tuples to copy are defined by three values similar to parameters of
2479  * the Python function \c range(\c start,\c stop,\c step).
2480  * The tuples to assign to are defined by index of the first tuple, and
2481  * their number is defined by number of tuples to copy.
2482  * All components of selected tuples are copied.
2483  *  \param [in] tupleIdStart - index of the first tuple of \a this array to assign
2484  *              values to.
2485  *  \param [in] a - the array to copy values from.
2486  *  \param [in] bg - index of the first tuple to copy of the array \a a.
2487  *  \param [in] end2 - index of the tuple of \a a before which the tuples to copy
2488  *              are located.
2489  *  \param [in] step - index increment to get index of the next tuple to copy.
2490  *  \throw If \a this is not allocated.
2491  *  \throw If \a a is NULL.
2492  *  \throw If \a a is not allocated.
2493  *  \throw If <em>this->getNumberOfComponents() != a->getNumberOfComponents()</em>.
2494  *  \throw If <em>tupleIdStart + len(range(bg,end2,step)) > this->getNumberOfTuples().</em>
2495  *  \throw If parameters specifying tuples to copy, do not give a
2496  *            non-empty range of increasing indices or indices are out of a valid range
2497  *            for the array \a a.
2498  */
2499 void DataArrayDouble::setContigPartOfSelectedValues2(int tupleIdStart, const DataArrayDouble *a, int bg, int end2, int step) throw(INTERP_KERNEL::Exception)
2500 {
2501   if(!a)
2502     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues2 : input DataArrayDouble is NULL !");
2503   checkAllocated();
2504   a->checkAllocated();
2505   int nbOfComp=getNumberOfComponents();
2506   const char msg[]="DataArrayDouble::setContigPartOfSelectedValues2";
2507   int nbOfTupleToWrite=DataArray::GetNumberOfItemGivenBES(bg,end2,step,msg);
2508   if(nbOfComp!=a->getNumberOfComponents())
2509     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues2 : This and a do not have the same number of components !");
2510   int thisNt=getNumberOfTuples();
2511   int aNt=a->getNumberOfTuples();
2512   double *valsToSet=getPointer()+tupleIdStart*nbOfComp;
2513   if(tupleIdStart+nbOfTupleToWrite>thisNt)
2514     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues2 : invalid number range of values to write !");
2515   if(end2>aNt)
2516     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues2 : invalid range of values to read !");
2517   const double *valsSrc=a->getConstPointer()+bg*nbOfComp;
2518   for(int i=0;i<nbOfTupleToWrite;i++,valsToSet+=nbOfComp,valsSrc+=step*nbOfComp)
2519     {
2520       std::copy(valsSrc,valsSrc+nbOfComp,valsToSet);
2521     }
2522 }
2523
2524 /*!
2525  * Returns a value located at specified tuple and component.
2526  * This method is equivalent to DataArrayDouble::getIJ() except that validity of
2527  * parameters is checked. So this method is safe but expensive if used to go through
2528  * all values of \a this.
2529  *  \param [in] tupleId - index of tuple of interest.
2530  *  \param [in] compoId - index of component of interest.
2531  *  \return double - value located by \a tupleId and \a compoId.
2532  *  \throw If \a this is not allocated.
2533  *  \throw If condition <em>( 0 <= tupleId < this->getNumberOfTuples() )</em> is violated.
2534  *  \throw If condition <em>( 0 <= compoId < this->getNumberOfComponents() )</em> is violated.
2535  */
2536 double DataArrayDouble::getIJSafe(int tupleId, int compoId) const throw(INTERP_KERNEL::Exception)
2537 {
2538   checkAllocated();
2539   if(tupleId<0 || tupleId>=getNumberOfTuples())
2540     {
2541       std::ostringstream oss; oss << "DataArrayDouble::getIJSafe : request for tupleId " << tupleId << " should be in [0," << getNumberOfTuples() << ") !";
2542       throw INTERP_KERNEL::Exception(oss.str().c_str());
2543     }
2544   if(compoId<0 || compoId>=getNumberOfComponents())
2545     {
2546       std::ostringstream oss; oss << "DataArrayDouble::getIJSafe : request for compoId " << compoId << " should be in [0," << getNumberOfComponents() << ") !";
2547       throw INTERP_KERNEL::Exception(oss.str().c_str());
2548     }
2549   return _mem[tupleId*((int)_info_on_compo.size())+compoId];
2550 }
2551
2552 /*!
2553  * Returns the last value of \a this. 
2554  *  \return double - the last value of \a this array.
2555  *  \throw If \a this is not allocated.
2556  *  \throw If \a this->getNumberOfComponents() != 1.
2557  *  \throw If \a this->getNumberOfTuples() < 1.
2558  */
2559 double DataArrayDouble::back() const throw(INTERP_KERNEL::Exception)
2560 {
2561   checkAllocated();
2562   if(getNumberOfComponents()!=1)
2563     throw INTERP_KERNEL::Exception("DataArrayDouble::back : number of components not equal to one !");
2564   int nbOfTuples=getNumberOfTuples();
2565   if(nbOfTuples<1)
2566     throw INTERP_KERNEL::Exception("DataArrayDouble::back : number of tuples must be >= 1 !");
2567   return *(getConstPointer()+nbOfTuples-1);
2568 }
2569
2570 void DataArrayDouble::SetArrayIn(DataArrayDouble *newArray, DataArrayDouble* &arrayToSet)
2571 {
2572   if(newArray!=arrayToSet)
2573     {
2574       if(arrayToSet)
2575         arrayToSet->decrRef();
2576       arrayToSet=newArray;
2577       if(arrayToSet)
2578         arrayToSet->incrRef();
2579     }
2580 }
2581
2582 /*!
2583  * Sets a C array to be used as raw data of \a this. The previously set info
2584  *  of components is retained and re-sized. 
2585  * For more info see \ref MEDCouplingArraySteps1.
2586  *  \param [in] array - the C array to be used as raw data of \a this.
2587  *  \param [in] ownership - if \a true, \a array will be deallocated at destruction of \a this.
2588  *  \param [in] type - specifies how to deallocate \a array. If \a type == ParaMEDMEM::CPP_DEALLOC,
2589  *                     \c delete [] \c array; will be called. If \a type == ParaMEDMEM::C_DEALLOC,
2590  *                     \c free(\c array ) will be called.
2591  *  \param [in] nbOfTuple - new number of tuples in \a this.
2592  *  \param [in] nbOfCompo - new number of components in \a this.
2593  */
2594 void DataArrayDouble::useArray(const double *array, bool ownership, DeallocType type, int nbOfTuple, int nbOfCompo)
2595 {
2596   _info_on_compo.resize(nbOfCompo);
2597   _mem.useArray(array,ownership,type,nbOfTuple*nbOfCompo);
2598   declareAsNew();
2599 }
2600
2601 void DataArrayDouble::useExternalArrayWithRWAccess(const double *array, int nbOfTuple, int nbOfCompo)
2602 {
2603   _info_on_compo.resize(nbOfCompo);
2604   _mem.useExternalArrayWithRWAccess(array,nbOfTuple*nbOfCompo);
2605   declareAsNew();
2606 }
2607
2608 /*!
2609  * Checks if 0.0 value is present in \a this array. If it is the case, an exception
2610  * is thrown.
2611  * \throw If zero is found in \a this array.
2612  */
2613 void DataArrayDouble::checkNoNullValues() const throw(INTERP_KERNEL::Exception)
2614 {
2615   const double *tmp=getConstPointer();
2616   int nbOfElems=getNbOfElems();
2617   const double *where=std::find(tmp,tmp+nbOfElems,0.);
2618   if(where!=tmp+nbOfElems)
2619     throw INTERP_KERNEL::Exception("A value 0.0 have been detected !");
2620 }
2621
2622 /*!
2623  * Computes minimal and maximal value in each component. An output array is filled
2624  * with \c 2 * \a this->getNumberOfComponents() values, so the caller is to allocate
2625  * enough memory before calling this method.
2626  *  \param [out] bounds - array of size at least 2 *\a this->getNumberOfComponents().
2627  *               It is filled as follows:<br>
2628  *               \a bounds[0] = \c min_of_component_0 <br>
2629  *               \a bounds[1] = \c max_of_component_0 <br>
2630  *               \a bounds[2] = \c min_of_component_1 <br>
2631  *               \a bounds[3] = \c max_of_component_1 <br>
2632  *               ...
2633  */
2634 void DataArrayDouble::getMinMaxPerComponent(double *bounds) const throw(INTERP_KERNEL::Exception)
2635 {
2636   checkAllocated();
2637   int dim=getNumberOfComponents();
2638   for (int idim=0; idim<dim; idim++)
2639     {
2640       bounds[idim*2]=std::numeric_limits<double>::max();
2641       bounds[idim*2+1]=-std::numeric_limits<double>::max();
2642     } 
2643   const double *ptr=getConstPointer();
2644   int nbOfTuples=getNumberOfTuples();
2645   for(int i=0;i<nbOfTuples;i++)
2646     {
2647       for(int idim=0;idim<dim;idim++)
2648         {
2649           if(bounds[idim*2]>ptr[i*dim+idim])
2650             {
2651               bounds[idim*2]=ptr[i*dim+idim];
2652             }
2653           if(bounds[idim*2+1]<ptr[i*dim+idim])
2654             {
2655               bounds[idim*2+1]=ptr[i*dim+idim];
2656             }
2657         }
2658     }
2659 }
2660
2661 /*!
2662  * This method retrieves a newly allocated DataArrayDouble instance having same number of tuples than \a this and twice number of components than \a this
2663  * to store both the min and max per component of each tuples. 
2664  * \param [in] epsilon the width of the bbox (identical in each direction) - 0.0 by default
2665  *
2666  * \return a newly created DataArrayDouble instance having \c this->getNumberOfTuples() tuples and 2 * \c this->getNumberOfComponent() components
2667  *
2668  * \throw If \a this is not allocated yet.
2669  */
2670 DataArrayDouble *DataArrayDouble::computeBBoxPerTuple(double epsilon)const throw(INTERP_KERNEL::Exception)
2671 {
2672   checkAllocated();
2673   const double *dataPtr=getConstPointer();
2674   int nbOfCompo=getNumberOfComponents();
2675   int nbTuples=getNumberOfTuples();
2676   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> bbox=DataArrayDouble::New();
2677   bbox->alloc(nbTuples,2*nbOfCompo);
2678   double *bboxPtr=bbox->getPointer();
2679   for(int i=0;i<nbTuples;i++)
2680     {
2681       for(int j=0;j<nbOfCompo;j++)
2682         {
2683           bboxPtr[2*nbOfCompo*i+2*j]=dataPtr[nbOfCompo*i+j]-epsilon;
2684           bboxPtr[2*nbOfCompo*i+2*j+1]=dataPtr[nbOfCompo*i+j]+epsilon;
2685         }
2686     }
2687   return bbox.retn();
2688 }
2689
2690 /*!
2691  * For each tuples **t** in \a other, this method retrieves tuples in \a this that are equal to **t**.
2692  * Two tuples are considered equal if the euclidian distance between the two tuples is lower than \a eps.
2693  * 
2694  * \param [in] other a DataArrayDouble having same number of components than \a this.
2695  * \param [in] eps absolute precision representing euclidian distance between 2 tuples behind which 2 tuples are considered equal.
2696  * \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.
2697  *             \a cI allows to extract information in \a c.
2698  * \param [out] cI is an indirection array that allows to extract the data contained in \a c.
2699  *
2700  * \throw In case of:
2701  *  - \a this is not allocated
2702  *  - \a other is not allocated or null
2703  *  - \a this and \a other do not have the same number of components
2704  *  - if number of components of \a this is not in [1,2,3]
2705  *
2706  * \sa MEDCouplingPointSet::getNodeIdsNearPoints, DataArrayDouble::getDifferentValues
2707  */
2708 void DataArrayDouble::computeTupleIdsNearTuples(const DataArrayDouble *other, double eps, DataArrayInt *& c, DataArrayInt *& cI) const throw(INTERP_KERNEL::Exception)
2709 {
2710   if(!other)
2711     throw INTERP_KERNEL::Exception("DataArrayDouble::computeTupleIdsNearTuples : input pointer other is null !");
2712   checkAllocated();
2713   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> bbox=computeBBoxPerTuple(eps);
2714   other->checkAllocated();
2715   int nbOfCompo=getNumberOfComponents();
2716   int otherNbOfCompo=other->getNumberOfComponents();
2717   if(nbOfCompo!=otherNbOfCompo)
2718     throw INTERP_KERNEL::Exception("DataArrayDouble::computeTupleIdsNearTuples : number of components should be equal between this and other !");
2719   int nbOfTuplesOther=other->getNumberOfTuples();
2720   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cArr(DataArrayInt::New()),cIArr(DataArrayInt::New()); cArr->alloc(0,1); cIArr->pushBackSilent(0);
2721   switch(nbOfCompo)
2722     {
2723     case 3:
2724       {
2725         BBTree<3,int> myTree(bbox->getConstPointer(),0,0,getNumberOfTuples(),eps/10);
2726         FindTupleIdsNearTuplesAlg<3>(myTree,other->getConstPointer(),nbOfTuplesOther,eps,cArr,cIArr);
2727         break;
2728       }
2729     case 2:
2730       {
2731         BBTree<2,int> myTree(bbox->getConstPointer(),0,0,getNumberOfTuples(),eps/10);
2732         FindTupleIdsNearTuplesAlg<2>(myTree,other->getConstPointer(),nbOfTuplesOther,eps,cArr,cIArr);
2733         break;
2734       }
2735     case 1:
2736       {
2737         BBTree<1,int> myTree(bbox->getConstPointer(),0,0,getNumberOfTuples(),eps/10);
2738         FindTupleIdsNearTuplesAlg<1>(myTree,other->getConstPointer(),nbOfTuplesOther,eps,cArr,cIArr);
2739         break;
2740       }
2741     default:
2742       throw INTERP_KERNEL::Exception("Unexpected spacedim of coords for computeTupleIdsNearTuples. Must be 1, 2 or 3.");
2743     }
2744   c=cArr.retn(); cI=cIArr.retn();
2745 }
2746
2747 /*!
2748  * 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
2749  * around origin of 'radius' 1.
2750  * 
2751  * \param [in] eps absolute epsilon. under that value of delta between max and min no scale is performed.
2752  */
2753 void DataArrayDouble::recenterForMaxPrecision(double eps) throw(INTERP_KERNEL::Exception)
2754 {
2755   checkAllocated();
2756   int dim=getNumberOfComponents();
2757   std::vector<double> bounds(2*dim);
2758   getMinMaxPerComponent(&bounds[0]);
2759   for(int i=0;i<dim;i++)
2760     {
2761       double delta=bounds[2*i+1]-bounds[2*i];
2762       double offset=(bounds[2*i]+bounds[2*i+1])/2.;
2763       if(delta>eps)
2764         applyLin(1./delta,-offset/delta,i);
2765       else
2766         applyLin(1.,-offset,i);
2767     }
2768 }
2769
2770 /*!
2771  * Returns the maximal value and its location within \a this one-dimensional array.
2772  *  \param [out] tupleId - index of the tuple holding the maximal value.
2773  *  \return double - the maximal value among all values of \a this array.
2774  *  \throw If \a this->getNumberOfComponents() != 1
2775  *  \throw If \a this->getNumberOfTuples() < 1
2776  */
2777 double DataArrayDouble::getMaxValue(int& tupleId) const throw(INTERP_KERNEL::Exception)
2778 {
2779   checkAllocated();
2780   if(getNumberOfComponents()!=1)
2781     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 !");
2782   int nbOfTuples=getNumberOfTuples();
2783   if(nbOfTuples<=0)
2784     throw INTERP_KERNEL::Exception("DataArrayDouble::getMaxValue : array exists but number of tuples must be > 0 !");
2785   const double *vals=getConstPointer();
2786   const double *loc=std::max_element(vals,vals+nbOfTuples);
2787   tupleId=(int)std::distance(vals,loc);
2788   return *loc;
2789 }
2790
2791 /*!
2792  * Returns the maximal value within \a this array that is allowed to have more than
2793  *  one component.
2794  *  \return double - the maximal value among all values of \a this array.
2795  *  \throw If \a this is not allocated.
2796  */
2797 double DataArrayDouble::getMaxValueInArray() const throw(INTERP_KERNEL::Exception)
2798 {
2799   checkAllocated();
2800   const double *loc=std::max_element(begin(),end());
2801   return *loc;
2802 }
2803
2804 /*!
2805  * Returns the maximal value and all its locations within \a this one-dimensional array.
2806  *  \param [out] tupleIds - a new instance of DataArrayInt containg indices of
2807  *               tuples holding the maximal value. The caller is to delete it using
2808  *               decrRef() as it is no more needed.
2809  *  \return double - the maximal value among all values of \a this array.
2810  *  \throw If \a this->getNumberOfComponents() != 1
2811  *  \throw If \a this->getNumberOfTuples() < 1
2812  */
2813 double DataArrayDouble::getMaxValue2(DataArrayInt*& tupleIds) const throw(INTERP_KERNEL::Exception)
2814 {
2815   int tmp;
2816   tupleIds=0;
2817   double ret=getMaxValue(tmp);
2818   tupleIds=getIdsInRange(ret,ret);
2819   return ret;
2820 }
2821
2822 /*!
2823  * Returns the minimal value and its location within \a this one-dimensional array.
2824  *  \param [out] tupleId - index of the tuple holding the minimal value.
2825  *  \return double - the minimal value among all values of \a this array.
2826  *  \throw If \a this->getNumberOfComponents() != 1
2827  *  \throw If \a this->getNumberOfTuples() < 1
2828  */
2829 double DataArrayDouble::getMinValue(int& tupleId) const throw(INTERP_KERNEL::Exception)
2830 {
2831   checkAllocated();
2832   if(getNumberOfComponents()!=1)
2833     throw INTERP_KERNEL::Exception("DataArrayDouble::getMinValue : must be applied on DataArrayDouble with only one component, you can call 'rearrange' method before call 'getMinValueInArray' method !");
2834   int nbOfTuples=getNumberOfTuples();
2835   if(nbOfTuples<=0)
2836     throw INTERP_KERNEL::Exception("DataArrayDouble::getMinValue : array exists but number of tuples must be > 0 !");
2837   const double *vals=getConstPointer();
2838   const double *loc=std::min_element(vals,vals+nbOfTuples);
2839   tupleId=(int)std::distance(vals,loc);
2840   return *loc;
2841 }
2842
2843 /*!
2844  * Returns the minimal value within \a this array that is allowed to have more than
2845  *  one component.
2846  *  \return double - the minimal value among all values of \a this array.
2847  *  \throw If \a this is not allocated.
2848  */
2849 double DataArrayDouble::getMinValueInArray() const throw(INTERP_KERNEL::Exception)
2850 {
2851   checkAllocated();
2852   const double *loc=std::min_element(begin(),end());
2853   return *loc;
2854 }
2855
2856 /*!
2857  * Returns the minimal value and all its locations within \a this one-dimensional array.
2858  *  \param [out] tupleIds - a new instance of DataArrayInt containg indices of
2859  *               tuples holding the minimal value. The caller is to delete it using
2860  *               decrRef() as it is no more needed.
2861  *  \return double - the minimal value among all values of \a this array.
2862  *  \throw If \a this->getNumberOfComponents() != 1
2863  *  \throw If \a this->getNumberOfTuples() < 1
2864  */
2865 double DataArrayDouble::getMinValue2(DataArrayInt*& tupleIds) const throw(INTERP_KERNEL::Exception)
2866 {
2867   int tmp;
2868   tupleIds=0;
2869   double ret=getMinValue(tmp);
2870   tupleIds=getIdsInRange(ret,ret);
2871   return ret;
2872 }
2873
2874 /*!
2875  * Returns the average value of \a this one-dimensional array.
2876  *  \return double - the average value over all values of \a this array.
2877  *  \throw If \a this->getNumberOfComponents() != 1
2878  *  \throw If \a this->getNumberOfTuples() < 1
2879  */
2880 double DataArrayDouble::getAverageValue() const throw(INTERP_KERNEL::Exception)
2881 {
2882   if(getNumberOfComponents()!=1)
2883     throw INTERP_KERNEL::Exception("DataArrayDouble::getAverageValue : must be applied on DataArrayDouble with only one component, you can call 'rearrange' method before !");
2884   int nbOfTuples=getNumberOfTuples();
2885   if(nbOfTuples<=0)
2886     throw INTERP_KERNEL::Exception("DataArrayDouble::getAverageValue : array exists but number of tuples must be > 0 !");
2887   const double *vals=getConstPointer();
2888   double ret=std::accumulate(vals,vals+nbOfTuples,0.);
2889   return ret/nbOfTuples;
2890 }
2891
2892 /*!
2893  * Returns the Euclidean norm of the vector defined by \a this array.
2894  *  \return double - the value of the Euclidean norm, i.e.
2895  *          the square root of the inner product of vector.
2896  *  \throw If \a this is not allocated.
2897  */
2898 double DataArrayDouble::norm2() const throw(INTERP_KERNEL::Exception)
2899 {
2900   checkAllocated();
2901   double ret=0.;
2902   int nbOfElems=getNbOfElems();
2903   const double *pt=getConstPointer();
2904   for(int i=0;i<nbOfElems;i++,pt++)
2905     ret+=(*pt)*(*pt);
2906   return sqrt(ret);
2907 }
2908
2909 /*!
2910  * Returns the maximum norm of the vector defined by \a this array.
2911  *  \return double - the value of the maximum norm, i.e.
2912  *          the maximal absolute value among values of \a this array.
2913  *  \throw If \a this is not allocated.
2914  */
2915 double DataArrayDouble::normMax() const throw(INTERP_KERNEL::Exception)
2916 {
2917   checkAllocated();
2918   double ret=-1.;
2919   int nbOfElems=getNbOfElems();
2920   const double *pt=getConstPointer();
2921   for(int i=0;i<nbOfElems;i++,pt++)
2922     {
2923       double val=std::abs(*pt);
2924       if(val>ret)
2925         ret=val;
2926     }
2927   return ret;
2928 }
2929
2930 /*!
2931  * Accumulates values of each component of \a this array.
2932  *  \param [out] res - an array of length \a this->getNumberOfComponents(), allocated 
2933  *         by the caller, that is filled by this method with sum value for each
2934  *         component.
2935  *  \throw If \a this is not allocated.
2936  */
2937 void DataArrayDouble::accumulate(double *res) const throw(INTERP_KERNEL::Exception)
2938 {
2939   checkAllocated();
2940   const double *ptr=getConstPointer();
2941   int nbTuple=getNumberOfTuples();
2942   int nbComps=getNumberOfComponents();
2943   std::fill(res,res+nbComps,0.);
2944   for(int i=0;i<nbTuple;i++)
2945     std::transform(ptr+i*nbComps,ptr+(i+1)*nbComps,res,res,std::plus<double>());
2946 }
2947
2948 /*!
2949  * This method returns the min distance from an external tuple defined by [ \a tupleBg , \a tupleEnd ) to \a this and
2950  * the first tuple in \a this that matches the returned distance. If there is no tuples in \a this an exception will be thrown.
2951  *
2952  *
2953  * \a this is expected to be allocated and expected to have a number of components equal to the distance from \a tupleBg to
2954  * \a tupleEnd. If not an exception will be thrown.
2955  *
2956  * \param [in] tupleBg start pointer (included) of input external tuple
2957  * \param [in] tupleEnd end pointer (not included) of input external tuple
2958  * \param [out] tupleId the tuple id in \a this that matches the min of distance between \a this and input external tuple
2959  * \return the min distance.
2960  * \sa MEDCouplingUMesh::distanceToPoint
2961  */
2962 double DataArrayDouble::distanceToTuple(const double *tupleBg, const double *tupleEnd, int& tupleId) const throw(INTERP_KERNEL::Exception)
2963 {
2964   checkAllocated();
2965   int nbTuple=getNumberOfTuples();
2966   int nbComps=getNumberOfComponents();
2967   if(nbComps!=(int)std::distance(tupleBg,tupleEnd))
2968     { 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()); }
2969   if(nbTuple==0)
2970     throw INTERP_KERNEL::Exception("DataArrayDouble::distanceToTuple : no tuple in this ! No distance to compute !");
2971   double ret0=std::numeric_limits<double>::max();
2972   tupleId=-1;
2973   const double *work=getConstPointer();
2974   for(int i=0;i<nbTuple;i++)
2975     {
2976       double val=0.;
2977       for(int j=0;j<nbComps;j++,work++) 
2978         val+=(*work-tupleBg[j])*((*work-tupleBg[j]));
2979       if(val>=ret0)
2980         continue;
2981       else
2982         { ret0=val; tupleId=i; }
2983     }
2984   return sqrt(ret0);
2985 }
2986
2987 /*!
2988  * Accumulate values of the given component of \a this array.
2989  *  \param [in] compId - the index of the component of interest.
2990  *  \return double - a sum value of \a compId-th component.
2991  *  \throw If \a this is not allocated.
2992  *  \throw If \a the condition ( 0 <= \a compId < \a this->getNumberOfComponents() ) is
2993  *         not respected.
2994  */
2995 double DataArrayDouble::accumulate(int compId) const throw(INTERP_KERNEL::Exception)
2996 {
2997   checkAllocated();
2998   const double *ptr=getConstPointer();
2999   int nbTuple=getNumberOfTuples();
3000   int nbComps=getNumberOfComponents();
3001   if(compId<0 || compId>=nbComps)
3002     throw INTERP_KERNEL::Exception("DataArrayDouble::accumulate : Invalid compId specified : No such nb of components !");
3003   double ret=0.;
3004   for(int i=0;i<nbTuple;i++)
3005     ret+=ptr[i*nbComps+compId];
3006   return ret;
3007 }
3008
3009 /*!
3010  * Converts each 2D point defined by the tuple of \a this array from the Polar to the
3011  * Cartesian coordinate system. The two components of the tuple of \a this array are 
3012  * considered to contain (1) radius and (2) angle of the point in the Polar CS.
3013  *  \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
3014  *          contains X and Y coordinates of the point in the Cartesian CS. The caller
3015  *          is to delete this array using decrRef() as it is no more needed. The array
3016  *          does not contain any textual info on components.
3017  *  \throw If \a this->getNumberOfComponents() != 2.
3018  */
3019 DataArrayDouble *DataArrayDouble::fromPolarToCart() const throw(INTERP_KERNEL::Exception)
3020 {
3021   checkAllocated();
3022   int nbOfComp=getNumberOfComponents();
3023   if(nbOfComp!=2)
3024     throw INTERP_KERNEL::Exception("DataArrayDouble::fromPolarToCart : must be an array with exactly 2 components !");
3025   int nbOfTuple=getNumberOfTuples();
3026   DataArrayDouble *ret=DataArrayDouble::New();
3027   ret->alloc(nbOfTuple,2);
3028   double *w=ret->getPointer();
3029   const double *wIn=getConstPointer();
3030   for(int i=0;i<nbOfTuple;i++,w+=2,wIn+=2)
3031     {
3032       w[0]=wIn[0]*cos(wIn[1]);
3033       w[1]=wIn[0]*sin(wIn[1]);
3034     }
3035   return ret;
3036 }
3037
3038 /*!
3039  * Converts each 3D point defined by the tuple of \a this array from the Cylindrical to
3040  * the Cartesian coordinate system. The three components of the tuple of \a this array 
3041  * are considered to contain (1) radius, (2) azimuth and (3) altitude of the point in
3042  * the Cylindrical CS.
3043  *  \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
3044  *          contains X, Y and Z coordinates of the point in the Cartesian CS. The info
3045  *          on the third component is copied from \a this array. The caller
3046  *          is to delete this array using decrRef() as it is no more needed. 
3047  *  \throw If \a this->getNumberOfComponents() != 3.
3048  */
3049 DataArrayDouble *DataArrayDouble::fromCylToCart() const throw(INTERP_KERNEL::Exception)
3050 {
3051   checkAllocated();
3052   int nbOfComp=getNumberOfComponents();
3053   if(nbOfComp!=3)
3054     throw INTERP_KERNEL::Exception("DataArrayDouble::fromCylToCart : must be an array with exactly 3 components !");
3055   int nbOfTuple=getNumberOfTuples();
3056   DataArrayDouble *ret=DataArrayDouble::New();
3057   ret->alloc(getNumberOfTuples(),3);
3058   double *w=ret->getPointer();
3059   const double *wIn=getConstPointer();
3060   for(int i=0;i<nbOfTuple;i++,w+=3,wIn+=3)
3061     {
3062       w[0]=wIn[0]*cos(wIn[1]);
3063       w[1]=wIn[0]*sin(wIn[1]);
3064       w[2]=wIn[2];
3065     }
3066   ret->setInfoOnComponent(2,getInfoOnComponent(2).c_str());
3067   return ret;
3068 }
3069
3070 /*!
3071  * Converts each 3D point defined by the tuple of \a this array from the Spherical to
3072  * the Cartesian coordinate system. The three components of the tuple of \a this array 
3073  * are considered to contain (1) radius, (2) polar angle and (3) azimuthal angle of the
3074  * point in the Cylindrical CS.
3075  *  \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
3076  *          contains X, Y and Z coordinates of the point in the Cartesian CS. The info
3077  *          on the third component is copied from \a this array. The caller
3078  *          is to delete this array using decrRef() as it is no more needed.
3079  *  \throw If \a this->getNumberOfComponents() != 3.
3080  */
3081 DataArrayDouble *DataArrayDouble::fromSpherToCart() const throw(INTERP_KERNEL::Exception)
3082 {
3083   checkAllocated();
3084   int nbOfComp=getNumberOfComponents();
3085   if(nbOfComp!=3)
3086     throw INTERP_KERNEL::Exception("DataArrayDouble::fromSpherToCart : must be an array with exactly 3 components !");
3087   int nbOfTuple=getNumberOfTuples();
3088   DataArrayDouble *ret=DataArrayDouble::New();
3089   ret->alloc(getNumberOfTuples(),3);
3090   double *w=ret->getPointer();
3091   const double *wIn=getConstPointer();
3092   for(int i=0;i<nbOfTuple;i++,w+=3,wIn+=3)
3093     {
3094       w[0]=wIn[0]*cos(wIn[2])*sin(wIn[1]);
3095       w[1]=wIn[0]*sin(wIn[2])*sin(wIn[1]);
3096       w[2]=wIn[0]*cos(wIn[1]);
3097     }
3098   return ret;
3099 }
3100
3101 /*!
3102  * Computes the doubly contracted product of every tensor defined by the tuple of \a this
3103  * array contating 6 components.
3104  *  \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
3105  *          is calculated from the tuple <em>(t)</em> of \a this array as follows:
3106  *          \f$ t[0]^2+t[1]^2+t[2]^2+2*t[3]^2+2*t[4]^2+2*t[5]^2\f$.
3107  *         The caller is to delete this result array using decrRef() as it is no more needed. 
3108  *  \throw If \a this->getNumberOfComponents() != 6.
3109  */
3110 DataArrayDouble *DataArrayDouble::doublyContractedProduct() const throw(INTERP_KERNEL::Exception)
3111 {
3112   checkAllocated();
3113   int nbOfComp=getNumberOfComponents();
3114   if(nbOfComp!=6)
3115     throw INTERP_KERNEL::Exception("DataArrayDouble::doublyContractedProduct : must be an array with exactly 6 components !");
3116   DataArrayDouble *ret=DataArrayDouble::New();
3117   int nbOfTuple=getNumberOfTuples();
3118   ret->alloc(nbOfTuple,1);
3119   const double *src=getConstPointer();
3120   double *dest=ret->getPointer();
3121   for(int i=0;i<nbOfTuple;i++,dest++,src+=6)
3122     *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];
3123   return ret;
3124 }
3125
3126 /*!
3127  * Computes the determinant of every square matrix defined by the tuple of \a this
3128  * array, which contains either 4, 6 or 9 components. The case of 6 components
3129  * corresponds to that of the upper triangular matrix.
3130  *  \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
3131  *          is the determinant of matrix of the corresponding tuple of \a this array.
3132  *          The caller is to delete this result array using decrRef() as it is no more
3133  *          needed. 
3134  *  \throw If \a this->getNumberOfComponents() is not in [4,6,9].
3135  */
3136 DataArrayDouble *DataArrayDouble::determinant() const throw(INTERP_KERNEL::Exception)
3137 {
3138   checkAllocated();
3139   DataArrayDouble *ret=DataArrayDouble::New();
3140   int nbOfTuple=getNumberOfTuples();
3141   ret->alloc(nbOfTuple,1);
3142   const double *src=getConstPointer();
3143   double *dest=ret->getPointer();
3144   switch(getNumberOfComponents())
3145     {
3146     case 6:
3147       for(int i=0;i<nbOfTuple;i++,dest++,src+=6)
3148         *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];
3149       return ret;
3150     case 4:
3151       for(int i=0;i<nbOfTuple;i++,dest++,src+=4)
3152         *dest=src[0]*src[3]-src[1]*src[2];
3153       return ret;
3154     case 9:
3155       for(int i=0;i<nbOfTuple;i++,dest++,src+=9)
3156         *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];
3157       return ret;
3158     default:
3159       ret->decrRef();
3160       throw INTERP_KERNEL::Exception("DataArrayDouble::determinant : Invalid number of components ! must be in 4,6,9 !");
3161     }
3162 }
3163
3164 /*!
3165  * Computes 3 eigenvalues of every upper triangular matrix defined by the tuple of
3166  * \a this array, which contains 6 components.
3167  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing 3
3168  *          components, whose each tuple contains the eigenvalues of the matrix of
3169  *          corresponding tuple of \a this array. 
3170  *          The caller is to delete this result array using decrRef() as it is no more
3171  *          needed. 
3172  *  \throw If \a this->getNumberOfComponents() != 6.
3173  */
3174 DataArrayDouble *DataArrayDouble::eigenValues() const throw(INTERP_KERNEL::Exception)
3175 {
3176   checkAllocated();
3177   int nbOfComp=getNumberOfComponents();
3178   if(nbOfComp!=6)
3179     throw INTERP_KERNEL::Exception("DataArrayDouble::eigenValues : must be an array with exactly 6 components !");
3180   DataArrayDouble *ret=DataArrayDouble::New();
3181   int nbOfTuple=getNumberOfTuples();
3182   ret->alloc(nbOfTuple,3);
3183   const double *src=getConstPointer();
3184   double *dest=ret->getPointer();
3185   for(int i=0;i<nbOfTuple;i++,dest+=3,src+=6)
3186     INTERP_KERNEL::computeEigenValues6(src,dest);
3187   return ret;
3188 }
3189
3190 /*!
3191  * Computes 3 eigenvectors of every upper triangular matrix defined by the tuple of
3192  * \a this array, which contains 6 components.
3193  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing 9
3194  *          components, whose each tuple contains 3 eigenvectors of the matrix of
3195  *          corresponding tuple of \a this array.
3196  *          The caller is to delete this result array using decrRef() as it is no more
3197  *          needed.
3198  *  \throw If \a this->getNumberOfComponents() != 6.
3199  */
3200 DataArrayDouble *DataArrayDouble::eigenVectors() const throw(INTERP_KERNEL::Exception)
3201 {
3202   checkAllocated();
3203   int nbOfComp=getNumberOfComponents();
3204   if(nbOfComp!=6)
3205     throw INTERP_KERNEL::Exception("DataArrayDouble::eigenVectors : must be an array with exactly 6 components !");
3206   DataArrayDouble *ret=DataArrayDouble::New();
3207   int nbOfTuple=getNumberOfTuples();
3208   ret->alloc(nbOfTuple,9);
3209   const double *src=getConstPointer();
3210   double *dest=ret->getPointer();
3211   for(int i=0;i<nbOfTuple;i++,src+=6)
3212     {
3213       double tmp[3];
3214       INTERP_KERNEL::computeEigenValues6(src,tmp);
3215       for(int j=0;j<3;j++,dest+=3)
3216         INTERP_KERNEL::computeEigenVectorForEigenValue6(src,tmp[j],1e-12,dest);
3217     }
3218   return ret;
3219 }
3220
3221 /*!
3222  * Computes the inverse matrix of every matrix defined by the tuple of \a this
3223  * array, which contains either 4, 6 or 9 components. The case of 6 components
3224  * corresponds to that of the upper triangular matrix.
3225  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
3226  *          same number of components as \a this one, whose each tuple is the inverse
3227  *          matrix of the matrix of corresponding tuple of \a this array. 
3228  *          The caller is to delete this result array using decrRef() as it is no more
3229  *          needed. 
3230  *  \throw If \a this->getNumberOfComponents() is not in [4,6,9].
3231  */
3232 DataArrayDouble *DataArrayDouble::inverse() const throw(INTERP_KERNEL::Exception)
3233 {
3234   checkAllocated();
3235   int nbOfComp=getNumberOfComponents();
3236   if(nbOfComp!=6 && nbOfComp!=9 && nbOfComp!=4)
3237     throw INTERP_KERNEL::Exception("DataArrayDouble::inversion : must be an array with 4,6 or 9 components !");
3238   DataArrayDouble *ret=DataArrayDouble::New();
3239   int nbOfTuple=getNumberOfTuples();
3240   ret->alloc(nbOfTuple,nbOfComp);
3241   const double *src=getConstPointer();
3242   double *dest=ret->getPointer();
3243 if(nbOfComp==6)
3244     for(int i=0;i<nbOfTuple;i++,dest+=6,src+=6)
3245       {
3246         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];
3247         dest[0]=(src[1]*src[2]-src[4]*src[4])/det;
3248         dest[1]=(src[0]*src[2]-src[5]*src[5])/det;
3249         dest[2]=(src[0]*src[1]-src[3]*src[3])/det;
3250         dest[3]=(src[5]*src[4]-src[3]*src[2])/det;
3251         dest[4]=(src[5]*src[3]-src[0]*src[4])/det;
3252         dest[5]=(src[3]*src[4]-src[1]*src[5])/det;
3253       }
3254   else if(nbOfComp==4)
3255     for(int i=0;i<nbOfTuple;i++,dest+=4,src+=4)
3256       {
3257         double det=src[0]*src[3]-src[1]*src[2];
3258         dest[0]=src[3]/det;
3259         dest[1]=-src[1]/det;
3260         dest[2]=-src[2]/det;
3261         dest[3]=src[0]/det;
3262       }
3263   else
3264     for(int i=0;i<nbOfTuple;i++,dest+=9,src+=9)
3265       {
3266         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];
3267         dest[0]=(src[4]*src[8]-src[7]*src[5])/det;
3268         dest[1]=(src[7]*src[2]-src[1]*src[8])/det;
3269         dest[2]=(src[1]*src[5]-src[4]*src[2])/det;
3270         dest[3]=(src[6]*src[5]-src[3]*src[8])/det;
3271         dest[4]=(src[0]*src[8]-src[6]*src[2])/det;
3272         dest[5]=(src[2]*src[3]-src[0]*src[5])/det;
3273         dest[6]=(src[3]*src[7]-src[6]*src[4])/det;
3274         dest[7]=(src[6]*src[1]-src[0]*src[7])/det;
3275         dest[8]=(src[0]*src[4]-src[1]*src[3])/det;
3276       }
3277   return ret;
3278 }
3279
3280 /*!
3281  * Computes the trace of every matrix defined by the tuple of \a this
3282  * array, which contains either 4, 6 or 9 components. The case of 6 components
3283  * corresponds to that of the upper triangular matrix.
3284  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing 
3285  *          1 component, whose each tuple is the trace of
3286  *          the matrix of corresponding tuple of \a this array. 
3287  *          The caller is to delete this result array using decrRef() as it is no more
3288  *          needed. 
3289  *  \throw If \a this->getNumberOfComponents() is not in [4,6,9].
3290  */
3291 DataArrayDouble *DataArrayDouble::trace() const throw(INTERP_KERNEL::Exception)
3292 {
3293   checkAllocated();
3294   int nbOfComp=getNumberOfComponents();
3295   if(nbOfComp!=6 && nbOfComp!=9 && nbOfComp!=4)
3296     throw INTERP_KERNEL::Exception("DataArrayDouble::trace : must be an array with 4,6 or 9 components !");
3297   DataArrayDouble *ret=DataArrayDouble::New();
3298   int nbOfTuple=getNumberOfTuples();
3299   ret->alloc(nbOfTuple,1);
3300   const double *src=getConstPointer();
3301   double *dest=ret->getPointer();
3302   if(nbOfComp==6)
3303     for(int i=0;i<nbOfTuple;i++,dest++,src+=6)
3304       *dest=src[0]+src[1]+src[2];
3305   else if(nbOfComp==4)
3306     for(int i=0;i<nbOfTuple;i++,dest++,src+=4)
3307       *dest=src[0]+src[3];
3308   else
3309     for(int i=0;i<nbOfTuple;i++,dest++,src+=9)
3310       *dest=src[0]+src[4]+src[8];
3311   return ret;
3312 }
3313
3314 /*!
3315  * Computes the stress deviator tensor of every stress tensor defined by the tuple of
3316  * \a this array, which contains 6 components.
3317  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
3318  *          same number of components and tuples as \a this array.
3319  *          The caller is to delete this result array using decrRef() as it is no more
3320  *          needed.
3321  *  \throw If \a this->getNumberOfComponents() != 6.
3322  */
3323 DataArrayDouble *DataArrayDouble::deviator() const throw(INTERP_KERNEL::Exception)
3324 {
3325   checkAllocated();
3326   int nbOfComp=getNumberOfComponents();
3327   if(nbOfComp!=6)
3328     throw INTERP_KERNEL::Exception("DataArrayDouble::deviator : must be an array with exactly 6 components !");
3329   DataArrayDouble *ret=DataArrayDouble::New();
3330   int nbOfTuple=getNumberOfTuples();
3331   ret->alloc(nbOfTuple,6);
3332   const double *src=getConstPointer();
3333   double *dest=ret->getPointer();
3334   for(int i=0;i<nbOfTuple;i++,dest+=6,src+=6)
3335     {
3336       double tr=(src[0]+src[1]+src[2])/3.;
3337       dest[0]=src[0]-tr;
3338       dest[1]=src[1]-tr;
3339       dest[2]=src[2]-tr;
3340       dest[3]=src[3];
3341       dest[4]=src[4];
3342       dest[5]=src[5];
3343     }
3344   return ret;
3345 }
3346
3347 /*!
3348  * Computes the magnitude of every vector defined by the tuple of
3349  * \a this array.
3350  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
3351  *          same number of tuples as \a this array and one component.
3352  *          The caller is to delete this result array using decrRef() as it is no more
3353  *          needed.
3354  *  \throw If \a this is not allocated.
3355  */
3356 DataArrayDouble *DataArrayDouble::magnitude() const throw(INTERP_KERNEL::Exception)
3357 {
3358   checkAllocated();
3359   int nbOfComp=getNumberOfComponents();
3360   DataArrayDouble *ret=DataArrayDouble::New();
3361   int nbOfTuple=getNumberOfTuples();
3362   ret->alloc(nbOfTuple,1);
3363   const double *src=getConstPointer();
3364   double *dest=ret->getPointer();
3365   for(int i=0;i<nbOfTuple;i++,dest++)
3366     {
3367       double sum=0.;
3368       for(int j=0;j<nbOfComp;j++,src++)
3369         sum+=(*src)*(*src);
3370       *dest=sqrt(sum);
3371     }
3372   return ret;
3373 }
3374
3375 /*!
3376  * Computes the maximal value within every tuple of \a this array.
3377  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
3378  *          same number of tuples as \a this array and one component.
3379  *          The caller is to delete this result array using decrRef() as it is no more
3380  *          needed.
3381  *  \throw If \a this is not allocated.
3382  */
3383 DataArrayDouble *DataArrayDouble::maxPerTuple() const throw(INTERP_KERNEL::Exception)
3384 {
3385   checkAllocated();
3386   int nbOfComp=getNumberOfComponents();
3387   DataArrayDouble *ret=DataArrayDouble::New();
3388   int nbOfTuple=getNumberOfTuples();
3389   ret->alloc(nbOfTuple,1);
3390   const double *src=getConstPointer();
3391   double *dest=ret->getPointer();
3392   for(int i=0;i<nbOfTuple;i++,dest++,src+=nbOfComp)
3393     *dest=*std::max_element(src,src+nbOfComp);
3394   return ret;
3395 }
3396
3397 /*!
3398  * This method returns a newly allocated DataArrayDouble instance having one component and \c this->getNumberOfTuples() * \c this->getNumberOfTuples() tuples.
3399  * \n This returned array contains the euclidian distance for each tuple in \a this. 
3400  * \n So the returned array can be seen as a dense symmetrical matrix whose diagonal elements are equal to 0.
3401  * \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)
3402  *
3403  * \warning use this method with care because it can leads to big amount of consumed memory !
3404  * 
3405  * \return A newly allocated (huge) ParaMEDMEM::DataArrayDouble instance that the caller should deal with.
3406  *
3407  * \throw If \a this is not allocated.
3408  *
3409  * \sa DataArrayDouble::buildEuclidianDistanceDenseMatrixWith
3410  */
3411 DataArrayDouble *DataArrayDouble::buildEuclidianDistanceDenseMatrix() const throw(INTERP_KERNEL::Exception)
3412 {
3413   checkAllocated();
3414   int nbOfComp=getNumberOfComponents();
3415   int nbOfTuples=getNumberOfTuples();
3416   const double *inData=getConstPointer();
3417   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
3418   ret->alloc(nbOfTuples*nbOfTuples,1);
3419   double *outData=ret->getPointer();
3420   for(int i=0;i<nbOfTuples;i++)
3421     {
3422       outData[i*nbOfTuples+i]=0.;
3423       for(int j=i+1;j<nbOfTuples;j++)
3424         {
3425           double dist=0.;
3426           for(int k=0;k<nbOfComp;k++)
3427             { double delta=inData[i*nbOfComp+k]-inData[j*nbOfComp+k]; dist+=delta*delta; }
3428           dist=sqrt(dist);
3429           outData[i*nbOfTuples+j]=dist;
3430           outData[j*nbOfTuples+i]=dist;
3431         }
3432     }
3433   return ret.retn();
3434 }
3435
3436 /*!
3437  * This method returns a newly allocated DataArrayDouble instance having one component and \c this->getNumberOfTuples() * \c other->getNumberOfTuples() tuples.
3438  * \n This returned array contains the euclidian distance for each tuple in \a other with each tuple in \a this. 
3439  * \n So the returned array can be seen as a dense rectangular matrix with \c other->getNumberOfTuples() rows and \c this->getNumberOfTuples() columns.
3440  * \n Output rectangular matrix is sorted along rows.
3441  * \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)
3442  *
3443  * \warning use this method with care because it can leads to big amount of consumed memory !
3444  * 
3445  * \param [in] other DataArrayDouble instance having same number of components than \a this.
3446  * \return A newly allocated (huge) ParaMEDMEM::DataArrayDouble instance that the caller should deal with.
3447  *
3448  * \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.
3449  *
3450  * \sa DataArrayDouble::buildEuclidianDistanceDenseMatrix
3451  */
3452 DataArrayDouble *DataArrayDouble::buildEuclidianDistanceDenseMatrixWith(const DataArrayDouble *other) const throw(INTERP_KERNEL::Exception)
3453 {
3454   if(!other)
3455     throw INTERP_KERNEL::Exception("DataArrayDouble::buildEuclidianDistanceDenseMatrixWith : input parameter is null !");
3456   checkAllocated();
3457   other->checkAllocated();
3458   int nbOfComp=getNumberOfComponents();
3459   int otherNbOfComp=other->getNumberOfComponents();
3460   if(nbOfComp!=otherNbOfComp)
3461     {
3462       std::ostringstream oss; oss << "DataArrayDouble::buildEuclidianDistanceDenseMatrixWith : this nb of compo=" << nbOfComp << " and other nb of compo=" << otherNbOfComp << ". It should match !";
3463       throw INTERP_KERNEL::Exception(oss.str().c_str());
3464     }
3465   int nbOfTuples=getNumberOfTuples();
3466   int otherNbOfTuples=other->getNumberOfTuples();
3467   const double *inData=getConstPointer();
3468   const double *inDataOther=other->getConstPointer();
3469   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
3470   ret->alloc(otherNbOfTuples*nbOfTuples,1);
3471   double *outData=ret->getPointer();
3472   for(int i=0;i<otherNbOfTuples;i++,inDataOther+=nbOfComp)
3473     {
3474       for(int j=0;j<nbOfTuples;j++)
3475         {
3476           double dist=0.;
3477           for(int k=0;k<nbOfComp;k++)
3478             { double delta=inDataOther[k]-inData[j*nbOfComp+k]; dist+=delta*delta; }
3479           dist=sqrt(dist);
3480           outData[i*nbOfTuples+j]=dist;
3481         }
3482     }
3483   return ret.retn();
3484 }
3485
3486 /*!
3487  * Sorts value within every tuple of \a this array.
3488  *  \param [in] asc - if \a true, the values are sorted in ascending order, else,
3489  *              in descending order.
3490  *  \throw If \a this is not allocated.
3491  */
3492 void DataArrayDouble::sortPerTuple(bool asc) throw(INTERP_KERNEL::Exception)
3493 {
3494   checkAllocated();
3495   double *pt=getPointer();
3496   int nbOfTuple=getNumberOfTuples();
3497   int nbOfComp=getNumberOfComponents();
3498   if(asc)
3499     for(int i=0;i<nbOfTuple;i++,pt+=nbOfComp)
3500       std::sort(pt,pt+nbOfComp);
3501   else
3502     for(int i=0;i<nbOfTuple;i++,pt+=nbOfComp)
3503       std::sort(pt,pt+nbOfComp,std::greater<double>());
3504   declareAsNew();
3505 }
3506
3507 /*!
3508  * Converts every value of \a this array to its absolute value.
3509  *  \throw If \a this is not allocated.
3510  */
3511 void DataArrayDouble::abs() throw(INTERP_KERNEL::Exception)
3512 {
3513   checkAllocated();
3514   double *ptr=getPointer();
3515   int nbOfElems=getNbOfElems();
3516   std::transform(ptr,ptr+nbOfElems,ptr,std::ptr_fun<double,double>(fabs));
3517   declareAsNew();
3518 }
3519
3520 /*!
3521  * Apply a liner function to a given component of \a this array, so that
3522  * an array element <em>(x)</em> becomes \f$ a * x + b \f$.
3523  *  \param [in] a - the first coefficient of the function.
3524  *  \param [in] b - the second coefficient of the function.
3525  *  \param [in] compoId - the index of component to modify.
3526  *  \throw If \a this is not allocated.
3527  */
3528 void DataArrayDouble::applyLin(double a, double b, int compoId) throw(INTERP_KERNEL::Exception)
3529 {
3530   checkAllocated();
3531   double *ptr=getPointer()+compoId;
3532   int nbOfComp=getNumberOfComponents();
3533   int nbOfTuple=getNumberOfTuples();
3534   for(int i=0;i<nbOfTuple;i++,ptr+=nbOfComp)
3535     *ptr=a*(*ptr)+b;
3536   declareAsNew();
3537 }
3538
3539 /*!
3540  * Apply a liner function to all elements of \a this array, so that
3541  * an element _x_ becomes \f$ a * x + b \f$.
3542  *  \param [in] a - the first coefficient of the function.
3543  *  \param [in] b - the second coefficient of the function.
3544  *  \throw If \a this is not allocated.
3545  */
3546 void DataArrayDouble::applyLin(double a, double b) throw(INTERP_KERNEL::Exception)
3547 {
3548   checkAllocated();
3549   double *ptr=getPointer();
3550   int nbOfElems=getNbOfElems();
3551   for(int i=0;i<nbOfElems;i++,ptr++)
3552     *ptr=a*(*ptr)+b;
3553   declareAsNew();
3554 }
3555
3556 /*!
3557  * Modify all elements of \a this array, so that
3558  * an element _x_ becomes \f$ numerator / x \f$.
3559  *  \param [in] numerator - the numerator used to modify array elements.
3560  *  \throw If \a this is not allocated.
3561  *  \throw If there is an element equal to 0.0 in \a this array.
3562  *  \warning If an exception is thrown because of presence of 0.0 element in \a this 
3563  *           array, all elements processed before detection of the zero element remain
3564  *           modified.
3565  */
3566 void DataArrayDouble::applyInv(double numerator) throw(INTERP_KERNEL::Exception)
3567 {
3568   checkAllocated();
3569   double *ptr=getPointer();
3570   int nbOfElems=getNbOfElems();
3571   for(int i=0;i<nbOfElems;i++,ptr++)
3572     {
3573       if(std::abs(*ptr)>std::numeric_limits<double>::min())
3574         {
3575           *ptr=numerator/(*ptr);
3576         }
3577       else
3578         {
3579           std::ostringstream oss; oss << "DataArrayDouble::applyInv : presence of null value in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
3580           oss << " !";
3581           throw INTERP_KERNEL::Exception(oss.str().c_str());
3582         }
3583     }
3584   declareAsNew();
3585 }
3586
3587 /*!
3588  * Returns a full copy of \a this array except that sign of all elements is reversed.
3589  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
3590  *          same number of tuples and component as \a this array.
3591  *          The caller is to delete this result array using decrRef() as it is no more
3592  *          needed.
3593  *  \throw If \a this is not allocated.
3594  */
3595 DataArrayDouble *DataArrayDouble::negate() const throw(INTERP_KERNEL::Exception)
3596 {
3597   checkAllocated();
3598   DataArrayDouble *newArr=DataArrayDouble::New();
3599   int nbOfTuples=getNumberOfTuples();
3600   int nbOfComp=getNumberOfComponents();
3601   newArr->alloc(nbOfTuples,nbOfComp);
3602   const double *cptr=getConstPointer();
3603   std::transform(cptr,cptr+nbOfTuples*nbOfComp,newArr->getPointer(),std::negate<double>());
3604   newArr->copyStringInfoFrom(*this);
3605   return newArr;
3606 }
3607
3608 /*!
3609  * Returns a new DataArrayDouble created from \a this one by applying \a
3610  * FunctionToEvaluate to every tuple of \a this array. Textual data is not copied.
3611  * For more info see \ref MEDCouplingArrayApplyFunc
3612  *  \param [in] nbOfComp - number of components in the result array.
3613  *  \param [in] func - the \a FunctionToEvaluate declared as 
3614  *              \c bool (*\a func)(\c const \c double *\a pos, \c double *\a res), 
3615  *              where \a pos points to the first component of a tuple of \a this array
3616  *              and \a res points to the first component of a tuple of the result array.
3617  *              Note that length (number of components) of \a pos can differ from
3618  *              that of \a res.
3619  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
3620  *          same number of tuples as \a this array.
3621  *          The caller is to delete this result array using decrRef() as it is no more
3622  *          needed.
3623  *  \throw If \a this is not allocated.
3624  *  \throw If \a func returns \a false.
3625  */
3626 DataArrayDouble *DataArrayDouble::applyFunc(int nbOfComp, FunctionToEvaluate func) const throw(INTERP_KERNEL::Exception)
3627 {
3628   checkAllocated();
3629   DataArrayDouble *newArr=DataArrayDouble::New();
3630   int nbOfTuples=getNumberOfTuples();
3631   int oldNbOfComp=getNumberOfComponents();
3632   newArr->alloc(nbOfTuples,nbOfComp);
3633   const double *ptr=getConstPointer();
3634   double *ptrToFill=newArr->getPointer();
3635   for(int i=0;i<nbOfTuples;i++)
3636     {
3637       if(!func(ptr+i*oldNbOfComp,ptrToFill+i*nbOfComp))
3638         {
3639           std::ostringstream oss; oss << "For tuple # " << i << " with value (";
3640           std::copy(ptr+oldNbOfComp*i,ptr+oldNbOfComp*(i+1),std::ostream_iterator<double>(oss,", "));
3641           oss << ") : Evaluation of function failed !";
3642           newArr->decrRef();
3643           throw INTERP_KERNEL::Exception(oss.str().c_str());
3644         }
3645     }
3646   return newArr;
3647 }
3648
3649 /*!
3650  * Returns a new DataArrayDouble created from \a this one by applying a function to every
3651  * tuple of \a this array. Textual data is not copied.
3652  * For more info see \ref MEDCouplingArrayApplyFunc1.
3653  *  \param [in] nbOfComp - number of components in the result array.
3654  *  \param [in] func - the expression defining how to transform a tuple of \a this array.
3655  *              Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
3656  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
3657  *          same number of tuples as \a this array and \a nbOfComp components.
3658  *          The caller is to delete this result array using decrRef() as it is no more
3659  *          needed.
3660  *  \throw If \a this is not allocated.
3661  *  \throw If computing \a func fails.
3662  */
3663 DataArrayDouble *DataArrayDouble::applyFunc(int nbOfComp, const char *func) const throw(INTERP_KERNEL::Exception)
3664 {
3665   checkAllocated();
3666   INTERP_KERNEL::ExprParser expr(func);
3667   expr.parse();
3668   std::set<std::string> vars;
3669   expr.getTrueSetOfVars(vars);
3670   int oldNbOfComp=getNumberOfComponents();
3671   if((int)vars.size()>oldNbOfComp)
3672     {
3673       std::ostringstream oss; oss << "The field has " << oldNbOfComp << " components and there are ";
3674       oss << vars.size() << " variables : ";
3675       std::copy(vars.begin(),vars.end(),std::ostream_iterator<std::string>(oss," "));
3676       throw INTERP_KERNEL::Exception(oss.str().c_str());
3677     }
3678   std::vector<std::string> varsV(vars.begin(),vars.end());
3679   expr.prepareExprEvaluation(varsV,oldNbOfComp,nbOfComp);
3680   //
3681   DataArrayDouble *newArr=DataArrayDouble::New();
3682   int nbOfTuples=getNumberOfTuples();
3683   newArr->alloc(nbOfTuples,nbOfComp);
3684   const double *ptr=getConstPointer();
3685   double *ptrToFill=newArr->getPointer();
3686   for(int i=0;i<nbOfTuples;i++)
3687     {
3688       try
3689         {
3690           expr.evaluateExpr(nbOfComp,ptr+i*oldNbOfComp,ptrToFill+i*nbOfComp);
3691         }
3692       catch(INTERP_KERNEL::Exception& e)
3693         {
3694           std::ostringstream oss; oss << "For tuple # " << i << " with value (";
3695           std::copy(ptr+oldNbOfComp*i,ptr+oldNbOfComp*(i+1),std::ostream_iterator<double>(oss,", "));
3696           oss << ") : Evaluation of function failed !" << e.what();
3697           newArr->decrRef();
3698           throw INTERP_KERNEL::Exception(oss.str().c_str());
3699         }
3700     }
3701   return newArr;
3702 }
3703
3704 /*!
3705  * Returns a new DataArrayDouble created from \a this one by applying a function to every
3706  * tuple of \a this array. Textual data is not copied.
3707  * For more info see \ref MEDCouplingArrayApplyFunc0.
3708  *  \param [in] func - the expression defining how to transform a tuple of \a this array.
3709  *              Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
3710  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
3711  *          same number of tuples and components as \a this array.
3712  *          The caller is to delete this result array using decrRef() as it is no more
3713  *          needed.
3714  *  \throw If \a this is not allocated.
3715  *  \throw If computing \a func fails.
3716  */
3717 DataArrayDouble *DataArrayDouble::applyFunc(const char *func) const throw(INTERP_KERNEL::Exception)
3718 {
3719   checkAllocated();
3720   INTERP_KERNEL::ExprParser expr(func);
3721   expr.parse();
3722   expr.prepareExprEvaluationVec();
3723   //
3724   DataArrayDouble *newArr=DataArrayDouble::New();
3725   int nbOfTuples=getNumberOfTuples();
3726   int nbOfComp=getNumberOfComponents();
3727   newArr->alloc(nbOfTuples,nbOfComp);
3728   const double *ptr=getConstPointer();
3729   double *ptrToFill=newArr->getPointer();
3730   for(int i=0;i<nbOfTuples;i++)
3731     {
3732       try
3733         {
3734           expr.evaluateExpr(nbOfComp,ptr+i*nbOfComp,ptrToFill+i*nbOfComp);
3735         }
3736       catch(INTERP_KERNEL::Exception& e)
3737         {
3738           std::ostringstream oss; oss << "For tuple # " << i << " with value (";
3739           std::copy(ptr+nbOfComp*i,ptr+nbOfComp*(i+1),std::ostream_iterator<double>(oss,", "));
3740           oss << ") : Evaluation of function failed ! " << e.what();
3741           newArr->decrRef();
3742           throw INTERP_KERNEL::Exception(oss.str().c_str());
3743         }
3744     }
3745   return newArr;
3746 }
3747
3748 /*!
3749  * Returns a new DataArrayDouble created from \a this one by applying a function to every
3750  * tuple of \a this array. Textual data is not copied.
3751  * For more info see \ref MEDCouplingArrayApplyFunc2.
3752  *  \param [in] nbOfComp - number of components in the result array.
3753  *  \param [in] func - the expression defining how to transform a tuple of \a this array.
3754  *              Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
3755  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
3756  *          same number of tuples as \a this array.
3757  *          The caller is to delete this result array using decrRef() as it is no more
3758  *          needed.
3759  *  \throw If \a this is not allocated.
3760  *  \throw If \a func contains vars that are not in \a this->getInfoOnComponent().
3761  *  \throw If computing \a func fails.
3762  */
3763 DataArrayDouble *DataArrayDouble::applyFunc2(int nbOfComp, const char *func) const throw(INTERP_KERNEL::Exception)
3764 {
3765   checkAllocated();
3766   INTERP_KERNEL::ExprParser expr(func);
3767   expr.parse();
3768   std::set<std::string> vars;
3769   expr.getTrueSetOfVars(vars);
3770   int oldNbOfComp=getNumberOfComponents();
3771   if((int)vars.size()>oldNbOfComp)
3772     {
3773       std::ostringstream oss; oss << "The field has " << oldNbOfComp << " components and there are ";
3774       oss << vars.size() << " variables : ";
3775       std::copy(vars.begin(),vars.end(),std::ostream_iterator<std::string>(oss," "));
3776       throw INTERP_KERNEL::Exception(oss.str().c_str());
3777     }
3778   expr.prepareExprEvaluation(getVarsOnComponent(),oldNbOfComp,nbOfComp);
3779   //
3780   DataArrayDouble *newArr=DataArrayDouble::New();
3781   int nbOfTuples=getNumberOfTuples();
3782   newArr->alloc(nbOfTuples,nbOfComp);
3783   const double *ptr=getConstPointer();
3784   double *ptrToFill=newArr->getPointer();
3785   for(int i=0;i<nbOfTuples;i++)
3786     {
3787       try
3788         {
3789           expr.evaluateExpr(nbOfComp,ptr+i*oldNbOfComp,ptrToFill+i*nbOfComp);
3790         }
3791       catch(INTERP_KERNEL::Exception& e)
3792         {
3793           std::ostringstream oss; oss << "For tuple # " << i << " with value (";
3794           std::copy(ptr+oldNbOfComp*i,ptr+oldNbOfComp*(i+1),std::ostream_iterator<double>(oss,", "));
3795           oss << ") : Evaluation of function failed !" << e.what();
3796           newArr->decrRef();
3797           throw INTERP_KERNEL::Exception(oss.str().c_str());
3798         }
3799     }
3800   return newArr;
3801 }
3802
3803 /*!
3804  * Returns a new DataArrayDouble created from \a this one by applying a function to every
3805  * tuple of \a this array. Textual data is not copied.
3806  * For more info see \ref MEDCouplingArrayApplyFunc3.
3807  *  \param [in] nbOfComp - number of components in the result array.
3808  *  \param [in] varsOrder - sequence of vars defining their order.
3809  *  \param [in] func - the expression defining how to transform a tuple of \a this array.
3810  *              Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
3811  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
3812  *          same number of tuples as \a this array.
3813  *          The caller is to delete this result array using decrRef() as it is no more
3814  *          needed.
3815  *  \throw If \a this is not allocated.
3816  *  \throw If \a func contains vars not in \a varsOrder.
3817  *  \throw If computing \a func fails.
3818  */
3819 DataArrayDouble *DataArrayDouble::applyFunc3(int nbOfComp, const std::vector<std::string>& varsOrder, const char *func) const throw(INTERP_KERNEL::Exception)
3820 {
3821   checkAllocated();
3822   INTERP_KERNEL::ExprParser expr(func);
3823   expr.parse();
3824   std::set<std::string> vars;
3825   expr.getTrueSetOfVars(vars);
3826   int oldNbOfComp=getNumberOfComponents();
3827   if((int)vars.size()>oldNbOfComp)
3828     {
3829       std::ostringstream oss; oss << "The field has " << oldNbOfComp << " components and there are ";
3830       oss << vars.size() << " variables : ";
3831       std::copy(vars.begin(),vars.end(),std::ostream_iterator<std::string>(oss," "));
3832       throw INTERP_KERNEL::Exception(oss.str().c_str());
3833     }
3834   expr.prepareExprEvaluation(varsOrder,oldNbOfComp,nbOfComp);
3835   //
3836   DataArrayDouble *newArr=DataArrayDouble::New();
3837   int nbOfTuples=getNumberOfTuples();
3838   newArr->alloc(nbOfTuples,nbOfComp);
3839   const double *ptr=getConstPointer();
3840   double *ptrToFill=newArr->getPointer();
3841   for(int i=0;i<nbOfTuples;i++)
3842     {
3843       try
3844         {
3845           expr.evaluateExpr(nbOfComp,ptr+i*oldNbOfComp,ptrToFill+i*nbOfComp);
3846         }
3847       catch(INTERP_KERNEL::Exception& e)
3848         {
3849           std::ostringstream oss; oss << "For tuple # " << i << " with value (";
3850           std::copy(ptr+oldNbOfComp*i,ptr+oldNbOfComp*(i+1),std::ostream_iterator<double>(oss,", "));
3851           oss << ") : Evaluation of function failed !" << e.what();
3852           newArr->decrRef();
3853           throw INTERP_KERNEL::Exception(oss.str().c_str());
3854         }
3855     }
3856   return newArr;
3857 }
3858
3859 void DataArrayDouble::applyFuncFast32(const char *func) throw(INTERP_KERNEL::Exception)
3860 {
3861   checkAllocated();
3862   INTERP_KERNEL::ExprParser expr(func);
3863   expr.parse();
3864   char *funcStr=expr.compileX86();
3865   MYFUNCPTR funcPtr;
3866   *((void **)&funcPtr)=funcStr;//he he...
3867   //
3868   double *ptr=getPointer();
3869   int nbOfComp=getNumberOfComponents();
3870   int nbOfTuples=getNumberOfTuples();
3871   int nbOfElems=nbOfTuples*nbOfComp;
3872   for(int i=0;i<nbOfElems;i++,ptr++)
3873     *ptr=funcPtr(*ptr);
3874   declareAsNew();
3875 }
3876
3877 void DataArrayDouble::applyFuncFast64(const char *func) throw(INTERP_KERNEL::Exception)
3878 {
3879   checkAllocated();
3880   INTERP_KERNEL::ExprParser expr(func);
3881   expr.parse();
3882   char *funcStr=expr.compileX86_64();
3883   MYFUNCPTR funcPtr;
3884   *((void **)&funcPtr)=funcStr;//he he...
3885   //
3886   double *ptr=getPointer();
3887   int nbOfComp=getNumberOfComponents();
3888   int nbOfTuples=getNumberOfTuples();
3889   int nbOfElems=nbOfTuples*nbOfComp;
3890   for(int i=0;i<nbOfElems;i++,ptr++)
3891     *ptr=funcPtr(*ptr);
3892   declareAsNew();
3893 }
3894
3895 DataArrayDoubleIterator *DataArrayDouble::iterator()
3896 {
3897   return new DataArrayDoubleIterator(this);
3898 }
3899
3900 /*!
3901  * Returns a new DataArrayInt contating indices of tuples of \a this one-dimensional
3902  * array whose values are within a given range. Textual data is not copied.
3903  *  \param [in] vmin - a lowest acceptable value.
3904  *  \param [in] vmax - a greatest acceptable value.
3905  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
3906  *          The caller is to delete this result array using decrRef() as it is no more
3907  *          needed.
3908  *  \throw If \a this->getNumberOfComponents() != 1
3909  *
3910  *  \ref cpp_mcdataarraydouble_getidsinrange "Here is a C++ example".
3911  *
3912  *  \ref py_mcdataarraydouble_getidsinrange "Here is a Python example".
3913  */
3914 DataArrayInt *DataArrayDouble::getIdsInRange(double vmin, double vmax) const throw(INTERP_KERNEL::Exception)
3915 {
3916   checkAllocated();
3917   if(getNumberOfComponents()!=1)
3918     throw INTERP_KERNEL::Exception("DataArrayDouble::getIdsInRange : this must have exactly one component !");
3919   const double *cptr=getConstPointer();
3920   std::vector<int> res;
3921   int nbOfTuples=getNumberOfTuples();
3922   for(int i=0;i<nbOfTuples;i++,cptr++)
3923     if(*cptr>=vmin && *cptr<=vmax)
3924       res.push_back(i);
3925   DataArrayInt *ret=DataArrayInt::New();
3926   ret->alloc((int)res.size(),1);
3927   std::copy(res.begin(),res.end(),ret->getPointer());
3928   return ret;
3929 }
3930
3931 /*!
3932  * Returns a new DataArrayDouble by concatenating two given arrays, so that (1) the number
3933  * of tuples in the result array is a sum of the number of tuples of given arrays and (2)
3934  * the number of component in the result array is same as that of each of given arrays.
3935  * Info on components is copied from the first of the given arrays. Number of components
3936  * in the given arrays must be  the same.
3937  *  \param [in] a1 - an array to include in the result array.
3938  *  \param [in] a2 - another array to include in the result array.
3939  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
3940  *          The caller is to delete this result array using decrRef() as it is no more
3941  *          needed.
3942  *  \throw If both \a a1 and \a a2 are NULL.
3943  *  \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents().
3944  */
3945 DataArrayDouble *DataArrayDouble::Aggregate(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception)
3946 {
3947   std::vector<const DataArrayDouble *> tmp(2);
3948   tmp[0]=a1; tmp[1]=a2;
3949   return Aggregate(tmp);
3950 }
3951
3952 /*!
3953  * Returns a new DataArrayDouble by concatenating all given arrays, so that (1) the number
3954  * of tuples in the result array is a sum of the number of tuples of given arrays and (2)
3955  * the number of component in the result array is same as that of each of given arrays.
3956  * Info on components is copied from the first of the given arrays. Number of components
3957  * in the given arrays must be  the same.
3958  *  \param [in] arr - a sequence of arrays to include in the result array.
3959  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
3960  *          The caller is to delete this result array using decrRef() as it is no more
3961  *          needed.
3962  *  \throw If all arrays within \a arr are NULL.
3963  *  \throw If getNumberOfComponents() of arrays within \a arr.
3964  */
3965 DataArrayDouble *DataArrayDouble::Aggregate(const std::vector<const DataArrayDouble *>& arr) throw(INTERP_KERNEL::Exception)
3966 {
3967   std::vector<const DataArrayDouble *> a;
3968   for(std::vector<const DataArrayDouble *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
3969     if(*it4)
3970       a.push_back(*it4);
3971   if(a.empty())
3972     throw INTERP_KERNEL::Exception("DataArrayDouble::Aggregate : input list must contain at least one NON EMPTY DataArrayDouble !");
3973   std::vector<const DataArrayDouble *>::const_iterator it=a.begin();
3974   int nbOfComp=(*it)->getNumberOfComponents();
3975   int nbt=(*it++)->getNumberOfTuples();
3976   for(int i=1;it!=a.end();it++,i++)
3977     {
3978       if((*it)->getNumberOfComponents()!=nbOfComp)
3979         throw INTERP_KERNEL::Exception("DataArrayDouble::Aggregate : Nb of components mismatch for array aggregation !");
3980       nbt+=(*it)->getNumberOfTuples();
3981     }
3982   DataArrayDouble *ret=DataArrayDouble::New();
3983   ret->alloc(nbt,nbOfComp);
3984   double *pt=ret->getPointer();
3985   for(it=a.begin();it!=a.end();it++)
3986     pt=std::copy((*it)->getConstPointer(),(*it)->getConstPointer()+(*it)->getNbOfElems(),pt);
3987   ret->copyStringInfoFrom(*(a[0]));
3988   return ret;
3989 }
3990
3991 /*!
3992  * Returns a new DataArrayDouble by aggregating two given arrays, so that (1) the number
3993  * of components in the result array is a sum of the number of components of given arrays
3994  * and (2) the number of tuples in the result array is same as that of each of given
3995  * arrays. In other words the i-th tuple of result array includes all components of
3996  * i-th tuples of all given arrays.
3997  * Number of tuples in the given arrays must be  the same.
3998  *  \param [in] a1 - an array to include in the result array.
3999  *  \param [in] a2 - another array to include in the result array.
4000  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4001  *          The caller is to delete this result array using decrRef() as it is no more
4002  *          needed.
4003  *  \throw If both \a a1 and \a a2 are NULL.
4004  *  \throw If any given array is not allocated.
4005  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
4006  */
4007 DataArrayDouble *DataArrayDouble::Meld(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception)
4008 {
4009   std::vector<const DataArrayDouble *> arr(2);
4010   arr[0]=a1; arr[1]=a2;
4011   return Meld(arr);
4012 }
4013
4014 /*!
4015  * Returns a new DataArrayDouble by aggregating all given arrays, so that (1) the number
4016  * of components in the result array is a sum of the number of components of given arrays
4017  * and (2) the number of tuples in the result array is same as that of each of given
4018  * arrays. In other words the i-th tuple of result array includes all components of
4019  * i-th tuples of all given arrays.
4020  * Number of tuples in the given arrays must be  the same.
4021  *  \param [in] arr - a sequence of arrays to include in the result array.
4022  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4023  *          The caller is to delete this result array using decrRef() as it is no more
4024  *          needed.
4025  *  \throw If all arrays within \a arr are NULL.
4026  *  \throw If any given array is not allocated.
4027  *  \throw If getNumberOfTuples() of arrays within \a arr is different.
4028  */
4029 DataArrayDouble *DataArrayDouble::Meld(const std::vector<const DataArrayDouble *>& arr) throw(INTERP_KERNEL::Exception)
4030 {
4031   std::vector<const DataArrayDouble *> a;
4032   for(std::vector<const DataArrayDouble *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
4033     if(*it4)
4034       a.push_back(*it4);
4035   if(a.empty())
4036     throw INTERP_KERNEL::Exception("DataArrayDouble::Meld : input list must contain at least one NON EMPTY DataArrayDouble !");
4037   std::vector<const DataArrayDouble *>::const_iterator it;
4038   for(it=a.begin();it!=a.end();it++)
4039     (*it)->checkAllocated();
4040   it=a.begin();
4041   int nbOfTuples=(*it)->getNumberOfTuples();
4042   std::vector<int> nbc(a.size());
4043   std::vector<const double *> pts(a.size());
4044   nbc[0]=(*it)->getNumberOfComponents();
4045   pts[0]=(*it++)->getConstPointer();
4046   for(int i=1;it!=a.end();it++,i++)
4047     {
4048       if(nbOfTuples!=(*it)->getNumberOfTuples())
4049         throw INTERP_KERNEL::Exception("DataArrayDouble::Meld : mismatch of number of tuples !");
4050       nbc[i]=(*it)->getNumberOfComponents();
4051       pts[i]=(*it)->getConstPointer();
4052     }
4053   int totalNbOfComp=std::accumulate(nbc.begin(),nbc.end(),0);
4054   DataArrayDouble *ret=DataArrayDouble::New();
4055   ret->alloc(nbOfTuples,totalNbOfComp);
4056   double *retPtr=ret->getPointer();
4057   for(int i=0;i<nbOfTuples;i++)
4058     for(int j=0;j<(int)a.size();j++)
4059       {
4060         retPtr=std::copy(pts[j],pts[j]+nbc[j],retPtr);
4061         pts[j]+=nbc[j];
4062       }
4063   int k=0;
4064   for(int i=0;i<(int)a.size();i++)
4065     for(int j=0;j<nbc[i];j++,k++)
4066       ret->setInfoOnComponent(k,a[i]->getInfoOnComponent(j).c_str());
4067   return ret;
4068 }
4069
4070 /*!
4071  * Returns a new DataArrayDouble containing a dot product of two given arrays, so that
4072  * the i-th tuple of the result array is a sum of products of j-th components of i-th
4073  * tuples of given arrays (\f$ a_i = \sum_{j=1}^n a1_j * a2_j \f$).
4074  * Info on components and name is copied from the first of the given arrays.
4075  * Number of tuples and components in the given arrays must be the same.
4076  *  \param [in] a1 - a given array.
4077  *  \param [in] a2 - another given array.
4078  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4079  *          The caller is to delete this result array using decrRef() as it is no more
4080  *          needed.
4081  *  \throw If either \a a1 or \a a2 is NULL.
4082  *  \throw If any given array is not allocated.
4083  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
4084  *  \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents()
4085  */
4086 DataArrayDouble *DataArrayDouble::Dot(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception)
4087 {
4088   if(!a1 || !a2)
4089     throw INTERP_KERNEL::Exception("DataArrayDouble::Dot : input DataArrayDouble instance is NULL !");
4090   a1->checkAllocated();
4091   a2->checkAllocated();
4092   int nbOfComp=a1->getNumberOfComponents();
4093   if(nbOfComp!=a2->getNumberOfComponents())
4094     throw INTERP_KERNEL::Exception("Nb of components mismatch for array Dot !");
4095   int nbOfTuple=a1->getNumberOfTuples();
4096   if(nbOfTuple!=a2->getNumberOfTuples())
4097     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Dot !");
4098   DataArrayDouble *ret=DataArrayDouble::New();
4099   ret->alloc(nbOfTuple,1);
4100   double *retPtr=ret->getPointer();
4101   const double *a1Ptr=a1->getConstPointer();
4102   const double *a2Ptr=a2->getConstPointer();
4103   for(int i=0;i<nbOfTuple;i++)
4104     {
4105       double sum=0.;
4106       for(int j=0;j<nbOfComp;j++)
4107         sum+=a1Ptr[i*nbOfComp+j]*a2Ptr[i*nbOfComp+j];
4108       retPtr[i]=sum;
4109     }
4110   ret->setInfoOnComponent(0,a1->getInfoOnComponent(0).c_str());
4111   ret->setName(a1->getName().c_str());
4112   return ret;
4113 }
4114
4115 /*!
4116  * Returns a new DataArrayDouble containing a cross product of two given arrays, so that
4117  * the i-th tuple of the result array contains 3 components of a vector which is a cross
4118  * product of two vectors defined by the i-th tuples of given arrays.
4119  * Info on components is copied from the first of the given arrays.
4120  * Number of tuples in the given arrays must be the same.
4121  * Number of components in the given arrays must be 3.
4122  *  \param [in] a1 - a given array.
4123  *  \param [in] a2 - another given array.
4124  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4125  *          The caller is to delete this result array using decrRef() as it is no more
4126  *          needed.
4127  *  \throw If either \a a1 or \a a2 is NULL.
4128  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
4129  *  \throw If \a a1->getNumberOfComponents() != 3
4130  *  \throw If \a a2->getNumberOfComponents() != 3
4131  */
4132 DataArrayDouble *DataArrayDouble::CrossProduct(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception)
4133 {
4134   if(!a1 || !a2)
4135     throw INTERP_KERNEL::Exception("DataArrayDouble::CrossProduct : input DataArrayDouble instance is NULL !");
4136   int nbOfComp=a1->getNumberOfComponents();
4137   if(nbOfComp!=a2->getNumberOfComponents())
4138     throw INTERP_KERNEL::Exception("Nb of components mismatch for array crossProduct !");
4139   if(nbOfComp!=3)
4140     throw INTERP_KERNEL::Exception("Nb of components must be equal to 3 for array crossProduct !");
4141   int nbOfTuple=a1->getNumberOfTuples();
4142   if(nbOfTuple!=a2->getNumberOfTuples())
4143     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array crossProduct !");
4144   DataArrayDouble *ret=DataArrayDouble::New();
4145   ret->alloc(nbOfTuple,3);
4146   double *retPtr=ret->getPointer();
4147   const double *a1Ptr=a1->getConstPointer();
4148   const double *a2Ptr=a2->getConstPointer();
4149   for(int i=0;i<nbOfTuple;i++)
4150     {
4151       retPtr[3*i]=a1Ptr[3*i+1]*a2Ptr[3*i+2]-a1Ptr[3*i+2]*a2Ptr[3*i+1];
4152       retPtr[3*i+1]=a1Ptr[3*i+2]*a2Ptr[3*i]-a1Ptr[3*i]*a2Ptr[3*i+2];
4153       retPtr[3*i+2]=a1Ptr[3*i]*a2Ptr[3*i+1]-a1Ptr[3*i+1]*a2Ptr[3*i];
4154     }
4155   ret->copyStringInfoFrom(*a1);
4156   return ret;
4157 }
4158
4159 /*!
4160  * Returns a new DataArrayDouble containing maximal values of two given arrays.
4161  * Info on components is copied from the first of the given arrays.
4162  * Number of tuples and components in the given arrays must be the same.
4163  *  \param [in] a1 - an array to compare values with another one.
4164  *  \param [in] a2 - another array to compare values with the first one.
4165  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4166  *          The caller is to delete this result array using decrRef() as it is no more
4167  *          needed.
4168  *  \throw If either \a a1 or \a a2 is NULL.
4169  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
4170  *  \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents()
4171  */
4172 DataArrayDouble *DataArrayDouble::Max(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception)
4173 {
4174   if(!a1 || !a2)
4175     throw INTERP_KERNEL::Exception("DataArrayDouble::Max : input DataArrayDouble instance is NULL !");
4176   int nbOfComp=a1->getNumberOfComponents();
4177   if(nbOfComp!=a2->getNumberOfComponents())
4178     throw INTERP_KERNEL::Exception("Nb of components mismatch for array Max !");
4179   int nbOfTuple=a1->getNumberOfTuples();
4180   if(nbOfTuple!=a2->getNumberOfTuples())
4181     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Max !");
4182   DataArrayDouble *ret=DataArrayDouble::New();
4183   ret->alloc(nbOfTuple,nbOfComp);
4184   double *retPtr=ret->getPointer();
4185   const double *a1Ptr=a1->getConstPointer();
4186   const double *a2Ptr=a2->getConstPointer();
4187   int nbElem=nbOfTuple*nbOfComp;
4188   for(int i=0;i<nbElem;i++)
4189     retPtr[i]=std::max(a1Ptr[i],a2Ptr[i]);
4190   ret->copyStringInfoFrom(*a1);
4191   return ret;
4192 }
4193
4194 /*!
4195  * Returns a new DataArrayDouble containing minimal values of two given arrays.
4196  * Info on components is copied from the first of the given arrays.
4197  * Number of tuples and components in the given arrays must be the same.
4198  *  \param [in] a1 - an array to compare values with another one.
4199  *  \param [in] a2 - another array to compare values with the first one.
4200  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4201  *          The caller is to delete this result array using decrRef() as it is no more
4202  *          needed.
4203  *  \throw If either \a a1 or \a a2 is NULL.
4204  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
4205  *  \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents()
4206  */
4207 DataArrayDouble *DataArrayDouble::Min(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception)
4208 {
4209   if(!a1 || !a2)
4210     throw INTERP_KERNEL::Exception("DataArrayDouble::Min : input DataArrayDouble instance is NULL !");
4211   int nbOfComp=a1->getNumberOfComponents();
4212   if(nbOfComp!=a2->getNumberOfComponents())
4213     throw INTERP_KERNEL::Exception("Nb of components mismatch for array min !");
4214   int nbOfTuple=a1->getNumberOfTuples();
4215   if(nbOfTuple!=a2->getNumberOfTuples())
4216     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array min !");
4217   DataArrayDouble *ret=DataArrayDouble::New();
4218   ret->alloc(nbOfTuple,nbOfComp);
4219   double *retPtr=ret->getPointer();
4220   const double *a1Ptr=a1->getConstPointer();
4221   const double *a2Ptr=a2->getConstPointer();
4222   int nbElem=nbOfTuple*nbOfComp;
4223   for(int i=0;i<nbElem;i++)
4224     retPtr[i]=std::min(a1Ptr[i],a2Ptr[i]);
4225   ret->copyStringInfoFrom(*a1);
4226   return ret;
4227 }
4228
4229 /*!
4230  * Returns a new DataArrayDouble that is a sum of two given arrays. There are 3
4231  * valid cases.
4232  * 1.  The arrays have same number of tuples and components. Then each value of
4233  *   the result array (_a_) is a sum of the corresponding values of \a a1 and \a a2,
4234  *   i.e.: _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ i, j ].
4235  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
4236  *   component. Then
4237  *   _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ i, 0 ].
4238  * 3.  The arrays have same number of components and one array, say _a2_, has one
4239  *   tuple. Then
4240  *   _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ 0, j ].
4241  *
4242  * Info on components is copied either from the first array (in the first case) or from
4243  * the array with maximal number of elements (getNbOfElems()).
4244  *  \param [in] a1 - an array to sum up.
4245  *  \param [in] a2 - another array to sum up.
4246  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4247  *          The caller is to delete this result array using decrRef() as it is no more
4248  *          needed.
4249  *  \throw If either \a a1 or \a a2 is NULL.
4250  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
4251  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
4252  *         none of them has number of tuples or components equal to 1.
4253  */
4254 DataArrayDouble *DataArrayDouble::Add(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception)
4255 {
4256   if(!a1 || !a2)
4257     throw INTERP_KERNEL::Exception("DataArrayDouble::Add : input DataArrayDouble instance is NULL !");
4258   int nbOfTuple=a1->getNumberOfTuples();
4259   int nbOfTuple2=a2->getNumberOfTuples();
4260   int nbOfComp=a1->getNumberOfComponents();
4261   int nbOfComp2=a2->getNumberOfComponents();
4262   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=0;
4263   if(nbOfTuple==nbOfTuple2)
4264     {
4265       if(nbOfComp==nbOfComp2)
4266         {
4267           ret=DataArrayDouble::New();
4268           ret->alloc(nbOfTuple,nbOfComp);
4269           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::plus<double>());
4270           ret->copyStringInfoFrom(*a1);
4271         }
4272       else
4273         {
4274           int nbOfCompMin,nbOfCompMax;
4275           const DataArrayDouble *aMin, *aMax;
4276           if(nbOfComp>nbOfComp2)
4277             {
4278               nbOfCompMin=nbOfComp2; nbOfCompMax=nbOfComp;
4279               aMin=a2; aMax=a1;
4280             }
4281           else
4282             {
4283               nbOfCompMin=nbOfComp; nbOfCompMax=nbOfComp2;
4284               aMin=a1; aMax=a2;
4285             }
4286           if(nbOfCompMin==1)
4287             {
4288               ret=DataArrayDouble::New();
4289               ret->alloc(nbOfTuple,nbOfCompMax);
4290               const double *aMinPtr=aMin->getConstPointer();
4291               const double *aMaxPtr=aMax->getConstPointer();
4292               double *res=ret->getPointer();
4293               for(int i=0;i<nbOfTuple;i++)
4294                 res=std::transform(aMaxPtr+i*nbOfCompMax,aMaxPtr+(i+1)*nbOfCompMax,res,std::bind2nd(std::plus<double>(),aMinPtr[i]));
4295               ret->copyStringInfoFrom(*aMax);
4296             }
4297           else
4298             throw INTERP_KERNEL::Exception("Nb of components mismatch for array Add !");
4299         }
4300     }
4301   else if((nbOfTuple==1 && nbOfTuple2>1) || (nbOfTuple>1 && nbOfTuple2==1))
4302     {
4303       if(nbOfComp==nbOfComp2)
4304         {
4305           int nbOfTupleMax=std::max(nbOfTuple,nbOfTuple2);
4306           const DataArrayDouble *aMin=nbOfTuple>nbOfTuple2?a2:a1;
4307           const DataArrayDouble *aMax=nbOfTuple>nbOfTuple2?a1:a2;
4308           const double *aMinPtr=aMin->getConstPointer(),*aMaxPtr=aMax->getConstPointer();
4309           ret=DataArrayDouble::New();
4310           ret->alloc(nbOfTupleMax,nbOfComp);
4311           double *res=ret->getPointer();
4312           for(int i=0;i<nbOfTupleMax;i++)
4313             res=std::transform(aMaxPtr+i*nbOfComp,aMaxPtr+(i+1)*nbOfComp,aMinPtr,res,std::plus<double>());
4314           ret->copyStringInfoFrom(*aMax);
4315         }
4316       else
4317         throw INTERP_KERNEL::Exception("Nb of components mismatch for array Add !");
4318     }
4319   else
4320     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Add !");
4321   return ret.retn();
4322 }
4323
4324 /*!
4325  * Adds values of another DataArrayDouble to values of \a this one. There are 3
4326  * valid cases.
4327  * 1.  The arrays have same number of tuples and components. Then each value of
4328  *   \a other array is added to the corresponding value of \a this array, i.e.:
4329  *   _a_ [ i, j ] += _other_ [ i, j ].
4330  * 2.  The arrays have same number of tuples and \a other array has one component. Then
4331  *   _a_ [ i, j ] += _other_ [ i, 0 ].
4332  * 3.  The arrays have same number of components and \a other array has one tuple. Then
4333  *   _a_ [ i, j ] += _a2_ [ 0, j ].
4334  *
4335  *  \param [in] other - an array to add to \a this one.
4336  *  \throw If \a other is NULL.
4337  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
4338  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
4339  *         \a other has number of both tuples and components not equal to 1.
4340  */
4341 void DataArrayDouble::addEqual(const DataArrayDouble *other) throw(INTERP_KERNEL::Exception)
4342 {
4343   if(!other)
4344     throw INTERP_KERNEL::Exception("DataArrayDouble::addEqual : input DataArrayDouble instance is NULL !");
4345   const char *msg="Nb of tuples mismatch for DataArrayDouble::addEqual  !";
4346   checkAllocated();
4347   other->checkAllocated();
4348   int nbOfTuple=getNumberOfTuples();
4349   int nbOfTuple2=other->getNumberOfTuples();
4350   int nbOfComp=getNumberOfComponents();
4351   int nbOfComp2=other->getNumberOfComponents();
4352   if(nbOfTuple==nbOfTuple2)
4353     {
4354       if(nbOfComp==nbOfComp2)
4355         {
4356           std::transform(begin(),end(),other->begin(),getPointer(),std::plus<double>());
4357         }
4358       else if(nbOfComp2==1)
4359         {
4360           double *ptr=getPointer();
4361           const double *ptrc=other->getConstPointer();
4362           for(int i=0;i<nbOfTuple;i++)
4363             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::plus<double>(),*ptrc++));
4364         }
4365       else
4366         throw INTERP_KERNEL::Exception(msg);
4367     }
4368   else if(nbOfTuple2==1)
4369     {
4370       if(nbOfComp2==nbOfComp)
4371         {
4372           double *ptr=getPointer();
4373           const double *ptrc=other->getConstPointer();
4374           for(int i=0;i<nbOfTuple;i++)
4375             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::plus<double>());
4376         }
4377       else
4378         throw INTERP_KERNEL::Exception(msg);
4379     }
4380   else
4381     throw INTERP_KERNEL::Exception(msg);
4382   declareAsNew();
4383 }
4384
4385 /*!
4386  * Returns a new DataArrayDouble that is a subtraction of two given arrays. There are 3
4387  * valid cases.
4388  * 1.  The arrays have same number of tuples and components. Then each value of
4389  *   the result array (_a_) is a subtraction of the corresponding values of \a a1 and
4390  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ i, j ].
4391  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
4392  *   component. Then
4393  *   _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ i, 0 ].
4394  * 3.  The arrays have same number of components and one array, say _a2_, has one
4395  *   tuple. Then
4396  *   _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ 0, j ].
4397  *
4398  * Info on components is copied either from the first array (in the first case) or from
4399  * the array with maximal number of elements (getNbOfElems()).
4400  *  \param [in] a1 - an array to subtract from.
4401  *  \param [in] a2 - an array to subtract.
4402  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4403  *          The caller is to delete this result array using decrRef() as it is no more
4404  *          needed.
4405  *  \throw If either \a a1 or \a a2 is NULL.
4406  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
4407  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
4408  *         none of them has number of tuples or components equal to 1.
4409  */
4410 DataArrayDouble *DataArrayDouble::Substract(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception)
4411 {
4412   if(!a1 || !a2)
4413     throw INTERP_KERNEL::Exception("DataArrayDouble::Substract : input DataArrayDouble instance is NULL !");
4414   int nbOfTuple1=a1->getNumberOfTuples();
4415   int nbOfTuple2=a2->getNumberOfTuples();
4416   int nbOfComp1=a1->getNumberOfComponents();
4417   int nbOfComp2=a2->getNumberOfComponents();
4418   if(nbOfTuple2==nbOfTuple1)
4419     {
4420       if(nbOfComp1==nbOfComp2)
4421         {
4422           MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
4423           ret->alloc(nbOfTuple2,nbOfComp1);
4424           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::minus<double>());
4425           ret->copyStringInfoFrom(*a1);
4426           return ret.retn();
4427         }
4428       else if(nbOfComp2==1)
4429         {
4430           MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
4431           ret->alloc(nbOfTuple1,nbOfComp1);
4432           const double *a2Ptr=a2->getConstPointer();
4433           const double *a1Ptr=a1->getConstPointer();
4434           double *res=ret->getPointer();
4435           for(int i=0;i<nbOfTuple1;i++)
4436             res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::minus<double>(),a2Ptr[i]));
4437           ret->copyStringInfoFrom(*a1);
4438           return ret.retn();
4439         }
4440       else
4441         {
4442           a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Substract !");
4443           return 0;
4444         }
4445     }
4446   else if(nbOfTuple2==1)
4447     {
4448       a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Substract !");
4449       MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
4450       ret->alloc(nbOfTuple1,nbOfComp1);
4451       const double *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
4452       double *pt=ret->getPointer();
4453       for(int i=0;i<nbOfTuple1;i++)
4454         pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::minus<double>());
4455       ret->copyStringInfoFrom(*a1);
4456       return ret.retn();
4457     }
4458   else
4459     {
4460       a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Substract !");//will always throw an exception
4461       return 0;
4462     }
4463 }
4464
4465 /*!
4466  * Subtract values of another DataArrayDouble from values of \a this one. There are 3
4467  * valid cases.
4468  * 1.  The arrays have same number of tuples and components. Then each value of
4469  *   \a other array is subtracted from the corresponding value of \a this array, i.e.:
4470  *   _a_ [ i, j ] -= _other_ [ i, j ].
4471  * 2.  The arrays have same number of tuples and \a other array has one component. Then
4472  *   _a_ [ i, j ] -= _other_ [ i, 0 ].
4473  * 3.  The arrays have same number of components and \a other array has one tuple. Then
4474  *   _a_ [ i, j ] -= _a2_ [ 0, j ].
4475  *
4476  *  \param [in] other - an array to subtract from \a this one.
4477  *  \throw If \a other is NULL.
4478  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
4479  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
4480  *         \a other has number of both tuples and components not equal to 1.
4481  */
4482 void DataArrayDouble::substractEqual(const DataArrayDouble *other) throw(INTERP_KERNEL::Exception)
4483 {
4484   if(!other)
4485     throw INTERP_KERNEL::Exception("DataArrayDouble::substractEqual : input DataArrayDouble instance is NULL !");
4486   const char *msg="Nb of tuples mismatch for DataArrayDouble::substractEqual  !";
4487   checkAllocated();
4488   other->checkAllocated();
4489   int nbOfTuple=getNumberOfTuples();
4490   int nbOfTuple2=other->getNumberOfTuples();
4491   int nbOfComp=getNumberOfComponents();
4492   int nbOfComp2=other->getNumberOfComponents();
4493   if(nbOfTuple==nbOfTuple2)
4494     {
4495       if(nbOfComp==nbOfComp2)
4496         {
4497           std::transform(begin(),end(),other->begin(),getPointer(),std::minus<double>());
4498         }
4499       else if(nbOfComp2==1)
4500         {
4501           double *ptr=getPointer();
4502           const double *ptrc=other->getConstPointer();
4503           for(int i=0;i<nbOfTuple;i++)
4504             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::minus<double>(),*ptrc++)); 
4505         }
4506       else
4507         throw INTERP_KERNEL::Exception(msg);
4508     }
4509   else if(nbOfTuple2==1)
4510     {
4511       if(nbOfComp2==nbOfComp)
4512         {
4513           double *ptr=getPointer();
4514           const double *ptrc=other->getConstPointer();
4515           for(int i=0;i<nbOfTuple;i++)
4516             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::minus<double>());
4517         }
4518       else
4519         throw INTERP_KERNEL::Exception(msg);
4520     }
4521   else
4522     throw INTERP_KERNEL::Exception(msg);
4523   declareAsNew();
4524 }
4525
4526 /*!
4527  * Returns a new DataArrayDouble that is a product of two given arrays. There are 3
4528  * valid cases.
4529  * 1.  The arrays have same number of tuples and components. Then each value of
4530  *   the result array (_a_) is a product of the corresponding values of \a a1 and
4531  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ i, j ].
4532  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
4533  *   component. Then
4534  *   _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ i, 0 ].
4535  * 3.  The arrays have same number of components and one array, say _a2_, has one
4536  *   tuple. Then
4537  *   _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ 0, j ].
4538  *
4539  * Info on components is copied either from the first array (in the first case) or from
4540  * the array with maximal number of elements (getNbOfElems()).
4541  *  \param [in] a1 - a factor array.
4542  *  \param [in] a2 - another factor array.
4543  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4544  *          The caller is to delete this result array using decrRef() as it is no more
4545  *          needed.
4546  *  \throw If either \a a1 or \a a2 is NULL.
4547  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
4548  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
4549  *         none of them has number of tuples or components equal to 1.
4550  */
4551 DataArrayDouble *DataArrayDouble::Multiply(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception)
4552 {
4553   if(!a1 || !a2)
4554     throw INTERP_KERNEL::Exception("DataArrayDouble::Multiply : input DataArrayDouble instance is NULL !");
4555   int nbOfTuple=a1->getNumberOfTuples();
4556   int nbOfTuple2=a2->getNumberOfTuples();
4557   int nbOfComp=a1->getNumberOfComponents();
4558   int nbOfComp2=a2->getNumberOfComponents();
4559   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=0;
4560   if(nbOfTuple==nbOfTuple2)
4561     {
4562       if(nbOfComp==nbOfComp2)
4563         {
4564           ret=DataArrayDouble::New();
4565           ret->alloc(nbOfTuple,nbOfComp);
4566           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::multiplies<double>());
4567           ret->copyStringInfoFrom(*a1);
4568         }
4569       else
4570         {
4571           int nbOfCompMin,nbOfCompMax;
4572           const DataArrayDouble *aMin, *aMax;
4573           if(nbOfComp>nbOfComp2)
4574             {
4575               nbOfCompMin=nbOfComp2; nbOfCompMax=nbOfComp;
4576               aMin=a2; aMax=a1;
4577             }
4578           else
4579             {
4580               nbOfCompMin=nbOfComp; nbOfCompMax=nbOfComp2;
4581               aMin=a1; aMax=a2;
4582             }
4583           if(nbOfCompMin==1)
4584             {
4585               ret=DataArrayDouble::New();
4586               ret->alloc(nbOfTuple,nbOfCompMax);
4587               const double *aMinPtr=aMin->getConstPointer();
4588               const double *aMaxPtr=aMax->getConstPointer();
4589               double *res=ret->getPointer();
4590               for(int i=0;i<nbOfTuple;i++)
4591                 res=std::transform(aMaxPtr+i*nbOfCompMax,aMaxPtr+(i+1)*nbOfCompMax,res,std::bind2nd(std::multiplies<double>(),aMinPtr[i]));
4592               ret->copyStringInfoFrom(*aMax);
4593             }
4594           else
4595             throw INTERP_KERNEL::Exception("Nb of components mismatch for array Multiply !");
4596         }
4597     }
4598   else if((nbOfTuple==1 && nbOfTuple2>1) || (nbOfTuple>1 && nbOfTuple2==1))
4599     {
4600       if(nbOfComp==nbOfComp2)
4601         {
4602           int nbOfTupleMax=std::max(nbOfTuple,nbOfTuple2);
4603           const DataArrayDouble *aMin=nbOfTuple>nbOfTuple2?a2:a1;
4604           const DataArrayDouble *aMax=nbOfTuple>nbOfTuple2?a1:a2;
4605           const double *aMinPtr=aMin->getConstPointer(),*aMaxPtr=aMax->getConstPointer();
4606           ret=DataArrayDouble::New();
4607           ret->alloc(nbOfTupleMax,nbOfComp);
4608           double *res=ret->getPointer();
4609           for(int i=0;i<nbOfTupleMax;i++)
4610             res=std::transform(aMaxPtr+i*nbOfComp,aMaxPtr+(i+1)*nbOfComp,aMinPtr,res,std::multiplies<double>());
4611           ret->copyStringInfoFrom(*aMax);
4612         }
4613       else
4614         throw INTERP_KERNEL::Exception("Nb of components mismatch for array Multiply !");
4615     }
4616   else
4617     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Multiply !");
4618   return ret.retn();
4619 }
4620
4621 /*!
4622  * Multiply values of another DataArrayDouble to values of \a this one. There are 3
4623  * valid cases.
4624  * 1.  The arrays have same number of tuples and components. Then each value of
4625  *   \a other array is multiplied to the corresponding value of \a this array, i.e.:
4626  *   _a_ [ i, j ] *= _other_ [ i, j ].
4627  * 2.  The arrays have same number of tuples and \a other array has one component. Then
4628  *   _a_ [ i, j ] *= _other_ [ i, 0 ].
4629  * 3.  The arrays have same number of components and \a other array has one tuple. Then
4630  *   _a_ [ i, j ] *= _a2_ [ 0, j ].
4631  *
4632  *  \param [in] other - an array to multiply to \a this one.
4633  *  \throw If \a other is NULL.
4634  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
4635  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
4636  *         \a other has number of both tuples and components not equal to 1.
4637  */
4638 void DataArrayDouble::multiplyEqual(const DataArrayDouble *other) throw(INTERP_KERNEL::Exception)
4639 {
4640   if(!other)
4641     throw INTERP_KERNEL::Exception("DataArrayDouble::multiplyEqual : input DataArrayDouble instance is NULL !");
4642   const char *msg="Nb of tuples mismatch for DataArrayDouble::multiplyEqual !";
4643   checkAllocated();
4644   other->checkAllocated();
4645   int nbOfTuple=getNumberOfTuples();
4646   int nbOfTuple2=other->getNumberOfTuples();
4647   int nbOfComp=getNumberOfComponents();
4648   int nbOfComp2=other->getNumberOfComponents();
4649   if(nbOfTuple==nbOfTuple2)
4650     {
4651       if(nbOfComp==nbOfComp2)
4652         {
4653           std::transform(begin(),end(),other->begin(),getPointer(),std::multiplies<double>());
4654         }
4655       else if(nbOfComp2==1)
4656         {
4657           double *ptr=getPointer();
4658           const double *ptrc=other->getConstPointer();
4659           for(int i=0;i<nbOfTuple;i++)
4660             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::multiplies<double>(),*ptrc++));
4661         }
4662       else
4663         throw INTERP_KERNEL::Exception(msg);
4664     }
4665   else if(nbOfTuple2==1)
4666     {
4667       if(nbOfComp2==nbOfComp)
4668         {
4669           double *ptr=getPointer();
4670           const double *ptrc=other->getConstPointer();
4671           for(int i=0;i<nbOfTuple;i++)
4672             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::multiplies<double>());
4673         }
4674       else
4675         throw INTERP_KERNEL::Exception(msg);
4676     }
4677   else
4678     throw INTERP_KERNEL::Exception(msg);
4679   declareAsNew();
4680 }
4681
4682 /*!
4683  * Returns a new DataArrayDouble that is a division of two given arrays. There are 3
4684  * valid cases.
4685  * 1.  The arrays have same number of tuples and components. Then each value of
4686  *   the result array (_a_) is a division of the corresponding values of \a a1 and
4687  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ i, j ].
4688  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
4689  *   component. Then
4690  *   _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ i, 0 ].
4691  * 3.  The arrays have same number of components and one array, say _a2_, has one
4692  *   tuple. Then
4693  *   _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ 0, j ].
4694  *
4695  * Info on components is copied either from the first array (in the first case) or from
4696  * the array with maximal number of elements (getNbOfElems()).
4697  *  \param [in] a1 - a numerator array.
4698  *  \param [in] a2 - a denominator array.
4699  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4700  *          The caller is to delete this result array using decrRef() as it is no more
4701  *          needed.
4702  *  \throw If either \a a1 or \a a2 is NULL.
4703  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
4704  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
4705  *         none of them has number of tuples or components equal to 1.
4706  *  \warning No check of division by zero is performed!
4707  */
4708 DataArrayDouble *DataArrayDouble::Divide(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception)
4709 {
4710   if(!a1 || !a2)
4711     throw INTERP_KERNEL::Exception("DataArrayDouble::Divide : input DataArrayDouble instance is NULL !");
4712   int nbOfTuple1=a1->getNumberOfTuples();
4713   int nbOfTuple2=a2->getNumberOfTuples();
4714   int nbOfComp1=a1->getNumberOfComponents();
4715   int nbOfComp2=a2->getNumberOfComponents();
4716   if(nbOfTuple2==nbOfTuple1)
4717     {
4718       if(nbOfComp1==nbOfComp2)
4719         {
4720           MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
4721           ret->alloc(nbOfTuple2,nbOfComp1);
4722           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::divides<double>());
4723           ret->copyStringInfoFrom(*a1);
4724           return ret.retn();
4725         }
4726       else if(nbOfComp2==1)
4727         {
4728           MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
4729           ret->alloc(nbOfTuple1,nbOfComp1);
4730           const double *a2Ptr=a2->getConstPointer();
4731           const double *a1Ptr=a1->getConstPointer();
4732           double *res=ret->getPointer();
4733           for(int i=0;i<nbOfTuple1;i++)
4734             res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::divides<double>(),a2Ptr[i]));
4735           ret->copyStringInfoFrom(*a1);
4736           return ret.retn();
4737         }
4738       else
4739         {
4740           a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Divide !");
4741           return 0;
4742         }
4743     }
4744   else if(nbOfTuple2==1)
4745     {
4746       a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Divide !");
4747       MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
4748       ret->alloc(nbOfTuple1,nbOfComp1);
4749       const double *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
4750       double *pt=ret->getPointer();
4751       for(int i=0;i<nbOfTuple1;i++)
4752         pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::divides<double>());
4753       ret->copyStringInfoFrom(*a1);
4754       return ret.retn();
4755     }
4756   else
4757     {
4758       a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Divide !");//will always throw an exception
4759       return 0;
4760     }
4761 }
4762
4763 /*!
4764  * Divide values of \a this array by values of another DataArrayDouble. There are 3
4765  * valid cases.
4766  * 1.  The arrays have same number of tuples and components. Then each value of
4767  *    \a this array is divided by the corresponding value of \a other one, i.e.:
4768  *   _a_ [ i, j ] /= _other_ [ i, j ].
4769  * 2.  The arrays have same number of tuples and \a other array has one component. Then
4770  *   _a_ [ i, j ] /= _other_ [ i, 0 ].
4771  * 3.  The arrays have same number of components and \a other array has one tuple. Then
4772  *   _a_ [ i, j ] /= _a2_ [ 0, j ].
4773  *
4774  *  \param [in] other - an array to divide \a this one by.
4775  *  \throw If \a other is NULL.
4776  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
4777  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
4778  *         \a other has number of both tuples and components not equal to 1.
4779  *  \warning No check of division by zero is performed!
4780  */
4781 void DataArrayDouble::divideEqual(const DataArrayDouble *other) throw(INTERP_KERNEL::Exception)
4782 {
4783   if(!other)
4784     throw INTERP_KERNEL::Exception("DataArrayDouble::divideEqual : input DataArrayDouble instance is NULL !");
4785   const char *msg="Nb of tuples mismatch for DataArrayDouble::divideEqual !";
4786   checkAllocated();
4787   other->checkAllocated();
4788   int nbOfTuple=getNumberOfTuples();
4789   int nbOfTuple2=other->getNumberOfTuples();
4790   int nbOfComp=getNumberOfComponents();
4791   int nbOfComp2=other->getNumberOfComponents();
4792   if(nbOfTuple==nbOfTuple2)
4793     {
4794       if(nbOfComp==nbOfComp2)
4795         {
4796           std::transform(begin(),end(),other->begin(),getPointer(),std::divides<double>());
4797         }
4798       else if(nbOfComp2==1)
4799         {
4800           double *ptr=getPointer();
4801           const double *ptrc=other->getConstPointer();
4802           for(int i=0;i<nbOfTuple;i++)
4803             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::divides<double>(),*ptrc++));
4804         }
4805       else
4806         throw INTERP_KERNEL::Exception(msg);
4807     }
4808   else if(nbOfTuple2==1)
4809     {
4810       if(nbOfComp2==nbOfComp)
4811         {
4812           double *ptr=getPointer();
4813           const double *ptrc=other->getConstPointer();
4814           for(int i=0;i<nbOfTuple;i++)
4815             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::divides<double>());
4816         }
4817       else
4818         throw INTERP_KERNEL::Exception(msg);
4819     }
4820   else
4821     throw INTERP_KERNEL::Exception(msg);
4822   declareAsNew();
4823 }
4824
4825 /*!
4826  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
4827  * Server side.
4828  */
4829 void DataArrayDouble::getTinySerializationIntInformation(std::vector<int>& tinyInfo) const
4830 {
4831   tinyInfo.resize(2);
4832   if(isAllocated())
4833     {
4834       tinyInfo[0]=getNumberOfTuples();
4835       tinyInfo[1]=getNumberOfComponents();
4836     }
4837   else
4838     {
4839       tinyInfo[0]=-1;
4840       tinyInfo[1]=-1;
4841     }
4842 }
4843
4844 /*!
4845  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
4846  * Server side.
4847  */
4848 void DataArrayDouble::getTinySerializationStrInformation(std::vector<std::string>& tinyInfo) const
4849 {
4850   if(isAllocated())
4851     {
4852       int nbOfCompo=getNumberOfComponents();
4853       tinyInfo.resize(nbOfCompo+1);
4854       tinyInfo[0]=getName();
4855       for(int i=0;i<nbOfCompo;i++)
4856         tinyInfo[i+1]=getInfoOnComponent(i);
4857     }
4858   else
4859     {
4860       tinyInfo.resize(1);
4861       tinyInfo[0]=getName();
4862     }
4863 }
4864
4865 /*!
4866  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
4867  * This method returns if a feeding is needed.
4868  */
4869 bool DataArrayDouble::resizeForUnserialization(const std::vector<int>& tinyInfoI)
4870 {
4871   int nbOfTuple=tinyInfoI[0];
4872   int nbOfComp=tinyInfoI[1];
4873   if(nbOfTuple!=-1 || nbOfComp!=-1)
4874     {
4875       alloc(nbOfTuple,nbOfComp);
4876       return true;
4877     }
4878   return false;
4879 }
4880
4881 /*!
4882  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
4883  */
4884 void DataArrayDouble::finishUnserialization(const std::vector<int>& tinyInfoI, const std::vector<std::string>& tinyInfoS)
4885 {
4886   setName(tinyInfoS[0].c_str());
4887   if(isAllocated())
4888     {
4889       int nbOfCompo=getNumberOfComponents();
4890       for(int i=0;i<nbOfCompo;i++)
4891         setInfoOnComponent(i,tinyInfoS[i+1].c_str());
4892     }
4893 }
4894
4895 DataArrayDoubleIterator::DataArrayDoubleIterator(DataArrayDouble *da):_da(da),_tuple_id(0),_nb_comp(0),_nb_tuple(0)
4896 {
4897   if(_da)
4898     {
4899       _da->incrRef();
4900       if(_da->isAllocated())
4901         {
4902           _nb_comp=da->getNumberOfComponents();
4903           _nb_tuple=da->getNumberOfTuples();
4904           _pt=da->getPointer();
4905         }
4906     }
4907 }
4908
4909 DataArrayDoubleIterator::~DataArrayDoubleIterator()
4910 {
4911   if(_da)
4912     _da->decrRef();
4913 }
4914
4915 DataArrayDoubleTuple *DataArrayDoubleIterator::nextt()
4916 {
4917   if(_tuple_id<_nb_tuple)
4918     {
4919       _tuple_id++;
4920       DataArrayDoubleTuple *ret=new DataArrayDoubleTuple(_pt,_nb_comp);
4921       _pt+=_nb_comp;
4922       return ret;
4923     }
4924   else
4925     return 0;
4926 }
4927
4928 DataArrayDoubleTuple::DataArrayDoubleTuple(double *pt, int nbOfComp):_pt(pt),_nb_of_compo(nbOfComp)
4929 {
4930 }
4931
4932
4933 std::string DataArrayDoubleTuple::repr() const
4934 {
4935   std::ostringstream oss; oss.precision(17); oss << "(";
4936   for(int i=0;i<_nb_of_compo-1;i++)
4937     oss << _pt[i] << ", ";
4938   oss << _pt[_nb_of_compo-1] << ")";
4939   return oss.str();
4940 }
4941
4942 double DataArrayDoubleTuple::doubleValue() const throw(INTERP_KERNEL::Exception)
4943 {
4944   if(_nb_of_compo==1)
4945     return *_pt;
4946   throw INTERP_KERNEL::Exception("DataArrayDoubleTuple::doubleValue : DataArrayDoubleTuple instance has not exactly 1 component -> Not possible to convert it into a double precision float !");
4947 }
4948
4949 /*!
4950  * This method returns a newly allocated instance the caller should dealed with by a ParaMEDMEM::DataArrayDouble::decrRef.
4951  * This method performs \b no copy of data. The content is only referenced using ParaMEDMEM::DataArrayDouble::useArray with ownership set to \b false.
4952  * 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
4953  * \b nbOfCompo=1 and \bnbOfTuples==this->_nb_of_elem.
4954  */
4955 DataArrayDouble *DataArrayDoubleTuple::buildDADouble(int nbOfTuples, int nbOfCompo) const throw(INTERP_KERNEL::Exception)
4956 {
4957   if((_nb_of_compo==nbOfCompo && nbOfTuples==1) || (_nb_of_compo==nbOfTuples && nbOfCompo==1))
4958     {
4959       DataArrayDouble *ret=DataArrayDouble::New();
4960       ret->useExternalArrayWithRWAccess(_pt,nbOfTuples,nbOfCompo);
4961       return ret;
4962     }
4963   else
4964     {
4965       std::ostringstream oss; oss << "DataArrayDoubleTuple::buildDADouble : unable to build a requested DataArrayDouble instance with nbofTuple=" << nbOfTuples << " and nbOfCompo=" << nbOfCompo;
4966       oss << ".\nBecause the number of elements in this is " << _nb_of_compo << " !";
4967       throw INTERP_KERNEL::Exception(oss.str().c_str());
4968     }
4969 }
4970
4971 /*!
4972  * Returns a new instance of DataArrayInt. The caller is to delete this array
4973  * using decrRef() as it is no more needed. 
4974  */
4975 DataArrayInt *DataArrayInt::New()
4976 {
4977   return new DataArrayInt;
4978 }
4979
4980 /*!
4981  * Checks if raw data is allocated. Read more on the raw data
4982  * in \ref MEDCouplingArrayBasicsTuplesAndCompo "DataArrays infos" for more information.
4983  *  \return bool - \a true if the raw data is allocated, \a false else.
4984  */
4985 bool DataArrayInt::isAllocated() const
4986 {
4987   return getConstPointer()!=0;
4988 }
4989
4990 /*!
4991  * Checks if raw data is allocated and throws an exception if it is not the case.
4992  *  \throw If the raw data is not allocated.
4993  */
4994 void DataArrayInt::checkAllocated() const throw(INTERP_KERNEL::Exception)
4995 {
4996   if(!isAllocated())
4997     throw INTERP_KERNEL::Exception("DataArrayInt::checkAllocated : Array is defined but not allocated ! Call alloc or setValues method first !");
4998 }
4999
5000 std::size_t DataArrayInt::getHeapMemorySize() const
5001 {
5002   std::size_t sz=(std::size_t)_mem.getNbOfElemAllocated();
5003   sz*=sizeof(int);
5004   return DataArray::getHeapMemorySize()+sz;
5005 }
5006
5007 /*!
5008  * Sets information on all components. This method can change number of components
5009  * at certain conditions; if the conditions are not respected, an exception is thrown.
5010  * The number of components can be changed provided that \a this is not allocated.
5011  *
5012  * To know more on format of the component information see
5013  * \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
5014  *  \param [in] info - a vector of component infos.
5015  *  \throw If \a this->getNumberOfComponents() != \a info.size() && \a this->isAllocated()
5016  */
5017 void DataArrayInt::setInfoAndChangeNbOfCompo(const std::vector<std::string>& info) throw(INTERP_KERNEL::Exception)
5018 {
5019   if(getNumberOfComponents()!=(int)info.size())
5020     {
5021       if(!isAllocated())
5022         _info_on_compo=info;
5023       else
5024         {
5025           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 !";
5026           throw INTERP_KERNEL::Exception(oss.str().c_str());
5027         }
5028     }
5029   else
5030     _info_on_compo=info;
5031 }
5032
5033 /*!
5034  * Returns the only one value in \a this, if and only if number of elements
5035  * (nb of tuples * nb of components) is equal to 1, and that \a this is allocated.
5036  *  \return double - the sole value stored in \a this array.
5037  *  \throw If at least one of conditions stated above is not fulfilled.
5038  */
5039 int DataArrayInt::intValue() const throw(INTERP_KERNEL::Exception)
5040 {
5041   if(isAllocated())
5042     {
5043       if(getNbOfElems()==1)
5044         {
5045           return *getConstPointer();
5046         }
5047       else
5048         throw INTERP_KERNEL::Exception("DataArrayInt::intValue : DataArrayInt instance is allocated but number of elements is not equal to 1 !");
5049     }
5050   else
5051     throw INTERP_KERNEL::Exception("DataArrayInt::intValue : DataArrayInt instance is not allocated !");
5052 }
5053
5054 /*!
5055  * Returns an integer value characterizing \a this array, which is useful for a quick
5056  * comparison of many instances of DataArrayInt.
5057  *  \return int - the hash value.
5058  *  \throw If \a this is not allocated.
5059  */
5060 int DataArrayInt::getHashCode() const throw(INTERP_KERNEL::Exception)
5061 {
5062   checkAllocated();
5063   int nbOfElems=getNbOfElems();
5064   int ret=nbOfElems*65536;
5065   int delta=3;
5066   if(nbOfElems>48)
5067     delta=nbOfElems/8;
5068   int ret0=0;
5069   const int *pt=begin();
5070   for(int i=0;i<nbOfElems;i+=delta)
5071     ret0+=pt[i] & 0x1FFF;
5072   return ret+ret0;
5073 }
5074
5075 /*!
5076  * Checks the number of tuples.
5077  *  \return bool - \a true if getNumberOfTuples() == 0, \a false else.
5078  *  \throw If \a this is not allocated.
5079  */
5080 bool DataArrayInt::empty() const throw(INTERP_KERNEL::Exception)
5081 {
5082   checkAllocated();
5083   return getNumberOfTuples()==0;
5084 }
5085
5086 /*!
5087  * Returns a full copy of \a this. For more info on copying data arrays see
5088  * \ref MEDCouplingArrayBasicsCopyDeep.
5089  *  \return DataArrayInt * - a new instance of DataArrayInt.
5090  */
5091 DataArrayInt *DataArrayInt::deepCpy() const
5092 {
5093   return new DataArrayInt(*this);
5094 }
5095
5096 /*!
5097  * Returns either a \a deep or \a shallow copy of this array. For more info see
5098  * \ref MEDCouplingArrayBasicsCopyDeep and \ref MEDCouplingArrayBasicsCopyShallow.
5099  *  \param [in] dCpy - if \a true, a deep copy is returned, else, a shallow one.
5100  *  \return DataArrayInt * - either a new instance of DataArrayInt (if \a dCpy
5101  *          == \a true) or \a this instance (if \a dCpy == \a false).
5102  */
5103 DataArrayInt *DataArrayInt::performCpy(bool dCpy) const
5104 {
5105   if(dCpy)
5106     return deepCpy();
5107   else
5108     {
5109       incrRef();
5110       return const_cast<DataArrayInt *>(this);
5111     }
5112 }
5113
5114 /*!
5115  * Copies all the data from another DataArrayInt. For more info see
5116  * \ref MEDCouplingArrayBasicsCopyDeepAssign.
5117  *  \param [in] other - another instance of DataArrayInt to copy data from.
5118  *  \throw If the \a other is not allocated.
5119  */
5120 void DataArrayInt::cpyFrom(const DataArrayInt& other) throw(INTERP_KERNEL::Exception)
5121 {
5122   other.checkAllocated();
5123   int nbOfTuples=other.getNumberOfTuples();
5124   int nbOfComp=other.getNumberOfComponents();
5125   allocIfNecessary(nbOfTuples,nbOfComp);
5126   int nbOfElems=nbOfTuples*nbOfComp;
5127   int *pt=getPointer();
5128   const int *ptI=other.getConstPointer();
5129   for(int i=0;i<nbOfElems;i++)
5130     pt[i]=ptI[i];
5131   copyStringInfoFrom(other);
5132 }
5133
5134 /*!
5135  * This method reserve nbOfElems elements in memory ( nbOfElems*4 bytes ) \b without impacting the number of tuples in \a this.
5136  * 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.
5137  * If \a this has not already been allocated, number of components is set to one.
5138  * This method allows to reduce number of reallocations on invokation of DataArrayInt::pushBackSilent and DataArrayInt::pushBackValsSilent on \a this.
5139  * 
5140  * \sa DataArrayInt::pack, DataArrayInt::pushBackSilent, DataArrayInt::pushBackValsSilent
5141  */
5142 void DataArrayInt::reserve(int nbOfElems) throw(INTERP_KERNEL::Exception)
5143 {
5144   int nbCompo=getNumberOfComponents();
5145   if(nbCompo==1)
5146     {
5147       _mem.reserve(nbOfElems);
5148     }
5149   else if(nbCompo==0)
5150     {
5151       _mem.reserve(nbOfElems);
5152       _info_on_compo.resize(1);
5153     }
5154   else
5155     throw INTERP_KERNEL::Exception("DataArrayInt::reserve : not available for DataArrayInt with number of components different than 1 !");
5156 }
5157
5158 /*!
5159  * 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
5160  * of counter. So the caller is expected to call TimeLabel::declareAsNew on \a this at the end of the push session.
5161  *
5162  * \param [in] val the value to be added in \a this
5163  * \throw If \a this has already been allocated with number of components different from one.
5164  * \sa DataArrayInt::pushBackValsSilent
5165  */
5166 void DataArrayInt::pushBackSilent(int val) throw(INTERP_KERNEL::Exception)
5167 {
5168   int nbCompo=getNumberOfComponents();
5169   if(nbCompo==1)
5170     _mem.pushBack(val);
5171   else if(nbCompo==0)
5172     {
5173       _info_on_compo.resize(1);
5174       _mem.pushBack(val);
5175     }
5176   else
5177     throw INTERP_KERNEL::Exception("DataArrayInt::pushBackSilent : not available for DataArrayInt with number of components different than 1 !");
5178 }
5179
5180 /*!
5181  * 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
5182  * of counter. So the caller is expected to call TimeLabel::declareAsNew on \a this at the end of the push session.
5183  *
5184  *  \param [in] valsBg - an array of values to push at the end of \this.
5185  *  \param [in] valsEnd - specifies the end of the array \a valsBg, so that
5186  *              the last value of \a valsBg is \a valsEnd[ -1 ].
5187  * \throw If \a this has already been allocated with number of components different from one.
5188  * \sa DataArrayInt::pushBackSilent
5189  */
5190 void DataArrayInt::pushBackValsSilent(const int *valsBg, const int *valsEnd) throw(INTERP_KERNEL::Exception)
5191 {
5192   int nbCompo=getNumberOfComponents();
5193   if(nbCompo==1)
5194     _mem.insertAtTheEnd(valsBg,valsEnd);
5195   else if(nbCompo==0)
5196     {
5197       _info_on_compo.resize(1);
5198       _mem.insertAtTheEnd(valsBg,valsEnd);
5199     }
5200   else
5201     throw INTERP_KERNEL::Exception("DataArrayInt::pushBackValsSilent : not available for DataArrayInt with number of components different than 1 !");
5202 }
5203
5204 /*!
5205  * This method returns silently ( without updating time label in \a this ) the last value, if any and suppress it.
5206  * \throw If \a this is already empty.
5207  * \throw If \a this has number of components different from one.
5208  */
5209 int DataArrayInt::popBackSilent() throw(INTERP_KERNEL::Exception)
5210 {
5211   if(getNumberOfComponents()==1)
5212     return _mem.popBack();
5213   else
5214     throw INTERP_KERNEL::Exception("DataArrayInt::popBackSilent : not available for DataArrayInt with number of components different than 1 !");
5215 }
5216
5217 /*!
5218  * 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.
5219  *
5220  * \sa DataArrayInt::getHeapMemorySize, DataArrayInt::reserve
5221  */
5222 void DataArrayInt::pack() const throw(INTERP_KERNEL::Exception)
5223 {
5224   _mem.pack();
5225 }
5226
5227 /*!
5228  * Allocates the raw data in memory. If exactly as same memory as needed already
5229  * allocated, it is not re-allocated.
5230  *  \param [in] nbOfTuple - number of tuples of data to allocate.
5231  *  \param [in] nbOfCompo - number of components of data to allocate.
5232  *  \throw If \a nbOfTuple < 0 or \a nbOfCompo < 0.
5233  */
5234 void DataArrayInt::allocIfNecessary(int nbOfTuple, int nbOfCompo)
5235 {
5236   if(isAllocated())
5237     {
5238       if(nbOfTuple!=getNumberOfTuples() || nbOfCompo!=getNumberOfComponents())
5239         alloc(nbOfTuple,nbOfCompo);
5240     }
5241   else
5242     alloc(nbOfTuple,nbOfCompo);
5243 }
5244
5245 /*!
5246  * Allocates the raw data in memory. If the memory was already allocated, then it is
5247  * freed and re-allocated. See an example of this method use
5248  * \ref MEDCouplingArraySteps1WC "here".
5249  *  \param [in] nbOfTuple - number of tuples of data to allocate.
5250  *  \param [in] nbOfCompo - number of components of data to allocate.
5251  *  \throw If \a nbOfTuple < 0 or \a nbOfCompo < 0.
5252  */
5253 void DataArrayInt::alloc(int nbOfTuple, int nbOfCompo) throw(INTERP_KERNEL::Exception)
5254 {
5255   if(nbOfTuple<0 || nbOfCompo<0)
5256     throw INTERP_KERNEL::Exception("DataArrayInt::alloc : request for negative length of data !");
5257   _info_on_compo.resize(nbOfCompo);
5258   _mem.alloc(nbOfCompo*nbOfTuple);
5259   declareAsNew();
5260 }
5261
5262 /*!
5263  * Assign zero to all values in \a this array. To know more on filling arrays see
5264  * \ref MEDCouplingArrayFill.
5265  * \throw If \a this is not allocated.
5266  */
5267 void DataArrayInt::fillWithZero() throw(INTERP_KERNEL::Exception)
5268 {
5269   checkAllocated();
5270   _mem.fillWithValue(0);
5271   declareAsNew();
5272 }
5273
5274 /*!
5275  * Assign \a val to all values in \a this array. To know more on filling arrays see
5276  * \ref MEDCouplingArrayFill.
5277  *  \param [in] val - the value to fill with.
5278  *  \throw If \a this is not allocated.
5279  */
5280 void DataArrayInt::fillWithValue(int val) throw(INTERP_KERNEL::Exception)
5281 {
5282   checkAllocated();
5283   _mem.fillWithValue(val);
5284   declareAsNew();
5285 }
5286
5287 /*!
5288  * Set all values in \a this array so that the i-th element equals to \a init + i
5289  * (i starts from zero). To know more on filling arrays see \ref MEDCouplingArrayFill.
5290  *  \param [in] init - value to assign to the first element of array.
5291  *  \throw If \a this->getNumberOfComponents() != 1
5292  *  \throw If \a this is not allocated.
5293  */
5294 void DataArrayInt::iota(int init) throw(INTERP_KERNEL::Exception)
5295 {
5296   checkAllocated();
5297   if(getNumberOfComponents()!=1)
5298     throw INTERP_KERNEL::Exception("DataArrayInt::iota : works only for arrays with only one component, you can call 'rearrange' method before !");
5299   int *ptr=getPointer();
5300   int ntuples=getNumberOfTuples();
5301   for(int i=0;i<ntuples;i++)
5302     ptr[i]=init+i;
5303   declareAsNew();
5304 }
5305
5306 /*!
5307  * Returns a textual and human readable representation of \a this instance of
5308  * DataArrayInt. This text is shown when a DataArrayInt is printed in Python.
5309  *  \return std::string - text describing \a this DataArrayInt.
5310  */
5311 std::string DataArrayInt::repr() const
5312 {
5313   std::ostringstream ret;
5314   reprStream(ret);
5315   return ret.str();
5316 }
5317
5318 std::string DataArrayInt::reprZip() const
5319 {
5320   std::ostringstream ret;
5321   reprZipStream(ret);
5322   return ret.str();
5323 }
5324
5325 void DataArrayInt::writeVTK(std::ostream& ofs, int indent, const char *type, const char *nameInFile) const throw(INTERP_KERNEL::Exception)
5326 {
5327   checkAllocated();
5328   std::string idt(indent,' ');
5329   ofs << idt << "<DataArray type=\"" << type << "\" Name=\"" << nameInFile << "\" NumberOfComponents=\"" << getNumberOfComponents() << "\"";
5330   ofs << " format=\"ascii\" RangeMin=\"" << getMinValueInArray() << "\" RangeMax=\"" << getMaxValueInArray() << "\">\n" << idt;
5331   std::copy(begin(),end(),std::ostream_iterator<int>(ofs," "));
5332   ofs << std::endl << idt << "</DataArray>\n";
5333 }
5334
5335 void DataArrayInt::reprStream(std::ostream& stream) const
5336 {
5337   stream << "Name of int array : \"" << _name << "\"\n";
5338   reprWithoutNameStream(stream);
5339 }
5340
5341 void DataArrayInt::reprZipStream(std::ostream& stream) const
5342 {
5343   stream << "Name of int array : \"" << _name << "\"\n";
5344   reprZipWithoutNameStream(stream);
5345 }
5346
5347 void DataArrayInt::reprWithoutNameStream(std::ostream& stream) const
5348 {
5349   DataArray::reprWithoutNameStream(stream);
5350   _mem.repr(getNumberOfComponents(),stream);
5351 }
5352
5353 void DataArrayInt::reprZipWithoutNameStream(std::ostream& stream) const
5354 {
5355   DataArray::reprWithoutNameStream(stream);
5356   _mem.reprZip(getNumberOfComponents(),stream);
5357 }
5358
5359 void DataArrayInt::reprCppStream(const char *varName, std::ostream& stream) const
5360 {
5361   int nbTuples=getNumberOfTuples(),nbComp=getNumberOfComponents();
5362   const int *data=getConstPointer();
5363   stream << "DataArrayInt *" << varName << "=DataArrayInt::New();" << std::endl;
5364   if(nbTuples*nbComp>=1)
5365     {
5366       stream << "const int " << varName << "Data[" << nbTuples*nbComp << "]={";
5367       std::copy(data,data+nbTuples*nbComp-1,std::ostream_iterator<int>(stream,","));
5368       stream << data[nbTuples*nbComp-1] << "};" << std::endl;
5369       stream << varName << "->useArray(" << varName << "Data,false,CPP_DEALLOC," << nbTuples << "," << nbComp << ");" << std::endl;
5370     }
5371   else
5372     stream << varName << "->alloc(" << nbTuples << "," << nbComp << ");" << std::endl;
5373   stream << varName << "->setName(\"" << getName() << "\");" << std::endl;
5374 }
5375
5376 /*!
5377  * Modifies \a this one-dimensional array so that each value \a v = \a indArrBg[ \a v ],
5378  * i.e. a current value is used as in index to get a new value from \a indArrBg.
5379  *  \param [in] indArrBg - pointer to the first element of array of new values to assign
5380  *         to \a this array.
5381  *  \param [in] indArrEnd - specifies the end of the array \a indArrBg, so that
5382  *              the last value of \a indArrBg is \a indArrEnd[ -1 ].
5383  *  \throw If \a this->getNumberOfComponents() != 1
5384  *  \throw If any value of \a this can't be used as a valid index for 
5385  *         [\a indArrBg, \a indArrEnd).
5386  */
5387 void DataArrayInt::transformWithIndArr(const int *indArrBg, const int *indArrEnd) throw(INTERP_KERNEL::Exception)
5388 {
5389   checkAllocated();
5390   if(getNumberOfComponents()!=1)
5391     throw INTERP_KERNEL::Exception("Call transformWithIndArr method on DataArrayInt with only one component, you can call 'rearrange' method before !");
5392   int nbElemsIn=(int)std::distance(indArrBg,indArrEnd);
5393   int nbOfTuples=getNumberOfTuples();
5394   int *pt=getPointer();
5395   for(int i=0;i<nbOfTuples;i++,pt++)
5396     {
5397       if(*pt>=0 && *pt<nbElemsIn)
5398         *pt=indArrBg[*pt];
5399       else
5400         {
5401           std::ostringstream oss; oss << "DataArrayInt::transformWithIndArr : error on tuple #" << i << " value is " << *pt << " and indirectionnal array as a size equal to " << nbElemsIn;
5402           throw INTERP_KERNEL::Exception(oss.str().c_str());
5403         }
5404     }
5405   declareAsNew();
5406 }
5407
5408 /*!
5409  * Computes distribution of values of \a this one-dimensional array between given value
5410  * ranges (casts). This method is typically useful for entity number spliting by types,
5411  * for example. 
5412  *  \param [in] arrBg - the array of ascending values defining the value ranges. The i-th
5413  *         value of \a arrBg (\a arrBg[ i ]) gives the lowest value of the i-th range,
5414  *         and the greatest value of the i-th range equals to \a arrBg[ i+1 ] - 1. \a
5415  *         arrBg containing \a n values defines \a n-1 ranges. The last value of \a arrBg
5416  *         should be more than every value in \a this array.
5417  *  \param [in] arrEnd - specifies the end of the array \a arrBg, so that
5418  *              the last value of \a arrBg is \a arrEnd[ -1 ].
5419  *  \param [out] castArr - a new instance of DataArrayInt, of same size as \a this array
5420  *         (same number of tuples and components), the caller is to delete 
5421  *         using decrRef() as it is no more needed.
5422  *         This array contains indices of ranges for every value of \a this array. I.e.
5423  *         the i-th value of \a castArr gives the index of range the i-th value of \a this
5424  *         belongs to. Or, in other words, this parameter contains for each tuple in \a
5425  *         this in which cast it holds.
5426  *  \param [out] rankInsideCast - a new instance of DataArrayInt, of same size as \a this
5427  *         array, the caller is to delete using decrRef() as it is no more needed.
5428  *         This array contains ranks of values of \a this array within ranges
5429  *         they belongs to. I.e. the i-th value of \a rankInsideCast gives the rank of
5430  *         the i-th value of \a this array within the \a castArr[ i ]-th range, to which
5431  *         the i-th value of \a this belongs to. Or, in other words, this param contains 
5432  *         for each tuple its rank inside its cast. The rank is computed as difference
5433  *         between the value and the lowest value of range.
5434  *  \param [out] castsPresent - a new instance of DataArrayInt, containing indices of
5435  *         ranges (casts) to which at least one value of \a this array belongs.
5436  *         Or, in other words, this param contains the casts that \a this contains.
5437  *         The caller is to delete this array using decrRef() as it is no more needed.
5438  *
5439  * \b Example: If \a this contains [6,5,0,3,2,7,8,1,4] and \a arrBg contains [0,4,9] then
5440  *            the output of this method will be : 
5441  * - \a castArr       : [1,1,0,0,0,1,1,0,1]
5442  * - \a rankInsideCast: [2,1,0,3,2,3,4,1,0]
5443  * - \a castsPresent  : [0,1]
5444  *
5445  * I.e. values of \a this array belong to 2 ranges: #0 and #1. Value 6 belongs to the
5446  * range #1 and its rank within this range is 2; etc.
5447  *
5448  *  \throw If \a this->getNumberOfComponents() != 1.
5449  *  \throw If \a arrEnd - arrBg < 2.
5450  *  \throw If any value of \a this is not less than \a arrEnd[-1].
5451  *  \warning The values contained in \a arrBg should be sorted ascendently. No
5452  *           check of this is be done. If not, the result is not warranted. 
5453  * 
5454  */
5455 void DataArrayInt::splitByValueRange(const int *arrBg, const int *arrEnd,
5456                                      DataArrayInt *& castArr, DataArrayInt *& rankInsideCast, DataArrayInt *& castsPresent) const throw(INTERP_KERNEL::Exception)
5457 {
5458   checkAllocated();
5459   if(getNumberOfComponents()!=1)
5460     throw INTERP_KERNEL::Exception("Call splitByValueRange  method on DataArrayInt with only one component, you can call 'rearrange' method before !");
5461   int nbOfTuples=getNumberOfTuples();
5462   std::size_t nbOfCast=std::distance(arrBg,arrEnd);
5463   if(nbOfCast<2)
5464     throw INTERP_KERNEL::Exception("DataArrayInt::splitByValueRange : The input array giving the cast range values should be of size >=2 !");
5465   nbOfCast--;
5466   const int *work=getConstPointer();
5467   typedef std::reverse_iterator<const int *> rintstart;
5468   rintstart bg(arrEnd);//OK no problem because size of 'arr' is greater or equal 2
5469   rintstart end2(arrBg);
5470   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret1=DataArrayInt::New();
5471   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret2=DataArrayInt::New();
5472   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret3=DataArrayInt::New();
5473   ret1->alloc(nbOfTuples,1);
5474   ret2->alloc(nbOfTuples,1);
5475   int *ret1Ptr=ret1->getPointer();
5476   int *ret2Ptr=ret2->getPointer();
5477   std::set<std::size_t> castsDetected;
5478   for(int i=0;i<nbOfTuples;i++)
5479     {
5480       rintstart res=std::find_if(bg,end2,std::bind2nd(std::less_equal<int>(), work[i]));
5481       std::size_t pos=std::distance(bg,res);
5482       std::size_t pos2=nbOfCast-pos;
5483       if(pos2<nbOfCast)
5484         {
5485           ret1Ptr[i]=(int)pos2;
5486           ret2Ptr[i]=work[i]-arrBg[pos2];
5487           castsDetected.insert(pos2);
5488         }
5489       else
5490         {
5491           std::ostringstream oss; oss << "DataArrayInt::splitByValueRange : At rank #" << i << " the value is " << work[i] << " whereas the last value is " << *bg;
5492           throw INTERP_KERNEL::Exception(oss.str().c_str());
5493         }
5494     }
5495   ret3->alloc((int)castsDetected.size(),1);
5496   std::copy(castsDetected.begin(),castsDetected.end(),ret3->getPointer());
5497   castArr=ret1.retn();
5498   rankInsideCast=ret2.retn();
5499   castsPresent=ret3.retn();
5500 }
5501
5502 /*!
5503  * Creates a one-dimensional DataArrayInt (\a res) whose contents are computed from 
5504  * values of \a this (\a a) and the given (\a indArr) arrays as follows:
5505  * \a res[ \a indArr[ \a a[ i ]]] = i. I.e. for each value in place i \a v = \a a[ i ],
5506  * new value in place \a indArr[ \a v ] is i.
5507  *  \param [in] indArrBg - the array holding indices within the result array to assign
5508  *         indices of values of \a this array pointing to values of \a indArrBg.
5509  *  \param [in] indArrEnd - specifies the end of the array \a indArrBg, so that
5510  *              the last value of \a indArrBg is \a indArrEnd[ -1 ].
5511  *  \return DataArrayInt * - the new instance of DataArrayInt.
5512  *          The caller is to delete this result array using decrRef() as it is no more
5513  *          needed.
5514  *  \throw If \a this->getNumberOfComponents() != 1.
5515  *  \throw If any value of \a this array is not a valid index for \a indArrBg array.
5516  *  \throw If any value of \a indArrBg is not a valid index for \a this array.
5517  */
5518 DataArrayInt *DataArrayInt::transformWithIndArrR(const int *indArrBg, const int *indArrEnd) const throw(INTERP_KERNEL::Exception)
5519 {
5520   checkAllocated();
5521   if(getNumberOfComponents()!=1)
5522     throw INTERP_KERNEL::Exception("Call transformWithIndArrR method on DataArrayInt with only one component, you can call 'rearrange' method before !");
5523   int nbElemsIn=(int)std::distance(indArrBg,indArrEnd);
5524   int nbOfTuples=getNumberOfTuples();
5525   const int *pt=getConstPointer();
5526   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
5527   ret->alloc(nbOfTuples,1);
5528   ret->fillWithValue(-1);
5529   int *tmp=ret->getPointer();
5530   for(int i=0;i<nbOfTuples;i++,pt++)
5531     {
5532       if(*pt>=0 && *pt<nbElemsIn)
5533         {
5534           int pos=indArrBg[*pt];
5535           if(pos>=0 && pos<nbOfTuples)
5536             tmp[pos]=i;
5537           else
5538             {
5539               std::ostringstream oss; oss << "DataArrayInt::transformWithIndArrR : error on tuple #" << i << " value of new pos is " << pos << " ( indArrBg[" << *pt << "]) ! Should be in [0," << nbOfTuples << ") !";
5540               throw INTERP_KERNEL::Exception(oss.str().c_str());
5541             }
5542         }
5543       else
5544         {
5545           std::ostringstream oss; oss << "DataArrayInt::transformWithIndArrR : error on tuple #" << i << " value is " << *pt << " and indirectionnal array as a size equal to " << nbElemsIn << " !";
5546           throw INTERP_KERNEL::Exception(oss.str().c_str());
5547         }
5548     }
5549   return ret.retn();
5550 }
5551
5552 /*!
5553  * Creates a one-dimensional DataArrayInt of given length, whose contents are computed
5554  * from values of \a this array, which is supposed to contain a renumbering map in 
5555  * "Old to New" mode. The result array contains a renumbering map in "New to Old" mode.
5556  * To know how to use the renumbering maps see \ref MEDCouplingArrayRenumbering.
5557  *  \param [in] newNbOfElem - the number of tuples in the result array.
5558  *  \return DataArrayInt * - the new instance of DataArrayInt.
5559  *          The caller is to delete this result array using decrRef() as it is no more
5560  *          needed.
5561  * 
5562  *  \ref cpp_mcdataarrayint_invertarrayo2n2n2o "Here is a C++ example".
5563  *
5564  *  \ref py_mcdataarrayint_invertarrayo2n2n2o "Here is a Python example".
5565  */
5566 DataArrayInt *DataArrayInt::invertArrayO2N2N2O(int newNbOfElem) const
5567 {
5568   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
5569   ret->alloc(newNbOfElem,1);
5570   int nbOfOldNodes=getNumberOfTuples();
5571   const int *old2New=getConstPointer();
5572   int *pt=ret->getPointer();
5573   for(int i=0;i!=nbOfOldNodes;i++)
5574     if(old2New[i]!=-1)
5575       pt[old2New[i]]=i;
5576   return ret.retn();
5577 }
5578
5579 /*!
5580  * This method is similar to DataArrayInt::invertArrayO2N2N2O except that 
5581  * 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]
5582  */
5583 DataArrayInt *DataArrayInt::invertArrayO2N2N2OBis(int newNbOfElem) const throw(INTERP_KERNEL::Exception)
5584 {
5585   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
5586   ret->alloc(newNbOfElem,1);
5587   int nbOfOldNodes=getNumberOfTuples();
5588   const int *old2New=getConstPointer();
5589   int *pt=ret->getPointer();
5590   for(int i=nbOfOldNodes-1;i>=0;i--)
5591     if(old2New[i]!=-1)
5592       pt[old2New[i]]=i;
5593   return ret.retn();
5594 }
5595
5596 /*!
5597  * Creates a one-dimensional DataArrayInt of given length, whose contents are computed
5598  * from values of \a this array, which is supposed to contain a renumbering map in 
5599  * "New to Old" mode. The result array contains a renumbering map in "Old to New" mode.
5600  * To know how to use the renumbering maps see \ref MEDCouplingArrayRenumbering.
5601  *  \param [in] newNbOfElem - the number of tuples in the result array.
5602  *  \return DataArrayInt * - the new instance of DataArrayInt.
5603  *          The caller is to delete this result array using decrRef() as it is no more
5604  *          needed.
5605  * 
5606  *  \ref cpp_mcdataarrayint_invertarrayn2o2o2n "Here is a C++ example".
5607  *
5608  *  \ref py_mcdataarrayint_invertarrayn2o2o2n "Here is a Python example".
5609  */
5610 DataArrayInt *DataArrayInt::invertArrayN2O2O2N(int oldNbOfElem) const
5611 {
5612   checkAllocated();
5613   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
5614   ret->alloc(oldNbOfElem,1);
5615   const int *new2Old=getConstPointer();
5616   int *pt=ret->getPointer();
5617   std::fill(pt,pt+oldNbOfElem,-1);
5618   int nbOfNewElems=getNumberOfTuples();
5619   for(int i=0;i<nbOfNewElems;i++)
5620     pt[new2Old[i]]=i;
5621   return ret.retn();
5622 }
5623
5624 bool DataArrayInt::isEqualIfNotWhy(const DataArrayInt& other, std::string& reason) const
5625 {
5626   if(!areInfoEqualsIfNotWhy(other,reason))
5627     return false;
5628   return _mem.isEqual(other._mem,0,reason);
5629 }
5630
5631 /*!
5632  * Checks if \a this and another DataArrayInt are fully equal. For more info see
5633  * \ref MEDCouplingArrayBasicsCompare.
5634  *  \param [in] other - an instance of DataArrayInt to compare with \a this one.
5635  *  \return bool - \a true if the two arrays are equal, \a false else.
5636  */
5637 bool DataArrayInt::isEqual(const DataArrayInt& other) const
5638 {
5639   std::string tmp;
5640   return isEqualIfNotWhy(other,tmp);
5641 }
5642
5643 /*!
5644  * Checks if values of \a this and another DataArrayInt are 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 values of two arrays are equal, \a false else.
5648  */
5649 bool DataArrayInt::isEqualWithoutConsideringStr(const DataArrayInt& other) const
5650 {
5651   std::string tmp;
5652   return _mem.isEqual(other._mem,0,tmp);
5653 }
5654
5655 /*!
5656  * Checks if values of \a this and another DataArrayInt are equal. Comparison is
5657  * performed on sorted value sequences.
5658  * For more info see\ref MEDCouplingArrayBasicsCompare.
5659  *  \param [in] other - an instance of DataArrayInt to compare with \a this one.
5660  *  \return bool - \a true if the sorted values of two arrays are equal, \a false else.
5661  */
5662 bool DataArrayInt::isEqualWithoutConsideringStrAndOrder(const DataArrayInt& other) const throw(INTERP_KERNEL::Exception)
5663 {
5664   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> a=deepCpy();
5665   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> b=other.deepCpy();
5666   a->sort();
5667   b->sort();
5668   return a->isEqualWithoutConsideringStr(*b);
5669 }
5670
5671 /*!
5672  * Sorts values of the array.
5673  *  \param [in] asc - \a true means ascending order, \a false, descending.
5674  *  \throw If \a this is not allocated.
5675  *  \throw If \a this->getNumberOfComponents() != 1.
5676  */
5677 void DataArrayInt::sort(bool asc) throw(INTERP_KERNEL::Exception)
5678 {
5679   checkAllocated();
5680   if(getNumberOfComponents()!=1)
5681     throw INTERP_KERNEL::Exception("DataArrayInt::sort : only supported with 'this' array with ONE component !");
5682   _mem.sort(asc);
5683 }
5684
5685 /*!
5686  * Reverse the array values.
5687  *  \throw If \a this->getNumberOfComponents() != 1.
5688  *  \throw If \a this is not allocated.
5689  */
5690 void DataArrayInt::reverse() throw(INTERP_KERNEL::Exception)
5691 {
5692   checkAllocated();
5693   if(getNumberOfComponents()!=1)
5694     throw INTERP_KERNEL::Exception("DataArrayInt::reverse : only supported with 'this' array with ONE component !");
5695   _mem.reverse();
5696 }
5697
5698 /*!
5699  * Checks that \a this array is consistently **increasing** or **decreasing** in value.
5700  * If not an exception is thrown.
5701  *  \param [in] increasing - if \a true, the array values should be increasing.
5702  *  \throw If sequence of values is not strictly monotonic in agreement with \a
5703  *         increasing arg.
5704  *  \throw If \a this->getNumberOfComponents() != 1.
5705  *  \throw If \a this is not allocated.
5706  */
5707 void DataArrayInt::checkMonotonic(bool increasing) const throw(INTERP_KERNEL::Exception)
5708 {
5709   if(!isMonotonic(increasing))
5710     {
5711       if (increasing)
5712         throw INTERP_KERNEL::Exception("DataArrayInt::checkMonotonic : 'this' is not INCREASING monotonic !");
5713       else
5714         throw INTERP_KERNEL::Exception("DataArrayInt::checkMonotonic : 'this' is not DECREASING monotonic !");
5715     }
5716 }
5717
5718 /*!
5719  * Checks that \a this array is consistently **increasing** or **decreasing** in value.
5720  *  \param [in] increasing - if \a true, array values should be increasing.
5721  *  \return bool - \a true if values change in accordance with \a increasing arg.
5722  *  \throw If \a this->getNumberOfComponents() != 1.
5723  *  \throw If \a this is not allocated.
5724  */
5725 bool DataArrayInt::isMonotonic(bool increasing) const throw(INTERP_KERNEL::Exception)
5726 {
5727   checkAllocated();
5728   if(getNumberOfComponents()!=1)
5729     throw INTERP_KERNEL::Exception("DataArrayInt::isMonotonic : only supported with 'this' array with ONE component !");
5730   int nbOfElements=getNumberOfTuples();
5731   const int *ptr=getConstPointer();
5732   if(nbOfElements==0)
5733     return true;
5734   int ref=ptr[0];
5735   if(increasing)
5736     {
5737       for(int i=1;i<nbOfElements;i++)
5738         {
5739           if(ptr[i]>=ref)
5740             ref=ptr[i];
5741           else
5742             return false;
5743         }
5744     }
5745   else
5746     {
5747       for(int i=1;i<nbOfElements;i++)
5748         {
5749           if(ptr[i]<=ref)
5750             ref=ptr[i];
5751           else
5752             return false;
5753         }
5754     }
5755   return true;
5756 }
5757
5758 /*!
5759  * This method check that array consistently INCREASING or DECREASING in value.
5760  */
5761 bool DataArrayInt::isStrictlyMonotonic(bool increasing) const throw(INTERP_KERNEL::Exception)
5762 {
5763   checkAllocated();
5764   if(getNumberOfComponents()!=1)
5765     throw INTERP_KERNEL::Exception("DataArrayInt::isStrictlyMonotonic : only supported with 'this' array with ONE component !");
5766   int nbOfElements=getNumberOfTuples();
5767   const int *ptr=getConstPointer();
5768   if(nbOfElements==0)
5769     return true;
5770   int ref=ptr[0];
5771   if(increasing)
5772     {
5773       for(int i=1;i<nbOfElements;i++)
5774         {
5775           if(ptr[i]>ref)
5776             ref=ptr[i];
5777           else
5778             return false;
5779         }
5780     }
5781   else
5782     {
5783       for(int i=1;i<nbOfElements;i++)
5784         {
5785           if(ptr[i]<ref)
5786             ref=ptr[i];
5787           else
5788             return false;
5789         }
5790     }
5791   return true;
5792 }
5793
5794 /*!
5795  * This method check that array consistently INCREASING or DECREASING in value.
5796  */
5797 void DataArrayInt::checkStrictlyMonotonic(bool increasing) const throw(INTERP_KERNEL::Exception)
5798 {
5799   if(!isStrictlyMonotonic(increasing))
5800     {
5801       if (increasing)
5802         throw INTERP_KERNEL::Exception("DataArrayInt::checkStrictlyMonotonic : 'this' is not strictly INCREASING monotonic !");
5803       else
5804         throw INTERP_KERNEL::Exception("DataArrayInt::checkStrictlyMonotonic : 'this' is not strictly DECREASING monotonic !");
5805     }
5806 }
5807
5808 /*!
5809  * Creates a new one-dimensional DataArrayInt of the same size as \a this and a given
5810  * one-dimensional arrays that must be of the same length. The result array describes
5811  * correspondence between \a this and \a other arrays, so that 
5812  * <em> other.getIJ(i,0) == this->getIJ(ret->getIJ(i),0)</em>. If such a permutation is
5813  * not possible because some element in \a other is not in \a this, an exception is thrown.
5814  *  \param [in] other - an array to compute permutation to.
5815  *  \return DataArrayInt * - a new instance of DataArrayInt, which is a permutation array
5816  * from \a this to \a other. The caller is to delete this array using decrRef() as it is
5817  * no more needed.
5818  *  \throw If \a this->getNumberOfComponents() != 1.
5819  *  \throw If \a other->getNumberOfComponents() != 1.
5820  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples().
5821  *  \throw If \a other includes a value which is not in \a this array.
5822  * 
5823  *  \ref cpp_mcdataarrayint_buildpermutationarr "Here is a C++ example".
5824  *
5825  *  \ref py_mcdataarrayint_buildpermutationarr "Here is a Python example".
5826  */
5827 DataArrayInt *DataArrayInt::buildPermutationArr(const DataArrayInt& other) const throw(INTERP_KERNEL::Exception)
5828 {
5829   checkAllocated();
5830   if(getNumberOfComponents()!=1 || other.getNumberOfComponents()!=1)
5831     throw INTERP_KERNEL::Exception("DataArrayInt::buildPermutationArr : 'this' and 'other' have to have exactly ONE component !");
5832   int nbTuple=getNumberOfTuples();
5833   other.checkAllocated();
5834   if(nbTuple!=other.getNumberOfTuples())
5835     throw INTERP_KERNEL::Exception("DataArrayInt::buildPermutationArr : 'this' and 'other' must have the same number of tuple !");
5836   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
5837   ret->alloc(nbTuple,1);
5838   ret->fillWithValue(-1);
5839   const int *pt=getConstPointer();
5840   std::map<int,int> mm;
5841   for(int i=0;i<nbTuple;i++)
5842     mm[pt[i]]=i;
5843   pt=other.getConstPointer();
5844   int *retToFill=ret->getPointer();
5845   for(int i=0;i<nbTuple;i++)
5846     {
5847       std::map<int,int>::const_iterator it=mm.find(pt[i]);
5848       if(it==mm.end())
5849         {
5850           std::ostringstream oss; oss << "DataArrayInt::buildPermutationArr : Arrays mismatch : element (" << pt[i] << ") in 'other' not findable in 'this' !";
5851           throw INTERP_KERNEL::Exception(oss.str().c_str());
5852         }
5853       retToFill[i]=(*it).second;
5854     }
5855   return ret.retn();
5856 }
5857
5858 /*!
5859  * Sets a C array to be used as raw data of \a this. The previously set info
5860  *  of components is retained and re-sized. 
5861  * For more info see \ref MEDCouplingArraySteps1.
5862  *  \param [in] array - the C array to be used as raw data of \a this.
5863  *  \param [in] ownership - if \a true, \a array will be deallocated at destruction of \a this.
5864  *  \param [in] type - specifies how to deallocate \a array. If \a type == ParaMEDMEM::CPP_DEALLOC,
5865  *                     \c delete [] \c array; will be called. If \a type == ParaMEDMEM::C_DEALLOC,
5866  *                     \c free(\c array ) will be called.
5867  *  \param [in] nbOfTuple - new number of tuples in \a this.
5868  *  \param [in] nbOfCompo - new number of components in \a this.
5869  */
5870 void DataArrayInt::useArray(const int *array, bool ownership,  DeallocType type, int nbOfTuple, int nbOfCompo)
5871 {
5872   _info_on_compo.resize(nbOfCompo);
5873   _mem.useArray(array,ownership,type,nbOfTuple*nbOfCompo);
5874   declareAsNew();
5875 }
5876
5877 void DataArrayInt::useExternalArrayWithRWAccess(const int *array, int nbOfTuple, int nbOfCompo)
5878 {
5879   _info_on_compo.resize(nbOfCompo);
5880   _mem.useExternalArrayWithRWAccess(array,nbOfTuple*nbOfCompo);
5881   declareAsNew();
5882 }
5883
5884 /*!
5885  * Returns a new DataArrayInt holding the same values as \a this array but differently
5886  * arranged in memory. If \a this array holds 2 components of 3 values:
5887  * \f$ x_0,x_1,x_2,y_0,y_1,y_2 \f$, then the result array holds these values arranged
5888  * as follows: \f$ x_0,y_0,x_1,y_1,x_2,y_2 \f$.
5889  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
5890  *          is to delete using decrRef() as it is no more needed.
5891  *  \throw If \a this is not allocated.
5892  *  \warning Do not confuse this method with transpose()!
5893  */
5894 DataArrayInt *DataArrayInt::fromNoInterlace() const throw(INTERP_KERNEL::Exception)
5895 {
5896   checkAllocated();
5897   if(_mem.isNull())
5898     throw INTERP_KERNEL::Exception("DataArrayInt::fromNoInterlace : Not defined array !");
5899   int *tab=_mem.fromNoInterlace(getNumberOfComponents());
5900   DataArrayInt *ret=DataArrayInt::New();
5901   ret->useArray(tab,true,CPP_DEALLOC,getNumberOfTuples(),getNumberOfComponents());
5902   return ret;
5903 }
5904
5905 /*!
5906  * Returns a new DataArrayInt holding the same values as \a this array but differently
5907  * arranged in memory. If \a this array holds 2 components of 3 values:
5908  * \f$ x_0,y_0,x_1,y_1,x_2,y_2 \f$, then the result array holds these values arranged
5909  * as follows: \f$ x_0,x_1,x_2,y_0,y_1,y_2 \f$.
5910  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
5911  *          is to delete using decrRef() as it is no more needed.
5912  *  \throw If \a this is not allocated.
5913  *  \warning Do not confuse this method with transpose()!
5914  */
5915 DataArrayInt *DataArrayInt::toNoInterlace() const throw(INTERP_KERNEL::Exception)
5916 {
5917   checkAllocated();
5918   if(_mem.isNull())
5919     throw INTERP_KERNEL::Exception("DataArrayInt::toNoInterlace : Not defined array !");
5920   int *tab=_mem.toNoInterlace(getNumberOfComponents());
5921   DataArrayInt *ret=DataArrayInt::New();
5922   ret->useArray(tab,true,CPP_DEALLOC,getNumberOfTuples(),getNumberOfComponents());
5923   return ret;
5924 }
5925
5926 /*!
5927  * Permutes values of \a this array as required by \a old2New array. The values are
5928  * permuted so that \c new[ \a old2New[ i ]] = \c old[ i ]. Number of tuples remains
5929  * the same as in \this one.
5930  * If a permutation reduction is needed, substr() or selectByTupleId() should be used.
5931  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
5932  *  \param [in] old2New - C array of length equal to \a this->getNumberOfTuples()
5933  *     giving a new position for i-th old value.
5934  */
5935 void DataArrayInt::renumberInPlace(const int *old2New)
5936 {
5937   checkAllocated();
5938   int nbTuples=getNumberOfTuples();
5939   int nbOfCompo=getNumberOfComponents();
5940   int *tmp=new int[nbTuples*nbOfCompo];
5941   const int *iptr=getConstPointer();
5942   for(int i=0;i<nbTuples;i++)
5943     std::copy(iptr+nbOfCompo*i,iptr+nbOfCompo*(i+1),tmp+nbOfCompo*old2New[i]);
5944   std::copy(tmp,tmp+nbTuples*nbOfCompo,getPointer());
5945   delete [] tmp;
5946   declareAsNew();
5947 }
5948
5949 /*!
5950  * Permutes values of \a this array as required by \a new2Old array. The values are
5951  * permuted so that \c new[ i ] = \c old[ \a new2Old[ i ]]. Number of tuples remains
5952  * the same as in \this one.
5953  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
5954  *  \param [in] new2Old - C array of length equal to \a this->getNumberOfTuples()
5955  *     giving a previous position of i-th new value.
5956  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
5957  *          is to delete using decrRef() as it is no more needed.
5958  */
5959 void DataArrayInt::renumberInPlaceR(const int *new2Old)
5960 {
5961   checkAllocated();
5962   int nbTuples=getNumberOfTuples();
5963   int nbOfCompo=getNumberOfComponents();
5964   int *tmp=new int[nbTuples*nbOfCompo];
5965   const int *iptr=getConstPointer();
5966   for(int i=0;i<nbTuples;i++)
5967     std::copy(iptr+nbOfCompo*new2Old[i],iptr+nbOfCompo*(new2Old[i]+1),tmp+nbOfCompo*i);
5968   std::copy(tmp,tmp+nbTuples*nbOfCompo,getPointer());
5969   delete [] tmp;
5970   declareAsNew();
5971 }
5972
5973 /*!
5974  * Returns a copy of \a this array with values permuted as required by \a old2New array.
5975  * The values are permuted so that  \c new[ \a old2New[ i ]] = \c old[ i ].
5976  * Number of tuples in the result array remains the same as in \this one.
5977  * If a permutation reduction is needed, renumberAndReduce() should be used.
5978  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
5979  *  \param [in] old2New - C array of length equal to \a this->getNumberOfTuples()
5980  *          giving a new position for i-th old value.
5981  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
5982  *          is to delete using decrRef() as it is no more needed.
5983  *  \throw If \a this is not allocated.
5984  */
5985 DataArrayInt *DataArrayInt::renumber(const int *old2New) const
5986 {
5987   checkAllocated();
5988   int nbTuples=getNumberOfTuples();
5989   int nbOfCompo=getNumberOfComponents();
5990   DataArrayInt *ret=DataArrayInt::New();
5991   ret->alloc(nbTuples,nbOfCompo);
5992   ret->copyStringInfoFrom(*this);
5993   const int *iptr=getConstPointer();
5994   int *optr=ret->getPointer();
5995   for(int i=0;i<nbTuples;i++)
5996     std::copy(iptr+nbOfCompo*i,iptr+nbOfCompo*(i+1),optr+nbOfCompo*old2New[i]);
5997   ret->copyStringInfoFrom(*this);
5998   return ret;
5999 }
6000
6001 /*!
6002  * Returns a copy of \a this array with values permuted as required by \a new2Old array.
6003  * The values are permuted so that  \c new[ i ] = \c old[ \a new2Old[ i ]]. Number of
6004  * tuples in the result array remains the same as in \this one.
6005  * If a permutation reduction is needed, substr() or selectByTupleId() should be used.
6006  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
6007  *  \param [in] new2Old - C array of length equal to \a this->getNumberOfTuples()
6008  *     giving a previous position of i-th new value.
6009  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
6010  *          is to delete using decrRef() as it is no more needed.
6011  */
6012 DataArrayInt *DataArrayInt::renumberR(const int *new2Old) const
6013 {
6014   checkAllocated();
6015   int nbTuples=getNumberOfTuples();
6016   int nbOfCompo=getNumberOfComponents();
6017   DataArrayInt *ret=DataArrayInt::New();
6018   ret->alloc(nbTuples,nbOfCompo);
6019   ret->copyStringInfoFrom(*this);
6020   const int *iptr=getConstPointer();
6021   int *optr=ret->getPointer();
6022   for(int i=0;i<nbTuples;i++)
6023     std::copy(iptr+nbOfCompo*new2Old[i],iptr+nbOfCompo*(new2Old[i]+1),optr+nbOfCompo*i);
6024   ret->copyStringInfoFrom(*this);
6025   return ret;
6026 }
6027
6028 /*!
6029  * Returns a shorten and permuted copy of \a this array. The new DataArrayInt is
6030  * of size \a newNbOfTuple and it's values are permuted as required by \a old2New array.
6031  * The values are permuted so that  \c new[ \a old2New[ i ]] = \c old[ i ] for all
6032  * \a old2New[ i ] >= 0. In other words every i-th tuple in \a this array, for which 
6033  * \a old2New[ i ] is negative, is missing from the result array.
6034  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
6035  *  \param [in] old2New - C array of length equal to \a this->getNumberOfTuples()
6036  *     giving a new position for i-th old tuple and giving negative position for
6037  *     for i-th old tuple that should be omitted.
6038  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
6039  *          is to delete using decrRef() as it is no more needed.
6040  */
6041 DataArrayInt *DataArrayInt::renumberAndReduce(const int *old2New, int newNbOfTuple) const
6042 {
6043   checkAllocated();
6044   int nbTuples=getNumberOfTuples();
6045   int nbOfCompo=getNumberOfComponents();
6046   DataArrayInt *ret=DataArrayInt::New();
6047   ret->alloc(newNbOfTuple,nbOfCompo);
6048   const int *iptr=getConstPointer();
6049   int *optr=ret->getPointer();
6050   for(int i=0;i<nbTuples;i++)
6051     {
6052       int w=old2New[i];
6053       if(w>=0)
6054         std::copy(iptr+i*nbOfCompo,iptr+(i+1)*nbOfCompo,optr+w*nbOfCompo);
6055     }
6056   ret->copyStringInfoFrom(*this);
6057   return ret;
6058 }
6059
6060 /*!
6061  * Returns a shorten and permuted copy of \a this array. The new DataArrayInt is
6062  * of size \a new2OldEnd - \a new2OldBg and it's values are permuted as required by
6063  * \a new2OldBg array.
6064  * The values are permuted so that  \c new[ i ] = \c old[ \a new2OldBg[ i ]].
6065  * This method is equivalent to renumberAndReduce() except that convention in input is
6066  * \c new2old and \b not \c old2new.
6067  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
6068  *  \param [in] new2OldBg - pointer to the beginning of a permutation array that gives a
6069  *              tuple index in \a this array to fill the i-th tuple in the new array.
6070  *  \param [in] new2OldEnd - specifies the end of the permutation array that starts at
6071  *              \a new2OldBg, so that pointer to a tuple index (\a pi) varies as this:
6072  *              \a new2OldBg <= \a pi < \a new2OldEnd.
6073  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
6074  *          is to delete using decrRef() as it is no more needed.
6075  */
6076 DataArrayInt *DataArrayInt::selectByTupleId(const int *new2OldBg, const int *new2OldEnd) const
6077 {
6078   checkAllocated();
6079   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6080   int nbComp=getNumberOfComponents();
6081   ret->alloc((int)std::distance(new2OldBg,new2OldEnd),nbComp);
6082   ret->copyStringInfoFrom(*this);
6083   int *pt=ret->getPointer();
6084   const int *srcPt=getConstPointer();
6085   int i=0;
6086   for(const int *w=new2OldBg;w!=new2OldEnd;w++,i++)
6087     std::copy(srcPt+(*w)*nbComp,srcPt+((*w)+1)*nbComp,pt+i*nbComp);
6088   ret->copyStringInfoFrom(*this);
6089   return ret.retn();
6090 }
6091
6092 /*!
6093  * Returns a shorten and permuted copy of \a this array. The new DataArrayInt is
6094  * of size \a new2OldEnd - \a new2OldBg and it's values are permuted as required by
6095  * \a new2OldBg array.
6096  * The values are permuted so that  \c new[ i ] = \c old[ \a new2OldBg[ i ]].
6097  * This method is equivalent to renumberAndReduce() except that convention in input is
6098  * \c new2old and \b not \c old2new.
6099  * This method is equivalent to selectByTupleId() except that it prevents coping data
6100  * from behind the end of \a this array.
6101  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
6102  *  \param [in] new2OldBg - pointer to the beginning of a permutation array that gives a
6103  *              tuple index in \a this array to fill the i-th tuple in the new array.
6104  *  \param [in] new2OldEnd - specifies the end of the permutation array that starts at
6105  *              \a new2OldBg, so that pointer to a tuple index (\a pi) varies as this:
6106  *              \a new2OldBg <= \a pi < \a new2OldEnd.
6107  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
6108  *          is to delete using decrRef() as it is no more needed.
6109  *  \throw If \a new2OldEnd - \a new2OldBg > \a this->getNumberOfTuples().
6110  */
6111 DataArrayInt *DataArrayInt::selectByTupleIdSafe(const int *new2OldBg, const int *new2OldEnd) const throw(INTERP_KERNEL::Exception)
6112 {
6113   checkAllocated();
6114   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6115   int nbComp=getNumberOfComponents();
6116   int oldNbOfTuples=getNumberOfTuples();
6117   ret->alloc((int)std::distance(new2OldBg,new2OldEnd),nbComp);
6118   ret->copyStringInfoFrom(*this);
6119   int *pt=ret->getPointer();
6120   const int *srcPt=getConstPointer();
6121   int i=0;
6122   for(const int *w=new2OldBg;w!=new2OldEnd;w++,i++)
6123     if(*w>=0 && *w<oldNbOfTuples)
6124       std::copy(srcPt+(*w)*nbComp,srcPt+((*w)+1)*nbComp,pt+i*nbComp);
6125     else
6126       throw INTERP_KERNEL::Exception("DataArrayInt::selectByTupleIdSafe : some ids has been detected to be out of [0,this->getNumberOfTuples) !");
6127   ret->copyStringInfoFrom(*this);
6128   return ret.retn();
6129 }
6130
6131 /*!
6132  * Returns a shorten copy of \a this array. The new DataArrayInt contains every
6133  * (\a bg + \c i * \a step)-th tuple of \a this array located before the \a end2-th
6134  * tuple. Indices of the selected tuples are the same as ones returned by the Python
6135  * command \c range( \a bg, \a end2, \a step ).
6136  * This method is equivalent to selectByTupleIdSafe() except that the input array is
6137  * not constructed explicitly.
6138  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
6139  *  \param [in] bg - index of the first tuple to copy from \a this array.
6140  *  \param [in] end2 - index of the tuple before which the tuples to copy are located.
6141  *  \param [in] step - index increment to get index of the next tuple to copy.
6142  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
6143  *          is to delete using decrRef() as it is no more needed.
6144  *  \throw If (\a end2 < \a bg) or (\a step <= 0).
6145  *  \sa DataArrayInt::substr.
6146  */
6147 DataArrayInt *DataArrayInt::selectByTupleId2(int bg, int end2, int step) const throw(INTERP_KERNEL::Exception)
6148 {
6149   checkAllocated();
6150   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6151   int nbComp=getNumberOfComponents();
6152   int newNbOfTuples=GetNumberOfItemGivenBES(bg,end2,step,"DataArrayInt::selectByTupleId2 : ");
6153   ret->alloc(newNbOfTuples,nbComp);
6154   int *pt=ret->getPointer();
6155   const int *srcPt=getConstPointer()+bg*nbComp;
6156   for(int i=0;i<newNbOfTuples;i++,srcPt+=step*nbComp)
6157     std::copy(srcPt,srcPt+nbComp,pt+i*nbComp);
6158   ret->copyStringInfoFrom(*this);
6159   return ret.retn();
6160 }
6161
6162 /*!
6163  * Returns a shorten copy of \a this array. The new DataArrayInt contains ranges
6164  * of tuples specified by \a ranges parameter.
6165  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
6166  *  \param [in] ranges - std::vector of std::pair's each of which defines a range
6167  *              of tuples in [\c begin,\c end) format.
6168  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
6169  *          is to delete using decrRef() as it is no more needed.
6170  *  \throw If \a end < \a begin.
6171  *  \throw If \a end > \a this->getNumberOfTuples().
6172  *  \throw If \a this is not allocated.
6173  */
6174 DataArrayInt *DataArrayInt::selectByTupleRanges(const std::vector<std::pair<int,int> >& ranges) const throw(INTERP_KERNEL::Exception)
6175 {
6176   checkAllocated();
6177   int nbOfComp=getNumberOfComponents();
6178   int nbOfTuplesThis=getNumberOfTuples();
6179   if(ranges.empty())
6180     {
6181       MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6182       ret->alloc(0,nbOfComp);
6183       ret->copyStringInfoFrom(*this);
6184       return ret.retn();
6185     }
6186   int ref=ranges.front().first;
6187   int nbOfTuples=0;
6188   bool isIncreasing=true;
6189   for(std::vector<std::pair<int,int> >::const_iterator it=ranges.begin();it!=ranges.end();it++)
6190     {
6191       if((*it).first<=(*it).second)
6192         {
6193           if((*it).first>=0 && (*it).second<=nbOfTuplesThis)
6194             {
6195               nbOfTuples+=(*it).second-(*it).first;
6196               if(isIncreasing)
6197                 isIncreasing=ref<=(*it).first;
6198               ref=(*it).second;
6199             }
6200           else
6201             {
6202               std::ostringstream oss; oss << "DataArrayInt::selectByTupleRanges : on range #" << std::distance(ranges.begin(),it);
6203               oss << " (" << (*it).first << "," << (*it).second << ") is greater than number of tuples of this :" << nbOfTuples << " !";
6204               throw INTERP_KERNEL::Exception(oss.str().c_str());
6205             }
6206         }
6207       else
6208         {
6209           std::ostringstream oss; oss << "DataArrayInt::selectByTupleRanges : on range #" << std::distance(ranges.begin(),it);
6210           oss << " (" << (*it).first << "," << (*it).second << ") end is before begin !";
6211           throw INTERP_KERNEL::Exception(oss.str().c_str());
6212         }
6213     }
6214   if(isIncreasing && nbOfTuplesThis==nbOfTuples)
6215     return deepCpy();
6216   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6217   ret->alloc(nbOfTuples,nbOfComp);
6218   ret->copyStringInfoFrom(*this);
6219   const int *src=getConstPointer();
6220   int *work=ret->getPointer();
6221   for(std::vector<std::pair<int,int> >::const_iterator it=ranges.begin();it!=ranges.end();it++)
6222     work=std::copy(src+(*it).first*nbOfComp,src+(*it).second*nbOfComp,work);
6223   return ret.retn();
6224 }
6225
6226 /*!
6227  * Returns a new DataArrayInt containing a renumbering map in "Old to New" mode.
6228  * This map, if applied to \a this array, would make it sorted. For example, if
6229  * \a this array contents are [9,10,0,6,4,11,3,7] then the contents of the result array
6230  * are [5,6,0,3,2,7,1,4]; if this result array (\a res) is used as an argument in call
6231  * \a this->renumber(\a res) then the returned array contains [0,3,4,6,7,9,10,11].
6232  * This method is useful for renumbering (in MED file for example). For more info
6233  * on renumbering see \ref MEDCouplingArrayRenumbering.
6234  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
6235  *          array using decrRef() as it is no more needed.
6236  *  \throw If \a this is not allocated.
6237  *  \throw If \a this->getNumberOfComponents() != 1.
6238  *  \throw If there are equal values in \a this array.
6239  */
6240 DataArrayInt *DataArrayInt::checkAndPreparePermutation() const throw(INTERP_KERNEL::Exception)
6241 {
6242   checkAllocated();
6243   if(getNumberOfComponents()!=1)
6244     throw INTERP_KERNEL::Exception("DataArrayInt::checkAndPreparePermutation : number of components must == 1 !");
6245   int nbTuples=getNumberOfTuples();
6246   const int *pt=getConstPointer();
6247   int *pt2=CheckAndPreparePermutation(pt,pt+nbTuples);
6248   DataArrayInt *ret=DataArrayInt::New();
6249   ret->useArray(pt2,true,CPP_DEALLOC,nbTuples,1);
6250   return ret;
6251 }
6252
6253 /*!
6254  * Returns two arrays describing a surjective mapping from \a this set of values (\a A)
6255  * onto a set of values of size \a targetNb (\a B). The surjective function is 
6256  * \a B[ \a A[ i ]] = i. That is to say that for each \a id in [0,\a targetNb), where \a
6257  * targetNb < \a this->getNumberOfTuples(), there exists at least one tupleId (\a tid) so
6258  * that <em> this->getIJ( tid, 0 ) == id</em>. <br>
6259  * The first of out arrays returns indices of elements of \a this array, grouped by their
6260  * place in the set \a B. The second out array is the index of the first one; it shows how
6261  * many elements of \a A are mapped into each element of \a B. <br>
6262  * For more info on
6263  * mapping and its usage in renumbering see \ref MEDCouplingArrayRenumbering. <br>
6264  * \b Example:
6265  * - \a this: [0,3,2,3,2,2,1,2]
6266  * - \a targetNb: 4
6267  * - \a arr:  [0,  6,  2,4,5,7,  1,3]
6268  * - \a arrI: [0,1,2,6,8]
6269  *
6270  * This result means: <br>
6271  * the element of \a B 0 encounters within \a A once (\a arrI[ 0+1 ] - \a arrI[ 0 ]) and
6272  * its index within \a A is 0 ( \a arr[ 0:1 ] == \a arr[ \a arrI[ 0 ] : \a arrI[ 0+1 ]]);<br>
6273  * the element of \a B 2 encounters within \a A 4 times (\a arrI[ 2+1 ] - \a arrI[ 2 ]) and
6274  * its indices within \a A are [2,4,5,7] ( \a arr[ 2:6 ] == \a arr[ \a arrI[ 2 ] : 
6275  * \a arrI[ 2+1 ]]); <br> etc.
6276  *  \param [in] targetNb - the size of the set \a B. \a targetNb must be equal or more
6277  *         than the maximal value of \a A.
6278  *  \param [out] arr - a new instance of DataArrayInt returning indices of
6279  *         elements of \a this, grouped by their place in the set \a B. The caller is to delete
6280  *         this array using decrRef() as it is no more needed.
6281  *  \param [out] arrI - a new instance of DataArrayInt returning size of groups of equal
6282  *         elements of \a this. The caller is to delete this array using decrRef() as it
6283  *         is no more needed.
6284  *  \throw If \a this is not allocated.
6285  *  \throw If \a this->getNumberOfComponents() != 1.
6286  *  \throw If any value in \a this is more or equal to \a targetNb.
6287  */
6288 void DataArrayInt::changeSurjectiveFormat(int targetNb, DataArrayInt *&arr, DataArrayInt *&arrI) const throw(INTERP_KERNEL::Exception)
6289 {
6290   checkAllocated();
6291   if(getNumberOfComponents()!=1)
6292     throw INTERP_KERNEL::Exception("DataArrayInt::changeSurjectiveFormat : number of components must == 1 !");
6293   int nbOfTuples=getNumberOfTuples();
6294   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New());
6295   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> retI(DataArrayInt::New());
6296   retI->alloc(targetNb+1,1);
6297   const int *input=getConstPointer();
6298   std::vector< std::vector<int> > tmp(targetNb);
6299   for(int i=0;i<nbOfTuples;i++)
6300     {
6301       int tmp2=input[i];
6302       if(tmp2>=0 && tmp2<targetNb)
6303         tmp[tmp2].push_back(i);
6304       else
6305         {
6306           std::ostringstream oss; oss << "DataArrayInt::changeSurjectiveFormat : At pos " << i << " presence of element " << tmp2 << " ! should be in [0," << targetNb << ") !";
6307           throw INTERP_KERNEL::Exception(oss.str().c_str());
6308         }
6309     }
6310   int *retIPtr=retI->getPointer();
6311   *retIPtr=0;
6312   for(std::vector< std::vector<int> >::const_iterator it1=tmp.begin();it1!=tmp.end();it1++,retIPtr++)
6313     retIPtr[1]=retIPtr[0]+(int)((*it1).size());
6314   if(nbOfTuples!=retI->getIJ(targetNb,0))
6315     throw INTERP_KERNEL::Exception("DataArrayInt::changeSurjectiveFormat : big problem should never happen !");
6316   ret->alloc(nbOfTuples,1);
6317   int *retPtr=ret->getPointer();
6318   for(std::vector< std::vector<int> >::const_iterator it1=tmp.begin();it1!=tmp.end();it1++)
6319     retPtr=std::copy((*it1).begin(),(*it1).end(),retPtr);
6320   arr=ret.retn();
6321   arrI=retI.retn();
6322 }
6323
6324
6325 /*!
6326  * Returns a new DataArrayInt containing a renumbering map in "Old to New" mode computed
6327  * from a zip representation of a surjective format (returned e.g. by
6328  * \ref ParaMEDMEM::DataArrayDouble::findCommonTuples() "DataArrayDouble::findCommonTuples()"
6329  * for example). The result array minimizes the permutation. <br>
6330  * For more info on renumbering see \ref MEDCouplingArrayRenumbering. <br>
6331  * \b Example: <br>
6332  * - \a nbOfOldTuples: 10 
6333  * - \a arr          : [0,3, 5,7,9]
6334  * - \a arrIBg       : [0,2,5]
6335  * - \a newNbOfTuples: 7
6336  * - result array    : [0,1,2,0,3,4,5,4,6,4]
6337  *
6338  *  \param [in] nbOfOldTuples - number of tuples in the initial array \a arr.
6339  *  \param [in] arr - the array of tuple indices grouped by \a arrIBg array.
6340  *  \param [in] arrIBg - the array dividing all indices stored in \a arr into groups of
6341  *         (indices of) equal values. Its every element (except the last one) points to
6342  *         the first element of a group of equal values.
6343  *  \param [in] arrIEnd - specifies the end of \a arrIBg, so that the last element of \a
6344  *          arrIBg is \a arrIEnd[ -1 ].
6345  *  \param [out] newNbOfTuples - number of tuples after surjection application.
6346  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
6347  *          array using decrRef() as it is no more needed.
6348  *  \throw If any value of \a arr breaks condition ( 0 <= \a arr[ i ] < \a nbOfOldTuples ).
6349  */
6350 DataArrayInt *DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2(int nbOfOldTuples, const int *arr, const int *arrIBg, const int *arrIEnd, int &newNbOfTuples) throw(INTERP_KERNEL::Exception)
6351 {
6352   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6353   ret->alloc(nbOfOldTuples,1);
6354   int *pt=ret->getPointer();
6355   std::fill(pt,pt+nbOfOldTuples,-1);
6356   int nbOfGrps=((int)std::distance(arrIBg,arrIEnd))-1;
6357   const int *cIPtr=arrIBg;
6358   for(int i=0;i<nbOfGrps;i++)
6359     pt[arr[cIPtr[i]]]=-(i+2);
6360   int newNb=0;
6361   for(int iNode=0;iNode<nbOfOldTuples;iNode++)
6362     {
6363       if(pt[iNode]<0)
6364         {
6365           if(pt[iNode]==-1)
6366             pt[iNode]=newNb++;
6367           else
6368             {
6369               int grpId=-(pt[iNode]+2);
6370               for(int j=cIPtr[grpId];j<cIPtr[grpId+1];j++)
6371                 {
6372                   if(arr[j]>=0 && arr[j]<nbOfOldTuples)
6373                     pt[arr[j]]=newNb;
6374                   else
6375                     {
6376                       std::ostringstream oss; oss << "DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2 : With element #" << j << " value is " << arr[j] << " should be in [0," << nbOfOldTuples << ") !";
6377                       throw INTERP_KERNEL::Exception(oss.str().c_str());
6378                     }
6379                 }
6380               newNb++;
6381             }
6382         }
6383     }
6384   newNbOfTuples=newNb;
6385   return ret.retn();
6386 }
6387
6388 /*!
6389  * Returns a new DataArrayInt containing a renumbering map in "New to Old" mode,
6390  * which if applied to \a this array would make it sorted ascendingly.
6391  * For more info on renumbering see \ref MEDCouplingArrayRenumbering. <br>
6392  * \b Example: <br>
6393  * - \a this: [2,0,1,1,0,1,2,0,1,1,0,0]
6394  * - result: [10,0,5,6,1,7,11,2,8,9,3,4]
6395  * - after applying result to \a this: [0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2] 
6396  *
6397  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
6398  *          array using decrRef() as it is no more needed.
6399  *  \throw If \a this is not allocated.
6400  *  \throw If \a this->getNumberOfComponents() != 1.
6401  */
6402 DataArrayInt *DataArrayInt::buildPermArrPerLevel() const throw(INTERP_KERNEL::Exception)
6403 {
6404   checkAllocated();
6405   if(getNumberOfComponents()!=1)
6406     throw INTERP_KERNEL::Exception("DataArrayInt::buildPermArrPerLevel : number of components must == 1 !");
6407   int nbOfTuples=getNumberOfTuples();
6408   const int *pt=getConstPointer();
6409   std::map<int,int> m;
6410   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6411   ret->alloc(nbOfTuples,1);
6412   int *opt=ret->getPointer();
6413   for(int i=0;i<nbOfTuples;i++,pt++,opt++)
6414     {
6415       int val=*pt;
6416       std::map<int,int>::iterator it=m.find(val);
6417       if(it!=m.end())
6418         {
6419           *opt=(*it).second;
6420           (*it).second++;
6421         }
6422       else
6423         {
6424           *opt=0;
6425           m.insert(std::pair<int,int>(val,1));
6426         }
6427     }
6428   int sum=0;
6429   for(std::map<int,int>::iterator it=m.begin();it!=m.end();it++)
6430     {
6431       int vt=(*it).second;
6432       (*it).second=sum;
6433       sum+=vt;
6434     }
6435   pt=getConstPointer();
6436   opt=ret->getPointer();
6437   for(int i=0;i<nbOfTuples;i++,pt++,opt++)
6438     *opt+=m[*pt];
6439   //
6440   return ret.retn();
6441 }
6442
6443 /*!
6444  * Checks if contents of \a this array are equal to that of an array filled with
6445  * iota(). This method is particularly useful for DataArrayInt instances that represent
6446  * a renumbering array to check the real need in renumbering. 
6447  *  \return bool - \a true if \a this array contents == \a range( \a this->getNumberOfTuples())
6448  *  \throw If \a this is not allocated.
6449  *  \throw If \a this->getNumberOfComponents() != 1.
6450  */
6451 bool DataArrayInt::isIdentity() const throw(INTERP_KERNEL::Exception)
6452 {
6453   checkAllocated();
6454   if(getNumberOfComponents()!=1)
6455     return false;
6456   int nbOfTuples=getNumberOfTuples();
6457   const int *pt=getConstPointer();
6458   for(int i=0;i<nbOfTuples;i++,pt++)
6459     if(*pt!=i)
6460       return false;
6461   return true;
6462 }
6463
6464 /*!
6465  * Checks if all values in \a this array are equal to \a val.
6466  *  \param [in] val - value to check equality of array values to.
6467  *  \return bool - \a true if all values are \a val.
6468  *  \throw If \a this is not allocated.
6469  *  \throw If \a this->getNumberOfComponents() != 1
6470  */
6471 bool DataArrayInt::isUniform(int val) const throw(INTERP_KERNEL::Exception)
6472 {
6473   checkAllocated();
6474   if(getNumberOfComponents()!=1)
6475     throw INTERP_KERNEL::Exception("DataArrayInt::isUniform : must be applied on DataArrayInt with only one component, you can call 'rearrange' method before !");
6476   int nbOfTuples=getNumberOfTuples();
6477   const int *w=getConstPointer();
6478   const int *end2=w+nbOfTuples;
6479   for(;w!=end2;w++)
6480     if(*w!=val)
6481       return false;
6482   return true;
6483 }
6484
6485 /*!
6486  * Creates a new DataArrayDouble and assigns all (textual and numerical) data of \a this
6487  * array to the new one.
6488  *  \return DataArrayDouble * - the new instance of DataArrayInt.
6489  */
6490 DataArrayDouble *DataArrayInt::convertToDblArr() const
6491 {
6492   checkAllocated();
6493   DataArrayDouble *ret=DataArrayDouble::New();
6494   ret->alloc(getNumberOfTuples(),getNumberOfComponents());
6495   int nbOfVals=getNbOfElems();
6496   const int *src=getConstPointer();
6497   double *dest=ret->getPointer();
6498   std::copy(src,src+nbOfVals,dest);
6499   ret->copyStringInfoFrom(*this);
6500   return ret;
6501 }
6502
6503 /*!
6504  * Returns a shorten copy of \a this array. The new DataArrayInt contains all
6505  * tuples starting from the \a tupleIdBg-th tuple and including all tuples located before
6506  * the \a tupleIdEnd-th one. This methods has a similar behavior as std::string::substr().
6507  * This method is a specialization of selectByTupleId2().
6508  *  \param [in] tupleIdBg - index of the first tuple to copy from \a this array.
6509  *  \param [in] tupleIdEnd - index of the tuple before which the tuples to copy are located.
6510  *          If \a tupleIdEnd == -1, all the tuples till the end of \a this array are copied.
6511  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
6512  *          is to delete using decrRef() as it is no more needed.
6513  *  \throw If \a tupleIdBg < 0.
6514  *  \throw If \a tupleIdBg > \a this->getNumberOfTuples().
6515     \throw If \a tupleIdEnd != -1 && \a tupleIdEnd < \a this->getNumberOfTuples().
6516  *  \sa DataArrayInt::selectByTupleId2
6517  */
6518 DataArrayInt *DataArrayInt::substr(int tupleIdBg, int tupleIdEnd) const throw(INTERP_KERNEL::Exception)
6519 {
6520   checkAllocated();
6521   int nbt=getNumberOfTuples();
6522   if(tupleIdBg<0)
6523     throw INTERP_KERNEL::Exception("DataArrayInt::substr : The tupleIdBg parameter must be greater than 0 !");
6524   if(tupleIdBg>nbt)
6525     throw INTERP_KERNEL::Exception("DataArrayInt::substr : The tupleIdBg parameter is greater than number of tuples !");
6526   int trueEnd=tupleIdEnd;
6527   if(tupleIdEnd!=-1)
6528     {
6529       if(tupleIdEnd>nbt)
6530         throw INTERP_KERNEL::Exception("DataArrayInt::substr : The tupleIdBg parameter is greater or equal than number of tuples !");
6531     }
6532   else
6533     trueEnd=nbt;
6534   int nbComp=getNumberOfComponents();
6535   DataArrayInt *ret=DataArrayInt::New();
6536   ret->alloc(trueEnd-tupleIdBg,nbComp);
6537   ret->copyStringInfoFrom(*this);
6538   std::copy(getConstPointer()+tupleIdBg*nbComp,getConstPointer()+trueEnd*nbComp,ret->getPointer());
6539   return ret;
6540 }
6541
6542 /*!
6543  * Changes the number of components within \a this array so that its raw data **does
6544  * not** change, instead splitting this data into tuples changes.
6545  *  \param [in] newNbOfComp - number of components for \a this array to have.
6546  *  \throw If \a this is not allocated
6547  *  \throw If getNbOfElems() % \a newNbOfCompo != 0.
6548  *  \warning This method erases all (name and unit) component info set before!
6549  */
6550 void DataArrayInt::rearrange(int newNbOfCompo) throw(INTERP_KERNEL::Exception)
6551 {
6552   checkAllocated();
6553   int nbOfElems=getNbOfElems();
6554   if(nbOfElems%newNbOfCompo!=0)
6555     throw INTERP_KERNEL::Exception("DataArrayInt::rearrange : nbOfElems%newNbOfCompo!=0 !");
6556   _info_on_compo.clear();
6557   _info_on_compo.resize(newNbOfCompo);
6558   declareAsNew();
6559 }
6560
6561 /*!
6562  * Changes the number of components within \a this array to be equal to its number
6563  * of tuples, and inversely its number of tuples to become equal to its number of 
6564  * components. So that its raw data **does not** change, instead splitting this
6565  * data into tuples changes.
6566  *  \throw If \a this is not allocated.
6567  *  \warning This method erases all (name and unit) component info set before!
6568  *  \warning Do not confuse this method with fromNoInterlace() and toNoInterlace()!
6569  *  \sa rearrange()
6570  */
6571 void DataArrayInt::transpose() throw(INTERP_KERNEL::Exception)
6572 {
6573   checkAllocated();
6574   int nbOfTuples=getNumberOfTuples();
6575   rearrange(nbOfTuples);
6576 }
6577
6578 /*!
6579  * Returns a shorten or extended copy of \a this array. If \a newNbOfComp is less
6580  * than \a this->getNumberOfComponents() then the result array is shorten as each tuple
6581  * is truncated to have \a newNbOfComp components, keeping first components. If \a
6582  * newNbOfComp is more than \a this->getNumberOfComponents() then the result array is
6583  * expanded as each tuple is populated with \a dftValue to have \a newNbOfComp
6584  * components.  
6585  *  \param [in] newNbOfComp - number of components for the new array to have.
6586  *  \param [in] dftValue - value assigned to new values added to the new array.
6587  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
6588  *          is to delete using decrRef() as it is no more needed.
6589  *  \throw If \a this is not allocated.
6590  */
6591 DataArrayInt *DataArrayInt::changeNbOfComponents(int newNbOfComp, int dftValue) const throw(INTERP_KERNEL::Exception)
6592 {
6593   checkAllocated();
6594   DataArrayInt *ret=DataArrayInt::New();
6595   ret->alloc(getNumberOfTuples(),newNbOfComp);
6596   const int *oldc=getConstPointer();
6597   int *nc=ret->getPointer();
6598   int nbOfTuples=getNumberOfTuples();
6599   int oldNbOfComp=getNumberOfComponents();
6600   int dim=std::min(oldNbOfComp,newNbOfComp);
6601   for(int i=0;i<nbOfTuples;i++)
6602     {
6603       int j=0;
6604       for(;j<dim;j++)
6605         nc[newNbOfComp*i+j]=oldc[i*oldNbOfComp+j];
6606       for(;j<newNbOfComp;j++)
6607         nc[newNbOfComp*i+j]=dftValue;
6608     }
6609   ret->setName(getName().c_str());
6610   for(int i=0;i<dim;i++)
6611     ret->setInfoOnComponent(i,getInfoOnComponent(i).c_str());
6612   ret->setName(getName().c_str());
6613   return ret;
6614 }
6615
6616 /*!
6617  * Changes number of tuples in the array. If the new number of tuples is smaller
6618  * than the current number the array is truncated, otherwise the array is extended.
6619  *  \param [in] nbOfTuples - new number of tuples. 
6620  *  \throw If \a this is not allocated.
6621  */
6622 void DataArrayInt::reAlloc(int nbOfTuples) throw(INTERP_KERNEL::Exception)
6623 {
6624   checkAllocated();
6625   _mem.reAlloc(getNumberOfComponents()*nbOfTuples);
6626   declareAsNew();
6627 }
6628
6629
6630 /*!
6631  * Returns a copy of \a this array composed of selected components.
6632  * The new DataArrayInt has the same number of tuples but includes components
6633  * specified by \a compoIds parameter. So that getNbOfElems() of the result array
6634  * can be either less, same or more than \a this->getNbOfElems().
6635  *  \param [in] compoIds - sequence of zero based indices of components to include
6636  *              into the new array.
6637  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
6638  *          is to delete using decrRef() as it is no more needed.
6639  *  \throw If \a this is not allocated.
6640  *  \throw If a component index (\a i) is not valid: 
6641  *         \a i < 0 || \a i >= \a this->getNumberOfComponents().
6642  *
6643  *  \ref cpp_mcdataarrayint_keepselectedcomponents "Here is a Python example".
6644  */
6645 DataArrayInt *DataArrayInt::keepSelectedComponents(const std::vector<int>& compoIds) const throw(INTERP_KERNEL::Exception)
6646 {
6647   checkAllocated();
6648   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New());
6649   int newNbOfCompo=(int)compoIds.size();
6650   int oldNbOfCompo=getNumberOfComponents();
6651   for(std::vector<int>::const_iterator it=compoIds.begin();it!=compoIds.end();it++)
6652     DataArray::CheckValueInRange(oldNbOfCompo,(*it),"keepSelectedComponents invalid requested component");
6653   int nbOfTuples=getNumberOfTuples();
6654   ret->alloc(nbOfTuples,newNbOfCompo);
6655   ret->copyPartOfStringInfoFrom(*this,compoIds);
6656   const int *oldc=getConstPointer();
6657   int *nc=ret->getPointer();
6658   for(int i=0;i<nbOfTuples;i++)
6659     for(int j=0;j<newNbOfCompo;j++,nc++)
6660       *nc=oldc[i*oldNbOfCompo+compoIds[j]];
6661   return ret.retn();
6662 }
6663
6664 /*!
6665  * Appends components of another array to components of \a this one, tuple by tuple.
6666  * So that the number of tuples of \a this array remains the same and the number of 
6667  * components increases.
6668  *  \param [in] other - the DataArrayInt to append to \a this one.
6669  *  \throw If \a this is not allocated.
6670  *  \throw If \a this and \a other arrays have different number of tuples.
6671  *
6672  *  \ref cpp_mcdataarrayint_meldwith "Here is a C++ example".
6673  *
6674  *  \ref py_mcdataarrayint_meldwith "Here is a Python example".
6675  */
6676 void DataArrayInt::meldWith(const DataArrayInt *other) throw(INTERP_KERNEL::Exception)
6677 {
6678   if(!other)
6679     throw INTERP_KERNEL::Exception("DataArrayInt::meldWith : DataArrayInt pointer in input is NULL !");
6680   checkAllocated();
6681   other->checkAllocated();
6682   int nbOfTuples=getNumberOfTuples();
6683   if(nbOfTuples!=other->getNumberOfTuples())
6684     throw INTERP_KERNEL::Exception("DataArrayInt::meldWith : mismatch of number of tuples !");
6685   int nbOfComp1=getNumberOfComponents();
6686   int nbOfComp2=other->getNumberOfComponents();
6687   int *newArr=new int[nbOfTuples*(nbOfComp1+nbOfComp2)];
6688   int *w=newArr;
6689   const int *inp1=getConstPointer();
6690   const int *inp2=other->getConstPointer();
6691   for(int i=0;i<nbOfTuples;i++,inp1+=nbOfComp1,inp2+=nbOfComp2)
6692     {
6693       w=std::copy(inp1,inp1+nbOfComp1,w);
6694       w=std::copy(inp2,inp2+nbOfComp2,w);
6695     }
6696   useArray(newArr,true,CPP_DEALLOC,nbOfTuples,nbOfComp1+nbOfComp2);
6697   std::vector<int> compIds(nbOfComp2);
6698   for(int i=0;i<nbOfComp2;i++)
6699     compIds[i]=nbOfComp1+i;
6700   copyPartOfStringInfoFrom2(compIds,*other);
6701 }
6702
6703 /*!
6704  * Copy all components in a specified order from another DataArrayInt.
6705  * The specified components become the first ones in \a this array.
6706  * Both numerical and textual data is copied. The number of tuples in \a this and
6707  * the other array can be different.
6708  *  \param [in] a - the array to copy data from.
6709  *  \param [in] compoIds - sequence of zero based indices of components, data of which is
6710  *              to be copied.
6711  *  \throw If \a a is NULL.
6712  *  \throw If \a compoIds.size() != \a a->getNumberOfComponents().
6713  *  \throw If \a compoIds[i] < 0 or \a compoIds[i] > \a this->getNumberOfComponents().
6714  *
6715  *  \ref cpp_mcdataarrayint_setselectedcomponents "Here is a Python example".
6716  */
6717 void DataArrayInt::setSelectedComponents(const DataArrayInt *a, const std::vector<int>& compoIds) throw(INTERP_KERNEL::Exception)
6718 {
6719   if(!a)
6720     throw INTERP_KERNEL::Exception("DataArrayInt::setSelectedComponents : input DataArrayInt is NULL !");
6721   checkAllocated();
6722   a->checkAllocated();
6723   copyPartOfStringInfoFrom2(compoIds,*a);
6724   std::size_t partOfCompoSz=compoIds.size();
6725   int nbOfCompo=getNumberOfComponents();
6726   int nbOfTuples=std::min(getNumberOfTuples(),a->getNumberOfTuples());
6727   const int *ac=a->getConstPointer();
6728   int *nc=getPointer();
6729   for(int i=0;i<nbOfTuples;i++)
6730     for(std::size_t j=0;j<partOfCompoSz;j++,ac++)
6731       nc[nbOfCompo*i+compoIds[j]]=*ac;
6732 }
6733
6734 /*!
6735  * Copy all values from another DataArrayInt into specified tuples and components
6736  * of \a this array. Textual data is not copied.
6737  * The tree parameters defining set of indices of tuples and components are similar to
6738  * the tree parameters of the Python function \c range(\c start,\c stop,\c step).
6739  *  \param [in] a - the array to copy values from.
6740  *  \param [in] bgTuples - index of the first tuple of \a this array to assign values to.
6741  *  \param [in] endTuples - index of the tuple before which the tuples to assign to
6742  *              are located.
6743  *  \param [in] stepTuples - index increment to get index of the next tuple to assign to.
6744  *  \param [in] bgComp - index of the first component of \a this array to assign values to.
6745  *  \param [in] endComp - index of the component before which the components to assign
6746  *              to are located.
6747  *  \param [in] stepComp - index increment to get index of the next component to assign to.
6748  *  \param [in] strictCompoCompare - if \a true (by default), then \a a->getNumberOfComponents() 
6749  *              must be equal to the number of columns to assign to, else an
6750  *              exception is thrown; if \a false, then it is only required that \a
6751  *              a->getNbOfElems() equals to number of values to assign to (this condition
6752  *              must be respected even if \a strictCompoCompare is \a true). The number of 
6753  *              values to assign to is given by following Python expression:
6754  *              \a nbTargetValues = 
6755  *              \c len(\c range(\a bgTuples,\a endTuples,\a stepTuples)) *
6756  *              \c len(\c range(\a bgComp,\a endComp,\a stepComp)).
6757  *  \throw If \a a is NULL.
6758  *  \throw If \a a is not allocated.
6759  *  \throw If \a this is not allocated.
6760  *  \throw If parameters specifying tuples and components to assign to do not give a
6761  *            non-empty range of increasing indices.
6762  *  \throw If \a a->getNbOfElems() != \a nbTargetValues.
6763  *  \throw If \a strictCompoCompare == \a true && \a a->getNumberOfComponents() !=
6764  *            \c len(\c range(\a bgComp,\a endComp,\a stepComp)).
6765  *
6766  *  \ref cpp_mcdataarrayint_setpartofvalues1 "Here is a Python example".
6767  */
6768 void DataArrayInt::setPartOfValues1(const DataArrayInt *a, int bgTuples, int endTuples, int stepTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare) throw(INTERP_KERNEL::Exception)
6769 {
6770   if(!a)
6771     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValues1 : DataArrayInt pointer in input is NULL !");
6772   const char msg[]="DataArrayInt::setPartOfValues1";
6773   checkAllocated();
6774   a->checkAllocated();
6775   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
6776   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
6777   int nbComp=getNumberOfComponents();
6778   int nbOfTuples=getNumberOfTuples();
6779   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
6780   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
6781   bool assignTech=true;
6782   if(a->getNbOfElems()==newNbOfTuples*newNbOfComp)
6783     {
6784       if(strictCompoCompare)
6785         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
6786     }
6787   else
6788     {
6789       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
6790       assignTech=false;
6791     }
6792   int *pt=getPointer()+bgTuples*nbComp+bgComp;
6793   const int *srcPt=a->getConstPointer();
6794   if(assignTech)
6795     {
6796       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
6797         for(int j=0;j<newNbOfComp;j++,srcPt++)
6798           pt[j*stepComp]=*srcPt;
6799     }
6800   else
6801     {
6802       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
6803         {
6804           const int *srcPt2=srcPt;
6805           for(int j=0;j<newNbOfComp;j++,srcPt2++)
6806             pt[j*stepComp]=*srcPt2;
6807         }
6808     }
6809 }
6810
6811 /*!
6812  * Assign a given value to values at specified tuples and components of \a this array.
6813  * The tree parameters defining set of indices of tuples and components are similar to
6814  * the tree parameters of the Python function \c range(\c start,\c stop,\c step)..
6815  *  \param [in] a - the value to assign.
6816  *  \param [in] bgTuples - index of the first tuple of \a this array to assign to.
6817  *  \param [in] endTuples - index of the tuple before which the tuples to assign to
6818  *              are located.
6819  *  \param [in] stepTuples - index increment to get index of the next tuple to assign to.
6820  *  \param [in] bgComp - index of the first component of \a this array to assign to.
6821  *  \param [in] endComp - index of the component before which the components to assign
6822  *              to are located.
6823  *  \param [in] stepComp - index increment to get index of the next component to assign to.
6824  *  \throw If \a this is not allocated.
6825  *  \throw If parameters specifying tuples and components to assign to, do not give a
6826  *            non-empty range of increasing indices or indices are out of a valid range
6827  *            for \this array.
6828  *
6829  *  \ref cpp_mcdataarrayint_setpartofvaluessimple1 "Here is a Python example".
6830  */
6831 void DataArrayInt::setPartOfValuesSimple1(int a, int bgTuples, int endTuples, int stepTuples, int bgComp, int endComp, int stepComp) throw(INTERP_KERNEL::Exception)
6832 {
6833   const char msg[]="DataArrayInt::setPartOfValuesSimple1";
6834   checkAllocated();
6835   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
6836   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
6837   int nbComp=getNumberOfComponents();
6838   int nbOfTuples=getNumberOfTuples();
6839   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
6840   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
6841   int *pt=getPointer()+bgTuples*nbComp+bgComp;
6842   for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
6843     for(int j=0;j<newNbOfComp;j++)
6844       pt[j*stepComp]=a;
6845 }
6846
6847
6848 /*!
6849  * Copy all values from another DataArrayInt (\a a) into specified tuples and 
6850  * components of \a this array. Textual data is not copied.
6851  * The tuples and components to assign to are defined by C arrays of indices.
6852  * There are two *modes of usage*:
6853  * - If \a a->getNbOfElems() equals to number of values to assign to, then every value
6854  *   of \a a is assigned to its own location within \a this array. 
6855  * - If \a a includes one tuple, then all values of \a a are assigned to the specified
6856  *   components of every specified tuple of \a this array. In this mode it is required
6857  *   that \a a->getNumberOfComponents() equals to the number of specified components.
6858  * 
6859  *  \param [in] a - the array to copy values from.
6860  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
6861  *              assign values of \a a to.
6862  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
6863  *              pointer to a tuple index <em>(pi)</em> varies as this: 
6864  *              \a bgTuples <= \a pi < \a endTuples.
6865  *  \param [in] bgComp - pointer to an array of component indices of \a this array to
6866  *              assign values of \a a to.
6867  *  \param [in] endComp - specifies the end of the array \a bgTuples, so that
6868  *              pointer to a component index <em>(pi)</em> varies as this: 
6869  *              \a bgComp <= \a pi < \a endComp.
6870  *  \param [in] strictCompoCompare - this parameter is checked only if the
6871  *               *mode of usage* is the first; if it is \a true (default), 
6872  *               then \a a->getNumberOfComponents() must be equal 
6873  *               to the number of specified columns, else this is not required.
6874  *  \throw If \a a is NULL.
6875  *  \throw If \a a is not allocated.
6876  *  \throw If \a this is not allocated.
6877  *  \throw If any index of tuple/component given by <em>bgTuples / bgComp</em> is
6878  *         out of a valid range for \a this array.
6879  *  \throw In the first *mode of usage*, if <em>strictCompoCompare == true </em> and
6880  *         if <em> a->getNumberOfComponents() != (endComp - bgComp) </em>.
6881  *  \throw In the second *mode of usage*, if \a a->getNumberOfTuples() != 1 or
6882  *         <em> a->getNumberOfComponents() != (endComp - bgComp)</em>.
6883  *
6884  *  \ref cpp_mcdataarrayint_setpartofvalues2 "Here is a Python example".
6885  */
6886 void DataArrayInt::setPartOfValues2(const DataArrayInt *a, const int *bgTuples, const int *endTuples, const int *bgComp, const int *endComp, bool strictCompoCompare) throw(INTERP_KERNEL::Exception)
6887 {
6888   if(!a)
6889     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValues2 : DataArrayInt pointer in input is NULL !");
6890   const char msg[]="DataArrayInt::setPartOfValues2";
6891   checkAllocated();
6892   a->checkAllocated();
6893   int nbComp=getNumberOfComponents();
6894   int nbOfTuples=getNumberOfTuples();
6895   for(const int *z=bgComp;z!=endComp;z++)
6896     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
6897   int newNbOfTuples=(int)std::distance(bgTuples,endTuples);
6898   int newNbOfComp=(int)std::distance(bgComp,endComp);
6899   bool assignTech=true;
6900   if(a->getNbOfElems()==newNbOfTuples*newNbOfComp)
6901     {
6902       if(strictCompoCompare)
6903         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
6904     }
6905   else
6906     {
6907       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
6908       assignTech=false;
6909     }
6910   int *pt=getPointer();
6911   const int *srcPt=a->getConstPointer();
6912   if(assignTech)
6913     {    
6914       for(const int *w=bgTuples;w!=endTuples;w++)
6915         {
6916           DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
6917           for(const int *z=bgComp;z!=endComp;z++,srcPt++)
6918             {    
6919               pt[(*w)*nbComp+(*z)]=*srcPt;
6920             }
6921         }
6922     }
6923   else
6924     {
6925       for(const int *w=bgTuples;w!=endTuples;w++)
6926         {
6927           const int *srcPt2=srcPt;
6928           DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
6929           for(const int *z=bgComp;z!=endComp;z++,srcPt2++)
6930             {    
6931               pt[(*w)*nbComp+(*z)]=*srcPt2;
6932             }
6933         }
6934     }
6935 }
6936
6937 /*!
6938  * Assign a given value to values at specified tuples and components of \a this array.
6939  * The tuples and components to assign to are defined by C arrays of indices.
6940  *  \param [in] a - the value to assign.
6941  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
6942  *              assign \a a to.
6943  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
6944  *              pointer to a tuple index (\a pi) varies as this: 
6945  *              \a bgTuples <= \a pi < \a endTuples.
6946  *  \param [in] bgComp - pointer to an array of component indices of \a this array to
6947  *              assign \a a to.
6948  *  \param [in] endComp - specifies the end of the array \a bgTuples, so that
6949  *              pointer to a component index (\a pi) varies as this: 
6950  *              \a bgComp <= \a pi < \a endComp.
6951  *  \throw If \a this is not allocated.
6952  *  \throw If any index of tuple/component given by <em>bgTuples / bgComp</em> is
6953  *         out of a valid range for \a this array.
6954  *
6955  *  \ref cpp_mcdataarrayint_setpartofvaluessimple2 "Here is a Python example".
6956  */
6957 void DataArrayInt::setPartOfValuesSimple2(int a, const int *bgTuples, const int *endTuples, const int *bgComp, const int *endComp) throw(INTERP_KERNEL::Exception)
6958 {
6959   checkAllocated();
6960   int nbComp=getNumberOfComponents();
6961   int nbOfTuples=getNumberOfTuples();
6962   for(const int *z=bgComp;z!=endComp;z++)
6963     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
6964   int *pt=getPointer();
6965   for(const int *w=bgTuples;w!=endTuples;w++)
6966     for(const int *z=bgComp;z!=endComp;z++)
6967       {
6968         DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
6969         pt[(*w)*nbComp+(*z)]=a;
6970       }
6971 }
6972
6973 /*!
6974  * Copy all values from another DataArrayInt (\a a) into specified tuples and 
6975  * components of \a this array. Textual data is not copied.
6976  * The tuples to assign to are defined by a C array of indices.
6977  * The components to assign to are defined by three values similar to parameters of
6978  * the Python function \c range(\c start,\c stop,\c step).
6979  * There are two *modes of usage*:
6980  * - If \a a->getNbOfElems() equals to number of values to assign to, then every value
6981  *   of \a a is assigned to its own location within \a this array. 
6982  * - If \a a includes one tuple, then all values of \a a are assigned to the specified
6983  *   components of every specified tuple of \a this array. In this mode it is required
6984  *   that \a a->getNumberOfComponents() equals to the number of specified components.
6985  *
6986  *  \param [in] a - the array to copy values from.
6987  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
6988  *              assign values of \a a to.
6989  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
6990  *              pointer to a tuple index <em>(pi)</em> varies as this: 
6991  *              \a bgTuples <= \a pi < \a endTuples.
6992  *  \param [in] bgComp - index of the first component of \a this array to assign to.
6993  *  \param [in] endComp - index of the component before which the components to assign
6994  *              to are located.
6995  *  \param [in] stepComp - index increment to get index of the next component to assign to.
6996  *  \param [in] strictCompoCompare - this parameter is checked only in the first
6997  *               *mode of usage*; if \a strictCompoCompare is \a true (default), 
6998  *               then \a a->getNumberOfComponents() must be equal 
6999  *               to the number of specified columns, else this is not required.
7000  *  \throw If \a a is NULL.
7001  *  \throw If \a a is not allocated.
7002  *  \throw If \a this is not allocated.
7003  *  \throw If any index of tuple given by \a bgTuples is out of a valid range for 
7004  *         \a this array.
7005  *  \throw In the first *mode of usage*, if <em>strictCompoCompare == true </em> and
7006  *         if <em> a->getNumberOfComponents()</em> is unequal to the number of components
7007  *         defined by <em>(bgComp,endComp,stepComp)</em>.
7008  *  \throw In the second *mode of usage*, if \a a->getNumberOfTuples() != 1 or
7009  *         <em> a->getNumberOfComponents()</em> is unequal to the number of components
7010  *         defined by <em>(bgComp,endComp,stepComp)</em>.
7011  *  \throw If parameters specifying components to assign to, do not give a
7012  *            non-empty range of increasing indices or indices are out of a valid range
7013  *            for \this array.
7014  *
7015  *  \ref cpp_mcdataarrayint_setpartofvalues3 "Here is a Python example".
7016  */
7017 void DataArrayInt::setPartOfValues3(const DataArrayInt *a, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare) throw(INTERP_KERNEL::Exception)
7018 {
7019   if(!a)
7020     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValues3 : DataArrayInt pointer in input is NULL !");
7021   const char msg[]="DataArrayInt::setPartOfValues3";
7022   checkAllocated();
7023   a->checkAllocated();
7024   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
7025   int nbComp=getNumberOfComponents();
7026   int nbOfTuples=getNumberOfTuples();
7027   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
7028   int newNbOfTuples=(int)std::distance(bgTuples,endTuples);
7029   bool assignTech=true;
7030   if(a->getNbOfElems()==newNbOfTuples*newNbOfComp)
7031     {
7032       if(strictCompoCompare)
7033         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
7034     }
7035   else
7036     {
7037       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
7038       assignTech=false;
7039     }
7040   int *pt=getPointer()+bgComp;
7041   const int *srcPt=a->getConstPointer();
7042   if(assignTech)
7043     {
7044       for(const int *w=bgTuples;w!=endTuples;w++)
7045         for(int j=0;j<newNbOfComp;j++,srcPt++)
7046           {
7047             DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
7048             pt[(*w)*nbComp+j*stepComp]=*srcPt;
7049           }
7050     }
7051   else
7052     {
7053       for(const int *w=bgTuples;w!=endTuples;w++)
7054         {
7055           const int *srcPt2=srcPt;
7056           for(int j=0;j<newNbOfComp;j++,srcPt2++)
7057             {
7058               DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
7059               pt[(*w)*nbComp+j*stepComp]=*srcPt2;
7060             }
7061         }
7062     }
7063 }
7064
7065 /*!
7066  * Assign a given value to values at specified tuples and components of \a this array.
7067  * The tuples to assign to are defined by a C array of indices.
7068  * The components to assign to are defined by three values similar to parameters of
7069  * the Python function \c range(\c start,\c stop,\c step).
7070  *  \param [in] a - the value to assign.
7071  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
7072  *              assign \a a to.
7073  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
7074  *              pointer to a tuple index <em>(pi)</em> varies as this: 
7075  *              \a bgTuples <= \a pi < \a endTuples.
7076  *  \param [in] bgComp - index of the first component of \a this array to assign to.
7077  *  \param [in] endComp - index of the component before which the components to assign
7078  *              to are located.
7079  *  \param [in] stepComp - index increment to get index of the next component to assign to.
7080  *  \throw If \a this is not allocated.
7081  *  \throw If any index of tuple given by \a bgTuples is out of a valid range for 
7082  *         \a this array.
7083  *  \throw If parameters specifying components to assign to, do not give a
7084  *            non-empty range of increasing indices or indices are out of a valid range
7085  *            for \this array.
7086  *
7087  *  \ref cpp_mcdataarrayint_setpartofvaluessimple3 "Here is a Python example".
7088  */
7089 void DataArrayInt::setPartOfValuesSimple3(int a, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp) throw(INTERP_KERNEL::Exception)
7090 {
7091   const char msg[]="DataArrayInt::setPartOfValuesSimple3";
7092   checkAllocated();
7093   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
7094   int nbComp=getNumberOfComponents();
7095   int nbOfTuples=getNumberOfTuples();
7096   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
7097   int *pt=getPointer()+bgComp;
7098   for(const int *w=bgTuples;w!=endTuples;w++)
7099     for(int j=0;j<newNbOfComp;j++)
7100       {
7101         DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
7102         pt[(*w)*nbComp+j*stepComp]=a;
7103       }
7104 }
7105
7106 void DataArrayInt::setPartOfValues4(const DataArrayInt *a, int bgTuples, int endTuples, int stepTuples, const int *bgComp, const int *endComp, bool strictCompoCompare) throw(INTERP_KERNEL::Exception)
7107 {
7108   if(!a)
7109     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValues4 : input DataArrayInt is NULL !");
7110   const char msg[]="DataArrayInt::setPartOfValues4";
7111   checkAllocated();
7112   a->checkAllocated();
7113   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
7114   int newNbOfComp=(int)std::distance(bgComp,endComp);
7115   int nbComp=getNumberOfComponents();
7116   for(const int *z=bgComp;z!=endComp;z++)
7117     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
7118   int nbOfTuples=getNumberOfTuples();
7119   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
7120   bool assignTech=true;
7121   if(a->getNbOfElems()==newNbOfTuples*newNbOfComp)
7122     {
7123       if(strictCompoCompare)
7124         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
7125     }
7126   else
7127     {
7128       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
7129       assignTech=false;
7130     }
7131   const int *srcPt=a->getConstPointer();
7132   int *pt=getPointer()+bgTuples*nbComp;
7133   if(assignTech)
7134     {
7135       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
7136         for(const int *z=bgComp;z!=endComp;z++,srcPt++)
7137           pt[*z]=*srcPt;
7138     }
7139   else
7140     {
7141       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
7142         {
7143           const int *srcPt2=srcPt;
7144           for(const int *z=bgComp;z!=endComp;z++,srcPt2++)
7145             pt[*z]=*srcPt2;
7146         }
7147     }
7148 }
7149
7150 void DataArrayInt::setPartOfValuesSimple4(int a, int bgTuples, int endTuples, int stepTuples, const int *bgComp, const int *endComp) throw(INTERP_KERNEL::Exception)
7151 {
7152   const char msg[]="DataArrayInt::setPartOfValuesSimple4";
7153   checkAllocated();
7154   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
7155   int nbComp=getNumberOfComponents();
7156   for(const int *z=bgComp;z!=endComp;z++)
7157     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
7158   int nbOfTuples=getNumberOfTuples();
7159   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
7160   int *pt=getPointer()+bgTuples*nbComp;
7161   for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
7162     for(const int *z=bgComp;z!=endComp;z++)
7163       pt[*z]=a;
7164 }
7165
7166 /*!
7167  * Copy some tuples from another DataArrayInt into specified tuples
7168  * of \a this array. Textual data is not copied. Both arrays must have equal number of
7169  * components.
7170  * Both the tuples to assign and the tuples to assign to are defined by a DataArrayInt.
7171  * All components of selected tuples are copied.
7172  *  \param [in] a - the array to copy values from.
7173  *  \param [in] tuplesSelec - the array specifying both source tuples of \a a and
7174  *              target tuples of \a this. \a tuplesSelec has two components, and the
7175  *              first component specifies index of the source tuple and the second
7176  *              one specifies index of the target tuple.
7177  *  \throw If \a this is not allocated.
7178  *  \throw If \a a is NULL.
7179  *  \throw If \a a is not allocated.
7180  *  \throw If \a tuplesSelec is NULL.
7181  *  \throw If \a tuplesSelec is not allocated.
7182  *  \throw If <em>this->getNumberOfComponents() != a->getNumberOfComponents()</em>.
7183  *  \throw If \a tuplesSelec->getNumberOfComponents() != 2.
7184  *  \throw If any tuple index given by \a tuplesSelec is out of a valid range for 
7185  *         the corresponding (\a this or \a a) array.
7186  */
7187 void DataArrayInt::setPartOfValuesAdv(const DataArrayInt *a, const DataArrayInt *tuplesSelec) throw(INTERP_KERNEL::Exception)
7188 {
7189   if(!a || !tuplesSelec)
7190     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValuesAdv : DataArrayInt pointer in input is NULL !");
7191   checkAllocated();
7192   a->checkAllocated();
7193   tuplesSelec->checkAllocated();
7194   int nbOfComp=getNumberOfComponents();
7195   if(nbOfComp!=a->getNumberOfComponents())
7196     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValuesAdv : This and a do not have the same number of components !");
7197   if(tuplesSelec->getNumberOfComponents()!=2)
7198     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValuesAdv : Expecting to have a tuple selector DataArrayInt instance with exactly 2 components !");
7199   int thisNt=getNumberOfTuples();
7200   int aNt=a->getNumberOfTuples();
7201   int *valsToSet=getPointer();
7202   const int *valsSrc=a->getConstPointer();
7203   for(const int *tuple=tuplesSelec->begin();tuple!=tuplesSelec->end();tuple+=2)
7204     {
7205       if(tuple[1]>=0 && tuple[1]<aNt)
7206         {
7207           if(tuple[0]>=0 && tuple[0]<thisNt)
7208             std::copy(valsSrc+nbOfComp*tuple[1],valsSrc+nbOfComp*(tuple[1]+1),valsToSet+nbOfComp*tuple[0]);
7209           else
7210             {
7211               std::ostringstream oss; oss << "DataArrayInt::setPartOfValuesAdv : Tuple #" << std::distance(tuplesSelec->begin(),tuple)/2;
7212               oss << " of 'tuplesSelec' request of tuple id #" << tuple[0] << " in 'this' ! It should be in [0," << thisNt << ") !";
7213               throw INTERP_KERNEL::Exception(oss.str().c_str());
7214             }
7215         }
7216       else
7217         {
7218           std::ostringstream oss; oss << "DataArrayInt::setPartOfValuesAdv : Tuple #" << std::distance(tuplesSelec->begin(),tuple)/2;
7219           oss << " of 'tuplesSelec' request of tuple id #" << tuple[1] << " in 'a' ! It should be in [0," << aNt << ") !";
7220           throw INTERP_KERNEL::Exception(oss.str().c_str());
7221         }
7222     }
7223 }
7224
7225 /*!
7226  * Copy some tuples from another DataArrayInt (\a a) into contiguous tuples
7227  * of \a this array. Textual data is not copied. Both arrays must have equal number of
7228  * components.
7229  * The tuples to assign to are defined by index of the first tuple, and
7230  * their number is defined by \a tuplesSelec->getNumberOfTuples().
7231  * The tuples to copy are defined by values of a DataArrayInt.
7232  * All components of selected tuples are copied.
7233  *  \param [in] tupleIdStart - index of the first tuple of \a this array to assign
7234  *              values to.
7235  *  \param [in] a - the array to copy values from.
7236  *  \param [in] tuplesSelec - the array specifying tuples of \a a to copy.
7237  *  \throw If \a this is not allocated.
7238  *  \throw If \a a is NULL.
7239  *  \throw If \a a is not allocated.
7240  *  \throw If \a tuplesSelec is NULL.
7241  *  \throw If \a tuplesSelec is not allocated.
7242  *  \throw If <em>this->getNumberOfComponents() != a->getNumberOfComponents()</em>.
7243  *  \throw If \a tuplesSelec->getNumberOfComponents() != 1.
7244  *  \throw If <em>tupleIdStart + tuplesSelec->getNumberOfTuples() > this->getNumberOfTuples().</em>
7245  *  \throw If any tuple index given by \a tuplesSelec is out of a valid range for 
7246  *         \a a array.
7247  */
7248 void DataArrayInt::setContigPartOfSelectedValues(int tupleIdStart, const DataArrayInt*a, const DataArrayInt *tuplesSelec) throw(INTERP_KERNEL::Exception)
7249 {
7250   checkAllocated();
7251   a->checkAllocated();
7252   tuplesSelec->checkAllocated();
7253   int nbOfComp=getNumberOfComponents();
7254   if(nbOfComp!=a->getNumberOfComponents())
7255     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues : This and a do not have the same number of components !");
7256   if(tuplesSelec->getNumberOfComponents()!=1)
7257     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues : Expecting to have a tuple selector DataArrayInt instance with exactly 1 component !");
7258   int thisNt=getNumberOfTuples();
7259   int aNt=a->getNumberOfTuples();
7260   int nbOfTupleToWrite=tuplesSelec->getNumberOfTuples();
7261   int *valsToSet=getPointer()+tupleIdStart*nbOfComp;
7262   if(tupleIdStart+nbOfTupleToWrite>thisNt)
7263     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues : invalid number range of values to write !");
7264   const int *valsSrc=a->getConstPointer();
7265   for(const int *tuple=tuplesSelec->begin();tuple!=tuplesSelec->end();tuple++,valsToSet+=nbOfComp)
7266     {
7267       if(*tuple>=0 && *tuple<aNt)
7268         {
7269           std::copy(valsSrc+nbOfComp*(*tuple),valsSrc+nbOfComp*(*tuple+1),valsToSet);
7270         }
7271       else
7272         {
7273           std::ostringstream oss; oss << "DataArrayInt::setContigPartOfSelectedValues : Tuple #" << std::distance(tuplesSelec->begin(),tuple);
7274           oss << " of 'tuplesSelec' request of tuple id #" << *tuple << " in 'a' ! It should be in [0," << aNt << ") !";
7275           throw INTERP_KERNEL::Exception(oss.str().c_str());
7276         }
7277     }
7278 }
7279
7280 /*!
7281  * Copy some tuples from another DataArrayInt (\a a) into contiguous tuples
7282  * of \a this array. Textual data is not copied. Both arrays must have equal number of
7283  * components.
7284  * The tuples to copy are defined by three values similar to parameters of
7285  * the Python function \c range(\c start,\c stop,\c step).
7286  * The tuples to assign to are defined by index of the first tuple, and
7287  * their number is defined by number of tuples to copy.
7288  * All components of selected tuples are copied.
7289  *  \param [in] tupleIdStart - index of the first tuple of \a this array to assign
7290  *              values to.
7291  *  \param [in] a - the array to copy values from.
7292  *  \param [in] bg - index of the first tuple to copy of the array \a a.
7293  *  \param [in] end2 - index of the tuple of \a a before which the tuples to copy
7294  *              are located.
7295  *  \param [in] step - index increment to get index of the next tuple to copy.
7296  *  \throw If \a this is not allocated.
7297  *  \throw If \a a is NULL.
7298  *  \throw If \a a is not allocated.
7299  *  \throw If <em>this->getNumberOfComponents() != a->getNumberOfComponents()</em>.
7300  *  \throw If <em>tupleIdStart + len(range(bg,end2,step)) > this->getNumberOfTuples().</em>
7301  *  \throw If parameters specifying tuples to copy, do not give a
7302  *            non-empty range of increasing indices or indices are out of a valid range
7303  *            for the array \a a.
7304  */
7305 void DataArrayInt::setContigPartOfSelectedValues2(int tupleIdStart, const DataArrayInt *a, int bg, int end2, int step) throw(INTERP_KERNEL::Exception)
7306 {
7307   checkAllocated();
7308   a->checkAllocated();
7309   int nbOfComp=getNumberOfComponents();
7310   const char msg[]="DataArrayInt::setContigPartOfSelectedValues2";
7311   int nbOfTupleToWrite=DataArray::GetNumberOfItemGivenBES(bg,end2,step,msg);
7312   if(nbOfComp!=a->getNumberOfComponents())
7313     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues2 : This and a do not have the same number of components !");
7314   int thisNt=getNumberOfTuples();
7315   int aNt=a->getNumberOfTuples();
7316   int *valsToSet=getPointer()+tupleIdStart*nbOfComp;
7317   if(tupleIdStart+nbOfTupleToWrite>thisNt)
7318     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues2 : invalid number range of values to write !");
7319   if(end2>aNt)
7320     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues2 : invalid range of values to read !");
7321   const int *valsSrc=a->getConstPointer()+bg*nbOfComp;
7322   for(int i=0;i<nbOfTupleToWrite;i++,valsToSet+=nbOfComp,valsSrc+=step*nbOfComp)
7323     {
7324       std::copy(valsSrc,valsSrc+nbOfComp,valsToSet);
7325     }
7326 }
7327
7328 /*!
7329  * Returns a value located at specified tuple and component.
7330  * This method is equivalent to DataArrayInt::getIJ() except that validity of
7331  * parameters is checked. So this method is safe but expensive if used to go through
7332  * all values of \a this.
7333  *  \param [in] tupleId - index of tuple of interest.
7334  *  \param [in] compoId - index of component of interest.
7335  *  \return double - value located by \a tupleId and \a compoId.
7336  *  \throw If \a this is not allocated.
7337  *  \throw If condition <em>( 0 <= tupleId < this->getNumberOfTuples() )</em> is violated.
7338  *  \throw If condition <em>( 0 <= compoId < this->getNumberOfComponents() )</em> is violated.
7339  */
7340 int DataArrayInt::getIJSafe(int tupleId, int compoId) const throw(INTERP_KERNEL::Exception)
7341 {
7342   checkAllocated();
7343   if(tupleId<0 || tupleId>=getNumberOfTuples())
7344     {
7345       std::ostringstream oss; oss << "DataArrayInt::getIJSafe : request for tupleId " << tupleId << " should be in [0," << getNumberOfTuples() << ") !";
7346       throw INTERP_KERNEL::Exception(oss.str().c_str());
7347     }
7348   if(compoId<0 || compoId>=getNumberOfComponents())
7349     {
7350       std::ostringstream oss; oss << "DataArrayInt::getIJSafe : request for compoId " << compoId << " should be in [0," << getNumberOfComponents() << ") !";
7351       throw INTERP_KERNEL::Exception(oss.str().c_str());
7352     }
7353   return _mem[tupleId*((int)_info_on_compo.size())+compoId];
7354 }
7355
7356 /*!
7357  * Returns the last value of \a this. 
7358  *  \return double - the last value of \a this array.
7359  *  \throw If \a this is not allocated.
7360  *  \throw If \a this->getNumberOfComponents() != 1.
7361  *  \throw If \a this->getNumberOfTuples() < 1.
7362  */
7363 int DataArrayInt::back() const throw(INTERP_KERNEL::Exception)
7364 {
7365   checkAllocated();
7366   if(getNumberOfComponents()!=1)
7367     throw INTERP_KERNEL::Exception("DataArrayInt::back : number of components not equal to one !");
7368   int nbOfTuples=getNumberOfTuples();
7369   if(nbOfTuples<1)
7370     throw INTERP_KERNEL::Exception("DataArrayInt::back : number of tuples must be >= 1 !");
7371   return *(getConstPointer()+nbOfTuples-1);
7372 }
7373
7374 /*!
7375  * Assign pointer to one array to a pointer to another appay. Reference counter of
7376  * \a arrayToSet is incremented / decremented.
7377  *  \param [in] newArray - the pointer to array to assign to \a arrayToSet.
7378  *  \param [in,out] arrayToSet - the pointer to array to assign to.
7379  */
7380 void DataArrayInt::SetArrayIn(DataArrayInt *newArray, DataArrayInt* &arrayToSet)
7381 {
7382   if(newArray!=arrayToSet)
7383     {
7384       if(arrayToSet)
7385         arrayToSet->decrRef();
7386       arrayToSet=newArray;
7387       if(arrayToSet)
7388         arrayToSet->incrRef();
7389     }
7390 }
7391
7392 DataArrayIntIterator *DataArrayInt::iterator()
7393 {
7394   return new DataArrayIntIterator(this);
7395 }
7396
7397 /*!
7398  * Creates a new DataArrayInt containing IDs (indices) of tuples holding value equal to a
7399  * given one.
7400  *  \param [in] val - the value to find within \a this.
7401  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
7402  *          array using decrRef() as it is no more needed.
7403  *  \throw If \a this is not allocated.
7404  *  \throw If \a this->getNumberOfComponents() != 1.
7405  */
7406 DataArrayInt *DataArrayInt::getIdsEqual(int val) const throw(INTERP_KERNEL::Exception)
7407 {
7408   checkAllocated();
7409   if(getNumberOfComponents()!=1)
7410     throw INTERP_KERNEL::Exception("DataArrayInt::getIdsEqual : the array must have only one component, you can call 'rearrange' method before !");
7411   const int *cptr=getConstPointer();
7412   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
7413   int nbOfTuples=getNumberOfTuples();
7414   for(int i=0;i<nbOfTuples;i++,cptr++)
7415     if(*cptr==val)
7416       ret->pushBackSilent(i);
7417   return ret.retn();
7418 }
7419
7420 /*!
7421  * Creates a new DataArrayInt containing IDs (indices) of tuples holding value \b not
7422  * equal to a given one. 
7423  *  \param [in] val - the value to ignore within \a this.
7424  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
7425  *          array using decrRef() as it is no more needed.
7426  *  \throw If \a this is not allocated.
7427  *  \throw If \a this->getNumberOfComponents() != 1.
7428  */
7429 DataArrayInt *DataArrayInt::getIdsNotEqual(int val) const throw(INTERP_KERNEL::Exception)
7430 {
7431   checkAllocated();
7432   if(getNumberOfComponents()!=1)
7433     throw INTERP_KERNEL::Exception("DataArrayInt::getIdsNotEqual : the array must have only one component, you can call 'rearrange' method before !");
7434   const int *cptr=getConstPointer();
7435   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
7436   int nbOfTuples=getNumberOfTuples();
7437   for(int i=0;i<nbOfTuples;i++,cptr++)
7438     if(*cptr!=val)
7439       ret->pushBackSilent(i);
7440   return ret.retn();
7441 }
7442
7443
7444 /*!
7445  * Assigns \a newValue to all elements holding \a oldValue within \a this
7446  * one-dimensional array.
7447  *  \param [in] oldValue - the value to replace.
7448  *  \param [in] newValue - the value to assign.
7449  *  \return int - number of replacements performed.
7450  *  \throw If \a this is not allocated.
7451  *  \throw If \a this->getNumberOfComponents() != 1.
7452  */
7453 int DataArrayInt::changeValue(int oldValue, int newValue) throw(INTERP_KERNEL::Exception)
7454 {
7455   checkAllocated();
7456   if(getNumberOfComponents()!=1)
7457     throw INTERP_KERNEL::Exception("DataArrayInt::changeValue : the array must have only one component, you can call 'rearrange' method before !");
7458   int *start=getPointer();
7459   int *end2=start+getNbOfElems();
7460   int ret=0;
7461   for(int *val=start;val!=end2;val++)
7462     {
7463       if(*val==oldValue)
7464         {
7465           *val=newValue;
7466           ret++;
7467         }
7468     }
7469   return ret;
7470 }
7471
7472 /*!
7473  * Creates a new DataArrayInt containing IDs (indices) of tuples holding value equal to
7474  * one of given values.
7475  *  \param [in] valsBg - an array of values to find within \a this array.
7476  *  \param [in] valsEnd - specifies the end of the array \a valsBg, so that
7477  *              the last value of \a valsBg is \a valsEnd[ -1 ].
7478  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
7479  *          array using decrRef() as it is no more needed.
7480  *  \throw If \a this->getNumberOfComponents() != 1.
7481  */
7482 DataArrayInt *DataArrayInt::getIdsEqualList(const int *valsBg, const int *valsEnd) const throw(INTERP_KERNEL::Exception)
7483 {
7484   if(getNumberOfComponents()!=1)
7485     throw INTERP_KERNEL::Exception("DataArrayInt::getIdsEqualList : the array must have only one component, you can call 'rearrange' method before !");
7486   std::set<int> vals2(valsBg,valsEnd);
7487   const int *cptr=getConstPointer();
7488   std::vector<int> res;
7489   int nbOfTuples=getNumberOfTuples();
7490   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
7491   for(int i=0;i<nbOfTuples;i++,cptr++)
7492     if(vals2.find(*cptr)!=vals2.end())
7493       ret->pushBackSilent(i);
7494   return ret.retn();
7495 }
7496
7497 /*!
7498  * Creates a new DataArrayInt containing IDs (indices) of tuples holding values \b not
7499  * equal to any of given values.
7500  *  \param [in] valsBg - an array of values to ignore within \a this array.
7501  *  \param [in] valsEnd - specifies the end of the array \a valsBg, so that
7502  *              the last value of \a valsBg is \a valsEnd[ -1 ].
7503  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
7504  *          array using decrRef() as it is no more needed.
7505  *  \throw If \a this->getNumberOfComponents() != 1.
7506  */
7507 DataArrayInt *DataArrayInt::getIdsNotEqualList(const int *valsBg, const int *valsEnd) const throw(INTERP_KERNEL::Exception)
7508 {
7509   if(getNumberOfComponents()!=1)
7510     throw INTERP_KERNEL::Exception("DataArrayInt::getIdsNotEqualList : the array must have only one component, you can call 'rearrange' method before !");
7511   std::set<int> vals2(valsBg,valsEnd);
7512   const int *cptr=getConstPointer();
7513   std::vector<int> res;
7514   int nbOfTuples=getNumberOfTuples();
7515   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
7516   for(int i=0;i<nbOfTuples;i++,cptr++)
7517     if(vals2.find(*cptr)==vals2.end())
7518       ret->pushBackSilent(i);
7519   return ret.retn();
7520 }
7521
7522 /*!
7523  * This method is an extension of DataArrayInt::locateValue method because this method works for DataArrayInt with
7524  * any number of components excepted 0 (an INTERP_KERNEL::Exception is thrown in this case).
7525  * This method searches in \b this is there is a tuple that matched the input parameter \b tupl.
7526  * If any the tuple id is returned. If not -1 is returned.
7527  * 
7528  * This method throws an INTERP_KERNEL::Exception if the number of components in \b this mismatches with the size of
7529  * the input vector. An INTERP_KERNEL::Exception is thrown too if \b this is not allocated.
7530  *
7531  * \return tuple id where \b tupl is. -1 if no such tuple exists in \b this.
7532  * \sa DataArrayInt::search, DataArrayInt::presenceOfTuple.
7533  */
7534 int DataArrayInt::locateTuple(const std::vector<int>& tupl) const throw(INTERP_KERNEL::Exception)
7535 {
7536   checkAllocated();
7537   int nbOfCompo=getNumberOfComponents();
7538   if(nbOfCompo==0)
7539     throw INTERP_KERNEL::Exception("DataArrayInt::locateTuple : 0 components in 'this' !");
7540   if(nbOfCompo!=(int)tupl.size())
7541     {
7542       std::ostringstream oss; oss << "DataArrayInt::locateTuple : 'this' contains " << nbOfCompo << " components and searching for a tuple of length " << tupl.size() << " !";
7543       throw INTERP_KERNEL::Exception(oss.str().c_str());
7544     }
7545   const int *cptr=getConstPointer();
7546   int nbOfVals=getNbOfElems();
7547   for(const int *work=cptr;work!=cptr+nbOfVals;)
7548     {
7549       work=std::search(work,cptr+nbOfVals,tupl.begin(),tupl.end());
7550       if(work!=cptr+nbOfVals)
7551         {
7552           if(std::distance(cptr,work)%nbOfCompo!=0)
7553             work++;
7554           else
7555             return std::distance(cptr,work)/nbOfCompo;
7556         }
7557     }
7558   return -1;
7559 }
7560
7561 /*!
7562  * This method searches the sequence specified in input parameter \b vals in \b this.
7563  * This works only for DataArrayInt having number of components equal to one (if not an INTERP_KERNEL::Exception will be thrown).
7564  * This method differs from DataArrayInt::locateTuple in that the position is internal raw data is not considered here contrary to DataArrayInt::locateTuple.
7565  * \sa DataArrayInt::locateTuple
7566  */
7567 int DataArrayInt::search(const std::vector<int>& vals) const throw(INTERP_KERNEL::Exception)
7568 {
7569   checkAllocated();
7570   int nbOfCompo=getNumberOfComponents();
7571   if(nbOfCompo!=1)
7572     throw INTERP_KERNEL::Exception("DataArrayInt::search : works only for DataArrayInt instance with one component !");
7573   const int *cptr=getConstPointer();
7574   int nbOfVals=getNbOfElems();
7575   const int *loc=std::search(cptr,cptr+nbOfVals,vals.begin(),vals.end());
7576   if(loc!=cptr+nbOfVals)
7577     return std::distance(cptr,loc);
7578   return -1;
7579 }
7580
7581 /*!
7582  * This method expects to be called when number of components of this is equal to one.
7583  * This method returns the tuple id, if it exists, of the first tuple equal to \b value.
7584  * If not any tuple contains \b value -1 is returned.
7585  * \sa DataArrayInt::presenceOfValue
7586  */
7587 int DataArrayInt::locateValue(int value) const throw(INTERP_KERNEL::Exception)
7588 {
7589   checkAllocated();
7590   if(getNumberOfComponents()!=1)
7591     throw INTERP_KERNEL::Exception("DataArrayInt::presenceOfValue : the array must have only one component, you can call 'rearrange' method before !");
7592   const int *cptr=getConstPointer();
7593   int nbOfTuples=getNumberOfTuples();
7594   const int *ret=std::find(cptr,cptr+nbOfTuples,value);
7595   if(ret!=cptr+nbOfTuples)
7596     return std::distance(cptr,ret);
7597   return -1;
7598 }
7599
7600 /*!
7601  * This method expects to be called when number of components of this is equal to one.
7602  * This method returns the tuple id, if it exists, of the first tuple so that the value is contained in \b vals.
7603  * If not any tuple contains one of the values contained in 'vals' false is returned.
7604  * \sa DataArrayInt::presenceOfValue
7605  */
7606 int DataArrayInt::locateValue(const std::vector<int>& vals) const throw(INTERP_KERNEL::Exception)
7607 {
7608   checkAllocated();
7609   if(getNumberOfComponents()!=1)
7610     throw INTERP_KERNEL::Exception("DataArrayInt::presenceOfValue : the array must have only one component, you can call 'rearrange' method before !");
7611   std::set<int> vals2(vals.begin(),vals.end());
7612   const int *cptr=getConstPointer();
7613   int nbOfTuples=getNumberOfTuples();
7614   for(const int *w=cptr;w!=cptr+nbOfTuples;w++)
7615     if(vals2.find(*w)!=vals2.end())
7616       return std::distance(cptr,w);
7617   return -1;
7618 }
7619
7620 /*!
7621  * This method is an extension of DataArrayInt::presenceOfValue method because this method works for DataArrayInt with
7622  * any number of components excepted 0 (an INTERP_KERNEL::Exception is thrown in this case).
7623  * This method searches in \b this is there is a tuple that matched the input parameter \b tupl.
7624  * This method throws an INTERP_KERNEL::Exception if the number of components in \b this mismatches with the size of
7625  * the input vector. An INTERP_KERNEL::Exception is thrown too if \b this is not allocated.
7626  * \sa DataArrayInt::locateTuple
7627  */
7628 bool DataArrayInt::presenceOfTuple(const std::vector<int>& tupl) const throw(INTERP_KERNEL::Exception)
7629 {
7630   return locateTuple(tupl)!=-1;
7631 }
7632
7633
7634 /*!
7635  * Returns \a true if a given value is present within \a this one-dimensional array.
7636  *  \param [in] value - the value to find within \a this array.
7637  *  \return bool - \a true in case if \a value is present within \a this array.
7638  *  \throw If \a this is not allocated.
7639  *  \throw If \a this->getNumberOfComponents() != 1.
7640  *  \sa locateValue()
7641  */
7642 bool DataArrayInt::presenceOfValue(int value) const throw(INTERP_KERNEL::Exception)
7643 {
7644   return locateValue(value)!=-1;
7645 }
7646
7647 /*!
7648  * This method expects to be called when number of components of this is equal to one.
7649  * This method returns true if it exists a tuple so that the value is contained in \b vals.
7650  * If not any tuple contains one of the values contained in 'vals' false is returned.
7651  * \sa DataArrayInt::locateValue
7652  */
7653 bool DataArrayInt::presenceOfValue(const std::vector<int>& vals) const throw(INTERP_KERNEL::Exception)
7654 {
7655   return locateValue(vals)!=-1;
7656 }
7657
7658 /*!
7659  * Accumulates values of each component of \a this array.
7660  *  \param [out] res - an array of length \a this->getNumberOfComponents(), allocated 
7661  *         by the caller, that is filled by this method with sum value for each
7662  *         component.
7663  *  \throw If \a this is not allocated.
7664  */
7665 void DataArrayInt::accumulate(int *res) const throw(INTERP_KERNEL::Exception)
7666 {
7667   checkAllocated();
7668   const int *ptr=getConstPointer();
7669   int nbTuple=getNumberOfTuples();
7670   int nbComps=getNumberOfComponents();
7671   std::fill(res,res+nbComps,0);
7672   for(int i=0;i<nbTuple;i++)
7673     std::transform(ptr+i*nbComps,ptr+(i+1)*nbComps,res,res,std::plus<int>());
7674 }
7675
7676 int DataArrayInt::accumulate(int compId) const throw(INTERP_KERNEL::Exception)
7677 {
7678   checkAllocated();
7679   const int *ptr=getConstPointer();
7680   int nbTuple=getNumberOfTuples();
7681   int nbComps=getNumberOfComponents();
7682   if(compId<0 || compId>=nbComps)
7683     throw INTERP_KERNEL::Exception("DataArrayInt::accumulate : Invalid compId specified : No such nb of components !");
7684   int ret=0;
7685   for(int i=0;i<nbTuple;i++)
7686     ret+=ptr[i*nbComps+compId];
7687   return ret;
7688 }
7689
7690 /*!
7691  * Returns a new DataArrayInt by concatenating two given arrays, so that (1) the number
7692  * of tuples in the result array is <em> a1->getNumberOfTuples() + a2->getNumberOfTuples() -
7693  * offsetA2</em> and (2)
7694  * the number of component in the result array is same as that of each of given arrays.
7695  * First \a offsetA2 tuples of \a a2 are skipped and thus are missing from the result array.
7696  * Info on components is copied from the first of the given arrays. Number of components
7697  * in the given arrays must be the same.
7698  *  \param [in] a1 - an array to include in the result array.
7699  *  \param [in] a2 - another array to include in the result array.
7700  *  \param [in] offsetA2 - number of tuples of \a a2 to skip.
7701  *  \return DataArrayInt * - the new instance of DataArrayInt.
7702  *          The caller is to delete this result array using decrRef() as it is no more
7703  *          needed.
7704  *  \throw If either \a a1 or \a a2 is NULL.
7705  *  \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents().
7706  */
7707 DataArrayInt *DataArrayInt::Aggregate(const DataArrayInt *a1, const DataArrayInt *a2, int offsetA2)
7708 {
7709   if(!a1 || !a2)
7710     throw INTERP_KERNEL::Exception("DataArrayInt::Aggregate : input DataArrayInt instance is NULL !");
7711   int nbOfComp=a1->getNumberOfComponents();
7712   if(nbOfComp!=a2->getNumberOfComponents())
7713     throw INTERP_KERNEL::Exception("Nb of components mismatch for array Aggregation !");
7714   int nbOfTuple1=a1->getNumberOfTuples();
7715   int nbOfTuple2=a2->getNumberOfTuples();
7716   DataArrayInt *ret=DataArrayInt::New();
7717   ret->alloc(nbOfTuple1+nbOfTuple2-offsetA2,nbOfComp);
7718   int *pt=std::copy(a1->getConstPointer(),a1->getConstPointer()+nbOfTuple1*nbOfComp,ret->getPointer());
7719   std::copy(a2->getConstPointer()+offsetA2*nbOfComp,a2->getConstPointer()+nbOfTuple2*nbOfComp,pt);
7720   ret->copyStringInfoFrom(*a1);
7721   return ret;
7722 }
7723
7724 /*!
7725  * Returns a new DataArrayInt by concatenating all given arrays, so that (1) the number
7726  * of tuples in the result array is a sum of the number of tuples of given arrays and (2)
7727  * the number of component in the result array is same as that of each of given arrays.
7728  * Info on components is copied from the first of the given arrays. Number of components
7729  * in the given arrays must be  the same.
7730  *  \param [in] arr - a sequence of arrays to include in the result array.
7731  *  \return DataArrayInt * - the new instance of DataArrayInt.
7732  *          The caller is to delete this result array using decrRef() as it is no more
7733  *          needed.
7734  *  \throw If all arrays within \a arr are NULL.
7735  *  \throw If getNumberOfComponents() of arrays within \a arr.
7736  */
7737 DataArrayInt *DataArrayInt::Aggregate(const std::vector<const DataArrayInt *>& arr) throw(INTERP_KERNEL::Exception)
7738 {
7739   std::vector<const DataArrayInt *> a;
7740   for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
7741     if(*it4)
7742       a.push_back(*it4);
7743   if(a.empty())
7744     throw INTERP_KERNEL::Exception("DataArrayInt::Aggregate : input list must be NON EMPTY !");
7745   std::vector<const DataArrayInt *>::const_iterator it=a.begin();
7746   int nbOfComp=(*it)->getNumberOfComponents();
7747   int nbt=(*it++)->getNumberOfTuples();
7748   for(int i=1;it!=a.end();it++,i++)
7749     {
7750       if((*it)->getNumberOfComponents()!=nbOfComp)
7751         throw INTERP_KERNEL::Exception("DataArrayInt::Aggregate : Nb of components mismatch for array aggregation !");
7752       nbt+=(*it)->getNumberOfTuples();
7753     }
7754   DataArrayInt *ret=DataArrayInt::New();
7755   ret->alloc(nbt,nbOfComp);
7756   int *pt=ret->getPointer();
7757   for(it=a.begin();it!=a.end();it++)
7758     pt=std::copy((*it)->getConstPointer(),(*it)->getConstPointer()+(*it)->getNbOfElems(),pt);
7759   ret->copyStringInfoFrom(*(a[0]));
7760   return ret;
7761 }
7762
7763 /*!
7764  * Returns the maximal value and its location within \a this one-dimensional array.
7765  *  \param [out] tupleId - index of the tuple holding the maximal value.
7766  *  \return double - the maximal value among all values of \a this array.
7767  *  \throw If \a this->getNumberOfComponents() != 1
7768  *  \throw If \a this->getNumberOfTuples() < 1
7769  */
7770 int DataArrayInt::getMaxValue(int& tupleId) const throw(INTERP_KERNEL::Exception)
7771 {
7772   checkAllocated();
7773   if(getNumberOfComponents()!=1)
7774     throw INTERP_KERNEL::Exception("DataArrayInt::getMaxValue : must be applied on DataArrayInt with only one component !");
7775   int nbOfTuples=getNumberOfTuples();
7776   if(nbOfTuples<=0)
7777     throw INTERP_KERNEL::Exception("DataArrayInt::getMaxValue : array exists but number of tuples must be > 0 !");
7778   const int *vals=getConstPointer();
7779   const int *loc=std::max_element(vals,vals+nbOfTuples);
7780   tupleId=(int)std::distance(vals,loc);
7781   return *loc;
7782 }
7783
7784 /*!
7785  * Returns the maximal value within \a this array that is allowed to have more than
7786  *  one component.
7787  *  \return int - the maximal value among all values of \a this array.
7788  *  \throw If \a this is not allocated.
7789  */
7790 int DataArrayInt::getMaxValueInArray() const throw(INTERP_KERNEL::Exception)
7791 {
7792   checkAllocated();
7793   const int *loc=std::max_element(begin(),end());
7794   return *loc;
7795 }
7796
7797 /*!
7798  * Returns the minimal value and its location within \a this one-dimensional array.
7799  *  \param [out] tupleId - index of the tuple holding the minimal value.
7800  *  \return int - the minimal value among all values of \a this array.
7801  *  \throw If \a this->getNumberOfComponents() != 1
7802  *  \throw If \a this->getNumberOfTuples() < 1
7803  */
7804 int DataArrayInt::getMinValue(int& tupleId) const throw(INTERP_KERNEL::Exception)
7805 {
7806   checkAllocated();
7807   if(getNumberOfComponents()!=1)
7808     throw INTERP_KERNEL::Exception("DataArrayInt::getMaxValue : must be applied on DataArrayInt with only one component !");
7809   int nbOfTuples=getNumberOfTuples();
7810   if(nbOfTuples<=0)
7811     throw INTERP_KERNEL::Exception("DataArrayInt::getMaxValue : array exists but number of tuples must be > 0 !");
7812   const int *vals=getConstPointer();
7813   const int *loc=std::min_element(vals,vals+nbOfTuples);
7814   tupleId=(int)std::distance(vals,loc);
7815   return *loc;
7816 }
7817
7818 /*!
7819  * Returns the minimal value within \a this array that is allowed to have more than
7820  *  one component.
7821  *  \return int - the minimal value among all values of \a this array.
7822  *  \throw If \a this is not allocated.
7823  */
7824 int DataArrayInt::getMinValueInArray() const throw(INTERP_KERNEL::Exception)
7825 {
7826   checkAllocated();
7827   const int *loc=std::min_element(begin(),end());
7828   return *loc;
7829 }
7830
7831 /*!
7832  * Converts every value of \a this array to its absolute value.
7833  *  \throw If \a this is not allocated.
7834  */
7835 void DataArrayInt::abs() throw(INTERP_KERNEL::Exception)
7836 {
7837   checkAllocated();
7838   int *ptr=getPointer();
7839   int nbOfElems=getNbOfElems();
7840   std::transform(ptr,ptr+nbOfElems,ptr,std::ptr_fun<int,int>(std::abs));
7841   declareAsNew();
7842 }
7843
7844 /*!
7845  * Apply a liner function to a given component of \a this array, so that
7846  * an array element <em>(x)</em> becomes \f$ a * x + b \f$.
7847  *  \param [in] a - the first coefficient of the function.
7848  *  \param [in] b - the second coefficient of the function.
7849  *  \param [in] compoId - the index of component to modify.
7850  *  \throw If \a this is not allocated.
7851  */
7852 void DataArrayInt::applyLin(int a, int b, int compoId) throw(INTERP_KERNEL::Exception)
7853 {
7854   checkAllocated();
7855   int *ptr=getPointer()+compoId;
7856   int nbOfComp=getNumberOfComponents();
7857   int nbOfTuple=getNumberOfTuples();
7858   for(int i=0;i<nbOfTuple;i++,ptr+=nbOfComp)
7859     *ptr=a*(*ptr)+b;
7860   declareAsNew();
7861 }
7862
7863 /*!
7864  * Apply a liner function to all elements of \a this array, so that
7865  * an element _x_ becomes \f$ a * x + b \f$.
7866  *  \param [in] a - the first coefficient of the function.
7867  *  \param [in] b - the second coefficient of the function.
7868  *  \throw If \a this is not allocated.
7869  */
7870 void DataArrayInt::applyLin(int a, int b) throw(INTERP_KERNEL::Exception)
7871 {
7872   checkAllocated();
7873   int *ptr=getPointer();
7874   int nbOfElems=getNbOfElems();
7875   for(int i=0;i<nbOfElems;i++,ptr++)
7876     *ptr=a*(*ptr)+b;
7877   declareAsNew();
7878 }
7879
7880 /*!
7881  * Returns a full copy of \a this array except that sign of all elements is reversed.
7882  *  \return DataArrayInt * - the new instance of DataArrayInt containing the
7883  *          same number of tuples and component as \a this array.
7884  *          The caller is to delete this result array using decrRef() as it is no more
7885  *          needed.
7886  *  \throw If \a this is not allocated.
7887  */
7888 DataArrayInt *DataArrayInt::negate() const throw(INTERP_KERNEL::Exception)
7889 {
7890   checkAllocated();
7891   DataArrayInt *newArr=DataArrayInt::New();
7892   int nbOfTuples=getNumberOfTuples();
7893   int nbOfComp=getNumberOfComponents();
7894   newArr->alloc(nbOfTuples,nbOfComp);
7895   const int *cptr=getConstPointer();
7896   std::transform(cptr,cptr+nbOfTuples*nbOfComp,newArr->getPointer(),std::negate<int>());
7897   newArr->copyStringInfoFrom(*this);
7898   return newArr;
7899 }
7900
7901 /*!
7902  * Modify all elements of \a this array, so that
7903  * an element _x_ becomes \f$ numerator / x \f$.
7904  *  \param [in] numerator - the numerator used to modify array elements.
7905  *  \throw If \a this is not allocated.
7906  *  \throw If there is an element equal to 0 in \a this array.
7907  *  \warning If an exception is thrown because of presence of 0 element in \a this 
7908  *           array, all elements processed before detection of the zero element remain
7909  *           modified.
7910  */
7911 void DataArrayInt::applyInv(int numerator) throw(INTERP_KERNEL::Exception)
7912 {
7913   checkAllocated();
7914   int *ptr=getPointer();
7915   int nbOfElems=getNbOfElems();
7916   for(int i=0;i<nbOfElems;i++,ptr++)
7917     {
7918       if(*ptr!=0)
7919         {
7920           *ptr=numerator/(*ptr);
7921         }
7922       else
7923         {
7924           std::ostringstream oss; oss << "DataArrayInt::applyInv : presence of null value in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
7925           oss << " !";
7926           throw INTERP_KERNEL::Exception(oss.str().c_str());
7927         }
7928     }
7929   declareAsNew();
7930 }
7931
7932 /*!
7933  * Modify all elements of \a this array, so that
7934  * an element _x_ becomes \f$ x / val \f$.
7935  *  \param [in] val - the denominator used to modify array elements.
7936  *  \throw If \a this is not allocated.
7937  *  \throw If \a val == 0.
7938  */
7939 void DataArrayInt::applyDivideBy(int val) throw(INTERP_KERNEL::Exception)
7940 {
7941   if(val==0)
7942     throw INTERP_KERNEL::Exception("DataArrayInt::applyDivideBy : Trying to divide by 0 !");
7943   checkAllocated();
7944   int *ptr=getPointer();
7945   int nbOfElems=getNbOfElems();
7946   std::transform(ptr,ptr+nbOfElems,ptr,std::bind2nd(std::divides<int>(),val));
7947   declareAsNew();
7948 }
7949
7950 /*!
7951  * Modify all elements of \a this array, so that
7952  * an element _x_ becomes  <em> x % val </em>.
7953  *  \param [in] val - the divisor used to modify array elements.
7954  *  \throw If \a this is not allocated.
7955  *  \throw If \a val <= 0.
7956  */
7957 void DataArrayInt::applyModulus(int val) throw(INTERP_KERNEL::Exception)
7958 {
7959   if(val<=0)
7960     throw INTERP_KERNEL::Exception("DataArrayInt::applyDivideBy : Trying to operate modulus on value <= 0 !");
7961   checkAllocated();
7962   int *ptr=getPointer();
7963   int nbOfElems=getNbOfElems();
7964   std::transform(ptr,ptr+nbOfElems,ptr,std::bind2nd(std::modulus<int>(),val));
7965   declareAsNew();
7966 }
7967
7968 /*!
7969  * This method works only on data array with one component.
7970  * This method returns a newly allocated array storing stored ascendantly tuple ids in \b this so that
7971  * this[*id] in [\b vmin,\b vmax)
7972  * 
7973  * \param [in] vmin begin of range. This value is included in range.
7974  * \param [out] vmax end of range. This value is \b not included in range.
7975  * \return a newly allocated data array that the caller should deal with.
7976  */
7977 DataArrayInt *DataArrayInt::getIdsInRange(int vmin, int vmax) const throw(INTERP_KERNEL::Exception)
7978 {
7979   checkAllocated();
7980   if(getNumberOfComponents()!=1)
7981     throw INTERP_KERNEL::Exception("DataArrayInt::getIdsInRange : this must have exactly one component !");
7982   const int *cptr=getConstPointer();
7983   std::vector<int> res;
7984   int nbOfTuples=getNumberOfTuples();
7985   for(int i=0;i<nbOfTuples;i++,cptr++)
7986     if(*cptr>=vmin && *cptr<vmax)
7987       res.push_back(i);
7988   DataArrayInt *ret=DataArrayInt::New();
7989   ret->alloc((int)res.size(),1);
7990   std::copy(res.begin(),res.end(),ret->getPointer());
7991   return ret;
7992 }
7993
7994 /*!
7995  * Modify all elements of \a this array, so that
7996  * an element _x_ becomes <em> val % x </em>.
7997  *  \param [in] val - the divident used to modify array elements.
7998  *  \throw If \a this is not allocated.
7999  *  \throw If there is an element equal to or less than 0 in \a this array.
8000  *  \warning If an exception is thrown because of presence of an element <= 0 in \a this 
8001  *           array, all elements processed before detection of the zero element remain
8002  *           modified.
8003  */
8004 void DataArrayInt::applyRModulus(int val) throw(INTERP_KERNEL::Exception)
8005 {
8006   checkAllocated();
8007   int *ptr=getPointer();
8008   int nbOfElems=getNbOfElems();
8009   for(int i=0;i<nbOfElems;i++,ptr++)
8010     {
8011       if(*ptr>0)
8012         {
8013           *ptr=val%(*ptr);
8014         }
8015       else
8016         {
8017           std::ostringstream oss; oss << "DataArrayInt::applyRModulus : presence of value <=0 in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
8018           oss << " !";
8019           throw INTERP_KERNEL::Exception(oss.str().c_str());
8020         }
8021     }
8022   declareAsNew();
8023 }
8024
8025 /*!
8026  * Returns a new DataArrayInt by aggregating two given arrays, so that (1) the number
8027  * of components in the result array is a sum of the number of components of given arrays
8028  * and (2) the number of tuples in the result array is same as that of each of given
8029  * arrays. In other words the i-th tuple of result array includes all components of
8030  * i-th tuples of all given arrays.
8031  * Number of tuples in the given arrays must be the same.
8032  *  \param [in] a1 - an array to include in the result array.
8033  *  \param [in] a2 - another array to include in the result array.
8034  *  \return DataArrayInt * - the new instance of DataArrayInt.
8035  *          The caller is to delete this result array using decrRef() as it is no more
8036  *          needed.
8037  *  \throw If both \a a1 and \a a2 are NULL.
8038  *  \throw If any given array is not allocated.
8039  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
8040  */
8041 DataArrayInt *DataArrayInt::Meld(const DataArrayInt *a1, const DataArrayInt *a2) throw(INTERP_KERNEL::Exception)
8042 {
8043   std::vector<const DataArrayInt *> arr(2);
8044   arr[0]=a1; arr[1]=a2;
8045   return Meld(arr);
8046 }
8047
8048 /*!
8049  * Returns a new DataArrayInt by aggregating all given arrays, so that (1) the number
8050  * of components in the result array is a sum of the number of components of given arrays
8051  * and (2) the number of tuples in the result array is same as that of each of given
8052  * arrays. In other words the i-th tuple of result array includes all components of
8053  * i-th tuples of all given arrays.
8054  * Number of tuples in the given arrays must be  the same.
8055  *  \param [in] arr - a sequence of arrays to include in the result array.
8056  *  \return DataArrayInt * - the new instance of DataArrayInt.
8057  *          The caller is to delete this result array using decrRef() as it is no more
8058  *          needed.
8059  *  \throw If all arrays within \a arr are NULL.
8060  *  \throw If any given array is not allocated.
8061  *  \throw If getNumberOfTuples() of arrays within \a arr is different.
8062  */
8063 DataArrayInt *DataArrayInt::Meld(const std::vector<const DataArrayInt *>& arr) throw(INTERP_KERNEL::Exception)
8064 {
8065   std::vector<const DataArrayInt *> a;
8066   for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
8067     if(*it4)
8068       a.push_back(*it4);
8069   if(a.empty())
8070     throw INTERP_KERNEL::Exception("DataArrayInt::Meld : array must be NON empty !");
8071   std::vector<const DataArrayInt *>::const_iterator it;
8072   for(it=a.begin();it!=a.end();it++)
8073     (*it)->checkAllocated();
8074   it=a.begin();
8075   int nbOfTuples=(*it)->getNumberOfTuples();
8076   std::vector<int> nbc(a.size());
8077   std::vector<const int *> pts(a.size());
8078   nbc[0]=(*it)->getNumberOfComponents();
8079   pts[0]=(*it++)->getConstPointer();
8080   for(int i=1;it!=a.end();it++,i++)
8081     {
8082       if(nbOfTuples!=(*it)->getNumberOfTuples())
8083         throw INTERP_KERNEL::Exception("DataArrayInt::meld : mismatch of number of tuples !");
8084       nbc[i]=(*it)->getNumberOfComponents();
8085       pts[i]=(*it)->getConstPointer();
8086     }
8087   int totalNbOfComp=std::accumulate(nbc.begin(),nbc.end(),0);
8088   DataArrayInt *ret=DataArrayInt::New();
8089   ret->alloc(nbOfTuples,totalNbOfComp);
8090   int *retPtr=ret->getPointer();
8091   for(int i=0;i<nbOfTuples;i++)
8092     for(int j=0;j<(int)a.size();j++)
8093       {
8094         retPtr=std::copy(pts[j],pts[j]+nbc[j],retPtr);
8095         pts[j]+=nbc[j];
8096       }
8097   int k=0;
8098   for(int i=0;i<(int)a.size();i++)
8099     for(int j=0;j<nbc[i];j++,k++)
8100       ret->setInfoOnComponent(k,a[i]->getInfoOnComponent(j).c_str());
8101   return ret;
8102 }
8103
8104 /*!
8105  * Returns a new DataArrayInt which is a minimal partition of elements of \a groups.
8106  * The i-th item of the result array is an ID of a set of elements belonging to a
8107  * unique set of groups, which the i-th element is a part of. This set of elements
8108  * belonging to a unique set of groups is called \a family, so the result array contains
8109  * IDs of families each element belongs to.
8110  *
8111  * \b Example: if we have two groups of elements: \a group1 [0,4] and \a group2 [ 0,1,2 ],
8112  * then there are 3 families:
8113  * - \a family1 (with ID 1) contains element [0] belonging to ( \a group1 + \a group2 ),
8114  * - \a family2 (with ID 2) contains elements [4] belonging to ( \a group1 ),
8115  * - \a family3 (with ID 3) contains element [1,2] belonging to ( \a group2 ), <br>
8116  * and the result array contains IDs of families [ 1,3,3,0,2 ]. <br> Note a family ID 0 which
8117  * stands for the element #3 which is in none of groups.
8118  *
8119  *  \param [in] groups - sequence of groups of element IDs.
8120  *  \param [in] newNb - total number of elements; it must be more than max ID of element
8121  *         in \a groups.
8122  *  \param [out] fidsOfGroups - IDs of families the elements of each group belong to.
8123  *  \return DataArrayInt * - a new instance of DataArrayInt containing IDs of families
8124  *         each element with ID from range [0, \a newNb ) belongs to. The caller is to
8125  *         delete this array using decrRef() as it is no more needed.
8126  *  \throw If any element ID in \a groups violates condition ( 0 <= ID < \a newNb ).
8127  */
8128 DataArrayInt *DataArrayInt::MakePartition(const std::vector<const DataArrayInt *>& groups, int newNb, std::vector< std::vector<int> >& fidsOfGroups) throw(INTERP_KERNEL::Exception)
8129 {
8130   std::vector<const DataArrayInt *> groups2;
8131   for(std::vector<const DataArrayInt *>::const_iterator it4=groups.begin();it4!=groups.end();it4++)
8132     if(*it4)
8133       groups2.push_back(*it4);
8134   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
8135   ret->alloc(newNb,1);
8136   int *retPtr=ret->getPointer();
8137   std::fill(retPtr,retPtr+newNb,0);
8138   int fid=1;
8139   for(std::vector<const DataArrayInt *>::const_iterator iter=groups2.begin();iter!=groups2.end();iter++)
8140     {
8141       const int *ptr=(*iter)->getConstPointer();
8142       int nbOfElem=(*iter)->getNbOfElems();
8143       int sfid=fid;
8144       for(int j=0;j<sfid;j++)
8145         {
8146           bool found=false;
8147           for(int i=0;i<nbOfElem;i++)
8148             {
8149               if(ptr[i]>=0 && ptr[i]<newNb)
8150                 {
8151                   if(retPtr[ptr[i]]==j)
8152                     {
8153                       retPtr[ptr[i]]=fid;
8154                       found=true;
8155                     }
8156                 }
8157               else
8158                 {
8159                   std::ostringstream oss; oss << "DataArrayInt::MakePartition : In group \"" << (*iter)->getName() << "\" in tuple #" << i << " value = " << ptr[i] << " ! Should be in [0," << newNb;
8160                   oss << ") !";
8161                   throw INTERP_KERNEL::Exception(oss.str().c_str());
8162                 }
8163             }
8164           if(found)
8165             fid++;
8166         }
8167     }
8168   fidsOfGroups.clear();
8169   fidsOfGroups.resize(groups2.size());
8170   int grId=0;
8171   for(std::vector<const DataArrayInt *>::const_iterator iter=groups2.begin();iter!=groups2.end();iter++,grId++)
8172     {
8173       std::set<int> tmp;
8174       const int *ptr=(*iter)->getConstPointer();
8175       int nbOfElem=(*iter)->getNbOfElems();
8176       for(const int *p=ptr;p!=ptr+nbOfElem;p++)
8177         tmp.insert(retPtr[*p]);
8178       fidsOfGroups[grId].insert(fidsOfGroups[grId].end(),tmp.begin(),tmp.end());
8179     }
8180   return ret.retn();
8181 }
8182
8183 /*!
8184  * Returns a new DataArrayInt which contains all elements of given one-dimensional
8185  * not negative arrays. The result array does not contain any duplicates and its values
8186  * are sorted in ascending order.
8187  *  \param [in] arr - sequence of DataArrayInt's to unite.
8188  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
8189  *         array using decrRef() as it is no more needed.
8190  *  \throw If any \a arr[i] is not allocated.
8191  *  \throw If \a arr[i]->getNumberOfComponents() != 1.
8192  *  \throw If any value of \a arr[i] is negative.
8193  */
8194 DataArrayInt *DataArrayInt::BuildUnion(const std::vector<const DataArrayInt *>& arr) throw(INTERP_KERNEL::Exception)
8195 {
8196   std::vector<const DataArrayInt *> a;
8197   for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
8198     if(*it4)
8199       a.push_back(*it4);
8200   int valm=std::numeric_limits<int>::max();
8201   for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
8202     {
8203       (*it)->checkAllocated();
8204       if((*it)->getNumberOfComponents()!=1)
8205         throw INTERP_KERNEL::Exception("DataArrayInt::BuildUnion : only single component allowed !");
8206       int tmp1;
8207       valm=std::min((*it)->getMinValue(tmp1),valm);
8208     }
8209   if(valm<0)
8210     throw INTERP_KERNEL::Exception("DataArrayInt::BuildUnion : a negative value has been detected !");
8211   //
8212   std::set<int> r;
8213   for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
8214     {
8215       const int *pt=(*it)->getConstPointer();
8216       int nbOfTuples=(*it)->getNumberOfTuples();
8217       r.insert(pt,pt+nbOfTuples);
8218     }
8219   DataArrayInt *ret=DataArrayInt::New();
8220   ret->alloc((int)r.size(),1);
8221   std::copy(r.begin(),r.end(),ret->getPointer());
8222   return ret;
8223 }
8224
8225 /*!
8226  * Returns a new DataArrayInt which contains elements present in each of given one-dimensional
8227  * not negative arrays. The result array does not contain any duplicates and its values
8228  * are sorted in ascending order.
8229  *  \param [in] arr - sequence of DataArrayInt's to intersect.
8230  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
8231  *         array using decrRef() as it is no more needed.
8232  *  \throw If any \a arr[i] is not allocated.
8233  *  \throw If \a arr[i]->getNumberOfComponents() != 1.
8234  *  \throw If any value of \a arr[i] < 0.
8235  */
8236 DataArrayInt *DataArrayInt::BuildIntersection(const std::vector<const DataArrayInt *>& arr) throw(INTERP_KERNEL::Exception)
8237 {
8238   std::vector<const DataArrayInt *> a;
8239   for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
8240     if(*it4)
8241       a.push_back(*it4);
8242   int valm=std::numeric_limits<int>::max();
8243   for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
8244     {
8245       (*it)->checkAllocated();
8246       if((*it)->getNumberOfComponents()!=1)
8247         throw INTERP_KERNEL::Exception("DataArrayInt::BuildIntersection : only single component allowed !");
8248       int tmp1;
8249       valm=std::min((*it)->getMinValue(tmp1),valm);
8250     }
8251   if(valm<0)
8252     throw INTERP_KERNEL::Exception("DataArrayInt::BuildIntersection : a negative value has been detected !");
8253   //
8254   std::set<int> r;
8255   for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
8256     {
8257       const int *pt=(*it)->getConstPointer();
8258       int nbOfTuples=(*it)->getNumberOfTuples();
8259       std::set<int> s1(pt,pt+nbOfTuples);
8260       if(it!=a.begin())
8261         {
8262           std::set<int> r2;
8263           std::set_intersection(r.begin(),r.end(),s1.begin(),s1.end(),inserter(r2,r2.end()));
8264           r=r2;
8265         }
8266       else
8267         r=s1;
8268     }
8269   DataArrayInt *ret=DataArrayInt::New();
8270   ret->alloc((int)r.size(),1);
8271   std::copy(r.begin(),r.end(),ret->getPointer());
8272   return ret;
8273 }
8274
8275 /*!
8276  * Returns a new DataArrayInt which contains a complement of elements of \a this
8277  * one-dimensional array. I.e. the result array contains all elements from the range [0,
8278  * \a nbOfElement) not present in \a this array.
8279  *  \param [in] nbOfElement - maximal size of the result array.
8280  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
8281  *         array using decrRef() as it is no more needed.
8282  *  \throw If \a this is not allocated.
8283  *  \throw If \a this->getNumberOfComponents() != 1.
8284  *  \throw If any element \a x of \a this array violates condition ( 0 <= \a x < \a
8285  *         nbOfElement ).
8286  */
8287 DataArrayInt *DataArrayInt::buildComplement(int nbOfElement) const throw(INTERP_KERNEL::Exception)
8288 {
8289    checkAllocated();
8290    if(getNumberOfComponents()!=1)
8291      throw INTERP_KERNEL::Exception("DataArrayInt::buildComplement : only single component allowed !");
8292    std::vector<bool> tmp(nbOfElement);
8293    const int *pt=getConstPointer();
8294    int nbOfTuples=getNumberOfTuples();
8295    for(const int *w=pt;w!=pt+nbOfTuples;w++)
8296      if(*w>=0 && *w<nbOfElement)
8297        tmp[*w]=true;
8298      else
8299        throw INTERP_KERNEL::Exception("DataArrayInt::buildComplement : an element is not in valid range : [0,nbOfElement) !");
8300    int nbOfRetVal=(int)std::count(tmp.begin(),tmp.end(),false);
8301    DataArrayInt *ret=DataArrayInt::New();
8302    ret->alloc(nbOfRetVal,1);
8303    int j=0;
8304    int *retPtr=ret->getPointer();
8305    for(int i=0;i<nbOfElement;i++)
8306      if(!tmp[i])
8307        retPtr[j++]=i;
8308    return ret;
8309 }
8310
8311 /*!
8312  * Returns a new DataArrayInt containing elements of \a this one-dimensional missing
8313  * from an \a other one-dimensional array.
8314  *  \param [in] other - a DataArrayInt containing elements not to include in the result array.
8315  *  \return DataArrayInt * - a new instance of DataArrayInt with one component. The
8316  *         caller is to delete this array using decrRef() as it is no more needed.
8317  *  \throw If \a other is NULL.
8318  *  \throw If \a other is not allocated.
8319  *  \throw If \a other->getNumberOfComponents() != 1.
8320  *  \throw If \a this is not allocated.
8321  *  \throw If \a this->getNumberOfComponents() != 1.
8322  *  \sa DataArrayInt::buildSubstractionOptimized()
8323  */
8324 DataArrayInt *DataArrayInt::buildSubstraction(const DataArrayInt *other) const throw(INTERP_KERNEL::Exception)
8325 {
8326   if(!other)
8327     throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstraction : DataArrayInt pointer in input is NULL !");
8328   checkAllocated();
8329   other->checkAllocated();
8330   if(getNumberOfComponents()!=1)
8331      throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstraction : only single component allowed !");
8332   if(other->getNumberOfComponents()!=1)
8333      throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstraction : only single component allowed for other type !");
8334   const int *pt=getConstPointer();
8335   int nbOfTuples=getNumberOfTuples();
8336   std::set<int> s1(pt,pt+nbOfTuples);
8337   pt=other->getConstPointer();
8338   nbOfTuples=other->getNumberOfTuples();
8339   std::set<int> s2(pt,pt+nbOfTuples);
8340   std::vector<int> r;
8341   std::set_difference(s1.begin(),s1.end(),s2.begin(),s2.end(),std::back_insert_iterator< std::vector<int> >(r));
8342   DataArrayInt *ret=DataArrayInt::New();
8343   ret->alloc((int)r.size(),1);
8344   std::copy(r.begin(),r.end(),ret->getPointer());
8345   return ret;
8346 }
8347
8348 /*!
8349  * \a this is expected to have one component and to be sorted ascendingly (as for \a other).
8350  * \a other is expected to be a part of \a this. If not DataArrayInt::buildSubstraction should be called instead.
8351  * 
8352  * \param [in] other an array with one component and expected to be sorted ascendingly.
8353  * \ret list of ids in \a this but not in \a other.
8354  * \sa DataArrayInt::buildSubstraction
8355  */
8356 DataArrayInt *DataArrayInt::buildSubstractionOptimized(const DataArrayInt *other) const throw(INTERP_KERNEL::Exception)
8357 {
8358   static const char *MSG="DataArrayInt::buildSubstractionOptimized : only single component allowed !";
8359   if(!other) throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstractionOptimized : NULL input array !");
8360   checkAllocated(); other->checkAllocated();
8361   if(getNumberOfComponents()!=1) throw INTERP_KERNEL::Exception(MSG);
8362   if(other->getNumberOfComponents()!=1) throw INTERP_KERNEL::Exception(MSG);
8363   const int *pt1Bg(begin()),*pt1End(end()),*pt2Bg(other->begin()),*pt2End(other->end()),*work1(pt1Bg),*work2(pt2Bg);
8364   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
8365   for(;work1!=pt1End;work1++)
8366     {
8367       if(work2!=pt2End && *work1==*work2)
8368         work2++;
8369       else
8370         ret->pushBackSilent(*work1);
8371     }
8372   return ret.retn();
8373 }
8374
8375
8376 /*!
8377  * Returns a new DataArrayInt which contains all elements of \a this and a given
8378  * one-dimensional not negative arrays. The result array does not contain any duplicates
8379  * and its values are sorted in ascending order.
8380  *  \param [in] other - an array to unite with \a this one.
8381  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
8382  *         array using decrRef() as it is no more needed.
8383  *  \throw If \a this or \a other is not allocated.
8384  *  \throw If \a this->getNumberOfComponents() != 1.
8385  *  \throw If \a other->getNumberOfComponents() != 1.
8386  *  \throw If any value of \a this or \a other is negative.
8387  */
8388 DataArrayInt *DataArrayInt::buildUnion(const DataArrayInt *other) const throw(INTERP_KERNEL::Exception)
8389 {
8390   std::vector<const DataArrayInt *>arrs(2);
8391   arrs[0]=this; arrs[1]=other;
8392   return BuildUnion(arrs);
8393 }
8394
8395
8396 /*!
8397  * Returns a new DataArrayInt which contains elements present in both \a this and a given
8398  * one-dimensional not negative arrays. The result array does not contain any duplicates
8399  * and its values are sorted in ascending order.
8400  *  \param [in] other - an array to intersect with \a this one.
8401  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
8402  *         array using decrRef() as it is no more needed.
8403  *  \throw If \a this or \a other is not allocated.
8404  *  \throw If \a this->getNumberOfComponents() != 1.
8405  *  \throw If \a other->getNumberOfComponents() != 1.
8406  *  \throw If any value of \a this or \a other is negative.
8407  */
8408 DataArrayInt *DataArrayInt::buildIntersection(const DataArrayInt *other) const throw(INTERP_KERNEL::Exception)
8409 {
8410   std::vector<const DataArrayInt *>arrs(2);
8411   arrs[0]=this; arrs[1]=other;
8412   return BuildIntersection(arrs);
8413 }
8414
8415 /*!
8416  * This method can be applied on allocated with one component DataArrayInt instance.
8417  * This method is typically relevant for sorted arrays. All consecutive duplicated items in \a this will appear only once in returned DataArrayInt instance.
8418  * 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]
8419  * 
8420  * \return a newly allocated array that contain the result of the unique operation applied on \a this.
8421  * \throw if \a this is not allocated or if \a this has not exactly one component.
8422  */
8423 DataArrayInt *DataArrayInt::buildUnique() const throw(INTERP_KERNEL::Exception)
8424 {
8425   checkAllocated();
8426   if(getNumberOfComponents()!=1)
8427      throw INTERP_KERNEL::Exception("DataArrayInt::buildUnique : only single component allowed !");
8428   int nbOfTuples=getNumberOfTuples();
8429   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp=deepCpy();
8430   int *data=tmp->getPointer();
8431   int *last=std::unique(data,data+nbOfTuples);
8432   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
8433   ret->alloc(std::distance(data,last),1);
8434   std::copy(data,last,ret->getPointer());
8435   return ret.retn();
8436 }
8437
8438 /*!
8439  * Returns a new DataArrayInt which contains size of every of groups described by \a this
8440  * "index" array. Such "index" array is returned for example by 
8441  * \ref ParaMEDMEM::MEDCouplingUMesh::buildDescendingConnectivity
8442  * "MEDCouplingUMesh::buildDescendingConnectivity" and
8443  * \ref ParaMEDMEM::MEDCouplingUMesh::getNodalConnectivityIndex
8444  * "MEDCouplingUMesh::getNodalConnectivityIndex" etc.
8445  *  \return DataArrayInt * - a new instance of DataArrayInt, whose number of tuples
8446  *          equals to \a this->getNumberOfComponents() - 1, and number of components is 1.
8447  *          The caller is to delete this array using decrRef() as it is no more needed. 
8448  *  \throw If \a this is not allocated.
8449  *  \throw If \a this->getNumberOfComponents() != 1.
8450  *  \throw If \a this->getNumberOfTuples() < 2.
8451  *
8452  *  \b Example: <br> 
8453  *         - this contains [1,3,6,7,7,9,15]
8454  *         - result array contains [2,3,1,0,2,6],
8455  *          where 2 = 3 - 1, 3 = 6 - 3, 1 = 7 - 6 etc.
8456  */
8457 DataArrayInt *DataArrayInt::deltaShiftIndex() const throw(INTERP_KERNEL::Exception)
8458 {
8459   checkAllocated();
8460   if(getNumberOfComponents()!=1)
8461      throw INTERP_KERNEL::Exception("DataArrayInt::deltaShiftIndex : only single component allowed !");
8462   int nbOfTuples=getNumberOfTuples();
8463   if(nbOfTuples<2)
8464     throw INTERP_KERNEL::Exception("DataArrayInt::deltaShiftIndex : 1 tuple at least must be present in 'this' !");
8465   const int *ptr=getConstPointer();
8466   DataArrayInt *ret=DataArrayInt::New();
8467   ret->alloc(nbOfTuples-1,1);
8468   int *out=ret->getPointer();
8469   std::transform(ptr+1,ptr+nbOfTuples,ptr,out,std::minus<int>());
8470   return ret;
8471 }
8472
8473 /*!
8474  * Modifies \a this one-dimensional array so that value of each element \a x
8475  * of \a this array (\a a) is computed as \f$ x_i = \sum_{j=0}^{i-1} a[ j ] \f$.
8476  * Or: for each i>0 new[i]=new[i-1]+old[i-1] for i==0 new[i]=0. Number of tuples
8477  * and components remains the same.<br>
8478  * This method is useful for allToAllV in MPI with contiguous policy. This method
8479  * differs from computeOffsets2() in that the number of tuples is \b not changed by
8480  * this one.
8481  *  \throw If \a this is not allocated.
8482  *  \throw If \a this->getNumberOfComponents() != 1.
8483  *
8484  *  \b Example: <br>
8485  *          - Before \a this contains [3,5,1,2,0,8]
8486  *          - After \a this contains  [0,3,8,9,11,11]<br>
8487  *          Note that the last element 19 = 11 + 8 is missing because size of \a this
8488  *          array is retained and thus there is no space to store the last element.
8489  */
8490 void DataArrayInt::computeOffsets() throw(INTERP_KERNEL::Exception)
8491 {
8492   checkAllocated();
8493   if(getNumberOfComponents()!=1)
8494      throw INTERP_KERNEL::Exception("DataArrayInt::computeOffsets : only single component allowed !");
8495   int nbOfTuples=getNumberOfTuples();
8496   if(nbOfTuples==0)
8497     return ;
8498   int *work=getPointer();
8499   int tmp=work[0];
8500   work[0]=0;
8501   for(int i=1;i<nbOfTuples;i++)
8502     {
8503       int tmp2=work[i];
8504       work[i]=work[i-1]+tmp;
8505       tmp=tmp2;
8506     }
8507   declareAsNew();
8508 }
8509
8510
8511 /*!
8512  * Modifies \a this one-dimensional array so that value of each element \a x
8513  * of \a this array (\a a) is computed as \f$ x_i = \sum_{j=0}^{i-1} a[ j ] \f$.
8514  * Or: for each i>0 new[i]=new[i-1]+old[i-1] for i==0 new[i]=0. Number
8515  * components remains the same and number of tuples is inceamented by one.<br>
8516  * This method is useful for allToAllV in MPI with contiguous policy. This method
8517  * differs from computeOffsets() in that the number of tuples is changed by this one.
8518  *  \throw If \a this is not allocated.
8519  *  \throw If \a this->getNumberOfComponents() != 1.
8520  *
8521  *  \b Example: <br>
8522  *          - Before \a this contains [3,5,1,2,0,8]
8523  *          - After \a this contains  [0,3,8,9,11,11,19]<br>
8524  */
8525 void DataArrayInt::computeOffsets2() throw(INTERP_KERNEL::Exception)
8526 {
8527   checkAllocated();
8528   if(getNumberOfComponents()!=1)
8529     throw INTERP_KERNEL::Exception("DataArrayInt::computeOffsets2 : only single component allowed !");
8530   int nbOfTuples=getNumberOfTuples();
8531   int *ret=new int[nbOfTuples+1];
8532   if(nbOfTuples==0)
8533     return ;
8534   const int *work=getConstPointer();
8535   ret[0]=0;
8536   for(int i=0;i<nbOfTuples;i++)
8537     ret[i+1]=work[i]+ret[i];
8538   useArray(ret,true,CPP_DEALLOC,nbOfTuples+1,1);
8539   declareAsNew();
8540 }
8541
8542
8543 /*!
8544  * Returns a new DataArrayInt whose contents is computed from that of \a this and \a
8545  * offsets arrays as follows. \a offsets is a one-dimensional array considered as an
8546  * "index" array of a "iota" array, thus, whose each element gives an index of a group
8547  * beginning within the "iota" array. And \a this is a one-dimensional array
8548  * considered as a selector of groups described by \a offsets to include into the result array.
8549  *  \throw If \a offsets is NULL.
8550  *  \throw If \a offsets is not allocated.
8551  *  \throw If \a offsets->getNumberOfComponents() != 1.
8552  *  \throw If \a offsets is not monotonically increasing.
8553  *  \throw If \a this is not allocated.
8554  *  \throw If \a this->getNumberOfComponents() != 1.
8555  *  \throw If any element of \a this is not a valid index for \a offsets array.
8556  *
8557  *  \b Example: <br>
8558  *          - \a this: [0,2,3]
8559  *          - \a offsets: [0,3,6,10,14,20]
8560  *          - result array: [0,1,2,6,7,8,9,10,11,12,13] == <br>
8561  *            \c range(0,3) + \c range(6,10) + \c range(10,14) ==<br>
8562  *            \c range( \a offsets[ \a this[0] ], offsets[ \a this[0]+1 ]) + 
8563  *            \c range( \a offsets[ \a this[1] ], offsets[ \a this[1]+1 ]) + 
8564  *            \c range( \a offsets[ \a this[2] ], offsets[ \a this[2]+1 ])
8565  */
8566 DataArrayInt *DataArrayInt::buildExplicitArrByRanges(const DataArrayInt *offsets) const throw(INTERP_KERNEL::Exception)
8567 {
8568   if(!offsets)
8569     throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrByRanges : DataArrayInt pointer in input is NULL !");
8570   checkAllocated();
8571   if(getNumberOfComponents()!=1)
8572      throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrByRanges : only single component allowed !");
8573   offsets->checkAllocated();
8574   if(offsets->getNumberOfComponents()!=1)
8575      throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrByRanges : input array should have only single component !");
8576   int othNbTuples=offsets->getNumberOfTuples()-1;
8577   int nbOfTuples=getNumberOfTuples();
8578   int retNbOftuples=0;
8579   const int *work=getConstPointer();
8580   const int *offPtr=offsets->getConstPointer();
8581   for(int i=0;i<nbOfTuples;i++)
8582     {
8583       int val=work[i];
8584       if(val>=0 && val<othNbTuples)
8585         {
8586           int delta=offPtr[val+1]-offPtr[val];
8587           if(delta>=0)
8588             retNbOftuples+=delta;
8589           else
8590             {
8591               std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrByRanges : Tuple #" << val << " of offset array has a delta < 0 !";
8592               throw INTERP_KERNEL::Exception(oss.str().c_str());
8593             }
8594         }
8595       else
8596         {
8597           std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrByRanges : Tuple #" << i << " in this contains " << val;
8598           oss << " whereas offsets array is of size " << othNbTuples+1 << " !";
8599           throw INTERP_KERNEL::Exception(oss.str().c_str());
8600         }
8601     }
8602   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
8603   ret->alloc(retNbOftuples,1);
8604   int *retPtr=ret->getPointer();
8605   for(int i=0;i<nbOfTuples;i++)
8606     {
8607       int val=work[i];
8608       int start=offPtr[val];
8609       int off=offPtr[val+1]-start;
8610       for(int j=0;j<off;j++,retPtr++)
8611         *retPtr=start+j;
8612     }
8613   return ret.retn();
8614 }
8615
8616 /*!
8617  * 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.
8618  * 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
8619  * in tuple **i** of returned DataArrayInt.
8620  * If ranges overlapped (in theory it should not) this method do not detect it and always returns the first range.
8621  *
8622  * 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)]
8623  * The return DataArrayInt will contain : **[0,4,1,2,2,3]**
8624  * 
8625  * \param [in] ranges typically come from output of MEDCouplingUMesh::ComputeRangesFromTypeDistribution. Each range is specified like this : 1st component is
8626  *             for lower value included and 2nd component is the upper value of corresponding range **excluded**.
8627  * \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
8628  *        is thrown if no ranges in \a ranges contains value in \a this.
8629  * 
8630  * \sa DataArrayInt::findIdInRangeForEachTuple
8631  */
8632 DataArrayInt *DataArrayInt::findRangeIdForEachTuple(const DataArrayInt *ranges) const throw(INTERP_KERNEL::Exception)
8633 {
8634   if(!ranges)
8635     throw INTERP_KERNEL::Exception("DataArrayInt::findRangeIdForEachTuple : null input pointer !");
8636   if(ranges->getNumberOfComponents()!=2)
8637     throw INTERP_KERNEL::Exception("DataArrayInt::findRangeIdForEachTuple : input DataArrayInt instance should have 2 components !");
8638   checkAllocated();
8639   if(getNumberOfComponents()!=1)
8640     throw INTERP_KERNEL::Exception("DataArrayInt::findRangeIdForEachTuple : this should have only one component !");
8641   int nbTuples=getNumberOfTuples();
8642   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbTuples,1);
8643   int nbOfRanges=ranges->getNumberOfTuples();
8644   const int *rangesPtr=ranges->getConstPointer();
8645   int *retPtr=ret->getPointer();
8646   const int *inPtr=getConstPointer();
8647   for(int i=0;i<nbTuples;i++,retPtr++)
8648     {
8649       int val=inPtr[i];
8650       bool found=false;
8651       for(int j=0;j<nbOfRanges && !found;j++)
8652         if(val>=rangesPtr[2*j] && val<rangesPtr[2*j+1])
8653           { *retPtr=j; found=true; }
8654       if(found)
8655         continue;
8656       else
8657         {
8658           std::ostringstream oss; oss << "DataArrayInt::findRangeIdForEachTuple : tuple #" << i << " not found by any ranges !";
8659           throw INTERP_KERNEL::Exception(oss.str().c_str());
8660         }
8661     }
8662   return ret.retn();
8663 }
8664
8665 /*!
8666  * 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.
8667  * 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
8668  * in tuple **i** of returned DataArrayInt.
8669  * If ranges overlapped (in theory it should not) this method do not detect it and always returns the sub position of the first range.
8670  *
8671  * 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)]
8672  * The return DataArrayInt will contain : **[1,2,4,0,2,2]**
8673  * This method is often called in pair with DataArrayInt::findRangeIdForEachTuple method.
8674  * 
8675  * \param [in] ranges typically come from output of MEDCouplingUMesh::ComputeRangesFromTypeDistribution. Each range is specified like this : 1st component is
8676  *             for lower value included and 2nd component is the upper value of corresponding range **excluded**.
8677  * \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
8678  *        is thrown if no ranges in \a ranges contains value in \a this.
8679  * \sa DataArrayInt::findRangeIdForEachTuple
8680  */
8681 DataArrayInt *DataArrayInt::findIdInRangeForEachTuple(const DataArrayInt *ranges) const throw(INTERP_KERNEL::Exception)
8682 {
8683   if(!ranges)
8684     throw INTERP_KERNEL::Exception("DataArrayInt::findIdInRangeForEachTuple : null input pointer !");
8685   if(ranges->getNumberOfComponents()!=2)
8686     throw INTERP_KERNEL::Exception("DataArrayInt::findIdInRangeForEachTuple : input DataArrayInt instance should have 2 components !");
8687   checkAllocated();
8688   if(getNumberOfComponents()!=1)
8689     throw INTERP_KERNEL::Exception("DataArrayInt::findIdInRangeForEachTuple : this should have only one component !");
8690   int nbTuples=getNumberOfTuples();
8691   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbTuples,1);
8692   int nbOfRanges=ranges->getNumberOfTuples();
8693   const int *rangesPtr=ranges->getConstPointer();
8694   int *retPtr=ret->getPointer();
8695   const int *inPtr=getConstPointer();
8696   for(int i=0;i<nbTuples;i++,retPtr++)
8697     {
8698       int val=inPtr[i];
8699       bool found=false;
8700       for(int j=0;j<nbOfRanges && !found;j++)
8701         if(val>=rangesPtr[2*j] && val<rangesPtr[2*j+1])
8702           { *retPtr=val-rangesPtr[2*j]; found=true; }
8703       if(found)
8704         continue;
8705       else
8706         {
8707           std::ostringstream oss; oss << "DataArrayInt::findIdInRangeForEachTuple : tuple #" << i << " not found by any ranges !";
8708           throw INTERP_KERNEL::Exception(oss.str().c_str());
8709         }
8710     }
8711   return ret.retn();
8712 }
8713
8714 /*!
8715  * 
8716  * \param [in] nbTimes specifies the nb of times each tuples in \a this will be duplicated contiguouly in returned DataArrayInt instance.
8717  *             \a nbTimes  should be at least equal to 1.
8718  * \return a newly allocated DataArrayInt having one component and number of tuples equal to \a nbTimes * \c this->getNumberOfTuples.
8719  * \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.
8720  */
8721 DataArrayInt *DataArrayInt::duplicateEachTupleNTimes(int nbTimes) const throw(INTERP_KERNEL::Exception)
8722 {
8723   checkAllocated();
8724   if(getNumberOfComponents()!=1)
8725     throw INTERP_KERNEL::Exception("DataArrayInt::duplicateEachTupleNTimes : this should have only one component !");
8726   if(nbTimes<1)
8727     throw INTERP_KERNEL::Exception("DataArrayInt::duplicateEachTupleNTimes : nb times should be >= 1 !");
8728   int nbTuples=getNumberOfTuples();
8729   const int *inPtr=getConstPointer();
8730   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbTimes*nbTuples,1);
8731   int *retPtr=ret->getPointer();
8732   for(int i=0;i<nbTuples;i++,inPtr++)
8733     {
8734       int val=*inPtr;
8735       for(int j=0;j<nbTimes;j++,retPtr++)
8736         *retPtr=val;
8737     }
8738   ret->copyStringInfoFrom(*this);
8739   return ret.retn();
8740 }
8741
8742 /*!
8743  * This method returns all different values found in \a this. This method throws if \a this has not been allocated.
8744  * But the number of components can be different from one.
8745  * \return a newly allocated array (that should be dealt by the caller) containing different values in \a this.
8746  */
8747 DataArrayInt *DataArrayInt::getDifferentValues() const throw(INTERP_KERNEL::Exception)
8748 {
8749   checkAllocated();
8750   std::set<int> ret;
8751   ret.insert(begin(),end());
8752   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret2=DataArrayInt::New(); ret2->alloc((int)ret.size(),1);
8753   std::copy(ret.begin(),ret.end(),ret2->getPointer());
8754   return ret2.retn();
8755 }
8756
8757 /*!
8758  * This method is a refinement of DataArrayInt::getDifferentValues because it returns not only different values in \a this but also, for each of
8759  * them it tells which tuple id have this id.
8760  * This method works only on arrays with one component (if it is not the case call DataArrayInt::rearrange(1) ).
8761  * This method returns two arrays having same size.
8762  * 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.
8763  * 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]]
8764  */
8765 std::vector<DataArrayInt *> DataArrayInt::partitionByDifferentValues(std::vector<int>& differentIds) const throw(INTERP_KERNEL::Exception)
8766 {
8767   checkAllocated();
8768   if(getNumberOfComponents()!=1)
8769     throw INTERP_KERNEL::Exception("DataArrayInt::partitionByDifferentValues : this should have only one component !");
8770   int id=0;
8771   std::map<int,int> m,m2,m3;
8772   for(const int *w=begin();w!=end();w++)
8773     m[*w]++;
8774   differentIds.resize(m.size());
8775   std::vector<DataArrayInt *> ret(m.size());
8776   std::vector<int *> retPtr(m.size());
8777   for(std::map<int,int>::const_iterator it=m.begin();it!=m.end();it++,id++)
8778     {
8779       m2[(*it).first]=id;
8780       ret[id]=DataArrayInt::New();
8781       ret[id]->alloc((*it).second,1);
8782       retPtr[id]=ret[id]->getPointer();
8783       differentIds[id]=(*it).first;
8784     }
8785   id=0;
8786   for(const int *w=begin();w!=end();w++,id++)
8787     {
8788       retPtr[m2[*w]][m3[*w]++]=id;
8789     }
8790   return ret;
8791 }
8792
8793 /*!
8794  * Returns a new DataArrayInt that is a sum of two given arrays. There are 3
8795  * valid cases.
8796  * 1.  The arrays have same number of tuples and components. Then each value of
8797  *   the result array (_a_) is a sum of the corresponding values of \a a1 and \a a2,
8798  *   i.e.: _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ i, j ].
8799  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
8800  *   component. Then
8801  *   _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ i, 0 ].
8802  * 3.  The arrays have same number of components and one array, say _a2_, has one
8803  *   tuple. Then
8804  *   _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ 0, j ].
8805  *
8806  * Info on components is copied either from the first array (in the first case) or from
8807  * the array with maximal number of elements (getNbOfElems()).
8808  *  \param [in] a1 - an array to sum up.
8809  *  \param [in] a2 - another array to sum up.
8810  *  \return DataArrayInt * - the new instance of DataArrayInt.
8811  *          The caller is to delete this result array using decrRef() as it is no more
8812  *          needed.
8813  *  \throw If either \a a1 or \a a2 is NULL.
8814  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
8815  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
8816  *         none of them has number of tuples or components equal to 1.
8817  */
8818 DataArrayInt *DataArrayInt::Add(const DataArrayInt *a1, const DataArrayInt *a2) throw(INTERP_KERNEL::Exception)
8819 {
8820   if(!a1 || !a2)
8821     throw INTERP_KERNEL::Exception("DataArrayInt::Add : input DataArrayInt instance is NULL !");
8822   int nbOfTuple=a1->getNumberOfTuples();
8823   int nbOfTuple2=a2->getNumberOfTuples();
8824   int nbOfComp=a1->getNumberOfComponents();
8825   int nbOfComp2=a2->getNumberOfComponents();
8826   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=0;
8827   if(nbOfTuple==nbOfTuple2)
8828     {
8829       if(nbOfComp==nbOfComp2)
8830         {
8831           ret=DataArrayInt::New();
8832           ret->alloc(nbOfTuple,nbOfComp);
8833           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::plus<int>());
8834           ret->copyStringInfoFrom(*a1);
8835         }
8836       else
8837         {
8838           int nbOfCompMin,nbOfCompMax;
8839           const DataArrayInt *aMin, *aMax;
8840           if(nbOfComp>nbOfComp2)
8841             {
8842               nbOfCompMin=nbOfComp2; nbOfCompMax=nbOfComp;
8843               aMin=a2; aMax=a1;
8844             }
8845           else
8846             {
8847               nbOfCompMin=nbOfComp; nbOfCompMax=nbOfComp2;
8848               aMin=a1; aMax=a2;
8849             }
8850           if(nbOfCompMin==1)
8851             {
8852               ret=DataArrayInt::New();
8853               ret->alloc(nbOfTuple,nbOfCompMax);
8854               const int *aMinPtr=aMin->getConstPointer();
8855               const int *aMaxPtr=aMax->getConstPointer();
8856               int *res=ret->getPointer();
8857               for(int i=0;i<nbOfTuple;i++)
8858                 res=std::transform(aMaxPtr+i*nbOfCompMax,aMaxPtr+(i+1)*nbOfCompMax,res,std::bind2nd(std::plus<int>(),aMinPtr[i]));
8859               ret->copyStringInfoFrom(*aMax);
8860             }
8861           else
8862             throw INTERP_KERNEL::Exception("Nb of components mismatch for array Add !");
8863         }
8864     }
8865   else if((nbOfTuple==1 && nbOfTuple2>1) || (nbOfTuple>1 && nbOfTuple2==1))
8866     {
8867       if(nbOfComp==nbOfComp2)
8868         {
8869           int nbOfTupleMax=std::max(nbOfTuple,nbOfTuple2);
8870           const DataArrayInt *aMin=nbOfTuple>nbOfTuple2?a2:a1;
8871           const DataArrayInt *aMax=nbOfTuple>nbOfTuple2?a1:a2;
8872           const int *aMinPtr=aMin->getConstPointer(),*aMaxPtr=aMax->getConstPointer();
8873           ret=DataArrayInt::New();
8874           ret->alloc(nbOfTupleMax,nbOfComp);
8875           int *res=ret->getPointer();
8876           for(int i=0;i<nbOfTupleMax;i++)
8877             res=std::transform(aMaxPtr+i*nbOfComp,aMaxPtr+(i+1)*nbOfComp,aMinPtr,res,std::plus<int>());
8878           ret->copyStringInfoFrom(*aMax);
8879         }
8880       else
8881         throw INTERP_KERNEL::Exception("Nb of components mismatch for array Add !");
8882     }
8883   else
8884     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Add !");
8885   return ret.retn();
8886 }
8887
8888 /*!
8889  * Adds values of another DataArrayInt to values of \a this one. There are 3
8890  * valid cases.
8891  * 1.  The arrays have same number of tuples and components. Then each value of
8892  *   \a other array is added to the corresponding value of \a this array, i.e.:
8893  *   _a_ [ i, j ] += _other_ [ i, j ].
8894  * 2.  The arrays have same number of tuples and \a other array has one component. Then
8895  *   _a_ [ i, j ] += _other_ [ i, 0 ].
8896  * 3.  The arrays have same number of components and \a other array has one tuple. Then
8897  *   _a_ [ i, j ] += _a2_ [ 0, j ].
8898  *
8899  *  \param [in] other - an array to add to \a this one.
8900  *  \throw If \a other is NULL.
8901  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
8902  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
8903  *         \a other has number of both tuples and components not equal to 1.
8904  */
8905 void DataArrayInt::addEqual(const DataArrayInt *other) throw(INTERP_KERNEL::Exception)
8906 {
8907   if(!other)
8908     throw INTERP_KERNEL::Exception("DataArrayInt::addEqual : input DataArrayInt instance is NULL !");
8909   const char *msg="Nb of tuples mismatch for DataArrayInt::addEqual  !";
8910   checkAllocated(); other->checkAllocated();
8911   int nbOfTuple=getNumberOfTuples();
8912   int nbOfTuple2=other->getNumberOfTuples();
8913   int nbOfComp=getNumberOfComponents();
8914   int nbOfComp2=other->getNumberOfComponents();
8915   if(nbOfTuple==nbOfTuple2)
8916     {
8917       if(nbOfComp==nbOfComp2)
8918         {
8919           std::transform(begin(),end(),other->begin(),getPointer(),std::plus<int>());
8920         }
8921       else if(nbOfComp2==1)
8922         {
8923           int *ptr=getPointer();
8924           const int *ptrc=other->getConstPointer();
8925           for(int i=0;i<nbOfTuple;i++)
8926             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::plus<int>(),*ptrc++));
8927         }
8928       else
8929         throw INTERP_KERNEL::Exception(msg);
8930     }
8931   else if(nbOfTuple2==1)
8932     {
8933       if(nbOfComp2==nbOfComp)
8934         {
8935           int *ptr=getPointer();
8936           const int *ptrc=other->getConstPointer();
8937           for(int i=0;i<nbOfTuple;i++)
8938             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::plus<int>());
8939         }
8940       else
8941         throw INTERP_KERNEL::Exception(msg);
8942     }
8943   else
8944     throw INTERP_KERNEL::Exception(msg);
8945   declareAsNew();
8946 }
8947
8948 /*!
8949  * Returns a new DataArrayInt that is a subtraction of two given arrays. There are 3
8950  * valid cases.
8951  * 1.  The arrays have same number of tuples and components. Then each value of
8952  *   the result array (_a_) is a subtraction of the corresponding values of \a a1 and
8953  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ i, j ].
8954  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
8955  *   component. Then
8956  *   _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ i, 0 ].
8957  * 3.  The arrays have same number of components and one array, say _a2_, has one
8958  *   tuple. Then
8959  *   _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ 0, j ].
8960  *
8961  * Info on components is copied either from the first array (in the first case) or from
8962  * the array with maximal number of elements (getNbOfElems()).
8963  *  \param [in] a1 - an array to subtract from.
8964  *  \param [in] a2 - an array to subtract.
8965  *  \return DataArrayInt * - the new instance of DataArrayInt.
8966  *          The caller is to delete this result array using decrRef() as it is no more
8967  *          needed.
8968  *  \throw If either \a a1 or \a a2 is NULL.
8969  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
8970  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
8971  *         none of them has number of tuples or components equal to 1.
8972  */
8973 DataArrayInt *DataArrayInt::Substract(const DataArrayInt *a1, const DataArrayInt *a2) throw(INTERP_KERNEL::Exception)
8974 {
8975   if(!a1 || !a2)
8976     throw INTERP_KERNEL::Exception("DataArrayInt::Substract : input DataArrayInt instance is NULL !");
8977   int nbOfTuple1=a1->getNumberOfTuples();
8978   int nbOfTuple2=a2->getNumberOfTuples();
8979   int nbOfComp1=a1->getNumberOfComponents();
8980   int nbOfComp2=a2->getNumberOfComponents();
8981   if(nbOfTuple2==nbOfTuple1)
8982     {
8983       if(nbOfComp1==nbOfComp2)
8984         {
8985           MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
8986           ret->alloc(nbOfTuple2,nbOfComp1);
8987           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::minus<int>());
8988           ret->copyStringInfoFrom(*a1);
8989           return ret.retn();
8990         }
8991       else if(nbOfComp2==1)
8992         {
8993           MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
8994           ret->alloc(nbOfTuple1,nbOfComp1);
8995           const int *a2Ptr=a2->getConstPointer();
8996           const int *a1Ptr=a1->getConstPointer();
8997           int *res=ret->getPointer();
8998           for(int i=0;i<nbOfTuple1;i++)
8999             res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::minus<int>(),a2Ptr[i]));
9000           ret->copyStringInfoFrom(*a1);
9001           return ret.retn();
9002         }
9003       else
9004         {
9005           a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Substract !");
9006           return 0;
9007         }
9008     }
9009   else if(nbOfTuple2==1)
9010     {
9011       a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Substract !");
9012       MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
9013       ret->alloc(nbOfTuple1,nbOfComp1);
9014       const int *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
9015       int *pt=ret->getPointer();
9016       for(int i=0;i<nbOfTuple1;i++)
9017         pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::minus<int>());
9018       ret->copyStringInfoFrom(*a1);
9019       return ret.retn();
9020     }
9021   else
9022     {
9023       a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Substract !");//will always throw an exception
9024       return 0;
9025     }
9026 }
9027
9028 /*!
9029  * Subtract values of another DataArrayInt from values of \a this one. There are 3
9030  * valid cases.
9031  * 1.  The arrays have same number of tuples and components. Then each value of
9032  *   \a other array is subtracted from the corresponding value of \a this array, i.e.:
9033  *   _a_ [ i, j ] -= _other_ [ i, j ].
9034  * 2.  The arrays have same number of tuples and \a other array has one component. Then
9035  *   _a_ [ i, j ] -= _other_ [ i, 0 ].
9036  * 3.  The arrays have same number of components and \a other array has one tuple. Then
9037  *   _a_ [ i, j ] -= _a2_ [ 0, j ].
9038  *
9039  *  \param [in] other - an array to subtract from \a this one.
9040  *  \throw If \a other is NULL.
9041  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
9042  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
9043  *         \a other has number of both tuples and components not equal to 1.
9044  */
9045 void DataArrayInt::substractEqual(const DataArrayInt *other) throw(INTERP_KERNEL::Exception)
9046 {
9047   if(!other)
9048     throw INTERP_KERNEL::Exception("DataArrayInt::substractEqual : input DataArrayInt instance is NULL !");
9049   const char *msg="Nb of tuples mismatch for DataArrayInt::substractEqual  !";
9050   checkAllocated(); other->checkAllocated();
9051   int nbOfTuple=getNumberOfTuples();
9052   int nbOfTuple2=other->getNumberOfTuples();
9053   int nbOfComp=getNumberOfComponents();
9054   int nbOfComp2=other->getNumberOfComponents();
9055   if(nbOfTuple==nbOfTuple2)
9056     {
9057       if(nbOfComp==nbOfComp2)
9058         {
9059           std::transform(begin(),end(),other->begin(),getPointer(),std::minus<int>());
9060         }
9061       else if(nbOfComp2==1)
9062         {
9063           int *ptr=getPointer();
9064           const int *ptrc=other->getConstPointer();
9065           for(int i=0;i<nbOfTuple;i++)
9066             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::minus<int>(),*ptrc++));
9067         }
9068       else
9069         throw INTERP_KERNEL::Exception(msg);
9070     }
9071   else if(nbOfTuple2==1)
9072     {
9073       int *ptr=getPointer();
9074       const int *ptrc=other->getConstPointer();
9075       for(int i=0;i<nbOfTuple;i++)
9076         std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::minus<int>());
9077     }
9078   else
9079     throw INTERP_KERNEL::Exception(msg);
9080   declareAsNew();
9081 }
9082
9083 /*!
9084  * Returns a new DataArrayInt that is a product of two given arrays. There are 3
9085  * valid cases.
9086  * 1.  The arrays have same number of tuples and components. Then each value of
9087  *   the result array (_a_) is a product of the corresponding values of \a a1 and
9088  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ i, j ].
9089  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
9090  *   component. Then
9091  *   _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ i, 0 ].
9092  * 3.  The arrays have same number of components and one array, say _a2_, has one
9093  *   tuple. Then
9094  *   _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ 0, j ].
9095  *
9096  * Info on components is copied either from the first array (in the first case) or from
9097  * the array with maximal number of elements (getNbOfElems()).
9098  *  \param [in] a1 - a factor array.
9099  *  \param [in] a2 - another factor array.
9100  *  \return DataArrayInt * - the new instance of DataArrayInt.
9101  *          The caller is to delete this result array using decrRef() as it is no more
9102  *          needed.
9103  *  \throw If either \a a1 or \a a2 is NULL.
9104  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
9105  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
9106  *         none of them has number of tuples or components equal to 1.
9107  */
9108 DataArrayInt *DataArrayInt::Multiply(const DataArrayInt *a1, const DataArrayInt *a2) throw(INTERP_KERNEL::Exception)
9109 {
9110   if(!a1 || !a2)
9111     throw INTERP_KERNEL::Exception("DataArrayInt::Multiply : input DataArrayInt instance is NULL !");
9112   int nbOfTuple=a1->getNumberOfTuples();
9113   int nbOfTuple2=a2->getNumberOfTuples();
9114   int nbOfComp=a1->getNumberOfComponents();
9115   int nbOfComp2=a2->getNumberOfComponents();
9116   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=0;
9117   if(nbOfTuple==nbOfTuple2)
9118     {
9119       if(nbOfComp==nbOfComp2)
9120         {
9121           ret=DataArrayInt::New();
9122           ret->alloc(nbOfTuple,nbOfComp);
9123           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::multiplies<int>());
9124           ret->copyStringInfoFrom(*a1);
9125         }
9126       else
9127         {
9128           int nbOfCompMin,nbOfCompMax;
9129           const DataArrayInt *aMin, *aMax;
9130           if(nbOfComp>nbOfComp2)
9131             {
9132               nbOfCompMin=nbOfComp2; nbOfCompMax=nbOfComp;
9133               aMin=a2; aMax=a1;
9134             }
9135           else
9136             {
9137               nbOfCompMin=nbOfComp; nbOfCompMax=nbOfComp2;
9138               aMin=a1; aMax=a2;
9139             }
9140           if(nbOfCompMin==1)
9141             {
9142               ret=DataArrayInt::New();
9143               ret->alloc(nbOfTuple,nbOfCompMax);
9144               const int *aMinPtr=aMin->getConstPointer();
9145               const int *aMaxPtr=aMax->getConstPointer();
9146               int *res=ret->getPointer();
9147               for(int i=0;i<nbOfTuple;i++)
9148                 res=std::transform(aMaxPtr+i*nbOfCompMax,aMaxPtr+(i+1)*nbOfCompMax,res,std::bind2nd(std::multiplies<int>(),aMinPtr[i]));
9149               ret->copyStringInfoFrom(*aMax);
9150             }
9151           else
9152             throw INTERP_KERNEL::Exception("Nb of components mismatch for array Multiply !");
9153         }
9154     }
9155   else if((nbOfTuple==1 && nbOfTuple2>1) || (nbOfTuple>1 && nbOfTuple2==1))
9156     {
9157       if(nbOfComp==nbOfComp2)
9158         {
9159           int nbOfTupleMax=std::max(nbOfTuple,nbOfTuple2);
9160           const DataArrayInt *aMin=nbOfTuple>nbOfTuple2?a2:a1;
9161           const DataArrayInt *aMax=nbOfTuple>nbOfTuple2?a1:a2;
9162           const int *aMinPtr=aMin->getConstPointer(),*aMaxPtr=aMax->getConstPointer();
9163           ret=DataArrayInt::New();
9164           ret->alloc(nbOfTupleMax,nbOfComp);
9165           int *res=ret->getPointer();
9166           for(int i=0;i<nbOfTupleMax;i++)
9167             res=std::transform(aMaxPtr+i*nbOfComp,aMaxPtr+(i+1)*nbOfComp,aMinPtr,res,std::multiplies<int>());
9168           ret->copyStringInfoFrom(*aMax);
9169         }
9170       else
9171         throw INTERP_KERNEL::Exception("Nb of components mismatch for array Multiply !");
9172     }
9173   else
9174     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Multiply !");
9175   return ret.retn();
9176 }
9177
9178
9179 /*!
9180  * Multiply values of another DataArrayInt to values of \a this one. There are 3
9181  * valid cases.
9182  * 1.  The arrays have same number of tuples and components. Then each value of
9183  *   \a other array is multiplied to the corresponding value of \a this array, i.e.:
9184  *   _a_ [ i, j ] *= _other_ [ i, j ].
9185  * 2.  The arrays have same number of tuples and \a other array has one component. Then
9186  *   _a_ [ i, j ] *= _other_ [ i, 0 ].
9187  * 3.  The arrays have same number of components and \a other array has one tuple. Then
9188  *   _a_ [ i, j ] *= _a2_ [ 0, j ].
9189  *
9190  *  \param [in] other - an array to multiply to \a this one.
9191  *  \throw If \a other is NULL.
9192  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
9193  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
9194  *         \a other has number of both tuples and components not equal to 1.
9195  */
9196 void DataArrayInt::multiplyEqual(const DataArrayInt *other) throw(INTERP_KERNEL::Exception)
9197 {
9198   if(!other)
9199     throw INTERP_KERNEL::Exception("DataArrayInt::multiplyEqual : input DataArrayInt instance is NULL !");
9200   const char *msg="Nb of tuples mismatch for DataArrayInt::multiplyEqual !";
9201   checkAllocated(); other->checkAllocated();
9202   int nbOfTuple=getNumberOfTuples();
9203   int nbOfTuple2=other->getNumberOfTuples();
9204   int nbOfComp=getNumberOfComponents();
9205   int nbOfComp2=other->getNumberOfComponents();
9206   if(nbOfTuple==nbOfTuple2)
9207     {
9208       if(nbOfComp==nbOfComp2)
9209         {
9210           std::transform(begin(),end(),other->begin(),getPointer(),std::multiplies<int>());
9211         }
9212       else if(nbOfComp2==1)
9213         {
9214           int *ptr=getPointer();
9215           const int *ptrc=other->getConstPointer();
9216           for(int i=0;i<nbOfTuple;i++)
9217             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::multiplies<int>(),*ptrc++));    
9218         }
9219       else
9220         throw INTERP_KERNEL::Exception(msg);
9221     }
9222   else if(nbOfTuple2==1)
9223     {
9224       if(nbOfComp2==nbOfComp)
9225         {
9226           int *ptr=getPointer();
9227           const int *ptrc=other->getConstPointer();
9228           for(int i=0;i<nbOfTuple;i++)
9229             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::multiplies<int>());
9230         }
9231       else
9232         throw INTERP_KERNEL::Exception(msg);
9233     }
9234   else
9235     throw INTERP_KERNEL::Exception(msg);
9236   declareAsNew();
9237 }
9238
9239
9240 /*!
9241  * Returns a new DataArrayInt that is a division of two given arrays. There are 3
9242  * valid cases.
9243  * 1.  The arrays have same number of tuples and components. Then each value of
9244  *   the result array (_a_) is a division of the corresponding values of \a a1 and
9245  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ i, j ].
9246  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
9247  *   component. Then
9248  *   _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ i, 0 ].
9249  * 3.  The arrays have same number of components and one array, say _a2_, has one
9250  *   tuple. Then
9251  *   _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ 0, j ].
9252  *
9253  * Info on components is copied either from the first array (in the first case) or from
9254  * the array with maximal number of elements (getNbOfElems()).
9255  *  \param [in] a1 - a numerator array.
9256  *  \param [in] a2 - a denominator array.
9257  *  \return DataArrayInt * - the new instance of DataArrayInt.
9258  *          The caller is to delete this result array using decrRef() as it is no more
9259  *          needed.
9260  *  \throw If either \a a1 or \a a2 is NULL.
9261  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
9262  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
9263  *         none of them has number of tuples or components equal to 1.
9264  *  \warning No check of division by zero is performed!
9265  */
9266 DataArrayInt *DataArrayInt::Divide(const DataArrayInt *a1, const DataArrayInt *a2) throw(INTERP_KERNEL::Exception)
9267 {
9268   if(!a1 || !a2)
9269     throw INTERP_KERNEL::Exception("DataArrayInt::Divide : input DataArrayInt instance is NULL !");
9270   int nbOfTuple1=a1->getNumberOfTuples();
9271   int nbOfTuple2=a2->getNumberOfTuples();
9272   int nbOfComp1=a1->getNumberOfComponents();
9273   int nbOfComp2=a2->getNumberOfComponents();
9274   if(nbOfTuple2==nbOfTuple1)
9275     {
9276       if(nbOfComp1==nbOfComp2)
9277         {
9278           MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
9279           ret->alloc(nbOfTuple2,nbOfComp1);
9280           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::divides<int>());
9281           ret->copyStringInfoFrom(*a1);
9282           return ret.retn();
9283         }
9284       else if(nbOfComp2==1)
9285         {
9286           MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
9287           ret->alloc(nbOfTuple1,nbOfComp1);
9288           const int *a2Ptr=a2->getConstPointer();
9289           const int *a1Ptr=a1->getConstPointer();
9290           int *res=ret->getPointer();
9291           for(int i=0;i<nbOfTuple1;i++)
9292             res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::divides<int>(),a2Ptr[i]));
9293           ret->copyStringInfoFrom(*a1);
9294           return ret.retn();
9295         }
9296       else
9297         {
9298           a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Divide !");
9299           return 0;
9300         }
9301     }
9302   else if(nbOfTuple2==1)
9303     {
9304       a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Divide !");
9305       MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
9306       ret->alloc(nbOfTuple1,nbOfComp1);
9307       const int *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
9308       int *pt=ret->getPointer();
9309       for(int i=0;i<nbOfTuple1;i++)
9310         pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::divides<int>());
9311       ret->copyStringInfoFrom(*a1);
9312       return ret.retn();
9313     }
9314   else
9315     {
9316       a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Divide !");//will always throw an exception
9317       return 0;
9318     }
9319 }
9320
9321 /*!
9322  * Divide values of \a this array by values of another DataArrayInt. There are 3
9323  * valid cases.
9324  * 1.  The arrays have same number of tuples and components. Then each value of
9325  *    \a this array is divided by the corresponding value of \a other one, i.e.:
9326  *   _a_ [ i, j ] /= _other_ [ i, j ].
9327  * 2.  The arrays have same number of tuples and \a other array has one component. Then
9328  *   _a_ [ i, j ] /= _other_ [ i, 0 ].
9329  * 3.  The arrays have same number of components and \a other array has one tuple. Then
9330  *   _a_ [ i, j ] /= _a2_ [ 0, j ].
9331  *
9332  *  \param [in] other - an array to divide \a this one by.
9333  *  \throw If \a other is NULL.
9334  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
9335  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
9336  *         \a other has number of both tuples and components not equal to 1.
9337  *  \warning No check of division by zero is performed!
9338  */
9339 void DataArrayInt::divideEqual(const DataArrayInt *other) throw(INTERP_KERNEL::Exception)
9340 {
9341   if(!other)
9342     throw INTERP_KERNEL::Exception("DataArrayInt::divideEqual : input DataArrayInt instance is NULL !");
9343   const char *msg="Nb of tuples mismatch for DataArrayInt::divideEqual !";
9344   checkAllocated(); other->checkAllocated();
9345   int nbOfTuple=getNumberOfTuples();
9346   int nbOfTuple2=other->getNumberOfTuples();
9347   int nbOfComp=getNumberOfComponents();
9348   int nbOfComp2=other->getNumberOfComponents();
9349   if(nbOfTuple==nbOfTuple2)
9350     {
9351       if(nbOfComp==nbOfComp2)
9352         {
9353           std::transform(begin(),end(),other->begin(),getPointer(),std::divides<int>());
9354         }
9355       else if(nbOfComp2==1)
9356         {
9357           int *ptr=getPointer();
9358           const int *ptrc=other->getConstPointer();
9359           for(int i=0;i<nbOfTuple;i++)
9360             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::divides<int>(),*ptrc++));
9361         }
9362       else
9363         throw INTERP_KERNEL::Exception(msg);
9364     }
9365   else if(nbOfTuple2==1)
9366     {
9367       if(nbOfComp2==nbOfComp)
9368         {
9369           int *ptr=getPointer();
9370           const int *ptrc=other->getConstPointer();
9371           for(int i=0;i<nbOfTuple;i++)
9372             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::divides<int>());
9373         }
9374       else
9375         throw INTERP_KERNEL::Exception(msg);
9376     }
9377   else
9378     throw INTERP_KERNEL::Exception(msg);
9379   declareAsNew();
9380 }
9381
9382
9383 /*!
9384  * Returns a new DataArrayInt that is a modulus of two given arrays. There are 3
9385  * valid cases.
9386  * 1.  The arrays have same number of tuples and components. Then each value of
9387  *   the result array (_a_) is a division of the corresponding values of \a a1 and
9388  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] % _a2_ [ i, j ].
9389  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
9390  *   component. Then
9391  *   _a_ [ i, j ] = _a1_ [ i, j ] % _a2_ [ i, 0 ].
9392  * 3.  The arrays have same number of components and one array, say _a2_, has one
9393  *   tuple. Then
9394  *   _a_ [ i, j ] = _a1_ [ i, j ] % _a2_ [ 0, j ].
9395  *
9396  * Info on components is copied either from the first array (in the first case) or from
9397  * the array with maximal number of elements (getNbOfElems()).
9398  *  \param [in] a1 - a dividend array.
9399  *  \param [in] a2 - a divisor array.
9400  *  \return DataArrayInt * - the new instance of DataArrayInt.
9401  *          The caller is to delete this result array using decrRef() as it is no more
9402  *          needed.
9403  *  \throw If either \a a1 or \a a2 is NULL.
9404  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
9405  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
9406  *         none of them has number of tuples or components equal to 1.
9407  *  \warning No check of division by zero is performed!
9408  */
9409 DataArrayInt *DataArrayInt::Modulus(const DataArrayInt *a1, const DataArrayInt *a2) throw(INTERP_KERNEL::Exception)
9410 {
9411     if(!a1 || !a2)
9412     throw INTERP_KERNEL::Exception("DataArrayInt::Modulus : input DataArrayInt instance is NULL !");
9413   int nbOfTuple1=a1->getNumberOfTuples();
9414   int nbOfTuple2=a2->getNumberOfTuples();
9415   int nbOfComp1=a1->getNumberOfComponents();
9416   int nbOfComp2=a2->getNumberOfComponents();
9417   if(nbOfTuple2==nbOfTuple1)
9418     {
9419       if(nbOfComp1==nbOfComp2)
9420         {
9421           MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
9422           ret->alloc(nbOfTuple2,nbOfComp1);
9423           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::modulus<int>());
9424           ret->copyStringInfoFrom(*a1);
9425           return ret.retn();
9426         }
9427       else if(nbOfComp2==1)
9428         {
9429           MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
9430           ret->alloc(nbOfTuple1,nbOfComp1);
9431           const int *a2Ptr=a2->getConstPointer();
9432           const int *a1Ptr=a1->getConstPointer();
9433           int *res=ret->getPointer();
9434           for(int i=0;i<nbOfTuple1;i++)
9435             res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::modulus<int>(),a2Ptr[i]));
9436           ret->copyStringInfoFrom(*a1);
9437           return ret.retn();
9438         }
9439       else
9440         {
9441           a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Modulus !");
9442           return 0;
9443         }
9444     }
9445   else if(nbOfTuple2==1)
9446     {
9447       a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Modulus !");
9448       MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
9449       ret->alloc(nbOfTuple1,nbOfComp1);
9450       const int *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
9451       int *pt=ret->getPointer();
9452       for(int i=0;i<nbOfTuple1;i++)
9453         pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::modulus<int>());
9454       ret->copyStringInfoFrom(*a1);
9455       return ret.retn();
9456     }
9457   else
9458     {
9459       a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Modulus !");//will always throw an exception
9460       return 0;
9461     }
9462 }
9463
9464 /*!
9465  * Modify \a this array so that each value becomes a modulus of division of this value by
9466  * a value of another DataArrayInt. There are 3 valid cases.
9467  * 1.  The arrays have same number of tuples and components. Then each value of
9468  *    \a this array is divided by the corresponding value of \a other one, i.e.:
9469  *   _a_ [ i, j ] %= _other_ [ i, j ].
9470  * 2.  The arrays have same number of tuples and \a other array has one component. Then
9471  *   _a_ [ i, j ] %= _other_ [ i, 0 ].
9472  * 3.  The arrays have same number of components and \a other array has one tuple. Then
9473  *   _a_ [ i, j ] %= _a2_ [ 0, j ].
9474  *
9475  *  \param [in] other - a divisor array.
9476  *  \throw If \a other is NULL.
9477  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
9478  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
9479  *         \a other has number of both tuples and components not equal to 1.
9480  *  \warning No check of division by zero is performed!
9481  */
9482 void DataArrayInt::modulusEqual(const DataArrayInt *other) throw(INTERP_KERNEL::Exception)
9483 {
9484   if(!other)
9485     throw INTERP_KERNEL::Exception("DataArrayInt::modulusEqual : input DataArrayInt instance is NULL !");
9486   const char *msg="Nb of tuples mismatch for DataArrayInt::modulusEqual !";
9487   checkAllocated(); other->checkAllocated();
9488   int nbOfTuple=getNumberOfTuples();
9489   int nbOfTuple2=other->getNumberOfTuples();
9490   int nbOfComp=getNumberOfComponents();
9491   int nbOfComp2=other->getNumberOfComponents();
9492   if(nbOfTuple==nbOfTuple2)
9493     {
9494       if(nbOfComp==nbOfComp2)
9495         {
9496           std::transform(begin(),end(),other->begin(),getPointer(),std::modulus<int>());
9497         }
9498       else if(nbOfComp2==1)
9499         {
9500           if(nbOfComp2==nbOfComp)
9501             {
9502               int *ptr=getPointer();
9503               const int *ptrc=other->getConstPointer();
9504               for(int i=0;i<nbOfTuple;i++)
9505                 std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::modulus<int>(),*ptrc++));
9506             }
9507           else
9508             throw INTERP_KERNEL::Exception(msg);
9509         }
9510       else
9511         throw INTERP_KERNEL::Exception(msg);
9512     }
9513   else if(nbOfTuple2==1)
9514     {
9515       int *ptr=getPointer();
9516       const int *ptrc=other->getConstPointer();
9517       for(int i=0;i<nbOfTuple;i++)
9518         std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::modulus<int>());
9519     }
9520   else
9521     throw INTERP_KERNEL::Exception(msg);
9522   declareAsNew();
9523 }
9524
9525 /*!
9526  * Returns a C array which is a renumbering map in "Old to New" mode for the input array.
9527  * This map, if applied to \a start array, would make it sorted. For example, if
9528  * \a start array contents are [9,10,0,6,4,11,3,7] then the contents of the result array is
9529  * [5,6,0,3,2,7,1,4].
9530  *  \param [in] start - pointer to the first element of the array for which the
9531  *         permutation map is computed.
9532  *  \param [in] end - pointer specifying the end of the array \a start, so that
9533  *         the last value of \a start is \a end[ -1 ].
9534  *  \return int * - the result permutation array that the caller is to delete as it is no
9535  *         more needed.
9536  *  \throw If there are equal values in the input array.
9537  */
9538 int *DataArrayInt::CheckAndPreparePermutation(const int *start, const int *end)
9539 {
9540   std::size_t sz=std::distance(start,end);
9541   int *ret=new int[sz];
9542   int *work=new int[sz];
9543   std::copy(start,end,work);
9544   std::sort(work,work+sz);
9545   if(std::unique(work,work+sz)!=work+sz)
9546     {
9547       delete [] work;
9548       delete [] ret;
9549       throw INTERP_KERNEL::Exception("Some elements are equals in the specified array !");
9550     }
9551   int *iter2=ret;
9552   for(const int *iter=start;iter!=end;iter++,iter2++)
9553     *iter2=(int)std::distance(work,std::find(work,work+sz,*iter));
9554   delete [] work;
9555   return ret;
9556 }
9557
9558 /*!
9559  * Returns a new DataArrayInt containing an arithmetic progression
9560  * that is equal to the sequence returned by Python \c range(\a begin,\a  end,\a  step )
9561  * function.
9562  *  \param [in] begin - the start value of the result sequence.
9563  *  \param [in] end - limiting value, so that every value of the result array is less than
9564  *              \a end.
9565  *  \param [in] step - specifies the increment or decrement.
9566  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
9567  *          array using decrRef() as it is no more needed.
9568  *  \throw If \a step == 0.
9569  *  \throw If \a end < \a begin && \a step > 0.
9570  *  \throw If \a end > \a begin && \a step < 0.
9571  */
9572 DataArrayInt *DataArrayInt::Range(int begin, int end, int step) throw(INTERP_KERNEL::Exception)
9573 {
9574   int nbOfTuples=GetNumberOfItemGivenBESRelative(begin,end,step,"DataArrayInt::Range");
9575   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
9576   ret->alloc(nbOfTuples,1);
9577   int *ptr=ret->getPointer();
9578   if(step>0)
9579     {
9580       for(int i=begin;i<end;i+=step,ptr++)
9581         *ptr=i;
9582     }
9583   else
9584     {
9585       for(int i=begin;i>end;i+=step,ptr++)
9586         *ptr=i;
9587     }
9588   return ret.retn();
9589 }
9590
9591 /*!
9592  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
9593  * Server side.
9594  */
9595 void DataArrayInt::getTinySerializationIntInformation(std::vector<int>& tinyInfo) const
9596 {
9597   tinyInfo.resize(2);
9598   if(isAllocated())
9599     {
9600       tinyInfo[0]=getNumberOfTuples();
9601       tinyInfo[1]=getNumberOfComponents();
9602     }
9603   else
9604     {
9605       tinyInfo[0]=-1;
9606       tinyInfo[1]=-1;
9607     }
9608 }
9609
9610 /*!
9611  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
9612  * Server side.
9613  */
9614 void DataArrayInt::getTinySerializationStrInformation(std::vector<std::string>& tinyInfo) const
9615 {
9616   if(isAllocated())
9617     {
9618       int nbOfCompo=getNumberOfComponents();
9619       tinyInfo.resize(nbOfCompo+1);
9620       tinyInfo[0]=getName();
9621       for(int i=0;i<nbOfCompo;i++)
9622         tinyInfo[i+1]=getInfoOnComponent(i);
9623     }
9624   else
9625     {
9626       tinyInfo.resize(1);
9627       tinyInfo[0]=getName();
9628     }
9629 }
9630
9631 /*!
9632  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
9633  * This method returns if a feeding is needed.
9634  */
9635 bool DataArrayInt::resizeForUnserialization(const std::vector<int>& tinyInfoI)
9636 {
9637   int nbOfTuple=tinyInfoI[0];
9638   int nbOfComp=tinyInfoI[1];
9639   if(nbOfTuple!=-1 || nbOfComp!=-1)
9640     {
9641       alloc(nbOfTuple,nbOfComp);
9642       return true;
9643     }
9644   return false;
9645 }
9646
9647 /*!
9648  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
9649  * This method returns if a feeding is needed.
9650  */
9651 void DataArrayInt::finishUnserialization(const std::vector<int>& tinyInfoI, const std::vector<std::string>& tinyInfoS)
9652 {
9653   setName(tinyInfoS[0].c_str());
9654   if(isAllocated())
9655     {
9656       int nbOfCompo=getNumberOfComponents();
9657       for(int i=0;i<nbOfCompo;i++)
9658         setInfoOnComponent(i,tinyInfoS[i+1].c_str());
9659     }
9660 }
9661
9662 DataArrayIntIterator::DataArrayIntIterator(DataArrayInt *da):_da(da),_pt(0),_tuple_id(0),_nb_comp(0),_nb_tuple(0)
9663 {
9664   if(_da)
9665     {
9666       _da->incrRef();
9667       if(_da->isAllocated())
9668         {
9669           _nb_comp=da->getNumberOfComponents();
9670           _nb_tuple=da->getNumberOfTuples();
9671           _pt=da->getPointer();
9672         }
9673     }
9674 }
9675
9676 DataArrayIntIterator::~DataArrayIntIterator()
9677 {
9678   if(_da)
9679     _da->decrRef();
9680 }
9681
9682 DataArrayIntTuple *DataArrayIntIterator::nextt()
9683 {
9684   if(_tuple_id<_nb_tuple)
9685     {
9686       _tuple_id++;
9687       DataArrayIntTuple *ret=new DataArrayIntTuple(_pt,_nb_comp);
9688       _pt+=_nb_comp;
9689       return ret;
9690     }
9691   else
9692     return 0;
9693 }
9694
9695 DataArrayIntTuple::DataArrayIntTuple(int *pt, int nbOfComp):_pt(pt),_nb_of_compo(nbOfComp)
9696 {
9697 }
9698
9699 std::string DataArrayIntTuple::repr() const
9700 {
9701   std::ostringstream oss; oss << "(";
9702   for(int i=0;i<_nb_of_compo-1;i++)
9703     oss << _pt[i] << ", ";
9704   oss << _pt[_nb_of_compo-1] << ")";
9705   return oss.str();
9706 }
9707
9708 int DataArrayIntTuple::intValue() const throw(INTERP_KERNEL::Exception)
9709 {
9710   if(_nb_of_compo==1)
9711     return *_pt;
9712   throw INTERP_KERNEL::Exception("DataArrayIntTuple::intValue : DataArrayIntTuple instance has not exactly 1 component -> Not possible to convert it into an integer !");
9713 }
9714
9715 /*!
9716  * This method returns a newly allocated instance the caller should dealed with by a ParaMEDMEM::DataArrayInt::decrRef.
9717  * This method performs \b no copy of data. The content is only referenced using ParaMEDMEM::DataArrayInt::useArray with ownership set to \b false.
9718  * 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
9719  * \b nbOfCompo=1 and \bnbOfTuples==this->_nb_of_elem.
9720  */
9721 DataArrayInt *DataArrayIntTuple::buildDAInt(int nbOfTuples, int nbOfCompo) const throw(INTERP_KERNEL::Exception)
9722 {
9723   if((_nb_of_compo==nbOfCompo && nbOfTuples==1) || (_nb_of_compo==nbOfTuples && nbOfCompo==1))
9724     {
9725       DataArrayInt *ret=DataArrayInt::New();
9726       ret->useExternalArrayWithRWAccess(_pt,nbOfTuples,nbOfCompo);
9727       return ret;
9728     }
9729   else
9730     {
9731       std::ostringstream oss; oss << "DataArrayIntTuple::buildDAInt : unable to build a requested DataArrayInt instance with nbofTuple=" << nbOfTuples << " and nbOfCompo=" << nbOfCompo;
9732       oss << ".\nBecause the number of elements in this is " << _nb_of_compo << " !";
9733       throw INTERP_KERNEL::Exception(oss.str().c_str());
9734     }
9735 }