Salome HOME
Merge from V6_main_20120808 08Aug12
[modules/med.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
20 #include "MEDCouplingMemArray.txx"
21 #include "MEDCouplingAutoRefCountObjectPtr.hxx"
22
23 #include "GenMathFormulae.hxx"
24 #include "InterpKernelExprParser.hxx"
25
26 #include <set>
27 #include <cmath>
28 #include <limits>
29 #include <numeric>
30 #include <functional>
31
32 typedef double (*MYFUNCPTR)(double);
33
34 using namespace ParaMEDMEM;
35
36 template<int SPACEDIM>
37 void DataArrayDouble::findCommonTuplesAlg(const double *bbox, int nbNodes, int limitNodeId, double prec, std::vector<int>& c, std::vector<int>& cI) const
38 {
39   const double *coordsPtr=getConstPointer();
40   BBTree<SPACEDIM,int> myTree(bbox,0,0,nbNodes,prec/10);
41   std::vector<bool> isDone(nbNodes);
42   for(int i=0;i<nbNodes;i++)
43     {
44       if(!isDone[i])
45         {
46           std::vector<int> intersectingElems;
47           myTree.getElementsAroundPoint(coordsPtr+i*SPACEDIM,intersectingElems);
48           if(intersectingElems.size()>1)
49             {
50               std::vector<int> commonNodes;
51               for(std::vector<int>::const_iterator it=intersectingElems.begin();it!=intersectingElems.end();it++)
52                 if(*it!=i)
53                   if(*it>=limitNodeId)
54                     {
55                       commonNodes.push_back(*it);
56                       isDone[*it]=true;
57                     }
58               if(!commonNodes.empty())
59                 {
60                   cI.push_back(cI.back()+(int)commonNodes.size()+1);
61                   c.push_back(i);
62                   c.insert(c.end(),commonNodes.begin(),commonNodes.end());
63                 }
64             }
65         }
66     }
67 }
68
69 template<int SPACEDIM>
70 void DataArrayDouble::findTupleIdsNearTuplesAlg(const BBTree<SPACEDIM,int>& myTree, const double *pos, int nbOfTuples, double eps,
71                                                 std::vector<int>& c, std::vector<int>& cI) const
72 {
73   const double *coordsPtr=getConstPointer();
74   for(int i=0;i<nbOfTuples;i++)
75     {
76       std::vector<int> intersectingElems;
77       myTree.getElementsAroundPoint(pos+i*SPACEDIM,intersectingElems);
78       std::vector<int> commonNodes;
79       for(std::vector<int>::const_iterator it=intersectingElems.begin();it!=intersectingElems.end();it++)
80         commonNodes.push_back(*it);
81       cI.push_back(cI.back()+(int)commonNodes.size());
82       c.insert(c.end(),commonNodes.begin(),commonNodes.end());
83     }
84 }
85
86 void DataArray::setName(const char *name)
87 {
88   _name=name;
89 }
90
91 void DataArray::copyStringInfoFrom(const DataArray& other) throw(INTERP_KERNEL::Exception)
92 {
93   if(_info_on_compo.size()!=other._info_on_compo.size())
94     throw INTERP_KERNEL::Exception("Size of arrays mismatches on copyStringInfoFrom !");
95   _name=other._name;
96   _info_on_compo=other._info_on_compo;
97 }
98
99 void DataArray::copyPartOfStringInfoFrom(const DataArray& other, const std::vector<int>& compoIds) throw(INTERP_KERNEL::Exception)
100 {
101   int nbOfCompoOth=other.getNumberOfComponents();
102   std::size_t newNbOfCompo=compoIds.size();
103   for(std::size_t i=0;i<newNbOfCompo;i++)
104     if(compoIds[i]>=nbOfCompoOth || compoIds[i]<0)
105       {
106         std::ostringstream oss; oss << "Specified component id is out of range (" << compoIds[i] << ") compared with nb of actual components (" << nbOfCompoOth << ")";
107         throw INTERP_KERNEL::Exception(oss.str().c_str());
108       }
109   for(std::size_t i=0;i<newNbOfCompo;i++)
110     setInfoOnComponent((int)i,other.getInfoOnComponent(compoIds[i]).c_str());
111 }
112
113 void DataArray::copyPartOfStringInfoFrom2(const std::vector<int>& compoIds, const DataArray& other) throw(INTERP_KERNEL::Exception)
114 {
115   int nbOfCompo=getNumberOfComponents();
116   std::size_t partOfCompoToSet=compoIds.size();
117   if((int)partOfCompoToSet!=other.getNumberOfComponents())
118     throw INTERP_KERNEL::Exception("Given compoIds has not the same size as number of components of given array !");
119   for(std::size_t i=0;i<partOfCompoToSet;i++)
120     if(compoIds[i]>=nbOfCompo || compoIds[i]<0)
121       {
122         std::ostringstream oss; oss << "Specified component id is out of range (" << compoIds[i] << ") compared with nb of actual components (" << nbOfCompo << ")";
123         throw INTERP_KERNEL::Exception(oss.str().c_str());
124       }
125   for(std::size_t i=0;i<partOfCompoToSet;i++)
126     setInfoOnComponent(compoIds[i],other.getInfoOnComponent((int)i).c_str());
127 }
128
129 bool DataArray::areInfoEqualsIfNotWhy(const DataArray& other, std::string& reason) const
130 {
131   std::ostringstream oss;
132   if(_nb_of_tuples!=other._nb_of_tuples)
133     {
134       oss << "Number of tuples of DataArray mismatch : this number of tuples=" << _nb_of_tuples << " other number of tuples=" << other._nb_of_tuples;
135       reason=oss.str();
136       return false;
137     }
138   if(_name!=other._name)
139     {
140       oss << "Names DataArray mismatch : this name=\"" << _name << " other name=\"" << other._name << "\" !";
141       reason=oss.str();
142       return false;
143     }
144   if(_info_on_compo!=other._info_on_compo)
145     {
146       oss << "Components DataArray mismatch : \nThis components=";
147       for(std::vector<std::string>::const_iterator it=_info_on_compo.begin();it!=_info_on_compo.end();it++)
148         oss << "\"" << *it << "\",";
149       oss << "\nOther components=";
150       for(std::vector<std::string>::const_iterator it=other._info_on_compo.begin();it!=other._info_on_compo.end();it++)
151         oss << "\"" << *it << "\",";
152       reason=oss.str();
153       return false;
154     }
155   return true;
156 }
157
158 bool DataArray::areInfoEquals(const DataArray& other) const
159 {
160   std::string tmp;
161   return areInfoEqualsIfNotWhy(other,tmp);
162 }
163
164 void DataArray::reprWithoutNameStream(std::ostream& stream) const
165 {
166   stream << "Number of components : "<< getNumberOfComponents() << "\n";
167   stream << "Info of these components : ";
168   for(std::vector<std::string>::const_iterator iter=_info_on_compo.begin();iter!=_info_on_compo.end();iter++)
169     stream << "\"" << *iter << "\"   ";
170   stream << "\n";
171 }
172
173 void DataArray::setInfoOnComponents(const std::vector<std::string>& info) throw(INTERP_KERNEL::Exception)
174 {
175   if(getNumberOfComponents()!=(int)info.size())
176     {
177       std::ostringstream oss; oss << "DataArray::setInfoOnComponents : input is of size " << info.size() << " whereas number of components is equal to " << getNumberOfComponents() << " !";
178       throw INTERP_KERNEL::Exception(oss.str().c_str());
179     }
180   _info_on_compo=info;
181 }
182
183 std::vector<std::string> DataArray::getVarsOnComponent() const
184 {
185   int nbOfCompo=(int)_info_on_compo.size();
186   std::vector<std::string> ret(nbOfCompo);
187   for(int i=0;i<nbOfCompo;i++)
188     ret[i]=getVarOnComponent(i);
189   return ret;
190 }
191
192 std::vector<std::string> DataArray::getUnitsOnComponent() const
193 {
194   int nbOfCompo=(int)_info_on_compo.size();
195   std::vector<std::string> ret(nbOfCompo);
196   for(int i=0;i<nbOfCompo;i++)
197     ret[i]=getUnitOnComponent(i);
198   return ret;
199 }
200
201 std::string DataArray::getInfoOnComponent(int i) const throw(INTERP_KERNEL::Exception)
202 {
203   if(i<(int)_info_on_compo.size() && i>=0)
204     return _info_on_compo[i];
205   else
206     {
207       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();
208       throw INTERP_KERNEL::Exception(oss.str().c_str());
209     }
210 }
211
212 /*!
213  * In the info part of i_th component this method returns the var part.
214  * For example, if getInfoOnComponent(0) return "SIGXY (N/m^2)", getVarOnComponent(0) will return "SIGXY"
215  */
216 std::string DataArray::getVarOnComponent(int i) const throw(INTERP_KERNEL::Exception)
217 {
218   if(i<(int)_info_on_compo.size() && i>=0)
219     {
220       return GetVarNameFromInfo(_info_on_compo[i]);
221     }
222   else
223     {
224       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();
225       throw INTERP_KERNEL::Exception(oss.str().c_str());
226     }
227 }
228
229 /*!
230  * In the info part of i_th component this method returns the var part.
231  * For example, if getInfoOnComponent(0) return "SIGXY (N/m^2)", getUnitOnComponent(0) will return "N/m^2"
232  */
233 std::string DataArray::getUnitOnComponent(int i) const throw(INTERP_KERNEL::Exception)
234 {
235   if(i<(int)_info_on_compo.size() && i>=0)
236     {
237       return GetUnitFromInfo(_info_on_compo[i]);
238     }
239   else
240     {
241       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();
242       throw INTERP_KERNEL::Exception(oss.str().c_str());
243     }
244 }
245
246 std::string DataArray::GetVarNameFromInfo(const std::string& info) throw(INTERP_KERNEL::Exception)
247 {
248   std::size_t p1=info.find_last_of('[');
249   std::size_t p2=info.find_last_of(']');
250   if(p1==std::string::npos || p2==std::string::npos)
251     return info;
252   if(p1>p2)
253     return info;
254   if(p1==0)
255     return std::string();
256   std::size_t p3=info.find_last_not_of(' ',p1-1);
257   return info.substr(0,p3+1);
258 }
259
260 std::string DataArray::GetUnitFromInfo(const std::string& info) throw(INTERP_KERNEL::Exception)
261 {
262   std::size_t p1=info.find_last_of('[');
263   std::size_t p2=info.find_last_of(']');
264   if(p1==std::string::npos || p2==std::string::npos)
265     return std::string();
266   if(p1>p2)
267     return std::string();
268   return info.substr(p1+1,p2-p1-1);
269 }
270
271 void DataArray::setInfoOnComponent(int i, const char *info) throw(INTERP_KERNEL::Exception)
272 {
273   if(i<(int)_info_on_compo.size() && i>=0)
274     _info_on_compo[i]=info;
275   else
276     {
277       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();
278       throw INTERP_KERNEL::Exception(oss.str().c_str());
279     }
280 }
281
282 void DataArray::checkNbOfTuples(int nbOfTuples, const char *msg) const throw(INTERP_KERNEL::Exception)
283 {
284   if(getNumberOfTuples()!=nbOfTuples)
285     {
286       std::ostringstream oss; oss << msg << " : mismatch number of tuples : expected " <<  nbOfTuples << " having " << getNumberOfTuples() << " !";
287       throw INTERP_KERNEL::Exception(oss.str().c_str());
288     }
289 }
290
291 void DataArray::checkNbOfComps(int nbOfCompo, const char *msg) const throw(INTERP_KERNEL::Exception)
292 {
293   if(getNumberOfComponents()!=nbOfCompo)
294     {
295       std::ostringstream oss; oss << msg << " : mismatch number of components : expected " << nbOfCompo << " having " << getNumberOfComponents() << " !";
296       throw INTERP_KERNEL::Exception(oss.str().c_str());
297     }
298 }
299
300 void DataArray::checkNbOfElems(int nbOfElems, const char *msg) const throw(INTERP_KERNEL::Exception)
301 {
302   if(getNbOfElems()!=nbOfElems)
303     {
304       std::ostringstream oss; oss << msg << " : mismatch number of elems : Expected " << nbOfElems << " having " << getNbOfElems() << " !";
305       throw INTERP_KERNEL::Exception(oss.str().c_str());
306     }
307 }
308
309 void DataArray::checkNbOfTuplesAndComp(const DataArray& other, const char *msg) const throw(INTERP_KERNEL::Exception)
310 {
311    if(getNumberOfTuples()!=other.getNumberOfTuples())
312     {
313       std::ostringstream oss; oss << msg << " : mismatch number of tuples : expected " <<  other.getNumberOfTuples() << " having " << getNumberOfTuples() << " !";
314       throw INTERP_KERNEL::Exception(oss.str().c_str());
315     }
316   if(getNumberOfComponents()!=other.getNumberOfComponents())
317     {
318       std::ostringstream oss; oss << msg << " : mismatch number of components : expected " << other.getNumberOfComponents() << " having " << getNumberOfComponents() << " !";
319       throw INTERP_KERNEL::Exception(oss.str().c_str());
320     }
321 }
322
323 void DataArray::checkNbOfTuplesAndComp(int nbOfTuples, int nbOfCompo, const char *msg) const throw(INTERP_KERNEL::Exception)
324 {
325   checkNbOfTuples(nbOfTuples,msg);
326   checkNbOfComps(nbOfCompo,msg);
327 }
328
329 /*!
330  * Simply this method checks that \b value is in [0,\b ref).
331  */
332 void DataArray::CheckValueInRange(int ref, int value, const char *msg) throw(INTERP_KERNEL::Exception)
333 {
334   if(value<0 || value>=ref)
335     {
336       std::ostringstream oss; oss << "DataArray::CheckValueInRange : " << msg  << " ! Expected in range [0," << ref << "[ having " << value << " !";
337       throw INTERP_KERNEL::Exception(oss.str().c_str());
338     }
339 }
340
341 /*!
342  * This method checks that [\b start, \b end) is compliant with ref length \b value.
343  * typicaly start in [0,\b value) and end in [0,\b value). If value==start and start==end, it is supported.
344  */
345 void DataArray::CheckValueInRangeEx(int value, int start, int end, const char *msg) throw(INTERP_KERNEL::Exception)
346 {
347   if(start<0 || start>=value)
348     {
349       if(value!=start || end!=start)
350         {
351           std::ostringstream oss; oss << "DataArray::CheckValueInRange : " << msg  << " ! Expected start " << start << " of range in [0," << value << "[ !";
352           throw INTERP_KERNEL::Exception(oss.str().c_str());
353         }
354     }
355   if(end<0 || end>value)
356     {
357       std::ostringstream oss; oss << "DataArray::CheckClosingParInRange : " << msg  << " ! Expected start " << end << " of range in [0," << value << "[ !";
358       throw INTERP_KERNEL::Exception(oss.str().c_str());
359     }
360 }
361
362 void DataArray::CheckClosingParInRange(int ref, int value, const char *msg) throw(INTERP_KERNEL::Exception)
363 {
364   if(value<0 || value>ref)
365     {
366       std::ostringstream oss; oss << "DataArray::CheckClosingParInRange : " << msg  << " ! Expected a range in [0," << ref << "] having closing open parenthesis " << value << " !";
367       throw INTERP_KERNEL::Exception(oss.str().c_str());
368     }
369 }
370
371 int DataArray::GetNumberOfItemGivenBES(int begin, int end, int step, const char *msg) throw(INTERP_KERNEL::Exception)
372 {
373   if(end<begin)
374     {
375       std::ostringstream oss; oss << msg << " : end before begin !";
376       throw INTERP_KERNEL::Exception(oss.str().c_str());
377     }
378   if(step<=0)
379     {
380       std::ostringstream oss; oss << msg << " : invalid step should be > 0 !";
381       throw INTERP_KERNEL::Exception(oss.str().c_str());
382     }
383   return (end-1-begin)/step+1;
384 }
385
386 int DataArray::GetNumberOfItemGivenBESRelative(int begin, int end, int step, const char *msg) throw(INTERP_KERNEL::Exception)
387 {
388   if(step==0)
389     throw INTERP_KERNEL::Exception("DataArray::GetNumberOfItemGivenBES : step=0 is not allowed !");
390   if(end<begin && step>0)
391     {
392       std::ostringstream oss; oss << msg << " : end before begin whereas step is positive !";
393       throw INTERP_KERNEL::Exception(oss.str().c_str());
394     }
395   if(begin<end && step<0)
396     {
397       std::ostringstream oss; oss << msg << " : invalid step should be > 0 !";
398       throw INTERP_KERNEL::Exception(oss.str().c_str());
399     }
400   if(begin!=end)
401     return (std::max(begin,end)-1-std::min(begin,end))/std::abs(step)+1;
402   else
403     return 0;
404 }
405
406 int DataArray::GetPosOfItemGivenBESRelativeNoThrow(int value, int begin, int end, int step) throw(INTERP_KERNEL::Exception)
407 {
408   if(step!=0)
409     {
410       if(step>0)
411         {
412           if(begin<=value && value<end)
413             {
414               if((value-begin)%step==0)
415                 return (value-begin)/step;
416               else
417                 return -1;
418             }
419           else
420             return -1;
421         }
422       else
423         {
424           if(begin>=value && value>end)
425             {
426               if((begin-value)%(-step)==0)
427                 return (begin-value)/(-step);
428               else
429                 return -1;
430             }
431           else
432             return -1;
433         }
434     }
435   else
436     return -1;
437 }
438
439 DataArrayDouble *DataArrayDouble::New()
440 {
441   return new DataArrayDouble;
442 }
443
444 bool DataArrayDouble::isAllocated() const
445 {
446   return getConstPointer()!=0;
447 }
448
449 void DataArrayDouble::checkAllocated() const throw(INTERP_KERNEL::Exception)
450 {
451   if(!isAllocated())
452     throw INTERP_KERNEL::Exception("DataArrayDouble::checkAllocated : Array is defined but not allocated ! Call alloc or setValues method first !");
453 }
454
455 /*!
456  * This method differs from DataArray::setInfoOnComponents in the sense that if 'this->getNumberOfComponents()!=info.size()'
457  * and if 'this' is not allocated it will change the number of components of 'this'.
458  * If 'this->getNumberOfComponents()==info.size()' the behaviour is the same than DataArray::setInfoOnComponents method.
459  * If 'this->getNumberOfComponents()!=info.size()' and the 'this' is already allocated an exception will be thrown.
460  */
461 void DataArrayDouble::setInfoAndChangeNbOfCompo(const std::vector<std::string>& info) throw(INTERP_KERNEL::Exception)
462 {
463   if(getNumberOfComponents()!=(int)info.size())
464     {
465       if(!isAllocated())
466         _info_on_compo=info;
467       else
468         {
469           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 !";
470           throw INTERP_KERNEL::Exception(oss.str().c_str());
471         }
472     }
473   else
474     _info_on_compo=info;
475 }
476
477 /*!
478  * This method returns the only one value in 'this', if and only if number of elements (nb of tuples * nb of components) is equal to 1, and that 'this' is allocated.
479  * If one or more conditions is not fulfilled an exception will be thrown.
480  */
481 double DataArrayDouble::doubleValue() const throw(INTERP_KERNEL::Exception)
482 {
483   if(isAllocated())
484     {
485       if(getNbOfElems()==1)
486         {
487           return *getConstPointer();
488         }
489       else
490         throw INTERP_KERNEL::Exception("DataArrayDouble::doubleValue : DataArrayDouble instance is allocated but number of elements is not equal to 1 !");
491     }
492   else
493     throw INTERP_KERNEL::Exception("DataArrayDouble::doubleValue : DataArrayDouble instance is not allocated !");
494 }
495
496 /*!
497  * This method should be called on an allocated DataArrayDouble instance. If not an exception will be throw !
498  * This method checks the number of tupes. If it is equal to 0, it returns true, if not false is returned.
499  */
500 bool DataArrayDouble::empty() const throw(INTERP_KERNEL::Exception)
501 {
502   checkAllocated();
503   return getNumberOfTuples()==0;
504 }
505
506 DataArrayDouble *DataArrayDouble::deepCpy() const
507 {
508   return new DataArrayDouble(*this);
509 }
510
511 DataArrayDouble *DataArrayDouble::performCpy(bool dCpy) const
512 {
513   if(dCpy)
514     return deepCpy();
515   else
516     {
517       incrRef();
518       return const_cast<DataArrayDouble *>(this);
519     }
520 }
521
522 void DataArrayDouble::cpyFrom(const DataArrayDouble& other) throw(INTERP_KERNEL::Exception)
523 {
524   other.checkAllocated();
525   int nbOfTuples=other.getNumberOfTuples();
526   int nbOfComp=other.getNumberOfComponents();
527   allocIfNecessary(nbOfTuples,nbOfComp);
528   int nbOfElems=nbOfTuples*nbOfComp;
529   double *pt=getPointer();
530   const double *ptI=other.getConstPointer();
531   for(int i=0;i<nbOfElems;i++)
532     pt[i]=ptI[i];
533   copyStringInfoFrom(other);
534 }
535
536 void DataArrayDouble::allocIfNecessary(int nbOfTuple, int nbOfCompo)
537 {
538   if(isAllocated())
539     {
540       if(nbOfTuple!=getNumberOfTuples() || nbOfCompo!=getNumberOfComponents())
541         alloc(nbOfTuple,nbOfCompo);
542     }
543   else
544     alloc(nbOfTuple,nbOfCompo);
545 }
546
547 void DataArrayDouble::alloc(int nbOfTuple, int nbOfCompo) throw(INTERP_KERNEL::Exception)
548 {
549   if(nbOfTuple<0 || nbOfCompo<0)
550     throw INTERP_KERNEL::Exception("DataArrayDouble::alloc : request for negative length of data !");
551   _nb_of_tuples=nbOfTuple;
552   _info_on_compo.resize(nbOfCompo);
553   _mem.alloc(nbOfCompo*_nb_of_tuples);
554   declareAsNew();
555 }
556
557 void DataArrayDouble::fillWithZero() throw(INTERP_KERNEL::Exception)
558 {
559   checkAllocated();
560   _mem.fillWithValue(0.);
561   declareAsNew();
562 }
563
564 void DataArrayDouble::fillWithValue(double val) throw(INTERP_KERNEL::Exception)
565 {
566   checkAllocated();
567   _mem.fillWithValue(val);
568   declareAsNew();
569 }
570
571 void DataArrayDouble::iota(double init) throw(INTERP_KERNEL::Exception)
572 {
573   checkAllocated();
574   if(getNumberOfComponents()!=1)
575     throw INTERP_KERNEL::Exception("DataArrayDouble::iota : works only for arrays with only one component, you can call 'rearrange' method before !");
576   double *ptr=getPointer();
577   int ntuples=getNumberOfTuples();
578   for(int i=0;i<ntuples;i++)
579     ptr[i]=init+double(i);
580   declareAsNew();
581 }
582
583 bool DataArrayDouble::isUniform(double val, double eps) const throw(INTERP_KERNEL::Exception)
584 {
585   checkAllocated();
586   if(getNumberOfComponents()!=1)
587     throw INTERP_KERNEL::Exception("DataArrayDouble::isUniform : must be applied on DataArrayDouble with only one component, you can call 'rearrange' method before !");
588   int nbOfTuples=getNumberOfTuples();
589   const double *w=getConstPointer();
590   const double *end2=w+nbOfTuples;
591   const double vmin=val-eps;
592   const double vmax=val+eps;
593   for(;w!=end2;w++)
594     if(*w<vmin || *w>vmax)
595       return false;
596   return true;
597 }
598
599 void DataArrayDouble::sort(bool asc) throw(INTERP_KERNEL::Exception)
600 {
601   checkAllocated();
602   if(getNumberOfComponents()!=1)
603     throw INTERP_KERNEL::Exception("DataArrayDouble::sort : only supported with 'this' array with ONE component !");
604   _mem.sort(asc);
605 }
606
607 void DataArrayDouble::reverse() throw(INTERP_KERNEL::Exception)
608 {
609   checkAllocated();
610   if(getNumberOfComponents()!=1)
611     throw INTERP_KERNEL::Exception("DataArrayDouble::reverse : only supported with 'this' array with ONE component !");
612   _mem.reverse();
613 }
614
615 /*!
616  * This method check that (Maths) array consistently INCREASING or DECREASING in value,
617  * with at least absolute difference value of |eps| at each step.
618  * if not an exception will be thrown.
619  */
620  void DataArrayDouble::checkMonotonic(bool increasing, double eps) const throw(INTERP_KERNEL::Exception)
621 {
622   if(!isMonotonic(increasing, eps))
623     {
624       if (increasing)
625         {
626           throw INTERP_KERNEL::Exception("DataArrayDouble::checkMonotonic : 'this' is not INCREASING monotonic !");
627         }
628       else
629         {
630           throw INTERP_KERNEL::Exception("DataArrayDouble::checkMonotonic : 'this' is not DECREASING monotonic !");
631         }
632     }
633 }
634
635 /*!
636  * This method check that (Maths) array consistently INCREASING or DECREASING in value,
637  * with at least absolute difference value of |eps| at each step.
638  */
639 bool DataArrayDouble::isMonotonic(bool increasing, double eps) const throw(INTERP_KERNEL::Exception)
640 {
641   checkAllocated();
642   if(getNumberOfComponents()!=1)
643     throw INTERP_KERNEL::Exception("DataArrayDouble::isMonotonic : only supported with 'this' array with ONE component !");
644   int nbOfElements=getNumberOfTuples();
645   const double *ptr=getConstPointer();
646   if(nbOfElements==0)
647     return true;
648   double ref=ptr[0];
649   double absEps=fabs(eps);
650   if (increasing)
651     {
652       for(int i=1;i<nbOfElements;i++)
653         {
654           if(ptr[i]<(ref+absEps))
655             return false;
656           ref=ptr[i];
657         }
658       return true;
659     }
660   else
661     {
662       for(int i=1;i<nbOfElements;i++)
663         {
664           if(ptr[i]>(ref-absEps))
665             return false;
666           ref=ptr[i];
667         }
668       return true;
669     }
670 }
671
672 std::string DataArrayDouble::repr() const
673 {
674   std::ostringstream ret;
675   reprStream(ret);
676   return ret.str();
677 }
678
679 std::string DataArrayDouble::reprZip() const
680 {
681   std::ostringstream ret;
682   reprZipStream(ret);
683   return ret.str();
684 }
685
686 void DataArrayDouble::writeVTK(std::ostream& ofs, int indent, const char *nameInFile) const throw(INTERP_KERNEL::Exception)
687 {
688   std::string idt(indent,' ');
689   ofs.precision(15);
690   ofs << idt << "<DataArray type=\"Float32\" Name=\"" << nameInFile << "\" NumberOfComponents=\"" << getNumberOfComponents() << "\"";
691   ofs << " format=\"ascii\" RangeMin=\"" << getMinValueInArray() << "\" RangeMax=\"" << getMaxValueInArray() << "\">\n" << idt;
692   std::copy(begin(),end(),std::ostream_iterator<double>(ofs," "));
693   ofs << std::endl << idt << "</DataArray>\n";
694 }
695
696 void DataArrayDouble::reprStream(std::ostream& stream) const
697 {
698   stream << "Name of double array : \"" << _name << "\"\n";
699   reprWithoutNameStream(stream);
700 }
701
702 void DataArrayDouble::reprZipStream(std::ostream& stream) const
703 {
704   stream << "Name of double array : \"" << _name << "\"\n";
705   reprZipWithoutNameStream(stream);
706 }
707
708 void DataArrayDouble::reprWithoutNameStream(std::ostream& stream) const
709 {
710   DataArray::reprWithoutNameStream(stream);
711   stream.precision(15);
712   _mem.repr(getNumberOfComponents(),stream);
713 }
714
715 void DataArrayDouble::reprZipWithoutNameStream(std::ostream& stream) const
716 {
717   DataArray::reprWithoutNameStream(stream);
718   stream.precision(15);
719   _mem.reprZip(getNumberOfComponents(),stream);
720 }
721
722 bool DataArrayDouble::isEqualIfNotWhy(const DataArrayDouble& other, double prec, std::string& reason) const
723 {
724   if(!areInfoEqualsIfNotWhy(other,reason))
725     return false;
726   return _mem.isEqual(other._mem,prec,reason);
727 }
728
729 bool DataArrayDouble::isEqual(const DataArrayDouble& other, double prec) const
730 {
731   std::string tmp;
732   return isEqualIfNotWhy(other,prec,tmp);
733 }
734
735 bool DataArrayDouble::isEqualWithoutConsideringStr(const DataArrayDouble& other, double prec) const
736 {
737   std::string tmp;
738   return _mem.isEqual(other._mem,prec,tmp);
739 }
740
741 void DataArrayDouble::reAlloc(int nbOfTuples) throw(INTERP_KERNEL::Exception)
742 {
743   checkAllocated();
744   _mem.reAlloc((int)(_info_on_compo.size())*nbOfTuples);
745   _nb_of_tuples=nbOfTuples;
746   declareAsNew();
747 }
748
749 DataArrayInt *DataArrayDouble::convertToIntArr() const
750 {
751   DataArrayInt *ret=DataArrayInt::New();
752   ret->alloc(getNumberOfTuples(),getNumberOfComponents());
753   int nbOfVals=getNbOfElems();
754   const double *src=getConstPointer();
755   int *dest=ret->getPointer();
756   std::copy(src,src+nbOfVals,dest);
757   ret->copyStringInfoFrom(*this);
758   return ret;
759 }
760
761 DataArrayDouble *DataArrayDouble::fromNoInterlace() const throw(INTERP_KERNEL::Exception)
762 {
763   if(_mem.isNull())
764     throw INTERP_KERNEL::Exception("DataArrayDouble::fromNoInterlace : Not defined array !");
765   double *tab=_mem.fromNoInterlace(getNumberOfComponents());
766   DataArrayDouble *ret=DataArrayDouble::New();
767   ret->useArray(tab,true,CPP_DEALLOC,getNumberOfTuples(),getNumberOfComponents());
768   return ret;
769 }
770
771 DataArrayDouble *DataArrayDouble::toNoInterlace() const throw(INTERP_KERNEL::Exception)
772 {
773   if(_mem.isNull())
774     throw INTERP_KERNEL::Exception("DataArrayDouble::fromNoInterlace : Not defined array !");
775   double *tab=_mem.toNoInterlace(getNumberOfComponents());
776   DataArrayDouble *ret=DataArrayDouble::New();
777   ret->useArray(tab,true,CPP_DEALLOC,getNumberOfTuples(),getNumberOfComponents());
778   return ret;
779 }
780
781 /*!
782  * This method does \b not change the number of tuples after this call.
783  * Only a permutation is done. If a permutation reduction is needed substr, or selectByTupleId should be used.
784  */
785 void DataArrayDouble::renumberInPlace(const int *old2New)
786 {
787   int nbTuples=getNumberOfTuples();
788   int nbOfCompo=getNumberOfComponents();
789   double *tmp=new double[nbTuples*nbOfCompo];
790   const double *iptr=getConstPointer();
791   for(int i=0;i<nbTuples;i++)
792     std::copy(iptr+nbOfCompo*i,iptr+nbOfCompo*(i+1),tmp+nbOfCompo*old2New[i]);
793   std::copy(tmp,tmp+nbTuples*nbOfCompo,getPointer());
794   delete [] tmp;
795   declareAsNew();
796 }
797
798 /*!
799  * This method does \b not change the number of tuples after this call.
800  * Only a permutation is done.
801  */
802 void DataArrayDouble::renumberInPlaceR(const int *new2Old)
803 {
804   int nbTuples=getNumberOfTuples();
805   int nbOfCompo=getNumberOfComponents();
806   double *tmp=new double[nbTuples*nbOfCompo];
807   const double *iptr=getConstPointer();
808   for(int i=0;i<nbTuples;i++)
809     std::copy(iptr+nbOfCompo*new2Old[i],iptr+nbOfCompo*(new2Old[i]+1),tmp+nbOfCompo*i);
810   std::copy(tmp,tmp+nbTuples*nbOfCompo,getPointer());
811   delete [] tmp;
812   declareAsNew();
813 }
814
815 /*!
816  * This method does \b not change the number of tuples after this call.
817  * Only a permutation is done. If a permutation reduction is needed renumberAndReduce.
818  */
819 DataArrayDouble *DataArrayDouble::renumber(const int *old2New) const
820 {
821   int nbTuples=getNumberOfTuples();
822   int nbOfCompo=getNumberOfComponents();
823   DataArrayDouble *ret=DataArrayDouble::New();
824   ret->alloc(nbTuples,nbOfCompo);
825   ret->copyStringInfoFrom(*this);
826   const double *iptr=getConstPointer();
827   double *optr=ret->getPointer();
828   for(int i=0;i<nbTuples;i++)
829     std::copy(iptr+nbOfCompo*i,iptr+nbOfCompo*(i+1),optr+nbOfCompo*old2New[i]);
830   ret->copyStringInfoFrom(*this);
831   return ret;
832 }
833
834 /*!
835  * This method does \b not change the number of tuples after this call.
836  * Only a permutation is done. If a permutation reduction is needed substr, or selectByTupleId should be used.
837  */
838 DataArrayDouble *DataArrayDouble::renumberR(const int *new2Old) const
839 {
840   int nbTuples=getNumberOfTuples();
841   int nbOfCompo=getNumberOfComponents();
842   DataArrayDouble *ret=DataArrayDouble::New();
843   ret->alloc(nbTuples,nbOfCompo);
844   ret->copyStringInfoFrom(*this);
845   const double *iptr=getConstPointer();
846   double *optr=ret->getPointer();
847   for(int i=0;i<nbTuples;i++)
848     std::copy(iptr+nbOfCompo*new2Old[i],iptr+nbOfCompo*(new2Old[i]+1),optr+i*nbOfCompo);
849   ret->copyStringInfoFrom(*this);
850   return ret;
851 }
852
853 /*!
854  * Idem DataArrayDouble::renumber method except that the number of tuples is reduced.
855  * That is to say that it is expected that newNbOfTuple<this->getNumberOfTuples().
856  * ['old2New','old2New'+getNumberOfTuples()) defines a range containing old to new array. For every negative value in ['old2NewBg','old2New'+getNumberOfTuples()) the corresponding tuple is
857  * omitted.
858  */
859 DataArrayDouble *DataArrayDouble::renumberAndReduce(const int *old2New, int newNbOfTuple) const
860 {
861   int nbTuples=getNumberOfTuples();
862   int nbOfCompo=getNumberOfComponents();
863   DataArrayDouble *ret=DataArrayDouble::New();
864   ret->alloc(newNbOfTuple,nbOfCompo);
865   const double *iptr=getConstPointer();
866   double *optr=ret->getPointer();
867   for(int i=0;i<nbTuples;i++)
868     {
869       int w=old2New[i];
870       if(w>=0)
871         std::copy(iptr+i*nbOfCompo,iptr+(i+1)*nbOfCompo,optr+w*nbOfCompo);
872     }
873   ret->copyStringInfoFrom(*this);
874   return ret;
875 }
876
877 /*!
878  * This method is a generalization of DataArrayDouble::substr method because a not contigous range can be specified here.
879  * This method is equivalent to DataArrayDouble::renumberAndReduce except that convention in input is new2old and \b not old2new.
880  */
881 DataArrayDouble *DataArrayDouble::selectByTupleId(const int *new2OldBg, const int *new2OldEnd) const
882 {
883   DataArrayDouble *ret=DataArrayDouble::New();
884   int nbComp=getNumberOfComponents();
885   ret->alloc((int)std::distance(new2OldBg,new2OldEnd),nbComp);
886   ret->copyStringInfoFrom(*this);
887   double *pt=ret->getPointer();
888   const double *srcPt=getConstPointer();
889   int i=0;
890   for(const int *w=new2OldBg;w!=new2OldEnd;w++,i++)
891     std::copy(srcPt+(*w)*nbComp,srcPt+((*w)+1)*nbComp,pt+i*nbComp);
892   ret->copyStringInfoFrom(*this);
893   return ret;
894 }
895
896 /*!
897  * This method is equivalent to DataArrayDouble::selectByTupleId except that an analyze to the content of input range to check that it will not lead to memory corruption !
898  */
899 DataArrayDouble *DataArrayDouble::selectByTupleIdSafe(const int *new2OldBg, const int *new2OldEnd) const throw(INTERP_KERNEL::Exception)
900 {
901   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
902   int nbComp=getNumberOfComponents();
903   int oldNbOfTuples=getNumberOfTuples();
904   ret->alloc((int)std::distance(new2OldBg,new2OldEnd),nbComp);
905   ret->copyStringInfoFrom(*this);
906   double *pt=ret->getPointer();
907   const double *srcPt=getConstPointer();
908   int i=0;
909   for(const int *w=new2OldBg;w!=new2OldEnd;w++,i++)
910     if(*w>=0 && *w<oldNbOfTuples)
911       std::copy(srcPt+(*w)*nbComp,srcPt+((*w)+1)*nbComp,pt+i*nbComp);
912     else
913       throw INTERP_KERNEL::Exception("DataArrayInt::selectByTupleIdSafe : some ids has been detected to be out of [0,this->getNumberOfTuples) !");
914   ret->copyStringInfoFrom(*this);
915   ret->incrRef();
916   return ret;
917 }
918
919 /*!
920  * Idem than DataArrayInt::selectByTupleIdSafe except that the input array is not constructed explicitely.
921  * The convention is as python one. ['bg','end2') with steps of 'step'.
922  * Returns a newly created array.
923  * This method is a generalization of DataArrayDouble::substr.
924  *
925  * \sa DataArrayDouble::substr
926  */
927 DataArrayDouble *DataArrayDouble::selectByTupleId2(int bg, int end2, int step) const throw(INTERP_KERNEL::Exception)
928 {
929   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
930   int nbComp=getNumberOfComponents();
931   int newNbOfTuples=GetNumberOfItemGivenBES(bg,end2,step,"DataArrayDouble::selectByTupleId2 : ");
932   ret->alloc(newNbOfTuples,nbComp);
933   double *pt=ret->getPointer();
934   const double *srcPt=getConstPointer()+bg*nbComp;
935   for(int i=0;i<newNbOfTuples;i++,srcPt+=step*nbComp)
936     std::copy(srcPt,srcPt+nbComp,pt+i*nbComp);
937   ret->copyStringInfoFrom(*this);
938   ret->incrRef();
939   return ret;
940 }
941
942 /*!
943  * This method returns a newly allocated array that is the concatenation of all tuples ranges in param 'ranges'.
944  * Each pair in input 'ranges' is in [begin,end) format. If there is a range in 'ranges' so that end is before begin an exception
945  * will be thrown. If there is a range in 'ranges' so that end is greater than number of tuples of 'this', an exception will be thrown too.
946  */
947 DataArrayDouble *DataArrayDouble::selectByTupleRanges(const std::vector<std::pair<int,int> >& ranges) const throw(INTERP_KERNEL::Exception)
948 {
949   checkAllocated();
950   int nbOfComp=getNumberOfComponents();
951   int nbOfTuplesThis=getNumberOfTuples();
952   if(ranges.empty())
953     {
954       DataArrayDouble *ret=DataArrayDouble::New();
955       ret->alloc(0,nbOfComp);
956       ret->copyStringInfoFrom(*this);
957       return ret;
958     }
959   int ref=ranges.front().first;
960   int nbOfTuples=0;
961   bool isIncreasing=true;
962   for(std::vector<std::pair<int,int> >::const_iterator it=ranges.begin();it!=ranges.end();it++)
963     {
964       if((*it).first<=(*it).second)
965         {
966           if((*it).first>=0 && (*it).second<=nbOfTuplesThis)
967             {
968               nbOfTuples+=(*it).second-(*it).first;
969               if(isIncreasing)
970                 isIncreasing=ref<=(*it).first;
971               ref=(*it).second;
972             }
973           else
974             {
975               std::ostringstream oss; oss << "DataArrayDouble::selectByTupleRanges : on range #" << std::distance(ranges.begin(),it);
976               oss << " (" << (*it).first << "," << (*it).second << ") is greater than number of tuples of this :" << nbOfTuples << " !";
977               throw INTERP_KERNEL::Exception(oss.str().c_str());
978             }
979         }
980       else
981         {
982           std::ostringstream oss; oss << "DataArrayDouble::selectByTupleRanges : on range #" << std::distance(ranges.begin(),it);
983           oss << " (" << (*it).first << "," << (*it).second << ") end is before begin !";
984           throw INTERP_KERNEL::Exception(oss.str().c_str());
985         }
986     }
987   if(isIncreasing && nbOfTuplesThis==nbOfTuples)
988     return deepCpy();
989   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
990   ret->alloc(nbOfTuples,nbOfComp);
991   ret->copyStringInfoFrom(*this);
992   const double *src=getConstPointer();
993   double *work=ret->getPointer();
994   for(std::vector<std::pair<int,int> >::const_iterator it=ranges.begin();it!=ranges.end();it++)
995     work=std::copy(src+(*it).first*nbOfComp,src+(*it).second*nbOfComp,work);
996   ret->incrRef();
997   return ret;
998 }
999
1000 /*!
1001  * This methods has a similar behaviour than std::string::substr. This method returns a newly created DataArrayInt that is part of this with same number of components.
1002  * The intervall is specified by [tupleIdBg,tupleIdEnd) except if tupleIdEnd ==-1 in this case the [tupleIdBg,this->end()) will be kept.
1003  * This method check that interval is valid regarding this, if not an exception will be thrown.
1004  * This method is a specialization of method DataArrayDouble::selectByTupleId2.
1005  *
1006  * \sa DataArrayDouble::selectByTupleId2
1007  */
1008 DataArrayDouble *DataArrayDouble::substr(int tupleIdBg, int tupleIdEnd) const throw(INTERP_KERNEL::Exception)
1009 {
1010   int nbt=getNumberOfTuples();
1011   if(tupleIdBg<0)
1012     throw INTERP_KERNEL::Exception("DataArrayDouble::substr : The tupleIdBg parameter must be greater than 0 !");
1013   if(tupleIdBg>nbt)
1014     throw INTERP_KERNEL::Exception("DataArrayDouble::substr : The tupleIdBg parameter is greater than number of tuples !");
1015   int trueEnd=tupleIdEnd;
1016   if(tupleIdEnd!=-1)
1017     {
1018       if(tupleIdEnd>nbt)
1019         throw INTERP_KERNEL::Exception("DataArrayDouble::substr : The tupleIdBg parameter is greater or equal than number of tuples !");
1020     }
1021   else
1022     trueEnd=nbt;
1023   int nbComp=getNumberOfComponents();
1024   DataArrayDouble *ret=DataArrayDouble::New();
1025   ret->alloc(trueEnd-tupleIdBg,nbComp);
1026   ret->copyStringInfoFrom(*this);
1027   std::copy(getConstPointer()+tupleIdBg*nbComp,getConstPointer()+trueEnd*nbComp,ret->getPointer());
1028   return ret;
1029 }
1030
1031 /*!
1032  * This method builds a new instance of DataArrayDouble (to deal with) that is reduction or an extension of 'this'.
1033  * if 'newNbOfComp' < this->getNumberOfComponents() a reduction is done and for each tuple 'newNbOfComp' first components are kept.
1034  * If 'newNbOfComp' > this->getNumberOfComponents() an extension is done, and for each components i such that i > getNumberOfComponents() 'dftValue' parameter is taken.
1035  */
1036 DataArrayDouble *DataArrayDouble::changeNbOfComponents(int newNbOfComp, double dftValue) const throw(INTERP_KERNEL::Exception)
1037 {
1038   checkAllocated();
1039   DataArrayDouble *ret=DataArrayDouble::New();
1040   ret->alloc(getNumberOfTuples(),newNbOfComp);
1041   const double *oldc=getConstPointer();
1042   double *nc=ret->getPointer();
1043   int nbOfTuples=getNumberOfTuples();
1044   int oldNbOfComp=getNumberOfComponents();
1045   int dim=std::min(oldNbOfComp,newNbOfComp);
1046   for(int i=0;i<nbOfTuples;i++)
1047     {
1048       int j=0;
1049       for(;j<dim;j++)
1050         nc[newNbOfComp*i+j]=oldc[i*oldNbOfComp+j];
1051       for(;j<newNbOfComp;j++)
1052         nc[newNbOfComp*i+j]=dftValue;
1053     }
1054   ret->setName(getName().c_str());
1055   for(int i=0;i<dim;i++)
1056     ret->setInfoOnComponent(i,getInfoOnComponent(i).c_str());
1057   ret->setName(getName().c_str());
1058   return ret;
1059 }
1060
1061 /*!
1062  * Contrary to DataArrayDouble::changeNbOfComponents method this method is \b not const. The content 
1063  * This method \b do \b not change the content of data but changes the splitting of this data seen by the caller.
1064  * This method makes the assumption that 'this' is already allocated. If not an exception will be thrown.
1065  * This method checks that getNbOfElems()%newNbOfCompo==0. If not an exception will be throw !
1066  * This method erases all components info set before call !
1067  */
1068 void DataArrayDouble::rearrange(int newNbOfCompo) throw(INTERP_KERNEL::Exception)
1069 {
1070   checkAllocated();
1071   int nbOfElems=getNbOfElems();
1072   if(nbOfElems%newNbOfCompo!=0)
1073     throw INTERP_KERNEL::Exception("DataArrayDouble::rearrange : nbOfElems%newNbOfCompo!=0 !");
1074   _nb_of_tuples=nbOfElems/newNbOfCompo;
1075   _info_on_compo.clear();
1076   _info_on_compo.resize(newNbOfCompo);
1077   declareAsNew();
1078 }
1079
1080 /*!
1081  * This method makes the assumption that \b this is allocated. If not an INTERP_KERNEL::Exception will be raised.
1082  * This method does not echange the values stored in \b this. Simply, the number of components before the call becomes the number of
1083  * tuples and inversely the number of tuples becomes the number of components. \b WARNING the info on components can be alterated by this method.
1084  */
1085 void DataArrayDouble::transpose() throw(INTERP_KERNEL::Exception)
1086 {
1087   checkAllocated();
1088   int nbOfTuples=getNumberOfTuples();
1089   rearrange(nbOfTuples);
1090 }
1091
1092 DataArrayDouble *DataArrayDouble::keepSelectedComponents(const std::vector<int>& compoIds) const throw(INTERP_KERNEL::Exception)
1093 {
1094   checkAllocated();
1095   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret(DataArrayDouble::New());
1096   std::size_t newNbOfCompo=compoIds.size();
1097   int oldNbOfCompo=getNumberOfComponents();
1098   for(std::vector<int>::const_iterator it=compoIds.begin();it!=compoIds.end();it++)
1099     if((*it)<0 || (*it)>=oldNbOfCompo)
1100       {
1101         std::ostringstream oss; oss << "DataArrayDouble::keepSelectedComponents : invalid requested component : " << *it << " whereas it should be in [0," << oldNbOfCompo << ") !";
1102         throw INTERP_KERNEL::Exception(oss.str().c_str());
1103       }
1104   int nbOfTuples=getNumberOfTuples();
1105   ret->alloc(nbOfTuples,(int)newNbOfCompo);
1106   ret->copyPartOfStringInfoFrom(*this,compoIds);
1107   const double *oldc=getConstPointer();
1108   double *nc=ret->getPointer();
1109   for(int i=0;i<nbOfTuples;i++)
1110     for(std::size_t j=0;j<newNbOfCompo;j++,nc++)
1111       *nc=oldc[i*oldNbOfCompo+compoIds[j]];
1112   ret->incrRef();
1113   return ret;
1114 }
1115
1116 /*!
1117  * This method melds the components of 'this' with components of 'other'.
1118  * After this call in case of success, 'this' will contain a number of components equal to the sum of 'this'
1119  * before the call and the number of components of 'other'.
1120  * This method expects that 'this' and 'other' have exactly the same number of tuples. If not an exception is thrown.
1121  */
1122 void DataArrayDouble::meldWith(const DataArrayDouble *other) throw(INTERP_KERNEL::Exception)
1123 {
1124   checkAllocated();
1125   other->checkAllocated();
1126   int nbOfTuples=getNumberOfTuples();
1127   if(nbOfTuples!=other->getNumberOfTuples())
1128     throw INTERP_KERNEL::Exception("DataArrayDouble::meldWith : mismatch of number of tuples !");
1129   int nbOfComp1=getNumberOfComponents();
1130   int nbOfComp2=other->getNumberOfComponents();
1131   double *newArr=new double[nbOfTuples*(nbOfComp1+nbOfComp2)];
1132   double *w=newArr;
1133   const double *inp1=getConstPointer();
1134   const double *inp2=other->getConstPointer();
1135   for(int i=0;i<nbOfTuples;i++,inp1+=nbOfComp1,inp2+=nbOfComp2)
1136     {
1137       w=std::copy(inp1,inp1+nbOfComp1,w);
1138       w=std::copy(inp2,inp2+nbOfComp2,w);
1139     }
1140   useArray(newArr,true,CPP_DEALLOC,nbOfTuples,nbOfComp1+nbOfComp2);
1141   std::vector<int> compIds(nbOfComp2);
1142   for(int i=0;i<nbOfComp2;i++)
1143     compIds[i]=nbOfComp1+i;
1144   copyPartOfStringInfoFrom2(compIds,*other);
1145 }
1146
1147 /*!
1148  * This methods searches for each tuple if there are any tuples in 'this' that are less far than 'prec' from n1. if any, these tuples are stored in out params
1149  * comm and commIndex. The distance is computed using norm2. This method expects that 'this' is allocated and that the number of components is in [1,2,3].
1150  * If not an exception will be thrown.
1151  * This method is typically used by MEDCouplingPointSet::findCommonNodes and MEDCouplingUMesh::mergeNodes.
1152  * In case of success, commIndex->getNumberOfTuples()-1 gives the number of tuples groupes that are within distance 'prec'.
1153  * comm->getNumberOfTuples()==commIndex->back()
1154  * The returned pair of DataArrayInt instances ('comm','commIndex') is called Surjectived Format 2 \sa DataArrayInt::BuildNew2OldArrayFromSurjectiveFormat2.
1155  * This format is more compact in surjective format because only all tuple ids not in 'comm' are remain unchanged.
1156  * 
1157  * @param prec is an absolute precision.
1158  * @param limitTupleId is the limit tuple id. All tuples which id is strictly lower than 'limiTupleId' will not be merged each other.
1159  * @param comm out parameter (not inout). Number of components is equal to 1.
1160  * @param commIndex out parameter (not inout). Number of components is equal to 1.
1161  */
1162 void DataArrayDouble::findCommonTuples(double prec, int limitTupleId, DataArrayInt *&comm, DataArrayInt *&commIndex) const throw(INTERP_KERNEL::Exception)
1163 {
1164   checkAllocated();
1165   int nbOfCompo=getNumberOfComponents();
1166   if ((nbOfCompo<1) || (nbOfCompo>3)) //test before work
1167     throw INTERP_KERNEL::Exception("DataArrayDouble::findCommonTuples : Unexpected spacedim of coords. Must be 1, 2 or 3.");
1168   
1169   int nbOfTuples=getNumberOfTuples();
1170   comm=DataArrayInt::New();
1171   commIndex=DataArrayInt::New();
1172   //
1173   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> bbox=computeBBoxPerTuple(prec);
1174   //
1175   std::vector<int> c,cI(1);
1176   switch(nbOfCompo)
1177     {
1178     case 3:
1179       findCommonTuplesAlg<3>(bbox->getConstPointer(),nbOfTuples,limitTupleId,prec,c,cI);
1180       break;
1181     case 2:
1182       findCommonTuplesAlg<2>(bbox->getConstPointer(),nbOfTuples,limitTupleId,prec,c,cI);
1183       break;
1184     case 1:
1185       findCommonTuplesAlg<1>(bbox->getConstPointer(),nbOfTuples,limitTupleId,prec,c,cI);
1186       break;
1187     default:
1188       throw INTERP_KERNEL::Exception("DataArrayDouble::findCommonTuples : nb of components managed are 1,2 and 3 ! not implemented for other number of components !");
1189     }
1190   commIndex->alloc((int)cI.size(),1);
1191   std::copy(cI.begin(),cI.end(),commIndex->getPointer());
1192   comm->alloc(cI.back(),1);
1193   std::copy(c.begin(),c.end(),comm->getPointer());
1194 }
1195
1196 /*!
1197  * 
1198  * \param [in] nbTimes specifies the nb of times each tuples in \a this will be duplicated contiguouly in returned DataArrayDouble instance.
1199  *             \a nbTimes  should be at least equal to 1.
1200  * \return a newly allocated DataArrayDouble having one component and number of tuples equal to \a nbTimes * \c this->getNumberOfTuples.
1201  * \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.
1202  */
1203 DataArrayDouble *DataArrayDouble::duplicateEachTupleNTimes(int nbTimes) const throw(INTERP_KERNEL::Exception)
1204 {
1205   checkAllocated();
1206   if(getNumberOfComponents()!=1)
1207     throw INTERP_KERNEL::Exception("DataArrayDouble::duplicateEachTupleNTimes : this should have only one component !");
1208   if(nbTimes<1)
1209     throw INTERP_KERNEL::Exception("DataArrayDouble::duplicateEachTupleNTimes : nb times should be >= 1 !");
1210   int nbTuples=getNumberOfTuples();
1211   const double *inPtr=getConstPointer();
1212   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New(); ret->alloc(nbTimes*nbTuples,1);
1213   double *retPtr=ret->getPointer();
1214   for(int i=0;i<nbTuples;i++,inPtr++)
1215     {
1216       double val=*inPtr;
1217       for(int j=0;j<nbTimes;j++,retPtr++)
1218         *retPtr=val;
1219     }
1220   ret->copyStringInfoFrom(*this);
1221   ret->incrRef();
1222   return ret;
1223 }
1224
1225 /*!
1226  * This method returns a newly allocated object the user should deal with.
1227  * This method works for arrays which have number of components into [1,2,3]. If not an exception will be thrown.
1228  * This method returns the different values in 'this' using 'prec'. The different values are kept in the same
1229  * order than 'this'. That is to say that returned DataArrayDouble instance is not systematically sorted.
1230  *
1231  * @param prec is an absolute precision.
1232  * @param limitTupleId is the limit tuple id. All tuples which id is strictly lower than 'limiTupleId' will not be merged each other.
1233  */
1234 DataArrayDouble *DataArrayDouble::getDifferentValues(double prec, int limitTupleId) const throw(INTERP_KERNEL::Exception)
1235 {
1236   DataArrayInt *c0=0,*cI0=0;
1237   findCommonTuples(prec,limitTupleId,c0,cI0);
1238   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> c(c0),cI(cI0);
1239   int newNbOfTuples=-1;
1240   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> o2n=DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2(getNumberOfTuples(),c0,cI0,newNbOfTuples);
1241   return renumberAndReduce(o2n->getConstPointer(),newNbOfTuples);
1242 }
1243
1244 void DataArrayDouble::setSelectedComponents(const DataArrayDouble *a, const std::vector<int>& compoIds) throw(INTERP_KERNEL::Exception)
1245 {
1246   if(!a)
1247     throw INTERP_KERNEL::Exception("DataArrayDouble::setSelectedComponents : input DataArrayDouble is NULL !");
1248   copyPartOfStringInfoFrom2(compoIds,*a);
1249   std::size_t partOfCompoSz=compoIds.size();
1250   int nbOfCompo=getNumberOfComponents();
1251   int nbOfTuples=getNumberOfTuples();
1252   const double *ac=a->getConstPointer();
1253   double *nc=getPointer();
1254   for(int i=0;i<nbOfTuples;i++)
1255     for(std::size_t j=0;j<partOfCompoSz;j++,ac++)
1256       nc[nbOfCompo*i+compoIds[j]]=*ac;
1257 }
1258
1259 /*!
1260  * This method performs a partial assignment of 'this' using 'a' as input. Other input parameters specifies the subpart being considered by the assignment.
1261  * 'strictCompoCompare' specifies if DataArray 'a' should have exactly same number of components and tuples than 'this' (true) or not (false). By default set to true with maximal test.
1262  */
1263 void DataArrayDouble::setPartOfValues1(const DataArrayDouble *a, int bgTuples, int endTuples, int stepTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare) throw(INTERP_KERNEL::Exception)
1264 {
1265   if(!a)
1266     throw INTERP_KERNEL::Exception("DataArrayDouble::setPartOfValues1 : input DataArrayDouble is NULL !");
1267   const char msg[]="DataArrayDouble::setPartOfValues1";
1268   checkAllocated();
1269   a->checkAllocated();
1270   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
1271   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
1272   int nbComp=getNumberOfComponents();
1273   int nbOfTuples=getNumberOfTuples();
1274   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
1275   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
1276   a->checkNbOfElems(newNbOfTuples*newNbOfComp,msg);
1277   if(strictCompoCompare)
1278     a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
1279   double *pt=getPointer()+bgTuples*nbComp+bgComp;
1280   const double *srcPt=a->getConstPointer();
1281   for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
1282     for(int j=0;j<newNbOfComp;j++,srcPt++)
1283       pt[j*stepComp]=*srcPt;
1284 }
1285
1286 /*!
1287  * This method performs a partial assignment of 'this' using 'a' as input. Other input parameters specifies the subpart being considered by the assignment.
1288  */
1289 void DataArrayDouble::setPartOfValuesSimple1(double a, int bgTuples, int endTuples, int stepTuples, int bgComp, int endComp, int stepComp) throw(INTERP_KERNEL::Exception)
1290 {
1291   const char msg[]="DataArrayDouble::setPartOfValuesSimple1";
1292   checkAllocated();
1293   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
1294   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
1295   int nbComp=getNumberOfComponents();
1296   int nbOfTuples=getNumberOfTuples();
1297   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
1298   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
1299   double *pt=getPointer()+bgTuples*nbComp+bgComp;
1300   for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
1301     for(int j=0;j<newNbOfComp;j++)
1302       pt[j*stepComp]=a;
1303 }
1304
1305 /*!
1306  * This method performs a partial assignment of 'this' using 'a' as input. Other input parameters specifies the subpart being considered by the assignment.
1307  * 'strictCompoCompare' specifies if DataArray 'a' should have exactly same number of components and tuples than 'this' (true) or not (false). By default set to true with maximal test.
1308  */
1309 void DataArrayDouble::setPartOfValues2(const DataArrayDouble *a, const int *bgTuples, const int *endTuples, const int *bgComp, const int *endComp, bool strictCompoCompare) throw(INTERP_KERNEL::Exception)
1310 {
1311   if(!a)
1312     throw INTERP_KERNEL::Exception("DataArrayDouble::setPartOfValues2 : input DataArrayDouble is NULL !");
1313   const char msg[]="DataArrayDouble::setPartOfValues2";
1314   checkAllocated();
1315   a->checkAllocated();
1316   int nbComp=getNumberOfComponents();
1317   int nbOfTuples=getNumberOfTuples();
1318   for(const int *z=bgComp;z!=endComp;z++)
1319     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
1320   int newNbOfTuples=(int)std::distance(bgTuples,endTuples);
1321   int newNbOfComp=(int)std::distance(bgComp,endComp);
1322   bool assignTech=true;
1323   if(a->getNbOfElems()==newNbOfTuples*newNbOfComp)
1324     {
1325       if(strictCompoCompare)
1326         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
1327     }
1328   else
1329     {
1330       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
1331       assignTech=false;
1332     }
1333   double *pt=getPointer();
1334   const double *srcPt=a->getConstPointer();
1335   if(assignTech)
1336     {    
1337       for(const int *w=bgTuples;w!=endTuples;w++)
1338         {
1339           DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
1340           for(const int *z=bgComp;z!=endComp;z++,srcPt++)
1341             {    
1342               pt[(*w)*nbComp+(*z)]=*srcPt;
1343             }
1344         }
1345     }
1346   else
1347     {
1348       for(const int *w=bgTuples;w!=endTuples;w++)
1349         {
1350           const double *srcPt2=srcPt;
1351           DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
1352           for(const int *z=bgComp;z!=endComp;z++,srcPt2++)
1353             {    
1354               pt[(*w)*nbComp+(*z)]=*srcPt2;
1355             }
1356         }
1357     }
1358 }
1359
1360 /*!
1361  * This method performs a partial assignment of 'this' using 'a' as input. Other input parameters specifies the subpart being considered by the assignment.
1362  */
1363 void DataArrayDouble::setPartOfValuesSimple2(double a, const int *bgTuples, const int *endTuples, const int *bgComp, const int *endComp) throw(INTERP_KERNEL::Exception)
1364 {
1365   checkAllocated();
1366   int nbComp=getNumberOfComponents();
1367   int nbOfTuples=getNumberOfTuples();
1368   for(const int *z=bgComp;z!=endComp;z++)
1369     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
1370   double *pt=getPointer();
1371   for(const int *w=bgTuples;w!=endTuples;w++)
1372     for(const int *z=bgComp;z!=endComp;z++)
1373       {
1374         DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
1375         pt[(*w)*nbComp+(*z)]=a;
1376       }
1377 }
1378
1379 /*!
1380  * This method performs a partial assignment of 'this' using 'a' as input. Other input parameters specifies the subpart being considered by the assignment.
1381  * 'strictCompoCompare' specifies if DataArray 'a' should have exactly same number of components and tuples than 'this' (true) or not (false). By default set to true with maximal test.
1382  */
1383 void DataArrayDouble::setPartOfValues3(const DataArrayDouble *a, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare) throw(INTERP_KERNEL::Exception)
1384 {
1385   if(!a)
1386     throw INTERP_KERNEL::Exception("DataArrayDouble::setPartOfValues3 : input DataArrayDouble is NULL !");
1387   const char msg[]="DataArrayDouble::setPartOfValues3";
1388   checkAllocated();
1389   a->checkAllocated();
1390   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
1391   int nbComp=getNumberOfComponents();
1392   int nbOfTuples=getNumberOfTuples();
1393   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
1394   int newNbOfTuples=(int)std::distance(bgTuples,endTuples);
1395   bool assignTech=true;
1396   if(a->getNbOfElems()==newNbOfTuples*newNbOfComp)
1397     {
1398       if(strictCompoCompare)
1399         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
1400     }
1401   else
1402     {
1403       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
1404       assignTech=false;
1405     }
1406   double *pt=getPointer()+bgComp;
1407   const double *srcPt=a->getConstPointer();
1408   if(assignTech)
1409     {
1410       for(const int *w=bgTuples;w!=endTuples;w++)
1411         for(int j=0;j<newNbOfComp;j++,srcPt++)
1412           {
1413             DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
1414             pt[(*w)*nbComp+j*stepComp]=*srcPt;
1415           }
1416     }
1417   else
1418     {
1419       for(const int *w=bgTuples;w!=endTuples;w++)
1420         {
1421           const double *srcPt2=srcPt;
1422           for(int j=0;j<newNbOfComp;j++,srcPt2++)
1423             {
1424               DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
1425               pt[(*w)*nbComp+j*stepComp]=*srcPt2;
1426             }
1427         }
1428     }
1429 }
1430
1431 /*!
1432  * This method performs a partial assignment of 'this' using 'a' as input. Other input parameters specifies the subpart being considered by the assignment.
1433  */
1434 void DataArrayDouble::setPartOfValuesSimple3(double a, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp) throw(INTERP_KERNEL::Exception)
1435 {
1436   const char msg[]="DataArrayDouble::setPartOfValuesSimple3";
1437   checkAllocated();
1438   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
1439   int nbComp=getNumberOfComponents();
1440   int nbOfTuples=getNumberOfTuples();
1441   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
1442   double *pt=getPointer()+bgComp;
1443   for(const int *w=bgTuples;w!=endTuples;w++)
1444     for(int j=0;j<newNbOfComp;j++)
1445       {
1446         DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
1447         pt[(*w)*nbComp+j*stepComp]=a;
1448       }
1449 }
1450
1451 /*!
1452  * 'this', 'a' and 'tuplesSelec' are expected to be defined. If not an exception will be thrown.
1453  * @param a is an array having exactly the same number of components than 'this'
1454  * @param tuplesSelec is an array having exactly 2 components. The first one refers to the tuple ids of 'this' that will be set. The second one refers to the tuple ids of 'a' that will be used for setting.
1455  */
1456 void DataArrayDouble::setPartOfValuesAdv(const DataArrayDouble *a, const DataArrayInt *tuplesSelec) throw(INTERP_KERNEL::Exception)
1457 {
1458   if(!a)
1459     throw INTERP_KERNEL::Exception("DataArrayDouble::setPartOfValuesAdv : input DataArrayDouble is NULL !");
1460   checkAllocated();
1461   a->checkAllocated();
1462   tuplesSelec->checkAllocated();
1463   int nbOfComp=getNumberOfComponents();
1464   if(nbOfComp!=a->getNumberOfComponents())
1465     throw INTERP_KERNEL::Exception("DataArrayDouble::setPartOfValuesAdv : This and a do not have the same number of components !");
1466   if(tuplesSelec->getNumberOfComponents()!=2)
1467     throw INTERP_KERNEL::Exception("DataArrayDouble::setPartOfValuesAdv : Expecting to have a tuple selector DataArrayInt instance with exactly 2 components !");
1468   int thisNt=getNumberOfTuples();
1469   int aNt=a->getNumberOfTuples();
1470   double *valsToSet=getPointer();
1471   const double *valsSrc=a->getConstPointer();
1472   for(const int *tuple=tuplesSelec->begin();tuple!=tuplesSelec->end();tuple+=2)
1473     {
1474       if(tuple[1]>=0 && tuple[1]<aNt)
1475         {
1476           if(tuple[0]>=0 && tuple[0]<thisNt)
1477             std::copy(valsSrc+nbOfComp*tuple[1],valsSrc+nbOfComp*(tuple[1]+1),valsToSet+nbOfComp*tuple[0]);
1478           else
1479             {
1480               std::ostringstream oss; oss << "DataArrayDouble::setPartOfValuesAdv : Tuple #" << std::distance(tuplesSelec->begin(),tuple)/2;
1481               oss << " of 'tuplesSelec' request of tuple id #" << tuple[0] << " in 'this' ! It should be in [0," << thisNt << ") !";
1482               throw INTERP_KERNEL::Exception(oss.str().c_str());
1483             }
1484         }
1485       else
1486         {
1487           std::ostringstream oss; oss << "DataArrayDouble::setPartOfValuesAdv : Tuple #" << std::distance(tuplesSelec->begin(),tuple)/2;
1488           oss << " of 'tuplesSelec' request of tuple id #" << tuple[1] << " in 'a' ! It should be in [0," << aNt << ") !";
1489           throw INTERP_KERNEL::Exception(oss.str().c_str());
1490         }
1491     }
1492 }
1493
1494 /*!
1495  * 'this', 'a' and 'tuplesSelec' are expected to be defined. If not an exception will be thrown.
1496  * This is a method that is a specialization to DataArrayDouble::setPartOfValuesAdv method, except that here the tuple selection of 'a' is given by a range ('bg','end2' and 'step')
1497  * rather than an explicite array of tuple ids (given by the 2nd component) and the feeding is done in 'this' contiguously starting from 'tupleIdStart'.
1498  * @param a is an array having exactly the same number of components than 'this'
1499  */
1500 void DataArrayDouble::setContigPartOfSelectedValues(int tupleIdStart, const DataArrayDouble *a, const DataArrayInt *tuplesSelec) throw(INTERP_KERNEL::Exception)
1501 {
1502   if(!a || !tuplesSelec)
1503     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues : input DataArray is NULL !");
1504   checkAllocated();
1505   a->checkAllocated();
1506   tuplesSelec->checkAllocated();
1507   int nbOfComp=getNumberOfComponents();
1508   if(nbOfComp!=a->getNumberOfComponents())
1509     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues : This and a do not have the same number of components !");
1510   if(tuplesSelec->getNumberOfComponents()!=1)
1511     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues : Expecting to have a tuple selector DataArrayInt instance with exactly 1 component !");
1512   int thisNt=getNumberOfTuples();
1513   int aNt=a->getNumberOfTuples();
1514   int nbOfTupleToWrite=tuplesSelec->getNumberOfTuples();
1515   double *valsToSet=getPointer()+tupleIdStart*nbOfComp;
1516   if(tupleIdStart+nbOfTupleToWrite>thisNt)
1517     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues : invalid number range of values to write !");
1518   const double *valsSrc=a->getConstPointer();
1519   for(const int *tuple=tuplesSelec->begin();tuple!=tuplesSelec->end();tuple++,valsToSet+=nbOfComp)
1520     {
1521       if(*tuple>=0 && *tuple<aNt)
1522         {
1523           std::copy(valsSrc+nbOfComp*(*tuple),valsSrc+nbOfComp*(*tuple+1),valsToSet);
1524         }
1525       else
1526         {
1527           std::ostringstream oss; oss << "DataArrayDouble::setContigPartOfSelectedValues : Tuple #" << std::distance(tuplesSelec->begin(),tuple);
1528           oss << " of 'tuplesSelec' request of tuple id #" << *tuple << " in 'a' ! It should be in [0," << aNt << ") !";
1529           throw INTERP_KERNEL::Exception(oss.str().c_str());
1530         }
1531     }
1532 }
1533
1534 /*!
1535  * 'this' and 'a' are expected to be defined. If not an exception will be thrown.
1536  * This is a method that is a specialization to DataArrayDouble::setContigPartOfSelectedValues method, except that here the tuple selection is givenin a is done by a range ('bg','end2' and 'step')
1537  * rather than an explicite array of tuple ids.
1538  * @param a is an array having exactly the same number of components than 'this'
1539  */
1540 void DataArrayDouble::setContigPartOfSelectedValues2(int tupleIdStart, const DataArrayDouble *a, int bg, int end2, int step) throw(INTERP_KERNEL::Exception)
1541 {
1542   if(!a)
1543     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues2 : input DataArrayDouble is NULL !");
1544   checkAllocated();
1545   a->checkAllocated();
1546   int nbOfComp=getNumberOfComponents();
1547   const char msg[]="DataArrayDouble::setContigPartOfSelectedValues2";
1548   int nbOfTupleToWrite=DataArray::GetNumberOfItemGivenBES(bg,end2,step,msg);
1549   if(nbOfComp!=a->getNumberOfComponents())
1550     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues2 : This and a do not have the same number of components !");
1551   int thisNt=getNumberOfTuples();
1552   int aNt=a->getNumberOfTuples();
1553   double *valsToSet=getPointer()+tupleIdStart*nbOfComp;
1554   if(tupleIdStart+nbOfTupleToWrite>thisNt)
1555     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues2 : invalid number range of values to write !");
1556   if(end2>aNt)
1557     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues2 : invalid range of values to read !");
1558   const double *valsSrc=a->getConstPointer()+bg*nbOfComp;
1559   for(int i=0;i<nbOfTupleToWrite;i++,valsToSet+=nbOfComp,valsSrc+=step*nbOfComp)
1560     {
1561       std::copy(valsSrc,valsSrc+nbOfComp,valsToSet);
1562     }
1563 }
1564
1565 /*!
1566  * This method is equivalent to DataArrayDouble::getIJ except that here \b tupleId is checked to be in [0,this->getNumberOfTuples()) and compoId to be in [0,this->getNumberOfComponents()).
1567  * If one of these check fails an INTERP_KERNEL::Exception will be thrown.
1568  * So this method is safe but expensive if used to go through all data of \b this.
1569  */
1570 double DataArrayDouble::getIJSafe(int tupleId, int compoId) const throw(INTERP_KERNEL::Exception)
1571 {
1572   checkAllocated();
1573   if(tupleId<0 || tupleId>=getNumberOfTuples())
1574     {
1575       std::ostringstream oss; oss << "DataArrayDouble::getIJSafe : request for tupleId " << tupleId << " should be in [0," << getNumberOfTuples() << ") !";
1576       throw INTERP_KERNEL::Exception(oss.str().c_str());
1577     }
1578   if(compoId<0 || compoId>=getNumberOfComponents())
1579     {
1580       std::ostringstream oss; oss << "DataArrayDouble::getIJSafe : request for compoId " << compoId << " should be in [0," << getNumberOfComponents() << ") !";
1581       throw INTERP_KERNEL::Exception(oss.str().c_str());
1582     }
1583   return _mem[tupleId*((int)_info_on_compo.size())+compoId];
1584 }
1585
1586 /*!
1587  * This method returns the last element in 'this'. So this method makes the hypothesis that 'this' is allocated.
1588  * This method works only for arrays that have exactly number of components equal to 1. If not an exception is thrown.
1589  * And to finish this method works for arrays that have number of tuples >= 1.
1590  */
1591 double DataArrayDouble::back() const throw(INTERP_KERNEL::Exception)
1592 {
1593   checkAllocated();
1594   if(getNumberOfComponents()!=1)
1595     throw INTERP_KERNEL::Exception("DataArrayDouble::back : number of components not equal to one !");
1596   int nbOfTuples=getNumberOfTuples();
1597   if(nbOfTuples<1)
1598     throw INTERP_KERNEL::Exception("DataArrayDouble::back : number of tuples must be >= 1 !");
1599   return *(getConstPointer()+nbOfTuples-1);
1600 }
1601
1602 void DataArrayDouble::SetArrayIn(DataArrayDouble *newArray, DataArrayDouble* &arrayToSet)
1603 {
1604   if(newArray!=arrayToSet)
1605     {
1606       if(arrayToSet)
1607         arrayToSet->decrRef();
1608       arrayToSet=newArray;
1609       if(arrayToSet)
1610         arrayToSet->incrRef();
1611     }
1612 }
1613
1614 void DataArrayDouble::useArray(const double *array, bool ownership,  DeallocType type, int nbOfTuple, int nbOfCompo)
1615 {
1616   _nb_of_tuples=nbOfTuple;
1617   _info_on_compo.resize(nbOfCompo);
1618   _mem.useArray(array,ownership,type,nbOfTuple*nbOfCompo);
1619   declareAsNew();
1620 }
1621
1622 void DataArrayDouble::checkNoNullValues() const throw(INTERP_KERNEL::Exception)
1623 {
1624   const double *tmp=getConstPointer();
1625   int nbOfElems=getNbOfElems();
1626   const double *where=std::find(tmp,tmp+nbOfElems,0.);
1627   if(where!=tmp+nbOfElems)
1628     throw INTERP_KERNEL::Exception("A value 0.0 have been detected !");
1629 }
1630
1631 /*!
1632  * This method assume that \b this is allocated. If not an INTERP_KERNEL::Exception will be thrown.
1633  * This method fills \b bounds params like that : \b bounds[0]=XMin, \b bounds[1]=XMax, \b bounds[2]=YMin, \b bounds[3]=YMax...
1634  * Where X refers to component #0, and Y to component #1...
1635  * This method set 2*this->getNumberOfComponents() elements in \b bounds, so it is up to the caller to allocated enough space before calling this method.
1636  *
1637  * @param [out] bounds array of size 2*this->getNumberOfComponents().
1638  */
1639 void DataArrayDouble::getMinMaxPerComponent(double *bounds) const throw(INTERP_KERNEL::Exception)
1640 {
1641   checkAllocated();
1642   int dim=getNumberOfComponents();
1643   for (int idim=0; idim<dim; idim++)
1644     {
1645       bounds[idim*2]=std::numeric_limits<double>::max();
1646       bounds[idim*2+1]=-std::numeric_limits<double>::max();
1647     } 
1648   const double *ptr=getConstPointer();
1649   int nbOfTuples=getNumberOfTuples();
1650   for(int i=0;i<nbOfTuples;i++)
1651     {
1652       for(int idim=0;idim<dim;idim++)
1653         {
1654           if(bounds[idim*2]>ptr[i*dim+idim])
1655             {
1656               bounds[idim*2]=ptr[i*dim+idim];
1657             }
1658           if(bounds[idim*2+1]<ptr[i*dim+idim])
1659             {
1660               bounds[idim*2+1]=ptr[i*dim+idim];
1661             }
1662         }
1663     }
1664 }
1665
1666 /*!
1667  * This method retrieves a newly allocated DataArrayDouble instance having same number of tuples than \a this and twice number of components than \a this
1668  * to store both the min and max per component of each tuples. 
1669  * \param [in] epsilon the width of the bbox (identical in each direction) - 0.0 by default
1670  *
1671  * \return a newly created DataArrayDouble instance having \c this->getNumberOfTuples() tuples and 2 * \c this->getNumberOfComponent() components
1672  *
1673  * \throw If \a this is not allocated yet.
1674  */
1675 DataArrayDouble *DataArrayDouble::computeBBoxPerTuple(double epsilon)const throw(INTERP_KERNEL::Exception)
1676 {
1677   checkAllocated();
1678   const double *dataPtr=getConstPointer();
1679   int nbOfCompo=getNumberOfComponents();
1680   int nbTuples=getNumberOfTuples();
1681   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> bbox=DataArrayDouble::New();
1682   bbox->alloc(nbTuples,2*nbOfCompo);
1683   double *bboxPtr=bbox->getPointer();
1684   for(int i=0;i<nbTuples;i++)
1685     {
1686       for(int j=0;j<nbOfCompo;j++)
1687         {
1688           bboxPtr[2*nbOfCompo*i+2*j]=dataPtr[nbOfCompo*i+j]-epsilon;
1689           bboxPtr[2*nbOfCompo*i+2*j+1]=dataPtr[nbOfCompo*i+j]+epsilon;
1690         }
1691     }
1692   bbox->incrRef();
1693   return bbox;
1694 }
1695
1696 /*!
1697  * For each tuples **t** in \a other, this method retrieves tuples in \a this that are equal to **t**.
1698  * Two tuples are considered equal if the euclidian distance between the two tuples is lower than \a eps.
1699  * 
1700  * \param [in] other a DataArrayDouble having same number of components than \a this.
1701  * \param [in] eps absolute precision representing euclidian distance between 2 tuples behind which 2 tuples are considered equal.
1702  * \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.
1703  *             \a cI allows to extract information in \a c.
1704  * \param [out] cI is an indirection array that allows to extract the data contained in \a c.
1705  *
1706  * \throw In case of:
1707  *  - \a this is not allocated
1708  *  - \a other is not allocated or null
1709  *  - \a this and \a other do not have the same number of components
1710  *  - if number of components of \a this is not in [1,2,3]
1711  *
1712  * \sa MEDCouplingPointSet::getNodeIdsNearPoints, DataArrayDouble::getDifferentValues
1713  */
1714 void DataArrayDouble::computeTupleIdsNearTuples(const DataArrayDouble *other, double eps, std::vector<int>& c, std::vector<int>& cI) const throw(INTERP_KERNEL::Exception)
1715 {
1716   if(!other)
1717     throw INTERP_KERNEL::Exception("DataArrayDouble::computeTupleIdsNearTuples : input pointer other is null !");
1718   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> bbox=computeBBoxPerTuple(eps);
1719   other->checkAllocated();
1720   int nbOfCompo=getNumberOfComponents();
1721   int otherNbOfCompo=other->getNumberOfComponents();
1722   if(nbOfCompo!=otherNbOfCompo)
1723     throw INTERP_KERNEL::Exception("DataArrayDouble::computeTupleIdsNearTuples : number of components should be equal between this and other !");
1724   int nbOfTuplesOther=other->getNumberOfTuples();
1725   std::vector<int> ret;
1726   c.clear();
1727   cI.resize(1); cI[0]=0;
1728   switch(nbOfCompo)
1729     {
1730     case 3:
1731       {
1732         BBTree<3,int> myTree(bbox->getConstPointer(),0,0,getNumberOfTuples(),eps/10);
1733         findTupleIdsNearTuplesAlg<3>(myTree,other->getConstPointer(),nbOfTuplesOther,eps,c,cI);
1734         break;
1735       }
1736     case 2:
1737       {
1738         BBTree<2,int> myTree(bbox->getConstPointer(),0,0,getNumberOfTuples(),eps/10);
1739         findTupleIdsNearTuplesAlg<2>(myTree,other->getConstPointer(),nbOfTuplesOther,eps,c,cI);
1740         break;
1741       }
1742     case 1:
1743       {
1744         BBTree<1,int> myTree(bbox->getConstPointer(),0,0,getNumberOfTuples(),eps/10);
1745         findTupleIdsNearTuplesAlg<1>(myTree,other->getConstPointer(),nbOfTuplesOther,eps,c,cI);
1746         break;
1747       }
1748     default:
1749       throw INTERP_KERNEL::Exception("Unexpected spacedim of coords for computeTupleIdsNearTuples. Must be 1, 2 or 3.");
1750     }
1751 }
1752
1753 /*!
1754  * 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
1755  * around origin of 'radius' 1.
1756  * 
1757  * \param [in] eps absolute epsilon. under that value of delta between max and min no scale is performed.
1758  */
1759 void DataArrayDouble::recenterForMaxPrecision(double eps) throw(INTERP_KERNEL::Exception)
1760 {
1761   checkAllocated();
1762   int dim=getNumberOfComponents();
1763   std::vector<double> bounds(2*dim);
1764   getMinMaxPerComponent(&bounds[0]);
1765   for(int i=0;i<dim;i++)
1766     {
1767       double delta=bounds[2*i+1]-bounds[2*i];
1768       double offset=(bounds[2*i]+bounds[2*i+1])/2.;
1769       if(delta>eps)
1770         applyLin(1./delta,-offset/delta,i);
1771       else
1772         applyLin(1.,-offset,i);
1773     }
1774 }
1775
1776 double DataArrayDouble::getMaxValue(int& tupleId) const throw(INTERP_KERNEL::Exception)
1777 {
1778   if(getNumberOfComponents()!=1)
1779     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 !");
1780   int nbOfTuples=getNumberOfTuples();
1781   if(nbOfTuples<=0)
1782     throw INTERP_KERNEL::Exception("DataArrayDouble::getMaxValue : array exists but number of tuples must be > 0 !");
1783   const double *vals=getConstPointer();
1784   const double *loc=std::max_element(vals,vals+nbOfTuples);
1785   tupleId=(int)std::distance(vals,loc);
1786   return *loc;
1787 }
1788
1789 /*!
1790  * Idem to DataArrayDouble::getMaxValue expect that here number of components can be >=1.
1791  */
1792 double DataArrayDouble::getMaxValueInArray() const throw(INTERP_KERNEL::Exception)
1793 {
1794   checkAllocated();
1795   const double *loc=std::max_element(begin(),end());
1796   return *loc;
1797 }
1798
1799 double DataArrayDouble::getMaxValue2(DataArrayInt*& tupleIds) const throw(INTERP_KERNEL::Exception)
1800 {
1801   int tmp;
1802   tupleIds=0;
1803   double ret=getMaxValue(tmp);
1804   tupleIds=getIdsInRange(ret,ret);
1805   return ret;
1806 }
1807
1808 double DataArrayDouble::getMinValue(int& tupleId) const throw(INTERP_KERNEL::Exception)
1809 {
1810   if(getNumberOfComponents()!=1)
1811     throw INTERP_KERNEL::Exception("DataArrayDouble::getMinValue : must be applied on DataArrayDouble with only one component, you can call 'rearrange' method before call 'getMinValueInArray' method !");
1812   int nbOfTuples=getNumberOfTuples();
1813   if(nbOfTuples<=0)
1814     throw INTERP_KERNEL::Exception("DataArrayDouble::getMinValue : array exists but number of tuples must be > 0 !");
1815   const double *vals=getConstPointer();
1816   const double *loc=std::min_element(vals,vals+nbOfTuples);
1817   tupleId=(int)std::distance(vals,loc);
1818   return *loc;
1819 }
1820
1821 /*!
1822  * Idem to DataArrayDouble::getMinValue expect that here number of components can be >=1.
1823  */
1824 double DataArrayDouble::getMinValueInArray() const throw(INTERP_KERNEL::Exception)
1825 {
1826   checkAllocated();
1827   const double *loc=std::min_element(begin(),end());
1828   return *loc;
1829 }
1830
1831 double DataArrayDouble::getMinValue2(DataArrayInt*& tupleIds) const throw(INTERP_KERNEL::Exception)
1832 {
1833   int tmp;
1834   tupleIds=0;
1835   double ret=getMinValue(tmp);
1836   tupleIds=getIdsInRange(ret,ret);
1837   return ret;
1838 }
1839
1840 double DataArrayDouble::getAverageValue() const throw(INTERP_KERNEL::Exception)
1841 {
1842   if(getNumberOfComponents()!=1)
1843     throw INTERP_KERNEL::Exception("DataArrayDouble::getAverageValue : must be applied on DataArrayDouble with only one component, you can call 'rearrange' method before !");
1844   int nbOfTuples=getNumberOfTuples();
1845   if(nbOfTuples<=0)
1846     throw INTERP_KERNEL::Exception("DataArrayDouble::getAverageValue : array exists but number of tuples must be > 0 !");
1847   const double *vals=getConstPointer();
1848   double ret=std::accumulate(vals,vals+nbOfTuples,0.);
1849   return ret/nbOfTuples;
1850 }
1851
1852 double DataArrayDouble::norm2() const throw(INTERP_KERNEL::Exception)
1853 {
1854   checkAllocated();
1855   double ret=0.;
1856   int nbOfElems=getNbOfElems();
1857   const double *pt=getConstPointer();
1858   for(int i=0;i<nbOfElems;i++,pt++)
1859     ret+=(*pt)*(*pt);
1860   return sqrt(ret);
1861 }
1862
1863 double DataArrayDouble::normMax() const throw(INTERP_KERNEL::Exception)
1864 {
1865   checkAllocated();
1866   double ret=-1.;
1867   int nbOfElems=getNbOfElems();
1868   const double *pt=getConstPointer();
1869   for(int i=0;i<nbOfElems;i++,pt++)
1870     {
1871       double val=std::abs(*pt);
1872       if(val>ret)
1873         ret=val;
1874     }
1875   return ret;
1876 }
1877
1878 void DataArrayDouble::accumulate(double *res) const throw(INTERP_KERNEL::Exception)
1879 {
1880   checkAllocated();
1881   const double *ptr=getConstPointer();
1882   int nbTuple=getNumberOfTuples();
1883   int nbComps=getNumberOfComponents();
1884   std::fill(res,res+nbComps,0.);
1885   for(int i=0;i<nbTuple;i++)
1886     std::transform(ptr+i*nbComps,ptr+(i+1)*nbComps,res,res,std::plus<double>());
1887 }
1888
1889 double DataArrayDouble::accumulate(int compId) const throw(INTERP_KERNEL::Exception)
1890 {
1891   checkAllocated();
1892   const double *ptr=getConstPointer();
1893   int nbTuple=getNumberOfTuples();
1894   int nbComps=getNumberOfComponents();
1895   if(compId>=nbComps)
1896     throw INTERP_KERNEL::Exception("DataArrayDouble::accumulate : Invalid compId specified : No such nb of components !");
1897   double ret=0.;
1898   for(int i=0;i<nbTuple;i++)
1899     ret+=ptr[i*nbComps+compId];
1900   return ret;
1901 }
1902
1903 DataArrayDouble *DataArrayDouble::fromPolarToCart() const throw(INTERP_KERNEL::Exception)
1904 {
1905   int nbOfComp=getNumberOfComponents();
1906   if(nbOfComp!=2)
1907     throw INTERP_KERNEL::Exception("DataArrayDouble::fromPolarToCart : must be an array with exactly 2 components !");
1908   int nbOfTuple=getNumberOfTuples();
1909   DataArrayDouble *ret=DataArrayDouble::New();
1910   ret->alloc(nbOfTuple,2);
1911   double *w=ret->getPointer();
1912   const double *wIn=getConstPointer();
1913   for(int i=0;i<nbOfTuple;i++,w+=2,wIn+=2)
1914     {
1915       w[0]=wIn[0]*cos(wIn[1]);
1916       w[1]=wIn[0]*sin(wIn[1]);
1917     }
1918   return ret;
1919 }
1920
1921 DataArrayDouble *DataArrayDouble::fromCylToCart() const throw(INTERP_KERNEL::Exception)
1922 {
1923   int nbOfComp=getNumberOfComponents();
1924   if(nbOfComp!=3)
1925     throw INTERP_KERNEL::Exception("DataArrayDouble::fromCylToCart : must be an array with exactly 3 components !");
1926   int nbOfTuple=getNumberOfTuples();
1927   DataArrayDouble *ret=DataArrayDouble::New();
1928   ret->alloc(getNumberOfTuples(),3);
1929   double *w=ret->getPointer();
1930   const double *wIn=getConstPointer();
1931   for(int i=0;i<nbOfTuple;i++,w+=3,wIn+=3)
1932     {
1933       w[0]=wIn[0]*cos(wIn[1]);
1934       w[1]=wIn[0]*sin(wIn[1]);
1935       w[2]=wIn[2];
1936     }
1937   ret->setInfoOnComponent(2,getInfoOnComponent(2).c_str());
1938   return ret;
1939 }
1940
1941 DataArrayDouble *DataArrayDouble::fromSpherToCart() const throw(INTERP_KERNEL::Exception)
1942 {
1943   int nbOfComp=getNumberOfComponents();
1944   if(nbOfComp!=3)
1945     throw INTERP_KERNEL::Exception("DataArrayDouble::fromSpherToCart : must be an array with exactly 3 components !");
1946   int nbOfTuple=getNumberOfTuples();
1947   DataArrayDouble *ret=DataArrayDouble::New();
1948   ret->alloc(getNumberOfTuples(),3);
1949   double *w=ret->getPointer();
1950   const double *wIn=getConstPointer();
1951   for(int i=0;i<nbOfTuple;i++,w+=3,wIn+=3)
1952     {
1953       w[0]=wIn[0]*cos(wIn[2])*sin(wIn[1]);
1954       w[1]=wIn[0]*sin(wIn[2])*sin(wIn[1]);
1955       w[2]=wIn[0]*cos(wIn[1]);
1956     }
1957   return ret;
1958 }
1959
1960 DataArrayDouble *DataArrayDouble::doublyContractedProduct() const throw(INTERP_KERNEL::Exception)
1961 {
1962   int nbOfComp=getNumberOfComponents();
1963   if(nbOfComp!=6)
1964     throw INTERP_KERNEL::Exception("DataArrayDouble::doublyContractedProduct : must be an array with exactly 6 components !");
1965   DataArrayDouble *ret=DataArrayDouble::New();
1966   int nbOfTuple=getNumberOfTuples();
1967   ret->alloc(nbOfTuple,1);
1968   const double *src=getConstPointer();
1969   double *dest=ret->getPointer();
1970   for(int i=0;i<nbOfTuple;i++,dest++,src+=6)
1971     *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];
1972   return ret;
1973 }
1974
1975 DataArrayDouble *DataArrayDouble::determinant() const throw(INTERP_KERNEL::Exception)
1976 {
1977   checkAllocated();
1978   DataArrayDouble *ret=DataArrayDouble::New();
1979   int nbOfTuple=getNumberOfTuples();
1980   ret->alloc(nbOfTuple,1);
1981   const double *src=getConstPointer();
1982   double *dest=ret->getPointer();
1983   switch(getNumberOfComponents())
1984     {
1985     case 6:
1986       for(int i=0;i<nbOfTuple;i++,dest++,src+=6)
1987         *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];
1988       return ret;
1989     case 4:
1990       for(int i=0;i<nbOfTuple;i++,dest++,src+=4)
1991         *dest=src[0]*src[3]-src[1]*src[2];
1992       return ret;
1993     case 9:
1994       for(int i=0;i<nbOfTuple;i++,dest++,src+=9)
1995         *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];
1996       return ret;
1997     default:
1998       ret->decrRef();
1999       throw INTERP_KERNEL::Exception("DataArrayDouble::determinant : Invalid number of components ! must be in 4,6,9 !");
2000     }
2001 }
2002
2003 DataArrayDouble *DataArrayDouble::eigenValues() const throw(INTERP_KERNEL::Exception)
2004 {
2005   int nbOfComp=getNumberOfComponents();
2006   if(nbOfComp!=6)
2007     throw INTERP_KERNEL::Exception("DataArrayDouble::eigenValues : must be an array with exactly 6 components !");
2008   DataArrayDouble *ret=DataArrayDouble::New();
2009   int nbOfTuple=getNumberOfTuples();
2010   ret->alloc(nbOfTuple,3);
2011   const double *src=getConstPointer();
2012   double *dest=ret->getPointer();
2013   for(int i=0;i<nbOfTuple;i++,dest+=3,src+=6)
2014     INTERP_KERNEL::computeEigenValues6(src,dest);
2015   return ret;
2016 }
2017
2018 DataArrayDouble *DataArrayDouble::eigenVectors() const throw(INTERP_KERNEL::Exception)
2019 {
2020   int nbOfComp=getNumberOfComponents();
2021   if(nbOfComp!=6)
2022     throw INTERP_KERNEL::Exception("DataArrayDouble::eigenVectors : must be an array with exactly 6 components !");
2023   DataArrayDouble *ret=DataArrayDouble::New();
2024   int nbOfTuple=getNumberOfTuples();
2025   ret->alloc(nbOfTuple,9);
2026   const double *src=getConstPointer();
2027   double *dest=ret->getPointer();
2028   for(int i=0;i<nbOfTuple;i++,src+=6)
2029     {
2030       double tmp[3];
2031       INTERP_KERNEL::computeEigenValues6(src,tmp);
2032       for(int j=0;j<3;j++,dest+=3)
2033         INTERP_KERNEL::computeEigenVectorForEigenValue6(src,tmp[j],1e-12,dest);
2034     }
2035   return ret;
2036 }
2037
2038 DataArrayDouble *DataArrayDouble::inverse() const throw(INTERP_KERNEL::Exception)
2039 {
2040   int nbOfComp=getNumberOfComponents();
2041   if(nbOfComp!=6 && nbOfComp!=9 && nbOfComp!=4)
2042     throw INTERP_KERNEL::Exception("DataArrayDouble::inversion : must be an array with 4,6 or 9 components !");
2043   DataArrayDouble *ret=DataArrayDouble::New();
2044   int nbOfTuple=getNumberOfTuples();
2045   ret->alloc(nbOfTuple,nbOfComp);
2046   const double *src=getConstPointer();
2047   double *dest=ret->getPointer();
2048 if(nbOfComp==6)
2049     for(int i=0;i<nbOfTuple;i++,dest+=6,src+=6)
2050       {
2051         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];
2052         dest[0]=(src[1]*src[2]-src[4]*src[4])/det;
2053         dest[1]=(src[0]*src[2]-src[5]*src[5])/det;
2054         dest[2]=(src[0]*src[1]-src[3]*src[3])/det;
2055         dest[3]=(src[5]*src[4]-src[3]*src[2])/det;
2056         dest[4]=(src[5]*src[3]-src[0]*src[4])/det;
2057         dest[5]=(src[3]*src[4]-src[1]*src[5])/det;
2058       }
2059   else if(nbOfComp==4)
2060     for(int i=0;i<nbOfTuple;i++,dest+=4,src+=4)
2061       {
2062         double det=src[0]*src[3]-src[1]*src[2];
2063         dest[0]=src[3]/det;
2064         dest[1]=-src[1]/det;
2065         dest[2]=-src[2]/det;
2066         dest[3]=src[0]/det;
2067       }
2068   else
2069     for(int i=0;i<nbOfTuple;i++,dest+=9,src+=9)
2070       {
2071         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];
2072         dest[0]=(src[4]*src[8]-src[7]*src[5])/det;
2073         dest[1]=(src[7]*src[2]-src[1]*src[8])/det;
2074         dest[2]=(src[1]*src[5]-src[4]*src[2])/det;
2075         dest[3]=(src[6]*src[5]-src[3]*src[8])/det;
2076         dest[4]=(src[0]*src[8]-src[6]*src[2])/det;
2077         dest[5]=(src[2]*src[3]-src[0]*src[5])/det;
2078         dest[6]=(src[3]*src[7]-src[6]*src[4])/det;
2079         dest[7]=(src[6]*src[1]-src[0]*src[7])/det;
2080         dest[8]=(src[0]*src[4]-src[1]*src[3])/det;
2081       }
2082   return ret;
2083 }
2084
2085 DataArrayDouble *DataArrayDouble::trace() const throw(INTERP_KERNEL::Exception)
2086 {
2087   int nbOfComp=getNumberOfComponents();
2088   if(nbOfComp!=6 && nbOfComp!=9 && nbOfComp!=4)
2089     throw INTERP_KERNEL::Exception("DataArrayDouble::trace : must be an array with 4,6 or 9 components !");
2090   DataArrayDouble *ret=DataArrayDouble::New();
2091   int nbOfTuple=getNumberOfTuples();
2092   ret->alloc(nbOfTuple,1);
2093   const double *src=getConstPointer();
2094   double *dest=ret->getPointer();
2095   if(nbOfComp==6)
2096     for(int i=0;i<nbOfTuple;i++,dest++,src+=6)
2097       *dest=src[0]+src[1]+src[2];
2098   else if(nbOfComp==4)
2099     for(int i=0;i<nbOfTuple;i++,dest++,src+=4)
2100       *dest=src[0]+src[3];
2101   else
2102     for(int i=0;i<nbOfTuple;i++,dest++,src+=9)
2103       *dest=src[0]+src[4]+src[8];
2104   return ret;
2105 }
2106
2107 DataArrayDouble *DataArrayDouble::deviator() const throw(INTERP_KERNEL::Exception)
2108 {
2109   int nbOfComp=getNumberOfComponents();
2110   if(nbOfComp!=6)
2111     throw INTERP_KERNEL::Exception("DataArrayDouble::deviator : must be an array with exactly 6 components !");
2112   DataArrayDouble *ret=DataArrayDouble::New();
2113   int nbOfTuple=getNumberOfTuples();
2114   ret->alloc(nbOfTuple,6);
2115   const double *src=getConstPointer();
2116   double *dest=ret->getPointer();
2117   for(int i=0;i<nbOfTuple;i++,dest+=6,src+=6)
2118     {
2119       double tr=(src[0]+src[1]+src[2])/3.;
2120       dest[0]=src[0]-tr;
2121       dest[1]=src[1]-tr;
2122       dest[2]=src[2]-tr;
2123       dest[3]=src[3];
2124       dest[4]=src[4];
2125       dest[5]=src[5];
2126     }
2127   return ret;
2128 }
2129
2130 DataArrayDouble *DataArrayDouble::magnitude() const throw(INTERP_KERNEL::Exception)
2131 {
2132   checkAllocated();
2133   int nbOfComp=getNumberOfComponents();
2134   DataArrayDouble *ret=DataArrayDouble::New();
2135   int nbOfTuple=getNumberOfTuples();
2136   ret->alloc(nbOfTuple,1);
2137   const double *src=getConstPointer();
2138   double *dest=ret->getPointer();
2139   for(int i=0;i<nbOfTuple;i++,dest++)
2140     {
2141       double sum=0.;
2142       for(int j=0;j<nbOfComp;j++,src++)
2143         sum+=(*src)*(*src);
2144       *dest=sqrt(sum);
2145     }
2146   return ret;
2147 }
2148
2149 DataArrayDouble *DataArrayDouble::maxPerTuple() const throw(INTERP_KERNEL::Exception)
2150 {
2151   checkAllocated();
2152   int nbOfComp=getNumberOfComponents();
2153   DataArrayDouble *ret=DataArrayDouble::New();
2154   int nbOfTuple=getNumberOfTuples();
2155   ret->alloc(nbOfTuple,1);
2156   const double *src=getConstPointer();
2157   double *dest=ret->getPointer();
2158   for(int i=0;i<nbOfTuple;i++,dest++,src+=nbOfComp)
2159     *dest=*std::max_element(src,src+nbOfComp);
2160   return ret;
2161 }
2162
2163 /*!
2164  * This method returns a newly allocated DataArrayDouble instance having one component and \c this->getNumberOfTuples() * \c this->getNumberOfTuples() tuples.
2165  * \n This returned array contains the euclidian distance for each tuple in \a this. 
2166  * \n So the returned array can be seen as a dense symmetrical matrix whose diagonal elements are equal to 0.
2167  * \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)
2168  *
2169  * \warning use this method with care because it can leads to big amount of consumed memory !
2170  * 
2171  * \return A newly allocated (huge) ParaMEDMEM::DataArrayDouble instance that the caller should deal with.
2172  *
2173  * \throw If \a this is not allocated.
2174  *
2175  * \sa DataArrayDouble::buildEuclidianDistanceDenseMatrixWith
2176  */
2177 DataArrayDouble *DataArrayDouble::buildEuclidianDistanceDenseMatrix() const throw(INTERP_KERNEL::Exception)
2178 {
2179   checkAllocated();
2180   int nbOfComp=getNumberOfComponents();
2181   int nbOfTuples=getNumberOfTuples();
2182   const double *inData=getConstPointer();
2183   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
2184   ret->alloc(nbOfTuples*nbOfTuples,1);
2185   double *outData=ret->getPointer();
2186   for(int i=0;i<nbOfTuples;i++)
2187     {
2188       outData[i*nbOfTuples+i]=0.;
2189       for(int j=i+1;j<nbOfTuples;j++)
2190         {
2191           double dist=0.;
2192           for(int k=0;k<nbOfComp;k++)
2193             { double delta=inData[i*nbOfComp+k]-inData[j*nbOfComp+k]; dist+=delta*delta; }
2194           dist=sqrt(dist);
2195           outData[i*nbOfTuples+j]=dist;
2196           outData[j*nbOfTuples+i]=dist;
2197         }
2198     }
2199   ret->incrRef();
2200   return ret;
2201 }
2202
2203 /*!
2204  * This method returns a newly allocated DataArrayDouble instance having one component and \c this->getNumberOfTuples() * \c other->getNumberOfTuples() tuples.
2205  * \n This returned array contains the euclidian distance for each tuple in \a other with each tuple in \a this. 
2206  * \n So the returned array can be seen as a dense rectangular matrix with \c other->getNumberOfTuples() rows and \c this->getNumberOfTuples() columns.
2207  * \n Output rectangular matrix is sorted along rows.
2208  * \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)
2209  *
2210  * \warning use this method with care because it can leads to big amount of consumed memory !
2211  * 
2212  * \param [in] other DataArrayDouble instance having same number of components than \a this.
2213  * \return A newly allocated (huge) ParaMEDMEM::DataArrayDouble instance that the caller should deal with.
2214  *
2215  * \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.
2216  *
2217  * \sa DataArrayDouble::buildEuclidianDistanceDenseMatrix
2218  */
2219 DataArrayDouble *DataArrayDouble::buildEuclidianDistanceDenseMatrixWith(const DataArrayDouble *other) const throw(INTERP_KERNEL::Exception)
2220 {
2221   if(!other)
2222     throw INTERP_KERNEL::Exception("DataArrayDouble::buildEuclidianDistanceDenseMatrixWith : input parameter is null !");
2223   checkAllocated();
2224   other->checkAllocated();
2225   int nbOfComp=getNumberOfComponents();
2226   int otherNbOfComp=other->getNumberOfComponents();
2227   if(nbOfComp!=otherNbOfComp)
2228     {
2229       std::ostringstream oss; oss << "DataArrayDouble::buildEuclidianDistanceDenseMatrixWith : this nb of compo=" << nbOfComp << " and other nb of compo=" << otherNbOfComp << ". It should match !";
2230       throw INTERP_KERNEL::Exception(oss.str().c_str());
2231     }
2232   int nbOfTuples=getNumberOfTuples();
2233   int otherNbOfTuples=other->getNumberOfTuples();
2234   const double *inData=getConstPointer();
2235   const double *inDataOther=other->getConstPointer();
2236   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
2237   ret->alloc(otherNbOfTuples*nbOfTuples,1);
2238   double *outData=ret->getPointer();
2239   for(int i=0;i<otherNbOfTuples;i++,inDataOther+=nbOfComp)
2240     {
2241       for(int j=0;j<nbOfTuples;j++)
2242         {
2243           double dist=0.;
2244           for(int k=0;k<nbOfComp;k++)
2245             { double delta=inDataOther[k]-inData[j*nbOfComp+k]; dist+=delta*delta; }
2246           dist=sqrt(dist);
2247           outData[i*nbOfTuples+j]=dist;
2248         }
2249     }
2250   ret->incrRef();
2251   return ret;
2252 }
2253
2254 void DataArrayDouble::sortPerTuple(bool asc) throw(INTERP_KERNEL::Exception)
2255 {
2256   checkAllocated();
2257   double *pt=getPointer();
2258   int nbOfTuple=getNumberOfTuples();
2259   int nbOfComp=getNumberOfComponents();
2260   if(asc)
2261     for(int i=0;i<nbOfTuple;i++,pt+=nbOfComp)
2262       std::sort(pt,pt+nbOfComp);
2263   else
2264     for(int i=0;i<nbOfTuple;i++,pt+=nbOfComp)
2265       std::sort(pt,pt+nbOfComp,std::greater<double>());
2266   declareAsNew();
2267 }
2268
2269 void DataArrayDouble::abs() throw(INTERP_KERNEL::Exception)
2270 {
2271   checkAllocated();
2272   double *ptr=getPointer();
2273   int nbOfElems=getNbOfElems();
2274   std::transform(ptr,ptr+nbOfElems,ptr,std::ptr_fun<double,double>(fabs));
2275 }
2276
2277 void DataArrayDouble::applyLin(double a, double b, int compoId) throw(INTERP_KERNEL::Exception)
2278 {
2279   checkAllocated();
2280   double *ptr=getPointer()+compoId;
2281   int nbOfComp=getNumberOfComponents();
2282   int nbOfTuple=getNumberOfTuples();
2283   for(int i=0;i<nbOfTuple;i++,ptr+=nbOfComp)
2284     *ptr=a*(*ptr)+b;
2285   declareAsNew();
2286 }
2287
2288 void DataArrayDouble::applyLin(double a, double b) throw(INTERP_KERNEL::Exception)
2289 {
2290   checkAllocated();
2291   double *ptr=getPointer();
2292   int nbOfElems=getNbOfElems();
2293   for(int i=0;i<nbOfElems;i++,ptr++)
2294     *ptr=a*(*ptr)+b;
2295   declareAsNew();
2296 }
2297
2298 /*!
2299  * This method applies the operation 'numerator/x' for each element 'x' in 'this'.
2300  * If there is a value in 'this' exactly equal to 0. an exception is thrown.
2301  * Warning if presence of null this is modified for each values previous than place where exception was thrown !
2302  */
2303 void DataArrayDouble::applyInv(double numerator) throw(INTERP_KERNEL::Exception)
2304 {
2305   checkAllocated();
2306   double *ptr=getPointer();
2307   int nbOfElems=getNbOfElems();
2308   for(int i=0;i<nbOfElems;i++,ptr++)
2309     {
2310       if(std::abs(*ptr)>std::numeric_limits<double>::min())
2311         {
2312           *ptr=numerator/(*ptr);
2313         }
2314       else
2315         {
2316           std::ostringstream oss; oss << "DataArrayDouble::applyInv : presence of null value in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
2317           oss << " !";
2318           throw INTERP_KERNEL::Exception(oss.str().c_str());
2319         }
2320     }
2321   declareAsNew();
2322 }
2323
2324 /*!
2325  * This method returns a newly allocated array containing the application of negate on \b this.
2326  * This method throws an INTERP_KERNEL::Exception if \b this is not allocated.
2327  */
2328 DataArrayDouble *DataArrayDouble::negate() const throw(INTERP_KERNEL::Exception)
2329 {
2330   checkAllocated();
2331   DataArrayDouble *newArr=DataArrayDouble::New();
2332   int nbOfTuples=getNumberOfTuples();
2333   int nbOfComp=getNumberOfComponents();
2334   newArr->alloc(nbOfTuples,nbOfComp);
2335   const double *cptr=getConstPointer();
2336   std::transform(cptr,cptr+nbOfTuples*nbOfComp,newArr->getPointer(),std::negate<double>());
2337   newArr->copyStringInfoFrom(*this);
2338   return newArr;
2339 }
2340
2341 DataArrayDouble *DataArrayDouble::applyFunc(int nbOfComp, FunctionToEvaluate func) const throw(INTERP_KERNEL::Exception)
2342 {
2343   checkAllocated();
2344   DataArrayDouble *newArr=DataArrayDouble::New();
2345   int nbOfTuples=getNumberOfTuples();
2346   int oldNbOfComp=getNumberOfComponents();
2347   newArr->alloc(nbOfTuples,nbOfComp);
2348   const double *ptr=getConstPointer();
2349   double *ptrToFill=newArr->getPointer();
2350   for(int i=0;i<nbOfTuples;i++)
2351     {
2352       if(!func(ptr+i*oldNbOfComp,ptrToFill+i*nbOfComp))
2353         {
2354           std::ostringstream oss; oss << "For tuple # " << i << " with value (";
2355           std::copy(ptr+oldNbOfComp*i,ptr+oldNbOfComp*(i+1),std::ostream_iterator<double>(oss,", "));
2356           oss << ") : Evaluation of function failed !";
2357           newArr->decrRef();
2358           throw INTERP_KERNEL::Exception(oss.str().c_str());
2359         }
2360     }
2361   return newArr;
2362 }
2363
2364 /*!
2365  * This method returns a newly allocated array the caller should deal with.
2366  * The returned array will have 'nbOfComp' components (that can be different from this->getNumberOfComponents()) contrary to the other DataArrayDouble::applyFunc overload method.
2367  */
2368 DataArrayDouble *DataArrayDouble::applyFunc(int nbOfComp, const char *func) const throw(INTERP_KERNEL::Exception)
2369 {
2370   checkAllocated();
2371   INTERP_KERNEL::ExprParser expr(func);
2372   expr.parse();
2373   std::set<std::string> vars;
2374   expr.getTrueSetOfVars(vars);
2375   int oldNbOfComp=getNumberOfComponents();
2376   if((int)vars.size()>oldNbOfComp)
2377     {
2378       std::ostringstream oss; oss << "The field has " << oldNbOfComp << " components and there are ";
2379       oss << vars.size() << " variables : ";
2380       std::copy(vars.begin(),vars.end(),std::ostream_iterator<std::string>(oss," "));
2381       throw INTERP_KERNEL::Exception(oss.str().c_str());
2382     }
2383   std::vector<std::string> varsV(vars.begin(),vars.end());
2384   expr.prepareExprEvaluation(varsV,oldNbOfComp,nbOfComp);
2385   //
2386   DataArrayDouble *newArr=DataArrayDouble::New();
2387   int nbOfTuples=getNumberOfTuples();
2388   newArr->alloc(nbOfTuples,nbOfComp);
2389   const double *ptr=getConstPointer();
2390   double *ptrToFill=newArr->getPointer();
2391   for(int i=0;i<nbOfTuples;i++)
2392     {
2393       try
2394         {
2395           expr.evaluateExpr(nbOfComp,ptr+i*oldNbOfComp,ptrToFill+i*nbOfComp);
2396         }
2397       catch(INTERP_KERNEL::Exception& e)
2398         {
2399           std::ostringstream oss; oss << "For tuple # " << i << " with value (";
2400           std::copy(ptr+oldNbOfComp*i,ptr+oldNbOfComp*(i+1),std::ostream_iterator<double>(oss,", "));
2401           oss << ") : Evaluation of function failed !" << e.what();
2402           newArr->decrRef();
2403           throw INTERP_KERNEL::Exception(oss.str().c_str());
2404         }
2405     }
2406   return newArr;
2407 }
2408
2409 DataArrayDouble *DataArrayDouble::applyFunc(const char *func) const throw(INTERP_KERNEL::Exception)
2410 {
2411   checkAllocated();
2412   INTERP_KERNEL::ExprParser expr(func);
2413   expr.parse();
2414   expr.prepareExprEvaluationVec();
2415   //
2416   DataArrayDouble *newArr=DataArrayDouble::New();
2417   int nbOfTuples=getNumberOfTuples();
2418   int nbOfComp=getNumberOfComponents();
2419   newArr->alloc(nbOfTuples,nbOfComp);
2420   const double *ptr=getConstPointer();
2421   double *ptrToFill=newArr->getPointer();
2422   for(int i=0;i<nbOfTuples;i++)
2423     {
2424       try
2425         {
2426           expr.evaluateExpr(nbOfComp,ptr+i*nbOfComp,ptrToFill+i*nbOfComp);
2427         }
2428       catch(INTERP_KERNEL::Exception& e)
2429         {
2430           std::ostringstream oss; oss << "For tuple # " << i << " with value (";
2431           std::copy(ptr+nbOfComp*i,ptr+nbOfComp*(i+1),std::ostream_iterator<double>(oss,", "));
2432           oss << ") : Evaluation of function failed ! " << e.what();
2433           newArr->decrRef();
2434           throw INTERP_KERNEL::Exception(oss.str().c_str());
2435         }
2436     }
2437   return newArr;
2438 }
2439
2440 /*!
2441  * This method is equivalent than DataArrayDouble::applyFunc, except that here components names are used to determine vars orders.
2442  * If 'func' contains vars that are not in \c this->getInfoOnComponent() an exception will be thrown.
2443  */
2444 DataArrayDouble *DataArrayDouble::applyFunc2(int nbOfComp, const char *func) const throw(INTERP_KERNEL::Exception)
2445 {
2446   checkAllocated();
2447   INTERP_KERNEL::ExprParser expr(func);
2448   expr.parse();
2449   std::set<std::string> vars;
2450   expr.getTrueSetOfVars(vars);
2451   int oldNbOfComp=getNumberOfComponents();
2452   if((int)vars.size()>oldNbOfComp)
2453     {
2454       std::ostringstream oss; oss << "The field has " << oldNbOfComp << " components and there are ";
2455       oss << vars.size() << " variables : ";
2456       std::copy(vars.begin(),vars.end(),std::ostream_iterator<std::string>(oss," "));
2457       throw INTERP_KERNEL::Exception(oss.str().c_str());
2458     }
2459   expr.prepareExprEvaluation(getVarsOnComponent(),oldNbOfComp,nbOfComp);
2460   //
2461   DataArrayDouble *newArr=DataArrayDouble::New();
2462   int nbOfTuples=getNumberOfTuples();
2463   newArr->alloc(nbOfTuples,nbOfComp);
2464   const double *ptr=getConstPointer();
2465   double *ptrToFill=newArr->getPointer();
2466   for(int i=0;i<nbOfTuples;i++)
2467     {
2468       try
2469         {
2470           expr.evaluateExpr(nbOfComp,ptr+i*oldNbOfComp,ptrToFill+i*nbOfComp);
2471         }
2472       catch(INTERP_KERNEL::Exception& e)
2473         {
2474           std::ostringstream oss; oss << "For tuple # " << i << " with value (";
2475           std::copy(ptr+oldNbOfComp*i,ptr+oldNbOfComp*(i+1),std::ostream_iterator<double>(oss,", "));
2476           oss << ") : Evaluation of function failed !" << e.what();
2477           newArr->decrRef();
2478           throw INTERP_KERNEL::Exception(oss.str().c_str());
2479         }
2480     }
2481   return newArr;
2482 }
2483
2484 /*!
2485  * This method is equivalent than DataArrayDouble::applyFunc, except that here order of vars is passed explicitely in parameter.
2486  * In 'func' contains vars not in 'varsOrder' an exception will be thrown.
2487  */
2488 DataArrayDouble *DataArrayDouble::applyFunc3(int nbOfComp, const std::vector<std::string>& varsOrder, const char *func) const throw(INTERP_KERNEL::Exception)
2489 {
2490   checkAllocated();
2491   INTERP_KERNEL::ExprParser expr(func);
2492   expr.parse();
2493   std::set<std::string> vars;
2494   expr.getTrueSetOfVars(vars);
2495   int oldNbOfComp=getNumberOfComponents();
2496   if((int)vars.size()>oldNbOfComp)
2497     {
2498       std::ostringstream oss; oss << "The field has " << oldNbOfComp << " components and there are ";
2499       oss << vars.size() << " variables : ";
2500       std::copy(vars.begin(),vars.end(),std::ostream_iterator<std::string>(oss," "));
2501       throw INTERP_KERNEL::Exception(oss.str().c_str());
2502     }
2503   expr.prepareExprEvaluation(varsOrder,oldNbOfComp,nbOfComp);
2504   //
2505   DataArrayDouble *newArr=DataArrayDouble::New();
2506   int nbOfTuples=getNumberOfTuples();
2507   newArr->alloc(nbOfTuples,nbOfComp);
2508   const double *ptr=getConstPointer();
2509   double *ptrToFill=newArr->getPointer();
2510   for(int i=0;i<nbOfTuples;i++)
2511     {
2512       try
2513         {
2514           expr.evaluateExpr(nbOfComp,ptr+i*oldNbOfComp,ptrToFill+i*nbOfComp);
2515         }
2516       catch(INTERP_KERNEL::Exception& e)
2517         {
2518           std::ostringstream oss; oss << "For tuple # " << i << " with value (";
2519           std::copy(ptr+oldNbOfComp*i,ptr+oldNbOfComp*(i+1),std::ostream_iterator<double>(oss,", "));
2520           oss << ") : Evaluation of function failed !" << e.what();
2521           newArr->decrRef();
2522           throw INTERP_KERNEL::Exception(oss.str().c_str());
2523         }
2524     }
2525   return newArr;
2526 }
2527
2528 void DataArrayDouble::applyFuncFast32(const char *func) throw(INTERP_KERNEL::Exception)
2529 {
2530   checkAllocated();
2531   INTERP_KERNEL::ExprParser expr(func);
2532   expr.parse();
2533   char *funcStr=expr.compileX86();
2534   MYFUNCPTR funcPtr;
2535   *((void **)&funcPtr)=funcStr;//he he...
2536   //
2537   double *ptr=getPointer();
2538   int nbOfComp=getNumberOfComponents();
2539   int nbOfTuples=getNumberOfTuples();
2540   int nbOfElems=nbOfTuples*nbOfComp;
2541   for(int i=0;i<nbOfElems;i++,ptr++)
2542     *ptr=funcPtr(*ptr);
2543   declareAsNew();
2544 }
2545
2546 void DataArrayDouble::applyFuncFast64(const char *func) throw(INTERP_KERNEL::Exception)
2547 {
2548   checkAllocated();
2549   INTERP_KERNEL::ExprParser expr(func);
2550   expr.parse();
2551   char *funcStr=expr.compileX86_64();
2552   MYFUNCPTR funcPtr;
2553   *((void **)&funcPtr)=funcStr;//he he...
2554   //
2555   double *ptr=getPointer();
2556   int nbOfComp=getNumberOfComponents();
2557   int nbOfTuples=getNumberOfTuples();
2558   int nbOfElems=nbOfTuples*nbOfComp;
2559   for(int i=0;i<nbOfElems;i++,ptr++)
2560     *ptr=funcPtr(*ptr);
2561   declareAsNew();
2562 }
2563
2564 DataArrayDoubleIterator *DataArrayDouble::iterator()
2565 {
2566   return new DataArrayDoubleIterator(this);
2567 }
2568
2569 DataArrayInt *DataArrayDouble::getIdsInRange(double vmin, double vmax) const throw(INTERP_KERNEL::Exception)
2570 {
2571   if(getNumberOfComponents()!=1)
2572     throw INTERP_KERNEL::Exception("DataArrayDouble::getIdsInRange : this must have exactly one component !");
2573   const double *cptr=getConstPointer();
2574   std::vector<int> res;
2575   int nbOfTuples=getNumberOfTuples();
2576   for(int i=0;i<nbOfTuples;i++,cptr++)
2577     if(*cptr>=vmin && *cptr<=vmax)
2578       res.push_back(i);
2579   DataArrayInt *ret=DataArrayInt::New();
2580   ret->alloc((int)res.size(),1);
2581   std::copy(res.begin(),res.end(),ret->getPointer());
2582   return ret;
2583 }
2584
2585 DataArrayDouble *DataArrayDouble::Aggregate(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception)
2586 {
2587   std::vector<const DataArrayDouble *> tmp(2);
2588   tmp[0]=a1; tmp[1]=a2;
2589   return Aggregate(tmp);
2590 }
2591
2592 DataArrayDouble *DataArrayDouble::Aggregate(const std::vector<const DataArrayDouble *>& arr) throw(INTERP_KERNEL::Exception)
2593 {
2594   std::vector<const DataArrayDouble *> a;
2595   for(std::vector<const DataArrayDouble *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
2596     if(*it4)
2597       a.push_back(*it4);
2598   if(a.empty())
2599     throw INTERP_KERNEL::Exception("DataArrayDouble::Aggregate : input list must contain at least one NON EMPTY DataArrayDouble !");
2600   std::vector<const DataArrayDouble *>::const_iterator it=a.begin();
2601   int nbOfComp=(*it)->getNumberOfComponents();
2602   int nbt=(*it++)->getNumberOfTuples();
2603   for(int i=1;it!=a.end();it++,i++)
2604     {
2605       if((*it)->getNumberOfComponents()!=nbOfComp)
2606         throw INTERP_KERNEL::Exception("DataArrayDouble::Aggregate : Nb of components mismatch for array aggregation !");
2607       nbt+=(*it)->getNumberOfTuples();
2608     }
2609   DataArrayDouble *ret=DataArrayDouble::New();
2610   ret->alloc(nbt,nbOfComp);
2611   double *pt=ret->getPointer();
2612   for(it=a.begin();it!=a.end();it++)
2613     pt=std::copy((*it)->getConstPointer(),(*it)->getConstPointer()+(*it)->getNbOfElems(),pt);
2614   ret->copyStringInfoFrom(*(a[0]));
2615   return ret;
2616 }
2617
2618 DataArrayDouble *DataArrayDouble::Meld(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception)
2619 {
2620   std::vector<const DataArrayDouble *> arr(2);
2621   arr[0]=a1; arr[1]=a2;
2622   return Meld(arr);
2623 }
2624
2625 DataArrayDouble *DataArrayDouble::Meld(const std::vector<const DataArrayDouble *>& arr) throw(INTERP_KERNEL::Exception)
2626 {
2627   std::vector<const DataArrayDouble *> a;
2628   for(std::vector<const DataArrayDouble *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
2629     if(*it4)
2630       a.push_back(*it4);
2631   if(a.empty())
2632     throw INTERP_KERNEL::Exception("DataArrayDouble::Meld : input list must contain at least one NON EMPTY DataArrayDouble !");
2633   std::vector<const DataArrayDouble *>::const_iterator it;
2634   for(it=a.begin();it!=a.end();it++)
2635     (*it)->checkAllocated();
2636   it=a.begin();
2637   int nbOfTuples=(*it)->getNumberOfTuples();
2638   std::vector<int> nbc(a.size());
2639   std::vector<const double *> pts(a.size());
2640   nbc[0]=(*it)->getNumberOfComponents();
2641   pts[0]=(*it++)->getConstPointer();
2642   for(int i=1;it!=a.end();it++,i++)
2643     {
2644       if(nbOfTuples!=(*it)->getNumberOfTuples())
2645         throw INTERP_KERNEL::Exception("DataArrayDouble::Meld : mismatch of number of tuples !");
2646       nbc[i]=(*it)->getNumberOfComponents();
2647       pts[i]=(*it)->getConstPointer();
2648     }
2649   int totalNbOfComp=std::accumulate(nbc.begin(),nbc.end(),0);
2650   DataArrayDouble *ret=DataArrayDouble::New();
2651   ret->alloc(nbOfTuples,totalNbOfComp);
2652   double *retPtr=ret->getPointer();
2653   for(int i=0;i<nbOfTuples;i++)
2654     for(int j=0;j<(int)a.size();j++)
2655       {
2656         retPtr=std::copy(pts[j],pts[j]+nbc[j],retPtr);
2657         pts[j]+=nbc[j];
2658       }
2659   int k=0;
2660   for(int i=0;i<(int)a.size();i++)
2661     for(int j=0;j<nbc[i];j++,k++)
2662       ret->setInfoOnComponent(k,a[i]->getInfoOnComponent(j).c_str());
2663   return ret;
2664 }
2665
2666 DataArrayDouble *DataArrayDouble::Dot(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception)
2667 {
2668   if(!a1 || !a2)
2669     throw INTERP_KERNEL::Exception("DataArrayDouble::Dot : input DataArrayDouble instance is NULL !");
2670   a1->checkAllocated();
2671   a2->checkAllocated();
2672   int nbOfComp=a1->getNumberOfComponents();
2673   if(nbOfComp!=a2->getNumberOfComponents())
2674     throw INTERP_KERNEL::Exception("Nb of components mismatch for array Dot !");
2675   int nbOfTuple=a1->getNumberOfTuples();
2676   if(nbOfTuple!=a2->getNumberOfTuples())
2677     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Dot !");
2678   DataArrayDouble *ret=DataArrayDouble::New();
2679   ret->alloc(nbOfTuple,1);
2680   double *retPtr=ret->getPointer();
2681   const double *a1Ptr=a1->getConstPointer();
2682   const double *a2Ptr=a2->getConstPointer();
2683   for(int i=0;i<nbOfTuple;i++)
2684     {
2685       double sum=0.;
2686       for(int j=0;j<nbOfComp;j++)
2687         sum+=a1Ptr[i*nbOfComp+j]*a2Ptr[i*nbOfComp+j];
2688       retPtr[i]=sum;
2689     }
2690   ret->setInfoOnComponent(0,a1->getInfoOnComponent(0).c_str());
2691   ret->setName(a1->getName().c_str());
2692   return ret;
2693 }
2694
2695 DataArrayDouble *DataArrayDouble::CrossProduct(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception)
2696 {
2697   if(!a1 || !a2)
2698     throw INTERP_KERNEL::Exception("DataArrayDouble::CrossProduct : input DataArrayDouble instance is NULL !");
2699   int nbOfComp=a1->getNumberOfComponents();
2700   if(nbOfComp!=a2->getNumberOfComponents())
2701     throw INTERP_KERNEL::Exception("Nb of components mismatch for array crossProduct !");
2702   if(nbOfComp!=3)
2703     throw INTERP_KERNEL::Exception("Nb of components must be equal to 3 for array crossProduct !");
2704   int nbOfTuple=a1->getNumberOfTuples();
2705   if(nbOfTuple!=a2->getNumberOfTuples())
2706     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array crossProduct !");
2707   DataArrayDouble *ret=DataArrayDouble::New();
2708   ret->alloc(nbOfTuple,3);
2709   double *retPtr=ret->getPointer();
2710   const double *a1Ptr=a1->getConstPointer();
2711   const double *a2Ptr=a2->getConstPointer();
2712   for(int i=0;i<nbOfTuple;i++)
2713     {
2714       retPtr[3*i]=a1Ptr[3*i+1]*a2Ptr[3*i+2]-a1Ptr[3*i+2]*a2Ptr[3*i+1];
2715       retPtr[3*i+1]=a1Ptr[3*i+2]*a2Ptr[3*i]-a1Ptr[3*i]*a2Ptr[3*i+2];
2716       retPtr[3*i+2]=a1Ptr[3*i]*a2Ptr[3*i+1]-a1Ptr[3*i+1]*a2Ptr[3*i];
2717     }
2718   ret->copyStringInfoFrom(*a1);
2719   return ret;
2720 }
2721
2722 DataArrayDouble *DataArrayDouble::Max(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception)
2723 {
2724   if(!a1 || !a2)
2725     throw INTERP_KERNEL::Exception("DataArrayDouble::Max : input DataArrayDouble instance is NULL !");
2726   int nbOfComp=a1->getNumberOfComponents();
2727   if(nbOfComp!=a2->getNumberOfComponents())
2728     throw INTERP_KERNEL::Exception("Nb of components mismatch for array Max !");
2729   int nbOfTuple=a1->getNumberOfTuples();
2730   if(nbOfTuple!=a2->getNumberOfTuples())
2731     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Max !");
2732   DataArrayDouble *ret=DataArrayDouble::New();
2733   ret->alloc(nbOfTuple,nbOfComp);
2734   double *retPtr=ret->getPointer();
2735   const double *a1Ptr=a1->getConstPointer();
2736   const double *a2Ptr=a2->getConstPointer();
2737   int nbElem=nbOfTuple*nbOfComp;
2738   for(int i=0;i<nbElem;i++)
2739     retPtr[i]=std::max(a1Ptr[i],a2Ptr[i]);
2740   ret->copyStringInfoFrom(*a1);
2741   return ret;
2742 }
2743
2744 DataArrayDouble *DataArrayDouble::Min(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception)
2745 {
2746   if(!a1 || !a2)
2747     throw INTERP_KERNEL::Exception("DataArrayDouble::Min : input DataArrayDouble instance is NULL !");
2748   int nbOfComp=a1->getNumberOfComponents();
2749   if(nbOfComp!=a2->getNumberOfComponents())
2750     throw INTERP_KERNEL::Exception("Nb of components mismatch for array min !");
2751   int nbOfTuple=a1->getNumberOfTuples();
2752   if(nbOfTuple!=a2->getNumberOfTuples())
2753     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array min !");
2754   DataArrayDouble *ret=DataArrayDouble::New();
2755   ret->alloc(nbOfTuple,nbOfComp);
2756   double *retPtr=ret->getPointer();
2757   const double *a1Ptr=a1->getConstPointer();
2758   const double *a2Ptr=a2->getConstPointer();
2759   int nbElem=nbOfTuple*nbOfComp;
2760   for(int i=0;i<nbElem;i++)
2761     retPtr[i]=std::min(a1Ptr[i],a2Ptr[i]);
2762   ret->copyStringInfoFrom(*a1);
2763   return ret;
2764 }
2765
2766 DataArrayDouble *DataArrayDouble::Add(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception)
2767 {
2768   if(!a1 || !a2)
2769     throw INTERP_KERNEL::Exception("DataArrayDouble::Add : input DataArrayDouble instance is NULL !");
2770   int nbOfTuple=a1->getNumberOfTuples();
2771   int nbOfTuple2=a2->getNumberOfTuples();
2772   int nbOfComp=a1->getNumberOfComponents();
2773   int nbOfComp2=a2->getNumberOfComponents();
2774   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=0;
2775   if(nbOfTuple==nbOfTuple2)
2776     {
2777       if(nbOfComp==nbOfComp2)
2778         {
2779           ret=DataArrayDouble::New();
2780           ret->alloc(nbOfTuple,nbOfComp);
2781           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::plus<double>());
2782           ret->copyStringInfoFrom(*a1);
2783         }
2784       else
2785         {
2786           int nbOfCompMin,nbOfCompMax;
2787           const DataArrayDouble *aMin, *aMax;
2788           if(nbOfComp>nbOfComp2)
2789             {
2790               nbOfCompMin=nbOfComp2; nbOfCompMax=nbOfComp;
2791               aMin=a2; aMax=a1;
2792             }
2793           else
2794             {
2795               nbOfCompMin=nbOfComp; nbOfCompMax=nbOfComp2;
2796               aMin=a1; aMax=a2;
2797             }
2798           if(nbOfCompMin==1)
2799             {
2800               ret=DataArrayDouble::New();
2801               ret->alloc(nbOfTuple,nbOfCompMax);
2802               const double *aMinPtr=aMin->getConstPointer();
2803               const double *aMaxPtr=aMax->getConstPointer();
2804               double *res=ret->getPointer();
2805               for(int i=0;i<nbOfTuple;i++)
2806                 res=std::transform(aMaxPtr+i*nbOfCompMax,aMaxPtr+(i+1)*nbOfCompMax,res,std::bind2nd(std::plus<double>(),aMinPtr[i]));
2807               ret->copyStringInfoFrom(*aMax);
2808             }
2809           else
2810             throw INTERP_KERNEL::Exception("Nb of components mismatch for array Add !");
2811         }
2812     }
2813   else if((nbOfTuple==1 && nbOfTuple2>1) || (nbOfTuple>1 && nbOfTuple2==1))
2814     {
2815       if(nbOfComp==nbOfComp2)
2816         {
2817           int nbOfTupleMax=std::max(nbOfTuple,nbOfTuple2);
2818           const DataArrayDouble *aMin=nbOfTuple>nbOfTuple2?a2:a1;
2819           const DataArrayDouble *aMax=nbOfTuple>nbOfTuple2?a1:a2;
2820           const double *aMinPtr=aMin->getConstPointer(),*aMaxPtr=aMax->getConstPointer();
2821           ret=DataArrayDouble::New();
2822           ret->alloc(nbOfTupleMax,nbOfComp);
2823           double *res=ret->getPointer();
2824           for(int i=0;i<nbOfTupleMax;i++)
2825             res=std::transform(aMaxPtr+i*nbOfComp,aMaxPtr+(i+1)*nbOfComp,aMinPtr,res,std::plus<double>());
2826           ret->copyStringInfoFrom(*aMax);
2827         }
2828       else
2829         throw INTERP_KERNEL::Exception("Nb of components mismatch for array Add !");
2830     }
2831   else
2832     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Add !");
2833   ret->incrRef();
2834   return ret;
2835 }
2836
2837 void DataArrayDouble::addEqual(const DataArrayDouble *other) throw(INTERP_KERNEL::Exception)
2838 {
2839   if(!other)
2840     throw INTERP_KERNEL::Exception("DataArrayDouble::addEqual : input DataArrayDouble instance is NULL !");
2841   const char *msg="Nb of tuples mismatch for DataArrayDouble::addEqual  !";
2842   int nbOfTuple=getNumberOfTuples();
2843   int nbOfTuple2=other->getNumberOfTuples();
2844   int nbOfComp=getNumberOfComponents();
2845   int nbOfComp2=other->getNumberOfComponents();
2846   if(nbOfTuple==nbOfTuple2)
2847     {
2848       if(nbOfComp==nbOfComp2)
2849         {
2850           std::transform(begin(),end(),other->begin(),getPointer(),std::plus<double>());
2851         }
2852       else if(nbOfComp2==1)
2853         {
2854           double *ptr=getPointer();
2855           const double *ptrc=other->getConstPointer();
2856           for(int i=0;i<nbOfTuple;i++)
2857             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::plus<double>(),*ptrc++));
2858         }
2859       else
2860         throw INTERP_KERNEL::Exception(msg);
2861     }
2862   else if(nbOfTuple2==1)
2863     {
2864       if(nbOfComp2==nbOfComp)
2865         {
2866           double *ptr=getPointer();
2867           const double *ptrc=other->getConstPointer();
2868           for(int i=0;i<nbOfTuple;i++)
2869             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::plus<double>());
2870         }
2871       else
2872         throw INTERP_KERNEL::Exception(msg);
2873     }
2874   else
2875     throw INTERP_KERNEL::Exception(msg);
2876   declareAsNew();
2877 }
2878
2879 DataArrayDouble *DataArrayDouble::Substract(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception)
2880 {
2881   if(!a1 || !a2)
2882     throw INTERP_KERNEL::Exception("DataArrayDouble::Substract : input DataArrayDouble instance is NULL !");
2883   int nbOfTuple1=a1->getNumberOfTuples();
2884   int nbOfTuple2=a2->getNumberOfTuples();
2885   int nbOfComp1=a1->getNumberOfComponents();
2886   int nbOfComp2=a2->getNumberOfComponents();
2887   if(nbOfTuple2==nbOfTuple1)
2888     {
2889       if(nbOfComp1==nbOfComp2)
2890         {
2891           MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
2892           ret->alloc(nbOfTuple2,nbOfComp1);
2893           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::minus<double>());
2894           ret->copyStringInfoFrom(*a1);
2895           ret->incrRef();
2896           return ret;
2897         }
2898       else if(nbOfComp2==1)
2899         {
2900           MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
2901           ret->alloc(nbOfTuple1,nbOfComp1);
2902           const double *a2Ptr=a2->getConstPointer();
2903           const double *a1Ptr=a1->getConstPointer();
2904           double *res=ret->getPointer();
2905           for(int i=0;i<nbOfTuple1;i++)
2906             res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::minus<double>(),a2Ptr[i]));
2907           ret->copyStringInfoFrom(*a1);
2908           ret->incrRef();
2909           return ret;
2910         }
2911       else
2912         {
2913           a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Substract !");
2914           return 0;
2915         }
2916     }
2917   else if(nbOfTuple2==1)
2918     {
2919       a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Substract !");
2920       MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
2921       ret->alloc(nbOfTuple1,nbOfComp1);
2922       const double *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
2923       double *pt=ret->getPointer();
2924       for(int i=0;i<nbOfTuple1;i++)
2925         pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::minus<double>());
2926       ret->copyStringInfoFrom(*a1);
2927       ret->incrRef();
2928       return ret;
2929     }
2930   else
2931     {
2932       a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Substract !");//will always throw an exception
2933       return 0;
2934     }
2935 }
2936
2937 void DataArrayDouble::substractEqual(const DataArrayDouble *other) throw(INTERP_KERNEL::Exception)
2938 {
2939   if(!other)
2940     throw INTERP_KERNEL::Exception("DataArrayDouble::substractEqual : input DataArrayDouble instance is NULL !");
2941   const char *msg="Nb of tuples mismatch for DataArrayDouble::substractEqual  !";
2942   int nbOfTuple=getNumberOfTuples();
2943   int nbOfTuple2=other->getNumberOfTuples();
2944   int nbOfComp=getNumberOfComponents();
2945   int nbOfComp2=other->getNumberOfComponents();
2946   if(nbOfTuple==nbOfTuple2)
2947     {
2948       if(nbOfComp==nbOfComp2)
2949         {
2950           std::transform(begin(),end(),other->begin(),getPointer(),std::minus<double>());
2951         }
2952       else if(nbOfComp2==1)
2953         {
2954           double *ptr=getPointer();
2955           const double *ptrc=other->getConstPointer();
2956           for(int i=0;i<nbOfTuple;i++)
2957             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::minus<double>(),*ptrc++)); 
2958         }
2959       else
2960         throw INTERP_KERNEL::Exception(msg);
2961     }
2962   else if(nbOfTuple2==1)
2963     {
2964       if(nbOfComp2==nbOfComp)
2965         {
2966           double *ptr=getPointer();
2967           const double *ptrc=other->getConstPointer();
2968           for(int i=0;i<nbOfTuple;i++)
2969             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::minus<double>());
2970         }
2971       else
2972         throw INTERP_KERNEL::Exception(msg);
2973     }
2974   else
2975     throw INTERP_KERNEL::Exception(msg);
2976   declareAsNew();
2977 }
2978
2979 DataArrayDouble *DataArrayDouble::Multiply(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception)
2980 {
2981   if(!a1 || !a2)
2982     throw INTERP_KERNEL::Exception("DataArrayDouble::Multiply : input DataArrayDouble instance is NULL !");
2983   int nbOfTuple=a1->getNumberOfTuples();
2984   int nbOfTuple2=a2->getNumberOfTuples();
2985   int nbOfComp=a1->getNumberOfComponents();
2986   int nbOfComp2=a2->getNumberOfComponents();
2987   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=0;
2988   if(nbOfTuple==nbOfTuple2)
2989     {
2990       if(nbOfComp==nbOfComp2)
2991         {
2992           ret=DataArrayDouble::New();
2993           ret->alloc(nbOfTuple,nbOfComp);
2994           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::multiplies<double>());
2995           ret->copyStringInfoFrom(*a1);
2996         }
2997       else
2998         {
2999           int nbOfCompMin,nbOfCompMax;
3000           const DataArrayDouble *aMin, *aMax;
3001           if(nbOfComp>nbOfComp2)
3002             {
3003               nbOfCompMin=nbOfComp2; nbOfCompMax=nbOfComp;
3004               aMin=a2; aMax=a1;
3005             }
3006           else
3007             {
3008               nbOfCompMin=nbOfComp; nbOfCompMax=nbOfComp2;
3009               aMin=a1; aMax=a2;
3010             }
3011           if(nbOfCompMin==1)
3012             {
3013               ret=DataArrayDouble::New();
3014               ret->alloc(nbOfTuple,nbOfCompMax);
3015               const double *aMinPtr=aMin->getConstPointer();
3016               const double *aMaxPtr=aMax->getConstPointer();
3017               double *res=ret->getPointer();
3018               for(int i=0;i<nbOfTuple;i++)
3019                 res=std::transform(aMaxPtr+i*nbOfCompMax,aMaxPtr+(i+1)*nbOfCompMax,res,std::bind2nd(std::multiplies<double>(),aMinPtr[i]));
3020               ret->copyStringInfoFrom(*aMax);
3021             }
3022           else
3023             throw INTERP_KERNEL::Exception("Nb of components mismatch for array Multiply !");
3024         }
3025     }
3026   else if((nbOfTuple==1 && nbOfTuple2>1) || (nbOfTuple>1 && nbOfTuple2==1))
3027     {
3028       if(nbOfComp==nbOfComp2)
3029         {
3030           int nbOfTupleMax=std::max(nbOfTuple,nbOfTuple2);
3031           const DataArrayDouble *aMin=nbOfTuple>nbOfTuple2?a2:a1;
3032           const DataArrayDouble *aMax=nbOfTuple>nbOfTuple2?a1:a2;
3033           const double *aMinPtr=aMin->getConstPointer(),*aMaxPtr=aMax->getConstPointer();
3034           ret=DataArrayDouble::New();
3035           ret->alloc(nbOfTupleMax,nbOfComp);
3036           double *res=ret->getPointer();
3037           for(int i=0;i<nbOfTupleMax;i++)
3038             res=std::transform(aMaxPtr+i*nbOfComp,aMaxPtr+(i+1)*nbOfComp,aMinPtr,res,std::multiplies<double>());
3039           ret->copyStringInfoFrom(*aMax);
3040         }
3041       else
3042         throw INTERP_KERNEL::Exception("Nb of components mismatch for array Multiply !");
3043     }
3044   else
3045     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Multiply !");
3046   ret->incrRef();
3047   return ret;
3048 }
3049
3050 void DataArrayDouble::multiplyEqual(const DataArrayDouble *other) throw(INTERP_KERNEL::Exception)
3051 {
3052   if(!other)
3053     throw INTERP_KERNEL::Exception("DataArrayDouble::multiplyEqual : input DataArrayDouble instance is NULL !");
3054   const char *msg="Nb of tuples mismatch for DataArrayDouble::multiplyEqual !";
3055   int nbOfTuple=getNumberOfTuples();
3056   int nbOfTuple2=other->getNumberOfTuples();
3057   int nbOfComp=getNumberOfComponents();
3058   int nbOfComp2=other->getNumberOfComponents();
3059   if(nbOfTuple==nbOfTuple2)
3060     {
3061       if(nbOfComp==nbOfComp2)
3062         {
3063           std::transform(begin(),end(),other->begin(),getPointer(),std::multiplies<double>());
3064         }
3065       else if(nbOfComp2==1)
3066         {
3067           double *ptr=getPointer();
3068           const double *ptrc=other->getConstPointer();
3069           for(int i=0;i<nbOfTuple;i++)
3070             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::multiplies<double>(),*ptrc++));
3071         }
3072       else
3073         throw INTERP_KERNEL::Exception(msg);
3074     }
3075   else if(nbOfTuple2==1)
3076     {
3077       if(nbOfComp2==nbOfComp)
3078         {
3079           double *ptr=getPointer();
3080           const double *ptrc=other->getConstPointer();
3081           for(int i=0;i<nbOfTuple;i++)
3082             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::multiplies<double>());
3083         }
3084       else
3085         throw INTERP_KERNEL::Exception(msg);
3086     }
3087   else
3088     throw INTERP_KERNEL::Exception(msg);
3089   declareAsNew();
3090 }
3091
3092 DataArrayDouble *DataArrayDouble::Divide(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception)
3093 {
3094   if(!a1 || !a2)
3095     throw INTERP_KERNEL::Exception("DataArrayDouble::Divide : input DataArrayDouble instance is NULL !");
3096   int nbOfTuple1=a1->getNumberOfTuples();
3097   int nbOfTuple2=a2->getNumberOfTuples();
3098   int nbOfComp1=a1->getNumberOfComponents();
3099   int nbOfComp2=a2->getNumberOfComponents();
3100   if(nbOfTuple2==nbOfTuple1)
3101     {
3102       if(nbOfComp1==nbOfComp2)
3103         {
3104           MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
3105           ret->alloc(nbOfTuple2,nbOfComp1);
3106           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::divides<double>());
3107           ret->copyStringInfoFrom(*a1);
3108           ret->incrRef();
3109           return ret;
3110         }
3111       else if(nbOfComp2==1)
3112         {
3113           MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
3114           ret->alloc(nbOfTuple1,nbOfComp1);
3115           const double *a2Ptr=a2->getConstPointer();
3116           const double *a1Ptr=a1->getConstPointer();
3117           double *res=ret->getPointer();
3118           for(int i=0;i<nbOfTuple1;i++)
3119             res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::divides<double>(),a2Ptr[i]));
3120           ret->copyStringInfoFrom(*a1);
3121           ret->incrRef();
3122           return ret;
3123         }
3124       else
3125         {
3126           a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Divide !");
3127           return 0;
3128         }
3129     }
3130   else if(nbOfTuple2==1)
3131     {
3132       a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Divide !");
3133       MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
3134       ret->alloc(nbOfTuple1,nbOfComp1);
3135       const double *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
3136       double *pt=ret->getPointer();
3137       for(int i=0;i<nbOfTuple1;i++)
3138         pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::divides<double>());
3139       ret->copyStringInfoFrom(*a1);
3140       ret->incrRef();
3141       return ret;
3142     }
3143   else
3144     {
3145       a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Divide !");//will always throw an exception
3146       return 0;
3147     }
3148 }
3149
3150 void DataArrayDouble::divideEqual(const DataArrayDouble *other) throw(INTERP_KERNEL::Exception)
3151 {
3152   if(!other)
3153     throw INTERP_KERNEL::Exception("DataArrayDouble::divideEqual : input DataArrayDouble instance is NULL !");
3154   const char *msg="Nb of tuples mismatch for DataArrayDouble::divideEqual !";
3155   int nbOfTuple=getNumberOfTuples();
3156   int nbOfTuple2=other->getNumberOfTuples();
3157   int nbOfComp=getNumberOfComponents();
3158   int nbOfComp2=other->getNumberOfComponents();
3159   if(nbOfTuple==nbOfTuple2)
3160     {
3161       if(nbOfComp==nbOfComp2)
3162         {
3163           std::transform(begin(),end(),other->begin(),getPointer(),std::divides<double>());
3164         }
3165       else if(nbOfComp2==1)
3166         {
3167           double *ptr=getPointer();
3168           const double *ptrc=other->getConstPointer();
3169           for(int i=0;i<nbOfTuple;i++)
3170             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::divides<double>(),*ptrc++));
3171         }
3172       else
3173         throw INTERP_KERNEL::Exception(msg);
3174     }
3175   else if(nbOfTuple2==1)
3176     {
3177       if(nbOfComp2==nbOfComp)
3178         {
3179           double *ptr=getPointer();
3180           const double *ptrc=other->getConstPointer();
3181           for(int i=0;i<nbOfTuple;i++)
3182             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::divides<double>());
3183         }
3184       else
3185         throw INTERP_KERNEL::Exception(msg);
3186     }
3187   else
3188     throw INTERP_KERNEL::Exception(msg);
3189   declareAsNew();
3190 }
3191
3192 /*!
3193  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
3194  * Server side.
3195  */
3196 void DataArrayDouble::getTinySerializationIntInformation(std::vector<int>& tinyInfo) const
3197 {
3198   tinyInfo.resize(2);
3199   if(isAllocated())
3200     {
3201       tinyInfo[0]=getNumberOfTuples();
3202       tinyInfo[1]=getNumberOfComponents();
3203     }
3204   else
3205     {
3206       tinyInfo[0]=-1;
3207       tinyInfo[1]=-1;
3208     }
3209 }
3210
3211 /*!
3212  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
3213  * Server side.
3214  */
3215 void DataArrayDouble::getTinySerializationStrInformation(std::vector<std::string>& tinyInfo) const
3216 {
3217   if(isAllocated())
3218     {
3219       int nbOfCompo=getNumberOfComponents();
3220       tinyInfo.resize(nbOfCompo+1);
3221       tinyInfo[0]=getName();
3222       for(int i=0;i<nbOfCompo;i++)
3223         tinyInfo[i+1]=getInfoOnComponent(i);
3224     }
3225   else
3226     {
3227       tinyInfo.resize(1);
3228       tinyInfo[0]=getName();
3229     }
3230 }
3231
3232 /*!
3233  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
3234  * This method returns if a feeding is needed.
3235  */
3236 bool DataArrayDouble::resizeForUnserialization(const std::vector<int>& tinyInfoI)
3237 {
3238   int nbOfTuple=tinyInfoI[0];
3239   int nbOfComp=tinyInfoI[1];
3240   if(nbOfTuple!=-1 || nbOfComp!=-1)
3241     {
3242       alloc(nbOfTuple,nbOfComp);
3243       return true;
3244     }
3245   return false;
3246 }
3247
3248 /*!
3249  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
3250  */
3251 void DataArrayDouble::finishUnserialization(const std::vector<int>& tinyInfoI, const std::vector<std::string>& tinyInfoS)
3252 {
3253   setName(tinyInfoS[0].c_str());
3254   if(isAllocated())
3255     {
3256       int nbOfCompo=getNumberOfComponents();
3257       for(int i=0;i<nbOfCompo;i++)
3258         setInfoOnComponent(i,tinyInfoS[i+1].c_str());
3259     }
3260 }
3261
3262 DataArrayDoubleIterator::DataArrayDoubleIterator(DataArrayDouble *da):_da(da),_tuple_id(0),_nb_comp(0),_nb_tuple(0)
3263 {
3264   if(_da)
3265     {
3266       _da->incrRef();
3267       if(_da->isAllocated())
3268         {
3269           _nb_comp=da->getNumberOfComponents();
3270           _nb_tuple=da->getNumberOfTuples();
3271           _pt=da->getPointer();
3272         }
3273     }
3274 }
3275
3276 DataArrayDoubleIterator::~DataArrayDoubleIterator()
3277 {
3278   if(_da)
3279     _da->decrRef();
3280 }
3281
3282 DataArrayDoubleTuple *DataArrayDoubleIterator::nextt()
3283 {
3284   if(_tuple_id<_nb_tuple)
3285     {
3286       _tuple_id++;
3287       DataArrayDoubleTuple *ret=new DataArrayDoubleTuple(_pt,_nb_comp);
3288       _pt+=_nb_comp;
3289       return ret;
3290     }
3291   else
3292     return 0;
3293 }
3294
3295 DataArrayDoubleTuple::DataArrayDoubleTuple(double *pt, int nbOfComp):_pt(pt),_nb_of_compo(nbOfComp)
3296 {
3297 }
3298
3299
3300 std::string DataArrayDoubleTuple::repr() const
3301 {
3302   std::ostringstream oss; oss.precision(15); oss << "(";
3303   for(int i=0;i<_nb_of_compo-1;i++)
3304     oss << _pt[i] << ", ";
3305   oss << _pt[_nb_of_compo-1] << ")";
3306   return oss.str();
3307 }
3308
3309 double DataArrayDoubleTuple::doubleValue() const throw(INTERP_KERNEL::Exception)
3310 {
3311   if(_nb_of_compo==1)
3312     return *_pt;
3313   throw INTERP_KERNEL::Exception("DataArrayDoubleTuple::doubleValue : DataArrayDoubleTuple instance has not exactly 1 component -> Not possible to convert it into a double precision float !");
3314 }
3315
3316 /*!
3317  * This method returns a newly allocated instance the caller should dealed with by a ParaMEDMEM::DataArrayDouble::decrRef.
3318  * This method performs \b no copy of data. The content is only referenced using ParaMEDMEM::DataArrayDouble::useArray with ownership set to \b false.
3319  * 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
3320  * \b nbOfCompo=1 and \bnbOfTuples==this->_nb_of_elem.
3321  */
3322 DataArrayDouble *DataArrayDoubleTuple::buildDADouble(int nbOfTuples, int nbOfCompo) const throw(INTERP_KERNEL::Exception)
3323 {
3324   if((_nb_of_compo==nbOfCompo && nbOfTuples==1) || (_nb_of_compo==nbOfTuples && nbOfCompo==1))
3325     {
3326       DataArrayDouble *ret=DataArrayDouble::New();
3327       ret->useArray(_pt,false,CPP_DEALLOC,nbOfTuples,nbOfCompo);
3328       return ret;
3329     }
3330   else
3331     {
3332       std::ostringstream oss; oss << "DataArrayDoubleTuple::buildDADouble : unable to build a requested DataArrayDouble instance with nbofTuple=" << nbOfTuples << " and nbOfCompo=" << nbOfCompo;
3333       oss << ".\nBecause the number of elements in this is " << _nb_of_compo << " !";
3334       throw INTERP_KERNEL::Exception(oss.str().c_str());
3335     }
3336 }
3337
3338 DataArrayInt *DataArrayInt::New()
3339 {
3340   return new DataArrayInt;
3341 }
3342
3343 bool DataArrayInt::isAllocated() const
3344 {
3345   return getConstPointer()!=0;
3346 }
3347
3348 void DataArrayInt::checkAllocated() const throw(INTERP_KERNEL::Exception)
3349 {
3350   if(!isAllocated())
3351     throw INTERP_KERNEL::Exception("DataArrayInt::checkAllocated : Array is defined but not allocated ! Call alloc or setValues method first !");
3352 }
3353
3354 /*!
3355  * This method differs from DataArray::setInfoOnComponents in the sense that if 'this->getNumberOfComponents()!=info.size()'
3356  * and if 'this' is not allocated it will change the number of components of 'this'.
3357  * If 'this->getNumberOfComponents()==info.size()' the behaviour is the same than DataArray::setInfoOnComponents method.
3358  * If 'this->getNumberOfComponents()!=info.size()' and the 'this' is already allocated an exception will be thrown.
3359  */
3360 void DataArrayInt::setInfoAndChangeNbOfCompo(const std::vector<std::string>& info) throw(INTERP_KERNEL::Exception)
3361 {
3362   if(getNumberOfComponents()!=(int)info.size())
3363     {
3364       if(!isAllocated())
3365         _info_on_compo=info;
3366       else
3367         {
3368           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 !";
3369           throw INTERP_KERNEL::Exception(oss.str().c_str());
3370         }
3371     }
3372   else
3373     _info_on_compo=info;
3374 }
3375
3376 /*!
3377  * This method returns the only one value in 'this', if and only if number of elements (nb of tuples * nb of components) is equal to 1, and that 'this' is allocated.
3378  * If one or more conditions is not fulfilled an exception will be thrown.
3379  */
3380 int DataArrayInt::intValue() const throw(INTERP_KERNEL::Exception)
3381 {
3382   if(isAllocated())
3383     {
3384       if(getNbOfElems()==1)
3385         {
3386           return *getConstPointer();
3387         }
3388       else
3389         throw INTERP_KERNEL::Exception("DataArrayInt::intValue : DataArrayInt instance is allocated but number of elements is not equal to 1 !");
3390     }
3391   else
3392     throw INTERP_KERNEL::Exception("DataArrayInt::intValue : DataArrayInt instance is not allocated !");
3393 }
3394
3395 /*!
3396  * This method expects that \b this is well allocated. If not an INTERP_KERNEL::Exception will be thrown. This method is useful for a quick comparison of many instances of DataArrayInt.
3397  */
3398 int DataArrayInt::getHashCode() const throw(INTERP_KERNEL::Exception)
3399 {
3400   checkAllocated();
3401   int nbOfElems=getNbOfElems();
3402   int ret=nbOfElems*65536;
3403   int delta=3;
3404   if(nbOfElems>48)
3405     delta=nbOfElems/8;
3406   int ret0=0;
3407   const int *pt=begin();
3408   for(int i=0;i<nbOfElems;i+=delta)
3409     ret0+=pt[i] & 0x1FFF;
3410   return ret+ret0;
3411 }
3412
3413 /*!
3414  * This method should be called on an allocated DataArrayInt instance. If not an exception will be throw !
3415  * This method checks the number of tupes. If it is equal to 0, it returns true, if not false is returned.
3416  */
3417 bool DataArrayInt::empty() const throw(INTERP_KERNEL::Exception)
3418 {
3419   checkAllocated();
3420   return getNumberOfTuples()==0;
3421 }
3422
3423 DataArrayInt *DataArrayInt::deepCpy() const
3424 {
3425   return new DataArrayInt(*this);
3426 }
3427
3428 DataArrayInt *DataArrayInt::performCpy(bool dCpy) const
3429 {
3430   if(dCpy)
3431     return deepCpy();
3432   else
3433     {
3434       incrRef();
3435       return const_cast<DataArrayInt *>(this);
3436     }
3437 }
3438
3439 void DataArrayInt::cpyFrom(const DataArrayInt& other) throw(INTERP_KERNEL::Exception)
3440 {
3441   other.checkAllocated();
3442   int nbOfTuples=other.getNumberOfTuples();
3443   int nbOfComp=other.getNumberOfComponents();
3444   allocIfNecessary(nbOfTuples,nbOfComp);
3445   int nbOfElems=nbOfTuples*nbOfComp;
3446   int *pt=getPointer();
3447   const int *ptI=other.getConstPointer();
3448   for(int i=0;i<nbOfElems;i++)
3449     pt[i]=ptI[i];
3450   copyStringInfoFrom(other);
3451 }
3452
3453 void DataArrayInt::allocIfNecessary(int nbOfTuple, int nbOfCompo)
3454 {
3455   if(isAllocated())
3456     {
3457       if(nbOfTuple!=getNumberOfTuples() || nbOfCompo!=getNumberOfComponents())
3458         alloc(nbOfTuple,nbOfCompo);
3459     }
3460   else
3461     alloc(nbOfTuple,nbOfCompo);
3462 }
3463
3464 void DataArrayInt::alloc(int nbOfTuple, int nbOfCompo) throw(INTERP_KERNEL::Exception)
3465 {
3466   if(nbOfTuple<0 || nbOfCompo<0)
3467     throw INTERP_KERNEL::Exception("DataArrayDouble::alloc : request for negative length of data !");
3468   _nb_of_tuples=nbOfTuple;
3469   _info_on_compo.resize(nbOfCompo);
3470   _mem.alloc(nbOfCompo*_nb_of_tuples);
3471   declareAsNew();
3472 }
3473
3474 void DataArrayInt::fillWithZero() throw(INTERP_KERNEL::Exception)
3475 {
3476   checkAllocated();
3477   _mem.fillWithValue(0);
3478   declareAsNew();
3479 }
3480
3481 void DataArrayInt::fillWithValue(int val) throw(INTERP_KERNEL::Exception)
3482 {
3483   checkAllocated();
3484   _mem.fillWithValue(val);
3485   declareAsNew();
3486 }
3487
3488 void DataArrayInt::iota(int init) throw(INTERP_KERNEL::Exception)
3489 {
3490   checkAllocated();
3491   if(getNumberOfComponents()!=1)
3492     throw INTERP_KERNEL::Exception("DataArrayInt::iota : works only for arrays with only one component, you can call 'rearrange' method before !");
3493   int *ptr=getPointer();
3494   int ntuples=getNumberOfTuples();
3495   for(int i=0;i<ntuples;i++)
3496     ptr[i]=init+i;
3497   declareAsNew();
3498 }
3499
3500 std::string DataArrayInt::repr() const
3501 {
3502   std::ostringstream ret;
3503   reprStream(ret);
3504   return ret.str();
3505 }
3506
3507 std::string DataArrayInt::reprZip() const
3508 {
3509   std::ostringstream ret;
3510   reprZipStream(ret);
3511   return ret.str();
3512 }
3513
3514 void DataArrayInt::writeVTK(std::ostream& ofs, int indent, const char *type, const char *nameInFile) const throw(INTERP_KERNEL::Exception)
3515 {
3516   std::string idt(indent,' ');
3517   ofs << idt << "<DataArray type=\"" << type << "\" Name=\"" << nameInFile << "\" NumberOfComponents=\"" << getNumberOfComponents() << "\"";
3518   ofs << " format=\"ascii\" RangeMin=\"" << getMinValueInArray() << "\" RangeMax=\"" << getMaxValueInArray() << "\">\n" << idt;
3519   std::copy(begin(),end(),std::ostream_iterator<int>(ofs," "));
3520   ofs << std::endl << idt << "</DataArray>\n";
3521 }
3522
3523 void DataArrayInt::reprStream(std::ostream& stream) const
3524 {
3525   stream << "Name of int array : \"" << _name << "\"\n";
3526   reprWithoutNameStream(stream);
3527 }
3528
3529 void DataArrayInt::reprZipStream(std::ostream& stream) const
3530 {
3531   stream << "Name of int array : \"" << _name << "\"\n";
3532   reprZipWithoutNameStream(stream);
3533 }
3534
3535 void DataArrayInt::reprWithoutNameStream(std::ostream& stream) const
3536 {
3537   DataArray::reprWithoutNameStream(stream);
3538   _mem.repr(getNumberOfComponents(),stream);
3539 }
3540
3541 void DataArrayInt::reprZipWithoutNameStream(std::ostream& stream) const
3542 {
3543   DataArray::reprWithoutNameStream(stream);
3544   _mem.reprZip(getNumberOfComponents(),stream);
3545 }
3546
3547 /*!
3548  * This method expects a number of components equal to 1.
3549  * This method sweeps all the values (tuples) in 'this' (it should be allocated) and for each value v is replaced by
3550  * indArr[v] where 'indArr' is defined by ['indArrBg','indArrEnd').
3551  * This method is safe that is to say if there is a value in 'this' not in [0,std::distance('indArrBg','indArrEnd')) an exception
3552  * will be thrown.
3553  */
3554 void DataArrayInt::transformWithIndArr(const int *indArrBg, const int *indArrEnd) throw(INTERP_KERNEL::Exception)
3555 {
3556   if(getNumberOfComponents()!=1)
3557     throw INTERP_KERNEL::Exception("Call transformWithIndArr method on DataArrayInt with only one component, you can call 'rearrange' method before !");
3558   int nbElemsIn=(int)std::distance(indArrBg,indArrEnd);
3559   int nbOfTuples=getNumberOfTuples();
3560   int *pt=getPointer();
3561   for(int i=0;i<nbOfTuples;i++,pt++)
3562     {
3563       if(*pt>=0 && *pt<nbElemsIn)
3564         *pt=indArrBg[*pt];
3565       else
3566         {
3567           std::ostringstream oss; oss << "DataArrayInt::transformWithIndArr : error on tuple #" << i << " value is " << *pt << " and indirectionnal array as a size equal to " << nbElemsIn;
3568           throw INTERP_KERNEL::Exception(oss.str().c_str());
3569         }
3570     }
3571   declareAsNew();
3572 }
3573
3574 /*!
3575  * 'this' should be allocated and with numberOfComponents set to one. If not an exception will be thrown.
3576  * This method takes as input an array defined by ['arrBg','arrEnd'). The size of the array (std::distance(arrBg,arrEnd)) is equal to the number of cast + 1.
3577  * The values contained in ['arrBg','arrEnd') should be sorted ascendently. No check of this will be done. If not the result is not waranted.
3578  * For each cast j the value range that defines the cast is equal to [arrBg[j],arrBg[j+1]).
3579  * This method returns three arrays (to be managed by the caller).
3580  * This method is typically usefull for entity number spliting by types for example.
3581  * Example : If 'this' contains [6,5,0,3,2,7,8,1,4] and if ['arrBg','arrEnd') contains [0,4,9] then the output of this method will be :
3582  * - 'castArr'        : [1,1,0,0,0,1,1,0,1]
3583  * - 'rankInsideCast' : [2,1,0,3,2,3,4,1,0]
3584  * - 'return' : [0,1]
3585  *
3586  * @param castArr is a returned param has the same number of tuples than 'this' and number of components set to one. In case of sucess, this param contains for each tuple in 'this' in which cast it holds.
3587  * @param rankInsideCast is an another returned param has the same number of tuples than 'this' and number of components set to one too. In case of sucess, this param contains for each tuple its rank inside its cast.
3588  * @param castsPresent the casts that 'this' contains.
3589  * @throw if a value in 'this' is greater or equal to the last value of ['arrBg','arrEnd')
3590  */
3591 void DataArrayInt::splitByValueRange(const int *arrBg, const int *arrEnd,
3592                                      DataArrayInt *& castArr, DataArrayInt *& rankInsideCast, DataArrayInt *& castsPresent) const throw(INTERP_KERNEL::Exception)
3593 {
3594   if(getNumberOfComponents()!=1)
3595     throw INTERP_KERNEL::Exception("Call splitByValueRange  method on DataArrayInt with only one component, you can call 'rearrange' method before !");
3596   int nbOfTuples=getNumberOfTuples();
3597   std::size_t nbOfCast=std::distance(arrBg,arrEnd);
3598   if(nbOfCast<2)
3599     throw INTERP_KERNEL::Exception("DataArrayInt::splitByValueRange : The input array giving the cast range values should be of size >=2 !");
3600   nbOfCast--;
3601   const int *work=getConstPointer();
3602   typedef std::reverse_iterator<const int *> rintstart;
3603   rintstart bg(arrEnd);//OK no problem because size of 'arr' is greater of equal 2
3604   rintstart end2(arrBg);
3605   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret1=DataArrayInt::New();
3606   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret2=DataArrayInt::New();
3607   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret3=DataArrayInt::New();
3608   ret1->alloc(nbOfTuples,1);
3609   ret2->alloc(nbOfTuples,1);
3610   int *ret1Ptr=ret1->getPointer();
3611   int *ret2Ptr=ret2->getPointer();
3612   std::set<std::size_t> castsDetected;
3613   for(int i=0;i<nbOfTuples;i++)
3614     {
3615       rintstart res=std::find_if(bg,end2,std::bind2nd(std::less_equal<int>(), work[i]));
3616       std::size_t pos=std::distance(bg,res);
3617       std::size_t pos2=nbOfCast-pos;
3618       if(pos2<nbOfCast)
3619         {
3620           ret1Ptr[i]=(int)pos2;
3621           ret2Ptr[i]=work[i]-arrBg[pos2];
3622           castsDetected.insert(pos2);
3623         }
3624       else
3625         {
3626           std::ostringstream oss; oss << "DataArrayInt::splitByValueRange : At rank #" << i << " the value is " << work[i] << " whereas the last value is " << *bg;
3627           throw INTERP_KERNEL::Exception(oss.str().c_str());
3628         }
3629     }
3630   ret3->alloc((int)castsDetected.size(),1);
3631   std::copy(castsDetected.begin(),castsDetected.end(),ret3->getPointer());
3632   ret1->incrRef();
3633   castArr=ret1;
3634   ret2->incrRef();
3635   rankInsideCast=ret2;
3636   ret3->incrRef();
3637   castsPresent=ret3;
3638 }
3639
3640 /*!
3641  * This method expects a number of components equal to 1.
3642  * This method sweeps all the values (tuples) in 'this' (it should be allocated) and for each value v on place i, place indArr[v] will have 
3643  * value i.
3644  * indArr[v] where 'indArr' is defined by ['indArrBg','indArrEnd').
3645  * This method is half/safe that is to say if there is location i so that indArr[v] is not in [0,this->getNumberOfTuples()) an exception
3646  * will be thrown.
3647  */
3648 DataArrayInt *DataArrayInt::transformWithIndArrR(const int *indArrBg, const int *indArrEnd) const throw(INTERP_KERNEL::Exception)
3649 {
3650   if(getNumberOfComponents()!=1)
3651     throw INTERP_KERNEL::Exception("Call transformWithIndArrR method on DataArrayInt with only one component, you can call 'rearrange' method before !");
3652   int nbElemsIn=(int)std::distance(indArrBg,indArrEnd);
3653   int nbOfTuples=getNumberOfTuples();
3654   const int *pt=getConstPointer();
3655   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
3656   ret->alloc(nbOfTuples,1);
3657   ret->fillWithValue(-1);
3658   int *tmp=ret->getPointer();
3659   for(int i=0;i<nbOfTuples;i++,pt++)
3660     {
3661       int pos=indArrBg[*pt];
3662       if(pos>=0 && pos<nbElemsIn)
3663         tmp[pos]=i;
3664       else
3665         {
3666           std::ostringstream oss; oss << "DataArrayInt::transformWithIndArrR : error on tuple #" << i << " value is " << *pt << " and indirectionnal array as a size equal to " << nbElemsIn;
3667           throw INTERP_KERNEL::Exception(oss.str().c_str());
3668         }
3669     }
3670   ret->incrRef();
3671   return ret;
3672 }
3673
3674 /*!
3675  * This method invert array 'di' that is a conversion map from Old to New numbering to New to Old numbering.
3676  */
3677 DataArrayInt *DataArrayInt::invertArrayO2N2N2O(int newNbOfElem) const
3678 {
3679   DataArrayInt *ret=DataArrayInt::New();
3680   ret->alloc(newNbOfElem,1);
3681   int nbOfOldNodes=getNumberOfTuples();
3682   const int *old2New=getConstPointer();
3683   int *pt=ret->getPointer();
3684   for(int i=0;i!=nbOfOldNodes;i++)
3685     if(old2New[i]!=-1)
3686       pt[old2New[i]]=i;
3687   return ret;
3688 }
3689
3690 /*!
3691  * This method invert array 'di' that is a conversion map from New to old numbering to Old to New numbering.
3692  */
3693 DataArrayInt *DataArrayInt::invertArrayN2O2O2N(int oldNbOfElem) const
3694 {
3695   DataArrayInt *ret=DataArrayInt::New();
3696   ret->alloc(oldNbOfElem,1);
3697   const int *new2Old=getConstPointer();
3698   int *pt=ret->getPointer();
3699   std::fill(pt,pt+oldNbOfElem,-1);
3700   int nbOfNewElems=getNumberOfTuples();
3701   for(int i=0;i<nbOfNewElems;i++)
3702     pt[new2Old[i]]=i;
3703   return ret;
3704 }
3705
3706 bool DataArrayInt::isEqualIfNotWhy(const DataArrayInt& other, std::string& reason) const
3707 {
3708   if(!areInfoEqualsIfNotWhy(other,reason))
3709     return false;
3710   return _mem.isEqual(other._mem,0,reason);
3711 }
3712
3713 bool DataArrayInt::isEqual(const DataArrayInt& other) const
3714 {
3715   std::string tmp;
3716   return isEqualIfNotWhy(other,tmp);
3717 }
3718
3719 bool DataArrayInt::isEqualWithoutConsideringStr(const DataArrayInt& other) const
3720 {
3721   std::string tmp;
3722   return _mem.isEqual(other._mem,0,tmp);
3723 }
3724
3725 bool DataArrayInt::isEqualWithoutConsideringStrAndOrder(const DataArrayInt& other) const throw(INTERP_KERNEL::Exception)
3726 {
3727   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> a=deepCpy();
3728   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> b=other.deepCpy();
3729   a->sort();
3730   b->sort();
3731   return a->isEqualWithoutConsideringStr(*b);
3732 }
3733
3734 void DataArrayInt::sort(bool asc) throw(INTERP_KERNEL::Exception)
3735 {
3736   checkAllocated();
3737   if(getNumberOfComponents()!=1)
3738     throw INTERP_KERNEL::Exception("DataArrayInt::sort : only supported with 'this' array with ONE component !");
3739   _mem.sort(asc);
3740 }
3741
3742 void DataArrayInt::reverse() throw(INTERP_KERNEL::Exception)
3743 {
3744   checkAllocated();
3745   if(getNumberOfComponents()!=1)
3746     throw INTERP_KERNEL::Exception("DataArrayInt::reverse : only supported with 'this' array with ONE component !");
3747   _mem.reverse();
3748 }
3749
3750 /*!
3751  * This method expects that 'this' and 'other' have the same number of tuples and exactly one component both. If not an exception will be thrown.
3752  * This method retrieves a newly created array with same number of tuples than 'this' and 'other' with one component.
3753  * The returned array 'ret' contains the correspondance from 'this' to 'other' that is to say for every i so that 0<=i<getNumberOfTuples()
3754  * other.getIJ(i,0)==this->getIJ(ret->getIJ(i),0)
3755  * If such permutation is not possible because it exists some elements in 'other' not in 'this', an exception will be thrown.
3756  */
3757 DataArrayInt *DataArrayInt::buildPermutationArr(const DataArrayInt& other) const throw(INTERP_KERNEL::Exception)
3758 {
3759   if(getNumberOfComponents()!=1 || other.getNumberOfComponents()!=1)
3760     throw INTERP_KERNEL::Exception("DataArrayInt::buildPermutationArr : 'this' and 'other' have to have exactly ONE component !");
3761   int nbTuple=getNumberOfTuples();
3762   if(nbTuple!=other.getNumberOfTuples())
3763     throw INTERP_KERNEL::Exception("DataArrayInt::buildPermutationArr : 'this' and 'other' must have the same number of tuple !");
3764   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
3765   ret->alloc(nbTuple,1);
3766   ret->fillWithValue(-1);
3767   const int *pt=getConstPointer();
3768   std::map<int,int> mm;
3769   for(int i=0;i<nbTuple;i++)
3770     mm[pt[i]]=i;
3771   pt=other.getConstPointer();
3772   int *retToFill=ret->getPointer();
3773   for(int i=0;i<nbTuple;i++)
3774     {
3775       std::map<int,int>::const_iterator it=mm.find(pt[i]);
3776       if(it==mm.end())
3777         {
3778           std::ostringstream oss; oss << "DataArrayInt::buildPermutationArr : Arrays mismatch : element (" << pt[i] << ") in 'other' not findable in 'this' !";
3779           throw INTERP_KERNEL::Exception(oss.str().c_str());
3780         }
3781       retToFill[i]=(*it).second;
3782     }
3783   ret->incrRef();
3784   return ret;
3785 }
3786
3787 void DataArrayInt::useArray(const int *array, bool ownership,  DeallocType type, int nbOfTuple, int nbOfCompo)
3788 {
3789   _nb_of_tuples=nbOfTuple;
3790   _info_on_compo.resize(nbOfCompo);
3791   _mem.useArray(array,ownership,type,nbOfTuple*nbOfCompo);
3792   declareAsNew();
3793 }
3794
3795 DataArrayInt *DataArrayInt::fromNoInterlace() const throw(INTERP_KERNEL::Exception)
3796 {
3797   if(_mem.isNull())
3798     throw INTERP_KERNEL::Exception("DataArrayInt::fromNoInterlace : Not defined array !");
3799   int *tab=_mem.fromNoInterlace(getNumberOfComponents());
3800   DataArrayInt *ret=DataArrayInt::New();
3801   ret->useArray(tab,true,CPP_DEALLOC,getNumberOfTuples(),getNumberOfComponents());
3802   return ret;
3803 }
3804
3805 DataArrayInt *DataArrayInt::toNoInterlace() const throw(INTERP_KERNEL::Exception)
3806 {
3807   if(_mem.isNull())
3808     throw INTERP_KERNEL::Exception("DataArrayInt::toNoInterlace : Not defined array !");
3809   int *tab=_mem.toNoInterlace(getNumberOfComponents());
3810   DataArrayInt *ret=DataArrayInt::New();
3811   ret->useArray(tab,true,CPP_DEALLOC,getNumberOfTuples(),getNumberOfComponents());
3812   return ret;
3813 }
3814
3815 void DataArrayInt::renumberInPlace(const int *old2New)
3816 {
3817   int nbTuples=getNumberOfTuples();
3818   int nbOfCompo=getNumberOfComponents();
3819   int *tmp=new int[nbTuples*nbOfCompo];
3820   const int *iptr=getConstPointer();
3821   for(int i=0;i<nbTuples;i++)
3822     std::copy(iptr+nbOfCompo*i,iptr+nbOfCompo*(i+1),tmp+nbOfCompo*old2New[i]);
3823   std::copy(tmp,tmp+nbTuples*nbOfCompo,getPointer());
3824   delete [] tmp;
3825   declareAsNew();
3826 }
3827
3828 void DataArrayInt::renumberInPlaceR(const int *new2Old)
3829 {
3830   int nbTuples=getNumberOfTuples();
3831   int nbOfCompo=getNumberOfComponents();
3832   int *tmp=new int[nbTuples*nbOfCompo];
3833   const int *iptr=getConstPointer();
3834   for(int i=0;i<nbTuples;i++)
3835     std::copy(iptr+nbOfCompo*new2Old[i],iptr+nbOfCompo*(new2Old[i]+1),tmp+nbOfCompo*i);
3836   std::copy(tmp,tmp+nbTuples*nbOfCompo,getPointer());
3837   delete [] tmp;
3838   declareAsNew();
3839 }
3840
3841 /*!
3842  * This method expects that 'this' is allocated, if not an exception is thrown.
3843  * This method in case of success returns a newly created array the user should deal with.
3844  * In the case of having a renumber array in "old to new" format. More info on renumbering \ref MEDCouplingArrayRenumbering "here".
3845  */
3846 DataArrayInt *DataArrayInt::renumber(const int *old2New) const
3847 {
3848   int nbTuples=getNumberOfTuples();
3849   int nbOfCompo=getNumberOfComponents();
3850   DataArrayInt *ret=DataArrayInt::New();
3851   ret->alloc(nbTuples,nbOfCompo);
3852   ret->copyStringInfoFrom(*this);
3853   const int *iptr=getConstPointer();
3854   int *optr=ret->getPointer();
3855   for(int i=0;i<nbTuples;i++)
3856     std::copy(iptr+nbOfCompo*i,iptr+nbOfCompo*(i+1),optr+nbOfCompo*old2New[i]);
3857   ret->copyStringInfoFrom(*this);
3858   return ret;
3859 }
3860
3861 DataArrayInt *DataArrayInt::renumberR(const int *new2Old) const
3862 {
3863   int nbTuples=getNumberOfTuples();
3864   int nbOfCompo=getNumberOfComponents();
3865   DataArrayInt *ret=DataArrayInt::New();
3866   ret->alloc(nbTuples,nbOfCompo);
3867   ret->copyStringInfoFrom(*this);
3868   const int *iptr=getConstPointer();
3869   int *optr=ret->getPointer();
3870   for(int i=0;i<nbTuples;i++)
3871     std::copy(iptr+nbOfCompo*new2Old[i],iptr+nbOfCompo*(new2Old[i]+1),optr+nbOfCompo*i);
3872   ret->copyStringInfoFrom(*this);
3873   return ret;
3874 }
3875
3876 /*!
3877  * Idem DataArrayDouble::renumber method except that the number of tuples is reduced.
3878  * That is to say that it is expected that newNbOfTuple<this->getNumberOfTuples().
3879  * ['old2New','old2New'+getNumberOfTuples()) defines a range containing old to new array. For every negative value in ['old2NewBg','old2New'getNumberOfTuples()) the corresponding tuple is
3880  * omitted.
3881  */
3882 DataArrayInt *DataArrayInt::renumberAndReduce(const int *old2New, int newNbOfTuple) const
3883 {
3884   int nbTuples=getNumberOfTuples();
3885   int nbOfCompo=getNumberOfComponents();
3886   DataArrayInt *ret=DataArrayInt::New();
3887   ret->alloc(newNbOfTuple,nbOfCompo);
3888   const int *iptr=getConstPointer();
3889   int *optr=ret->getPointer();
3890   for(int i=0;i<nbTuples;i++)
3891     {
3892       int w=old2New[i];
3893       if(w>=0)
3894         std::copy(iptr+i*nbOfCompo,iptr+(i+1)*nbOfCompo,optr+w*nbOfCompo);
3895     }
3896   ret->copyStringInfoFrom(*this);
3897   return ret;
3898 }
3899
3900 /*!
3901  * This method is a generalization of DataArrayDouble::substr method because a not contigous range can be specified here.
3902  * This method is equavalent to DataArrayInt::renumberAndReduce except that convention in input is new2old and \b not old2new.
3903  */
3904 DataArrayInt *DataArrayInt::selectByTupleId(const int *new2OldBg, const int *new2OldEnd) const
3905 {
3906   DataArrayInt *ret=DataArrayInt::New();
3907   int nbComp=getNumberOfComponents();
3908   ret->alloc((int)std::distance(new2OldBg,new2OldEnd),nbComp);
3909   ret->copyStringInfoFrom(*this);
3910   int *pt=ret->getPointer();
3911   const int *srcPt=getConstPointer();
3912   int i=0;
3913   for(const int *w=new2OldBg;w!=new2OldEnd;w++,i++)
3914     std::copy(srcPt+(*w)*nbComp,srcPt+((*w)+1)*nbComp,pt+i*nbComp);
3915   ret->copyStringInfoFrom(*this);
3916   return ret;
3917 }
3918
3919 /*!
3920  * This method is equivalent to DataArrayInt::selectByTupleId except that an analyze to the content of input range to check that it will not lead to memory corruption !
3921  */
3922 DataArrayInt *DataArrayInt::selectByTupleIdSafe(const int *new2OldBg, const int *new2OldEnd) const throw(INTERP_KERNEL::Exception)
3923 {
3924   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
3925   int nbComp=getNumberOfComponents();
3926   int oldNbOfTuples=getNumberOfTuples();
3927   ret->alloc((int)std::distance(new2OldBg,new2OldEnd),nbComp);
3928   ret->copyStringInfoFrom(*this);
3929   int *pt=ret->getPointer();
3930   const int *srcPt=getConstPointer();
3931   int i=0;
3932   for(const int *w=new2OldBg;w!=new2OldEnd;w++,i++)
3933     if(*w>=0 && *w<oldNbOfTuples)
3934       std::copy(srcPt+(*w)*nbComp,srcPt+((*w)+1)*nbComp,pt+i*nbComp);
3935     else
3936       throw INTERP_KERNEL::Exception("DataArrayInt::selectByTupleIdSafe : some ids has been detected to be out of [0,this->getNumberOfTuples) !");
3937   ret->copyStringInfoFrom(*this);
3938   ret->incrRef();
3939   return ret;
3940 }
3941
3942 /*!
3943  * Idem than DataArrayInt::selectByTupleIdSafe except that the input array is not constructed explicitely.
3944  * The convention is as python one. ['bg','end2') with steps of 'step'.
3945  * Returns a newly created array.
3946  * This method is an extension of DataArrayInt::substr method.
3947  * 
3948  * \sa DataArrayInt::substr
3949  */
3950 DataArrayInt *DataArrayInt::selectByTupleId2(int bg, int end2, int step) const throw(INTERP_KERNEL::Exception)
3951 {
3952   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
3953   int nbComp=getNumberOfComponents();
3954   int newNbOfTuples=GetNumberOfItemGivenBES(bg,end2,step,"DataArrayInt::selectByTupleId2 : ");
3955   ret->alloc(newNbOfTuples,nbComp);
3956   int *pt=ret->getPointer();
3957   const int *srcPt=getConstPointer()+bg*nbComp;
3958   for(int i=0;i<newNbOfTuples;i++,srcPt+=step*nbComp)
3959     std::copy(srcPt,srcPt+nbComp,pt+i*nbComp);
3960   ret->copyStringInfoFrom(*this);
3961   ret->incrRef();
3962   return ret;
3963 }
3964
3965 /*!
3966  * This method returns a newly allocated array that is the concatenation of all tuples ranges in param 'ranges'.
3967  * Each pair in input 'ranges' is in [begin,end) format. If there is a range in 'ranges' so that end is before begin an exception
3968  * will be thrown. If there is a range in 'ranges' so that end is greater than number of tuples of 'this', an exception will be thrown too.
3969  */
3970 DataArrayInt *DataArrayInt::selectByTupleRanges(const std::vector<std::pair<int,int> >& ranges) const throw(INTERP_KERNEL::Exception)
3971 {
3972   checkAllocated();
3973   int nbOfComp=getNumberOfComponents();
3974   int nbOfTuplesThis=getNumberOfTuples();
3975   if(ranges.empty())
3976     {
3977       DataArrayInt *ret=DataArrayInt::New();
3978       ret->alloc(0,nbOfComp);
3979       ret->copyStringInfoFrom(*this);
3980       return ret;
3981     }
3982   int ref=ranges.front().first;
3983   int nbOfTuples=0;
3984   bool isIncreasing=true;
3985   for(std::vector<std::pair<int,int> >::const_iterator it=ranges.begin();it!=ranges.end();it++)
3986     {
3987       if((*it).first<=(*it).second)
3988         {
3989           if((*it).first>=0 && (*it).second<=nbOfTuplesThis)
3990             {
3991               nbOfTuples+=(*it).second-(*it).first;
3992               if(isIncreasing)
3993                 isIncreasing=ref<=(*it).first;
3994               ref=(*it).second;
3995             }
3996           else
3997             {
3998               std::ostringstream oss; oss << "DataArrayInt::selectByTupleRanges : on range #" << std::distance(ranges.begin(),it);
3999               oss << " (" << (*it).first << "," << (*it).second << ") is greater than number of tuples of this :" << nbOfTuples << " !";
4000               throw INTERP_KERNEL::Exception(oss.str().c_str());
4001             }
4002         }
4003       else
4004         {
4005           std::ostringstream oss; oss << "DataArrayInt::selectByTupleRanges : on range #" << std::distance(ranges.begin(),it);
4006           oss << " (" << (*it).first << "," << (*it).second << ") end is before begin !";
4007           throw INTERP_KERNEL::Exception(oss.str().c_str());
4008         }
4009     }
4010   if(isIncreasing && nbOfTuplesThis==nbOfTuples)
4011     return deepCpy();
4012   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
4013   ret->alloc(nbOfTuples,nbOfComp);
4014   ret->copyStringInfoFrom(*this);
4015   const int *src=getConstPointer();
4016   int *work=ret->getPointer();
4017   for(std::vector<std::pair<int,int> >::const_iterator it=ranges.begin();it!=ranges.end();it++)
4018     work=std::copy(src+(*it).first*nbOfComp,src+(*it).second*nbOfComp,work);
4019   ret->incrRef();
4020   return ret;
4021 }
4022
4023 /*!
4024  * This method works only for arrays having single component.
4025  * If this contains the array a1 containing [9,10,0,6,4,11,3,7] this method returns an array a2 [5,6,0,3,2,7,1,4].
4026  * By doing a1.renumber(a2) the user will obtain array a3 equal to a1 sorted.
4027  * This method is useful for renumbering (in MED file for example). This method is used by MEDCouplingFieldDouble::renumberCells when check is set to true.
4028  * This method throws an exception if more 2 or more elements in 'this' are same.
4029  */
4030 DataArrayInt *DataArrayInt::checkAndPreparePermutation() const throw(INTERP_KERNEL::Exception)
4031 {
4032   checkAllocated();
4033   if(getNumberOfComponents()!=1)
4034     throw INTERP_KERNEL::Exception("DataArrayInt::checkAndPreparePermutation : number of components must == 1 !");
4035   int nbTuples=getNumberOfTuples();
4036   const int *pt=getConstPointer();
4037   int *pt2=CheckAndPreparePermutation(pt,pt+nbTuples);
4038   DataArrayInt *ret=DataArrayInt::New();
4039   ret->useArray(pt2,true,CPP_DEALLOC,nbTuples,1);
4040   return ret;
4041 }
4042
4043 /*!
4044  * This method makes the assumption that 'this' is correctly set, and has exactly one component. If not an exception will be thrown.
4045  * Given a sujective application defined by 'this' from a set of size this->getNumberOfTuples() to a set of size targetNb.
4046  * 'targetNb'<this->getNumberOfTuples(). 'this' should be surjective that is to say for each id in [0,'targetNb') it exists at least one tupleId tid
4047  * so that this->getIJ(tid,0)==id.
4048  * If not an exception will be thrown.
4049  * This method returns 2 newly allocated arrays 'arr' and 'arrI', corresponding respectively to array and its corresponding index.
4050  * This method is usefull for methods that returns old2New numbering concecutive to a reduction ( MEDCouplingUMesh::zipConnectivityTraducer, MEDCouplingUMesh::zipConnectivityTraducer for example)
4051  * Example : if 'this' equals [0,3,2,3,2,2,1,2] this method will return arrI=[0,1,2,6,8] arr=[0,  6,  2,4,5,7,  1,3]
4052  * That is to say elt id 2 has arrI[2+1]-arrI[2]=4 places in 'this'. The corresponding tuple ids are [2,4,5,7].
4053  */
4054 void DataArrayInt::changeSurjectiveFormat(int targetNb, DataArrayInt *&arr, DataArrayInt *&arrI) const throw(INTERP_KERNEL::Exception)
4055 {
4056   checkAllocated();
4057   if(getNumberOfComponents()!=1)
4058     throw INTERP_KERNEL::Exception("DataArrayInt::changeSurjectiveFormat : number of components must == 1 !");
4059   int nbOfTuples=getNumberOfTuples();
4060   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New());
4061   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> retI(DataArrayInt::New());
4062   retI->alloc(targetNb+1,1);
4063   const int *input=getConstPointer();
4064   std::vector< std::vector<int> > tmp(targetNb);
4065   for(int i=0;i<nbOfTuples;i++)
4066     {
4067       int tmp2=input[i];
4068       if(tmp2<targetNb)
4069         tmp[tmp2].push_back(i);
4070       else
4071         {
4072           std::ostringstream oss; oss << "DataArrayInt::changeSurjectiveFormat : At pos " << i << " presence of element " << tmp2 << " higher than " << targetNb;
4073           throw INTERP_KERNEL::Exception(oss.str().c_str());
4074         }
4075     }
4076   int *retIPtr=retI->getPointer();
4077   *retIPtr=0;
4078   for(std::vector< std::vector<int> >::const_iterator it1=tmp.begin();it1!=tmp.end();it1++,retIPtr++)
4079     retIPtr[1]=retIPtr[0]+(int)((*it1).size());
4080   if(nbOfTuples!=retI->getIJ(targetNb,0))
4081     throw INTERP_KERNEL::Exception("DataArrayInt::changeSurjectiveFormat : big problem should never happen !");
4082   ret->alloc(nbOfTuples,1);
4083   int *retPtr=ret->getPointer();
4084   for(std::vector< std::vector<int> >::const_iterator it1=tmp.begin();it1!=tmp.end();it1++)
4085     retPtr=std::copy((*it1).begin(),(*it1).end(),retPtr);
4086   ret->incrRef();
4087   retI->incrRef();
4088   arr=ret;
4089   arrI=retI;
4090 }
4091
4092 /*!
4093  * This static method computes a old 2 new format DataArrayInt instance from a zip representation of a surjective format (retrived by DataArrayDouble::findCommonTuples for example)
4094  * The retrieved array minimizes the permutation.
4095  * Let's take an example : 
4096  * If 'nbOfOldTuples'==10 and 'arr'==[0,3, 5,7,9] and 'arrI'==[0,2,5] it returns the following array [0,1,2,0,3,4,5,4,6,4] and newNbOfTuples==7.
4097  *
4098  * @param nbOfOldTuples is the number of tuples in initial array.
4099  * @param arr is the list of tuples ids grouped by 'arrI' array
4100  * @param arrI is the entry point of 'arr' array. arrI->getNumberOfTuples()-1 is the number of common groups > 1 tuple.
4101  * @param newNbOfTuples output parameter that retrieves the new number of tuples after surjection application
4102  */
4103 DataArrayInt *DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2(int nbOfOldTuples, const DataArrayInt *arr, const DataArrayInt *arrI, int &newNbOfTuples) throw(INTERP_KERNEL::Exception)
4104 {
4105   if(!arr || !arrI)
4106     throw INTERP_KERNEL::Exception("DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2 : presence of NULL ref of DataArrayInt in input !");
4107   DataArrayInt *ret=DataArrayInt::New();
4108   ret->alloc(nbOfOldTuples,1);
4109   int *pt=ret->getPointer();
4110   std::fill(pt,pt+nbOfOldTuples,-1);
4111   int nbOfGrps=arrI->getNumberOfTuples()-1;
4112   const int *cIPtr=arrI->getConstPointer();
4113   const int *cPtr=arr->getConstPointer();
4114   for(int i=0;i<nbOfGrps;i++)
4115     pt[cPtr[cIPtr[i]]]=-(i+2);
4116   int newNb=0;
4117   for(int iNode=0;iNode<nbOfOldTuples;iNode++)
4118     {
4119       if(pt[iNode]<0)
4120         {
4121           if(pt[iNode]==-1)
4122             pt[iNode]=newNb++;
4123           else
4124             {
4125               int grpId=-(pt[iNode]+2);
4126               for(int j=cIPtr[grpId];j<cIPtr[grpId+1];j++)
4127                 pt[cPtr[j]]=newNb;
4128               newNb++;
4129             }
4130         }
4131     }
4132   newNbOfTuples=newNb;
4133   return ret;
4134 }
4135
4136 /*!
4137  * This method expects that 'this' is allocated and with only one component. If not an exception will be thrown.
4138  * This method returns a newly created array with 'this->getNumberOfTuples()' tuples and 1 component.
4139  * This methods returns an 'old2New' corresponding array that allows to follow the following rules :
4140  * - Lower a value in tuple in 'this' is, higher is its priority.
4141  * - If two tuples i and j have same value if i<j then ret[i]<ret[j]
4142  * - The first tuple with the lowest value will have the value 0, inversely the last tuple with highest value will have value 'this->getNumberOfTuples()-1'
4143  * 
4144  * Example if 'this' contains the following array : [2,0,1,1,0,1,2,0,1,1,0,0] this method returns [10,0,5,6,1,7,11,2,8,9,3,4]
4145  */
4146 DataArrayInt *DataArrayInt::buildPermArrPerLevel() const throw(INTERP_KERNEL::Exception)
4147 {
4148   checkAllocated();
4149   if(getNumberOfComponents()!=1)
4150     throw INTERP_KERNEL::Exception("DataArrayInt::buildPermArrPerLevel : number of components must == 1 !");
4151   int nbOfTuples=getNumberOfTuples();
4152   const int *pt=getConstPointer();
4153   std::map<int,int> m;
4154   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
4155   ret->alloc(nbOfTuples,1);
4156   int *opt=ret->getPointer();
4157   for(int i=0;i<nbOfTuples;i++,pt++,opt++)
4158     {
4159       int val=*pt;
4160       std::map<int,int>::iterator it=m.find(val);
4161       if(it!=m.end())
4162         {
4163           *opt=(*it).second;
4164           (*it).second++;
4165         }
4166       else
4167         {
4168           *opt=0;
4169           m.insert(std::pair<int,int>(val,1));
4170         }
4171     }
4172   int sum=0;
4173   for(std::map<int,int>::iterator it=m.begin();it!=m.end();it++)
4174     {
4175       int vt=(*it).second;
4176       (*it).second=sum;
4177       sum+=vt;
4178     }
4179   pt=getConstPointer();
4180   opt=ret->getPointer();
4181   for(int i=0;i<nbOfTuples;i++,pt++,opt++)
4182     *opt+=m[*pt];
4183   //
4184   ret->incrRef();
4185   return ret;
4186 }
4187
4188 /*!
4189  * This method checks that 'this' is with numberofcomponents == 1 and that it is equal to
4190  * stdext::iota() of size getNumberOfTuples. This method is particalary usefull for DataArrayInt instances
4191  * that represents a renumbering array to check the real need in renumbering. 
4192  */
4193 bool DataArrayInt::isIdentity() const throw(INTERP_KERNEL::Exception)
4194 {
4195   checkAllocated();
4196   if(getNumberOfComponents()!=1)
4197     return false;
4198   int nbOfTuples=getNumberOfTuples();
4199   const int *pt=getConstPointer();
4200   for(int i=0;i<nbOfTuples;i++,pt++)
4201     if(*pt!=i)
4202       return false;
4203   return true;
4204 }
4205
4206 bool DataArrayInt::isUniform(int val) const throw(INTERP_KERNEL::Exception)
4207 {
4208   checkAllocated();
4209   if(getNumberOfComponents()!=1)
4210     throw INTERP_KERNEL::Exception("DataArrayInt::isUniform : must be applied on DataArrayInt with only one component, you can call 'rearrange' method before !");
4211   int nbOfTuples=getNumberOfTuples();
4212   const int *w=getConstPointer();
4213   const int *end2=w+nbOfTuples;
4214   for(;w!=end2;w++)
4215     if(*w!=val)
4216       return false;
4217   return true;
4218 }
4219
4220 DataArrayDouble *DataArrayInt::convertToDblArr() const
4221 {
4222   checkAllocated();
4223   DataArrayDouble *ret=DataArrayDouble::New();
4224   ret->alloc(getNumberOfTuples(),getNumberOfComponents());
4225   int nbOfVals=getNbOfElems();
4226   const int *src=getConstPointer();
4227   double *dest=ret->getPointer();
4228   std::copy(src,src+nbOfVals,dest);
4229   ret->copyStringInfoFrom(*this);
4230   return ret;
4231 }
4232
4233 /*!
4234  * This methods has a similar behaviour than std::string::substr. This method returns a newly created DataArrayInt that is part of this with same number of components.
4235  * The intervall is specified by [tupleIdBg,tupleIdEnd) except if tupleIdEnd ==-1 in this case the [tupleIdBg,this->end()) will be kept.
4236  * This method check that interval is valid regarding this, if not an exception will be thrown.
4237  * This method is a specialization of method DataArrayInt::selectByTupleId2.
4238  *
4239  * \sa DataArrayInt::selectByTupleId2
4240  */
4241 DataArrayInt *DataArrayInt::substr(int tupleIdBg, int tupleIdEnd) const throw(INTERP_KERNEL::Exception)
4242 {
4243   int nbt=getNumberOfTuples();
4244   if(tupleIdBg<0)
4245     throw INTERP_KERNEL::Exception("DataArrayInt::substr : The tupleIdBg parameter must be greater than 0 !");
4246   if(tupleIdBg>nbt)
4247     throw INTERP_KERNEL::Exception("DataArrayInt::substr : The tupleIdBg parameter is greater than number of tuples !");
4248   int trueEnd=tupleIdEnd;
4249   if(tupleIdEnd!=-1)
4250     {
4251       if(tupleIdEnd>nbt)
4252         throw INTERP_KERNEL::Exception("DataArrayInt::substr : The tupleIdBg parameter is greater or equal than number of tuples !");
4253     }
4254   else
4255     trueEnd=nbt;
4256   int nbComp=getNumberOfComponents();
4257   DataArrayInt *ret=DataArrayInt::New();
4258   ret->alloc(trueEnd-tupleIdBg,nbComp);
4259   ret->copyStringInfoFrom(*this);
4260   std::copy(getConstPointer()+tupleIdBg*nbComp,getConstPointer()+trueEnd*nbComp,ret->getPointer());
4261   return ret;
4262 }
4263
4264 /*!
4265  * Contrary to DataArrayInt::changeNbOfComponents method this method is \b not const. The content 
4266  * This method \b do \b not change the content of data but changes the splitting of this data seen by the caller.
4267  * This method makes the assumption that 'this' is already allocated. If not an exception will be thrown.
4268  * This method checks that getNbOfElems()%newNbOfCompo==0. If not an exception will be throw !
4269  * This method erases all components info set before call !
4270  */
4271 void DataArrayInt::rearrange(int newNbOfCompo) throw(INTERP_KERNEL::Exception)
4272 {
4273   checkAllocated();
4274   int nbOfElems=getNbOfElems();
4275   if(nbOfElems%newNbOfCompo!=0)
4276     throw INTERP_KERNEL::Exception("DataArrayInt::rearrange : nbOfElems%newNbOfCompo!=0 !");
4277   _nb_of_tuples=nbOfElems/newNbOfCompo;
4278   _info_on_compo.clear();
4279   _info_on_compo.resize(newNbOfCompo);
4280   declareAsNew();
4281 }
4282
4283 /*!
4284  * This method makes the assumption that \b this is allocated. If not an INTERP_KERNEL::Exception will be raised.
4285  * This method does not echange the values stored in \b this. Simply, the number of components before the call becomes the number of
4286  * tuples and inversely the number of tuples becomes the number of components. \b WARNING the info on components can be alterated by this method.
4287  */
4288 void DataArrayInt::transpose() throw(INTERP_KERNEL::Exception)
4289 {
4290   checkAllocated();
4291   int nbOfTuples=getNumberOfTuples();
4292   rearrange(nbOfTuples);
4293 }
4294
4295 /*!
4296  * This method builds a new instance of DataArrayInt (to deal with) that is reduction or an extension of 'this'.
4297  * if 'newNbOfComp' < this->getNumberOfComponents() a reduction is done and for each tuple 'newNbOfComp' first components are kept.
4298  * If 'newNbOfComp' > this->getNumberOfComponents() an extension is done, and for each components i such that i > getNumberOfComponents() 'dftValue' parameter is taken.
4299  */
4300 DataArrayInt *DataArrayInt::changeNbOfComponents(int newNbOfComp, int dftValue) const throw(INTERP_KERNEL::Exception)
4301 {
4302   checkAllocated();
4303   DataArrayInt *ret=DataArrayInt::New();
4304   ret->alloc(getNumberOfTuples(),newNbOfComp);
4305   const int *oldc=getConstPointer();
4306   int *nc=ret->getPointer();
4307   int nbOfTuples=getNumberOfTuples();
4308   int oldNbOfComp=getNumberOfComponents();
4309   int dim=std::min(oldNbOfComp,newNbOfComp);
4310   for(int i=0;i<nbOfTuples;i++)
4311     {
4312       int j=0;
4313       for(;j<dim;j++)
4314         nc[newNbOfComp*i+j]=oldc[i*oldNbOfComp+j];
4315       for(;j<newNbOfComp;j++)
4316         nc[newNbOfComp*i+j]=dftValue;
4317     }
4318   ret->setName(getName().c_str());
4319   for(int i=0;i<dim;i++)
4320     ret->setInfoOnComponent(i,getInfoOnComponent(i).c_str());
4321   ret->setName(getName().c_str());
4322   return ret;
4323 }
4324
4325 void DataArrayInt::reAlloc(int nbOfTuples) throw(INTERP_KERNEL::Exception)
4326 {
4327   checkAllocated();
4328   _mem.reAlloc((int)_info_on_compo.size()*nbOfTuples);
4329   _nb_of_tuples=nbOfTuples;
4330   declareAsNew();
4331 }
4332
4333 DataArrayInt *DataArrayInt::keepSelectedComponents(const std::vector<int>& compoIds) const throw(INTERP_KERNEL::Exception)
4334 {
4335   checkAllocated();
4336   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New());
4337   int newNbOfCompo=(int)compoIds.size();
4338   int oldNbOfCompo=getNumberOfComponents();
4339   for(std::vector<int>::const_iterator it=compoIds.begin();it!=compoIds.end();it++)
4340     DataArray::CheckValueInRange(oldNbOfCompo,(*it),"keepSelectedComponents invalid requested component");
4341   int nbOfTuples=getNumberOfTuples();
4342   ret->alloc(nbOfTuples,newNbOfCompo);
4343   ret->copyPartOfStringInfoFrom(*this,compoIds);
4344   const int *oldc=getConstPointer();
4345   int *nc=ret->getPointer();
4346   for(int i=0;i<nbOfTuples;i++)
4347     for(int j=0;j<newNbOfCompo;j++,nc++)
4348       *nc=oldc[i*oldNbOfCompo+compoIds[j]];
4349   ret->incrRef();
4350   return ret;
4351 }
4352
4353 /*!
4354  * This method melds the components of 'this' with components of 'other'.
4355  * After this call in case of success, 'this' will contain a number of components equal to the sum of 'this'
4356  * before the call and the number of components of 'other'.
4357  * This method expects that 'this' and 'other' have exactly the same number of tuples. If not an exception is thrown.
4358  */
4359 void DataArrayInt::meldWith(const DataArrayInt *other) throw(INTERP_KERNEL::Exception)
4360 {
4361   if(!other)
4362     throw INTERP_KERNEL::Exception("DataArrayInt::meldWith : DataArrayInt pointer in input is NULL !");
4363   checkAllocated();
4364   other->checkAllocated();
4365   int nbOfTuples=getNumberOfTuples();
4366   if(nbOfTuples!=other->getNumberOfTuples())
4367     throw INTERP_KERNEL::Exception("DataArrayInt::meldWith : mismatch of number of tuples !");
4368   int nbOfComp1=getNumberOfComponents();
4369   int nbOfComp2=other->getNumberOfComponents();
4370   int *newArr=new int[nbOfTuples*(nbOfComp1+nbOfComp2)];
4371   int *w=newArr;
4372   const int *inp1=getConstPointer();
4373   const int *inp2=other->getConstPointer();
4374   for(int i=0;i<nbOfTuples;i++,inp1+=nbOfComp1,inp2+=nbOfComp2)
4375     {
4376       w=std::copy(inp1,inp1+nbOfComp1,w);
4377       w=std::copy(inp2,inp2+nbOfComp2,w);
4378     }
4379   useArray(newArr,true,CPP_DEALLOC,nbOfTuples,nbOfComp1+nbOfComp2);
4380   std::vector<int> compIds(nbOfComp2);
4381   for(int i=0;i<nbOfComp2;i++)
4382     compIds[i]=nbOfComp1+i;
4383   copyPartOfStringInfoFrom2(compIds,*other);
4384 }
4385
4386 void DataArrayInt::setSelectedComponents(const DataArrayInt *a, const std::vector<int>& compoIds) throw(INTERP_KERNEL::Exception)
4387 {
4388   copyPartOfStringInfoFrom2(compoIds,*a);
4389   std::size_t partOfCompoSz=compoIds.size();
4390   int nbOfCompo=getNumberOfComponents();
4391   int nbOfTuples=getNumberOfTuples();
4392   const int *ac=a->getConstPointer();
4393   int *nc=getPointer();
4394   for(int i=0;i<nbOfTuples;i++)
4395     for(std::size_t j=0;j<partOfCompoSz;j++,ac++)
4396       nc[nbOfCompo*i+compoIds[j]]=*ac;
4397 }
4398
4399 /*!
4400  * This method performs a partial assignment of 'this' using 'a' as input. Other input parameters specifies the subpart being considered by the assignment.
4401  * 'strictCompoCompare' specifies if DataArray 'a' should have exactly same number of components and tuples than 'this' (true) or not (false). By default set to true with maximal test.
4402  */
4403 void DataArrayInt::setPartOfValues1(const DataArrayInt *a, int bgTuples, int endTuples, int stepTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare) throw(INTERP_KERNEL::Exception)
4404 {
4405   if(!a)
4406     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValues1 : DataArrayInt pointer in input is NULL !");
4407   const char msg[]="DataArrayInt::setPartOfValues1";
4408   checkAllocated();
4409   a->checkAllocated();
4410   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
4411   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
4412   int nbComp=getNumberOfComponents();
4413   int nbOfTuples=getNumberOfTuples();
4414   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
4415   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
4416   a->checkNbOfElems(newNbOfTuples*newNbOfComp,msg);
4417   if(strictCompoCompare)
4418     a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
4419   int *pt=getPointer()+bgTuples*nbComp+bgComp;
4420   const int *srcPt=a->getConstPointer();
4421   for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
4422     for(int j=0;j<newNbOfComp;j++,srcPt++)
4423       pt[j*stepComp]=*srcPt;
4424 }
4425
4426 /*!
4427  * This method performs a partial assignment of 'this' using 'a' as input. Other input parameters specifies the subpart being considered by the assignment.
4428  */
4429 void DataArrayInt::setPartOfValuesSimple1(int a, int bgTuples, int endTuples, int stepTuples, int bgComp, int endComp, int stepComp) throw(INTERP_KERNEL::Exception)
4430 {
4431   const char msg[]="DataArrayInt::setPartOfValuesSimple1";
4432   checkAllocated();
4433   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
4434   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
4435   int nbComp=getNumberOfComponents();
4436   int nbOfTuples=getNumberOfTuples();
4437   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
4438   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
4439   int *pt=getPointer()+bgTuples*nbComp+bgComp;
4440   for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
4441     for(int j=0;j<newNbOfComp;j++)
4442       pt[j*stepComp]=a;
4443 }
4444
4445 /*!
4446  * This method performs a partial assignment of 'this' using 'a' as input. Other input parameters specifies the subpart being considered by the assignment.
4447  * 'strictCompoCompare' specifies if DataArray 'a' should have exactly same number of components and tuples than 'this' (true) or not (false). By default set to true with maximal test.
4448  */
4449 void DataArrayInt::setPartOfValues2(const DataArrayInt *a, const int *bgTuples, const int *endTuples, const int *bgComp, const int *endComp, bool strictCompoCompare) throw(INTERP_KERNEL::Exception)
4450 {
4451   if(!a)
4452     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValues2 : DataArrayInt pointer in input is NULL !");
4453   const char msg[]="DataArrayInt::setPartOfValues2";
4454   checkAllocated();
4455   a->checkAllocated();
4456   int nbComp=getNumberOfComponents();
4457   int nbOfTuples=getNumberOfTuples();
4458   for(const int *z=bgComp;z!=endComp;z++)
4459     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
4460   int newNbOfTuples=(int)std::distance(bgTuples,endTuples);
4461   int newNbOfComp=(int)std::distance(bgComp,endComp);
4462   bool assignTech=true;
4463   if(a->getNbOfElems()==newNbOfTuples*newNbOfComp)
4464     {
4465       if(strictCompoCompare)
4466         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
4467     }
4468   else
4469     {
4470       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
4471       assignTech=false;
4472     }
4473   int *pt=getPointer();
4474   const int *srcPt=a->getConstPointer();
4475   if(assignTech)
4476     {    
4477       for(const int *w=bgTuples;w!=endTuples;w++)
4478         {
4479           DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
4480           for(const int *z=bgComp;z!=endComp;z++,srcPt++)
4481             {    
4482               pt[(*w)*nbComp+(*z)]=*srcPt;
4483             }
4484         }
4485     }
4486   else
4487     {
4488       for(const int *w=bgTuples;w!=endTuples;w++)
4489         {
4490           const int *srcPt2=srcPt;
4491           DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
4492           for(const int *z=bgComp;z!=endComp;z++,srcPt2++)
4493             {    
4494               pt[(*w)*nbComp+(*z)]=*srcPt2;
4495             }
4496         }
4497     }
4498 }
4499
4500 /*!
4501  * This method performs a partial assignment of 'this' using 'a' as input. Other input parameters specifies the subpart being considered by the assignment.
4502  */
4503 void DataArrayInt::setPartOfValuesSimple2(int a, const int *bgTuples, const int *endTuples, const int *bgComp, const int *endComp) throw(INTERP_KERNEL::Exception)
4504 {
4505   checkAllocated();
4506   int nbComp=getNumberOfComponents();
4507   int nbOfTuples=getNumberOfTuples();
4508   for(const int *z=bgComp;z!=endComp;z++)
4509     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
4510   int *pt=getPointer();
4511   for(const int *w=bgTuples;w!=endTuples;w++)
4512     for(const int *z=bgComp;z!=endComp;z++)
4513       {
4514         DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
4515         pt[(*w)*nbComp+(*z)]=a;
4516       }
4517 }
4518
4519 /*!
4520  * This method performs a partial assignment of 'this' using 'a' as input. Other input parameters specifies the subpart being considered by the assignment.
4521  * 'strictCompoCompare' specifies if DataArray 'a' should have exactly same number of components and tuples than 'this' (true) or not (false). By default set to true with maximal test.
4522  */
4523 void DataArrayInt::setPartOfValues3(const DataArrayInt *a, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare) throw(INTERP_KERNEL::Exception)
4524 {
4525   if(!a)
4526     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValues3 : DataArrayInt pointer in input is NULL !");
4527   const char msg[]="DataArrayInt::setPartOfValues3";
4528   checkAllocated();
4529   a->checkAllocated();
4530   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
4531   int nbComp=getNumberOfComponents();
4532   int nbOfTuples=getNumberOfTuples();
4533   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
4534   int newNbOfTuples=(int)std::distance(bgTuples,endTuples);
4535   bool assignTech=true;
4536   if(a->getNbOfElems()==newNbOfTuples*newNbOfComp)
4537     {
4538       if(strictCompoCompare)
4539         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
4540     }
4541   else
4542     {
4543       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
4544       assignTech=false;
4545     }
4546   int *pt=getPointer()+bgComp;
4547   const int *srcPt=a->getConstPointer();
4548   if(assignTech)
4549     {
4550       for(const int *w=bgTuples;w!=endTuples;w++)
4551         for(int j=0;j<newNbOfComp;j++,srcPt++)
4552           {
4553             DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
4554             pt[(*w)*nbComp+j*stepComp]=*srcPt;
4555           }
4556     }
4557   else
4558     {
4559       for(const int *w=bgTuples;w!=endTuples;w++)
4560         {
4561           const int *srcPt2=srcPt;
4562           for(int j=0;j<newNbOfComp;j++,srcPt2++)
4563             {
4564               DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
4565               pt[(*w)*nbComp+j*stepComp]=*srcPt2;
4566             }
4567         }
4568     }
4569 }
4570
4571 /*!
4572  * This method performs a partial assignment of 'this' using 'a' as input. Other input parameters specifies the subpart being considered by the assignment.
4573  */
4574 void DataArrayInt::setPartOfValuesSimple3(int a, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp) throw(INTERP_KERNEL::Exception)
4575 {
4576   const char msg[]="DataArrayInt::setPartOfValuesSimple3";
4577   checkAllocated();
4578   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
4579   int nbComp=getNumberOfComponents();
4580   int nbOfTuples=getNumberOfTuples();
4581   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
4582   int *pt=getPointer()+bgComp;
4583   for(const int *w=bgTuples;w!=endTuples;w++)
4584     for(int j=0;j<newNbOfComp;j++)
4585       {
4586         DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
4587         pt[(*w)*nbComp+j*stepComp]=a;
4588       }
4589 }
4590
4591 /*!
4592  * 'this', 'a' and 'tuplesSelec' are expected to be defined. If not an exception will be thrown.
4593  * @param a is an array having exactly the same number of components than 'this'
4594  * @param tuplesSelec is an array having exactly 2 components. The first one refers to the tuple ids of 'this' that will be set. The second one refers to the tuple ids of 'a' that will be used for setting.
4595  */
4596 void DataArrayInt::setPartOfValuesAdv(const DataArrayInt *a, const DataArrayInt *tuplesSelec) throw(INTERP_KERNEL::Exception)
4597 {
4598   if(!a)
4599     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValuesAdv : DataArrayInt pointer in input is NULL !");
4600   checkAllocated();
4601   a->checkAllocated();
4602   tuplesSelec->checkAllocated();
4603   int nbOfComp=getNumberOfComponents();
4604   if(nbOfComp!=a->getNumberOfComponents())
4605     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValuesAdv : This and a do not have the same number of components !");
4606   if(tuplesSelec->getNumberOfComponents()!=2)
4607     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValuesAdv : Expecting to have a tuple selector DataArrayInt instance with exactly 2 components !");
4608   int thisNt=getNumberOfTuples();
4609   int aNt=a->getNumberOfTuples();
4610   int *valsToSet=getPointer();
4611   const int *valsSrc=a->getConstPointer();
4612   for(const int *tuple=tuplesSelec->begin();tuple!=tuplesSelec->end();tuple+=2)
4613     {
4614       if(tuple[1]>=0 && tuple[1]<aNt)
4615         {
4616           if(tuple[0]>=0 && tuple[0]<thisNt)
4617             std::copy(valsSrc+nbOfComp*tuple[1],valsSrc+nbOfComp*(tuple[1]+1),valsToSet+nbOfComp*tuple[0]);
4618           else
4619             {
4620               std::ostringstream oss; oss << "DataArrayInt::setPartOfValuesAdv : Tuple #" << std::distance(tuplesSelec->begin(),tuple)/2;
4621               oss << " of 'tuplesSelec' request of tuple id #" << tuple[0] << " in 'this' ! It should be in [0," << thisNt << ") !";
4622               throw INTERP_KERNEL::Exception(oss.str().c_str());
4623             }
4624         }
4625       else
4626         {
4627           std::ostringstream oss; oss << "DataArrayInt::setPartOfValuesAdv : Tuple #" << std::distance(tuplesSelec->begin(),tuple)/2;
4628           oss << " of 'tuplesSelec' request of tuple id #" << tuple[1] << " in 'a' ! It should be in [0," << aNt << ") !";
4629           throw INTERP_KERNEL::Exception(oss.str().c_str());
4630         }
4631     }
4632 }
4633
4634 /*!
4635  * 'this', 'a' and 'tuplesSelec' are expected to be defined. If not an exception will be thrown.
4636  * This is a method that is a specialization to DataArrayInt::setPartOfValuesAdv method, except that here the tuple selection of 'a' is given by a range ('bg','end2' and 'step')
4637  * rather than an explicite array of tuple ids (given by the 2nd component) and the feeding is done in 'this' contiguously starting from 'tupleIdStart'.
4638  * @param a is an array having exactly the same number of components than 'this'
4639  */
4640 void DataArrayInt::setContigPartOfSelectedValues(int tupleIdStart, const DataArrayInt*a, const DataArrayInt *tuplesSelec) throw(INTERP_KERNEL::Exception)
4641 {
4642   checkAllocated();
4643   a->checkAllocated();
4644   tuplesSelec->checkAllocated();
4645   int nbOfComp=getNumberOfComponents();
4646   if(nbOfComp!=a->getNumberOfComponents())
4647     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues : This and a do not have the same number of components !");
4648   if(tuplesSelec->getNumberOfComponents()!=1)
4649     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues : Expecting to have a tuple selector DataArrayInt instance with exactly 1 component !");
4650   int thisNt=getNumberOfTuples();
4651   int aNt=a->getNumberOfTuples();
4652   int nbOfTupleToWrite=tuplesSelec->getNumberOfTuples();
4653   int *valsToSet=getPointer()+tupleIdStart*nbOfComp;
4654   if(tupleIdStart+nbOfTupleToWrite>thisNt)
4655     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues : invalid number range of values to write !");
4656   const int *valsSrc=a->getConstPointer();
4657   for(const int *tuple=tuplesSelec->begin();tuple!=tuplesSelec->end();tuple++,valsToSet+=nbOfComp)
4658     {
4659       if(*tuple>=0 && *tuple<aNt)
4660         {
4661           std::copy(valsSrc+nbOfComp*(*tuple),valsSrc+nbOfComp*(*tuple+1),valsToSet);
4662         }
4663       else
4664         {
4665           std::ostringstream oss; oss << "DataArrayInt::setContigPartOfSelectedValues : Tuple #" << std::distance(tuplesSelec->begin(),tuple);
4666           oss << " of 'tuplesSelec' request of tuple id #" << *tuple << " in 'a' ! It should be in [0," << aNt << ") !";
4667           throw INTERP_KERNEL::Exception(oss.str().c_str());
4668         }
4669     }
4670 }
4671
4672 /*!
4673  * 'this' and 'a' are expected to be defined. If not an exception will be thrown.
4674  * This is a method that is a specialization to DataArrayInt::setContigPartOfSelectedValues method, except that here the tuple selection is givenin a is done by a range ('bg','end2' and 'step')
4675  * rather than an explicite array of tuple ids.
4676  * @param a is an array having exactly the same number of components than 'this'
4677  */
4678 void DataArrayInt::setContigPartOfSelectedValues2(int tupleIdStart, const DataArrayInt *a, int bg, int end2, int step) throw(INTERP_KERNEL::Exception)
4679 {
4680   checkAllocated();
4681   a->checkAllocated();
4682   int nbOfComp=getNumberOfComponents();
4683   const char msg[]="DataArrayInt::setContigPartOfSelectedValues2";
4684   int nbOfTupleToWrite=DataArray::GetNumberOfItemGivenBES(bg,end2,step,msg);
4685   if(nbOfComp!=a->getNumberOfComponents())
4686     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues2 : This and a do not have the same number of components !");
4687   int thisNt=getNumberOfTuples();
4688   int aNt=a->getNumberOfTuples();
4689   int *valsToSet=getPointer()+tupleIdStart*nbOfComp;
4690   if(tupleIdStart+nbOfTupleToWrite>thisNt)
4691     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues2 : invalid number range of values to write !");
4692   if(end2>aNt)
4693     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues2 : invalid range of values to read !");
4694   const int *valsSrc=a->getConstPointer()+bg*nbOfComp;
4695   for(int i=0;i<nbOfTupleToWrite;i++,valsToSet+=nbOfComp,valsSrc+=step*nbOfComp)
4696     {
4697       std::copy(valsSrc,valsSrc+nbOfComp,valsToSet);
4698     }
4699 }
4700
4701 /*!
4702  * This method is equivalent to DataArrayInt::getIJ except that here \b tupleId is checked to be in [0,this->getNumberOfTuples()) and compoId to be in [0,this->getNumberOfComponents()).
4703  * If one of these check fails an INTERP_KERNEL::Exception will be thrown.
4704  * So this method is safe but expensive if used to go through all data of \b this.
4705  */
4706 int DataArrayInt::getIJSafe(int tupleId, int compoId) const throw(INTERP_KERNEL::Exception)
4707 {
4708   checkAllocated();
4709   if(tupleId<0 || tupleId>=getNumberOfTuples())
4710     {
4711       std::ostringstream oss; oss << "DataArrayInt::getIJSafe : request for tupleId " << tupleId << " should be in [0," << getNumberOfTuples() << ") !";
4712       throw INTERP_KERNEL::Exception(oss.str().c_str());
4713     }
4714   if(compoId<0 || compoId>=getNumberOfComponents())
4715     {
4716       std::ostringstream oss; oss << "DataArrayInt::getIJSafe : request for compoId " << compoId << " should be in [0," << getNumberOfComponents() << ") !";
4717       throw INTERP_KERNEL::Exception(oss.str().c_str());
4718     }
4719   return _mem[tupleId*((int)_info_on_compo.size())+compoId];
4720 }
4721
4722 /*!
4723  * This method returns the last element in 'this'. So this method makes the hypothesis that 'this' is allocated.
4724  * This method works only for arrays that have exactly number of components equal to 1. If not an exception is thrown.
4725  * And to finish this method works for arrays that have number of tuples >= 1.
4726  */
4727 int DataArrayInt::back() const throw(INTERP_KERNEL::Exception)
4728 {
4729   checkAllocated();
4730   if(getNumberOfComponents()!=1)
4731     throw INTERP_KERNEL::Exception("DataArrayInt::back : number of components not equal to one !");
4732   int nbOfTuples=getNumberOfTuples();
4733   if(nbOfTuples<1)
4734     throw INTERP_KERNEL::Exception("DataArrayInt::back : number of tuples must be >= 1 !");
4735   return *(getConstPointer()+nbOfTuples-1);
4736 }
4737
4738 void DataArrayInt::SetArrayIn(DataArrayInt *newArray, DataArrayInt* &arrayToSet)
4739 {
4740   if(newArray!=arrayToSet)
4741     {
4742       if(arrayToSet)
4743         arrayToSet->decrRef();
4744       arrayToSet=newArray;
4745       if(arrayToSet)
4746         arrayToSet->incrRef();
4747     }
4748 }
4749
4750 DataArrayIntIterator *DataArrayInt::iterator()
4751 {
4752   return new DataArrayIntIterator(this);
4753 }
4754
4755 DataArrayInt *DataArrayInt::getIdsEqual(int val) const throw(INTERP_KERNEL::Exception)
4756 {
4757   if(getNumberOfComponents()!=1)
4758     throw INTERP_KERNEL::Exception("DataArrayInt::getIdsEqual : the array must have only one component, you can call 'rearrange' method before !");
4759   const int *cptr=getConstPointer();
4760   std::vector<int> res;
4761   int nbOfTuples=getNumberOfTuples();
4762   for(int i=0;i<nbOfTuples;i++,cptr++)
4763     if(*cptr==val)
4764       res.push_back(i);
4765   DataArrayInt *ret=DataArrayInt::New();
4766   ret->alloc((int)res.size(),1);
4767   std::copy(res.begin(),res.end(),ret->getPointer());
4768   return ret;
4769 }
4770
4771 DataArrayInt *DataArrayInt::getIdsNotEqual(int val) const throw(INTERP_KERNEL::Exception)
4772 {
4773   if(getNumberOfComponents()!=1)
4774     throw INTERP_KERNEL::Exception("DataArrayInt::getIdsNotEqual : the array must have only one component, you can call 'rearrange' method before !");
4775   const int *cptr=getConstPointer();
4776   std::vector<int> res;
4777   int nbOfTuples=getNumberOfTuples();
4778   for(int i=0;i<nbOfTuples;i++,cptr++)
4779     if(*cptr!=val)
4780       res.push_back(i);
4781   DataArrayInt *ret=DataArrayInt::New();
4782   ret->alloc((int)res.size(),1);
4783   std::copy(res.begin(),res.end(),ret->getPointer());
4784   return ret;
4785 }
4786
4787 /*!
4788  * This method expects that 'this' is allocated. If not an exception will be thrown.
4789  * This method expect that the number of components is exactly equal to 1. If not an exception will be thrown.
4790  * For each element in 'this' equal to 'oldValue' will take the value 'newValue'.
4791  * @return number of elements impacted by the modification.
4792  */
4793 int DataArrayInt::changeValue(int oldValue, int newValue) throw(INTERP_KERNEL::Exception)
4794 {
4795   if(getNumberOfComponents()!=1)
4796     throw INTERP_KERNEL::Exception("DataArrayInt::changeValue : the array must have only one component, you can call 'rearrange' method before !");
4797   checkAllocated();
4798   int *start=getPointer();
4799   int *end2=start+getNbOfElems();
4800   int ret=0;
4801   for(int *val=start;val!=end2;val++)
4802     {
4803       if(*val==oldValue)
4804         {
4805           *val=newValue;
4806           ret++;
4807         }
4808     }
4809   return ret;
4810 }
4811
4812 DataArrayInt *DataArrayInt::getIdsEqualList(const int *valsBg, const int *valsEnd) const throw(INTERP_KERNEL::Exception)
4813 {
4814   if(getNumberOfComponents()!=1)
4815     throw INTERP_KERNEL::Exception("DataArrayInt::getIdsEqualList : the array must have only one component, you can call 'rearrange' method before !");
4816   std::set<int> vals2(valsBg,valsEnd);
4817   const int *cptr=getConstPointer();
4818   std::vector<int> res;
4819   int nbOfTuples=getNumberOfTuples();
4820   for(int i=0;i<nbOfTuples;i++,cptr++)
4821     if(vals2.find(*cptr)!=vals2.end())
4822       res.push_back(i);
4823   DataArrayInt *ret=DataArrayInt::New();
4824   ret->alloc((int)res.size(),1);
4825   std::copy(res.begin(),res.end(),ret->getPointer());
4826   return ret;
4827 }
4828
4829 DataArrayInt *DataArrayInt::getIdsNotEqualList(const int *valsBg, const int *valsEnd) const throw(INTERP_KERNEL::Exception)
4830 {
4831   if(getNumberOfComponents()!=1)
4832     throw INTERP_KERNEL::Exception("DataArrayInt::getIdsNotEqualList : the array must have only one component, you can call 'rearrange' method before !");
4833   std::set<int> vals2(valsBg,valsEnd);
4834   const int *cptr=getConstPointer();
4835   std::vector<int> res;
4836   int nbOfTuples=getNumberOfTuples();
4837   for(int i=0;i<nbOfTuples;i++,cptr++)
4838     if(vals2.find(*cptr)==vals2.end())
4839       res.push_back(i);
4840   DataArrayInt *ret=DataArrayInt::New();
4841   ret->alloc((int)res.size(),1);
4842   std::copy(res.begin(),res.end(),ret->getPointer());
4843   return ret;
4844 }
4845
4846 /*!
4847  * This method is an extension of DataArrayInt::locateValue method because this method works for DataArrayInt with
4848  * any number of components excepted 0 (an INTERP_KERNEL::Exception is thrown in this case).
4849  * This method searches in \b this is there is a tuple that matched the input parameter \b tupl.
4850  * If any the tuple id is returned. If not -1 is returned.
4851  * 
4852  * This method throws an INTERP_KERNEL::Exception if the number of components in \b this mismatches with the size of
4853  * the input vector. An INTERP_KERNEL::Exception is thrown too if \b this is not allocated.
4854  *
4855  * \return tuple id where \b tupl is. -1 if no such tuple exists in \b this.
4856  * \sa DataArrayInt::search, DataArrayInt::presenceOfTuple.
4857  */
4858 int DataArrayInt::locateTuple(const std::vector<int>& tupl) const throw(INTERP_KERNEL::Exception)
4859 {
4860   int nbOfCompo=getNumberOfComponents();
4861   if(nbOfCompo==0)
4862     throw INTERP_KERNEL::Exception("DataArrayInt::locateTuple : 0 components in 'this' !");
4863   if(nbOfCompo!=(int)tupl.size())
4864     {
4865       std::ostringstream oss; oss << "DataArrayInt::locateTuple : 'this' contains " << nbOfCompo << " components and searching for a tuple of length " << tupl.size() << " !";
4866       throw INTERP_KERNEL::Exception(oss.str().c_str());
4867     }
4868   const int *cptr=getConstPointer();
4869   int nbOfVals=getNbOfElems();
4870   for(const int *work=cptr;work!=cptr+nbOfVals;)
4871     {
4872       work=std::search(work,cptr+nbOfVals,tupl.begin(),tupl.end());
4873       if(work!=cptr+nbOfVals)
4874         {
4875           if(std::distance(cptr,work)%nbOfCompo!=0)
4876             work++;
4877           else
4878             return std::distance(cptr,work)/nbOfCompo;
4879         }
4880     }
4881   return -1;
4882 }
4883
4884 /*!
4885  * This method searches the sequence specified in input parameter \b vals in \b this.
4886  * This works only for DataArrayInt having number of components equal to one (if not an INTERP_KERNEL::Exception will be thrown).
4887  * This method differs from DataArrayInt::locateTuple in that the position is internal raw data is not considered here contrary to DataArrayInt::locateTuple.
4888  * \sa DataArrayInt::locateTuple
4889  */
4890 int DataArrayInt::search(const std::vector<int>& vals) const throw(INTERP_KERNEL::Exception)
4891 {
4892   int nbOfCompo=getNumberOfComponents();
4893   if(nbOfCompo!=1)
4894     throw INTERP_KERNEL::Exception("DataArrayInt::search : works only for DataArrayInt instance with one component !");
4895   const int *cptr=getConstPointer();
4896   int nbOfVals=getNbOfElems();
4897   const int *loc=std::search(cptr,cptr+nbOfVals,vals.begin(),vals.end());
4898   if(loc!=cptr+nbOfVals)
4899     return std::distance(cptr,loc);
4900   return -1;
4901 }
4902
4903 /*!
4904  * This method expects to be called when number of components of this is equal to one.
4905  * This method returns the tuple id, if it exists, of the first tuple equal to \b value.
4906  * If not any tuple contains \b value -1 is returned.
4907  * \sa DataArrayInt::presenceOfValue
4908  */
4909 int DataArrayInt::locateValue(int value) const throw(INTERP_KERNEL::Exception)
4910 {
4911   if(getNumberOfComponents()!=1)
4912     throw INTERP_KERNEL::Exception("DataArrayInt::presenceOfValue : the array must have only one component, you can call 'rearrange' method before !");
4913   const int *cptr=getConstPointer();
4914   int nbOfTuples=getNumberOfTuples();
4915   const int *ret=std::find(cptr,cptr+nbOfTuples,value);
4916   if(ret!=cptr+nbOfTuples)
4917     return std::distance(cptr,ret);
4918   return -1;
4919 }
4920
4921 /*!
4922  * This method expects to be called when number of components of this is equal to one.
4923  * This method returns the tuple id, if it exists, of the first tuple so that the value is contained in \b vals.
4924  * If not any tuple contains one of the values contained in 'vals' false is returned.
4925  * \sa DataArrayInt::presenceOfValue
4926  */
4927 int DataArrayInt::locateValue(const std::vector<int>& vals) const throw(INTERP_KERNEL::Exception)
4928 {
4929   if(getNumberOfComponents()!=1)
4930     throw INTERP_KERNEL::Exception("DataArrayInt::presenceOfValue : the array must have only one component, you can call 'rearrange' method before !");
4931   std::set<int> vals2(vals.begin(),vals.end());
4932   const int *cptr=getConstPointer();
4933   int nbOfTuples=getNumberOfTuples();
4934   for(const int *w=cptr;w!=cptr+nbOfTuples;w++)
4935     if(vals2.find(*w)!=vals2.end())
4936       return std::distance(cptr,w);
4937   return -1;
4938 }
4939
4940 /*!
4941  * This method is an extension of DataArrayInt::presenceOfValue method because this method works for DataArrayInt with
4942  * any number of components excepted 0 (an INTERP_KERNEL::Exception is thrown in this case).
4943  * This method searches in \b this is there is a tuple that matched the input parameter \b tupl.
4944  * This method throws an INTERP_KERNEL::Exception if the number of components in \b this mismatches with the size of
4945  * the input vector. An INTERP_KERNEL::Exception is thrown too if \b this is not allocated.
4946  * \sa DataArrayInt::locateTuple
4947  */
4948 bool DataArrayInt::presenceOfTuple(const std::vector<int>& tupl) const throw(INTERP_KERNEL::Exception)
4949 {
4950   return locateTuple(tupl)!=-1;
4951 }
4952
4953 /*!
4954  * This method expects to be called when number of components of this is equal to one.
4955  * This method returns true if it exists a tuple equal to \b value.
4956  * If not any tuple contains \b value false is returned.
4957  * \sa DataArrayInt::locateValue
4958  */
4959 bool DataArrayInt::presenceOfValue(int value) const throw(INTERP_KERNEL::Exception)
4960 {
4961   return locateValue(value)!=-1;
4962 }
4963
4964 /*!
4965  * This method expects to be called when number of components of this is equal to one.
4966  * This method returns true if it exists a tuple so that the value is contained in \b vals.
4967  * If not any tuple contains one of the values contained in 'vals' false is returned.
4968  * \sa DataArrayInt::locateValue
4969  */
4970 bool DataArrayInt::presenceOfValue(const std::vector<int>& vals) const throw(INTERP_KERNEL::Exception)
4971 {
4972   return locateValue(vals)!=-1;
4973 }
4974
4975 DataArrayInt *DataArrayInt::Aggregate(const DataArrayInt *a1, const DataArrayInt *a2, int offsetA2)
4976 {
4977   if(!a1 || !a2)
4978     throw INTERP_KERNEL::Exception("DataArrayInt::Aggregate : input DataArrayInt instance is NULL !");
4979   int nbOfComp=a1->getNumberOfComponents();
4980   if(nbOfComp!=a2->getNumberOfComponents())
4981     throw INTERP_KERNEL::Exception("Nb of components mismatch for array Aggregation !");
4982   int nbOfTuple1=a1->getNumberOfTuples();
4983   int nbOfTuple2=a2->getNumberOfTuples();
4984   DataArrayInt *ret=DataArrayInt::New();
4985   ret->alloc(nbOfTuple1+nbOfTuple2-offsetA2,nbOfComp);
4986   int *pt=std::copy(a1->getConstPointer(),a1->getConstPointer()+nbOfTuple1*nbOfComp,ret->getPointer());
4987   std::copy(a2->getConstPointer()+offsetA2*nbOfComp,a2->getConstPointer()+nbOfTuple2*nbOfComp,pt);
4988   ret->copyStringInfoFrom(*a1);
4989   return ret;
4990 }
4991
4992 DataArrayInt *DataArrayInt::Aggregate(const std::vector<const DataArrayInt *>& arr) throw(INTERP_KERNEL::Exception)
4993 {
4994   std::vector<const DataArrayInt *> a;
4995   for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
4996     if(*it4)
4997       a.push_back(*it4);
4998   if(a.empty())
4999     throw INTERP_KERNEL::Exception("DataArrayInt::Aggregate : input list must be NON EMPTY !");
5000   std::vector<const DataArrayInt *>::const_iterator it=a.begin();
5001   int nbOfComp=(*it)->getNumberOfComponents();
5002   int nbt=(*it++)->getNumberOfTuples();
5003   for(int i=1;it!=a.end();it++,i++)
5004     {
5005       if((*it)->getNumberOfComponents()!=nbOfComp)
5006         throw INTERP_KERNEL::Exception("DataArrayInt::Aggregate : Nb of components mismatch for array aggregation !");
5007       nbt+=(*it)->getNumberOfTuples();
5008     }
5009   DataArrayInt *ret=DataArrayInt::New();
5010   ret->alloc(nbt,nbOfComp);
5011   int *pt=ret->getPointer();
5012   for(it=a.begin();it!=a.end();it++)
5013     pt=std::copy((*it)->getConstPointer(),(*it)->getConstPointer()+(*it)->getNbOfElems(),pt);
5014   ret->copyStringInfoFrom(*(a[0]));
5015   return ret;
5016 }
5017
5018 int DataArrayInt::getMaxValue(int& tupleId) const throw(INTERP_KERNEL::Exception)
5019 {
5020   if(getNumberOfComponents()!=1)
5021     throw INTERP_KERNEL::Exception("DataArrayInt::getMaxValue : must be applied on DataArrayInt with only one component !");
5022   int nbOfTuples=getNumberOfTuples();
5023   if(nbOfTuples<=0)
5024     throw INTERP_KERNEL::Exception("DataArrayInt::getMaxValue : array exists but number of tuples must be > 0 !");
5025   const int *vals=getConstPointer();
5026   const int *loc=std::max_element(vals,vals+nbOfTuples);
5027   tupleId=(int)std::distance(vals,loc);
5028   return *loc;
5029 }
5030
5031 /*!
5032  * Idem to DataArrayInt::getMaxValue expect that here number of components can be >=1.
5033  */
5034 int DataArrayInt::getMaxValueInArray() const throw(INTERP_KERNEL::Exception)
5035 {
5036   checkAllocated();
5037   const int *loc=std::max_element(begin(),end());
5038   return *loc;
5039 }
5040
5041 int DataArrayInt::getMinValue(int& tupleId) const throw(INTERP_KERNEL::Exception)
5042 {
5043   if(getNumberOfComponents()!=1)
5044     throw INTERP_KERNEL::Exception("DataArrayInt::getMaxValue : must be applied on DataArrayInt with only one component !");
5045   int nbOfTuples=getNumberOfTuples();
5046   if(nbOfTuples<=0)
5047     throw INTERP_KERNEL::Exception("DataArrayInt::getMaxValue : array exists but number of tuples must be > 0 !");
5048   const int *vals=getConstPointer();
5049   const int *loc=std::min_element(vals,vals+nbOfTuples);
5050   tupleId=(int)std::distance(vals,loc);
5051   return *loc;
5052 }
5053
5054 /*!
5055  * Idem to DataArrayInt::getMinValue expect that here number of components can be >=1.
5056  */
5057 int DataArrayInt::getMinValueInArray() const throw(INTERP_KERNEL::Exception)
5058 {
5059   checkAllocated();
5060   const int *loc=std::min_element(begin(),end());
5061   return *loc;
5062 }
5063
5064 void DataArrayInt::abs() throw(INTERP_KERNEL::Exception)
5065 {
5066   checkAllocated();
5067   int *ptr=getPointer();
5068   int nbOfElems=getNbOfElems();
5069   std::transform(ptr,ptr+nbOfElems,ptr,std::ptr_fun<int,int>(std::abs));
5070 }
5071
5072 void DataArrayInt::applyLin(int a, int b, int compoId) throw(INTERP_KERNEL::Exception)
5073 {
5074   checkAllocated();
5075   int *ptr=getPointer()+compoId;
5076   int nbOfComp=getNumberOfComponents();
5077   int nbOfTuple=getNumberOfTuples();
5078   for(int i=0;i<nbOfTuple;i++,ptr+=nbOfComp)
5079     *ptr=a*(*ptr)+b;
5080   declareAsNew();
5081 }
5082
5083 void DataArrayInt::applyLin(int a, int b) throw(INTERP_KERNEL::Exception)
5084 {
5085   checkAllocated();
5086   int *ptr=getPointer();
5087   int nbOfElems=getNbOfElems();
5088   for(int i=0;i<nbOfElems;i++,ptr++)
5089     *ptr=a*(*ptr)+b;
5090   declareAsNew();
5091 }
5092
5093 /*!
5094  * This method returns a newly allocated array containing the application of negate on \b this.
5095  * This method throws an INTERP_KERNEL::Exception if \b this is not allocated.
5096  */
5097 DataArrayInt *DataArrayInt::negate() const throw(INTERP_KERNEL::Exception)
5098 {
5099   checkAllocated();
5100   DataArrayInt *newArr=DataArrayInt::New();
5101   int nbOfTuples=getNumberOfTuples();
5102   int nbOfComp=getNumberOfComponents();
5103   newArr->alloc(nbOfTuples,nbOfComp);
5104   const int *cptr=getConstPointer();
5105   std::transform(cptr,cptr+nbOfTuples*nbOfComp,newArr->getPointer(),std::negate<int>());
5106   newArr->copyStringInfoFrom(*this);
5107   return newArr;
5108 }
5109
5110 /*!
5111  * This method applies the operation 'numerator/x' for each element 'x' in 'this'.
5112  * If there is a value in 'this' exactly equal to 0. an exception is thrown.
5113  * Warning if presence of null this is modified for each values previous than place where exception was thrown !
5114  */
5115 void DataArrayInt::applyInv(int numerator) throw(INTERP_KERNEL::Exception)
5116 {
5117   checkAllocated();
5118   int *ptr=getPointer();
5119   int nbOfElems=getNbOfElems();
5120   for(int i=0;i<nbOfElems;i++,ptr++)
5121     {
5122       if(*ptr!=0)
5123         {
5124           *ptr=numerator/(*ptr);
5125         }
5126       else
5127         {
5128           std::ostringstream oss; oss << "DataArrayInt::applyInv : presence of null value in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
5129           oss << " !";
5130           throw INTERP_KERNEL::Exception(oss.str().c_str());
5131         }
5132     }
5133   declareAsNew();
5134 }
5135
5136 void DataArrayInt::applyDivideBy(int val) throw(INTERP_KERNEL::Exception)
5137 {
5138   if(val==0)
5139     throw INTERP_KERNEL::Exception("DataArrayInt::applyDivideBy : Trying to divide by 0 !");
5140   checkAllocated();
5141   int *ptr=getPointer();
5142   int nbOfElems=getNbOfElems();
5143   std::transform(ptr,ptr+nbOfElems,ptr,std::bind2nd(std::divides<int>(),val));
5144   declareAsNew();
5145 }
5146
5147 void DataArrayInt::applyModulus(int val) throw(INTERP_KERNEL::Exception)
5148 {
5149   if(val<=0)
5150     throw INTERP_KERNEL::Exception("DataArrayInt::applyDivideBy : Trying to operate modulus on value <= 0 !");
5151   checkAllocated();
5152   int *ptr=getPointer();
5153   int nbOfElems=getNbOfElems();
5154   std::transform(ptr,ptr+nbOfElems,ptr,std::bind2nd(std::modulus<int>(),val));
5155   declareAsNew();
5156 }
5157
5158 /*!
5159  * This method works only on data array with one component.
5160  * This method returns a newly allocated array storing stored ascendantly tuple ids in \b this so that
5161  * this[*id] in [\b vmin,\b vmax)
5162  * 
5163  * \param [in] vmin begin of range. This value is included in range.
5164  * \param [out] vmax end of range. This value is \b not included in range.
5165  * \return a newly allocated data array that the caller should deal with.
5166  */
5167 DataArrayInt *DataArrayInt::getIdsInRange(int vmin, int vmax) const throw(INTERP_KERNEL::Exception)
5168 {
5169   if(getNumberOfComponents()!=1)
5170     throw INTERP_KERNEL::Exception("DataArrayInt::getIdsInRange : this must have exactly one component !");
5171   const int *cptr=getConstPointer();
5172   std::vector<int> res;
5173   int nbOfTuples=getNumberOfTuples();
5174   for(int i=0;i<nbOfTuples;i++,cptr++)
5175     if(*cptr>=vmin && *cptr<vmax)
5176       res.push_back(i);
5177   DataArrayInt *ret=DataArrayInt::New();
5178   ret->alloc((int)res.size(),1);
5179   std::copy(res.begin(),res.end(),ret->getPointer());
5180   return ret;
5181 }
5182
5183 /*!
5184  * This method applies the operation 'numerator%x' for each element 'x' in 'this'.
5185  * If there is a value in 'this' exactly equals or lower than 0. an exception is thrown.
5186  * Warning if presence of null this is modified for each values previous than place where exception was thrown !
5187  */
5188 void DataArrayInt::applyRModulus(int val) throw(INTERP_KERNEL::Exception)
5189 {
5190   checkAllocated();
5191   int *ptr=getPointer();
5192   int nbOfElems=getNbOfElems();
5193   for(int i=0;i<nbOfElems;i++,ptr++)
5194     {
5195       if(*ptr>0)
5196         {
5197           *ptr=val%(*ptr);
5198         }
5199       else
5200         {
5201           std::ostringstream oss; oss << "DataArrayInt::applyRModulus : presence of value <=0 in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
5202           oss << " !";
5203           throw INTERP_KERNEL::Exception(oss.str().c_str());
5204         }
5205     }
5206   declareAsNew();
5207 }
5208
5209 DataArrayInt *DataArrayInt::Meld(const DataArrayInt *a1, const DataArrayInt *a2) throw(INTERP_KERNEL::Exception)
5210 {
5211   std::vector<const DataArrayInt *> arr(2);
5212   arr[0]=a1; arr[1]=a2;
5213   return Meld(arr);
5214 }
5215
5216 DataArrayInt *DataArrayInt::Meld(const std::vector<const DataArrayInt *>& arr) throw(INTERP_KERNEL::Exception)
5217 {
5218   std::vector<const DataArrayInt *> a;
5219   for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
5220     if(*it4)
5221       a.push_back(*it4);
5222   if(a.empty())
5223     throw INTERP_KERNEL::Exception("DataArrayInt::Meld : array must be NON empty !");
5224   std::vector<const DataArrayInt *>::const_iterator it;
5225   for(it=a.begin();it!=a.end();it++)
5226     (*it)->checkAllocated();
5227   it=a.begin();
5228   int nbOfTuples=(*it)->getNumberOfTuples();
5229   std::vector<int> nbc(a.size());
5230   std::vector<const int *> pts(a.size());
5231   nbc[0]=(*it)->getNumberOfComponents();
5232   pts[0]=(*it++)->getConstPointer();
5233   for(int i=1;it!=a.end();it++,i++)
5234     {
5235       if(nbOfTuples!=(*it)->getNumberOfTuples())
5236         throw INTERP_KERNEL::Exception("DataArrayInt::meld : mismatch of number of tuples !");
5237       nbc[i]=(*it)->getNumberOfComponents();
5238       pts[i]=(*it)->getConstPointer();
5239     }
5240   int totalNbOfComp=std::accumulate(nbc.begin(),nbc.end(),0);
5241   DataArrayInt *ret=DataArrayInt::New();
5242   ret->alloc(nbOfTuples,totalNbOfComp);
5243   int *retPtr=ret->getPointer();
5244   for(int i=0;i<nbOfTuples;i++)
5245     for(int j=0;j<(int)a.size();j++)
5246       {
5247         retPtr=std::copy(pts[j],pts[j]+nbc[j],retPtr);
5248         pts[j]+=nbc[j];
5249       }
5250   int k=0;
5251   for(int i=0;i<(int)a.size();i++)
5252     for(int j=0;j<nbc[i];j++,k++)
5253       ret->setInfoOnComponent(k,a[i]->getInfoOnComponent(j).c_str());
5254   return ret;
5255 }
5256
5257 /*!
5258  * This method create a minimal partition of groups 'groups' the std::iota array of size 'newNb'.
5259  * This method returns an array of size 'newNb' that specifies for each item at which familyId it owns to, and this method returns
5260  * for each group the familyId it contains. If an id so that id<newNb and that appears in no groups will appears with 0 in return array.
5261  *
5262  * @param groups in arrays specifying ids of each groups.
5263  * @param newNb specifies size of whole set. Must be at least equal to max eltid in 'groups'.
5264  * @return an array of size newNb specifying fid of each item.
5265  */
5266 DataArrayInt *DataArrayInt::MakePartition(const std::vector<const DataArrayInt *>& groups, int newNb, std::vector< std::vector<int> >& fidsOfGroups) throw(INTERP_KERNEL::Exception)
5267 {
5268   std::vector<const DataArrayInt *> groups2;
5269   for(std::vector<const DataArrayInt *>::const_iterator it4=groups.begin();it4!=groups.end();it4++)
5270     if(*it4)
5271       groups2.push_back(*it4);
5272   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
5273   ret->alloc(newNb,1);
5274   int *retPtr=ret->getPointer();
5275   std::fill(retPtr,retPtr+newNb,0);
5276   int fid=1;
5277   for(std::vector<const DataArrayInt *>::const_iterator iter=groups2.begin();iter!=groups2.end();iter++)
5278     {
5279       const int *ptr=(*iter)->getConstPointer();
5280       int nbOfElem=(*iter)->getNbOfElems();
5281       int sfid=fid;
5282       for(int j=0;j<sfid;j++)
5283         {
5284           bool found=false;
5285           for(int i=0;i<nbOfElem;i++)
5286             {
5287               if(ptr[i]>=0 && ptr[i]<newNb)
5288                 {
5289                   if(retPtr[ptr[i]]==j)
5290                     {
5291                       retPtr[ptr[i]]=fid;
5292                       found=true;
5293                     }
5294                 }
5295               else
5296                 {
5297                   std::ostringstream oss; oss << "DataArrayInt::MakePartition : In group \"" << (*iter)->getName() << "\" in tuple #" << i << " value = " << ptr[i] << " ! Should be in [0," << newNb;
5298                   oss << ") !";
5299                   throw INTERP_KERNEL::Exception(oss.str().c_str());
5300                 }
5301             }
5302           if(found)
5303             fid++;
5304         }
5305     }
5306   fidsOfGroups.clear();
5307   fidsOfGroups.resize(groups2.size());
5308   int grId=0;
5309   for(std::vector<const DataArrayInt *>::const_iterator iter=groups2.begin();iter!=groups2.end();iter++,grId++)
5310     {
5311       std::set<int> tmp;
5312       const int *ptr=(*iter)->getConstPointer();
5313       int nbOfElem=(*iter)->getNbOfElems();
5314       for(const int *p=ptr;p!=ptr+nbOfElem;p++)
5315         tmp.insert(retPtr[*p]);
5316       fidsOfGroups[grId].insert(fidsOfGroups[grId].end(),tmp.begin(),tmp.end());
5317     }
5318   ret->incrRef();
5319   return ret;
5320 }
5321
5322 DataArrayInt *DataArrayInt::BuildUnion(const std::vector<const DataArrayInt *>& arr) throw(INTERP_KERNEL::Exception)
5323 {
5324   std::vector<const DataArrayInt *> a;
5325   for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
5326     if(*it4)
5327       a.push_back(*it4);
5328   int valm=std::numeric_limits<int>::max();
5329   for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
5330     {
5331       (*it)->checkAllocated();
5332       if((*it)->getNumberOfComponents()!=1)
5333         throw INTERP_KERNEL::Exception("DataArrayInt::BuildUnion : only single component allowed !");
5334       int tmp1;
5335       valm=std::min((*it)->getMinValue(tmp1),valm);
5336     }
5337   if(valm<0)
5338     throw INTERP_KERNEL::Exception("DataArrayInt::BuildUnion : a negative value has been detected !");
5339   //
5340   std::set<int> r;
5341   for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
5342     {
5343       const int *pt=(*it)->getConstPointer();
5344       int nbOfTuples=(*it)->getNumberOfTuples();
5345       r.insert(pt,pt+nbOfTuples);
5346     }
5347   DataArrayInt *ret=DataArrayInt::New();
5348   ret->alloc((int)r.size(),1);
5349   std::copy(r.begin(),r.end(),ret->getPointer());
5350   return ret;
5351 }
5352
5353 DataArrayInt *DataArrayInt::BuildIntersection(const std::vector<const DataArrayInt *>& arr) throw(INTERP_KERNEL::Exception)
5354 {
5355   std::vector<const DataArrayInt *> a;
5356   for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
5357     if(*it4)
5358       a.push_back(*it4);
5359   int valm=std::numeric_limits<int>::max();
5360   for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
5361     {
5362       (*it)->checkAllocated();
5363       if((*it)->getNumberOfComponents()!=1)
5364         throw INTERP_KERNEL::Exception("DataArrayInt::BuildUnion : only single component allowed !");
5365       int tmp1;
5366       valm=std::min((*it)->getMinValue(tmp1),valm);
5367     }
5368   if(valm<0)
5369     throw INTERP_KERNEL::Exception("DataArrayInt::BuildUnion : a negative value has been detected !");
5370   //
5371   std::set<int> r;
5372   for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
5373     {
5374       const int *pt=(*it)->getConstPointer();
5375       int nbOfTuples=(*it)->getNumberOfTuples();
5376       std::set<int> s1(pt,pt+nbOfTuples);
5377       if(it!=a.begin())
5378         {
5379           std::set<int> r2;
5380           std::set_intersection(r.begin(),r.end(),s1.begin(),s1.end(),inserter(r2,r2.end()));
5381           r=r2;
5382         }
5383       else
5384         r=s1;
5385     }
5386   DataArrayInt *ret=DataArrayInt::New();
5387   ret->alloc((int)r.size(),1);
5388   std::copy(r.begin(),r.end(),ret->getPointer());
5389   return ret;
5390 }
5391
5392 DataArrayInt *DataArrayInt::buildComplement(int nbOfElement) const throw(INTERP_KERNEL::Exception)
5393 {
5394    checkAllocated();
5395    if(getNumberOfComponents()!=1)
5396      throw INTERP_KERNEL::Exception("DataArrayInt::buildComplement : only single component allowed !");
5397    std::vector<bool> tmp(nbOfElement);
5398    const int *pt=getConstPointer();
5399    int nbOfTuples=getNumberOfTuples();
5400    for(const int *w=pt;w!=pt+nbOfTuples;w++)
5401      if(*w>=0 && *w<nbOfElement)
5402        tmp[*w]=true;
5403      else
5404        throw INTERP_KERNEL::Exception("DataArrayInt::buildComplement : an element is not in valid range : [0,nbOfElement) !");
5405    int nbOfRetVal=(int)std::count(tmp.begin(),tmp.end(),false);
5406    DataArrayInt *ret=DataArrayInt::New();
5407    ret->alloc(nbOfRetVal,1);
5408    int j=0;
5409    int *retPtr=ret->getPointer();
5410    for(int i=0;i<nbOfElement;i++)
5411      if(!tmp[i])
5412        retPtr[j++]=i;
5413    return ret;
5414 }
5415
5416 DataArrayInt *DataArrayInt::buildSubstraction(const DataArrayInt *other) const throw(INTERP_KERNEL::Exception)
5417 {
5418   if(!other)
5419     throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstraction : DataArrayInt pointer in input is NULL !");
5420   checkAllocated();
5421   other->checkAllocated();
5422   if(getNumberOfComponents()!=1)
5423      throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstraction : only single component allowed !");
5424   if(other->getNumberOfComponents()!=1)
5425      throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstraction : only single component allowed for other type !");
5426   const int *pt=getConstPointer();
5427   int nbOfTuples=getNumberOfTuples();
5428   std::set<int> s1(pt,pt+nbOfTuples);
5429   pt=other->getConstPointer();
5430   nbOfTuples=other->getNumberOfTuples();
5431   std::set<int> s2(pt,pt+nbOfTuples);
5432   std::vector<int> r;
5433   std::set_difference(s1.begin(),s1.end(),s2.begin(),s2.end(),std::back_insert_iterator< std::vector<int> >(r));
5434   DataArrayInt *ret=DataArrayInt::New();
5435   ret->alloc((int)r.size(),1);
5436   std::copy(r.begin(),r.end(),ret->getPointer());
5437   return ret;
5438 }
5439
5440 DataArrayInt *DataArrayInt::buildUnion(const DataArrayInt *other) const throw(INTERP_KERNEL::Exception)
5441 {
5442   std::vector<const DataArrayInt *>arrs(2);
5443   arrs[0]=this; arrs[1]=other;
5444   return BuildUnion(arrs);
5445 }
5446
5447 DataArrayInt *DataArrayInt::buildIntersection(const DataArrayInt *other) const throw(INTERP_KERNEL::Exception)
5448 {
5449   std::vector<const DataArrayInt *>arrs(2);
5450   arrs[0]=this; arrs[1]=other;
5451   return BuildIntersection(arrs);
5452 }
5453
5454 /*!
5455  * This method could be usefull for returned DataArrayInt marked as index. Some methods that generate such DataArrayInt instances:
5456  * - ParaMEDMEM::MEDCouplingUMesh::buildDescendingConnectivity
5457  * - ParaMEDMEM::MEDCouplingUMesh::getNodalConnectivityIndex
5458  * This method makes the assumption that 'this' is allocated and has exactly one component and 2 or more tuples. If not an exception is thrown.
5459  * This method retrives a newly created DataArrayInt instance with 1 component and this->getNumberOfTuples()-1 tuples.
5460  * If this contains [1,3,6,7,7,9,15] -> returned array will contain [2,3,1,0,2,6].
5461  */
5462 DataArrayInt *DataArrayInt::deltaShiftIndex() const throw(INTERP_KERNEL::Exception)
5463 {
5464   checkAllocated();
5465   if(getNumberOfComponents()!=1)
5466      throw INTERP_KERNEL::Exception("DataArrayInt::deltaShiftIndex : only single component allowed !");
5467   int nbOfTuples=getNumberOfTuples();
5468   if(nbOfTuples<2)
5469     throw INTERP_KERNEL::Exception("DataArrayInt::deltaShiftIndex : 1 tuple at least must be present in 'this' !");
5470   const int *ptr=getConstPointer();
5471   DataArrayInt *ret=DataArrayInt::New();
5472   ret->alloc(nbOfTuples-1,1);
5473   int *out=ret->getPointer();
5474   std::transform(ptr+1,ptr+nbOfTuples,ptr,out,std::minus<int>());
5475   return ret;
5476 }
5477
5478 /*!
5479  * This method performs the work on itself. This method works on array with number of component equal to one and allocated. If not an exception is thrown.
5480  * This method conserves the number of tuples and number of components (1). No reallocation is done.
5481  * For an array [3,5,1,2,0,8] it becomes [0,3,8,9,11,11]. For each i>0 new[i]=new[i-1]+old[i-1] for i==0 new[i]=0.
5482  * This could be usefull for allToAllV in MPI with contiguous policy.
5483  */
5484 void DataArrayInt::computeOffsets() throw(INTERP_KERNEL::Exception)
5485 {
5486   checkAllocated();
5487   if(getNumberOfComponents()!=1)
5488      throw INTERP_KERNEL::Exception("DataArrayInt::computeOffsets : only single component allowed !");
5489   int nbOfTuples=getNumberOfTuples();
5490   if(nbOfTuples==0)
5491     return ;
5492   int *work=getPointer();
5493   int tmp=work[0];
5494   work[0]=0;
5495   for(int i=1;i<nbOfTuples;i++)
5496     {
5497       int tmp2=work[i];
5498       work[i]=work[i-1]+tmp;
5499       tmp=tmp2;
5500     }
5501   declareAsNew();
5502 }
5503
5504 /*!
5505  * Idem DataArrayInt::computeOffsets method execpt that 'this' changes its number of tuples.
5506  * After the call in case of success new number of tuples is equal to old number of tuples +1.
5507  * The content in 'this' for the first old number of tuples is exactly the same than those given by
5508  * DataArrayInt::computeOffsets method.
5509  * For an array [3,5,1,2,0,8] it becomes [0,3,8,9,11,11,19].
5510  */
5511 void DataArrayInt::computeOffsets2() throw(INTERP_KERNEL::Exception)
5512 {
5513   checkAllocated();
5514   if(getNumberOfComponents()!=1)
5515     throw INTERP_KERNEL::Exception("DataArrayInt::computeOffsets2 : only single component allowed !");
5516   int nbOfTuples=getNumberOfTuples();
5517   int *ret=new int[nbOfTuples+1];
5518   if(nbOfTuples==0)
5519     return ;
5520   const int *work=getConstPointer();
5521   ret[0]=0;
5522   for(int i=0;i<nbOfTuples;i++)
5523     ret[i+1]=work[i]+ret[i];
5524   useArray(ret,true,CPP_DEALLOC,nbOfTuples+1,1);
5525   declareAsNew();
5526 }
5527
5528 /*!
5529  * This method works on array with number of component equal to one and allocated. If not an exception is thrown.
5530  * 'offsets' should be monotic ascendently. If not, an exception will be thrown.
5531  * This method retrives a newly created DataArrayInt instance with 1 component and this->getNumberOfTuples()-1 tuples.
5532  * If 'this' contains [0,2,3] and 'offsets' [0,3,6,10,14,20] the returned array will contain [0,1,2,6,7,8,9,10,11,12,13]
5533  */
5534 DataArrayInt *DataArrayInt::buildExplicitArrByRanges(const DataArrayInt *offsets) const throw(INTERP_KERNEL::Exception)
5535 {
5536   if(!offsets)
5537     throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrByRanges : DataArrayInt pointer in input is NULL !");
5538   checkAllocated();
5539   if(getNumberOfComponents()!=1)
5540      throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrByRanges : only single component allowed !");
5541   offsets->checkAllocated();
5542   if(offsets->getNumberOfComponents()!=1)
5543      throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrByRanges : input array should have only single component !");
5544   int othNbTuples=offsets->getNumberOfTuples()-1;
5545   int nbOfTuples=getNumberOfTuples();
5546   int retNbOftuples=0;
5547   const int *work=getConstPointer();
5548   const int *offPtr=offsets->getConstPointer();
5549   for(int i=0;i<nbOfTuples;i++)
5550     {
5551       int val=work[i];
5552       if(val>=0 && val<othNbTuples)
5553         {
5554           int delta=offPtr[val+1]-offPtr[val];
5555           if(delta>=0)
5556             retNbOftuples+=delta;
5557           else
5558             {
5559               std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrByRanges : Tuple #" << val << " of offset array has a delta < 0 !";
5560               throw INTERP_KERNEL::Exception(oss.str().c_str());
5561             }
5562         }
5563       else
5564         {
5565           std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrByRanges : Tuple #" << i << " in this contains " << val;
5566           oss << " whereas offsets array is of size " << othNbTuples+1 << " !";
5567           throw INTERP_KERNEL::Exception(oss.str().c_str());
5568         }
5569     }
5570   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
5571   ret->alloc(retNbOftuples,1);
5572   int *retPtr=ret->getPointer();
5573   for(int i=0;i<nbOfTuples;i++)
5574     {
5575       int val=work[i];
5576       int start=offPtr[val];
5577       int off=offPtr[val+1]-start;
5578       for(int j=0;j<off;j++,retPtr++)
5579         *retPtr=start+j;
5580     }
5581   ret->incrRef();
5582   return ret;
5583 }
5584
5585 /*!
5586  * 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.
5587  * 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
5588  * in tuple **i** of returned DataArrayInt.
5589  * If ranges overlapped (in theory it should not) this method do not detect it and always returns the first range.
5590  *
5591  * 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)]
5592  * The return DataArrayInt will contain : **[0,4,1,2,2,3]**
5593  * 
5594  * \param [in] ranges typically come from output of MEDCouplingUMesh::ComputeRangesFromTypeDistribution. Each range is specified like this : 1st component is
5595  *             for lower value included and 2nd component is the upper value of corresponding range **excluded**.
5596  * \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
5597  *        is thrown if no ranges in \a ranges contains value in \a this.
5598  * 
5599  * \sa DataArrayInt::findIdInRangeForEachTuple
5600  */
5601 DataArrayInt *DataArrayInt::findRangeIdForEachTuple(const DataArrayInt *ranges) const throw(INTERP_KERNEL::Exception)
5602 {
5603   if(!ranges)
5604     throw INTERP_KERNEL::Exception("DataArrayInt::findRangeIdForEachTuple : null input pointer !");
5605   if(ranges->getNumberOfComponents()!=2)
5606     throw INTERP_KERNEL::Exception("DataArrayInt::findRangeIdForEachTuple : input DataArrayInt instance should have 2 components !");
5607   checkAllocated();
5608   if(getNumberOfComponents()!=1)
5609     throw INTERP_KERNEL::Exception("DataArrayInt::findRangeIdForEachTuple : this should have only one component !");
5610   int nbTuples=getNumberOfTuples();
5611   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbTuples,1);
5612   int nbOfRanges=ranges->getNumberOfTuples();
5613   const int *rangesPtr=ranges->getConstPointer();
5614   int *retPtr=ret->getPointer();
5615   const int *inPtr=getConstPointer();
5616   for(int i=0;i<nbTuples;i++,retPtr++)
5617     {
5618       int val=inPtr[i];
5619       bool found=false;
5620       for(int j=0;j<nbOfRanges && !found;j++)
5621         if(val>=rangesPtr[2*j] && val<rangesPtr[2*j+1])
5622           { *retPtr=j; found=true; }
5623       if(found)
5624         continue;
5625       else
5626         {
5627           std::ostringstream oss; oss << "DataArrayInt::findRangeIdForEachTuple : tuple #" << i << " not found by any ranges !";
5628           throw INTERP_KERNEL::Exception(oss.str().c_str());
5629         }
5630     }
5631   ret->incrRef();
5632   return ret;
5633 }
5634
5635 /*!
5636  * 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.
5637  * 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
5638  * in tuple **i** of returned DataArrayInt.
5639  * If ranges overlapped (in theory it should not) this method do not detect it and always returns the sub position of the first range.
5640  *
5641  * 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)]
5642  * The return DataArrayInt will contain : **[1,2,4,0,2,2]**
5643  * This method is often called in pair with DataArrayInt::findRangeIdForEachTuple method.
5644  * 
5645  * \param [in] ranges typically come from output of MEDCouplingUMesh::ComputeRangesFromTypeDistribution. Each range is specified like this : 1st component is
5646  *             for lower value included and 2nd component is the upper value of corresponding range **excluded**.
5647  * \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
5648  *        is thrown if no ranges in \a ranges contains value in \a this.
5649  * \sa DataArrayInt::findRangeIdForEachTuple
5650  */
5651 DataArrayInt *DataArrayInt::findIdInRangeForEachTuple(const DataArrayInt *ranges) const throw(INTERP_KERNEL::Exception)
5652 {
5653   if(!ranges)
5654     throw INTERP_KERNEL::Exception("DataArrayInt::findIdInRangeForEachTuple : null input pointer !");
5655   if(ranges->getNumberOfComponents()!=2)
5656     throw INTERP_KERNEL::Exception("DataArrayInt::findIdInRangeForEachTuple : input DataArrayInt instance should have 2 components !");
5657   checkAllocated();
5658   if(getNumberOfComponents()!=1)
5659     throw INTERP_KERNEL::Exception("DataArrayInt::findIdInRangeForEachTuple : this should have only one component !");
5660   int nbTuples=getNumberOfTuples();
5661   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbTuples,1);
5662   int nbOfRanges=ranges->getNumberOfTuples();
5663   const int *rangesPtr=ranges->getConstPointer();
5664   int *retPtr=ret->getPointer();
5665   const int *inPtr=getConstPointer();
5666   for(int i=0;i<nbTuples;i++,retPtr++)
5667     {
5668       int val=inPtr[i];
5669       bool found=false;
5670       for(int j=0;j<nbOfRanges && !found;j++)
5671         if(val>=rangesPtr[2*j] && val<rangesPtr[2*j+1])
5672           { *retPtr=val-rangesPtr[2*j]; found=true; }
5673       if(found)
5674         continue;
5675       else
5676         {
5677           std::ostringstream oss; oss << "DataArrayInt::findIdInRangeForEachTuple : tuple #" << i << " not found by any ranges !";
5678           throw INTERP_KERNEL::Exception(oss.str().c_str());
5679         }
5680     }
5681   ret->incrRef();
5682   return ret;
5683 }
5684
5685 /*!
5686  * 
5687  * \param [in] nbTimes specifies the nb of times each tuples in \a this will be duplicated contiguouly in returned DataArrayInt instance.
5688  *             \a nbTimes  should be at least equal to 1.
5689  * \return a newly allocated DataArrayInt having one component and number of tuples equal to \a nbTimes * \c this->getNumberOfTuples.
5690  * \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.
5691  */
5692 DataArrayInt *DataArrayInt::duplicateEachTupleNTimes(int nbTimes) const throw(INTERP_KERNEL::Exception)
5693 {
5694   checkAllocated();
5695   if(getNumberOfComponents()!=1)
5696     throw INTERP_KERNEL::Exception("DataArrayInt::duplicateEachTupleNTimes : this should have only one component !");
5697   if(nbTimes<1)
5698     throw INTERP_KERNEL::Exception("DataArrayInt::duplicateEachTupleNTimes : nb times should be >= 1 !");
5699   int nbTuples=getNumberOfTuples();
5700   const int *inPtr=getConstPointer();
5701   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbTimes*nbTuples,1);
5702   int *retPtr=ret->getPointer();
5703   for(int i=0;i<nbTuples;i++,inPtr++)
5704     {
5705       int val=*inPtr;
5706       for(int j=0;j<nbTimes;j++,retPtr++)
5707         *retPtr=val;
5708     }
5709   ret->copyStringInfoFrom(*this);
5710   ret->incrRef();
5711   return ret;
5712 }
5713
5714 /*!
5715  * This method returns all different values found in 'this'.
5716  */
5717 std::set<int> DataArrayInt::getDifferentValues() const throw(INTERP_KERNEL::Exception)
5718 {
5719   checkAllocated();
5720   std::set<int> ret;
5721   ret.insert(getConstPointer(),getConstPointer()+getNbOfElems());
5722   return ret;
5723 }
5724
5725 DataArrayInt *DataArrayInt::Add(const DataArrayInt *a1, const DataArrayInt *a2) throw(INTERP_KERNEL::Exception)
5726 {
5727   if(!a1 || !a2)
5728     throw INTERP_KERNEL::Exception("DataArrayInt::Add : input DataArrayInt instance is NULL !");
5729   int nbOfTuple=a1->getNumberOfTuples();
5730   int nbOfTuple2=a2->getNumberOfTuples();
5731   int nbOfComp=a1->getNumberOfComponents();
5732   int nbOfComp2=a2->getNumberOfComponents();
5733   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=0;
5734   if(nbOfTuple==nbOfTuple2)
5735     {
5736       if(nbOfComp==nbOfComp2)
5737         {
5738           ret=DataArrayInt::New();
5739           ret->alloc(nbOfTuple,nbOfComp);
5740           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::plus<int>());
5741           ret->copyStringInfoFrom(*a1);
5742         }
5743       else
5744         {
5745           int nbOfCompMin,nbOfCompMax;
5746           const DataArrayInt *aMin, *aMax;
5747           if(nbOfComp>nbOfComp2)
5748             {
5749               nbOfCompMin=nbOfComp2; nbOfCompMax=nbOfComp;
5750               aMin=a2; aMax=a1;
5751             }
5752           else
5753             {
5754               nbOfCompMin=nbOfComp; nbOfCompMax=nbOfComp2;
5755               aMin=a1; aMax=a2;
5756             }
5757           if(nbOfCompMin==1)
5758             {
5759               ret=DataArrayInt::New();
5760               ret->alloc(nbOfTuple,nbOfCompMax);
5761               const int *aMinPtr=aMin->getConstPointer();
5762               const int *aMaxPtr=aMax->getConstPointer();
5763               int *res=ret->getPointer();
5764               for(int i=0;i<nbOfTuple;i++)
5765                 res=std::transform(aMaxPtr+i*nbOfCompMax,aMaxPtr+(i+1)*nbOfCompMax,res,std::bind2nd(std::plus<int>(),aMinPtr[i]));
5766               ret->copyStringInfoFrom(*aMax);
5767             }
5768           else
5769             throw INTERP_KERNEL::Exception("Nb of components mismatch for array Add !");
5770         }
5771     }
5772   else if((nbOfTuple==1 && nbOfTuple2>1) || (nbOfTuple>1 && nbOfTuple2==1))
5773     {
5774       if(nbOfComp==nbOfComp2)
5775         {
5776           int nbOfTupleMax=std::max(nbOfTuple,nbOfTuple2);
5777           const DataArrayInt *aMin=nbOfTuple>nbOfTuple2?a2:a1;
5778           const DataArrayInt *aMax=nbOfTuple>nbOfTuple2?a1:a2;
5779           const int *aMinPtr=aMin->getConstPointer(),*aMaxPtr=aMax->getConstPointer();
5780           ret=DataArrayInt::New();
5781           ret->alloc(nbOfTupleMax,nbOfComp);
5782           int *res=ret->getPointer();
5783           for(int i=0;i<nbOfTupleMax;i++)
5784             res=std::transform(aMaxPtr+i*nbOfComp,aMaxPtr+(i+1)*nbOfComp,aMinPtr,res,std::plus<int>());
5785           ret->copyStringInfoFrom(*aMax);
5786         }
5787       else
5788         throw INTERP_KERNEL::Exception("Nb of components mismatch for array Add !");
5789     }
5790   else
5791     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Add !");
5792   ret->incrRef();
5793   return ret;
5794 }
5795
5796 void DataArrayInt::addEqual(const DataArrayInt *other) throw(INTERP_KERNEL::Exception)
5797 {
5798   if(!other)
5799     throw INTERP_KERNEL::Exception("DataArrayInt::addEqual : input DataArrayInt instance is NULL !");
5800   const char *msg="Nb of tuples mismatch for DataArrayInt::addEqual  !";
5801   int nbOfTuple=getNumberOfTuples();
5802   int nbOfTuple2=other->getNumberOfTuples();
5803   int nbOfComp=getNumberOfComponents();
5804   int nbOfComp2=other->getNumberOfComponents();
5805   if(nbOfTuple==nbOfTuple2)
5806     {
5807       if(nbOfComp==nbOfComp2)
5808         {
5809           std::transform(begin(),end(),other->begin(),getPointer(),std::plus<int>());
5810         }
5811       else if(nbOfComp2==1)
5812         {
5813           int *ptr=getPointer();
5814           const int *ptrc=other->getConstPointer();
5815           for(int i=0;i<nbOfTuple;i++)
5816             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::plus<int>(),*ptrc++));
5817         }
5818       else
5819         throw INTERP_KERNEL::Exception(msg);
5820     }
5821   else if(nbOfTuple2==1)
5822     {
5823       if(nbOfComp2==nbOfComp)
5824         {
5825           int *ptr=getPointer();
5826           const int *ptrc=other->getConstPointer();
5827           for(int i=0;i<nbOfTuple;i++)
5828             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::plus<int>());
5829         }
5830       else
5831         throw INTERP_KERNEL::Exception(msg);
5832     }
5833   else
5834     throw INTERP_KERNEL::Exception(msg);
5835   declareAsNew();
5836 }
5837
5838 DataArrayInt *DataArrayInt::Substract(const DataArrayInt *a1, const DataArrayInt *a2) throw(INTERP_KERNEL::Exception)
5839 {
5840   if(!a1 || !a2)
5841     throw INTERP_KERNEL::Exception("DataArrayInt::Substract : input DataArrayInt instance is NULL !");
5842   int nbOfTuple1=a1->getNumberOfTuples();
5843   int nbOfTuple2=a2->getNumberOfTuples();
5844   int nbOfComp1=a1->getNumberOfComponents();
5845   int nbOfComp2=a2->getNumberOfComponents();
5846   if(nbOfTuple2==nbOfTuple1)
5847     {
5848       if(nbOfComp1==nbOfComp2)
5849         {
5850           MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
5851           ret->alloc(nbOfTuple2,nbOfComp1);
5852           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::minus<int>());
5853           ret->copyStringInfoFrom(*a1);
5854           ret->incrRef();
5855           return ret;
5856         }
5857       else if(nbOfComp2==1)
5858         {
5859           MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
5860           ret->alloc(nbOfTuple1,nbOfComp1);
5861           const int *a2Ptr=a2->getConstPointer();
5862           const int *a1Ptr=a1->getConstPointer();
5863           int *res=ret->getPointer();
5864           for(int i=0;i<nbOfTuple1;i++)
5865             res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::minus<int>(),a2Ptr[i]));
5866           ret->copyStringInfoFrom(*a1);
5867           ret->incrRef();
5868           return ret;
5869         }
5870       else
5871         {
5872           a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Substract !");
5873           return 0;
5874         }
5875     }
5876   else if(nbOfTuple2==1)
5877     {
5878       a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Substract !");
5879       MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
5880       ret->alloc(nbOfTuple1,nbOfComp1);
5881       const int *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
5882       int *pt=ret->getPointer();
5883       for(int i=0;i<nbOfTuple1;i++)
5884         pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::minus<int>());
5885       ret->copyStringInfoFrom(*a1);
5886       ret->incrRef();
5887       return ret;
5888     }
5889   else
5890     {
5891       a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Substract !");//will always throw an exception
5892       return 0;
5893     }
5894 }
5895
5896 void DataArrayInt::substractEqual(const DataArrayInt *other) throw(INTERP_KERNEL::Exception)
5897 {
5898   if(!other)
5899     throw INTERP_KERNEL::Exception("DataArrayInt::substractEqual : input DataArrayInt instance is NULL !");
5900   const char *msg="Nb of tuples mismatch for DataArrayInt::substractEqual  !";
5901   int nbOfTuple=getNumberOfTuples();
5902   int nbOfTuple2=other->getNumberOfTuples();
5903   int nbOfComp=getNumberOfComponents();
5904   int nbOfComp2=other->getNumberOfComponents();
5905   if(nbOfTuple==nbOfTuple2)
5906     {
5907       if(nbOfComp==nbOfComp2)
5908         {
5909           std::transform(begin(),end(),other->begin(),getPointer(),std::minus<int>());
5910         }
5911       else if(nbOfComp2==1)
5912         {
5913           int *ptr=getPointer();
5914           const int *ptrc=other->getConstPointer();
5915           for(int i=0;i<nbOfTuple;i++)
5916             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::minus<int>(),*ptrc++));
5917         }
5918       else
5919         throw INTERP_KERNEL::Exception(msg);
5920     }
5921   else if(nbOfTuple2==1)
5922     {
5923       int *ptr=getPointer();
5924       const int *ptrc=other->getConstPointer();
5925       for(int i=0;i<nbOfTuple;i++)
5926         std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::minus<int>());
5927     }
5928   else
5929     throw INTERP_KERNEL::Exception(msg);
5930   declareAsNew();
5931 }
5932
5933 DataArrayInt *DataArrayInt::Multiply(const DataArrayInt *a1, const DataArrayInt *a2) throw(INTERP_KERNEL::Exception)
5934 {
5935   if(!a1 || !a2)
5936     throw INTERP_KERNEL::Exception("DataArrayInt::Multiply : input DataArrayInt instance is NULL !");
5937   int nbOfTuple=a1->getNumberOfTuples();
5938   int nbOfTuple2=a2->getNumberOfTuples();
5939   int nbOfComp=a1->getNumberOfComponents();
5940   int nbOfComp2=a2->getNumberOfComponents();
5941   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=0;
5942   if(nbOfTuple==nbOfTuple2)
5943     {
5944       if(nbOfComp==nbOfComp2)
5945         {
5946           ret=DataArrayInt::New();
5947           ret->alloc(nbOfTuple,nbOfComp);
5948           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::multiplies<int>());
5949           ret->copyStringInfoFrom(*a1);
5950         }
5951       else
5952         {
5953           int nbOfCompMin,nbOfCompMax;
5954           const DataArrayInt *aMin, *aMax;
5955           if(nbOfComp>nbOfComp2)
5956             {
5957               nbOfCompMin=nbOfComp2; nbOfCompMax=nbOfComp;
5958               aMin=a2; aMax=a1;
5959             }
5960           else
5961             {
5962               nbOfCompMin=nbOfComp; nbOfCompMax=nbOfComp2;
5963               aMin=a1; aMax=a2;
5964             }
5965           if(nbOfCompMin==1)
5966             {
5967               ret=DataArrayInt::New();
5968               ret->alloc(nbOfTuple,nbOfCompMax);
5969               const int *aMinPtr=aMin->getConstPointer();
5970               const int *aMaxPtr=aMax->getConstPointer();
5971               int *res=ret->getPointer();
5972               for(int i=0;i<nbOfTuple;i++)
5973                 res=std::transform(aMaxPtr+i*nbOfCompMax,aMaxPtr+(i+1)*nbOfCompMax,res,std::bind2nd(std::multiplies<int>(),aMinPtr[i]));
5974               ret->copyStringInfoFrom(*aMax);
5975             }
5976           else
5977             throw INTERP_KERNEL::Exception("Nb of components mismatch for array Multiply !");
5978         }
5979     }
5980   else if((nbOfTuple==1 && nbOfTuple2>1) || (nbOfTuple>1 && nbOfTuple2==1))
5981     {
5982       if(nbOfComp==nbOfComp2)
5983         {
5984           int nbOfTupleMax=std::max(nbOfTuple,nbOfTuple2);
5985           const DataArrayInt *aMin=nbOfTuple>nbOfTuple2?a2:a1;
5986           const DataArrayInt *aMax=nbOfTuple>nbOfTuple2?a1:a2;
5987           const int *aMinPtr=aMin->getConstPointer(),*aMaxPtr=aMax->getConstPointer();
5988           ret=DataArrayInt::New();
5989           ret->alloc(nbOfTupleMax,nbOfComp);
5990           int *res=ret->getPointer();
5991           for(int i=0;i<nbOfTupleMax;i++)
5992             res=std::transform(aMaxPtr+i*nbOfComp,aMaxPtr+(i+1)*nbOfComp,aMinPtr,res,std::multiplies<int>());
5993           ret->copyStringInfoFrom(*aMax);
5994         }
5995       else
5996         throw INTERP_KERNEL::Exception("Nb of components mismatch for array Multiply !");
5997     }
5998   else
5999     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Multiply !");
6000   ret->incrRef();
6001   return ret;
6002 }
6003
6004 void DataArrayInt::multiplyEqual(const DataArrayInt *other) throw(INTERP_KERNEL::Exception)
6005 {
6006   if(!other)
6007     throw INTERP_KERNEL::Exception("DataArrayInt::multiplyEqual : input DataArrayInt instance is NULL !");
6008   const char *msg="Nb of tuples mismatch for DataArrayInt::multiplyEqual !";
6009   int nbOfTuple=getNumberOfTuples();
6010   int nbOfTuple2=other->getNumberOfTuples();
6011   int nbOfComp=getNumberOfComponents();
6012   int nbOfComp2=other->getNumberOfComponents();
6013   if(nbOfTuple==nbOfTuple2)
6014     {
6015       if(nbOfComp==nbOfComp2)
6016         {
6017           std::transform(begin(),end(),other->begin(),getPointer(),std::multiplies<int>());
6018         }
6019       else if(nbOfComp2==1)
6020         {
6021           int *ptr=getPointer();
6022           const int *ptrc=other->getConstPointer();
6023           for(int i=0;i<nbOfTuple;i++)
6024             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::multiplies<int>(),*ptrc++));    
6025         }
6026       else
6027         throw INTERP_KERNEL::Exception(msg);
6028     }
6029   else if(nbOfTuple2==1)
6030     {
6031       if(nbOfComp2==nbOfComp)
6032         {
6033           int *ptr=getPointer();
6034           const int *ptrc=other->getConstPointer();
6035           for(int i=0;i<nbOfTuple;i++)
6036             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::multiplies<int>());
6037         }
6038       else
6039         throw INTERP_KERNEL::Exception(msg);
6040     }
6041   else
6042     throw INTERP_KERNEL::Exception(msg);
6043   declareAsNew();
6044 }
6045
6046 DataArrayInt *DataArrayInt::Divide(const DataArrayInt *a1, const DataArrayInt *a2) throw(INTERP_KERNEL::Exception)
6047 {
6048   if(!a1 || !a2)
6049     throw INTERP_KERNEL::Exception("DataArrayInt::Divide : input DataArrayInt instance is NULL !");
6050   int nbOfTuple1=a1->getNumberOfTuples();
6051   int nbOfTuple2=a2->getNumberOfTuples();
6052   int nbOfComp1=a1->getNumberOfComponents();
6053   int nbOfComp2=a2->getNumberOfComponents();
6054   if(nbOfTuple2==nbOfTuple1)
6055     {
6056       if(nbOfComp1==nbOfComp2)
6057         {
6058           MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6059           ret->alloc(nbOfTuple2,nbOfComp1);
6060           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::divides<int>());
6061           ret->copyStringInfoFrom(*a1);
6062           ret->incrRef();
6063           return ret;
6064         }
6065       else if(nbOfComp2==1)
6066         {
6067           MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6068           ret->alloc(nbOfTuple1,nbOfComp1);
6069           const int *a2Ptr=a2->getConstPointer();
6070           const int *a1Ptr=a1->getConstPointer();
6071           int *res=ret->getPointer();
6072           for(int i=0;i<nbOfTuple1;i++)
6073             res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::divides<int>(),a2Ptr[i]));
6074           ret->copyStringInfoFrom(*a1);
6075           ret->incrRef();
6076           return ret;
6077         }
6078       else
6079         {
6080           a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Divide !");
6081           return 0;
6082         }
6083     }
6084   else if(nbOfTuple2==1)
6085     {
6086       a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Divide !");
6087       MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6088       ret->alloc(nbOfTuple1,nbOfComp1);
6089       const int *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
6090       int *pt=ret->getPointer();
6091       for(int i=0;i<nbOfTuple1;i++)
6092         pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::divides<int>());
6093       ret->copyStringInfoFrom(*a1);
6094       ret->incrRef();
6095       return ret;
6096     }
6097   else
6098     {
6099       a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Divide !");//will always throw an exception
6100       return 0;
6101     }
6102 }
6103
6104 void DataArrayInt::divideEqual(const DataArrayInt *other) throw(INTERP_KERNEL::Exception)
6105 {
6106   if(!other)
6107     throw INTERP_KERNEL::Exception("DataArrayInt::divideEqual : input DataArrayInt instance is NULL !");
6108   const char *msg="Nb of tuples mismatch for DataArrayInt::divideEqual !";
6109   int nbOfTuple=getNumberOfTuples();
6110   int nbOfTuple2=other->getNumberOfTuples();
6111   int nbOfComp=getNumberOfComponents();
6112   int nbOfComp2=other->getNumberOfComponents();
6113   if(nbOfTuple==nbOfTuple2)
6114     {
6115       if(nbOfComp==nbOfComp2)
6116         {
6117           std::transform(begin(),end(),other->begin(),getPointer(),std::divides<int>());
6118         }
6119       else if(nbOfComp2==1)
6120         {
6121           int *ptr=getPointer();
6122           const int *ptrc=other->getConstPointer();
6123           for(int i=0;i<nbOfTuple;i++)
6124             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::divides<int>(),*ptrc++));
6125         }
6126       else
6127         throw INTERP_KERNEL::Exception(msg);
6128     }
6129   else if(nbOfTuple2==1)
6130     {
6131       if(nbOfComp2==nbOfComp)
6132         {
6133           int *ptr=getPointer();
6134           const int *ptrc=other->getConstPointer();
6135           for(int i=0;i<nbOfTuple;i++)
6136             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::divides<int>());
6137         }
6138       else
6139         throw INTERP_KERNEL::Exception(msg);
6140     }
6141   else
6142     throw INTERP_KERNEL::Exception(msg);
6143   declareAsNew();
6144 }
6145
6146 DataArrayInt *DataArrayInt::Modulus(const DataArrayInt *a1, const DataArrayInt *a2) throw(INTERP_KERNEL::Exception)
6147 {
6148     if(!a1 || !a2)
6149     throw INTERP_KERNEL::Exception("DataArrayInt::Modulus : input DataArrayInt instance is NULL !");
6150   int nbOfTuple1=a1->getNumberOfTuples();
6151   int nbOfTuple2=a2->getNumberOfTuples();
6152   int nbOfComp1=a1->getNumberOfComponents();
6153   int nbOfComp2=a2->getNumberOfComponents();
6154   if(nbOfTuple2==nbOfTuple1)
6155     {
6156       if(nbOfComp1==nbOfComp2)
6157         {
6158           MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6159           ret->alloc(nbOfTuple2,nbOfComp1);
6160           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::modulus<int>());
6161           ret->copyStringInfoFrom(*a1);
6162           ret->incrRef();
6163           return ret;
6164         }
6165       else if(nbOfComp2==1)
6166         {
6167           MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6168           ret->alloc(nbOfTuple1,nbOfComp1);
6169           const int *a2Ptr=a2->getConstPointer();
6170           const int *a1Ptr=a1->getConstPointer();
6171           int *res=ret->getPointer();
6172           for(int i=0;i<nbOfTuple1;i++)
6173             res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::modulus<int>(),a2Ptr[i]));
6174           ret->copyStringInfoFrom(*a1);
6175           ret->incrRef();
6176           return ret;
6177         }
6178       else
6179         {
6180           a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Modulus !");
6181           return 0;
6182         }
6183     }
6184   else if(nbOfTuple2==1)
6185     {
6186       a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Modulus !");
6187       MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6188       ret->alloc(nbOfTuple1,nbOfComp1);
6189       const int *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
6190       int *pt=ret->getPointer();
6191       for(int i=0;i<nbOfTuple1;i++)
6192         pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::modulus<int>());
6193       ret->copyStringInfoFrom(*a1);
6194       ret->incrRef();
6195       return ret;
6196     }
6197   else
6198     {
6199       a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Modulus !");//will always throw an exception
6200       return 0;
6201     }
6202 }
6203
6204 void DataArrayInt::modulusEqual(const DataArrayInt *other) throw(INTERP_KERNEL::Exception)
6205 {
6206   if(!other)
6207     throw INTERP_KERNEL::Exception("DataArrayInt::modulusEqual : input DataArrayInt instance is NULL !");
6208   const char *msg="Nb of tuples mismatch for DataArrayInt::modulusEqual !";
6209   int nbOfTuple=getNumberOfTuples();
6210   int nbOfTuple2=other->getNumberOfTuples();
6211   int nbOfComp=getNumberOfComponents();
6212   int nbOfComp2=other->getNumberOfComponents();
6213   if(nbOfTuple==nbOfTuple2)
6214     {
6215       if(nbOfComp==nbOfComp2)
6216         {
6217           std::transform(begin(),end(),other->begin(),getPointer(),std::modulus<int>());
6218         }
6219       else if(nbOfComp2==1)
6220         {
6221           if(nbOfComp2==nbOfComp)
6222             {
6223               int *ptr=getPointer();
6224               const int *ptrc=other->getConstPointer();
6225               for(int i=0;i<nbOfTuple;i++)
6226                 std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::modulus<int>(),*ptrc++));
6227             }
6228           else
6229             throw INTERP_KERNEL::Exception(msg);
6230         }
6231       else
6232         throw INTERP_KERNEL::Exception(msg);
6233     }
6234   else if(nbOfTuple2==1)
6235     {
6236       int *ptr=getPointer();
6237       const int *ptrc=other->getConstPointer();
6238       for(int i=0;i<nbOfTuple;i++)
6239         std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::modulus<int>());
6240     }
6241   else
6242     throw INTERP_KERNEL::Exception(msg);
6243   declareAsNew();
6244 }
6245
6246 int *DataArrayInt::CheckAndPreparePermutation(const int *start, const int *end)
6247 {
6248   std::size_t sz=std::distance(start,end);
6249   int *ret=new int[sz];
6250   int *work=new int[sz];
6251   std::copy(start,end,work);
6252   std::sort(work,work+sz);
6253   if(std::unique(work,work+sz)!=work+sz)
6254     {
6255       delete [] work;
6256       delete [] ret;
6257       throw INTERP_KERNEL::Exception("Some elements are equals in the specified array !");
6258     }
6259   int *iter2=ret;
6260   for(const int *iter=start;iter!=end;iter++,iter2++)
6261     *iter2=(int)std::distance(work,std::find(work,work+sz,*iter));
6262   delete [] work;
6263   return ret;
6264 }
6265
6266 DataArrayInt *DataArrayInt::Range(int begin, int end, int step) throw(INTERP_KERNEL::Exception)
6267 {
6268   int nbOfTuples=GetNumberOfItemGivenBESRelative(begin,end,step,"DataArrayInt::Range");
6269   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6270   ret->alloc(nbOfTuples,1);
6271   int *ptr=ret->getPointer();
6272   if(step>0)
6273     {
6274       for(int i=begin;i<end;i+=step,ptr++)
6275         *ptr=i;
6276     }
6277   else
6278     {
6279       for(int i=begin;i>end;i+=step,ptr++)
6280         *ptr=i;
6281     }
6282   ret->incrRef();
6283   return ret;
6284 }
6285
6286 /*!
6287  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
6288  * Server side.
6289  */
6290 void DataArrayInt::getTinySerializationIntInformation(std::vector<int>& tinyInfo) const
6291 {
6292   tinyInfo.resize(2);
6293   if(isAllocated())
6294     {
6295       tinyInfo[0]=getNumberOfTuples();
6296       tinyInfo[1]=getNumberOfComponents();
6297     }
6298   else
6299     {
6300       tinyInfo[0]=-1;
6301       tinyInfo[1]=-1;
6302     }
6303 }
6304
6305 /*!
6306  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
6307  * Server side.
6308  */
6309 void DataArrayInt::getTinySerializationStrInformation(std::vector<std::string>& tinyInfo) const
6310 {
6311   if(isAllocated())
6312     {
6313       int nbOfCompo=getNumberOfComponents();
6314       tinyInfo.resize(nbOfCompo+1);
6315       tinyInfo[0]=getName();
6316       for(int i=0;i<nbOfCompo;i++)
6317         tinyInfo[i+1]=getInfoOnComponent(i);
6318     }
6319   else
6320     {
6321       tinyInfo.resize(1);
6322       tinyInfo[0]=getName();
6323     }
6324 }
6325
6326 /*!
6327  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
6328  * This method returns if a feeding is needed.
6329  */
6330 bool DataArrayInt::resizeForUnserialization(const std::vector<int>& tinyInfoI)
6331 {
6332   int nbOfTuple=tinyInfoI[0];
6333   int nbOfComp=tinyInfoI[1];
6334   if(nbOfTuple!=-1 || nbOfComp!=-1)
6335     {
6336       alloc(nbOfTuple,nbOfComp);
6337       return true;
6338     }
6339   return false;
6340 }
6341
6342 /*!
6343  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
6344  * This method returns if a feeding is needed.
6345  */
6346 void DataArrayInt::finishUnserialization(const std::vector<int>& tinyInfoI, const std::vector<std::string>& tinyInfoS)
6347 {
6348   setName(tinyInfoS[0].c_str());
6349   if(isAllocated())
6350     {
6351       int nbOfCompo=getNumberOfComponents();
6352       for(int i=0;i<nbOfCompo;i++)
6353         setInfoOnComponent(i,tinyInfoS[i+1].c_str());
6354     }
6355 }
6356
6357 DataArrayIntIterator::DataArrayIntIterator(DataArrayInt *da):_da(da),_pt(0),_tuple_id(0),_nb_comp(0),_nb_tuple(0)
6358 {
6359   if(_da)
6360     {
6361       _da->incrRef();
6362       if(_da->isAllocated())
6363         {
6364           _nb_comp=da->getNumberOfComponents();
6365           _nb_tuple=da->getNumberOfTuples();
6366           _pt=da->getPointer();
6367         }
6368     }
6369 }
6370
6371 DataArrayIntIterator::~DataArrayIntIterator()
6372 {
6373   if(_da)
6374     _da->decrRef();
6375 }
6376
6377 DataArrayIntTuple *DataArrayIntIterator::nextt()
6378 {
6379   if(_tuple_id<_nb_tuple)
6380     {
6381       _tuple_id++;
6382       DataArrayIntTuple *ret=new DataArrayIntTuple(_pt,_nb_comp);
6383       _pt+=_nb_comp;
6384       return ret;
6385     }
6386   else
6387     return 0;
6388 }
6389
6390 DataArrayIntTuple::DataArrayIntTuple(int *pt, int nbOfComp):_pt(pt),_nb_of_compo(nbOfComp)
6391 {
6392 }
6393
6394 std::string DataArrayIntTuple::repr() const
6395 {
6396   std::ostringstream oss; oss << "(";
6397   for(int i=0;i<_nb_of_compo-1;i++)
6398     oss << _pt[i] << ", ";
6399   oss << _pt[_nb_of_compo-1] << ")";
6400   return oss.str();
6401 }
6402
6403 int DataArrayIntTuple::intValue() const throw(INTERP_KERNEL::Exception)
6404 {
6405   if(_nb_of_compo==1)
6406     return *_pt;
6407   throw INTERP_KERNEL::Exception("DataArrayIntTuple::intValue : DataArrayIntTuple instance has not exactly 1 component -> Not possible to convert it into an integer !");
6408 }
6409
6410 /*!
6411  * This method returns a newly allocated instance the caller should dealed with by a ParaMEDMEM::DataArrayInt::decrRef.
6412  * This method performs \b no copy of data. The content is only referenced using ParaMEDMEM::DataArrayInt::useArray with ownership set to \b false.
6413  * 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
6414  * \b nbOfCompo=1 and \bnbOfTuples==this->_nb_of_elem.
6415  */
6416 DataArrayInt *DataArrayIntTuple::buildDAInt(int nbOfTuples, int nbOfCompo) const throw(INTERP_KERNEL::Exception)
6417 {
6418   if((_nb_of_compo==nbOfCompo && nbOfTuples==1) || (_nb_of_compo==nbOfTuples && nbOfCompo==1))
6419     {
6420       DataArrayInt *ret=DataArrayInt::New();
6421       ret->useArray(_pt,false,CPP_DEALLOC,nbOfTuples,nbOfCompo);
6422       return ret;
6423     }
6424   else
6425     {
6426       std::ostringstream oss; oss << "DataArrayIntTuple::buildDAInt : unable to build a requested DataArrayInt instance with nbofTuple=" << nbOfTuples << " and nbOfCompo=" << nbOfCompo;
6427       oss << ".\nBecause the number of elements in this is " << _nb_of_compo << " !";
6428       throw INTERP_KERNEL::Exception(oss.str().c_str());
6429     }
6430 }