Salome HOME
Merge from V6_main (dev of Anthony GEAY) 11/06/2013
[modules/med.git] / src / MEDCoupling / MEDCouplingMemArray.cxx
1 // Copyright (C) 2007-2013  CEA/DEN, EDF R&D
2 //
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License.
7 //
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11 // Lesser General Public License for more details.
12 //
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
16 //
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
18 //
19 // Author : Anthony Geay (CEA/DEN)
20
21 #include "MEDCouplingMemArray.txx"
22 #include "MEDCouplingAutoRefCountObjectPtr.hxx"
23
24 #include "GenMathFormulae.hxx"
25 #include "InterpKernelExprParser.hxx"
26
27 #include <set>
28 #include <cmath>
29 #include <limits>
30 #include <numeric>
31 #include <algorithm>
32 #include <functional>
33
34 typedef double (*MYFUNCPTR)(double);
35
36 using namespace ParaMEDMEM;
37
38 template<int SPACEDIM>
39 void DataArrayDouble::findCommonTuplesAlg(const double *bbox, int nbNodes, int limitNodeId, double prec, DataArrayInt *c, DataArrayInt *cI) const
40 {
41   const double *coordsPtr=getConstPointer();
42   BBTreePts<SPACEDIM,int> myTree(bbox,0,0,nbNodes,prec);
43   std::vector<bool> isDone(nbNodes);
44   for(int i=0;i<nbNodes;i++)
45     {
46       if(!isDone[i])
47         {
48           std::vector<int> intersectingElems;
49           myTree.getElementsAroundPoint(coordsPtr+i*SPACEDIM,intersectingElems);
50           if(intersectingElems.size()>1)
51             {
52               std::vector<int> commonNodes;
53               for(std::vector<int>::const_iterator it=intersectingElems.begin();it!=intersectingElems.end();it++)
54                 if(*it!=i)
55                   if(*it>=limitNodeId)
56                     {
57                       commonNodes.push_back(*it);
58                       isDone[*it]=true;
59                     }
60               if(!commonNodes.empty())
61                 {
62                   cI->pushBackSilent(cI->back()+(int)commonNodes.size()+1);
63                   c->pushBackSilent(i);
64                   c->insertAtTheEnd(commonNodes.begin(),commonNodes.end());
65                 }
66             }
67         }
68     }
69 }
70
71 template<int SPACEDIM>
72 void DataArrayDouble::FindTupleIdsNearTuplesAlg(const BBTreePts<SPACEDIM,int>& myTree, const double *pos, int nbOfTuples, double eps,
73                                                 DataArrayInt *c, DataArrayInt *cI)
74 {
75   for(int i=0;i<nbOfTuples;i++)
76     {
77       std::vector<int> intersectingElems;
78       myTree.getElementsAroundPoint(pos+i*SPACEDIM,intersectingElems);
79       std::vector<int> commonNodes;
80       for(std::vector<int>::const_iterator it=intersectingElems.begin();it!=intersectingElems.end();it++)
81         commonNodes.push_back(*it);
82       cI->pushBackSilent(cI->back()+(int)commonNodes.size());
83       c->insertAtTheEnd(commonNodes.begin(),commonNodes.end());
84     }
85 }
86
87 template<int SPACEDIM>
88 void DataArrayDouble::FindClosestTupleIdAlg(const BBTreePts<SPACEDIM,int>& myTree, double dist, const double *pos, int nbOfTuples, const double *thisPt, int thisNbOfTuples, int *res)
89 {
90   double distOpt(dist);
91   const double *p(pos);
92   int *r(res);
93   for(int i=0;i<nbOfTuples;i++,p+=SPACEDIM,r++)
94     {
95       while(true)
96         {
97           int elem=-1;
98           double ret=myTree.getElementsAroundPoint2(p,distOpt,elem);
99           if(ret!=std::numeric_limits<double>::max())
100             {
101               distOpt=std::max(ret,1e-4);
102               *r=elem;
103               break;
104             }
105           else
106             { distOpt=2*distOpt; continue; }
107         }
108     }
109 }
110
111 std::size_t DataArray::getHeapMemorySize() const
112 {
113   std::size_t sz1=_name.capacity();
114   std::size_t sz2=_info_on_compo.capacity();
115   std::size_t sz3=0;
116   for(std::vector<std::string>::const_iterator it=_info_on_compo.begin();it!=_info_on_compo.end();it++)
117     sz3+=(*it).capacity();
118   return sz1+sz2+sz3;
119 }
120
121 /*!
122  * Sets the attribute \a _name of \a this array.
123  * See \ref MEDCouplingArrayBasicsName "DataArrays infos" for more information.
124  *  \param [in] name - new array name
125  */
126 void DataArray::setName(const char *name)
127 {
128   _name=name;
129 }
130
131 /*!
132  * Copies textual data from an \a other DataArray. The copied data are
133  * - the name attribute,
134  * - the information of components.
135  *
136  * For more information on these data see \ref MEDCouplingArrayBasicsName "DataArrays infos".
137  *
138  *  \param [in] other - another instance of DataArray to copy the textual data from.
139  *  \throw If number of components of \a this array differs from that of the \a other.
140  */
141 void DataArray::copyStringInfoFrom(const DataArray& other) throw(INTERP_KERNEL::Exception)
142 {
143   if(_info_on_compo.size()!=other._info_on_compo.size())
144     throw INTERP_KERNEL::Exception("Size of arrays mismatches on copyStringInfoFrom !");
145   _name=other._name;
146   _info_on_compo=other._info_on_compo;
147 }
148
149 void DataArray::copyPartOfStringInfoFrom(const DataArray& other, const std::vector<int>& compoIds) throw(INTERP_KERNEL::Exception)
150 {
151   int nbOfCompoOth=other.getNumberOfComponents();
152   std::size_t newNbOfCompo=compoIds.size();
153   for(std::size_t i=0;i<newNbOfCompo;i++)
154     if(compoIds[i]>=nbOfCompoOth || compoIds[i]<0)
155       {
156         std::ostringstream oss; oss << "Specified component id is out of range (" << compoIds[i] << ") compared with nb of actual components (" << nbOfCompoOth << ")";
157         throw INTERP_KERNEL::Exception(oss.str().c_str());
158       }
159   for(std::size_t i=0;i<newNbOfCompo;i++)
160     setInfoOnComponent((int)i,other.getInfoOnComponent(compoIds[i]).c_str());
161 }
162
163 void DataArray::copyPartOfStringInfoFrom2(const std::vector<int>& compoIds, const DataArray& other) throw(INTERP_KERNEL::Exception)
164 {
165   int nbOfCompo=getNumberOfComponents();
166   std::size_t partOfCompoToSet=compoIds.size();
167   if((int)partOfCompoToSet!=other.getNumberOfComponents())
168     throw INTERP_KERNEL::Exception("Given compoIds has not the same size as number of components of given array !");
169   for(std::size_t i=0;i<partOfCompoToSet;i++)
170     if(compoIds[i]>=nbOfCompo || compoIds[i]<0)
171       {
172         std::ostringstream oss; oss << "Specified component id is out of range (" << compoIds[i] << ") compared with nb of actual components (" << nbOfCompo << ")";
173         throw INTERP_KERNEL::Exception(oss.str().c_str());
174       }
175   for(std::size_t i=0;i<partOfCompoToSet;i++)
176     setInfoOnComponent(compoIds[i],other.getInfoOnComponent((int)i).c_str());
177 }
178
179 bool DataArray::areInfoEqualsIfNotWhy(const DataArray& other, std::string& reason) const throw(INTERP_KERNEL::Exception)
180 {
181   std::ostringstream oss;
182   if(_name!=other._name)
183     {
184       oss << "Names DataArray mismatch : this name=\"" << _name << " other name=\"" << other._name << "\" !";
185       reason=oss.str();
186       return false;
187     }
188   if(_info_on_compo!=other._info_on_compo)
189     {
190       oss << "Components DataArray mismatch : \nThis components=";
191       for(std::vector<std::string>::const_iterator it=_info_on_compo.begin();it!=_info_on_compo.end();it++)
192         oss << "\"" << *it << "\",";
193       oss << "\nOther components=";
194       for(std::vector<std::string>::const_iterator it=other._info_on_compo.begin();it!=other._info_on_compo.end();it++)
195         oss << "\"" << *it << "\",";
196       reason=oss.str();
197       return false;
198     }
199   return true;
200 }
201
202 /*!
203  * Compares textual information of \a this DataArray with that of an \a other one.
204  * The compared data are
205  * - the name attribute,
206  * - the information of components.
207  *
208  * For more information on these data see \ref MEDCouplingArrayBasicsName "DataArrays infos".
209  *  \param [in] other - another instance of DataArray to compare the textual data of.
210  *  \return bool - \a true if the textual information is same, \a false else.
211  */
212 bool DataArray::areInfoEquals(const DataArray& other) const throw(INTERP_KERNEL::Exception)
213 {
214   std::string tmp;
215   return areInfoEqualsIfNotWhy(other,tmp);
216 }
217
218 void DataArray::reprWithoutNameStream(std::ostream& stream) const throw(INTERP_KERNEL::Exception)
219 {
220   stream << "Number of components : "<< getNumberOfComponents() << "\n";
221   stream << "Info of these components : ";
222   for(std::vector<std::string>::const_iterator iter=_info_on_compo.begin();iter!=_info_on_compo.end();iter++)
223     stream << "\"" << *iter << "\"   ";
224   stream << "\n";
225 }
226
227 std::string DataArray::cppRepr(const char *varName) const throw(INTERP_KERNEL::Exception)
228 {
229   std::ostringstream ret;
230   reprCppStream(varName,ret);
231   return ret.str();
232 }
233
234 /*!
235  * Sets information on all components. To know more on format of this information
236  * see \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
237  *  \param [in] info - a vector of strings.
238  *  \throw If size of \a info differs from the number of components of \a this.
239  */
240 void DataArray::setInfoOnComponents(const std::vector<std::string>& info) throw(INTERP_KERNEL::Exception)
241 {
242   if(getNumberOfComponents()!=(int)info.size())
243     {
244       std::ostringstream oss; oss << "DataArray::setInfoOnComponents : input is of size " << info.size() << " whereas number of components is equal to " << getNumberOfComponents() << " !";
245       throw INTERP_KERNEL::Exception(oss.str().c_str());
246     }
247   _info_on_compo=info;
248 }
249
250 std::vector<std::string> DataArray::getVarsOnComponent() const throw(INTERP_KERNEL::Exception)
251 {
252   int nbOfCompo=(int)_info_on_compo.size();
253   std::vector<std::string> ret(nbOfCompo);
254   for(int i=0;i<nbOfCompo;i++)
255     ret[i]=getVarOnComponent(i);
256   return ret;
257 }
258
259 std::vector<std::string> DataArray::getUnitsOnComponent() const throw(INTERP_KERNEL::Exception)
260 {
261   int nbOfCompo=(int)_info_on_compo.size();
262   std::vector<std::string> ret(nbOfCompo);
263   for(int i=0;i<nbOfCompo;i++)
264     ret[i]=getUnitOnComponent(i);
265   return ret;
266 }
267
268 /*!
269  * Returns information on a component specified by an index.
270  * To know more on format of this information
271  * see \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
272  *  \param [in] i - the index (zero based) of the component of interest.
273  *  \return std::string - a string containing the information on \a i-th component.
274  *  \throw If \a i is not a valid component index.
275  */
276 std::string DataArray::getInfoOnComponent(int i) const throw(INTERP_KERNEL::Exception)
277 {
278   if(i<(int)_info_on_compo.size() && i>=0)
279     return _info_on_compo[i];
280   else
281     {
282       std::ostringstream oss; oss << "DataArray::getInfoOnComponent : Specified component id is out of range (" << i << ") compared with nb of actual components (" << (int) _info_on_compo.size();
283       throw INTERP_KERNEL::Exception(oss.str().c_str());
284     }
285 }
286
287 /*!
288  * Returns the var part of the full information of the \a i-th component.
289  * For example, if \c getInfoOnComponent(0) returns "SIGXY [N/m^2]", then
290  * \c getVarOnComponent(0) returns "SIGXY".
291  * If a unit part of information is not detected by presence of
292  * two square brackets, then the full information is returned.
293  * To read more about the component information format, see
294  * \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
295  *  \param [in] i - the index (zero based) of the component of interest.
296  *  \return std::string - a string containing the var information, or the full info.
297  *  \throw If \a i is not a valid component index.
298  */
299 std::string DataArray::getVarOnComponent(int i) const throw(INTERP_KERNEL::Exception)
300 {
301   if(i<(int)_info_on_compo.size() && i>=0)
302     {
303       return GetVarNameFromInfo(_info_on_compo[i]);
304     }
305   else
306     {
307       std::ostringstream oss; oss << "DataArray::getVarOnComponent : Specified component id is out of range  (" << i << ") compared with nb of actual components (" << (int) _info_on_compo.size();
308       throw INTERP_KERNEL::Exception(oss.str().c_str());
309     }
310 }
311
312 /*!
313  * Returns the unit part of the full information of the \a i-th component.
314  * For example, if \c getInfoOnComponent(0) returns "SIGXY [ N/m^2]", then
315  * \c getUnitOnComponent(0) returns " N/m^2".
316  * If a unit part of information is not detected by presence of
317  * two square brackets, then an empty string is returned.
318  * To read more about the component information format, see
319  * \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
320  *  \param [in] i - the index (zero based) of the component of interest.
321  *  \return std::string - a string containing the unit information, if any, or "".
322  *  \throw If \a i is not a valid component index.
323  */
324 std::string DataArray::getUnitOnComponent(int i) const throw(INTERP_KERNEL::Exception)
325 {
326   if(i<(int)_info_on_compo.size() && i>=0)
327     {
328       return GetUnitFromInfo(_info_on_compo[i]);
329     }
330   else
331     {
332       std::ostringstream oss; oss << "DataArray::getUnitOnComponent : Specified component id is out of range  (" << i << ") compared with nb of actual components (" << (int) _info_on_compo.size();
333       throw INTERP_KERNEL::Exception(oss.str().c_str());
334     }
335 }
336
337 /*!
338  * Returns the var part of the full component information.
339  * For example, if \a info == "SIGXY [N/m^2]", then this method returns "SIGXY".
340  * If a unit part of information is not detected by presence of
341  * two square brackets, then the whole \a info is returned.
342  * To read more about the component information format, see
343  * \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
344  *  \param [in] info - the full component information.
345  *  \return std::string - a string containing only var information, or the \a info.
346  */
347 std::string DataArray::GetVarNameFromInfo(const std::string& info) throw(INTERP_KERNEL::Exception)
348 {
349   std::size_t p1=info.find_last_of('[');
350   std::size_t p2=info.find_last_of(']');
351   if(p1==std::string::npos || p2==std::string::npos)
352     return info;
353   if(p1>p2)
354     return info;
355   if(p1==0)
356     return std::string();
357   std::size_t p3=info.find_last_not_of(' ',p1-1);
358   return info.substr(0,p3+1);
359 }
360
361 /*!
362  * Returns the unit part of the full component information.
363  * For example, if \a info == "SIGXY [ N/m^2]", then this method returns " N/m^2".
364  * If a unit part of information is not detected by presence of
365  * two square brackets, then an empty string is returned.
366  * To read more about the component information format, see
367  * \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
368  *  \param [in] info - the full component information.
369  *  \return std::string - a string containing only unit information, if any, or "".
370  */
371 std::string DataArray::GetUnitFromInfo(const std::string& info) throw(INTERP_KERNEL::Exception)
372 {
373   std::size_t p1=info.find_last_of('[');
374   std::size_t p2=info.find_last_of(']');
375   if(p1==std::string::npos || p2==std::string::npos)
376     return std::string();
377   if(p1>p2)
378     return std::string();
379   return info.substr(p1+1,p2-p1-1);
380 }
381
382 /*!
383  * Sets information on a component specified by an index.
384  * To know more on format of this information
385  * see \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
386  *  \warning Don't pass NULL as \a info!
387  *  \param [in] i - the index (zero based) of the component of interest.
388  *  \param [in] info - the string containing the information.
389  *  \throw If \a i is not a valid component index.
390  */
391 void DataArray::setInfoOnComponent(int i, const char *info) throw(INTERP_KERNEL::Exception)
392 {
393   if(i<(int)_info_on_compo.size() && i>=0)
394     _info_on_compo[i]=info;
395   else
396     {
397       std::ostringstream oss; oss << "DataArray::setInfoOnComponent : Specified component id is out of range  (" << i << ") compared with nb of actual components (" << (int) _info_on_compo.size();
398       throw INTERP_KERNEL::Exception(oss.str().c_str());
399     }
400 }
401
402 /*!
403  * Sets information on all components. This method can change number of components
404  * at certain conditions; if the conditions are not respected, an exception is thrown.
405  * The number of components can be changed provided that \a this is not allocated.
406  *
407  * To know more on format of the component information see
408  * \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
409  *  \param [in] info - a vector of component infos.
410  *  \throw If \a this->getNumberOfComponents() != \a info.size() && \a this->isAllocated()
411  */
412 void DataArray::setInfoAndChangeNbOfCompo(const std::vector<std::string>& info) throw(INTERP_KERNEL::Exception)
413 {
414   if(getNumberOfComponents()!=(int)info.size())
415     {
416       if(!isAllocated())
417         _info_on_compo=info;
418       else
419         {
420           std::ostringstream oss; oss << "DataArray::setInfoAndChangeNbOfCompo : input is of size " << info.size() << " whereas number of components is equal to " << getNumberOfComponents() << "  and this is already allocated !";
421           throw INTERP_KERNEL::Exception(oss.str().c_str());
422         }
423     }
424   else
425     _info_on_compo=info;
426 }
427
428 void DataArray::checkNbOfTuples(int nbOfTuples, const char *msg) const throw(INTERP_KERNEL::Exception)
429 {
430   if(getNumberOfTuples()!=nbOfTuples)
431     {
432       std::ostringstream oss; oss << msg << " : mismatch number of tuples : expected " <<  nbOfTuples << " having " << getNumberOfTuples() << " !";
433       throw INTERP_KERNEL::Exception(oss.str().c_str());
434     }
435 }
436
437 void DataArray::checkNbOfComps(int nbOfCompo, const char *msg) const throw(INTERP_KERNEL::Exception)
438 {
439   if(getNumberOfComponents()!=nbOfCompo)
440     {
441       std::ostringstream oss; oss << msg << " : mismatch number of components : expected " << nbOfCompo << " having " << getNumberOfComponents() << " !";
442       throw INTERP_KERNEL::Exception(oss.str().c_str());
443     }
444 }
445
446 void DataArray::checkNbOfElems(std::size_t nbOfElems, const char *msg) const throw(INTERP_KERNEL::Exception)
447 {
448   if(getNbOfElems()!=nbOfElems)
449     {
450       std::ostringstream oss; oss << msg << " : mismatch number of elems : Expected " << nbOfElems << " having " << getNbOfElems() << " !";
451       throw INTERP_KERNEL::Exception(oss.str().c_str());
452     }
453 }
454
455 void DataArray::checkNbOfTuplesAndComp(const DataArray& other, const char *msg) const throw(INTERP_KERNEL::Exception)
456 {
457    if(getNumberOfTuples()!=other.getNumberOfTuples())
458     {
459       std::ostringstream oss; oss << msg << " : mismatch number of tuples : expected " <<  other.getNumberOfTuples() << " having " << getNumberOfTuples() << " !";
460       throw INTERP_KERNEL::Exception(oss.str().c_str());
461     }
462   if(getNumberOfComponents()!=other.getNumberOfComponents())
463     {
464       std::ostringstream oss; oss << msg << " : mismatch number of components : expected " << other.getNumberOfComponents() << " having " << getNumberOfComponents() << " !";
465       throw INTERP_KERNEL::Exception(oss.str().c_str());
466     }
467 }
468
469 void DataArray::checkNbOfTuplesAndComp(int nbOfTuples, int nbOfCompo, const char *msg) const throw(INTERP_KERNEL::Exception)
470 {
471   checkNbOfTuples(nbOfTuples,msg);
472   checkNbOfComps(nbOfCompo,msg);
473 }
474
475 /*!
476  * Simply this method checks that \b value is in [0,\b ref).
477  */
478 void DataArray::CheckValueInRange(int ref, int value, const char *msg) throw(INTERP_KERNEL::Exception)
479 {
480   if(value<0 || value>=ref)
481     {
482       std::ostringstream oss; oss << "DataArray::CheckValueInRange : " << msg  << " ! Expected in range [0," << ref << "[ having " << value << " !";
483       throw INTERP_KERNEL::Exception(oss.str().c_str());
484     }
485 }
486
487 /*!
488  * This method checks that [\b start, \b end) is compliant with ref length \b value.
489  * typicaly start in [0,\b value) and end in [0,\b value). If value==start and start==end, it is supported.
490  */
491 void DataArray::CheckValueInRangeEx(int value, int start, int end, const char *msg) throw(INTERP_KERNEL::Exception)
492 {
493   if(start<0 || start>=value)
494     {
495       if(value!=start || end!=start)
496         {
497           std::ostringstream oss; oss << "DataArray::CheckValueInRangeEx : " << msg  << " ! Expected start " << start << " of input range, in [0," << value << "[ !";
498           throw INTERP_KERNEL::Exception(oss.str().c_str());
499         }
500     }
501   if(end<0 || end>value)
502     {
503       std::ostringstream oss; oss << "DataArray::CheckValueInRangeEx : " << msg  << " ! Expected end " << end << " of input range, in [0," << value << "] !";
504       throw INTERP_KERNEL::Exception(oss.str().c_str());
505     }
506 }
507
508 void DataArray::CheckClosingParInRange(int ref, int value, const char *msg) throw(INTERP_KERNEL::Exception)
509 {
510   if(value<0 || value>ref)
511     {
512       std::ostringstream oss; oss << "DataArray::CheckClosingParInRange : " << msg  << " ! Expected input range in [0," << ref << "] having closing open parenthesis " << value << " !";
513       throw INTERP_KERNEL::Exception(oss.str().c_str());
514     }
515 }
516
517 /*!
518  * This method is useful to slice work among a pool of threads or processes. \a begin, \a end \a step is the input whole slice of work to perform, 
519  * typically it is a whole slice of tuples of DataArray or cells, nodes of a mesh...
520  *
521  * The input \a sliceId should be an id in [0, \a nbOfSlices) that specifies the slice of work.
522  *
523  * \param [in] start - the start of the input slice of the whole work to perform splitted into slices.
524  * \param [in] stop - the stop of the input slice of the whole work to perform splitted into slices.
525  * \param [in] step - the step (that can be <0) of the input slice of the whole work to perform splitted into slices.
526  * \param [in] sliceId - the slice id considered
527  * \param [in] nbOfSlices - the number of slices (typically the number of cores on which the work is expected to be sliced)
528  * \param [out] startSlice - the start of the slice considered
529  * \param [out] stopSlice - the stop of the slice consided
530  * 
531  * \throw If \a step == 0
532  * \throw If \a nbOfSlices not > 0
533  * \throw If \a sliceId not in [0,nbOfSlices)
534  */
535 void DataArray::GetSlice(int start, int stop, int step, int sliceId, int nbOfSlices, int& startSlice, int& stopSlice) throw(INTERP_KERNEL::Exception)
536 {
537   if(nbOfSlices<=0)
538     {
539       std::ostringstream oss; oss << "DataArray::GetSlice : nbOfSlices (" << nbOfSlices << ") must be > 0 !";
540       throw INTERP_KERNEL::Exception(oss.str().c_str());
541     }
542   if(sliceId<0 || sliceId>=nbOfSlices)
543     {
544       std::ostringstream oss; oss << "DataArray::GetSlice : sliceId (" << nbOfSlices << ") must be in [0 , nbOfSlices (" << nbOfSlices << ") ) !";
545       throw INTERP_KERNEL::Exception(oss.str().c_str());
546     }
547   int nbElems=GetNumberOfItemGivenBESRelative(start,stop,step,"DataArray::GetSlice");
548   int minNbOfElemsPerSlice=nbElems/nbOfSlices;
549   startSlice=start+minNbOfElemsPerSlice*step*sliceId;
550   if(sliceId<nbOfSlices-1)
551     stopSlice=start+minNbOfElemsPerSlice*step*(sliceId+1);
552   else
553     stopSlice=stop;
554 }
555
556 int DataArray::GetNumberOfItemGivenBES(int begin, int end, int step, const char *msg) throw(INTERP_KERNEL::Exception)
557 {
558   if(end<begin)
559     {
560       std::ostringstream oss; oss << msg << " : end before begin !";
561       throw INTERP_KERNEL::Exception(oss.str().c_str());
562     }
563   if(end==begin)
564     return 0;
565   if(step<=0)
566     {
567       std::ostringstream oss; oss << msg << " : invalid step should be > 0 !";
568       throw INTERP_KERNEL::Exception(oss.str().c_str());
569     }
570   return (end-1-begin)/step+1;
571 }
572
573 int DataArray::GetNumberOfItemGivenBESRelative(int begin, int end, int step, const char *msg) throw(INTERP_KERNEL::Exception)
574 {
575   if(step==0)
576     throw INTERP_KERNEL::Exception("DataArray::GetNumberOfItemGivenBES : step=0 is not allowed !");
577   if(end<begin && step>0)
578     {
579       std::ostringstream oss; oss << msg << " : end before begin whereas step is positive !";
580       throw INTERP_KERNEL::Exception(oss.str().c_str());
581     }
582   if(begin<end && step<0)
583     {
584       std::ostringstream oss; oss << msg << " : invalid step should be > 0 !";
585       throw INTERP_KERNEL::Exception(oss.str().c_str());
586     }
587   if(begin!=end)
588     return (std::max(begin,end)-1-std::min(begin,end))/std::abs(step)+1;
589   else
590     return 0;
591 }
592
593 int DataArray::GetPosOfItemGivenBESRelativeNoThrow(int value, int begin, int end, int step) throw(INTERP_KERNEL::Exception)
594 {
595   if(step!=0)
596     {
597       if(step>0)
598         {
599           if(begin<=value && value<end)
600             {
601               if((value-begin)%step==0)
602                 return (value-begin)/step;
603               else
604                 return -1;
605             }
606           else
607             return -1;
608         }
609       else
610         {
611           if(begin>=value && value>end)
612             {
613               if((begin-value)%(-step)==0)
614                 return (begin-value)/(-step);
615               else
616                 return -1;
617             }
618           else
619             return -1;
620         }
621     }
622   else
623     return -1;
624 }
625
626 /*!
627  * Returns a new instance of DataArrayDouble. The caller is to delete this array
628  * using decrRef() as it is no more needed. 
629  */
630 DataArrayDouble *DataArrayDouble::New()
631 {
632   return new DataArrayDouble;
633 }
634
635 /*!
636  * Checks if raw data is allocated. Read more on the raw data
637  * in \ref MEDCouplingArrayBasicsTuplesAndCompo "DataArrays infos" for more information.
638  *  \return bool - \a true if the raw data is allocated, \a false else.
639  */
640 bool DataArrayDouble::isAllocated() const throw(INTERP_KERNEL::Exception)
641 {
642   return getConstPointer()!=0;
643 }
644
645 /*!
646  * Checks if raw data is allocated and throws an exception if it is not the case.
647  *  \throw If the raw data is not allocated.
648  */
649 void DataArrayDouble::checkAllocated() const throw(INTERP_KERNEL::Exception)
650 {
651   if(!isAllocated())
652     throw INTERP_KERNEL::Exception("DataArrayDouble::checkAllocated : Array is defined but not allocated ! Call alloc or setValues method first !");
653 }
654
655 std::size_t DataArrayDouble::getHeapMemorySize() const
656 {
657   std::size_t sz=_mem.getNbOfElemAllocated();
658   sz*=sizeof(double);
659   return DataArray::getHeapMemorySize()+sz;
660 }
661
662 /*!
663  * Returns the only one value in \a this, if and only if number of elements
664  * (nb of tuples * nb of components) is equal to 1, and that \a this is allocated.
665  *  \return double - the sole value stored in \a this array.
666  *  \throw If at least one of conditions stated above is not fulfilled.
667  */
668 double DataArrayDouble::doubleValue() const throw(INTERP_KERNEL::Exception)
669 {
670   if(isAllocated())
671     {
672       if(getNbOfElems()==1)
673         {
674           return *getConstPointer();
675         }
676       else
677         throw INTERP_KERNEL::Exception("DataArrayDouble::doubleValue : DataArrayDouble instance is allocated but number of elements is not equal to 1 !");
678     }
679   else
680     throw INTERP_KERNEL::Exception("DataArrayDouble::doubleValue : DataArrayDouble instance is not allocated !");
681 }
682
683 /*!
684  * Checks the number of tuples.
685  *  \return bool - \a true if getNumberOfTuples() == 0, \a false else.
686  *  \throw If \a this is not allocated.
687  */
688 bool DataArrayDouble::empty() const throw(INTERP_KERNEL::Exception)
689 {
690   checkAllocated();
691   return getNumberOfTuples()==0;
692 }
693
694 /*!
695  * Returns a full copy of \a this. For more info on copying data arrays see
696  * \ref MEDCouplingArrayBasicsCopyDeep.
697  *  \return DataArrayDouble * - a new instance of DataArrayDouble. The caller is to
698  *          delete this array using decrRef() as it is no more needed. 
699  */
700 DataArrayDouble *DataArrayDouble::deepCpy() const throw(INTERP_KERNEL::Exception)
701 {
702   return new DataArrayDouble(*this);
703 }
704
705 /*!
706  * Returns either a \a deep or \a shallow copy of this array. For more info see
707  * \ref MEDCouplingArrayBasicsCopyDeep and \ref MEDCouplingArrayBasicsCopyShallow.
708  *  \param [in] dCpy - if \a true, a deep copy is returned, else, a shallow one.
709  *  \return DataArrayDouble * - either a new instance of DataArrayDouble (if \a dCpy
710  *          == \a true) or \a this instance (if \a dCpy == \a false).
711  */
712 DataArrayDouble *DataArrayDouble::performCpy(bool dCpy) const throw(INTERP_KERNEL::Exception)
713 {
714   if(dCpy)
715     return deepCpy();
716   else
717     {
718       incrRef();
719       return const_cast<DataArrayDouble *>(this);
720     }
721 }
722
723 /*!
724  * Copies all the data from another DataArrayDouble. For more info see
725  * \ref MEDCouplingArrayBasicsCopyDeepAssign.
726  *  \param [in] other - another instance of DataArrayDouble to copy data from.
727  *  \throw If the \a other is not allocated.
728  */
729 void DataArrayDouble::cpyFrom(const DataArrayDouble& other) throw(INTERP_KERNEL::Exception)
730 {
731   other.checkAllocated();
732   int nbOfTuples=other.getNumberOfTuples();
733   int nbOfComp=other.getNumberOfComponents();
734   allocIfNecessary(nbOfTuples,nbOfComp);
735   std::size_t nbOfElems=(std::size_t)nbOfTuples*nbOfComp;
736   double *pt=getPointer();
737   const double *ptI=other.getConstPointer();
738   for(std::size_t i=0;i<nbOfElems;i++)
739     pt[i]=ptI[i];
740   copyStringInfoFrom(other);
741 }
742
743 /*!
744  * This method reserve nbOfElems elements in memory ( nbOfElems*8 bytes ) \b without impacting the number of tuples in \a this.
745  * If \a this has already been allocated, this method checks that \a this has only one component. If not an INTERP_KERNEL::Exception will be thrown.
746  * If \a this has not already been allocated, number of components is set to one.
747  * This method allows to reduce number of reallocations on invokation of DataArrayDouble::pushBackSilent and DataArrayDouble::pushBackValsSilent on \a this.
748  * 
749  * \sa DataArrayDouble::pack, DataArrayDouble::pushBackSilent, DataArrayDouble::pushBackValsSilent
750  */
751 void DataArrayDouble::reserve(std::size_t nbOfElems) throw(INTERP_KERNEL::Exception)
752 {
753   int nbCompo=getNumberOfComponents();
754   if(nbCompo==1)
755     {
756       _mem.reserve(nbOfElems);
757     }
758   else if(nbCompo==0)
759     {
760       _mem.reserve(nbOfElems);
761       _info_on_compo.resize(1);
762     }
763   else
764     throw INTERP_KERNEL::Exception("DataArrayDouble::reserve : not available for DataArrayDouble with number of components different than 1 !");
765 }
766
767 /*!
768  * This method adds at the end of \a this the single value \a val. This method do \b not update its time label to avoid useless incrementation
769  * of counter. So the caller is expected to call TimeLabel::declareAsNew on \a this at the end of the push session.
770  *
771  * \param [in] val the value to be added in \a this
772  * \throw If \a this has already been allocated with number of components different from one.
773  * \sa DataArrayDouble::pushBackValsSilent
774  */
775 void DataArrayDouble::pushBackSilent(double val) throw(INTERP_KERNEL::Exception)
776 {
777   int nbCompo=getNumberOfComponents();
778   if(nbCompo==1)
779     _mem.pushBack(val);
780   else if(nbCompo==0)
781     {
782       _info_on_compo.resize(1);
783       _mem.pushBack(val);
784     }
785   else
786     throw INTERP_KERNEL::Exception("DataArrayDouble::pushBackSilent : not available for DataArrayDouble with number of components different than 1 !");
787 }
788
789 /*!
790  * This method adds at the end of \a this a serie of values [\c valsBg,\c valsEnd). This method do \b not update its time label to avoid useless incrementation
791  * of counter. So the caller is expected to call TimeLabel::declareAsNew on \a this at the end of the push session.
792  *
793  *  \param [in] valsBg - an array of values to push at the end of \this.
794  *  \param [in] valsEnd - specifies the end of the array \a valsBg, so that
795  *              the last value of \a valsBg is \a valsEnd[ -1 ].
796  * \throw If \a this has already been allocated with number of components different from one.
797  * \sa DataArrayDouble::pushBackSilent
798  */
799 void DataArrayDouble::pushBackValsSilent(const double *valsBg, const double *valsEnd) throw(INTERP_KERNEL::Exception)
800 {
801   int nbCompo=getNumberOfComponents();
802   if(nbCompo==1)
803     _mem.insertAtTheEnd(valsBg,valsEnd);
804   else if(nbCompo==0)
805     {
806       _info_on_compo.resize(1);
807       _mem.insertAtTheEnd(valsBg,valsEnd);
808     }
809   else
810     throw INTERP_KERNEL::Exception("DataArrayDouble::pushBackValsSilent : not available for DataArrayDouble with number of components different than 1 !");
811 }
812
813 /*!
814  * This method returns silently ( without updating time label in \a this ) the last value, if any and suppress it.
815  * \throw If \a this is already empty.
816  * \throw If \a this has number of components different from one.
817  */
818 double DataArrayDouble::popBackSilent() throw(INTERP_KERNEL::Exception)
819 {
820   if(getNumberOfComponents()==1)
821     return _mem.popBack();
822   else
823     throw INTERP_KERNEL::Exception("DataArrayDouble::popBackSilent : not available for DataArrayDouble with number of components different than 1 !");
824 }
825
826 /*!
827  * This method \b do \b not modify content of \a this. It only modify its memory footprint if the allocated memory is to high regarding real data to store.
828  *
829  * \sa DataArrayDouble::getHeapMemorySize, DataArrayDouble::reserve
830  */
831 void DataArrayDouble::pack() const throw(INTERP_KERNEL::Exception)
832 {
833   _mem.pack();
834 }
835
836 /*!
837  * Allocates the raw data in memory. If exactly same memory as needed already
838  * allocated, it is not re-allocated.
839  *  \param [in] nbOfTuple - number of tuples of data to allocate.
840  *  \param [in] nbOfCompo - number of components of data to allocate.
841  *  \throw If \a nbOfTuple < 0 or \a nbOfCompo < 0.
842  */
843 void DataArrayDouble::allocIfNecessary(int nbOfTuple, int nbOfCompo) throw(INTERP_KERNEL::Exception)
844 {
845   if(isAllocated())
846     {
847       if(nbOfTuple!=getNumberOfTuples() || nbOfCompo!=getNumberOfComponents())
848         alloc(nbOfTuple,nbOfCompo);
849     }
850   else
851     alloc(nbOfTuple,nbOfCompo);
852 }
853
854 /*!
855  * Allocates the raw data in memory. If the memory was already allocated, then it is
856  * freed and re-allocated. See an example of this method use
857  * \ref MEDCouplingArraySteps1WC "here".
858  *  \param [in] nbOfTuple - number of tuples of data to allocate.
859  *  \param [in] nbOfCompo - number of components of data to allocate.
860  *  \throw If \a nbOfTuple < 0 or \a nbOfCompo < 0.
861  */
862 void DataArrayDouble::alloc(int nbOfTuple, int nbOfCompo) throw(INTERP_KERNEL::Exception)
863 {
864   if(nbOfTuple<0 || nbOfCompo<0)
865     throw INTERP_KERNEL::Exception("DataArrayDouble::alloc : request for negative length of data !");
866   _info_on_compo.resize(nbOfCompo);
867   _mem.alloc(nbOfCompo*(std::size_t)nbOfTuple);
868   declareAsNew();
869 }
870
871 /*!
872  * Assign zero to all values in \a this array. To know more on filling arrays see
873  * \ref MEDCouplingArrayFill.
874  * \throw If \a this is not allocated.
875  */
876 void DataArrayDouble::fillWithZero() throw(INTERP_KERNEL::Exception)
877 {
878   checkAllocated();
879   _mem.fillWithValue(0.);
880   declareAsNew();
881 }
882
883 /*!
884  * Assign \a val to all values in \a this array. To know more on filling arrays see
885  * \ref MEDCouplingArrayFill.
886  *  \param [in] val - the value to fill with.
887  *  \throw If \a this is not allocated.
888  */
889 void DataArrayDouble::fillWithValue(double val) throw(INTERP_KERNEL::Exception)
890 {
891   checkAllocated();
892   _mem.fillWithValue(val);
893   declareAsNew();
894 }
895
896 /*!
897  * Set all values in \a this array so that the i-th element equals to \a init + i
898  * (i starts from zero). To know more on filling arrays see \ref MEDCouplingArrayFill.
899  *  \param [in] init - value to assign to the first element of array.
900  *  \throw If \a this->getNumberOfComponents() != 1
901  *  \throw If \a this is not allocated.
902  */
903 void DataArrayDouble::iota(double init) throw(INTERP_KERNEL::Exception)
904 {
905   checkAllocated();
906   if(getNumberOfComponents()!=1)
907     throw INTERP_KERNEL::Exception("DataArrayDouble::iota : works only for arrays with only one component, you can call 'rearrange' method before !");
908   double *ptr=getPointer();
909   int ntuples=getNumberOfTuples();
910   for(int i=0;i<ntuples;i++)
911     ptr[i]=init+double(i);
912   declareAsNew();
913 }
914
915 /*!
916  * Checks if all values in \a this array are equal to \a val at precision \a eps.
917  *  \param [in] val - value to check equality of array values to.
918  *  \param [in] eps - precision to check the equality.
919  *  \return bool - \a true if all values are in range (_val_ - _eps_; _val_ + _eps_),
920  *                 \a false else.
921  *  \throw If \a this->getNumberOfComponents() != 1
922  *  \throw If \a this is not allocated.
923  */
924 bool DataArrayDouble::isUniform(double val, double eps) const throw(INTERP_KERNEL::Exception)
925 {
926   checkAllocated();
927   if(getNumberOfComponents()!=1)
928     throw INTERP_KERNEL::Exception("DataArrayDouble::isUniform : must be applied on DataArrayDouble with only one component, you can call 'rearrange' method before !");
929   int nbOfTuples=getNumberOfTuples();
930   const double *w=getConstPointer();
931   const double *end2=w+nbOfTuples;
932   const double vmin=val-eps;
933   const double vmax=val+eps;
934   for(;w!=end2;w++)
935     if(*w<vmin || *w>vmax)
936       return false;
937   return true;
938 }
939
940 /*!
941  * Sorts values of the array.
942  *  \param [in] asc - \a true means ascending order, \a false, descending.
943  *  \throw If \a this is not allocated.
944  *  \throw If \a this->getNumberOfComponents() != 1.
945  */
946 void DataArrayDouble::sort(bool asc) throw(INTERP_KERNEL::Exception)
947 {
948   checkAllocated();
949   if(getNumberOfComponents()!=1)
950     throw INTERP_KERNEL::Exception("DataArrayDouble::sort : only supported with 'this' array with ONE component !");
951   _mem.sort(asc);
952   declareAsNew();
953 }
954
955 /*!
956  * Reverse the array values.
957  *  \throw If \a this->getNumberOfComponents() < 1.
958  *  \throw If \a this is not allocated.
959  */
960 void DataArrayDouble::reverse() throw(INTERP_KERNEL::Exception)
961 {
962   checkAllocated();
963   _mem.reverse(getNumberOfComponents());
964   declareAsNew();
965 }
966
967 /*!
968  * Checks that \a this array is consistently **increasing** or **decreasing** in value,
969  * with at least absolute difference value of |\a eps| at each step.
970  * If not an exception is thrown.
971  *  \param [in] increasing - if \a true, the array values should be increasing.
972  *  \param [in] eps - minimal absolute difference between the neighbor values at which 
973  *                    the values are considered different.
974  *  \throw If sequence of values is not strictly monotonic in agreement with \a
975  *         increasing arg.
976  *  \throw If \a this->getNumberOfComponents() != 1.
977  *  \throw If \a this is not allocated.
978  */
979 void DataArrayDouble::checkMonotonic(bool increasing, double eps) const throw(INTERP_KERNEL::Exception)
980 {
981   if(!isMonotonic(increasing,eps))
982     {
983       if (increasing)
984         throw INTERP_KERNEL::Exception("DataArrayDouble::checkMonotonic : 'this' is not INCREASING monotonic !");
985       else
986         throw INTERP_KERNEL::Exception("DataArrayDouble::checkMonotonic : 'this' is not DECREASING monotonic !");
987     }
988 }
989
990 /*!
991  * Checks that \a this array is consistently **increasing** or **decreasing** in value,
992  * with at least absolute difference value of |\a eps| at each step.
993  *  \param [in] increasing - if \a true, array values should be increasing.
994  *  \param [in] eps - minimal absolute difference between the neighbor values at which 
995  *                    the values are considered different.
996  *  \return bool - \a true if values change in accordance with \a increasing arg.
997  *  \throw If \a this->getNumberOfComponents() != 1.
998  *  \throw If \a this is not allocated.
999  */
1000 bool DataArrayDouble::isMonotonic(bool increasing, double eps) const throw(INTERP_KERNEL::Exception)
1001 {
1002   checkAllocated();
1003   if(getNumberOfComponents()!=1)
1004     throw INTERP_KERNEL::Exception("DataArrayDouble::isMonotonic : only supported with 'this' array with ONE component !");
1005   int nbOfElements=getNumberOfTuples();
1006   const double *ptr=getConstPointer();
1007   if(nbOfElements==0)
1008     return true;
1009   double ref=ptr[0];
1010   double absEps=fabs(eps);
1011   if(increasing)
1012     {
1013       for(int i=1;i<nbOfElements;i++)
1014         {
1015           if(ptr[i]<(ref+absEps))
1016             return false;
1017           ref=ptr[i];
1018         }
1019       return true;
1020     }
1021   else
1022     {
1023       for(int i=1;i<nbOfElements;i++)
1024         {
1025           if(ptr[i]>(ref-absEps))
1026             return false;
1027           ref=ptr[i];
1028         }
1029       return true;
1030     }
1031 }
1032
1033 /*!
1034  * Returns a textual and human readable representation of \a this instance of
1035  * DataArrayDouble. This text is shown when a DataArrayDouble is printed in Python.
1036  *  \return std::string - text describing \a this DataArrayDouble.
1037  */
1038 std::string DataArrayDouble::repr() const throw(INTERP_KERNEL::Exception)
1039 {
1040   std::ostringstream ret;
1041   reprStream(ret);
1042   return ret.str();
1043 }
1044
1045 std::string DataArrayDouble::reprZip() const throw(INTERP_KERNEL::Exception)
1046 {
1047   std::ostringstream ret;
1048   reprZipStream(ret);
1049   return ret.str();
1050 }
1051
1052 void DataArrayDouble::writeVTK(std::ostream& ofs, int indent, const char *nameInFile) const throw(INTERP_KERNEL::Exception)
1053 {
1054   std::string idt(indent,' ');
1055   ofs.precision(17);
1056   ofs << idt << "<DataArray type=\"Float32\" Name=\"" << nameInFile << "\" NumberOfComponents=\"" << getNumberOfComponents() << "\"";
1057   ofs << " format=\"ascii\" RangeMin=\"" << getMinValueInArray() << "\" RangeMax=\"" << getMaxValueInArray() << "\">\n" << idt;
1058   std::copy(begin(),end(),std::ostream_iterator<double>(ofs," "));
1059   ofs << std::endl << idt << "</DataArray>\n";
1060 }
1061
1062 void DataArrayDouble::reprStream(std::ostream& stream) const throw(INTERP_KERNEL::Exception)
1063 {
1064   stream << "Name of double array : \"" << _name << "\"\n";
1065   reprWithoutNameStream(stream);
1066 }
1067
1068 void DataArrayDouble::reprZipStream(std::ostream& stream) const throw(INTERP_KERNEL::Exception)
1069 {
1070   stream << "Name of double array : \"" << _name << "\"\n";
1071   reprZipWithoutNameStream(stream);
1072 }
1073
1074 void DataArrayDouble::reprWithoutNameStream(std::ostream& stream) const throw(INTERP_KERNEL::Exception)
1075 {
1076   DataArray::reprWithoutNameStream(stream);
1077   stream.precision(17);
1078   _mem.repr(getNumberOfComponents(),stream);
1079 }
1080
1081 void DataArrayDouble::reprZipWithoutNameStream(std::ostream& stream) const throw(INTERP_KERNEL::Exception)
1082 {
1083   DataArray::reprWithoutNameStream(stream);
1084   stream.precision(17);
1085   _mem.reprZip(getNumberOfComponents(),stream);
1086 }
1087
1088 void DataArrayDouble::reprCppStream(const char *varName, std::ostream& stream) const throw(INTERP_KERNEL::Exception)
1089 {
1090   int nbTuples=getNumberOfTuples(),nbComp=getNumberOfComponents();
1091   const double *data=getConstPointer();
1092   stream.precision(17);
1093   stream << "DataArrayDouble *" << varName << "=DataArrayDouble::New();" << std::endl;
1094   if(nbTuples*nbComp>=1)
1095     {
1096       stream << "const double " << varName << "Data[" << nbTuples*nbComp << "]={";
1097       std::copy(data,data+nbTuples*nbComp-1,std::ostream_iterator<double>(stream,","));
1098       stream << data[nbTuples*nbComp-1] << "};" << std::endl;
1099       stream << varName << "->useArray(" << varName << "Data,false,CPP_DEALLOC," << nbTuples << "," << nbComp << ");" << std::endl;
1100     }
1101   else
1102     stream << varName << "->alloc(" << nbTuples << "," << nbComp << ");" << std::endl;
1103   stream << varName << "->setName(\"" << getName() << "\");" << std::endl;
1104 }
1105
1106 /*!
1107  * Method that gives a quick overvien of \a this for python.
1108  */
1109 void DataArrayDouble::reprQuickOverview(std::ostream& stream) const throw(INTERP_KERNEL::Exception)
1110 {
1111   static const std::size_t MAX_NB_OF_BYTE_IN_REPR=300;
1112   stream << "DataArrayDouble C++ instance at " << this << ". ";
1113   if(isAllocated())
1114     {
1115       int nbOfCompo=(int)_info_on_compo.size();
1116       if(nbOfCompo>=1)
1117         {
1118           int nbOfTuples=getNumberOfTuples();
1119           stream << "Number of tuples : " << nbOfTuples << ". Number of components : " << nbOfCompo << "." << std::endl;
1120           reprQuickOverviewData(stream,MAX_NB_OF_BYTE_IN_REPR);
1121         }
1122       else
1123         stream << "Number of components : 0.";
1124     }
1125   else
1126     stream << "*** No data allocated ****";
1127 }
1128
1129 void DataArrayDouble::reprQuickOverviewData(std::ostream& stream, std::size_t maxNbOfByteInRepr) const throw(INTERP_KERNEL::Exception)
1130 {
1131   const double *data=begin();
1132   int nbOfTuples=getNumberOfTuples();
1133   int nbOfCompo=(int)_info_on_compo.size();
1134   std::ostringstream oss2; oss2 << "[";
1135   oss2.precision(17);
1136   std::string oss2Str(oss2.str());
1137   bool isFinished=true;
1138   for(int i=0;i<nbOfTuples && isFinished;i++)
1139     {
1140       if(nbOfCompo>1)
1141         {
1142           oss2 << "(";
1143           for(int j=0;j<nbOfCompo;j++,data++)
1144             {
1145               oss2 << *data;
1146               if(j!=nbOfCompo-1) oss2 << ", ";
1147             }
1148           oss2 << ")";
1149         }
1150       else
1151         oss2 << *data++;
1152       if(i!=nbOfTuples-1) oss2 << ", ";
1153       std::string oss3Str(oss2.str());
1154       if(oss3Str.length()<maxNbOfByteInRepr)
1155         oss2Str=oss3Str;
1156       else
1157         isFinished=false;
1158     }
1159   stream << oss2Str;
1160   if(!isFinished)
1161     stream << "... ";
1162   stream << "]";
1163 }
1164
1165 /*!
1166  * Equivalent to DataArrayDouble::isEqual except that if false the reason of
1167  * mismatch is given.
1168  * 
1169  * \param [in] other the instance to be compared with \a this
1170  * \param [in] prec the precision to compare numeric data of the arrays.
1171  * \param [out] reason In case of inequality returns the reason.
1172  * \sa DataArrayDouble::isEqual
1173  */
1174 bool DataArrayDouble::isEqualIfNotWhy(const DataArrayDouble& other, double prec, std::string& reason) const throw(INTERP_KERNEL::Exception)
1175 {
1176   if(!areInfoEqualsIfNotWhy(other,reason))
1177     return false;
1178   return _mem.isEqual(other._mem,prec,reason);
1179 }
1180
1181 /*!
1182  * Checks if \a this and another DataArrayDouble are fully equal. For more info see
1183  * \ref MEDCouplingArrayBasicsCompare.
1184  *  \param [in] other - an instance of DataArrayDouble to compare with \a this one.
1185  *  \param [in] prec - precision value to compare numeric data of the arrays.
1186  *  \return bool - \a true if the two arrays are equal, \a false else.
1187  */
1188 bool DataArrayDouble::isEqual(const DataArrayDouble& other, double prec) const throw(INTERP_KERNEL::Exception)
1189 {
1190   std::string tmp;
1191   return isEqualIfNotWhy(other,prec,tmp);
1192 }
1193
1194 /*!
1195  * Checks if values of \a this and another DataArrayDouble are equal. For more info see
1196  * \ref MEDCouplingArrayBasicsCompare.
1197  *  \param [in] other - an instance of DataArrayDouble to compare with \a this one.
1198  *  \param [in] prec - precision value to compare numeric data of the arrays.
1199  *  \return bool - \a true if the values of two arrays are equal, \a false else.
1200  */
1201 bool DataArrayDouble::isEqualWithoutConsideringStr(const DataArrayDouble& other, double prec) const throw(INTERP_KERNEL::Exception)
1202 {
1203   std::string tmp;
1204   return _mem.isEqual(other._mem,prec,tmp);
1205 }
1206
1207 /*!
1208  * Changes number of tuples in the array. If the new number of tuples is smaller
1209  * than the current number the array is truncated, otherwise the array is extended.
1210  *  \param [in] nbOfTuples - new number of tuples. 
1211  *  \throw If \a this is not allocated.
1212  */
1213 void DataArrayDouble::reAlloc(int nbOfTuples) throw(INTERP_KERNEL::Exception)
1214 {
1215   checkAllocated();
1216   _mem.reAlloc(getNumberOfComponents()*(std::size_t)nbOfTuples);
1217   declareAsNew();
1218 }
1219
1220 /*!
1221  * Creates a new DataArrayInt and assigns all (textual and numerical) data of \a this
1222  * array to the new one.
1223  *  \return DataArrayInt * - the new instance of DataArrayInt.
1224  */
1225 DataArrayInt *DataArrayDouble::convertToIntArr() const
1226 {
1227   DataArrayInt *ret=DataArrayInt::New();
1228   ret->alloc(getNumberOfTuples(),getNumberOfComponents());
1229   std::size_t nbOfVals=getNbOfElems();
1230   const double *src=getConstPointer();
1231   int *dest=ret->getPointer();
1232   std::copy(src,src+nbOfVals,dest);
1233   ret->copyStringInfoFrom(*this);
1234   return ret;
1235 }
1236
1237 /*!
1238  * Returns a new DataArrayDouble holding the same values as \a this array but differently
1239  * arranged in memory. If \a this array holds 2 components of 3 values:
1240  * \f$ x_0,x_1,x_2,y_0,y_1,y_2 \f$, then the result array holds these values arranged
1241  * as follows: \f$ x_0,y_0,x_1,y_1,x_2,y_2 \f$.
1242  *  \warning Do not confuse this method with transpose()!
1243  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1244  *          is to delete using decrRef() as it is no more needed.
1245  *  \throw If \a this is not allocated.
1246  */
1247 DataArrayDouble *DataArrayDouble::fromNoInterlace() const throw(INTERP_KERNEL::Exception)
1248 {
1249   if(_mem.isNull())
1250     throw INTERP_KERNEL::Exception("DataArrayDouble::fromNoInterlace : Not defined array !");
1251   double *tab=_mem.fromNoInterlace(getNumberOfComponents());
1252   DataArrayDouble *ret=DataArrayDouble::New();
1253   ret->useArray(tab,true,C_DEALLOC,getNumberOfTuples(),getNumberOfComponents());
1254   return ret;
1255 }
1256
1257 /*!
1258  * Returns a new DataArrayDouble holding the same values as \a this array but differently
1259  * arranged in memory. If \a this array holds 2 components of 3 values:
1260  * \f$ x_0,y_0,x_1,y_1,x_2,y_2 \f$, then the result array holds these values arranged
1261  * as follows: \f$ x_0,x_1,x_2,y_0,y_1,y_2 \f$.
1262  *  \warning Do not confuse this method with transpose()!
1263  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1264  *          is to delete using decrRef() as it is no more needed.
1265  *  \throw If \a this is not allocated.
1266  */
1267 DataArrayDouble *DataArrayDouble::toNoInterlace() const throw(INTERP_KERNEL::Exception)
1268 {
1269   if(_mem.isNull())
1270     throw INTERP_KERNEL::Exception("DataArrayDouble::toNoInterlace : Not defined array !");
1271   double *tab=_mem.toNoInterlace(getNumberOfComponents());
1272   DataArrayDouble *ret=DataArrayDouble::New();
1273   ret->useArray(tab,true,C_DEALLOC,getNumberOfTuples(),getNumberOfComponents());
1274   return ret;
1275 }
1276
1277 /*!
1278  * Permutes values of \a this array as required by \a old2New array. The values are
1279  * permuted so that \c new[ \a old2New[ i ]] = \c old[ i ]. Number of tuples remains
1280  * the same as in \this one.
1281  * If a permutation reduction is needed, substr() or selectByTupleId() should be used.
1282  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
1283  *  \param [in] old2New - C array of length equal to \a this->getNumberOfTuples()
1284  *     giving a new position for i-th old value.
1285  */
1286 void DataArrayDouble::renumberInPlace(const int *old2New) throw(INTERP_KERNEL::Exception)
1287 {
1288   checkAllocated();
1289   int nbTuples=getNumberOfTuples();
1290   int nbOfCompo=getNumberOfComponents();
1291   double *tmp=new double[nbTuples*nbOfCompo];
1292   const double *iptr=getConstPointer();
1293   for(int i=0;i<nbTuples;i++)
1294     std::copy(iptr+nbOfCompo*i,iptr+nbOfCompo*(i+1),tmp+nbOfCompo*old2New[i]);
1295   std::copy(tmp,tmp+nbTuples*nbOfCompo,getPointer());
1296   delete [] tmp;
1297   declareAsNew();
1298 }
1299
1300 /*!
1301  * Permutes values of \a this array as required by \a new2Old array. The values are
1302  * permuted so that \c new[ i ] = \c old[ \a new2Old[ i ]]. Number of tuples remains
1303  * the same as in \this one.
1304  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
1305  *  \param [in] new2Old - C array of length equal to \a this->getNumberOfTuples()
1306  *     giving a previous position of i-th new value.
1307  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1308  *          is to delete using decrRef() as it is no more needed.
1309  */
1310 void DataArrayDouble::renumberInPlaceR(const int *new2Old) throw(INTERP_KERNEL::Exception)
1311 {
1312   checkAllocated();
1313   int nbTuples=getNumberOfTuples();
1314   int nbOfCompo=getNumberOfComponents();
1315   double *tmp=new double[nbTuples*nbOfCompo];
1316   const double *iptr=getConstPointer();
1317   for(int i=0;i<nbTuples;i++)
1318     std::copy(iptr+nbOfCompo*new2Old[i],iptr+nbOfCompo*(new2Old[i]+1),tmp+nbOfCompo*i);
1319   std::copy(tmp,tmp+nbTuples*nbOfCompo,getPointer());
1320   delete [] tmp;
1321   declareAsNew();
1322 }
1323
1324 /*!
1325  * Returns a copy of \a this array with values permuted as required by \a old2New array.
1326  * The values are permuted so that  \c new[ \a old2New[ i ]] = \c old[ i ].
1327  * Number of tuples in the result array remains the same as in \this one.
1328  * If a permutation reduction is needed, renumberAndReduce() should be used.
1329  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
1330  *  \param [in] old2New - C array of length equal to \a this->getNumberOfTuples()
1331  *          giving a new position for i-th old value.
1332  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1333  *          is to delete using decrRef() as it is no more needed.
1334  *  \throw If \a this is not allocated.
1335  */
1336 DataArrayDouble *DataArrayDouble::renumber(const int *old2New) const throw(INTERP_KERNEL::Exception)
1337 {
1338   checkAllocated();
1339   int nbTuples=getNumberOfTuples();
1340   int nbOfCompo=getNumberOfComponents();
1341   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
1342   ret->alloc(nbTuples,nbOfCompo);
1343   ret->copyStringInfoFrom(*this);
1344   const double *iptr=getConstPointer();
1345   double *optr=ret->getPointer();
1346   for(int i=0;i<nbTuples;i++)
1347     std::copy(iptr+nbOfCompo*i,iptr+nbOfCompo*(i+1),optr+nbOfCompo*old2New[i]);
1348   ret->copyStringInfoFrom(*this);
1349   return ret.retn();
1350 }
1351
1352 /*!
1353  * Returns a copy of \a this array with values permuted as required by \a new2Old array.
1354  * The values are permuted so that  \c new[ i ] = \c old[ \a new2Old[ i ]]. Number of
1355  * tuples in the result array remains the same as in \this one.
1356  * If a permutation reduction is needed, substr() or selectByTupleId() should be used.
1357  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
1358  *  \param [in] new2Old - C array of length equal to \a this->getNumberOfTuples()
1359  *     giving a previous position of i-th new value.
1360  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1361  *          is to delete using decrRef() as it is no more needed.
1362  */
1363 DataArrayDouble *DataArrayDouble::renumberR(const int *new2Old) const throw(INTERP_KERNEL::Exception)
1364 {
1365   checkAllocated();
1366   int nbTuples=getNumberOfTuples();
1367   int nbOfCompo=getNumberOfComponents();
1368   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
1369   ret->alloc(nbTuples,nbOfCompo);
1370   ret->copyStringInfoFrom(*this);
1371   const double *iptr=getConstPointer();
1372   double *optr=ret->getPointer();
1373   for(int i=0;i<nbTuples;i++)
1374     std::copy(iptr+nbOfCompo*new2Old[i],iptr+nbOfCompo*(new2Old[i]+1),optr+i*nbOfCompo);
1375   ret->copyStringInfoFrom(*this);
1376   return ret.retn();
1377 }
1378
1379 /*!
1380  * Returns a shorten and permuted copy of \a this array. The new DataArrayDouble is
1381  * of size \a newNbOfTuple and it's values are permuted as required by \a old2New array.
1382  * The values are permuted so that  \c new[ \a old2New[ i ]] = \c old[ i ] for all
1383  * \a old2New[ i ] >= 0. In other words every i-th tuple in \a this array, for which 
1384  * \a old2New[ i ] is negative, is missing from the result array.
1385  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
1386  *  \param [in] old2New - C array of length equal to \a this->getNumberOfTuples()
1387  *     giving a new position for i-th old tuple and giving negative position for
1388  *     for i-th old tuple that should be omitted.
1389  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1390  *          is to delete using decrRef() as it is no more needed.
1391  */
1392 DataArrayDouble *DataArrayDouble::renumberAndReduce(const int *old2New, int newNbOfTuple) const throw(INTERP_KERNEL::Exception)
1393 {
1394   checkAllocated();
1395   int nbTuples=getNumberOfTuples();
1396   int nbOfCompo=getNumberOfComponents();
1397   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
1398   ret->alloc(newNbOfTuple,nbOfCompo);
1399   const double *iptr=getConstPointer();
1400   double *optr=ret->getPointer();
1401   for(int i=0;i<nbTuples;i++)
1402     {
1403       int w=old2New[i];
1404       if(w>=0)
1405         std::copy(iptr+i*nbOfCompo,iptr+(i+1)*nbOfCompo,optr+w*nbOfCompo);
1406     }
1407   ret->copyStringInfoFrom(*this);
1408   return ret.retn();
1409 }
1410
1411 /*!
1412  * Returns a shorten and permuted copy of \a this array. The new DataArrayDouble is
1413  * of size \a new2OldEnd - \a new2OldBg and it's values are permuted as required by
1414  * \a new2OldBg array.
1415  * The values are permuted so that  \c new[ i ] = \c old[ \a new2OldBg[ i ]].
1416  * This method is equivalent to renumberAndReduce() except that convention in input is
1417  * \c new2old and \b not \c old2new.
1418  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
1419  *  \param [in] new2OldBg - pointer to the beginning of a permutation array that gives a
1420  *              tuple index in \a this array to fill the i-th tuple in the new array.
1421  *  \param [in] new2OldEnd - specifies the end of the permutation array that starts at
1422  *              \a new2OldBg, so that pointer to a tuple index (\a pi) varies as this:
1423  *              \a new2OldBg <= \a pi < \a new2OldEnd.
1424  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1425  *          is to delete using decrRef() as it is no more needed.
1426  */
1427 DataArrayDouble *DataArrayDouble::selectByTupleId(const int *new2OldBg, const int *new2OldEnd) const
1428 {
1429   checkAllocated();
1430   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
1431   int nbComp=getNumberOfComponents();
1432   ret->alloc((int)std::distance(new2OldBg,new2OldEnd),nbComp);
1433   ret->copyStringInfoFrom(*this);
1434   double *pt=ret->getPointer();
1435   const double *srcPt=getConstPointer();
1436   int i=0;
1437   for(const int *w=new2OldBg;w!=new2OldEnd;w++,i++)
1438     std::copy(srcPt+(*w)*nbComp,srcPt+((*w)+1)*nbComp,pt+i*nbComp);
1439   ret->copyStringInfoFrom(*this);
1440   return ret.retn();
1441 }
1442
1443 /*!
1444  * Returns a shorten and permuted copy of \a this array. The new DataArrayDouble is
1445  * of size \a new2OldEnd - \a new2OldBg and it's values are permuted as required by
1446  * \a new2OldBg array.
1447  * The values are permuted so that  \c new[ i ] = \c old[ \a new2OldBg[ i ]].
1448  * This method is equivalent to renumberAndReduce() except that convention in input is
1449  * \c new2old and \b not \c old2new.
1450  * This method is equivalent to selectByTupleId() except that it prevents coping data
1451  * from behind the end of \a this array.
1452  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
1453  *  \param [in] new2OldBg - pointer to the beginning of a permutation array that gives a
1454  *              tuple index in \a this array to fill the i-th tuple in the new array.
1455  *  \param [in] new2OldEnd - specifies the end of the permutation array that starts at
1456  *              \a new2OldBg, so that pointer to a tuple index (\a pi) varies as this:
1457  *              \a new2OldBg <= \a pi < \a new2OldEnd.
1458  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1459  *          is to delete using decrRef() as it is no more needed.
1460  *  \throw If \a new2OldEnd - \a new2OldBg > \a this->getNumberOfTuples().
1461  */
1462 DataArrayDouble *DataArrayDouble::selectByTupleIdSafe(const int *new2OldBg, const int *new2OldEnd) const throw(INTERP_KERNEL::Exception)
1463 {
1464   checkAllocated();
1465   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
1466   int nbComp=getNumberOfComponents();
1467   int oldNbOfTuples=getNumberOfTuples();
1468   ret->alloc((int)std::distance(new2OldBg,new2OldEnd),nbComp);
1469   ret->copyStringInfoFrom(*this);
1470   double *pt=ret->getPointer();
1471   const double *srcPt=getConstPointer();
1472   int i=0;
1473   for(const int *w=new2OldBg;w!=new2OldEnd;w++,i++)
1474     if(*w>=0 && *w<oldNbOfTuples)
1475       std::copy(srcPt+(*w)*nbComp,srcPt+((*w)+1)*nbComp,pt+i*nbComp);
1476     else
1477       throw INTERP_KERNEL::Exception("DataArrayDouble::selectByTupleIdSafe : some ids has been detected to be out of [0,this->getNumberOfTuples) !");
1478   ret->copyStringInfoFrom(*this);
1479   return ret.retn();
1480 }
1481
1482 /*!
1483  * Returns a shorten copy of \a this array. The new DataArrayDouble contains every
1484  * (\a bg + \c i * \a step)-th tuple of \a this array located before the \a end2-th
1485  * tuple. Indices of the selected tuples are the same as ones returned by the Python
1486  * command \c range( \a bg, \a end2, \a step ).
1487  * This method is equivalent to selectByTupleIdSafe() except that the input array is
1488  * not constructed explicitly.
1489  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
1490  *  \param [in] bg - index of the first tuple to copy from \a this array.
1491  *  \param [in] end2 - index of the tuple before which the tuples to copy are located.
1492  *  \param [in] step - index increment to get index of the next tuple to copy.
1493  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1494  *          is to delete using decrRef() as it is no more needed.
1495  *  \sa DataArrayDouble::substr.
1496  */
1497 DataArrayDouble *DataArrayDouble::selectByTupleId2(int bg, int end2, int step) const throw(INTERP_KERNEL::Exception)
1498 {
1499   checkAllocated();
1500   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
1501   int nbComp=getNumberOfComponents();
1502   int newNbOfTuples=GetNumberOfItemGivenBESRelative(bg,end2,step,"DataArrayDouble::selectByTupleId2 : ");
1503   ret->alloc(newNbOfTuples,nbComp);
1504   double *pt=ret->getPointer();
1505   const double *srcPt=getConstPointer()+bg*nbComp;
1506   for(int i=0;i<newNbOfTuples;i++,srcPt+=step*nbComp)
1507     std::copy(srcPt,srcPt+nbComp,pt+i*nbComp);
1508   ret->copyStringInfoFrom(*this);
1509   return ret.retn();
1510 }
1511
1512 /*!
1513  * Returns a shorten copy of \a this array. The new DataArrayDouble contains ranges
1514  * of tuples specified by \a ranges parameter.
1515  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
1516  *  \param [in] ranges - std::vector of std::pair's each of which defines a range
1517  *              of tuples in [\c begin,\c end) format.
1518  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1519  *          is to delete using decrRef() as it is no more needed.
1520  *  \throw If \a end < \a begin.
1521  *  \throw If \a end > \a this->getNumberOfTuples().
1522  *  \throw If \a this is not allocated.
1523  */
1524 DataArray *DataArrayDouble::selectByTupleRanges(const std::vector<std::pair<int,int> >& ranges) const throw(INTERP_KERNEL::Exception)
1525 {
1526   checkAllocated();
1527   int nbOfComp=getNumberOfComponents();
1528   int nbOfTuplesThis=getNumberOfTuples();
1529   if(ranges.empty())
1530     {
1531       DataArrayDouble *ret=DataArrayDouble::New();
1532       ret->alloc(0,nbOfComp);
1533       ret->copyStringInfoFrom(*this);
1534       return ret;
1535     }
1536   int ref=ranges.front().first;
1537   int nbOfTuples=0;
1538   bool isIncreasing=true;
1539   for(std::vector<std::pair<int,int> >::const_iterator it=ranges.begin();it!=ranges.end();it++)
1540     {
1541       if((*it).first<=(*it).second)
1542         {
1543           if((*it).first>=0 && (*it).second<=nbOfTuplesThis)
1544             {
1545               nbOfTuples+=(*it).second-(*it).first;
1546               if(isIncreasing)
1547                 isIncreasing=ref<=(*it).first;
1548               ref=(*it).second;
1549             }
1550           else
1551             {
1552               std::ostringstream oss; oss << "DataArrayDouble::selectByTupleRanges : on range #" << std::distance(ranges.begin(),it);
1553               oss << " (" << (*it).first << "," << (*it).second << ") is greater than number of tuples of this :" << nbOfTuples << " !";
1554               throw INTERP_KERNEL::Exception(oss.str().c_str());
1555             }
1556         }
1557       else
1558         {
1559           std::ostringstream oss; oss << "DataArrayDouble::selectByTupleRanges : on range #" << std::distance(ranges.begin(),it);
1560           oss << " (" << (*it).first << "," << (*it).second << ") end is before begin !";
1561           throw INTERP_KERNEL::Exception(oss.str().c_str());
1562         }
1563     }
1564   if(isIncreasing && nbOfTuplesThis==nbOfTuples)
1565     return deepCpy();
1566   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
1567   ret->alloc(nbOfTuples,nbOfComp);
1568   ret->copyStringInfoFrom(*this);
1569   const double *src=getConstPointer();
1570   double *work=ret->getPointer();
1571   for(std::vector<std::pair<int,int> >::const_iterator it=ranges.begin();it!=ranges.end();it++)
1572     work=std::copy(src+(*it).first*nbOfComp,src+(*it).second*nbOfComp,work);
1573   return ret.retn();
1574 }
1575
1576 /*!
1577  * Returns a shorten copy of \a this array. The new DataArrayDouble contains all
1578  * tuples starting from the \a tupleIdBg-th tuple and including all tuples located before
1579  * the \a tupleIdEnd-th one. This methods has a similar behavior as std::string::substr().
1580  * This method is a specialization of selectByTupleId2().
1581  *  \param [in] tupleIdBg - index of the first tuple to copy from \a this array.
1582  *  \param [in] tupleIdEnd - index of the tuple before which the tuples to copy are located.
1583  *          If \a tupleIdEnd == -1, all the tuples till the end of \a this array are copied.
1584  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1585  *          is to delete using decrRef() as it is no more needed.
1586  *  \throw If \a tupleIdBg < 0.
1587  *  \throw If \a tupleIdBg > \a this->getNumberOfTuples().
1588     \throw If \a tupleIdEnd != -1 && \a tupleIdEnd < \a this->getNumberOfTuples().
1589  *  \sa DataArrayDouble::selectByTupleId2
1590  */
1591 DataArrayDouble *DataArrayDouble::substr(int tupleIdBg, int tupleIdEnd) const throw(INTERP_KERNEL::Exception)
1592 {
1593   checkAllocated();
1594   int nbt=getNumberOfTuples();
1595   if(tupleIdBg<0)
1596     throw INTERP_KERNEL::Exception("DataArrayDouble::substr : The tupleIdBg parameter must be greater than 0 !");
1597   if(tupleIdBg>nbt)
1598     throw INTERP_KERNEL::Exception("DataArrayDouble::substr : The tupleIdBg parameter is greater than number of tuples !");
1599   int trueEnd=tupleIdEnd;
1600   if(tupleIdEnd!=-1)
1601     {
1602       if(tupleIdEnd>nbt)
1603         throw INTERP_KERNEL::Exception("DataArrayDouble::substr : The tupleIdBg parameter is greater or equal than number of tuples !");
1604     }
1605   else
1606     trueEnd=nbt;
1607   int nbComp=getNumberOfComponents();
1608   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
1609   ret->alloc(trueEnd-tupleIdBg,nbComp);
1610   ret->copyStringInfoFrom(*this);
1611   std::copy(getConstPointer()+tupleIdBg*nbComp,getConstPointer()+trueEnd*nbComp,ret->getPointer());
1612   return ret.retn();
1613 }
1614
1615 /*!
1616  * Returns a shorten or extended copy of \a this array. If \a newNbOfComp is less
1617  * than \a this->getNumberOfComponents() then the result array is shorten as each tuple
1618  * is truncated to have \a newNbOfComp components, keeping first components. If \a
1619  * newNbOfComp is more than \a this->getNumberOfComponents() then the result array is
1620  * expanded as each tuple is populated with \a dftValue to have \a newNbOfComp
1621  * components.  
1622  *  \param [in] newNbOfComp - number of components for the new array to have.
1623  *  \param [in] dftValue - value assigned to new values added to the new array.
1624  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1625  *          is to delete using decrRef() as it is no more needed.
1626  *  \throw If \a this is not allocated.
1627  */
1628 DataArrayDouble *DataArrayDouble::changeNbOfComponents(int newNbOfComp, double dftValue) const throw(INTERP_KERNEL::Exception)
1629 {
1630   checkAllocated();
1631   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
1632   ret->alloc(getNumberOfTuples(),newNbOfComp);
1633   const double *oldc=getConstPointer();
1634   double *nc=ret->getPointer();
1635   int nbOfTuples=getNumberOfTuples();
1636   int oldNbOfComp=getNumberOfComponents();
1637   int dim=std::min(oldNbOfComp,newNbOfComp);
1638   for(int i=0;i<nbOfTuples;i++)
1639     {
1640       int j=0;
1641       for(;j<dim;j++)
1642         nc[newNbOfComp*i+j]=oldc[i*oldNbOfComp+j];
1643       for(;j<newNbOfComp;j++)
1644         nc[newNbOfComp*i+j]=dftValue;
1645     }
1646   ret->setName(getName().c_str());
1647   for(int i=0;i<dim;i++)
1648     ret->setInfoOnComponent(i,getInfoOnComponent(i).c_str());
1649   ret->setName(getName().c_str());
1650   return ret.retn();
1651 }
1652
1653 /*!
1654  * Changes the number of components within \a this array so that its raw data **does
1655  * not** change, instead splitting this data into tuples changes.
1656  *  \warning This method erases all (name and unit) component info set before!
1657  *  \param [in] newNbOfComp - number of components for \a this array to have.
1658  *  \throw If \a this is not allocated
1659  *  \throw If getNbOfElems() % \a newNbOfCompo != 0.
1660  *  \throw If \a newNbOfCompo is lower than 1.
1661  *  \throw If the rearrange method would lead to a number of tuples higher than 2147483647 (maximal capacity of int32 !).
1662  *  \warning This method erases all (name and unit) component info set before!
1663  */
1664 void DataArrayDouble::rearrange(int newNbOfCompo) throw(INTERP_KERNEL::Exception)
1665 {
1666   checkAllocated();
1667   if(newNbOfCompo<1)
1668     throw INTERP_KERNEL::Exception("DataArrayDouble::rearrange : input newNbOfCompo must be > 0 !");
1669   std::size_t nbOfElems=getNbOfElems();
1670   if(nbOfElems%newNbOfCompo!=0)
1671     throw INTERP_KERNEL::Exception("DataArrayDouble::rearrange : nbOfElems%newNbOfCompo!=0 !");
1672   if(nbOfElems/newNbOfCompo>(std::size_t)std::numeric_limits<int>::max())
1673     throw INTERP_KERNEL::Exception("DataArrayDouble::rearrange : the rearrangement leads to too high number of tuples (> 2147483647) !");
1674   _info_on_compo.clear();
1675   _info_on_compo.resize(newNbOfCompo);
1676   declareAsNew();
1677 }
1678
1679 /*!
1680  * Changes the number of components within \a this array to be equal to its number
1681  * of tuples, and inversely its number of tuples to become equal to its number of 
1682  * components. So that its raw data **does not** change, instead splitting this
1683  * data into tuples changes.
1684  *  \warning This method erases all (name and unit) component info set before!
1685  *  \warning Do not confuse this method with fromNoInterlace() and toNoInterlace()!
1686  *  \throw If \a this is not allocated.
1687  *  \sa rearrange()
1688  */
1689 void DataArrayDouble::transpose() throw(INTERP_KERNEL::Exception)
1690 {
1691   checkAllocated();
1692   int nbOfTuples=getNumberOfTuples();
1693   rearrange(nbOfTuples);
1694 }
1695
1696 /*!
1697  * Returns a copy of \a this array composed of selected components.
1698  * The new DataArrayDouble has the same number of tuples but includes components
1699  * specified by \a compoIds parameter. So that getNbOfElems() of the result array
1700  * can be either less, same or more than \a this->getNbOfElems().
1701  *  \param [in] compoIds - sequence of zero based indices of components to include
1702  *              into the new array.
1703  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1704  *          is to delete using decrRef() as it is no more needed.
1705  *  \throw If \a this is not allocated.
1706  *  \throw If a component index (\a i) is not valid: 
1707  *         \a i < 0 || \a i >= \a this->getNumberOfComponents().
1708  *
1709  *  \ref py_mcdataarraydouble_KeepSelectedComponents "Here is a Python example".
1710  */
1711 DataArray *DataArrayDouble::keepSelectedComponents(const std::vector<int>& compoIds) const throw(INTERP_KERNEL::Exception)
1712 {
1713   checkAllocated();
1714   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret(DataArrayDouble::New());
1715   std::size_t newNbOfCompo=compoIds.size();
1716   int oldNbOfCompo=getNumberOfComponents();
1717   for(std::vector<int>::const_iterator it=compoIds.begin();it!=compoIds.end();it++)
1718     if((*it)<0 || (*it)>=oldNbOfCompo)
1719       {
1720         std::ostringstream oss; oss << "DataArrayDouble::keepSelectedComponents : invalid requested component : " << *it << " whereas it should be in [0," << oldNbOfCompo << ") !";
1721         throw INTERP_KERNEL::Exception(oss.str().c_str());
1722       }
1723   int nbOfTuples=getNumberOfTuples();
1724   ret->alloc(nbOfTuples,(int)newNbOfCompo);
1725   ret->copyPartOfStringInfoFrom(*this,compoIds);
1726   const double *oldc=getConstPointer();
1727   double *nc=ret->getPointer();
1728   for(int i=0;i<nbOfTuples;i++)
1729     for(std::size_t j=0;j<newNbOfCompo;j++,nc++)
1730       *nc=oldc[i*oldNbOfCompo+compoIds[j]];
1731   return ret.retn();
1732 }
1733
1734 /*!
1735  * Appends components of another array to components of \a this one, tuple by tuple.
1736  * So that the number of tuples of \a this array remains the same and the number of 
1737  * components increases.
1738  *  \param [in] other - the DataArrayDouble to append to \a this one.
1739  *  \throw If \a this is not allocated.
1740  *  \throw If \a this and \a other arrays have different number of tuples.
1741  *
1742  *  \ref cpp_mcdataarraydouble_meldwith "Here is a C++ example".
1743  *
1744  *  \ref py_mcdataarraydouble_meldwith "Here is a Python example".
1745  */
1746 void DataArrayDouble::meldWith(const DataArrayDouble *other) throw(INTERP_KERNEL::Exception)
1747 {
1748   checkAllocated();
1749   other->checkAllocated();
1750   int nbOfTuples=getNumberOfTuples();
1751   if(nbOfTuples!=other->getNumberOfTuples())
1752     throw INTERP_KERNEL::Exception("DataArrayDouble::meldWith : mismatch of number of tuples !");
1753   int nbOfComp1=getNumberOfComponents();
1754   int nbOfComp2=other->getNumberOfComponents();
1755   double *newArr=(double *)malloc((nbOfTuples*(nbOfComp1+nbOfComp2))*sizeof(double));
1756   double *w=newArr;
1757   const double *inp1=getConstPointer();
1758   const double *inp2=other->getConstPointer();
1759   for(int i=0;i<nbOfTuples;i++,inp1+=nbOfComp1,inp2+=nbOfComp2)
1760     {
1761       w=std::copy(inp1,inp1+nbOfComp1,w);
1762       w=std::copy(inp2,inp2+nbOfComp2,w);
1763     }
1764   useArray(newArr,true,C_DEALLOC,nbOfTuples,nbOfComp1+nbOfComp2);
1765   std::vector<int> compIds(nbOfComp2);
1766   for(int i=0;i<nbOfComp2;i++)
1767     compIds[i]=nbOfComp1+i;
1768   copyPartOfStringInfoFrom2(compIds,*other);
1769 }
1770
1771 /*!
1772  * Searches for tuples coincident within \a prec tolerance. Each tuple is considered
1773  * as coordinates of a point in getNumberOfComponents()-dimensional space. The
1774  * distance separating two points is computed with the infinite norm.
1775  *
1776  * Indices of coincident tuples are stored in output arrays.
1777  * A pair of arrays (\a comm, \a commIndex) is called "Surjective Format 2".
1778  *
1779  * This method is typically used by MEDCouplingPointSet::findCommonNodes() and
1780  * MEDCouplingUMesh::mergeNodes().
1781  *  \param [in] prec - minimal absolute distance between two tuples (infinite norm) at which they are
1782  *              considered not coincident.
1783  *  \param [in] limitTupleId - limit tuple id. If all tuples within a group of coincident
1784  *              tuples have id strictly lower than \a limitTupleId then they are not returned.
1785  *  \param [out] comm - the array holding ids (== indices) of coincident tuples. 
1786  *               \a comm->getNumberOfComponents() == 1. 
1787  *               \a comm->getNumberOfTuples() == \a commIndex->back().
1788  *  \param [out] commIndex - the array dividing all indices stored in \a comm into
1789  *               groups of (indices of) coincident tuples. Its every value is a tuple
1790  *               index where a next group of tuples begins. For example the second
1791  *               group of tuples in \a comm is described by following range of indices:
1792  *               [ \a commIndex[1], \a commIndex[2] ). \a commIndex->getNumberOfTuples()-1
1793  *               gives the number of groups of coincident tuples.
1794  *  \throw If \a this is not allocated.
1795  *  \throw If the number of components is not in [1,2,3].
1796  *
1797  *  \ref cpp_mcdataarraydouble_findcommontuples "Here is a C++ example".
1798  *
1799  *  \ref py_mcdataarraydouble_findcommontuples  "Here is a Python example".
1800  *  \sa DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2().
1801  */
1802 void DataArrayDouble::findCommonTuples(double prec, int limitTupleId, DataArrayInt *&comm, DataArrayInt *&commIndex) const throw(INTERP_KERNEL::Exception)
1803 {
1804   checkAllocated();
1805   int nbOfCompo=getNumberOfComponents();
1806   if ((nbOfCompo<1) || (nbOfCompo>3)) //test before work
1807     throw INTERP_KERNEL::Exception("DataArrayDouble::findCommonTuples : Unexpected spacedim of coords. Must be 1, 2 or 3.");
1808   
1809   int nbOfTuples=getNumberOfTuples();
1810   //
1811   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> c(DataArrayInt::New()),cI(DataArrayInt::New()); c->alloc(0,1); cI->pushBackSilent(0);
1812   switch(nbOfCompo)
1813     {
1814     case 3:
1815       findCommonTuplesAlg<3>(begin(),nbOfTuples,limitTupleId,prec,c,cI);
1816       break;
1817     case 2:
1818       findCommonTuplesAlg<2>(begin(),nbOfTuples,limitTupleId,prec,c,cI);
1819       break;
1820     case 1:
1821       findCommonTuplesAlg<1>(begin(),nbOfTuples,limitTupleId,prec,c,cI);
1822       break;
1823     default:
1824       throw INTERP_KERNEL::Exception("DataArrayDouble::findCommonTuples : nb of components managed are 1,2 and 3 ! not implemented for other number of components !");
1825     }
1826   comm=c.retn();
1827   commIndex=cI.retn();
1828 }
1829
1830 /*!
1831  * 
1832  * \param [in] nbTimes specifies the nb of times each tuples in \a this will be duplicated contiguouly in returned DataArrayDouble instance.
1833  *             \a nbTimes  should be at least equal to 1.
1834  * \return a newly allocated DataArrayDouble having one component and number of tuples equal to \a nbTimes * \c this->getNumberOfTuples.
1835  * \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.
1836  */
1837 DataArrayDouble *DataArrayDouble::duplicateEachTupleNTimes(int nbTimes) const throw(INTERP_KERNEL::Exception)
1838 {
1839   checkAllocated();
1840   if(getNumberOfComponents()!=1)
1841     throw INTERP_KERNEL::Exception("DataArrayDouble::duplicateEachTupleNTimes : this should have only one component !");
1842   if(nbTimes<1)
1843     throw INTERP_KERNEL::Exception("DataArrayDouble::duplicateEachTupleNTimes : nb times should be >= 1 !");
1844   int nbTuples=getNumberOfTuples();
1845   const double *inPtr=getConstPointer();
1846   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New(); ret->alloc(nbTimes*nbTuples,1);
1847   double *retPtr=ret->getPointer();
1848   for(int i=0;i<nbTuples;i++,inPtr++)
1849     {
1850       double val=*inPtr;
1851       for(int j=0;j<nbTimes;j++,retPtr++)
1852         *retPtr=val;
1853     }
1854   ret->copyStringInfoFrom(*this);
1855   return ret.retn();
1856 }
1857
1858 /*!
1859  * This methods returns the minimal distance between the two set of points \a this and \a other.
1860  * So \a this and \a other have to have the same number of components. If not an INTERP_KERNEL::Exception will be thrown.
1861  * This method works only if number of components of \a this (equal to those of \a other) is in 1, 2 or 3.
1862  *
1863  * \param [out] thisTupleId the tuple id in \a this corresponding to the returned minimal distance
1864  * \param [out] otherTupleId the tuple id in \a other corresponding to the returned minimal distance
1865  * \return the minimal distance between the two set of points \a this and \a other.
1866  * \sa DataArrayDouble::findClosestTupleId
1867  */
1868 double DataArrayDouble::minimalDistanceTo(const DataArrayDouble *other, int& thisTupleId, int& otherTupleId) const throw(INTERP_KERNEL::Exception)
1869 {
1870   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> part1=findClosestTupleId(other);
1871   int nbOfCompo(getNumberOfComponents());
1872   int otherNbTuples(other->getNumberOfTuples());
1873   const double *thisPt(begin()),*otherPt(other->begin());
1874   const int *part1Pt(part1->begin());
1875   double ret=std::numeric_limits<double>::max();
1876   for(int i=0;i<otherNbTuples;i++,part1Pt++,otherPt+=nbOfCompo)
1877     {
1878       double tmp(0.);
1879       for(int j=0;j<nbOfCompo;j++)
1880         tmp+=(otherPt[j]-thisPt[nbOfCompo*(*part1Pt)+j])*(otherPt[j]-thisPt[nbOfCompo*(*part1Pt)+j]);
1881       if(tmp<ret)
1882         { ret=tmp; thisTupleId=*part1Pt; otherTupleId=i; }
1883     }
1884   return sqrt(ret);
1885 }
1886
1887 /*!
1888  * This methods returns for each tuple in \a other which tuple in \a this is the closest.
1889  * So \a this and \a other have to have the same number of components. If not an INTERP_KERNEL::Exception will be thrown.
1890  * This method works only if number of components of \a this (equal to those of \a other) is in 1, 2 or 3.
1891  *
1892  * \return a newly allocated (new object to be dealt by the caller) DataArrayInt having \c other->getNumberOfTuples() tuples and one components.
1893  * \sa DataArrayDouble::minimalDistanceTo
1894  */
1895 DataArrayInt *DataArrayDouble::findClosestTupleId(const DataArrayDouble *other) const throw(INTERP_KERNEL::Exception)
1896 {
1897   if(!other)
1898     throw INTERP_KERNEL::Exception("DataArrayDouble::findClosestTupleId : other instance is NULL !");
1899   checkAllocated(); other->checkAllocated();
1900   int nbOfCompo=getNumberOfComponents();
1901   if(nbOfCompo!=other->getNumberOfComponents())
1902     {
1903       std::ostringstream oss; oss << "DataArrayDouble::findClosestTupleId : number of components in this is " << nbOfCompo;
1904       oss << ", whereas number of components in other is " << other->getNumberOfComponents() << "! Should be equal !";
1905       throw INTERP_KERNEL::Exception(oss.str().c_str());
1906     }
1907   int nbOfTuples=other->getNumberOfTuples();
1908   int thisNbOfTuples=getNumberOfTuples();
1909   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbOfTuples,1);
1910   double bounds[6];
1911   getMinMaxPerComponent(bounds);
1912   switch(nbOfCompo)
1913     {
1914     case 3:
1915       {
1916         double xDelta(fabs(bounds[1]-bounds[0])),yDelta(fabs(bounds[3]-bounds[2])),zDelta(fabs(bounds[5]-bounds[4]));
1917         double delta=std::max(xDelta,yDelta); delta=std::max(delta,zDelta);
1918         double characSize=pow((delta*delta*delta)/((double)thisNbOfTuples),1./3.);
1919         BBTreePts<3,int> myTree(begin(),0,0,getNumberOfTuples(),characSize*1e-12);
1920         FindClosestTupleIdAlg<3>(myTree,3.*characSize*characSize,other->begin(),nbOfTuples,begin(),thisNbOfTuples,ret->getPointer());
1921         break;
1922       }
1923     case 2:
1924       {
1925         double xDelta(fabs(bounds[1]-bounds[0])),yDelta(fabs(bounds[3]-bounds[2]));
1926         double delta=std::max(xDelta,yDelta);
1927         double characSize=sqrt(delta/(double)thisNbOfTuples);
1928         BBTreePts<2,int> myTree(begin(),0,0,getNumberOfTuples(),characSize*1e-12);
1929         FindClosestTupleIdAlg<2>(myTree,2.*characSize*characSize,other->begin(),nbOfTuples,begin(),thisNbOfTuples,ret->getPointer());
1930         break;
1931       }
1932     case 1:
1933       {
1934         double characSize=fabs(bounds[1]-bounds[0])/thisNbOfTuples;
1935         BBTreePts<1,int> myTree(begin(),0,0,getNumberOfTuples(),characSize*1e-12);
1936         FindClosestTupleIdAlg<1>(myTree,1.*characSize*characSize,other->begin(),nbOfTuples,begin(),thisNbOfTuples,ret->getPointer());
1937         break;
1938       }
1939     default:
1940       throw INTERP_KERNEL::Exception("Unexpected spacedim of coords for findClosestTupleId. Must be 1, 2 or 3.");
1941     }
1942   return ret.retn();
1943 }
1944
1945 /*!
1946  * Returns a copy of \a this array by excluding coincident tuples. Each tuple is
1947  * considered as coordinates of a point in getNumberOfComponents()-dimensional
1948  * space. The distance between tuples is computed using norm2. If several tuples are
1949  * not far each from other than \a prec, only one of them remains in the result
1950  * array. The order of tuples in the result array is same as in \a this one except
1951  * that coincident tuples are excluded.
1952  *  \param [in] prec - minimal absolute distance between two tuples at which they are
1953  *              considered not coincident.
1954  *  \param [in] limitTupleId - limit tuple id. If all tuples within a group of coincident
1955  *              tuples have id strictly lower than \a limitTupleId then they are not excluded.
1956  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1957  *          is to delete using decrRef() as it is no more needed.
1958  *  \throw If \a this is not allocated.
1959  *  \throw If the number of components is not in [1,2,3].
1960  *
1961  *  \ref py_mcdataarraydouble_getdifferentvalues "Here is a Python example".
1962  */
1963 DataArrayDouble *DataArrayDouble::getDifferentValues(double prec, int limitTupleId) const throw(INTERP_KERNEL::Exception)
1964 {
1965   checkAllocated();
1966   DataArrayInt *c0=0,*cI0=0;
1967   findCommonTuples(prec,limitTupleId,c0,cI0);
1968   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> c(c0),cI(cI0);
1969   int newNbOfTuples=-1;
1970   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> o2n=DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2(getNumberOfTuples(),c0->begin(),cI0->begin(),cI0->end(),newNbOfTuples);
1971   return renumberAndReduce(o2n->getConstPointer(),newNbOfTuples);
1972 }
1973
1974 /*!
1975  * Copy all components in a specified order from another DataArrayDouble.
1976  * Both numerical and textual data is copied. The number of tuples in \a this and
1977  * the other array can be different.
1978  *  \param [in] a - the array to copy data from.
1979  *  \param [in] compoIds - sequence of zero based indices of components, data of which is
1980  *              to be copied.
1981  *  \throw If \a a is NULL.
1982  *  \throw If \a compoIds.size() != \a a->getNumberOfComponents().
1983  *  \throw If \a compoIds[i] < 0 or \a compoIds[i] > \a this->getNumberOfComponents().
1984  *
1985  *  \ref py_mcdataarraydouble_setselectedcomponents "Here is a Python example".
1986  */
1987 void DataArrayDouble::setSelectedComponents(const DataArrayDouble *a, const std::vector<int>& compoIds) throw(INTERP_KERNEL::Exception)
1988 {
1989   if(!a)
1990     throw INTERP_KERNEL::Exception("DataArrayDouble::setSelectedComponents : input DataArrayDouble is NULL !");
1991   checkAllocated();
1992   copyPartOfStringInfoFrom2(compoIds,*a);
1993   std::size_t partOfCompoSz=compoIds.size();
1994   int nbOfCompo=getNumberOfComponents();
1995   int nbOfTuples=std::min(getNumberOfTuples(),a->getNumberOfTuples());
1996   const double *ac=a->getConstPointer();
1997   double *nc=getPointer();
1998   for(int i=0;i<nbOfTuples;i++)
1999     for(std::size_t j=0;j<partOfCompoSz;j++,ac++)
2000       nc[nbOfCompo*i+compoIds[j]]=*ac;
2001 }
2002
2003 /*!
2004  * Copy all values from another DataArrayDouble into specified tuples and components
2005  * of \a this array. Textual data is not copied.
2006  * The tree parameters defining set of indices of tuples and components are similar to
2007  * the tree parameters of the Python function \c range(\c start,\c stop,\c step).
2008  *  \param [in] a - the array to copy values from.
2009  *  \param [in] bgTuples - index of the first tuple of \a this array to assign values to.
2010  *  \param [in] endTuples - index of the tuple before which the tuples to assign to
2011  *              are located.
2012  *  \param [in] stepTuples - index increment to get index of the next tuple to assign to.
2013  *  \param [in] bgComp - index of the first component of \a this array to assign values to.
2014  *  \param [in] endComp - index of the component before which the components to assign
2015  *              to are located.
2016  *  \param [in] stepComp - index increment to get index of the next component to assign to.
2017  *  \param [in] strictCompoCompare - if \a true (by default), then \a a->getNumberOfComponents() 
2018  *              must be equal to the number of columns to assign to, else an
2019  *              exception is thrown; if \a false, then it is only required that \a
2020  *              a->getNbOfElems() equals to number of values to assign to (this condition
2021  *              must be respected even if \a strictCompoCompare is \a true). The number of 
2022  *              values to assign to is given by following Python expression:
2023  *              \a nbTargetValues = 
2024  *              \c len(\c range(\a bgTuples,\a endTuples,\a stepTuples)) *
2025  *              \c len(\c range(\a bgComp,\a endComp,\a stepComp)).
2026  *  \throw If \a a is NULL.
2027  *  \throw If \a a is not allocated.
2028  *  \throw If \a this is not allocated.
2029  *  \throw If parameters specifying tuples and components to assign to do not give a
2030  *            non-empty range of increasing indices.
2031  *  \throw If \a a->getNbOfElems() != \a nbTargetValues.
2032  *  \throw If \a strictCompoCompare == \a true && \a a->getNumberOfComponents() !=
2033  *            \c len(\c range(\a bgComp,\a endComp,\a stepComp)).
2034  *
2035  *  \ref py_mcdataarraydouble_setpartofvalues1 "Here is a Python example".
2036  */
2037 void DataArrayDouble::setPartOfValues1(const DataArrayDouble *a, int bgTuples, int endTuples, int stepTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare) throw(INTERP_KERNEL::Exception)
2038 {
2039   if(!a)
2040     throw INTERP_KERNEL::Exception("DataArrayDouble::setPartOfValues1 : input DataArrayDouble is NULL !");
2041   const char msg[]="DataArrayDouble::setPartOfValues1";
2042   checkAllocated();
2043   a->checkAllocated();
2044   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
2045   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
2046   int nbComp=getNumberOfComponents();
2047   int nbOfTuples=getNumberOfTuples();
2048   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
2049   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
2050   bool assignTech=true;
2051   if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
2052     {
2053       if(strictCompoCompare)
2054         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
2055     }
2056   else
2057     {
2058       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
2059       assignTech=false;
2060     }
2061   const double *srcPt=a->getConstPointer();
2062   double *pt=getPointer()+bgTuples*nbComp+bgComp;
2063   if(assignTech)
2064     {
2065       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
2066         for(int j=0;j<newNbOfComp;j++,srcPt++)
2067           pt[j*stepComp]=*srcPt;
2068     }
2069   else
2070     {
2071       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
2072         {
2073           const double *srcPt2=srcPt;
2074           for(int j=0;j<newNbOfComp;j++,srcPt2++)
2075             pt[j*stepComp]=*srcPt2;
2076         }
2077     }
2078 }
2079
2080 /*!
2081  * Assign a given value to values at specified tuples and components of \a this array.
2082  * The tree parameters defining set of indices of tuples and components are similar to
2083  * the tree parameters of the Python function \c range(\c start,\c stop,\c step)..
2084  *  \param [in] a - the value to assign.
2085  *  \param [in] bgTuples - index of the first tuple of \a this array to assign to.
2086  *  \param [in] endTuples - index of the tuple before which the tuples to assign to
2087  *              are located.
2088  *  \param [in] stepTuples - index increment to get index of the next tuple to assign to.
2089  *  \param [in] bgComp - index of the first component of \a this array to assign to.
2090  *  \param [in] endComp - index of the component before which the components to assign
2091  *              to are located.
2092  *  \param [in] stepComp - index increment to get index of the next component to assign to.
2093  *  \throw If \a this is not allocated.
2094  *  \throw If parameters specifying tuples and components to assign to, do not give a
2095  *            non-empty range of increasing indices or indices are out of a valid range
2096  *            for \this array.
2097  *
2098  *  \ref py_mcdataarraydouble_setpartofvaluessimple1 "Here is a Python example".
2099  */
2100 void DataArrayDouble::setPartOfValuesSimple1(double a, int bgTuples, int endTuples, int stepTuples, int bgComp, int endComp, int stepComp) throw(INTERP_KERNEL::Exception)
2101 {
2102   const char msg[]="DataArrayDouble::setPartOfValuesSimple1";
2103   checkAllocated();
2104   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
2105   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
2106   int nbComp=getNumberOfComponents();
2107   int nbOfTuples=getNumberOfTuples();
2108   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
2109   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
2110   double *pt=getPointer()+bgTuples*nbComp+bgComp;
2111   for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
2112     for(int j=0;j<newNbOfComp;j++)
2113       pt[j*stepComp]=a;
2114 }
2115
2116 /*!
2117  * Copy all values from another DataArrayDouble (\a a) into specified tuples and 
2118  * components of \a this array. Textual data is not copied.
2119  * The tuples and components to assign to are defined by C arrays of indices.
2120  * There are two *modes of usage*:
2121  * - If \a a->getNbOfElems() equals to number of values to assign to, then every value
2122  *   of \a a is assigned to its own location within \a this array. 
2123  * - If \a a includes one tuple, then all values of \a a are assigned to the specified
2124  *   components of every specified tuple of \a this array. In this mode it is required
2125  *   that \a a->getNumberOfComponents() equals to the number of specified components.
2126  *
2127  *  \param [in] a - the array to copy values from.
2128  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
2129  *              assign values of \a a to.
2130  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
2131  *              pointer to a tuple index <em>(pi)</em> varies as this: 
2132  *              \a bgTuples <= \a pi < \a endTuples.
2133  *  \param [in] bgComp - pointer to an array of component indices of \a this array to
2134  *              assign values of \a a to.
2135  *  \param [in] endComp - specifies the end of the array \a bgTuples, so that
2136  *              pointer to a component index <em>(pi)</em> varies as this: 
2137  *              \a bgComp <= \a pi < \a endComp.
2138  *  \param [in] strictCompoCompare - this parameter is checked only if the
2139  *               *mode of usage* is the first; if it is \a true (default), 
2140  *               then \a a->getNumberOfComponents() must be equal 
2141  *               to the number of specified columns, else this is not required.
2142  *  \throw If \a a is NULL.
2143  *  \throw If \a a is not allocated.
2144  *  \throw If \a this is not allocated.
2145  *  \throw If any index of tuple/component given by <em>bgTuples / bgComp</em> is
2146  *         out of a valid range for \a this array.
2147  *  \throw In the first *mode of usage*, if <em>strictCompoCompare == true </em> and
2148  *         if <em> a->getNumberOfComponents() != (endComp - bgComp) </em>.
2149  *  \throw In the second *mode of usage*, if \a a->getNumberOfTuples() != 1 or
2150  *         <em> a->getNumberOfComponents() != (endComp - bgComp)</em>.
2151  *
2152  *  \ref py_mcdataarraydouble_setpartofvalues2 "Here is a Python example".
2153  */
2154 void DataArrayDouble::setPartOfValues2(const DataArrayDouble *a, const int *bgTuples, const int *endTuples, const int *bgComp, const int *endComp, bool strictCompoCompare) throw(INTERP_KERNEL::Exception)
2155 {
2156   if(!a)
2157     throw INTERP_KERNEL::Exception("DataArrayDouble::setPartOfValues2 : input DataArrayDouble is NULL !");
2158   const char msg[]="DataArrayDouble::setPartOfValues2";
2159   checkAllocated();
2160   a->checkAllocated();
2161   int nbComp=getNumberOfComponents();
2162   int nbOfTuples=getNumberOfTuples();
2163   for(const int *z=bgComp;z!=endComp;z++)
2164     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
2165   int newNbOfTuples=(int)std::distance(bgTuples,endTuples);
2166   int newNbOfComp=(int)std::distance(bgComp,endComp);
2167   bool assignTech=true;
2168   if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
2169     {
2170       if(strictCompoCompare)
2171         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
2172     }
2173   else
2174     {
2175       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
2176       assignTech=false;
2177     }
2178   double *pt=getPointer();
2179   const double *srcPt=a->getConstPointer();
2180   if(assignTech)
2181     {    
2182       for(const int *w=bgTuples;w!=endTuples;w++)
2183         {
2184           DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
2185           for(const int *z=bgComp;z!=endComp;z++,srcPt++)
2186             {    
2187               pt[(std::size_t)(*w)*nbComp+(*z)]=*srcPt;
2188             }
2189         }
2190     }
2191   else
2192     {
2193       for(const int *w=bgTuples;w!=endTuples;w++)
2194         {
2195           const double *srcPt2=srcPt;
2196           DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
2197           for(const int *z=bgComp;z!=endComp;z++,srcPt2++)
2198             {    
2199               pt[(std::size_t)(*w)*nbComp+(*z)]=*srcPt2;
2200             }
2201         }
2202     }
2203 }
2204
2205 /*!
2206  * Assign a given value to values at specified tuples and components of \a this array.
2207  * The tuples and components to assign to are defined by C arrays of indices.
2208  *  \param [in] a - the value to assign.
2209  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
2210  *              assign \a a to.
2211  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
2212  *              pointer to a tuple index (\a pi) varies as this: 
2213  *              \a bgTuples <= \a pi < \a endTuples.
2214  *  \param [in] bgComp - pointer to an array of component indices of \a this array to
2215  *              assign \a a to.
2216  *  \param [in] endComp - specifies the end of the array \a bgTuples, so that
2217  *              pointer to a component index (\a pi) varies as this: 
2218  *              \a bgComp <= \a pi < \a endComp.
2219  *  \throw If \a this is not allocated.
2220  *  \throw If any index of tuple/component given by <em>bgTuples / bgComp</em> is
2221  *         out of a valid range for \a this array.
2222  *
2223  *  \ref py_mcdataarraydouble_setpartofvaluessimple2 "Here is a Python example".
2224  */
2225 void DataArrayDouble::setPartOfValuesSimple2(double a, const int *bgTuples, const int *endTuples, const int *bgComp, const int *endComp) throw(INTERP_KERNEL::Exception)
2226 {
2227   checkAllocated();
2228   int nbComp=getNumberOfComponents();
2229   int nbOfTuples=getNumberOfTuples();
2230   for(const int *z=bgComp;z!=endComp;z++)
2231     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
2232   double *pt=getPointer();
2233   for(const int *w=bgTuples;w!=endTuples;w++)
2234     for(const int *z=bgComp;z!=endComp;z++)
2235       {
2236         DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
2237         pt[(std::size_t)(*w)*nbComp+(*z)]=a;
2238       }
2239 }
2240
2241 /*!
2242  * Copy all values from another DataArrayDouble (\a a) into specified tuples and 
2243  * components of \a this array. Textual data is not copied.
2244  * The tuples to assign to are defined by a C array of indices.
2245  * The components to assign to are defined by three values similar to parameters of
2246  * the Python function \c range(\c start,\c stop,\c step).
2247  * There are two *modes of usage*:
2248  * - If \a a->getNbOfElems() equals to number of values to assign to, then every value
2249  *   of \a a is assigned to its own location within \a this array. 
2250  * - If \a a includes one tuple, then all values of \a a are assigned to the specified
2251  *   components of every specified tuple of \a this array. In this mode it is required
2252  *   that \a a->getNumberOfComponents() equals to the number of specified components.
2253  *
2254  *  \param [in] a - the array to copy values from.
2255  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
2256  *              assign values of \a a to.
2257  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
2258  *              pointer to a tuple index <em>(pi)</em> varies as this: 
2259  *              \a bgTuples <= \a pi < \a endTuples.
2260  *  \param [in] bgComp - index of the first component of \a this array to assign to.
2261  *  \param [in] endComp - index of the component before which the components to assign
2262  *              to are located.
2263  *  \param [in] stepComp - index increment to get index of the next component to assign to.
2264  *  \param [in] strictCompoCompare - this parameter is checked only in the first
2265  *               *mode of usage*; if \a strictCompoCompare is \a true (default), 
2266  *               then \a a->getNumberOfComponents() must be equal 
2267  *               to the number of specified columns, else this is not required.
2268  *  \throw If \a a is NULL.
2269  *  \throw If \a a is not allocated.
2270  *  \throw If \a this is not allocated.
2271  *  \throw If any index of tuple given by \a bgTuples is out of a valid range for 
2272  *         \a this array.
2273  *  \throw In the first *mode of usage*, if <em>strictCompoCompare == true </em> and
2274  *         if <em> a->getNumberOfComponents()</em> is unequal to the number of components
2275  *         defined by <em>(bgComp,endComp,stepComp)</em>.
2276  *  \throw In the second *mode of usage*, if \a a->getNumberOfTuples() != 1 or
2277  *         <em> a->getNumberOfComponents()</em> is unequal to the number of components
2278  *         defined by <em>(bgComp,endComp,stepComp)</em>.
2279  *  \throw If parameters specifying components to assign to, do not give a
2280  *            non-empty range of increasing indices or indices are out of a valid range
2281  *            for \this array.
2282  *
2283  *  \ref py_mcdataarraydouble_setpartofvalues3 "Here is a Python example".
2284  */
2285 void DataArrayDouble::setPartOfValues3(const DataArrayDouble *a, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare) throw(INTERP_KERNEL::Exception)
2286 {
2287   if(!a)
2288     throw INTERP_KERNEL::Exception("DataArrayDouble::setPartOfValues3 : input DataArrayDouble is NULL !");
2289   const char msg[]="DataArrayDouble::setPartOfValues3";
2290   checkAllocated();
2291   a->checkAllocated();
2292   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
2293   int nbComp=getNumberOfComponents();
2294   int nbOfTuples=getNumberOfTuples();
2295   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
2296   int newNbOfTuples=(int)std::distance(bgTuples,endTuples);
2297   bool assignTech=true;
2298   if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
2299     {
2300       if(strictCompoCompare)
2301         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
2302     }
2303   else
2304     {
2305       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
2306       assignTech=false;
2307     }
2308   double *pt=getPointer()+bgComp;
2309   const double *srcPt=a->getConstPointer();
2310   if(assignTech)
2311     {
2312       for(const int *w=bgTuples;w!=endTuples;w++)
2313         for(int j=0;j<newNbOfComp;j++,srcPt++)
2314           {
2315             DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
2316             pt[(std::size_t)(*w)*nbComp+j*stepComp]=*srcPt;
2317           }
2318     }
2319   else
2320     {
2321       for(const int *w=bgTuples;w!=endTuples;w++)
2322         {
2323           const double *srcPt2=srcPt;
2324           for(int j=0;j<newNbOfComp;j++,srcPt2++)
2325             {
2326               DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
2327               pt[(std::size_t)(*w)*nbComp+j*stepComp]=*srcPt2;
2328             }
2329         }
2330     }
2331 }
2332
2333 /*!
2334  * Assign a given value to values at specified tuples and components of \a this array.
2335  * The tuples to assign to are defined by a C array of indices.
2336  * The components to assign to are defined by three values similar to parameters of
2337  * the Python function \c range(\c start,\c stop,\c step).
2338  *  \param [in] a - the value to assign.
2339  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
2340  *              assign \a a to.
2341  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
2342  *              pointer to a tuple index <em>(pi)</em> varies as this: 
2343  *              \a bgTuples <= \a pi < \a endTuples.
2344  *  \param [in] bgComp - index of the first component of \a this array to assign to.
2345  *  \param [in] endComp - index of the component before which the components to assign
2346  *              to are located.
2347  *  \param [in] stepComp - index increment to get index of the next component to assign to.
2348  *  \throw If \a this is not allocated.
2349  *  \throw If any index of tuple given by \a bgTuples is out of a valid range for 
2350  *         \a this array.
2351  *  \throw If parameters specifying components to assign to, do not give a
2352  *            non-empty range of increasing indices or indices are out of a valid range
2353  *            for \this array.
2354  *
2355  *  \ref py_mcdataarraydouble_setpartofvaluessimple3 "Here is a Python example".
2356  */
2357 void DataArrayDouble::setPartOfValuesSimple3(double a, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp) throw(INTERP_KERNEL::Exception)
2358 {
2359   const char msg[]="DataArrayDouble::setPartOfValuesSimple3";
2360   checkAllocated();
2361   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
2362   int nbComp=getNumberOfComponents();
2363   int nbOfTuples=getNumberOfTuples();
2364   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
2365   double *pt=getPointer()+bgComp;
2366   for(const int *w=bgTuples;w!=endTuples;w++)
2367     for(int j=0;j<newNbOfComp;j++)
2368       {
2369         DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
2370         pt[(std::size_t)(*w)*nbComp+j*stepComp]=a;
2371       }
2372 }
2373
2374 /*!
2375  * Copy all values from another DataArrayDouble into specified tuples and components
2376  * of \a this array. Textual data is not copied.
2377  * The tree parameters defining set of indices of tuples and components are similar to
2378  * the tree parameters of the Python function \c range(\c start,\c stop,\c step).
2379  *  \param [in] a - the array to copy values from.
2380  *  \param [in] bgTuples - index of the first tuple of \a this array to assign values to.
2381  *  \param [in] endTuples - index of the tuple before which the tuples to assign to
2382  *              are located.
2383  *  \param [in] stepTuples - index increment to get index of the next tuple to assign to.
2384  *  \param [in] bgComp - pointer to an array of component indices of \a this array to
2385  *              assign \a a to.
2386  *  \param [in] endComp - specifies the end of the array \a bgTuples, so that
2387  *              pointer to a component index (\a pi) varies as this: 
2388  *              \a bgComp <= \a pi < \a endComp.
2389  *  \param [in] strictCompoCompare - if \a true (by default), then \a a->getNumberOfComponents() 
2390  *              must be equal to the number of columns to assign to, else an
2391  *              exception is thrown; if \a false, then it is only required that \a
2392  *              a->getNbOfElems() equals to number of values to assign to (this condition
2393  *              must be respected even if \a strictCompoCompare is \a true). The number of 
2394  *              values to assign to is given by following Python expression:
2395  *              \a nbTargetValues = 
2396  *              \c len(\c range(\a bgTuples,\a endTuples,\a stepTuples)) *
2397  *              \c len(\c range(\a bgComp,\a endComp,\a stepComp)).
2398  *  \throw If \a a is NULL.
2399  *  \throw If \a a is not allocated.
2400  *  \throw If \a this is not allocated.
2401  *  \throw If parameters specifying tuples and components to assign to do not give a
2402  *            non-empty range of increasing indices.
2403  *  \throw If \a a->getNbOfElems() != \a nbTargetValues.
2404  *  \throw If \a strictCompoCompare == \a true && \a a->getNumberOfComponents() !=
2405  *            \c len(\c range(\a bgComp,\a endComp,\a stepComp)).
2406  *
2407  */
2408 void DataArrayDouble::setPartOfValues4(const DataArrayDouble *a, int bgTuples, int endTuples, int stepTuples, const int *bgComp, const int *endComp, bool strictCompoCompare) throw(INTERP_KERNEL::Exception)
2409 {
2410   if(!a)
2411     throw INTERP_KERNEL::Exception("DataArrayDouble::setPartOfValues4 : input DataArrayDouble is NULL !");
2412   const char msg[]="DataArrayDouble::setPartOfValues4";
2413   checkAllocated();
2414   a->checkAllocated();
2415   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
2416   int newNbOfComp=(int)std::distance(bgComp,endComp);
2417   int nbComp=getNumberOfComponents();
2418   for(const int *z=bgComp;z!=endComp;z++)
2419     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
2420   int nbOfTuples=getNumberOfTuples();
2421   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
2422   bool assignTech=true;
2423   if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
2424     {
2425       if(strictCompoCompare)
2426         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
2427     }
2428   else
2429     {
2430       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
2431       assignTech=false;
2432     }
2433   const double *srcPt=a->getConstPointer();
2434   double *pt=getPointer()+bgTuples*nbComp;
2435   if(assignTech)
2436     {
2437       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
2438         for(const int *z=bgComp;z!=endComp;z++,srcPt++)
2439           pt[*z]=*srcPt;
2440     }
2441   else
2442     {
2443       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
2444         {
2445           const double *srcPt2=srcPt;
2446           for(const int *z=bgComp;z!=endComp;z++,srcPt2++)
2447             pt[*z]=*srcPt2;
2448         }
2449     }
2450 }
2451
2452 void DataArrayDouble::setPartOfValuesSimple4(double a, int bgTuples, int endTuples, int stepTuples, const int *bgComp, const int *endComp) throw(INTERP_KERNEL::Exception)
2453 {
2454   const char msg[]="DataArrayDouble::setPartOfValuesSimple4";
2455   checkAllocated();
2456   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
2457   int nbComp=getNumberOfComponents();
2458   for(const int *z=bgComp;z!=endComp;z++)
2459     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
2460   int nbOfTuples=getNumberOfTuples();
2461   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
2462   double *pt=getPointer()+bgTuples*nbComp;
2463   for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
2464     for(const int *z=bgComp;z!=endComp;z++)
2465       pt[*z]=a;
2466 }
2467
2468 /*!
2469  * Copy some tuples from another DataArrayDouble into specified tuples
2470  * of \a this array. Textual data is not copied. Both arrays must have equal number of
2471  * components.
2472  * Both the tuples to assign and the tuples to assign to are defined by a DataArrayInt.
2473  * All components of selected tuples are copied.
2474  *  \param [in] a - the array to copy values from.
2475  *  \param [in] tuplesSelec - the array specifying both source tuples of \a a and
2476  *              target tuples of \a this. \a tuplesSelec has two components, and the
2477  *              first component specifies index of the source tuple and the second
2478  *              one specifies index of the target tuple.
2479  *  \throw If \a this is not allocated.
2480  *  \throw If \a a is NULL.
2481  *  \throw If \a a is not allocated.
2482  *  \throw If \a tuplesSelec is NULL.
2483  *  \throw If \a tuplesSelec is not allocated.
2484  *  \throw If <em>this->getNumberOfComponents() != a->getNumberOfComponents()</em>.
2485  *  \throw If \a tuplesSelec->getNumberOfComponents() != 2.
2486  *  \throw If any tuple index given by \a tuplesSelec is out of a valid range for 
2487  *         the corresponding (\a this or \a a) array.
2488  */
2489 void DataArrayDouble::setPartOfValuesAdv(const DataArrayDouble *a, const DataArrayInt *tuplesSelec) throw(INTERP_KERNEL::Exception)
2490 {
2491   if(!a || !tuplesSelec)
2492     throw INTERP_KERNEL::Exception("DataArrayDouble::setPartOfValuesAdv : input DataArrayDouble is NULL !");
2493   checkAllocated();
2494   a->checkAllocated();
2495   tuplesSelec->checkAllocated();
2496   int nbOfComp=getNumberOfComponents();
2497   if(nbOfComp!=a->getNumberOfComponents())
2498     throw INTERP_KERNEL::Exception("DataArrayDouble::setPartOfValuesAdv : This and a do not have the same number of components !");
2499   if(tuplesSelec->getNumberOfComponents()!=2)
2500     throw INTERP_KERNEL::Exception("DataArrayDouble::setPartOfValuesAdv : Expecting to have a tuple selector DataArrayInt instance with exactly 2 components !");
2501   int thisNt=getNumberOfTuples();
2502   int aNt=a->getNumberOfTuples();
2503   double *valsToSet=getPointer();
2504   const double *valsSrc=a->getConstPointer();
2505   for(const int *tuple=tuplesSelec->begin();tuple!=tuplesSelec->end();tuple+=2)
2506     {
2507       if(tuple[1]>=0 && tuple[1]<aNt)
2508         {
2509           if(tuple[0]>=0 && tuple[0]<thisNt)
2510             std::copy(valsSrc+nbOfComp*tuple[1],valsSrc+nbOfComp*(tuple[1]+1),valsToSet+nbOfComp*tuple[0]);
2511           else
2512             {
2513               std::ostringstream oss; oss << "DataArrayDouble::setPartOfValuesAdv : Tuple #" << std::distance(tuplesSelec->begin(),tuple)/2;
2514               oss << " of 'tuplesSelec' request of tuple id #" << tuple[0] << " in 'this' ! It should be in [0," << thisNt << ") !";
2515               throw INTERP_KERNEL::Exception(oss.str().c_str());
2516             }
2517         }
2518       else
2519         {
2520           std::ostringstream oss; oss << "DataArrayDouble::setPartOfValuesAdv : Tuple #" << std::distance(tuplesSelec->begin(),tuple)/2;
2521           oss << " of 'tuplesSelec' request of tuple id #" << tuple[1] << " in 'a' ! It should be in [0," << aNt << ") !";
2522           throw INTERP_KERNEL::Exception(oss.str().c_str());
2523         }
2524     }
2525 }
2526
2527 /*!
2528  * Copy some tuples from another DataArrayDouble (\a a) into contiguous tuples
2529  * of \a this array. Textual data is not copied. Both arrays must have equal number of
2530  * components.
2531  * The tuples to assign to are defined by index of the first tuple, and
2532  * their number is defined by \a tuplesSelec->getNumberOfTuples().
2533  * The tuples to copy are defined by values of a DataArrayInt.
2534  * All components of selected tuples are copied.
2535  *  \param [in] tupleIdStart - index of the first tuple of \a this array to assign
2536  *              values to.
2537  *  \param [in] a - the array to copy values from.
2538  *  \param [in] tuplesSelec - the array specifying tuples of \a a to copy.
2539  *  \throw If \a this is not allocated.
2540  *  \throw If \a a is NULL.
2541  *  \throw If \a a is not allocated.
2542  *  \throw If \a tuplesSelec is NULL.
2543  *  \throw If \a tuplesSelec is not allocated.
2544  *  \throw If <em>this->getNumberOfComponents() != a->getNumberOfComponents()</em>.
2545  *  \throw If \a tuplesSelec->getNumberOfComponents() != 1.
2546  *  \throw If <em>tupleIdStart + tuplesSelec->getNumberOfTuples() > this->getNumberOfTuples().</em>
2547  *  \throw If any tuple index given by \a tuplesSelec is out of a valid range for 
2548  *         \a a array.
2549  */
2550 void DataArrayDouble::setContigPartOfSelectedValues(int tupleIdStart, const DataArray *aBase, const DataArrayInt *tuplesSelec) throw(INTERP_KERNEL::Exception)
2551 {
2552   if(!aBase || !tuplesSelec)
2553     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues : input DataArray is NULL !");
2554   const DataArrayDouble *a=dynamic_cast<const DataArrayDouble *>(aBase);
2555   if(!a)
2556     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues : input DataArray aBase is not a DataArrayDouble !");
2557   checkAllocated();
2558   a->checkAllocated();
2559   tuplesSelec->checkAllocated();
2560   int nbOfComp=getNumberOfComponents();
2561   if(nbOfComp!=a->getNumberOfComponents())
2562     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues : This and a do not have the same number of components !");
2563   if(tuplesSelec->getNumberOfComponents()!=1)
2564     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues : Expecting to have a tuple selector DataArrayInt instance with exactly 1 component !");
2565   int thisNt=getNumberOfTuples();
2566   int aNt=a->getNumberOfTuples();
2567   int nbOfTupleToWrite=tuplesSelec->getNumberOfTuples();
2568   double *valsToSet=getPointer()+tupleIdStart*nbOfComp;
2569   if(tupleIdStart+nbOfTupleToWrite>thisNt)
2570     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues : invalid number range of values to write !");
2571   const double *valsSrc=a->getConstPointer();
2572   for(const int *tuple=tuplesSelec->begin();tuple!=tuplesSelec->end();tuple++,valsToSet+=nbOfComp)
2573     {
2574       if(*tuple>=0 && *tuple<aNt)
2575         {
2576           std::copy(valsSrc+nbOfComp*(*tuple),valsSrc+nbOfComp*(*tuple+1),valsToSet);
2577         }
2578       else
2579         {
2580           std::ostringstream oss; oss << "DataArrayDouble::setContigPartOfSelectedValues : Tuple #" << std::distance(tuplesSelec->begin(),tuple);
2581           oss << " of 'tuplesSelec' request of tuple id #" << *tuple << " in 'a' ! It should be in [0," << aNt << ") !";
2582           throw INTERP_KERNEL::Exception(oss.str().c_str());
2583         }
2584     }
2585 }
2586
2587 /*!
2588  * Copy some tuples from another DataArrayDouble (\a a) into contiguous tuples
2589  * of \a this array. Textual data is not copied. Both arrays must have equal number of
2590  * components.
2591  * The tuples to copy are defined by three values similar to parameters of
2592  * the Python function \c range(\c start,\c stop,\c step).
2593  * The tuples to assign to are defined by index of the first tuple, and
2594  * their number is defined by number of tuples to copy.
2595  * All components of selected tuples are copied.
2596  *  \param [in] tupleIdStart - index of the first tuple of \a this array to assign
2597  *              values to.
2598  *  \param [in] a - the array to copy values from.
2599  *  \param [in] bg - index of the first tuple to copy of the array \a a.
2600  *  \param [in] end2 - index of the tuple of \a a before which the tuples to copy
2601  *              are located.
2602  *  \param [in] step - index increment to get index of the next tuple to copy.
2603  *  \throw If \a this is not allocated.
2604  *  \throw If \a a is NULL.
2605  *  \throw If \a a is not allocated.
2606  *  \throw If <em>this->getNumberOfComponents() != a->getNumberOfComponents()</em>.
2607  *  \throw If <em>tupleIdStart + len(range(bg,end2,step)) > this->getNumberOfTuples().</em>
2608  *  \throw If parameters specifying tuples to copy, do not give a
2609  *            non-empty range of increasing indices or indices are out of a valid range
2610  *            for the array \a a.
2611  */
2612 void DataArrayDouble::setContigPartOfSelectedValues2(int tupleIdStart, const DataArray *aBase, int bg, int end2, int step) throw(INTERP_KERNEL::Exception)
2613 {
2614   if(!aBase)
2615     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues2 : input DataArray is NULL !");
2616   const DataArrayDouble *a=dynamic_cast<const DataArrayDouble *>(aBase);
2617   if(!a)
2618     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues2 : input DataArray aBase is not a DataArrayDouble !");
2619   checkAllocated();
2620   a->checkAllocated();
2621   int nbOfComp=getNumberOfComponents();
2622   const char msg[]="DataArrayDouble::setContigPartOfSelectedValues2";
2623   int nbOfTupleToWrite=DataArray::GetNumberOfItemGivenBES(bg,end2,step,msg);
2624   if(nbOfComp!=a->getNumberOfComponents())
2625     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues2 : This and a do not have the same number of components !");
2626   int thisNt=getNumberOfTuples();
2627   int aNt=a->getNumberOfTuples();
2628   double *valsToSet=getPointer()+tupleIdStart*nbOfComp;
2629   if(tupleIdStart+nbOfTupleToWrite>thisNt)
2630     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues2 : invalid number range of values to write !");
2631   if(end2>aNt)
2632     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues2 : invalid range of values to read !");
2633   const double *valsSrc=a->getConstPointer()+bg*nbOfComp;
2634   for(int i=0;i<nbOfTupleToWrite;i++,valsToSet+=nbOfComp,valsSrc+=step*nbOfComp)
2635     {
2636       std::copy(valsSrc,valsSrc+nbOfComp,valsToSet);
2637     }
2638 }
2639
2640 /*!
2641  * Returns a value located at specified tuple and component.
2642  * This method is equivalent to DataArrayDouble::getIJ() except that validity of
2643  * parameters is checked. So this method is safe but expensive if used to go through
2644  * all values of \a this.
2645  *  \param [in] tupleId - index of tuple of interest.
2646  *  \param [in] compoId - index of component of interest.
2647  *  \return double - value located by \a tupleId and \a compoId.
2648  *  \throw If \a this is not allocated.
2649  *  \throw If condition <em>( 0 <= tupleId < this->getNumberOfTuples() )</em> is violated.
2650  *  \throw If condition <em>( 0 <= compoId < this->getNumberOfComponents() )</em> is violated.
2651  */
2652 double DataArrayDouble::getIJSafe(int tupleId, int compoId) const throw(INTERP_KERNEL::Exception)
2653 {
2654   checkAllocated();
2655   if(tupleId<0 || tupleId>=getNumberOfTuples())
2656     {
2657       std::ostringstream oss; oss << "DataArrayDouble::getIJSafe : request for tupleId " << tupleId << " should be in [0," << getNumberOfTuples() << ") !";
2658       throw INTERP_KERNEL::Exception(oss.str().c_str());
2659     }
2660   if(compoId<0 || compoId>=getNumberOfComponents())
2661     {
2662       std::ostringstream oss; oss << "DataArrayDouble::getIJSafe : request for compoId " << compoId << " should be in [0," << getNumberOfComponents() << ") !";
2663       throw INTERP_KERNEL::Exception(oss.str().c_str());
2664     }
2665   return _mem[tupleId*_info_on_compo.size()+compoId];
2666 }
2667
2668 /*!
2669  * Returns the last value of \a this. 
2670  *  \return double - the last value of \a this array.
2671  *  \throw If \a this is not allocated.
2672  *  \throw If \a this->getNumberOfComponents() != 1.
2673  *  \throw If \a this->getNumberOfTuples() < 1.
2674  */
2675 double DataArrayDouble::back() const throw(INTERP_KERNEL::Exception)
2676 {
2677   checkAllocated();
2678   if(getNumberOfComponents()!=1)
2679     throw INTERP_KERNEL::Exception("DataArrayDouble::back : number of components not equal to one !");
2680   int nbOfTuples=getNumberOfTuples();
2681   if(nbOfTuples<1)
2682     throw INTERP_KERNEL::Exception("DataArrayDouble::back : number of tuples must be >= 1 !");
2683   return *(getConstPointer()+nbOfTuples-1);
2684 }
2685
2686 void DataArrayDouble::SetArrayIn(DataArrayDouble *newArray, DataArrayDouble* &arrayToSet)
2687 {
2688   if(newArray!=arrayToSet)
2689     {
2690       if(arrayToSet)
2691         arrayToSet->decrRef();
2692       arrayToSet=newArray;
2693       if(arrayToSet)
2694         arrayToSet->incrRef();
2695     }
2696 }
2697
2698 /*!
2699  * Sets a C array to be used as raw data of \a this. The previously set info
2700  *  of components is retained and re-sized. 
2701  * For more info see \ref MEDCouplingArraySteps1.
2702  *  \param [in] array - the C array to be used as raw data of \a this.
2703  *  \param [in] ownership - if \a true, \a array will be deallocated at destruction of \a this.
2704  *  \param [in] type - specifies how to deallocate \a array. If \a type == ParaMEDMEM::CPP_DEALLOC,
2705  *                     \c delete [] \c array; will be called. If \a type == ParaMEDMEM::C_DEALLOC,
2706  *                     \c free(\c array ) will be called.
2707  *  \param [in] nbOfTuple - new number of tuples in \a this.
2708  *  \param [in] nbOfCompo - new number of components in \a this.
2709  */
2710 void DataArrayDouble::useArray(const double *array, bool ownership, DeallocType type, int nbOfTuple, int nbOfCompo) throw(INTERP_KERNEL::Exception)
2711 {
2712   _info_on_compo.resize(nbOfCompo);
2713   _mem.useArray(array,ownership,type,(std::size_t)nbOfTuple*nbOfCompo);
2714   declareAsNew();
2715 }
2716
2717 void DataArrayDouble::useExternalArrayWithRWAccess(const double *array, int nbOfTuple, int nbOfCompo) throw(INTERP_KERNEL::Exception)
2718 {
2719   _info_on_compo.resize(nbOfCompo);
2720   _mem.useExternalArrayWithRWAccess(array,(std::size_t)nbOfTuple*nbOfCompo);
2721   declareAsNew();
2722 }
2723
2724 /*!
2725  * Checks if 0.0 value is present in \a this array. If it is the case, an exception
2726  * is thrown.
2727  * \throw If zero is found in \a this array.
2728  */
2729 void DataArrayDouble::checkNoNullValues() const throw(INTERP_KERNEL::Exception)
2730 {
2731   const double *tmp=getConstPointer();
2732   std::size_t nbOfElems=getNbOfElems();
2733   const double *where=std::find(tmp,tmp+nbOfElems,0.);
2734   if(where!=tmp+nbOfElems)
2735     throw INTERP_KERNEL::Exception("A value 0.0 have been detected !");
2736 }
2737
2738 /*!
2739  * Computes minimal and maximal value in each component. An output array is filled
2740  * with \c 2 * \a this->getNumberOfComponents() values, so the caller is to allocate
2741  * enough memory before calling this method.
2742  *  \param [out] bounds - array of size at least 2 *\a this->getNumberOfComponents().
2743  *               It is filled as follows:<br>
2744  *               \a bounds[0] = \c min_of_component_0 <br>
2745  *               \a bounds[1] = \c max_of_component_0 <br>
2746  *               \a bounds[2] = \c min_of_component_1 <br>
2747  *               \a bounds[3] = \c max_of_component_1 <br>
2748  *               ...
2749  */
2750 void DataArrayDouble::getMinMaxPerComponent(double *bounds) const throw(INTERP_KERNEL::Exception)
2751 {
2752   checkAllocated();
2753   int dim=getNumberOfComponents();
2754   for (int idim=0; idim<dim; idim++)
2755     {
2756       bounds[idim*2]=std::numeric_limits<double>::max();
2757       bounds[idim*2+1]=-std::numeric_limits<double>::max();
2758     } 
2759   const double *ptr=getConstPointer();
2760   int nbOfTuples=getNumberOfTuples();
2761   for(int i=0;i<nbOfTuples;i++)
2762     {
2763       for(int idim=0;idim<dim;idim++)
2764         {
2765           if(bounds[idim*2]>ptr[i*dim+idim])
2766             {
2767               bounds[idim*2]=ptr[i*dim+idim];
2768             }
2769           if(bounds[idim*2+1]<ptr[i*dim+idim])
2770             {
2771               bounds[idim*2+1]=ptr[i*dim+idim];
2772             }
2773         }
2774     }
2775 }
2776
2777 /*!
2778  * This method retrieves a newly allocated DataArrayDouble instance having same number of tuples than \a this and twice number of components than \a this
2779  * to store both the min and max per component of each tuples. 
2780  * \param [in] epsilon the width of the bbox (identical in each direction) - 0.0 by default
2781  *
2782  * \return a newly created DataArrayDouble instance having \c this->getNumberOfTuples() tuples and 2 * \c this->getNumberOfComponent() components
2783  *
2784  * \throw If \a this is not allocated yet.
2785  */
2786 DataArrayDouble *DataArrayDouble::computeBBoxPerTuple(double epsilon)const throw(INTERP_KERNEL::Exception)
2787 {
2788   checkAllocated();
2789   const double *dataPtr=getConstPointer();
2790   int nbOfCompo=getNumberOfComponents();
2791   int nbTuples=getNumberOfTuples();
2792   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> bbox=DataArrayDouble::New();
2793   bbox->alloc(nbTuples,2*nbOfCompo);
2794   double *bboxPtr=bbox->getPointer();
2795   for(int i=0;i<nbTuples;i++)
2796     {
2797       for(int j=0;j<nbOfCompo;j++)
2798         {
2799           bboxPtr[2*nbOfCompo*i+2*j]=dataPtr[nbOfCompo*i+j]-epsilon;
2800           bboxPtr[2*nbOfCompo*i+2*j+1]=dataPtr[nbOfCompo*i+j]+epsilon;
2801         }
2802     }
2803   return bbox.retn();
2804 }
2805
2806 /*!
2807  * For each tuples **t** in \a other, this method retrieves tuples in \a this that are equal to **t**.
2808  * Two tuples are considered equal if the euclidian distance between the two tuples is lower than \a eps.
2809  * 
2810  * \param [in] other a DataArrayDouble having same number of components than \a this.
2811  * \param [in] eps absolute precision representing distance (using infinite norm) between 2 tuples behind which 2 tuples are considered equal.
2812  * \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.
2813  *             \a cI allows to extract information in \a c.
2814  * \param [out] cI is an indirection array that allows to extract the data contained in \a c.
2815  *
2816  * \throw In case of:
2817  *  - \a this is not allocated
2818  *  - \a other is not allocated or null
2819  *  - \a this and \a other do not have the same number of components
2820  *  - if number of components of \a this is not in [1,2,3]
2821  *
2822  * \sa MEDCouplingPointSet::getNodeIdsNearPoints, DataArrayDouble::getDifferentValues
2823  */
2824 void DataArrayDouble::computeTupleIdsNearTuples(const DataArrayDouble *other, double eps, DataArrayInt *& c, DataArrayInt *& cI) const throw(INTERP_KERNEL::Exception)
2825 {
2826   if(!other)
2827     throw INTERP_KERNEL::Exception("DataArrayDouble::computeTupleIdsNearTuples : input pointer other is null !");
2828   checkAllocated();
2829   other->checkAllocated();
2830   int nbOfCompo=getNumberOfComponents();
2831   int otherNbOfCompo=other->getNumberOfComponents();
2832   if(nbOfCompo!=otherNbOfCompo)
2833     throw INTERP_KERNEL::Exception("DataArrayDouble::computeTupleIdsNearTuples : number of components should be equal between this and other !");
2834   int nbOfTuplesOther=other->getNumberOfTuples();
2835   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cArr(DataArrayInt::New()),cIArr(DataArrayInt::New()); cArr->alloc(0,1); cIArr->pushBackSilent(0);
2836   switch(nbOfCompo)
2837     {
2838     case 3:
2839       {
2840         BBTreePts<3,int> myTree(begin(),0,0,getNumberOfTuples(),eps);
2841         FindTupleIdsNearTuplesAlg<3>(myTree,other->getConstPointer(),nbOfTuplesOther,eps,cArr,cIArr);
2842         break;
2843       }
2844     case 2:
2845       {
2846         BBTreePts<2,int> myTree(begin(),0,0,getNumberOfTuples(),eps);
2847         FindTupleIdsNearTuplesAlg<2>(myTree,other->getConstPointer(),nbOfTuplesOther,eps,cArr,cIArr);
2848         break;
2849       }
2850     case 1:
2851       {
2852         BBTreePts<1,int> myTree(begin(),0,0,getNumberOfTuples(),eps);
2853         FindTupleIdsNearTuplesAlg<1>(myTree,other->getConstPointer(),nbOfTuplesOther,eps,cArr,cIArr);
2854         break;
2855       }
2856     default:
2857       throw INTERP_KERNEL::Exception("Unexpected spacedim of coords for computeTupleIdsNearTuples. Must be 1, 2 or 3.");
2858     }
2859   c=cArr.retn(); cI=cIArr.retn();
2860 }
2861
2862 /*!
2863  * 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
2864  * around origin of 'radius' 1.
2865  * 
2866  * \param [in] eps absolute epsilon. under that value of delta between max and min no scale is performed.
2867  */
2868 void DataArrayDouble::recenterForMaxPrecision(double eps) throw(INTERP_KERNEL::Exception)
2869 {
2870   checkAllocated();
2871   int dim=getNumberOfComponents();
2872   std::vector<double> bounds(2*dim);
2873   getMinMaxPerComponent(&bounds[0]);
2874   for(int i=0;i<dim;i++)
2875     {
2876       double delta=bounds[2*i+1]-bounds[2*i];
2877       double offset=(bounds[2*i]+bounds[2*i+1])/2.;
2878       if(delta>eps)
2879         applyLin(1./delta,-offset/delta,i);
2880       else
2881         applyLin(1.,-offset,i);
2882     }
2883 }
2884
2885 /*!
2886  * Returns the maximal value and its location within \a this one-dimensional array.
2887  *  \param [out] tupleId - index of the tuple holding the maximal value.
2888  *  \return double - the maximal value among all values of \a this array.
2889  *  \throw If \a this->getNumberOfComponents() != 1
2890  *  \throw If \a this->getNumberOfTuples() < 1
2891  */
2892 double DataArrayDouble::getMaxValue(int& tupleId) const throw(INTERP_KERNEL::Exception)
2893 {
2894   checkAllocated();
2895   if(getNumberOfComponents()!=1)
2896     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 !");
2897   int nbOfTuples=getNumberOfTuples();
2898   if(nbOfTuples<=0)
2899     throw INTERP_KERNEL::Exception("DataArrayDouble::getMaxValue : array exists but number of tuples must be > 0 !");
2900   const double *vals=getConstPointer();
2901   const double *loc=std::max_element(vals,vals+nbOfTuples);
2902   tupleId=(int)std::distance(vals,loc);
2903   return *loc;
2904 }
2905
2906 /*!
2907  * Returns the maximal value within \a this array that is allowed to have more than
2908  *  one component.
2909  *  \return double - the maximal value among all values of \a this array.
2910  *  \throw If \a this is not allocated.
2911  */
2912 double DataArrayDouble::getMaxValueInArray() const throw(INTERP_KERNEL::Exception)
2913 {
2914   checkAllocated();
2915   const double *loc=std::max_element(begin(),end());
2916   return *loc;
2917 }
2918
2919 /*!
2920  * Returns the maximal value and all its locations within \a this one-dimensional array.
2921  *  \param [out] tupleIds - a new instance of DataArrayInt containg indices of
2922  *               tuples holding the maximal value. The caller is to delete it using
2923  *               decrRef() as it is no more needed.
2924  *  \return double - the maximal value among all values of \a this array.
2925  *  \throw If \a this->getNumberOfComponents() != 1
2926  *  \throw If \a this->getNumberOfTuples() < 1
2927  */
2928 double DataArrayDouble::getMaxValue2(DataArrayInt*& tupleIds) const throw(INTERP_KERNEL::Exception)
2929 {
2930   int tmp;
2931   tupleIds=0;
2932   double ret=getMaxValue(tmp);
2933   tupleIds=getIdsInRange(ret,ret);
2934   return ret;
2935 }
2936
2937 /*!
2938  * Returns the minimal value and its location within \a this one-dimensional array.
2939  *  \param [out] tupleId - index of the tuple holding the minimal value.
2940  *  \return double - the minimal value among all values of \a this array.
2941  *  \throw If \a this->getNumberOfComponents() != 1
2942  *  \throw If \a this->getNumberOfTuples() < 1
2943  */
2944 double DataArrayDouble::getMinValue(int& tupleId) const throw(INTERP_KERNEL::Exception)
2945 {
2946   checkAllocated();
2947   if(getNumberOfComponents()!=1)
2948     throw INTERP_KERNEL::Exception("DataArrayDouble::getMinValue : must be applied on DataArrayDouble with only one component, you can call 'rearrange' method before call 'getMinValueInArray' method !");
2949   int nbOfTuples=getNumberOfTuples();
2950   if(nbOfTuples<=0)
2951     throw INTERP_KERNEL::Exception("DataArrayDouble::getMinValue : array exists but number of tuples must be > 0 !");
2952   const double *vals=getConstPointer();
2953   const double *loc=std::min_element(vals,vals+nbOfTuples);
2954   tupleId=(int)std::distance(vals,loc);
2955   return *loc;
2956 }
2957
2958 /*!
2959  * Returns the minimal value within \a this array that is allowed to have more than
2960  *  one component.
2961  *  \return double - the minimal value among all values of \a this array.
2962  *  \throw If \a this is not allocated.
2963  */
2964 double DataArrayDouble::getMinValueInArray() const throw(INTERP_KERNEL::Exception)
2965 {
2966   checkAllocated();
2967   const double *loc=std::min_element(begin(),end());
2968   return *loc;
2969 }
2970
2971 /*!
2972  * Returns the minimal value and all its locations within \a this one-dimensional array.
2973  *  \param [out] tupleIds - a new instance of DataArrayInt containg indices of
2974  *               tuples holding the minimal value. The caller is to delete it using
2975  *               decrRef() as it is no more needed.
2976  *  \return double - the minimal value among all values of \a this array.
2977  *  \throw If \a this->getNumberOfComponents() != 1
2978  *  \throw If \a this->getNumberOfTuples() < 1
2979  */
2980 double DataArrayDouble::getMinValue2(DataArrayInt*& tupleIds) const throw(INTERP_KERNEL::Exception)
2981 {
2982   int tmp;
2983   tupleIds=0;
2984   double ret=getMinValue(tmp);
2985   tupleIds=getIdsInRange(ret,ret);
2986   return ret;
2987 }
2988
2989 /*!
2990  * This method returns the number of values in \a this that are equals ( within an absolute precision of \a eps ) to input parameter \a value.
2991  * This method only works for single component array.
2992  *
2993  * \return a value in [ 0, \c this->getNumberOfTuples() )
2994  *
2995  * \throw If \a this is not allocated
2996  *
2997  */
2998 int DataArrayDouble::count(double value, double eps) const throw(INTERP_KERNEL::Exception)
2999 {
3000   int ret=0;
3001   checkAllocated();
3002   if(getNumberOfComponents()!=1)
3003     throw INTERP_KERNEL::Exception("DataArrayDouble::count : must be applied on DataArrayDouble with only one component, you can call 'rearrange' method before !");
3004   const double *vals=begin();
3005   int nbOfTuples=getNumberOfTuples();
3006   for(int i=0;i<nbOfTuples;i++,vals++)
3007     if(fabs(*vals-value)<=eps)
3008       ret++;
3009   return ret;
3010 }
3011
3012 /*!
3013  * Returns the average value of \a this one-dimensional array.
3014  *  \return double - the average value over all values of \a this array.
3015  *  \throw If \a this->getNumberOfComponents() != 1
3016  *  \throw If \a this->getNumberOfTuples() < 1
3017  */
3018 double DataArrayDouble::getAverageValue() const throw(INTERP_KERNEL::Exception)
3019 {
3020   if(getNumberOfComponents()!=1)
3021     throw INTERP_KERNEL::Exception("DataArrayDouble::getAverageValue : must be applied on DataArrayDouble with only one component, you can call 'rearrange' method before !");
3022   int nbOfTuples=getNumberOfTuples();
3023   if(nbOfTuples<=0)
3024     throw INTERP_KERNEL::Exception("DataArrayDouble::getAverageValue : array exists but number of tuples must be > 0 !");
3025   const double *vals=getConstPointer();
3026   double ret=std::accumulate(vals,vals+nbOfTuples,0.);
3027   return ret/nbOfTuples;
3028 }
3029
3030 /*!
3031  * Returns the Euclidean norm of the vector defined by \a this array.
3032  *  \return double - the value of the Euclidean norm, i.e.
3033  *          the square root of the inner product of vector.
3034  *  \throw If \a this is not allocated.
3035  */
3036 double DataArrayDouble::norm2() const throw(INTERP_KERNEL::Exception)
3037 {
3038   checkAllocated();
3039   double ret=0.;
3040   std::size_t nbOfElems=getNbOfElems();
3041   const double *pt=getConstPointer();
3042   for(std::size_t i=0;i<nbOfElems;i++,pt++)
3043     ret+=(*pt)*(*pt);
3044   return sqrt(ret);
3045 }
3046
3047 /*!
3048  * Returns the maximum norm of the vector defined by \a this array.
3049  *  \return double - the value of the maximum norm, i.e.
3050  *          the maximal absolute value among values of \a this array.
3051  *  \throw If \a this is not allocated.
3052  */
3053 double DataArrayDouble::normMax() const throw(INTERP_KERNEL::Exception)
3054 {
3055   checkAllocated();
3056   double ret=-1.;
3057   std::size_t nbOfElems=getNbOfElems();
3058   const double *pt=getConstPointer();
3059   for(std::size_t i=0;i<nbOfElems;i++,pt++)
3060     {
3061       double val=std::abs(*pt);
3062       if(val>ret)
3063         ret=val;
3064     }
3065   return ret;
3066 }
3067
3068 /*!
3069  * Accumulates values of each component of \a this array.
3070  *  \param [out] res - an array of length \a this->getNumberOfComponents(), allocated 
3071  *         by the caller, that is filled by this method with sum value for each
3072  *         component.
3073  *  \throw If \a this is not allocated.
3074  */
3075 void DataArrayDouble::accumulate(double *res) const throw(INTERP_KERNEL::Exception)
3076 {
3077   checkAllocated();
3078   const double *ptr=getConstPointer();
3079   int nbTuple=getNumberOfTuples();
3080   int nbComps=getNumberOfComponents();
3081   std::fill(res,res+nbComps,0.);
3082   for(int i=0;i<nbTuple;i++)
3083     std::transform(ptr+i*nbComps,ptr+(i+1)*nbComps,res,res,std::plus<double>());
3084 }
3085
3086 /*!
3087  * This method returns the min distance from an external tuple defined by [ \a tupleBg , \a tupleEnd ) to \a this and
3088  * the first tuple in \a this that matches the returned distance. If there is no tuples in \a this an exception will be thrown.
3089  *
3090  *
3091  * \a this is expected to be allocated and expected to have a number of components equal to the distance from \a tupleBg to
3092  * \a tupleEnd. If not an exception will be thrown.
3093  *
3094  * \param [in] tupleBg start pointer (included) of input external tuple
3095  * \param [in] tupleEnd end pointer (not included) of input external tuple
3096  * \param [out] tupleId the tuple id in \a this that matches the min of distance between \a this and input external tuple
3097  * \return the min distance.
3098  * \sa MEDCouplingUMesh::distanceToPoint
3099  */
3100 double DataArrayDouble::distanceToTuple(const double *tupleBg, const double *tupleEnd, int& tupleId) const throw(INTERP_KERNEL::Exception)
3101 {
3102   checkAllocated();
3103   int nbTuple=getNumberOfTuples();
3104   int nbComps=getNumberOfComponents();
3105   if(nbComps!=(int)std::distance(tupleBg,tupleEnd))
3106     { std::ostringstream oss; oss << "DataArrayDouble::distanceToTuple : size of input tuple is " << std::distance(tupleBg,tupleEnd) << " should be equal to the number of components in this : " << nbComps << " !"; throw INTERP_KERNEL::Exception(oss.str().c_str()); }
3107   if(nbTuple==0)
3108     throw INTERP_KERNEL::Exception("DataArrayDouble::distanceToTuple : no tuple in this ! No distance to compute !");
3109   double ret0=std::numeric_limits<double>::max();
3110   tupleId=-1;
3111   const double *work=getConstPointer();
3112   for(int i=0;i<nbTuple;i++)
3113     {
3114       double val=0.;
3115       for(int j=0;j<nbComps;j++,work++) 
3116         val+=(*work-tupleBg[j])*((*work-tupleBg[j]));
3117       if(val>=ret0)
3118         continue;
3119       else
3120         { ret0=val; tupleId=i; }
3121     }
3122   return sqrt(ret0);
3123 }
3124
3125 /*!
3126  * Accumulate values of the given component of \a this array.
3127  *  \param [in] compId - the index of the component of interest.
3128  *  \return double - a sum value of \a compId-th component.
3129  *  \throw If \a this is not allocated.
3130  *  \throw If \a the condition ( 0 <= \a compId < \a this->getNumberOfComponents() ) is
3131  *         not respected.
3132  */
3133 double DataArrayDouble::accumulate(int compId) const throw(INTERP_KERNEL::Exception)
3134 {
3135   checkAllocated();
3136   const double *ptr=getConstPointer();
3137   int nbTuple=getNumberOfTuples();
3138   int nbComps=getNumberOfComponents();
3139   if(compId<0 || compId>=nbComps)
3140     throw INTERP_KERNEL::Exception("DataArrayDouble::accumulate : Invalid compId specified : No such nb of components !");
3141   double ret=0.;
3142   for(int i=0;i<nbTuple;i++)
3143     ret+=ptr[i*nbComps+compId];
3144   return ret;
3145 }
3146
3147 /*!
3148  * This method accumulate using addition tuples in \a this using input index array [ \a bgOfIndex, \a endOfIndex ).
3149  * The returned array will have same number of components than \a this and number of tuples equal to
3150  * \c std::distance(bgOfIndex,endOfIndex) \b minus \b one.
3151  *
3152  * The input index array is expected to be ascendingly sorted in which the all referenced ids should be in [0, \c this->getNumberOfTuples).
3153  * This method is quite useful for users that need to put a field on cells to field on nodes on the same mesh without a need of conservation.
3154  *
3155  * \param [in] bgOfIndex - begin (included) of the input index array.
3156  * \param [in] endOfIndex - end (excluded) of the input index array.
3157  * \return DataArrayDouble * - the new instance having the same number of components than \a this.
3158  * 
3159  * \throw If bgOfIndex or end is NULL.
3160  * \throw If input index array is not ascendingly sorted.
3161  * \throw If there is an id in [ \a bgOfIndex, \a endOfIndex ) not in [0, \c this->getNumberOfTuples).
3162  * \throw If std::distance(bgOfIndex,endOfIndex)==0.
3163  */
3164 DataArrayDouble *DataArrayDouble::accumulatePerChunck(const int *bgOfIndex, const int *endOfIndex) const throw(INTERP_KERNEL::Exception)
3165 {
3166   if(!bgOfIndex || !endOfIndex)
3167     throw INTERP_KERNEL::Exception("DataArrayDouble::accumulatePerChunck : input pointer NULL !");
3168   checkAllocated();
3169   int nbCompo=getNumberOfComponents();
3170   int nbOfTuples=getNumberOfTuples();
3171   int sz=(int)std::distance(bgOfIndex,endOfIndex);
3172   if(sz<1)
3173     throw INTERP_KERNEL::Exception("DataArrayDouble::accumulatePerChunck : invalid size of input index array !");
3174   sz--;
3175   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New(); ret->alloc(sz,nbCompo);
3176   const int *w=bgOfIndex;
3177   if(*w<0 || *w>=nbOfTuples)
3178     throw INTERP_KERNEL::Exception("DataArrayDouble::accumulatePerChunck : The first element of the input index not in [0,nbOfTuples) !");
3179   const double *srcPt=begin()+(*w)*nbCompo;
3180   double *tmp=ret->getPointer();
3181   for(int i=0;i<sz;i++,tmp+=nbCompo,w++)
3182     {
3183       std::fill(tmp,tmp+nbCompo,0.);
3184       if(w[1]>=w[0])
3185         {
3186           for(int j=w[0];j<w[1];j++,srcPt+=nbCompo)
3187             {
3188               if(j>=0 && j<nbOfTuples)
3189                 std::transform(srcPt,srcPt+nbCompo,tmp,tmp,std::plus<double>());
3190               else
3191                 {
3192                   std::ostringstream oss; oss << "DataArrayDouble::accumulatePerChunck : At rank #" << i << " the input index array points to id " << j << " should be in [0," << nbOfTuples << ") !";
3193                   throw INTERP_KERNEL::Exception(oss.str().c_str());
3194                 }
3195             }
3196         }
3197       else
3198         {
3199           std::ostringstream oss; oss << "DataArrayDouble::accumulatePerChunck : At rank #" << i << " the input index array is not in ascendingly sorted.";
3200           throw INTERP_KERNEL::Exception(oss.str().c_str());
3201         }
3202     }
3203   ret->copyStringInfoFrom(*this);
3204   return ret.retn();
3205 }
3206
3207 /*!
3208  * Converts each 2D point defined by the tuple of \a this array from the Polar to the
3209  * Cartesian coordinate system. The two components of the tuple of \a this array are 
3210  * considered to contain (1) radius and (2) angle of the point in the Polar CS.
3211  *  \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
3212  *          contains X and Y coordinates of the point in the Cartesian CS. The caller
3213  *          is to delete this array using decrRef() as it is no more needed. The array
3214  *          does not contain any textual info on components.
3215  *  \throw If \a this->getNumberOfComponents() != 2.
3216  */
3217 DataArrayDouble *DataArrayDouble::fromPolarToCart() const throw(INTERP_KERNEL::Exception)
3218 {
3219   checkAllocated();
3220   int nbOfComp=getNumberOfComponents();
3221   if(nbOfComp!=2)
3222     throw INTERP_KERNEL::Exception("DataArrayDouble::fromPolarToCart : must be an array with exactly 2 components !");
3223   int nbOfTuple=getNumberOfTuples();
3224   DataArrayDouble *ret=DataArrayDouble::New();
3225   ret->alloc(nbOfTuple,2);
3226   double *w=ret->getPointer();
3227   const double *wIn=getConstPointer();
3228   for(int i=0;i<nbOfTuple;i++,w+=2,wIn+=2)
3229     {
3230       w[0]=wIn[0]*cos(wIn[1]);
3231       w[1]=wIn[0]*sin(wIn[1]);
3232     }
3233   return ret;
3234 }
3235
3236 /*!
3237  * Converts each 3D point defined by the tuple of \a this array from the Cylindrical to
3238  * the Cartesian coordinate system. The three components of the tuple of \a this array 
3239  * are considered to contain (1) radius, (2) azimuth and (3) altitude of the point in
3240  * the Cylindrical CS.
3241  *  \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
3242  *          contains X, Y and Z coordinates of the point in the Cartesian CS. The info
3243  *          on the third component is copied from \a this array. The caller
3244  *          is to delete this array using decrRef() as it is no more needed. 
3245  *  \throw If \a this->getNumberOfComponents() != 3.
3246  */
3247 DataArrayDouble *DataArrayDouble::fromCylToCart() const throw(INTERP_KERNEL::Exception)
3248 {
3249   checkAllocated();
3250   int nbOfComp=getNumberOfComponents();
3251   if(nbOfComp!=3)
3252     throw INTERP_KERNEL::Exception("DataArrayDouble::fromCylToCart : must be an array with exactly 3 components !");
3253   int nbOfTuple=getNumberOfTuples();
3254   DataArrayDouble *ret=DataArrayDouble::New();
3255   ret->alloc(getNumberOfTuples(),3);
3256   double *w=ret->getPointer();
3257   const double *wIn=getConstPointer();
3258   for(int i=0;i<nbOfTuple;i++,w+=3,wIn+=3)
3259     {
3260       w[0]=wIn[0]*cos(wIn[1]);
3261       w[1]=wIn[0]*sin(wIn[1]);
3262       w[2]=wIn[2];
3263     }
3264   ret->setInfoOnComponent(2,getInfoOnComponent(2).c_str());
3265   return ret;
3266 }
3267
3268 /*!
3269  * Converts each 3D point defined by the tuple of \a this array from the Spherical to
3270  * the Cartesian coordinate system. The three components of the tuple of \a this array 
3271  * are considered to contain (1) radius, (2) polar angle and (3) azimuthal angle of the
3272  * point in the Cylindrical CS.
3273  *  \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
3274  *          contains X, Y and Z coordinates of the point in the Cartesian CS. The info
3275  *          on the third component is copied from \a this array. The caller
3276  *          is to delete this array using decrRef() as it is no more needed.
3277  *  \throw If \a this->getNumberOfComponents() != 3.
3278  */
3279 DataArrayDouble *DataArrayDouble::fromSpherToCart() const throw(INTERP_KERNEL::Exception)
3280 {
3281   checkAllocated();
3282   int nbOfComp=getNumberOfComponents();
3283   if(nbOfComp!=3)
3284     throw INTERP_KERNEL::Exception("DataArrayDouble::fromSpherToCart : must be an array with exactly 3 components !");
3285   int nbOfTuple=getNumberOfTuples();
3286   DataArrayDouble *ret=DataArrayDouble::New();
3287   ret->alloc(getNumberOfTuples(),3);
3288   double *w=ret->getPointer();
3289   const double *wIn=getConstPointer();
3290   for(int i=0;i<nbOfTuple;i++,w+=3,wIn+=3)
3291     {
3292       w[0]=wIn[0]*cos(wIn[2])*sin(wIn[1]);
3293       w[1]=wIn[0]*sin(wIn[2])*sin(wIn[1]);
3294       w[2]=wIn[0]*cos(wIn[1]);
3295     }
3296   return ret;
3297 }
3298
3299 /*!
3300  * Computes the doubly contracted product of every tensor defined by the tuple of \a this
3301  * array contating 6 components.
3302  *  \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
3303  *          is calculated from the tuple <em>(t)</em> of \a this array as follows:
3304  *          \f$ t[0]^2+t[1]^2+t[2]^2+2*t[3]^2+2*t[4]^2+2*t[5]^2\f$.
3305  *         The caller is to delete this result array using decrRef() as it is no more needed. 
3306  *  \throw If \a this->getNumberOfComponents() != 6.
3307  */
3308 DataArrayDouble *DataArrayDouble::doublyContractedProduct() const throw(INTERP_KERNEL::Exception)
3309 {
3310   checkAllocated();
3311   int nbOfComp=getNumberOfComponents();
3312   if(nbOfComp!=6)
3313     throw INTERP_KERNEL::Exception("DataArrayDouble::doublyContractedProduct : must be an array with exactly 6 components !");
3314   DataArrayDouble *ret=DataArrayDouble::New();
3315   int nbOfTuple=getNumberOfTuples();
3316   ret->alloc(nbOfTuple,1);
3317   const double *src=getConstPointer();
3318   double *dest=ret->getPointer();
3319   for(int i=0;i<nbOfTuple;i++,dest++,src+=6)
3320     *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];
3321   return ret;
3322 }
3323
3324 /*!
3325  * Computes the determinant of every square matrix defined by the tuple of \a this
3326  * array, which contains either 4, 6 or 9 components. The case of 6 components
3327  * corresponds to that of the upper triangular matrix.
3328  *  \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
3329  *          is the determinant of matrix of the corresponding tuple of \a this array.
3330  *          The caller is to delete this result array using decrRef() as it is no more
3331  *          needed. 
3332  *  \throw If \a this->getNumberOfComponents() is not in [4,6,9].
3333  */
3334 DataArrayDouble *DataArrayDouble::determinant() const throw(INTERP_KERNEL::Exception)
3335 {
3336   checkAllocated();
3337   DataArrayDouble *ret=DataArrayDouble::New();
3338   int nbOfTuple=getNumberOfTuples();
3339   ret->alloc(nbOfTuple,1);
3340   const double *src=getConstPointer();
3341   double *dest=ret->getPointer();
3342   switch(getNumberOfComponents())
3343     {
3344     case 6:
3345       for(int i=0;i<nbOfTuple;i++,dest++,src+=6)
3346         *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];
3347       return ret;
3348     case 4:
3349       for(int i=0;i<nbOfTuple;i++,dest++,src+=4)
3350         *dest=src[0]*src[3]-src[1]*src[2];
3351       return ret;
3352     case 9:
3353       for(int i=0;i<nbOfTuple;i++,dest++,src+=9)
3354         *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];
3355       return ret;
3356     default:
3357       ret->decrRef();
3358       throw INTERP_KERNEL::Exception("DataArrayDouble::determinant : Invalid number of components ! must be in 4,6,9 !");
3359     }
3360 }
3361
3362 /*!
3363  * Computes 3 eigenvalues of every upper triangular matrix defined by the tuple of
3364  * \a this array, which contains 6 components.
3365  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing 3
3366  *          components, whose each tuple contains the eigenvalues of the matrix of
3367  *          corresponding tuple of \a this array. 
3368  *          The caller is to delete this result array using decrRef() as it is no more
3369  *          needed. 
3370  *  \throw If \a this->getNumberOfComponents() != 6.
3371  */
3372 DataArrayDouble *DataArrayDouble::eigenValues() const throw(INTERP_KERNEL::Exception)
3373 {
3374   checkAllocated();
3375   int nbOfComp=getNumberOfComponents();
3376   if(nbOfComp!=6)
3377     throw INTERP_KERNEL::Exception("DataArrayDouble::eigenValues : must be an array with exactly 6 components !");
3378   DataArrayDouble *ret=DataArrayDouble::New();
3379   int nbOfTuple=getNumberOfTuples();
3380   ret->alloc(nbOfTuple,3);
3381   const double *src=getConstPointer();
3382   double *dest=ret->getPointer();
3383   for(int i=0;i<nbOfTuple;i++,dest+=3,src+=6)
3384     INTERP_KERNEL::computeEigenValues6(src,dest);
3385   return ret;
3386 }
3387
3388 /*!
3389  * Computes 3 eigenvectors of every upper triangular matrix defined by the tuple of
3390  * \a this array, which contains 6 components.
3391  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing 9
3392  *          components, whose each tuple contains 3 eigenvectors of the matrix of
3393  *          corresponding tuple of \a this array.
3394  *          The caller is to delete this result array using decrRef() as it is no more
3395  *          needed.
3396  *  \throw If \a this->getNumberOfComponents() != 6.
3397  */
3398 DataArrayDouble *DataArrayDouble::eigenVectors() const throw(INTERP_KERNEL::Exception)
3399 {
3400   checkAllocated();
3401   int nbOfComp=getNumberOfComponents();
3402   if(nbOfComp!=6)
3403     throw INTERP_KERNEL::Exception("DataArrayDouble::eigenVectors : must be an array with exactly 6 components !");
3404   DataArrayDouble *ret=DataArrayDouble::New();
3405   int nbOfTuple=getNumberOfTuples();
3406   ret->alloc(nbOfTuple,9);
3407   const double *src=getConstPointer();
3408   double *dest=ret->getPointer();
3409   for(int i=0;i<nbOfTuple;i++,src+=6)
3410     {
3411       double tmp[3];
3412       INTERP_KERNEL::computeEigenValues6(src,tmp);
3413       for(int j=0;j<3;j++,dest+=3)
3414         INTERP_KERNEL::computeEigenVectorForEigenValue6(src,tmp[j],1e-12,dest);
3415     }
3416   return ret;
3417 }
3418
3419 /*!
3420  * Computes the inverse matrix of every matrix defined by the tuple of \a this
3421  * array, which contains either 4, 6 or 9 components. The case of 6 components
3422  * corresponds to that of the upper triangular matrix.
3423  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
3424  *          same number of components as \a this one, whose each tuple is the inverse
3425  *          matrix of the matrix of corresponding tuple of \a this array. 
3426  *          The caller is to delete this result array using decrRef() as it is no more
3427  *          needed. 
3428  *  \throw If \a this->getNumberOfComponents() is not in [4,6,9].
3429  */
3430 DataArrayDouble *DataArrayDouble::inverse() const throw(INTERP_KERNEL::Exception)
3431 {
3432   checkAllocated();
3433   int nbOfComp=getNumberOfComponents();
3434   if(nbOfComp!=6 && nbOfComp!=9 && nbOfComp!=4)
3435     throw INTERP_KERNEL::Exception("DataArrayDouble::inversion : must be an array with 4,6 or 9 components !");
3436   DataArrayDouble *ret=DataArrayDouble::New();
3437   int nbOfTuple=getNumberOfTuples();
3438   ret->alloc(nbOfTuple,nbOfComp);
3439   const double *src=getConstPointer();
3440   double *dest=ret->getPointer();
3441 if(nbOfComp==6)
3442     for(int i=0;i<nbOfTuple;i++,dest+=6,src+=6)
3443       {
3444         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];
3445         dest[0]=(src[1]*src[2]-src[4]*src[4])/det;
3446         dest[1]=(src[0]*src[2]-src[5]*src[5])/det;
3447         dest[2]=(src[0]*src[1]-src[3]*src[3])/det;
3448         dest[3]=(src[5]*src[4]-src[3]*src[2])/det;
3449         dest[4]=(src[5]*src[3]-src[0]*src[4])/det;
3450         dest[5]=(src[3]*src[4]-src[1]*src[5])/det;
3451       }
3452   else if(nbOfComp==4)
3453     for(int i=0;i<nbOfTuple;i++,dest+=4,src+=4)
3454       {
3455         double det=src[0]*src[3]-src[1]*src[2];
3456         dest[0]=src[3]/det;
3457         dest[1]=-src[1]/det;
3458         dest[2]=-src[2]/det;
3459         dest[3]=src[0]/det;
3460       }
3461   else
3462     for(int i=0;i<nbOfTuple;i++,dest+=9,src+=9)
3463       {
3464         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];
3465         dest[0]=(src[4]*src[8]-src[7]*src[5])/det;
3466         dest[1]=(src[7]*src[2]-src[1]*src[8])/det;
3467         dest[2]=(src[1]*src[5]-src[4]*src[2])/det;
3468         dest[3]=(src[6]*src[5]-src[3]*src[8])/det;
3469         dest[4]=(src[0]*src[8]-src[6]*src[2])/det;
3470         dest[5]=(src[2]*src[3]-src[0]*src[5])/det;
3471         dest[6]=(src[3]*src[7]-src[6]*src[4])/det;
3472         dest[7]=(src[6]*src[1]-src[0]*src[7])/det;
3473         dest[8]=(src[0]*src[4]-src[1]*src[3])/det;
3474       }
3475   return ret;
3476 }
3477
3478 /*!
3479  * Computes the trace of every matrix defined by the tuple of \a this
3480  * array, which contains either 4, 6 or 9 components. The case of 6 components
3481  * corresponds to that of the upper triangular matrix.
3482  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing 
3483  *          1 component, whose each tuple is the trace of
3484  *          the matrix of corresponding tuple of \a this array. 
3485  *          The caller is to delete this result array using decrRef() as it is no more
3486  *          needed. 
3487  *  \throw If \a this->getNumberOfComponents() is not in [4,6,9].
3488  */
3489 DataArrayDouble *DataArrayDouble::trace() const throw(INTERP_KERNEL::Exception)
3490 {
3491   checkAllocated();
3492   int nbOfComp=getNumberOfComponents();
3493   if(nbOfComp!=6 && nbOfComp!=9 && nbOfComp!=4)
3494     throw INTERP_KERNEL::Exception("DataArrayDouble::trace : must be an array with 4,6 or 9 components !");
3495   DataArrayDouble *ret=DataArrayDouble::New();
3496   int nbOfTuple=getNumberOfTuples();
3497   ret->alloc(nbOfTuple,1);
3498   const double *src=getConstPointer();
3499   double *dest=ret->getPointer();
3500   if(nbOfComp==6)
3501     for(int i=0;i<nbOfTuple;i++,dest++,src+=6)
3502       *dest=src[0]+src[1]+src[2];
3503   else if(nbOfComp==4)
3504     for(int i=0;i<nbOfTuple;i++,dest++,src+=4)
3505       *dest=src[0]+src[3];
3506   else
3507     for(int i=0;i<nbOfTuple;i++,dest++,src+=9)
3508       *dest=src[0]+src[4]+src[8];
3509   return ret;
3510 }
3511
3512 /*!
3513  * Computes the stress deviator tensor of every stress tensor defined by the tuple of
3514  * \a this array, which contains 6 components.
3515  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
3516  *          same number of components and tuples as \a this array.
3517  *          The caller is to delete this result array using decrRef() as it is no more
3518  *          needed.
3519  *  \throw If \a this->getNumberOfComponents() != 6.
3520  */
3521 DataArrayDouble *DataArrayDouble::deviator() const throw(INTERP_KERNEL::Exception)
3522 {
3523   checkAllocated();
3524   int nbOfComp=getNumberOfComponents();
3525   if(nbOfComp!=6)
3526     throw INTERP_KERNEL::Exception("DataArrayDouble::deviator : must be an array with exactly 6 components !");
3527   DataArrayDouble *ret=DataArrayDouble::New();
3528   int nbOfTuple=getNumberOfTuples();
3529   ret->alloc(nbOfTuple,6);
3530   const double *src=getConstPointer();
3531   double *dest=ret->getPointer();
3532   for(int i=0;i<nbOfTuple;i++,dest+=6,src+=6)
3533     {
3534       double tr=(src[0]+src[1]+src[2])/3.;
3535       dest[0]=src[0]-tr;
3536       dest[1]=src[1]-tr;
3537       dest[2]=src[2]-tr;
3538       dest[3]=src[3];
3539       dest[4]=src[4];
3540       dest[5]=src[5];
3541     }
3542   return ret;
3543 }
3544
3545 /*!
3546  * Computes the magnitude of every vector defined by the tuple of
3547  * \a this array.
3548  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
3549  *          same number of tuples as \a this array and one component.
3550  *          The caller is to delete this result array using decrRef() as it is no more
3551  *          needed.
3552  *  \throw If \a this is not allocated.
3553  */
3554 DataArrayDouble *DataArrayDouble::magnitude() const throw(INTERP_KERNEL::Exception)
3555 {
3556   checkAllocated();
3557   int nbOfComp=getNumberOfComponents();
3558   DataArrayDouble *ret=DataArrayDouble::New();
3559   int nbOfTuple=getNumberOfTuples();
3560   ret->alloc(nbOfTuple,1);
3561   const double *src=getConstPointer();
3562   double *dest=ret->getPointer();
3563   for(int i=0;i<nbOfTuple;i++,dest++)
3564     {
3565       double sum=0.;
3566       for(int j=0;j<nbOfComp;j++,src++)
3567         sum+=(*src)*(*src);
3568       *dest=sqrt(sum);
3569     }
3570   return ret;
3571 }
3572
3573 /*!
3574  * Computes the maximal value within every tuple of \a this array.
3575  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
3576  *          same number of tuples as \a this array and one component.
3577  *          The caller is to delete this result array using decrRef() as it is no more
3578  *          needed.
3579  *  \throw If \a this is not allocated.
3580  *  \sa DataArrayDouble::maxPerTupleWithCompoId
3581  */
3582 DataArrayDouble *DataArrayDouble::maxPerTuple() const throw(INTERP_KERNEL::Exception)
3583 {
3584   checkAllocated();
3585   int nbOfComp=getNumberOfComponents();
3586   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
3587   int nbOfTuple=getNumberOfTuples();
3588   ret->alloc(nbOfTuple,1);
3589   const double *src=getConstPointer();
3590   double *dest=ret->getPointer();
3591   for(int i=0;i<nbOfTuple;i++,dest++,src+=nbOfComp)
3592     *dest=*std::max_element(src,src+nbOfComp);
3593   return ret.retn();
3594 }
3595
3596 /*!
3597  * Computes the maximal value within every tuple of \a this array and it returns the first component
3598  * id for each tuple that corresponds to the maximal value within the tuple.
3599  * 
3600  *  \param [out] compoIdOfMaxPerTuple - the new new instance of DataArrayInt containing the
3601  *          same number of tuples and only one component.
3602  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
3603  *          same number of tuples as \a this array and one component.
3604  *          The caller is to delete this result array using decrRef() as it is no more
3605  *          needed.
3606  *  \throw If \a this is not allocated.
3607  *  \sa DataArrayDouble::maxPerTuple
3608  */
3609 DataArrayDouble *DataArrayDouble::maxPerTupleWithCompoId(DataArrayInt* &compoIdOfMaxPerTuple) const throw(INTERP_KERNEL::Exception)
3610 {
3611   checkAllocated();
3612   int nbOfComp=getNumberOfComponents();
3613   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret0=DataArrayDouble::New();
3614   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret1=DataArrayInt::New();
3615   int nbOfTuple=getNumberOfTuples();
3616   ret0->alloc(nbOfTuple,1); ret1->alloc(nbOfTuple,1);
3617   const double *src=getConstPointer();
3618   double *dest=ret0->getPointer(); int *dest1=ret1->getPointer();
3619   for(int i=0;i<nbOfTuple;i++,dest++,dest1++,src+=nbOfComp)
3620     {
3621       const double *loc=std::max_element(src,src+nbOfComp);
3622       *dest=*loc;
3623       *dest1=(int)std::distance(src,loc);
3624     }
3625   compoIdOfMaxPerTuple=ret1.retn();
3626   return ret0.retn();
3627 }
3628
3629 /*!
3630  * This method returns a newly allocated DataArrayDouble instance having one component and \c this->getNumberOfTuples() * \c this->getNumberOfTuples() tuples.
3631  * \n This returned array contains the euclidian distance for each tuple in \a this. 
3632  * \n So the returned array can be seen as a dense symmetrical matrix whose diagonal elements are equal to 0.
3633  * \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)
3634  *
3635  * \warning use this method with care because it can leads to big amount of consumed memory !
3636  * 
3637  * \return A newly allocated (huge) ParaMEDMEM::DataArrayDouble instance that the caller should deal with.
3638  *
3639  * \throw If \a this is not allocated.
3640  *
3641  * \sa DataArrayDouble::buildEuclidianDistanceDenseMatrixWith
3642  */
3643 DataArrayDouble *DataArrayDouble::buildEuclidianDistanceDenseMatrix() const throw(INTERP_KERNEL::Exception)
3644 {
3645   checkAllocated();
3646   int nbOfComp=getNumberOfComponents();
3647   int nbOfTuples=getNumberOfTuples();
3648   const double *inData=getConstPointer();
3649   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
3650   ret->alloc(nbOfTuples*nbOfTuples,1);
3651   double *outData=ret->getPointer();
3652   for(int i=0;i<nbOfTuples;i++)
3653     {
3654       outData[i*nbOfTuples+i]=0.;
3655       for(int j=i+1;j<nbOfTuples;j++)
3656         {
3657           double dist=0.;
3658           for(int k=0;k<nbOfComp;k++)
3659             { double delta=inData[i*nbOfComp+k]-inData[j*nbOfComp+k]; dist+=delta*delta; }
3660           dist=sqrt(dist);
3661           outData[i*nbOfTuples+j]=dist;
3662           outData[j*nbOfTuples+i]=dist;
3663         }
3664     }
3665   return ret.retn();
3666 }
3667
3668 /*!
3669  * This method returns a newly allocated DataArrayDouble instance having one component and \c this->getNumberOfTuples() * \c other->getNumberOfTuples() tuples.
3670  * \n This returned array contains the euclidian distance for each tuple in \a other with each tuple in \a this. 
3671  * \n So the returned array can be seen as a dense rectangular matrix with \c other->getNumberOfTuples() rows and \c this->getNumberOfTuples() columns.
3672  * \n Output rectangular matrix is sorted along rows.
3673  * \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)
3674  *
3675  * \warning use this method with care because it can leads to big amount of consumed memory !
3676  * 
3677  * \param [in] other DataArrayDouble instance having same number of components than \a this.
3678  * \return A newly allocated (huge) ParaMEDMEM::DataArrayDouble instance that the caller should deal with.
3679  *
3680  * \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.
3681  *
3682  * \sa DataArrayDouble::buildEuclidianDistanceDenseMatrix
3683  */
3684 DataArrayDouble *DataArrayDouble::buildEuclidianDistanceDenseMatrixWith(const DataArrayDouble *other) const throw(INTERP_KERNEL::Exception)
3685 {
3686   if(!other)
3687     throw INTERP_KERNEL::Exception("DataArrayDouble::buildEuclidianDistanceDenseMatrixWith : input parameter is null !");
3688   checkAllocated();
3689   other->checkAllocated();
3690   int nbOfComp=getNumberOfComponents();
3691   int otherNbOfComp=other->getNumberOfComponents();
3692   if(nbOfComp!=otherNbOfComp)
3693     {
3694       std::ostringstream oss; oss << "DataArrayDouble::buildEuclidianDistanceDenseMatrixWith : this nb of compo=" << nbOfComp << " and other nb of compo=" << otherNbOfComp << ". It should match !";
3695       throw INTERP_KERNEL::Exception(oss.str().c_str());
3696     }
3697   int nbOfTuples=getNumberOfTuples();
3698   int otherNbOfTuples=other->getNumberOfTuples();
3699   const double *inData=getConstPointer();
3700   const double *inDataOther=other->getConstPointer();
3701   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
3702   ret->alloc(otherNbOfTuples*nbOfTuples,1);
3703   double *outData=ret->getPointer();
3704   for(int i=0;i<otherNbOfTuples;i++,inDataOther+=nbOfComp)
3705     {
3706       for(int j=0;j<nbOfTuples;j++)
3707         {
3708           double dist=0.;
3709           for(int k=0;k<nbOfComp;k++)
3710             { double delta=inDataOther[k]-inData[j*nbOfComp+k]; dist+=delta*delta; }
3711           dist=sqrt(dist);
3712           outData[i*nbOfTuples+j]=dist;
3713         }
3714     }
3715   return ret.retn();
3716 }
3717
3718 /*!
3719  * Sorts value within every tuple of \a this array.
3720  *  \param [in] asc - if \a true, the values are sorted in ascending order, else,
3721  *              in descending order.
3722  *  \throw If \a this is not allocated.
3723  */
3724 void DataArrayDouble::sortPerTuple(bool asc) throw(INTERP_KERNEL::Exception)
3725 {
3726   checkAllocated();
3727   double *pt=getPointer();
3728   int nbOfTuple=getNumberOfTuples();
3729   int nbOfComp=getNumberOfComponents();
3730   if(asc)
3731     for(int i=0;i<nbOfTuple;i++,pt+=nbOfComp)
3732       std::sort(pt,pt+nbOfComp);
3733   else
3734     for(int i=0;i<nbOfTuple;i++,pt+=nbOfComp)
3735       std::sort(pt,pt+nbOfComp,std::greater<double>());
3736   declareAsNew();
3737 }
3738
3739 /*!
3740  * Converts every value of \a this array to its absolute value.
3741  *  \throw If \a this is not allocated.
3742  */
3743 void DataArrayDouble::abs() throw(INTERP_KERNEL::Exception)
3744 {
3745   checkAllocated();
3746   double *ptr=getPointer();
3747   std::size_t nbOfElems=getNbOfElems();
3748   std::transform(ptr,ptr+nbOfElems,ptr,std::ptr_fun<double,double>(fabs));
3749   declareAsNew();
3750 }
3751
3752 /*!
3753  * Apply a liner function to a given component of \a this array, so that
3754  * an array element <em>(x)</em> becomes \f$ a * x + b \f$.
3755  *  \param [in] a - the first coefficient of the function.
3756  *  \param [in] b - the second coefficient of the function.
3757  *  \param [in] compoId - the index of component to modify.
3758  *  \throw If \a this is not allocated.
3759  */
3760 void DataArrayDouble::applyLin(double a, double b, int compoId) throw(INTERP_KERNEL::Exception)
3761 {
3762   checkAllocated();
3763   double *ptr=getPointer()+compoId;
3764   int nbOfComp=getNumberOfComponents();
3765   int nbOfTuple=getNumberOfTuples();
3766   for(int i=0;i<nbOfTuple;i++,ptr+=nbOfComp)
3767     *ptr=a*(*ptr)+b;
3768   declareAsNew();
3769 }
3770
3771 /*!
3772  * Apply a liner function to all elements of \a this array, so that
3773  * an element _x_ becomes \f$ a * x + b \f$.
3774  *  \param [in] a - the first coefficient of the function.
3775  *  \param [in] b - the second coefficient of the function.
3776  *  \throw If \a this is not allocated.
3777  */
3778 void DataArrayDouble::applyLin(double a, double b) throw(INTERP_KERNEL::Exception)
3779 {
3780   checkAllocated();
3781   double *ptr=getPointer();
3782   std::size_t nbOfElems=getNbOfElems();
3783   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
3784     *ptr=a*(*ptr)+b;
3785   declareAsNew();
3786 }
3787
3788 /*!
3789  * Modify all elements of \a this array, so that
3790  * an element _x_ becomes \f$ numerator / x \f$.
3791  *  \warning If an exception is thrown because of presence of 0.0 element in \a this 
3792  *           array, all elements processed before detection of the zero element remain
3793  *           modified.
3794  *  \param [in] numerator - the numerator used to modify array elements.
3795  *  \throw If \a this is not allocated.
3796  *  \throw If there is an element equal to 0.0 in \a this array.
3797  */
3798 void DataArrayDouble::applyInv(double numerator) throw(INTERP_KERNEL::Exception)
3799 {
3800   checkAllocated();
3801   double *ptr=getPointer();
3802   std::size_t nbOfElems=getNbOfElems();
3803   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
3804     {
3805       if(std::abs(*ptr)>std::numeric_limits<double>::min())
3806         {
3807           *ptr=numerator/(*ptr);
3808         }
3809       else
3810         {
3811           std::ostringstream oss; oss << "DataArrayDouble::applyInv : presence of null value in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
3812           oss << " !";
3813           throw INTERP_KERNEL::Exception(oss.str().c_str());
3814         }
3815     }
3816   declareAsNew();
3817 }
3818
3819 /*!
3820  * Returns a full copy of \a this array except that sign of all elements is reversed.
3821  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
3822  *          same number of tuples and component as \a this array.
3823  *          The caller is to delete this result array using decrRef() as it is no more
3824  *          needed.
3825  *  \throw If \a this is not allocated.
3826  */
3827 DataArrayDouble *DataArrayDouble::negate() const throw(INTERP_KERNEL::Exception)
3828 {
3829   checkAllocated();
3830   DataArrayDouble *newArr=DataArrayDouble::New();
3831   int nbOfTuples=getNumberOfTuples();
3832   int nbOfComp=getNumberOfComponents();
3833   newArr->alloc(nbOfTuples,nbOfComp);
3834   const double *cptr=getConstPointer();
3835   std::transform(cptr,cptr+nbOfTuples*nbOfComp,newArr->getPointer(),std::negate<double>());
3836   newArr->copyStringInfoFrom(*this);
3837   return newArr;
3838 }
3839
3840 /*!
3841  * Modify all elements of \a this array, so that
3842  * an element _x_ becomes <em> val ^ x </em>. Contrary to DataArrayInt::applyPow
3843  * all values in \a this have to be >= 0 if val is \b not integer.
3844  *  \param [in] val - the value used to apply pow on all array elements.
3845  *  \throw If \a this is not allocated.
3846  *  \warning If an exception is thrown because of presence of 0 element in \a this 
3847  *           array and \a val is \b not integer, all elements processed before detection of the zero element remain
3848  *           modified.
3849  */
3850 void DataArrayDouble::applyPow(double val) throw(INTERP_KERNEL::Exception)
3851 {
3852   checkAllocated();
3853   double *ptr=getPointer();
3854   std::size_t nbOfElems=getNbOfElems();
3855   int val2=(int)val;
3856   bool isInt=((double)val2)==val;
3857   if(!isInt)
3858     {
3859       for(std::size_t i=0;i<nbOfElems;i++,ptr++)
3860         {
3861           if(*ptr>=0)
3862             *ptr=pow(*ptr,val);
3863           else
3864             {
3865               std::ostringstream oss; oss << "DataArrayDouble::applyPow (double) : At elem # " << i << " value is " << *ptr << " ! must be >=0. !";
3866               throw INTERP_KERNEL::Exception(oss.str().c_str());
3867             }
3868         }
3869     }
3870   else
3871     {
3872       for(std::size_t i=0;i<nbOfElems;i++,ptr++)
3873         *ptr=pow(*ptr,val2);
3874     }
3875   declareAsNew();
3876 }
3877
3878 /*!
3879  * Modify all elements of \a this array, so that
3880  * an element _x_ becomes \f$ val ^ x \f$.
3881  *  \param [in] val - the value used to apply pow on all array elements.
3882  *  \throw If \a this is not allocated.
3883  *  \throw If \a val < 0.
3884  *  \warning If an exception is thrown because of presence of 0 element in \a this 
3885  *           array, all elements processed before detection of the zero element remain
3886  *           modified.
3887  */
3888 void DataArrayDouble::applyRPow(double val) throw(INTERP_KERNEL::Exception)
3889 {
3890   checkAllocated();
3891   if(val<0.)
3892     throw INTERP_KERNEL::Exception("DataArrayDouble::applyRPow : the input value has to be >= 0 !");
3893   double *ptr=getPointer();
3894   std::size_t nbOfElems=getNbOfElems();
3895   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
3896     *ptr=pow(val,*ptr);
3897   declareAsNew();
3898 }
3899
3900 /*!
3901  * Returns a new DataArrayDouble created from \a this one by applying \a
3902  * FunctionToEvaluate to every tuple of \a this array. Textual data is not copied.
3903  * For more info see \ref MEDCouplingArrayApplyFunc
3904  *  \param [in] nbOfComp - number of components in the result array.
3905  *  \param [in] func - the \a FunctionToEvaluate declared as 
3906  *              \c bool (*\a func)(\c const \c double *\a pos, \c double *\a res), 
3907  *              where \a pos points to the first component of a tuple of \a this array
3908  *              and \a res points to the first component of a tuple of the result array.
3909  *              Note that length (number of components) of \a pos can differ from
3910  *              that of \a res.
3911  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
3912  *          same number of tuples as \a this array.
3913  *          The caller is to delete this result array using decrRef() as it is no more
3914  *          needed.
3915  *  \throw If \a this is not allocated.
3916  *  \throw If \a func returns \a false.
3917  */
3918 DataArrayDouble *DataArrayDouble::applyFunc(int nbOfComp, FunctionToEvaluate func) const throw(INTERP_KERNEL::Exception)
3919 {
3920   checkAllocated();
3921   DataArrayDouble *newArr=DataArrayDouble::New();
3922   int nbOfTuples=getNumberOfTuples();
3923   int oldNbOfComp=getNumberOfComponents();
3924   newArr->alloc(nbOfTuples,nbOfComp);
3925   const double *ptr=getConstPointer();
3926   double *ptrToFill=newArr->getPointer();
3927   for(int i=0;i<nbOfTuples;i++)
3928     {
3929       if(!func(ptr+i*oldNbOfComp,ptrToFill+i*nbOfComp))
3930         {
3931           std::ostringstream oss; oss << "For tuple # " << i << " with value (";
3932           std::copy(ptr+oldNbOfComp*i,ptr+oldNbOfComp*(i+1),std::ostream_iterator<double>(oss,", "));
3933           oss << ") : Evaluation of function failed !";
3934           newArr->decrRef();
3935           throw INTERP_KERNEL::Exception(oss.str().c_str());
3936         }
3937     }
3938   return newArr;
3939 }
3940
3941 /*!
3942  * Returns a new DataArrayDouble created from \a this one by applying a function to every
3943  * tuple of \a this array. Textual data is not copied.
3944  * For more info see \ref MEDCouplingArrayApplyFunc1.
3945  *  \param [in] nbOfComp - number of components in the result array.
3946  *  \param [in] func - the expression defining how to transform a tuple of \a this array.
3947  *              Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
3948  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
3949  *          same number of tuples as \a this array and \a nbOfComp components.
3950  *          The caller is to delete this result array using decrRef() as it is no more
3951  *          needed.
3952  *  \throw If \a this is not allocated.
3953  *  \throw If computing \a func fails.
3954  */
3955 DataArrayDouble *DataArrayDouble::applyFunc(int nbOfComp, const char *func) const throw(INTERP_KERNEL::Exception)
3956 {
3957   checkAllocated();
3958   INTERP_KERNEL::ExprParser expr(func);
3959   expr.parse();
3960   std::set<std::string> vars;
3961   expr.getTrueSetOfVars(vars);
3962   int oldNbOfComp=getNumberOfComponents();
3963   if((int)vars.size()>oldNbOfComp)
3964     {
3965       std::ostringstream oss; oss << "The field has " << oldNbOfComp << " components and there are ";
3966       oss << vars.size() << " variables : ";
3967       std::copy(vars.begin(),vars.end(),std::ostream_iterator<std::string>(oss," "));
3968       throw INTERP_KERNEL::Exception(oss.str().c_str());
3969     }
3970   std::vector<std::string> varsV(vars.begin(),vars.end());
3971   expr.prepareExprEvaluation(varsV,oldNbOfComp,nbOfComp);
3972   //
3973   DataArrayDouble *newArr=DataArrayDouble::New();
3974   int nbOfTuples=getNumberOfTuples();
3975   newArr->alloc(nbOfTuples,nbOfComp);
3976   const double *ptr=getConstPointer();
3977   double *ptrToFill=newArr->getPointer();
3978   for(int i=0;i<nbOfTuples;i++)
3979     {
3980       try
3981         {
3982           expr.evaluateExpr(nbOfComp,ptr+i*oldNbOfComp,ptrToFill+i*nbOfComp);
3983         }
3984       catch(INTERP_KERNEL::Exception& e)
3985         {
3986           std::ostringstream oss; oss << "For tuple # " << i << " with value (";
3987           std::copy(ptr+oldNbOfComp*i,ptr+oldNbOfComp*(i+1),std::ostream_iterator<double>(oss,", "));
3988           oss << ") : Evaluation of function failed !" << e.what();
3989           newArr->decrRef();
3990           throw INTERP_KERNEL::Exception(oss.str().c_str());
3991         }
3992     }
3993   return newArr;
3994 }
3995
3996 /*!
3997  * Returns a new DataArrayDouble created from \a this one by applying a function to every
3998  * tuple of \a this array. Textual data is not copied.
3999  * For more info see \ref MEDCouplingArrayApplyFunc0.
4000  *  \param [in] func - the expression defining how to transform a tuple of \a this array.
4001  *              Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
4002  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
4003  *          same number of tuples and components as \a this array.
4004  *          The caller is to delete this result array using decrRef() as it is no more
4005  *          needed.
4006  *  \throw If \a this is not allocated.
4007  *  \throw If computing \a func fails.
4008  */
4009 DataArrayDouble *DataArrayDouble::applyFunc(const char *func) const throw(INTERP_KERNEL::Exception)
4010 {
4011   checkAllocated();
4012   INTERP_KERNEL::ExprParser expr(func);
4013   expr.parse();
4014   expr.prepareExprEvaluationVec();
4015   //
4016   DataArrayDouble *newArr=DataArrayDouble::New();
4017   int nbOfTuples=getNumberOfTuples();
4018   int nbOfComp=getNumberOfComponents();
4019   newArr->alloc(nbOfTuples,nbOfComp);
4020   const double *ptr=getConstPointer();
4021   double *ptrToFill=newArr->getPointer();
4022   for(int i=0;i<nbOfTuples;i++)
4023     {
4024       try
4025         {
4026           expr.evaluateExpr(nbOfComp,ptr+i*nbOfComp,ptrToFill+i*nbOfComp);
4027         }
4028       catch(INTERP_KERNEL::Exception& e)
4029         {
4030           std::ostringstream oss; oss << "For tuple # " << i << " with value (";
4031           std::copy(ptr+nbOfComp*i,ptr+nbOfComp*(i+1),std::ostream_iterator<double>(oss,", "));
4032           oss << ") : Evaluation of function failed ! " << e.what();
4033           newArr->decrRef();
4034           throw INTERP_KERNEL::Exception(oss.str().c_str());
4035         }
4036     }
4037   return newArr;
4038 }
4039
4040 /*!
4041  * Returns a new DataArrayDouble created from \a this one by applying a function to every
4042  * tuple of \a this array. Textual data is not copied.
4043  * For more info see \ref MEDCouplingArrayApplyFunc2.
4044  *  \param [in] nbOfComp - number of components in the result array.
4045  *  \param [in] func - the expression defining how to transform a tuple of \a this array.
4046  *              Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
4047  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
4048  *          same number of tuples as \a this array.
4049  *          The caller is to delete this result array using decrRef() as it is no more
4050  *          needed.
4051  *  \throw If \a this is not allocated.
4052  *  \throw If \a func contains vars that are not in \a this->getInfoOnComponent().
4053  *  \throw If computing \a func fails.
4054  */
4055 DataArrayDouble *DataArrayDouble::applyFunc2(int nbOfComp, const char *func) const throw(INTERP_KERNEL::Exception)
4056 {
4057   checkAllocated();
4058   INTERP_KERNEL::ExprParser expr(func);
4059   expr.parse();
4060   std::set<std::string> vars;
4061   expr.getTrueSetOfVars(vars);
4062   int oldNbOfComp=getNumberOfComponents();
4063   if((int)vars.size()>oldNbOfComp)
4064     {
4065       std::ostringstream oss; oss << "The field has " << oldNbOfComp << " components and there are ";
4066       oss << vars.size() << " variables : ";
4067       std::copy(vars.begin(),vars.end(),std::ostream_iterator<std::string>(oss," "));
4068       throw INTERP_KERNEL::Exception(oss.str().c_str());
4069     }
4070   expr.prepareExprEvaluation(getVarsOnComponent(),oldNbOfComp,nbOfComp);
4071   //
4072   DataArrayDouble *newArr=DataArrayDouble::New();
4073   int nbOfTuples=getNumberOfTuples();
4074   newArr->alloc(nbOfTuples,nbOfComp);
4075   const double *ptr=getConstPointer();
4076   double *ptrToFill=newArr->getPointer();
4077   for(int i=0;i<nbOfTuples;i++)
4078     {
4079       try
4080         {
4081           expr.evaluateExpr(nbOfComp,ptr+i*oldNbOfComp,ptrToFill+i*nbOfComp);
4082         }
4083       catch(INTERP_KERNEL::Exception& e)
4084         {
4085           std::ostringstream oss; oss << "For tuple # " << i << " with value (";
4086           std::copy(ptr+oldNbOfComp*i,ptr+oldNbOfComp*(i+1),std::ostream_iterator<double>(oss,", "));
4087           oss << ") : Evaluation of function failed !" << e.what();
4088           newArr->decrRef();
4089           throw INTERP_KERNEL::Exception(oss.str().c_str());
4090         }
4091     }
4092   return newArr;
4093 }
4094
4095 /*!
4096  * Returns a new DataArrayDouble created from \a this one by applying a function to every
4097  * tuple of \a this array. Textual data is not copied.
4098  * For more info see \ref MEDCouplingArrayApplyFunc3.
4099  *  \param [in] nbOfComp - number of components in the result array.
4100  *  \param [in] varsOrder - sequence of vars defining their order.
4101  *  \param [in] func - the expression defining how to transform a tuple of \a this array.
4102  *              Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
4103  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
4104  *          same number of tuples as \a this array.
4105  *          The caller is to delete this result array using decrRef() as it is no more
4106  *          needed.
4107  *  \throw If \a this is not allocated.
4108  *  \throw If \a func contains vars not in \a varsOrder.
4109  *  \throw If computing \a func fails.
4110  */
4111 DataArrayDouble *DataArrayDouble::applyFunc3(int nbOfComp, const std::vector<std::string>& varsOrder, const char *func) const throw(INTERP_KERNEL::Exception)
4112 {
4113   checkAllocated();
4114   INTERP_KERNEL::ExprParser expr(func);
4115   expr.parse();
4116   std::set<std::string> vars;
4117   expr.getTrueSetOfVars(vars);
4118   int oldNbOfComp=getNumberOfComponents();
4119   if((int)vars.size()>oldNbOfComp)
4120     {
4121       std::ostringstream oss; oss << "The field has " << oldNbOfComp << " components and there are ";
4122       oss << vars.size() << " variables : ";
4123       std::copy(vars.begin(),vars.end(),std::ostream_iterator<std::string>(oss," "));
4124       throw INTERP_KERNEL::Exception(oss.str().c_str());
4125     }
4126   expr.prepareExprEvaluation(varsOrder,oldNbOfComp,nbOfComp);
4127   //
4128   DataArrayDouble *newArr=DataArrayDouble::New();
4129   int nbOfTuples=getNumberOfTuples();
4130   newArr->alloc(nbOfTuples,nbOfComp);
4131   const double *ptr=getConstPointer();
4132   double *ptrToFill=newArr->getPointer();
4133   for(int i=0;i<nbOfTuples;i++)
4134     {
4135       try
4136         {
4137           expr.evaluateExpr(nbOfComp,ptr+i*oldNbOfComp,ptrToFill+i*nbOfComp);
4138         }
4139       catch(INTERP_KERNEL::Exception& e)
4140         {
4141           std::ostringstream oss; oss << "For tuple # " << i << " with value (";
4142           std::copy(ptr+oldNbOfComp*i,ptr+oldNbOfComp*(i+1),std::ostream_iterator<double>(oss,", "));
4143           oss << ") : Evaluation of function failed !" << e.what();
4144           newArr->decrRef();
4145           throw INTERP_KERNEL::Exception(oss.str().c_str());
4146         }
4147     }
4148   return newArr;
4149 }
4150
4151 void DataArrayDouble::applyFuncFast32(const char *func) throw(INTERP_KERNEL::Exception)
4152 {
4153   checkAllocated();
4154   INTERP_KERNEL::ExprParser expr(func);
4155   expr.parse();
4156   char *funcStr=expr.compileX86();
4157   MYFUNCPTR funcPtr;
4158   *((void **)&funcPtr)=funcStr;//he he...
4159   //
4160   double *ptr=getPointer();
4161   int nbOfComp=getNumberOfComponents();
4162   int nbOfTuples=getNumberOfTuples();
4163   int nbOfElems=nbOfTuples*nbOfComp;
4164   for(int i=0;i<nbOfElems;i++,ptr++)
4165     *ptr=funcPtr(*ptr);
4166   declareAsNew();
4167 }
4168
4169 void DataArrayDouble::applyFuncFast64(const char *func) throw(INTERP_KERNEL::Exception)
4170 {
4171   checkAllocated();
4172   INTERP_KERNEL::ExprParser expr(func);
4173   expr.parse();
4174   char *funcStr=expr.compileX86_64();
4175   MYFUNCPTR funcPtr;
4176   *((void **)&funcPtr)=funcStr;//he he...
4177   //
4178   double *ptr=getPointer();
4179   int nbOfComp=getNumberOfComponents();
4180   int nbOfTuples=getNumberOfTuples();
4181   int nbOfElems=nbOfTuples*nbOfComp;
4182   for(int i=0;i<nbOfElems;i++,ptr++)
4183     *ptr=funcPtr(*ptr);
4184   declareAsNew();
4185 }
4186
4187 DataArrayDoubleIterator *DataArrayDouble::iterator() throw(INTERP_KERNEL::Exception)
4188 {
4189   return new DataArrayDoubleIterator(this);
4190 }
4191
4192 /*!
4193  * Returns a new DataArrayInt contating indices of tuples of \a this one-dimensional
4194  * array whose values are within a given range. Textual data is not copied.
4195  *  \param [in] vmin - a lowest acceptable value (included).
4196  *  \param [in] vmax - a greatest acceptable value (included).
4197  *  \return DataArrayInt * - the new instance of DataArrayInt.
4198  *          The caller is to delete this result array using decrRef() as it is no more
4199  *          needed.
4200  *  \throw If \a this->getNumberOfComponents() != 1.
4201  *
4202  *  \ref cpp_mcdataarraydouble_getidsinrange "Here is a C++ example".<br>
4203  *  \ref py_mcdataarraydouble_getidsinrange "Here is a Python example".
4204  */
4205 DataArrayInt *DataArrayDouble::getIdsInRange(double vmin, double vmax) const throw(INTERP_KERNEL::Exception)
4206 {
4207   checkAllocated();
4208   if(getNumberOfComponents()!=1)
4209     throw INTERP_KERNEL::Exception("DataArrayDouble::getIdsInRange : this must have exactly one component !");
4210   const double *cptr=getConstPointer();
4211   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(0,1);
4212   int nbOfTuples=getNumberOfTuples();
4213   for(int i=0;i<nbOfTuples;i++,cptr++)
4214     if(*cptr>=vmin && *cptr<=vmax)
4215       ret->pushBackSilent(i);
4216   return ret.retn();
4217 }
4218
4219 /*!
4220  * Returns a new DataArrayDouble by concatenating two given arrays, so that (1) the number
4221  * of tuples in the result array is a sum of the number of tuples of given arrays and (2)
4222  * the number of component in the result array is same as that of each of given arrays.
4223  * Info on components is copied from the first of the given arrays. Number of components
4224  * in the given arrays must be  the same.
4225  *  \param [in] a1 - an array to include in the result array.
4226  *  \param [in] a2 - another array to include in the result array.
4227  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4228  *          The caller is to delete this result array using decrRef() as it is no more
4229  *          needed.
4230  *  \throw If both \a a1 and \a a2 are NULL.
4231  *  \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents().
4232  */
4233 DataArrayDouble *DataArrayDouble::Aggregate(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception)
4234 {
4235   std::vector<const DataArrayDouble *> tmp(2);
4236   tmp[0]=a1; tmp[1]=a2;
4237   return Aggregate(tmp);
4238 }
4239
4240 /*!
4241  * Returns a new DataArrayDouble by concatenating all given arrays, so that (1) the number
4242  * of tuples in the result array is a sum of the number of tuples of given arrays and (2)
4243  * the number of component in the result array is same as that of each of given arrays.
4244  * Info on components is copied from the first of the given arrays. Number of components
4245  * in the given arrays must be  the same.
4246  *  \param [in] arr - a sequence of arrays to include in the result array.
4247  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4248  *          The caller is to delete this result array using decrRef() as it is no more
4249  *          needed.
4250  *  \throw If all arrays within \a arr are NULL.
4251  *  \throw If getNumberOfComponents() of arrays within \a arr.
4252  */
4253 DataArrayDouble *DataArrayDouble::Aggregate(const std::vector<const DataArrayDouble *>& arr) throw(INTERP_KERNEL::Exception)
4254 {
4255   std::vector<const DataArrayDouble *> a;
4256   for(std::vector<const DataArrayDouble *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
4257     if(*it4)
4258       a.push_back(*it4);
4259   if(a.empty())
4260     throw INTERP_KERNEL::Exception("DataArrayDouble::Aggregate : input list must contain at least one NON EMPTY DataArrayDouble !");
4261   std::vector<const DataArrayDouble *>::const_iterator it=a.begin();
4262   int nbOfComp=(*it)->getNumberOfComponents();
4263   int nbt=(*it++)->getNumberOfTuples();
4264   for(int i=1;it!=a.end();it++,i++)
4265     {
4266       if((*it)->getNumberOfComponents()!=nbOfComp)
4267         throw INTERP_KERNEL::Exception("DataArrayDouble::Aggregate : Nb of components mismatch for array aggregation !");
4268       nbt+=(*it)->getNumberOfTuples();
4269     }
4270   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
4271   ret->alloc(nbt,nbOfComp);
4272   double *pt=ret->getPointer();
4273   for(it=a.begin();it!=a.end();it++)
4274     pt=std::copy((*it)->getConstPointer(),(*it)->getConstPointer()+(*it)->getNbOfElems(),pt);
4275   ret->copyStringInfoFrom(*(a[0]));
4276   return ret.retn();
4277 }
4278
4279 /*!
4280  * Returns a new DataArrayDouble by aggregating two given arrays, so that (1) the number
4281  * of components in the result array is a sum of the number of components of given arrays
4282  * and (2) the number of tuples in the result array is same as that of each of given
4283  * arrays. In other words the i-th tuple of result array includes all components of
4284  * i-th tuples of all given arrays.
4285  * Number of tuples in the given arrays must be  the same.
4286  *  \param [in] a1 - an array to include in the result array.
4287  *  \param [in] a2 - another array to include in the result array.
4288  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4289  *          The caller is to delete this result array using decrRef() as it is no more
4290  *          needed.
4291  *  \throw If both \a a1 and \a a2 are NULL.
4292  *  \throw If any given array is not allocated.
4293  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
4294  */
4295 DataArrayDouble *DataArrayDouble::Meld(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception)
4296 {
4297   std::vector<const DataArrayDouble *> arr(2);
4298   arr[0]=a1; arr[1]=a2;
4299   return Meld(arr);
4300 }
4301
4302 /*!
4303  * Returns a new DataArrayDouble by aggregating all given arrays, so that (1) the number
4304  * of components in the result array is a sum of the number of components of given arrays
4305  * and (2) the number of tuples in the result array is same as that of each of given
4306  * arrays. In other words the i-th tuple of result array includes all components of
4307  * i-th tuples of all given arrays.
4308  * Number of tuples in the given arrays must be  the same.
4309  *  \param [in] arr - a sequence of arrays to include in the result array.
4310  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4311  *          The caller is to delete this result array using decrRef() as it is no more
4312  *          needed.
4313  *  \throw If all arrays within \a arr are NULL.
4314  *  \throw If any given array is not allocated.
4315  *  \throw If getNumberOfTuples() of arrays within \a arr is different.
4316  */
4317 DataArrayDouble *DataArrayDouble::Meld(const std::vector<const DataArrayDouble *>& arr) throw(INTERP_KERNEL::Exception)
4318 {
4319   std::vector<const DataArrayDouble *> a;
4320   for(std::vector<const DataArrayDouble *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
4321     if(*it4)
4322       a.push_back(*it4);
4323   if(a.empty())
4324     throw INTERP_KERNEL::Exception("DataArrayDouble::Meld : input list must contain at least one NON EMPTY DataArrayDouble !");
4325   std::vector<const DataArrayDouble *>::const_iterator it;
4326   for(it=a.begin();it!=a.end();it++)
4327     (*it)->checkAllocated();
4328   it=a.begin();
4329   int nbOfTuples=(*it)->getNumberOfTuples();
4330   std::vector<int> nbc(a.size());
4331   std::vector<const double *> pts(a.size());
4332   nbc[0]=(*it)->getNumberOfComponents();
4333   pts[0]=(*it++)->getConstPointer();
4334   for(int i=1;it!=a.end();it++,i++)
4335     {
4336       if(nbOfTuples!=(*it)->getNumberOfTuples())
4337         throw INTERP_KERNEL::Exception("DataArrayDouble::Meld : mismatch of number of tuples !");
4338       nbc[i]=(*it)->getNumberOfComponents();
4339       pts[i]=(*it)->getConstPointer();
4340     }
4341   int totalNbOfComp=std::accumulate(nbc.begin(),nbc.end(),0);
4342   DataArrayDouble *ret=DataArrayDouble::New();
4343   ret->alloc(nbOfTuples,totalNbOfComp);
4344   double *retPtr=ret->getPointer();
4345   for(int i=0;i<nbOfTuples;i++)
4346     for(int j=0;j<(int)a.size();j++)
4347       {
4348         retPtr=std::copy(pts[j],pts[j]+nbc[j],retPtr);
4349         pts[j]+=nbc[j];
4350       }
4351   int k=0;
4352   for(int i=0;i<(int)a.size();i++)
4353     for(int j=0;j<nbc[i];j++,k++)
4354       ret->setInfoOnComponent(k,a[i]->getInfoOnComponent(j).c_str());
4355   return ret;
4356 }
4357
4358 /*!
4359  * Returns a new DataArrayDouble containing a dot product of two given arrays, so that
4360  * the i-th tuple of the result array is a sum of products of j-th components of i-th
4361  * tuples of given arrays (\f$ a_i = \sum_{j=1}^n a1_j * a2_j \f$).
4362  * Info on components and name is copied from the first of the given arrays.
4363  * Number of tuples and components in the given arrays must be the same.
4364  *  \param [in] a1 - a given array.
4365  *  \param [in] a2 - another given array.
4366  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4367  *          The caller is to delete this result array using decrRef() as it is no more
4368  *          needed.
4369  *  \throw If either \a a1 or \a a2 is NULL.
4370  *  \throw If any given array is not allocated.
4371  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
4372  *  \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents()
4373  */
4374 DataArrayDouble *DataArrayDouble::Dot(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception)
4375 {
4376   if(!a1 || !a2)
4377     throw INTERP_KERNEL::Exception("DataArrayDouble::Dot : input DataArrayDouble instance is NULL !");
4378   a1->checkAllocated();
4379   a2->checkAllocated();
4380   int nbOfComp=a1->getNumberOfComponents();
4381   if(nbOfComp!=a2->getNumberOfComponents())
4382     throw INTERP_KERNEL::Exception("Nb of components mismatch for array Dot !");
4383   int nbOfTuple=a1->getNumberOfTuples();
4384   if(nbOfTuple!=a2->getNumberOfTuples())
4385     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Dot !");
4386   DataArrayDouble *ret=DataArrayDouble::New();
4387   ret->alloc(nbOfTuple,1);
4388   double *retPtr=ret->getPointer();
4389   const double *a1Ptr=a1->getConstPointer();
4390   const double *a2Ptr=a2->getConstPointer();
4391   for(int i=0;i<nbOfTuple;i++)
4392     {
4393       double sum=0.;
4394       for(int j=0;j<nbOfComp;j++)
4395         sum+=a1Ptr[i*nbOfComp+j]*a2Ptr[i*nbOfComp+j];
4396       retPtr[i]=sum;
4397     }
4398   ret->setInfoOnComponent(0,a1->getInfoOnComponent(0).c_str());
4399   ret->setName(a1->getName().c_str());
4400   return ret;
4401 }
4402
4403 /*!
4404  * Returns a new DataArrayDouble containing a cross product of two given arrays, so that
4405  * the i-th tuple of the result array contains 3 components of a vector which is a cross
4406  * product of two vectors defined by the i-th tuples of given arrays.
4407  * Info on components is copied from the first of the given arrays.
4408  * Number of tuples in the given arrays must be the same.
4409  * Number of components in the given arrays must be 3.
4410  *  \param [in] a1 - a given array.
4411  *  \param [in] a2 - another given array.
4412  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4413  *          The caller is to delete this result array using decrRef() as it is no more
4414  *          needed.
4415  *  \throw If either \a a1 or \a a2 is NULL.
4416  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
4417  *  \throw If \a a1->getNumberOfComponents() != 3
4418  *  \throw If \a a2->getNumberOfComponents() != 3
4419  */
4420 DataArrayDouble *DataArrayDouble::CrossProduct(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception)
4421 {
4422   if(!a1 || !a2)
4423     throw INTERP_KERNEL::Exception("DataArrayDouble::CrossProduct : input DataArrayDouble instance is NULL !");
4424   int nbOfComp=a1->getNumberOfComponents();
4425   if(nbOfComp!=a2->getNumberOfComponents())
4426     throw INTERP_KERNEL::Exception("Nb of components mismatch for array crossProduct !");
4427   if(nbOfComp!=3)
4428     throw INTERP_KERNEL::Exception("Nb of components must be equal to 3 for array crossProduct !");
4429   int nbOfTuple=a1->getNumberOfTuples();
4430   if(nbOfTuple!=a2->getNumberOfTuples())
4431     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array crossProduct !");
4432   DataArrayDouble *ret=DataArrayDouble::New();
4433   ret->alloc(nbOfTuple,3);
4434   double *retPtr=ret->getPointer();
4435   const double *a1Ptr=a1->getConstPointer();
4436   const double *a2Ptr=a2->getConstPointer();
4437   for(int i=0;i<nbOfTuple;i++)
4438     {
4439       retPtr[3*i]=a1Ptr[3*i+1]*a2Ptr[3*i+2]-a1Ptr[3*i+2]*a2Ptr[3*i+1];
4440       retPtr[3*i+1]=a1Ptr[3*i+2]*a2Ptr[3*i]-a1Ptr[3*i]*a2Ptr[3*i+2];
4441       retPtr[3*i+2]=a1Ptr[3*i]*a2Ptr[3*i+1]-a1Ptr[3*i+1]*a2Ptr[3*i];
4442     }
4443   ret->copyStringInfoFrom(*a1);
4444   return ret;
4445 }
4446
4447 /*!
4448  * Returns a new DataArrayDouble containing maximal values of two given arrays.
4449  * Info on components is copied from the first of the given arrays.
4450  * Number of tuples and components in the given arrays must be the same.
4451  *  \param [in] a1 - an array to compare values with another one.
4452  *  \param [in] a2 - another array to compare values with the first one.
4453  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4454  *          The caller is to delete this result array using decrRef() as it is no more
4455  *          needed.
4456  *  \throw If either \a a1 or \a a2 is NULL.
4457  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
4458  *  \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents()
4459  */
4460 DataArrayDouble *DataArrayDouble::Max(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception)
4461 {
4462   if(!a1 || !a2)
4463     throw INTERP_KERNEL::Exception("DataArrayDouble::Max : input DataArrayDouble instance is NULL !");
4464   int nbOfComp=a1->getNumberOfComponents();
4465   if(nbOfComp!=a2->getNumberOfComponents())
4466     throw INTERP_KERNEL::Exception("Nb of components mismatch for array Max !");
4467   int nbOfTuple=a1->getNumberOfTuples();
4468   if(nbOfTuple!=a2->getNumberOfTuples())
4469     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Max !");
4470   DataArrayDouble *ret=DataArrayDouble::New();
4471   ret->alloc(nbOfTuple,nbOfComp);
4472   double *retPtr=ret->getPointer();
4473   const double *a1Ptr=a1->getConstPointer();
4474   const double *a2Ptr=a2->getConstPointer();
4475   int nbElem=nbOfTuple*nbOfComp;
4476   for(int i=0;i<nbElem;i++)
4477     retPtr[i]=std::max(a1Ptr[i],a2Ptr[i]);
4478   ret->copyStringInfoFrom(*a1);
4479   return ret;
4480 }
4481
4482 /*!
4483  * Returns a new DataArrayDouble containing minimal values of two given arrays.
4484  * Info on components is copied from the first of the given arrays.
4485  * Number of tuples and components in the given arrays must be the same.
4486  *  \param [in] a1 - an array to compare values with another one.
4487  *  \param [in] a2 - another array to compare values with the first one.
4488  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4489  *          The caller is to delete this result array using decrRef() as it is no more
4490  *          needed.
4491  *  \throw If either \a a1 or \a a2 is NULL.
4492  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
4493  *  \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents()
4494  */
4495 DataArrayDouble *DataArrayDouble::Min(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception)
4496 {
4497   if(!a1 || !a2)
4498     throw INTERP_KERNEL::Exception("DataArrayDouble::Min : input DataArrayDouble instance is NULL !");
4499   int nbOfComp=a1->getNumberOfComponents();
4500   if(nbOfComp!=a2->getNumberOfComponents())
4501     throw INTERP_KERNEL::Exception("Nb of components mismatch for array min !");
4502   int nbOfTuple=a1->getNumberOfTuples();
4503   if(nbOfTuple!=a2->getNumberOfTuples())
4504     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array min !");
4505   DataArrayDouble *ret=DataArrayDouble::New();
4506   ret->alloc(nbOfTuple,nbOfComp);
4507   double *retPtr=ret->getPointer();
4508   const double *a1Ptr=a1->getConstPointer();
4509   const double *a2Ptr=a2->getConstPointer();
4510   int nbElem=nbOfTuple*nbOfComp;
4511   for(int i=0;i<nbElem;i++)
4512     retPtr[i]=std::min(a1Ptr[i],a2Ptr[i]);
4513   ret->copyStringInfoFrom(*a1);
4514   return ret;
4515 }
4516
4517 /*!
4518  * Returns a new DataArrayDouble that is a sum of two given arrays. There are 3
4519  * valid cases.
4520  * 1.  The arrays have same number of tuples and components. Then each value of
4521  *   the result array (_a_) is a sum of the corresponding values of \a a1 and \a a2,
4522  *   i.e.: _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ i, j ].
4523  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
4524  *   component. Then
4525  *   _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ i, 0 ].
4526  * 3.  The arrays have same number of components and one array, say _a2_, has one
4527  *   tuple. Then
4528  *   _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ 0, j ].
4529  *
4530  * Info on components is copied either from the first array (in the first case) or from
4531  * the array with maximal number of elements (getNbOfElems()).
4532  *  \param [in] a1 - an array to sum up.
4533  *  \param [in] a2 - another array to sum up.
4534  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4535  *          The caller is to delete this result array using decrRef() as it is no more
4536  *          needed.
4537  *  \throw If either \a a1 or \a a2 is NULL.
4538  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
4539  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
4540  *         none of them has number of tuples or components equal to 1.
4541  */
4542 DataArrayDouble *DataArrayDouble::Add(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception)
4543 {
4544   if(!a1 || !a2)
4545     throw INTERP_KERNEL::Exception("DataArrayDouble::Add : input DataArrayDouble instance is NULL !");
4546   int nbOfTuple=a1->getNumberOfTuples();
4547   int nbOfTuple2=a2->getNumberOfTuples();
4548   int nbOfComp=a1->getNumberOfComponents();
4549   int nbOfComp2=a2->getNumberOfComponents();
4550   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=0;
4551   if(nbOfTuple==nbOfTuple2)
4552     {
4553       if(nbOfComp==nbOfComp2)
4554         {
4555           ret=DataArrayDouble::New();
4556           ret->alloc(nbOfTuple,nbOfComp);
4557           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::plus<double>());
4558           ret->copyStringInfoFrom(*a1);
4559         }
4560       else
4561         {
4562           int nbOfCompMin,nbOfCompMax;
4563           const DataArrayDouble *aMin, *aMax;
4564           if(nbOfComp>nbOfComp2)
4565             {
4566               nbOfCompMin=nbOfComp2; nbOfCompMax=nbOfComp;
4567               aMin=a2; aMax=a1;
4568             }
4569           else
4570             {
4571               nbOfCompMin=nbOfComp; nbOfCompMax=nbOfComp2;
4572               aMin=a1; aMax=a2;
4573             }
4574           if(nbOfCompMin==1)
4575             {
4576               ret=DataArrayDouble::New();
4577               ret->alloc(nbOfTuple,nbOfCompMax);
4578               const double *aMinPtr=aMin->getConstPointer();
4579               const double *aMaxPtr=aMax->getConstPointer();
4580               double *res=ret->getPointer();
4581               for(int i=0;i<nbOfTuple;i++)
4582                 res=std::transform(aMaxPtr+i*nbOfCompMax,aMaxPtr+(i+1)*nbOfCompMax,res,std::bind2nd(std::plus<double>(),aMinPtr[i]));
4583               ret->copyStringInfoFrom(*aMax);
4584             }
4585           else
4586             throw INTERP_KERNEL::Exception("Nb of components mismatch for array Add !");
4587         }
4588     }
4589   else if((nbOfTuple==1 && nbOfTuple2>1) || (nbOfTuple>1 && nbOfTuple2==1))
4590     {
4591       if(nbOfComp==nbOfComp2)
4592         {
4593           int nbOfTupleMax=std::max(nbOfTuple,nbOfTuple2);
4594           const DataArrayDouble *aMin=nbOfTuple>nbOfTuple2?a2:a1;
4595           const DataArrayDouble *aMax=nbOfTuple>nbOfTuple2?a1:a2;
4596           const double *aMinPtr=aMin->getConstPointer(),*aMaxPtr=aMax->getConstPointer();
4597           ret=DataArrayDouble::New();
4598           ret->alloc(nbOfTupleMax,nbOfComp);
4599           double *res=ret->getPointer();
4600           for(int i=0;i<nbOfTupleMax;i++)
4601             res=std::transform(aMaxPtr+i*nbOfComp,aMaxPtr+(i+1)*nbOfComp,aMinPtr,res,std::plus<double>());
4602           ret->copyStringInfoFrom(*aMax);
4603         }
4604       else
4605         throw INTERP_KERNEL::Exception("Nb of components mismatch for array Add !");
4606     }
4607   else
4608     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Add !");
4609   return ret.retn();
4610 }
4611
4612 /*!
4613  * Adds values of another DataArrayDouble to values of \a this one. There are 3
4614  * valid cases.
4615  * 1.  The arrays have same number of tuples and components. Then each value of
4616  *   \a other array is added to the corresponding value of \a this array, i.e.:
4617  *   _a_ [ i, j ] += _other_ [ i, j ].
4618  * 2.  The arrays have same number of tuples and \a other array has one component. Then
4619  *   _a_ [ i, j ] += _other_ [ i, 0 ].
4620  * 3.  The arrays have same number of components and \a other array has one tuple. Then
4621  *   _a_ [ i, j ] += _a2_ [ 0, j ].
4622  *
4623  *  \param [in] other - an array to add to \a this one.
4624  *  \throw If \a other is NULL.
4625  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
4626  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
4627  *         \a other has number of both tuples and components not equal to 1.
4628  */
4629 void DataArrayDouble::addEqual(const DataArrayDouble *other) throw(INTERP_KERNEL::Exception)
4630 {
4631   if(!other)
4632     throw INTERP_KERNEL::Exception("DataArrayDouble::addEqual : input DataArrayDouble instance is NULL !");
4633   const char *msg="Nb of tuples mismatch for DataArrayDouble::addEqual  !";
4634   checkAllocated();
4635   other->checkAllocated();
4636   int nbOfTuple=getNumberOfTuples();
4637   int nbOfTuple2=other->getNumberOfTuples();
4638   int nbOfComp=getNumberOfComponents();
4639   int nbOfComp2=other->getNumberOfComponents();
4640   if(nbOfTuple==nbOfTuple2)
4641     {
4642       if(nbOfComp==nbOfComp2)
4643         {
4644           std::transform(begin(),end(),other->begin(),getPointer(),std::plus<double>());
4645         }
4646       else if(nbOfComp2==1)
4647         {
4648           double *ptr=getPointer();
4649           const double *ptrc=other->getConstPointer();
4650           for(int i=0;i<nbOfTuple;i++)
4651             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::plus<double>(),*ptrc++));
4652         }
4653       else
4654         throw INTERP_KERNEL::Exception(msg);
4655     }
4656   else if(nbOfTuple2==1)
4657     {
4658       if(nbOfComp2==nbOfComp)
4659         {
4660           double *ptr=getPointer();
4661           const double *ptrc=other->getConstPointer();
4662           for(int i=0;i<nbOfTuple;i++)
4663             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::plus<double>());
4664         }
4665       else
4666         throw INTERP_KERNEL::Exception(msg);
4667     }
4668   else
4669     throw INTERP_KERNEL::Exception(msg);
4670   declareAsNew();
4671 }
4672
4673 /*!
4674  * Returns a new DataArrayDouble that is a subtraction of two given arrays. There are 3
4675  * valid cases.
4676  * 1.  The arrays have same number of tuples and components. Then each value of
4677  *   the result array (_a_) is a subtraction of the corresponding values of \a a1 and
4678  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ i, j ].
4679  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
4680  *   component. Then
4681  *   _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ i, 0 ].
4682  * 3.  The arrays have same number of components and one array, say _a2_, has one
4683  *   tuple. Then
4684  *   _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ 0, j ].
4685  *
4686  * Info on components is copied either from the first array (in the first case) or from
4687  * the array with maximal number of elements (getNbOfElems()).
4688  *  \param [in] a1 - an array to subtract from.
4689  *  \param [in] a2 - an array to subtract.
4690  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4691  *          The caller is to delete this result array using decrRef() as it is no more
4692  *          needed.
4693  *  \throw If either \a a1 or \a a2 is NULL.
4694  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
4695  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
4696  *         none of them has number of tuples or components equal to 1.
4697  */
4698 DataArrayDouble *DataArrayDouble::Substract(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception)
4699 {
4700   if(!a1 || !a2)
4701     throw INTERP_KERNEL::Exception("DataArrayDouble::Substract : input DataArrayDouble instance is NULL !");
4702   int nbOfTuple1=a1->getNumberOfTuples();
4703   int nbOfTuple2=a2->getNumberOfTuples();
4704   int nbOfComp1=a1->getNumberOfComponents();
4705   int nbOfComp2=a2->getNumberOfComponents();
4706   if(nbOfTuple2==nbOfTuple1)
4707     {
4708       if(nbOfComp1==nbOfComp2)
4709         {
4710           MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
4711           ret->alloc(nbOfTuple2,nbOfComp1);
4712           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::minus<double>());
4713           ret->copyStringInfoFrom(*a1);
4714           return ret.retn();
4715         }
4716       else if(nbOfComp2==1)
4717         {
4718           MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
4719           ret->alloc(nbOfTuple1,nbOfComp1);
4720           const double *a2Ptr=a2->getConstPointer();
4721           const double *a1Ptr=a1->getConstPointer();
4722           double *res=ret->getPointer();
4723           for(int i=0;i<nbOfTuple1;i++)
4724             res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::minus<double>(),a2Ptr[i]));
4725           ret->copyStringInfoFrom(*a1);
4726           return ret.retn();
4727         }
4728       else
4729         {
4730           a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Substract !");
4731           return 0;
4732         }
4733     }
4734   else if(nbOfTuple2==1)
4735     {
4736       a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Substract !");
4737       MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
4738       ret->alloc(nbOfTuple1,nbOfComp1);
4739       const double *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
4740       double *pt=ret->getPointer();
4741       for(int i=0;i<nbOfTuple1;i++)
4742         pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::minus<double>());
4743       ret->copyStringInfoFrom(*a1);
4744       return ret.retn();
4745     }
4746   else
4747     {
4748       a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Substract !");//will always throw an exception
4749       return 0;
4750     }
4751 }
4752
4753 /*!
4754  * Subtract values of another DataArrayDouble from values of \a this one. There are 3
4755  * valid cases.
4756  * 1.  The arrays have same number of tuples and components. Then each value of
4757  *   \a other array is subtracted from the corresponding value of \a this array, i.e.:
4758  *   _a_ [ i, j ] -= _other_ [ i, j ].
4759  * 2.  The arrays have same number of tuples and \a other array has one component. Then
4760  *   _a_ [ i, j ] -= _other_ [ i, 0 ].
4761  * 3.  The arrays have same number of components and \a other array has one tuple. Then
4762  *   _a_ [ i, j ] -= _a2_ [ 0, j ].
4763  *
4764  *  \param [in] other - an array to subtract from \a this one.
4765  *  \throw If \a other is NULL.
4766  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
4767  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
4768  *         \a other has number of both tuples and components not equal to 1.
4769  */
4770 void DataArrayDouble::substractEqual(const DataArrayDouble *other) throw(INTERP_KERNEL::Exception)
4771 {
4772   if(!other)
4773     throw INTERP_KERNEL::Exception("DataArrayDouble::substractEqual : input DataArrayDouble instance is NULL !");
4774   const char *msg="Nb of tuples mismatch for DataArrayDouble::substractEqual  !";
4775   checkAllocated();
4776   other->checkAllocated();
4777   int nbOfTuple=getNumberOfTuples();
4778   int nbOfTuple2=other->getNumberOfTuples();
4779   int nbOfComp=getNumberOfComponents();
4780   int nbOfComp2=other->getNumberOfComponents();
4781   if(nbOfTuple==nbOfTuple2)
4782     {
4783       if(nbOfComp==nbOfComp2)
4784         {
4785           std::transform(begin(),end(),other->begin(),getPointer(),std::minus<double>());
4786         }
4787       else if(nbOfComp2==1)
4788         {
4789           double *ptr=getPointer();
4790           const double *ptrc=other->getConstPointer();
4791           for(int i=0;i<nbOfTuple;i++)
4792             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::minus<double>(),*ptrc++)); 
4793         }
4794       else
4795         throw INTERP_KERNEL::Exception(msg);
4796     }
4797   else if(nbOfTuple2==1)
4798     {
4799       if(nbOfComp2==nbOfComp)
4800         {
4801           double *ptr=getPointer();
4802           const double *ptrc=other->getConstPointer();
4803           for(int i=0;i<nbOfTuple;i++)
4804             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::minus<double>());
4805         }
4806       else
4807         throw INTERP_KERNEL::Exception(msg);
4808     }
4809   else
4810     throw INTERP_KERNEL::Exception(msg);
4811   declareAsNew();
4812 }
4813
4814 /*!
4815  * Returns a new DataArrayDouble that is a product of two given arrays. There are 3
4816  * valid cases.
4817  * 1.  The arrays have same number of tuples and components. Then each value of
4818  *   the result array (_a_) is a product of the corresponding values of \a a1 and
4819  *   \a a2, i.e. _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ i, j ].
4820  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
4821  *   component. Then
4822  *   _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ i, 0 ].
4823  * 3.  The arrays have same number of components and one array, say _a2_, has one
4824  *   tuple. Then
4825  *   _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ 0, j ].
4826  *
4827  * Info on components is copied either from the first array (in the first case) or from
4828  * the array with maximal number of elements (getNbOfElems()).
4829  *  \param [in] a1 - a factor array.
4830  *  \param [in] a2 - another factor array.
4831  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4832  *          The caller is to delete this result array using decrRef() as it is no more
4833  *          needed.
4834  *  \throw If either \a a1 or \a a2 is NULL.
4835  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
4836  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
4837  *         none of them has number of tuples or components equal to 1.
4838  */
4839 DataArrayDouble *DataArrayDouble::Multiply(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception)
4840 {
4841   if(!a1 || !a2)
4842     throw INTERP_KERNEL::Exception("DataArrayDouble::Multiply : input DataArrayDouble instance is NULL !");
4843   int nbOfTuple=a1->getNumberOfTuples();
4844   int nbOfTuple2=a2->getNumberOfTuples();
4845   int nbOfComp=a1->getNumberOfComponents();
4846   int nbOfComp2=a2->getNumberOfComponents();
4847   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=0;
4848   if(nbOfTuple==nbOfTuple2)
4849     {
4850       if(nbOfComp==nbOfComp2)
4851         {
4852           ret=DataArrayDouble::New();
4853           ret->alloc(nbOfTuple,nbOfComp);
4854           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::multiplies<double>());
4855           ret->copyStringInfoFrom(*a1);
4856         }
4857       else
4858         {
4859           int nbOfCompMin,nbOfCompMax;
4860           const DataArrayDouble *aMin, *aMax;
4861           if(nbOfComp>nbOfComp2)
4862             {
4863               nbOfCompMin=nbOfComp2; nbOfCompMax=nbOfComp;
4864               aMin=a2; aMax=a1;
4865             }
4866           else
4867             {
4868               nbOfCompMin=nbOfComp; nbOfCompMax=nbOfComp2;
4869               aMin=a1; aMax=a2;
4870             }
4871           if(nbOfCompMin==1)
4872             {
4873               ret=DataArrayDouble::New();
4874               ret->alloc(nbOfTuple,nbOfCompMax);
4875               const double *aMinPtr=aMin->getConstPointer();
4876               const double *aMaxPtr=aMax->getConstPointer();
4877               double *res=ret->getPointer();
4878               for(int i=0;i<nbOfTuple;i++)
4879                 res=std::transform(aMaxPtr+i*nbOfCompMax,aMaxPtr+(i+1)*nbOfCompMax,res,std::bind2nd(std::multiplies<double>(),aMinPtr[i]));
4880               ret->copyStringInfoFrom(*aMax);
4881             }
4882           else
4883             throw INTERP_KERNEL::Exception("Nb of components mismatch for array Multiply !");
4884         }
4885     }
4886   else if((nbOfTuple==1 && nbOfTuple2>1) || (nbOfTuple>1 && nbOfTuple2==1))
4887     {
4888       if(nbOfComp==nbOfComp2)
4889         {
4890           int nbOfTupleMax=std::max(nbOfTuple,nbOfTuple2);
4891           const DataArrayDouble *aMin=nbOfTuple>nbOfTuple2?a2:a1;
4892           const DataArrayDouble *aMax=nbOfTuple>nbOfTuple2?a1:a2;
4893           const double *aMinPtr=aMin->getConstPointer(),*aMaxPtr=aMax->getConstPointer();
4894           ret=DataArrayDouble::New();
4895           ret->alloc(nbOfTupleMax,nbOfComp);
4896           double *res=ret->getPointer();
4897           for(int i=0;i<nbOfTupleMax;i++)
4898             res=std::transform(aMaxPtr+i*nbOfComp,aMaxPtr+(i+1)*nbOfComp,aMinPtr,res,std::multiplies<double>());
4899           ret->copyStringInfoFrom(*aMax);
4900         }
4901       else
4902         throw INTERP_KERNEL::Exception("Nb of components mismatch for array Multiply !");
4903     }
4904   else
4905     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Multiply !");
4906   return ret.retn();
4907 }
4908
4909 /*!
4910  * Multiply values of another DataArrayDouble to values of \a this one. There are 3
4911  * valid cases.
4912  * 1.  The arrays have same number of tuples and components. Then each value of
4913  *   \a other array is multiplied to the corresponding value of \a this array, i.e.
4914  *   _this_ [ i, j ] *= _other_ [ i, j ].
4915  * 2.  The arrays have same number of tuples and \a other array has one component. Then
4916  *   _this_ [ i, j ] *= _other_ [ i, 0 ].
4917  * 3.  The arrays have same number of components and \a other array has one tuple. Then
4918  *   _this_ [ i, j ] *= _a2_ [ 0, j ].
4919  *
4920  *  \param [in] other - an array to multiply to \a this one.
4921  *  \throw If \a other is NULL.
4922  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
4923  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
4924  *         \a other has number of both tuples and components not equal to 1.
4925  */
4926 void DataArrayDouble::multiplyEqual(const DataArrayDouble *other) throw(INTERP_KERNEL::Exception)
4927 {
4928   if(!other)
4929     throw INTERP_KERNEL::Exception("DataArrayDouble::multiplyEqual : input DataArrayDouble instance is NULL !");
4930   const char *msg="Nb of tuples mismatch for DataArrayDouble::multiplyEqual !";
4931   checkAllocated();
4932   other->checkAllocated();
4933   int nbOfTuple=getNumberOfTuples();
4934   int nbOfTuple2=other->getNumberOfTuples();
4935   int nbOfComp=getNumberOfComponents();
4936   int nbOfComp2=other->getNumberOfComponents();
4937   if(nbOfTuple==nbOfTuple2)
4938     {
4939       if(nbOfComp==nbOfComp2)
4940         {
4941           std::transform(begin(),end(),other->begin(),getPointer(),std::multiplies<double>());
4942         }
4943       else if(nbOfComp2==1)
4944         {
4945           double *ptr=getPointer();
4946           const double *ptrc=other->getConstPointer();
4947           for(int i=0;i<nbOfTuple;i++)
4948             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::multiplies<double>(),*ptrc++));
4949         }
4950       else
4951         throw INTERP_KERNEL::Exception(msg);
4952     }
4953   else if(nbOfTuple2==1)
4954     {
4955       if(nbOfComp2==nbOfComp)
4956         {
4957           double *ptr=getPointer();
4958           const double *ptrc=other->getConstPointer();
4959           for(int i=0;i<nbOfTuple;i++)
4960             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::multiplies<double>());
4961         }
4962       else
4963         throw INTERP_KERNEL::Exception(msg);
4964     }
4965   else
4966     throw INTERP_KERNEL::Exception(msg);
4967   declareAsNew();
4968 }
4969
4970 /*!
4971  * Returns a new DataArrayDouble that is a division of two given arrays. There are 3
4972  * valid cases.
4973  * 1.  The arrays have same number of tuples and components. Then each value of
4974  *   the result array (_a_) is a division of the corresponding values of \a a1 and
4975  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ i, j ].
4976  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
4977  *   component. Then
4978  *   _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ i, 0 ].
4979  * 3.  The arrays have same number of components and one array, say _a2_, has one
4980  *   tuple. Then
4981  *   _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ 0, j ].
4982  *
4983  * Info on components is copied either from the first array (in the first case) or from
4984  * the array with maximal number of elements (getNbOfElems()).
4985  *  \warning No check of division by zero is performed!
4986  *  \param [in] a1 - a numerator array.
4987  *  \param [in] a2 - a denominator array.
4988  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4989  *          The caller is to delete this result array using decrRef() as it is no more
4990  *          needed.
4991  *  \throw If either \a a1 or \a a2 is NULL.
4992  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
4993  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
4994  *         none of them has number of tuples or components equal to 1.
4995  */
4996 DataArrayDouble *DataArrayDouble::Divide(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception)
4997 {
4998   if(!a1 || !a2)
4999     throw INTERP_KERNEL::Exception("DataArrayDouble::Divide : input DataArrayDouble instance is NULL !");
5000   int nbOfTuple1=a1->getNumberOfTuples();
5001   int nbOfTuple2=a2->getNumberOfTuples();
5002   int nbOfComp1=a1->getNumberOfComponents();
5003   int nbOfComp2=a2->getNumberOfComponents();
5004   if(nbOfTuple2==nbOfTuple1)
5005     {
5006       if(nbOfComp1==nbOfComp2)
5007         {
5008           MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
5009           ret->alloc(nbOfTuple2,nbOfComp1);
5010           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::divides<double>());
5011           ret->copyStringInfoFrom(*a1);
5012           return ret.retn();
5013         }
5014       else if(nbOfComp2==1)
5015         {
5016           MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
5017           ret->alloc(nbOfTuple1,nbOfComp1);
5018           const double *a2Ptr=a2->getConstPointer();
5019           const double *a1Ptr=a1->getConstPointer();
5020           double *res=ret->getPointer();
5021           for(int i=0;i<nbOfTuple1;i++)
5022             res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::divides<double>(),a2Ptr[i]));
5023           ret->copyStringInfoFrom(*a1);
5024           return ret.retn();
5025         }
5026       else
5027         {
5028           a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Divide !");
5029           return 0;
5030         }
5031     }
5032   else if(nbOfTuple2==1)
5033     {
5034       a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Divide !");
5035       MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
5036       ret->alloc(nbOfTuple1,nbOfComp1);
5037       const double *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
5038       double *pt=ret->getPointer();
5039       for(int i=0;i<nbOfTuple1;i++)
5040         pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::divides<double>());
5041       ret->copyStringInfoFrom(*a1);
5042       return ret.retn();
5043     }
5044   else
5045     {
5046       a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Divide !");//will always throw an exception
5047       return 0;
5048     }
5049 }
5050
5051 /*!
5052  * Divide values of \a this array by values of another DataArrayDouble. There are 3
5053  * valid cases.
5054  * 1.  The arrays have same number of tuples and components. Then each value of
5055  *    \a this array is divided by the corresponding value of \a other one, i.e.:
5056  *   _a_ [ i, j ] /= _other_ [ i, j ].
5057  * 2.  The arrays have same number of tuples and \a other array has one component. Then
5058  *   _a_ [ i, j ] /= _other_ [ i, 0 ].
5059  * 3.  The arrays have same number of components and \a other array has one tuple. Then
5060  *   _a_ [ i, j ] /= _a2_ [ 0, j ].
5061  *
5062  *  \warning No check of division by zero is performed!
5063  *  \param [in] other - an array to divide \a this one by.
5064  *  \throw If \a other is NULL.
5065  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
5066  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
5067  *         \a other has number of both tuples and components not equal to 1.
5068  */
5069 void DataArrayDouble::divideEqual(const DataArrayDouble *other) throw(INTERP_KERNEL::Exception)
5070 {
5071   if(!other)
5072     throw INTERP_KERNEL::Exception("DataArrayDouble::divideEqual : input DataArrayDouble instance is NULL !");
5073   const char *msg="Nb of tuples mismatch for DataArrayDouble::divideEqual !";
5074   checkAllocated();
5075   other->checkAllocated();
5076   int nbOfTuple=getNumberOfTuples();
5077   int nbOfTuple2=other->getNumberOfTuples();
5078   int nbOfComp=getNumberOfComponents();
5079   int nbOfComp2=other->getNumberOfComponents();
5080   if(nbOfTuple==nbOfTuple2)
5081     {
5082       if(nbOfComp==nbOfComp2)
5083         {
5084           std::transform(begin(),end(),other->begin(),getPointer(),std::divides<double>());
5085         }
5086       else if(nbOfComp2==1)
5087         {
5088           double *ptr=getPointer();
5089           const double *ptrc=other->getConstPointer();
5090           for(int i=0;i<nbOfTuple;i++)
5091             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::divides<double>(),*ptrc++));
5092         }
5093       else
5094         throw INTERP_KERNEL::Exception(msg);
5095     }
5096   else if(nbOfTuple2==1)
5097     {
5098       if(nbOfComp2==nbOfComp)
5099         {
5100           double *ptr=getPointer();
5101           const double *ptrc=other->getConstPointer();
5102           for(int i=0;i<nbOfTuple;i++)
5103             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::divides<double>());
5104         }
5105       else
5106         throw INTERP_KERNEL::Exception(msg);
5107     }
5108   else
5109     throw INTERP_KERNEL::Exception(msg);
5110   declareAsNew();
5111 }
5112
5113 /*!
5114  * Returns a new DataArrayDouble that is the result of pow of two given arrays. There are 3
5115  * valid cases.
5116  *
5117  *  \param [in] a1 - an array to pow up.
5118  *  \param [in] a2 - another array to sum up.
5119  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
5120  *          The caller is to delete this result array using decrRef() as it is no more
5121  *          needed.
5122  *  \throw If either \a a1 or \a a2 is NULL.
5123  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
5124  *  \throw If \a a1->getNumberOfComponents() != 1 or \a a2->getNumberOfComponents() != 1.
5125  *  \throw If there is a negative value in \a a1.
5126  */
5127 DataArrayDouble *DataArrayDouble::Pow(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception)
5128 {
5129   if(!a1 || !a2)
5130     throw INTERP_KERNEL::Exception("DataArrayDouble::Pow : at least one of input instances is null !");
5131   int nbOfTuple=a1->getNumberOfTuples();
5132   int nbOfTuple2=a2->getNumberOfTuples();
5133   int nbOfComp=a1->getNumberOfComponents();
5134   int nbOfComp2=a2->getNumberOfComponents();
5135   if(nbOfTuple!=nbOfTuple2)
5136     throw INTERP_KERNEL::Exception("DataArrayDouble::Pow : number of tuples mismatches !");
5137   if(nbOfComp!=1 || nbOfComp2!=1)
5138     throw INTERP_KERNEL::Exception("DataArrayDouble::Pow : number of components of both arrays must be equal to 1 !");
5139   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New(); ret->alloc(nbOfTuple,1);
5140   const double *ptr1(a1->begin()),*ptr2(a2->begin());
5141   double *ptr=ret->getPointer();
5142   for(int i=0;i<nbOfTuple;i++,ptr1++,ptr2++,ptr++)
5143     {
5144       if(*ptr1>=0)
5145         {
5146           *ptr=pow(*ptr1,*ptr2);
5147         }
5148       else
5149         {
5150           std::ostringstream oss; oss << "DataArrayDouble::Pow : on tuple #" << i << " of a1 value is < 0 (" << *ptr1 << ") !";
5151           throw INTERP_KERNEL::Exception(oss.str().c_str());
5152         }
5153     }
5154   return ret.retn();
5155 }
5156
5157 /*!
5158  * Apply pow on values of another DataArrayDouble to values of \a this one.
5159  *
5160  *  \param [in] other - an array to pow to \a this one.
5161  *  \throw If \a other is NULL.
5162  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples()
5163  *  \throw If \a this->getNumberOfComponents() != 1 or \a other->getNumberOfComponents() != 1
5164  *  \throw If there is a negative value in \a this.
5165  */
5166 void DataArrayDouble::powEqual(const DataArrayDouble *other) throw(INTERP_KERNEL::Exception)
5167 {
5168   if(!other)
5169     throw INTERP_KERNEL::Exception("DataArrayDouble::powEqual : input instance is null !");
5170   int nbOfTuple=getNumberOfTuples();
5171   int nbOfTuple2=other->getNumberOfTuples();
5172   int nbOfComp=getNumberOfComponents();
5173   int nbOfComp2=other->getNumberOfComponents();
5174   if(nbOfTuple!=nbOfTuple2)
5175     throw INTERP_KERNEL::Exception("DataArrayDouble::powEqual : number of tuples mismatches !");
5176   if(nbOfComp!=1 || nbOfComp2!=1)
5177     throw INTERP_KERNEL::Exception("DataArrayDouble::powEqual : number of components of both arrays must be equal to 1 !");
5178   double *ptr=getPointer();
5179   const double *ptrc=other->begin();
5180   for(int i=0;i<nbOfTuple;i++,ptrc++,ptr++)
5181     {
5182       if(*ptr>=0)
5183         *ptr=pow(*ptr,*ptrc);
5184       else
5185         {
5186           std::ostringstream oss; oss << "DataArrayDouble::powEqual : on tuple #" << i << " of this value is < 0 (" << *ptr << ") !";
5187           throw INTERP_KERNEL::Exception(oss.str().c_str());
5188         }
5189     }
5190   declareAsNew();
5191 }
5192
5193 /*!
5194  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
5195  * Server side.
5196  */
5197 void DataArrayDouble::getTinySerializationIntInformation(std::vector<int>& tinyInfo) const
5198 {
5199   tinyInfo.resize(2);
5200   if(isAllocated())
5201     {
5202       tinyInfo[0]=getNumberOfTuples();
5203       tinyInfo[1]=getNumberOfComponents();
5204     }
5205   else
5206     {
5207       tinyInfo[0]=-1;
5208       tinyInfo[1]=-1;
5209     }
5210 }
5211
5212 /*!
5213  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
5214  * Server side.
5215  */
5216 void DataArrayDouble::getTinySerializationStrInformation(std::vector<std::string>& tinyInfo) const
5217 {
5218   if(isAllocated())
5219     {
5220       int nbOfCompo=getNumberOfComponents();
5221       tinyInfo.resize(nbOfCompo+1);
5222       tinyInfo[0]=getName();
5223       for(int i=0;i<nbOfCompo;i++)
5224         tinyInfo[i+1]=getInfoOnComponent(i);
5225     }
5226   else
5227     {
5228       tinyInfo.resize(1);
5229       tinyInfo[0]=getName();
5230     }
5231 }
5232
5233 /*!
5234  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
5235  * This method returns if a feeding is needed.
5236  */
5237 bool DataArrayDouble::resizeForUnserialization(const std::vector<int>& tinyInfoI)
5238 {
5239   int nbOfTuple=tinyInfoI[0];
5240   int nbOfComp=tinyInfoI[1];
5241   if(nbOfTuple!=-1 || nbOfComp!=-1)
5242     {
5243       alloc(nbOfTuple,nbOfComp);
5244       return true;
5245     }
5246   return false;
5247 }
5248
5249 /*!
5250  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
5251  */
5252 void DataArrayDouble::finishUnserialization(const std::vector<int>& tinyInfoI, const std::vector<std::string>& tinyInfoS)
5253 {
5254   setName(tinyInfoS[0].c_str());
5255   if(isAllocated())
5256     {
5257       int nbOfCompo=getNumberOfComponents();
5258       for(int i=0;i<nbOfCompo;i++)
5259         setInfoOnComponent(i,tinyInfoS[i+1].c_str());
5260     }
5261 }
5262
5263 DataArrayDoubleIterator::DataArrayDoubleIterator(DataArrayDouble *da):_da(da),_tuple_id(0),_nb_comp(0),_nb_tuple(0)
5264 {
5265   if(_da)
5266     {
5267       _da->incrRef();
5268       if(_da->isAllocated())
5269         {
5270           _nb_comp=da->getNumberOfComponents();
5271           _nb_tuple=da->getNumberOfTuples();
5272           _pt=da->getPointer();
5273         }
5274     }
5275 }
5276
5277 DataArrayDoubleIterator::~DataArrayDoubleIterator()
5278 {
5279   if(_da)
5280     _da->decrRef();
5281 }
5282
5283 DataArrayDoubleTuple *DataArrayDoubleIterator::nextt() throw(INTERP_KERNEL::Exception)
5284 {
5285   if(_tuple_id<_nb_tuple)
5286     {
5287       _tuple_id++;
5288       DataArrayDoubleTuple *ret=new DataArrayDoubleTuple(_pt,_nb_comp);
5289       _pt+=_nb_comp;
5290       return ret;
5291     }
5292   else
5293     return 0;
5294 }
5295
5296 DataArrayDoubleTuple::DataArrayDoubleTuple(double *pt, int nbOfComp):_pt(pt),_nb_of_compo(nbOfComp)
5297 {
5298 }
5299
5300
5301 std::string DataArrayDoubleTuple::repr() const throw(INTERP_KERNEL::Exception)
5302 {
5303   std::ostringstream oss; oss.precision(17); oss << "(";
5304   for(int i=0;i<_nb_of_compo-1;i++)
5305     oss << _pt[i] << ", ";
5306   oss << _pt[_nb_of_compo-1] << ")";
5307   return oss.str();
5308 }
5309
5310 double DataArrayDoubleTuple::doubleValue() const throw(INTERP_KERNEL::Exception)
5311 {
5312   if(_nb_of_compo==1)
5313     return *_pt;
5314   throw INTERP_KERNEL::Exception("DataArrayDoubleTuple::doubleValue : DataArrayDoubleTuple instance has not exactly 1 component -> Not possible to convert it into a double precision float !");
5315 }
5316
5317 /*!
5318  * This method returns a newly allocated instance the caller should dealed with by a ParaMEDMEM::DataArrayDouble::decrRef.
5319  * This method performs \b no copy of data. The content is only referenced using ParaMEDMEM::DataArrayDouble::useArray with ownership set to \b false.
5320  * 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
5321  * \b nbOfCompo=1 and \bnbOfTuples==this->_nb_of_elem.
5322  */
5323 DataArrayDouble *DataArrayDoubleTuple::buildDADouble(int nbOfTuples, int nbOfCompo) const throw(INTERP_KERNEL::Exception)
5324 {
5325   if((_nb_of_compo==nbOfCompo && nbOfTuples==1) || (_nb_of_compo==nbOfTuples && nbOfCompo==1))
5326     {
5327       DataArrayDouble *ret=DataArrayDouble::New();
5328       ret->useExternalArrayWithRWAccess(_pt,nbOfTuples,nbOfCompo);
5329       return ret;
5330     }
5331   else
5332     {
5333       std::ostringstream oss; oss << "DataArrayDoubleTuple::buildDADouble : unable to build a requested DataArrayDouble instance with nbofTuple=" << nbOfTuples << " and nbOfCompo=" << nbOfCompo;
5334       oss << ".\nBecause the number of elements in this is " << _nb_of_compo << " !";
5335       throw INTERP_KERNEL::Exception(oss.str().c_str());
5336     }
5337 }
5338
5339 /*!
5340  * Returns a new instance of DataArrayInt. The caller is to delete this array
5341  * using decrRef() as it is no more needed. 
5342  */
5343 DataArrayInt *DataArrayInt::New()
5344 {
5345   return new DataArrayInt;
5346 }
5347
5348 /*!
5349  * Checks if raw data is allocated. Read more on the raw data
5350  * in \ref MEDCouplingArrayBasicsTuplesAndCompo "DataArrays infos" for more information.
5351  *  \return bool - \a true if the raw data is allocated, \a false else.
5352  */
5353 bool DataArrayInt::isAllocated() const throw(INTERP_KERNEL::Exception)
5354 {
5355   return getConstPointer()!=0;
5356 }
5357
5358 /*!
5359  * Checks if raw data is allocated and throws an exception if it is not the case.
5360  *  \throw If the raw data is not allocated.
5361  */
5362 void DataArrayInt::checkAllocated() const throw(INTERP_KERNEL::Exception)
5363 {
5364   if(!isAllocated())
5365     throw INTERP_KERNEL::Exception("DataArrayInt::checkAllocated : Array is defined but not allocated ! Call alloc or setValues method first !");
5366 }
5367
5368 std::size_t DataArrayInt::getHeapMemorySize() const
5369 {
5370   std::size_t sz=_mem.getNbOfElemAllocated();
5371   sz*=sizeof(int);
5372   return DataArray::getHeapMemorySize()+sz;
5373 }
5374
5375 /*!
5376  * Returns the only one value in \a this, if and only if number of elements
5377  * (nb of tuples * nb of components) is equal to 1, and that \a this is allocated.
5378  *  \return double - the sole value stored in \a this array.
5379  *  \throw If at least one of conditions stated above is not fulfilled.
5380  */
5381 int DataArrayInt::intValue() const throw(INTERP_KERNEL::Exception)
5382 {
5383   if(isAllocated())
5384     {
5385       if(getNbOfElems()==1)
5386         {
5387           return *getConstPointer();
5388         }
5389       else
5390         throw INTERP_KERNEL::Exception("DataArrayInt::intValue : DataArrayInt instance is allocated but number of elements is not equal to 1 !");
5391     }
5392   else
5393     throw INTERP_KERNEL::Exception("DataArrayInt::intValue : DataArrayInt instance is not allocated !");
5394 }
5395
5396 /*!
5397  * Returns an integer value characterizing \a this array, which is useful for a quick
5398  * comparison of many instances of DataArrayInt.
5399  *  \return int - the hash value.
5400  *  \throw If \a this is not allocated.
5401  */
5402 int DataArrayInt::getHashCode() const throw(INTERP_KERNEL::Exception)
5403 {
5404   checkAllocated();
5405   std::size_t nbOfElems=getNbOfElems();
5406   int ret=nbOfElems*65536;
5407   int delta=3;
5408   if(nbOfElems>48)
5409     delta=nbOfElems/8;
5410   int ret0=0;
5411   const int *pt=begin();
5412   for(std::size_t i=0;i<nbOfElems;i+=delta)
5413     ret0+=pt[i] & 0x1FFF;
5414   return ret+ret0;
5415 }
5416
5417 /*!
5418  * Checks the number of tuples.
5419  *  \return bool - \a true if getNumberOfTuples() == 0, \a false else.
5420  *  \throw If \a this is not allocated.
5421  */
5422 bool DataArrayInt::empty() const throw(INTERP_KERNEL::Exception)
5423 {
5424   checkAllocated();
5425   return getNumberOfTuples()==0;
5426 }
5427
5428 /*!
5429  * Returns a full copy of \a this. For more info on copying data arrays see
5430  * \ref MEDCouplingArrayBasicsCopyDeep.
5431  *  \return DataArrayInt * - a new instance of DataArrayInt.
5432  */
5433 DataArrayInt *DataArrayInt::deepCpy() const throw(INTERP_KERNEL::Exception)
5434 {
5435   return new DataArrayInt(*this);
5436 }
5437
5438 /*!
5439  * Returns either a \a deep or \a shallow copy of this array. For more info see
5440  * \ref MEDCouplingArrayBasicsCopyDeep and \ref MEDCouplingArrayBasicsCopyShallow.
5441  *  \param [in] dCpy - if \a true, a deep copy is returned, else, a shallow one.
5442  *  \return DataArrayInt * - either a new instance of DataArrayInt (if \a dCpy
5443  *          == \a true) or \a this instance (if \a dCpy == \a false).
5444  */
5445 DataArrayInt *DataArrayInt::performCpy(bool dCpy) const throw(INTERP_KERNEL::Exception)
5446 {
5447   if(dCpy)
5448     return deepCpy();
5449   else
5450     {
5451       incrRef();
5452       return const_cast<DataArrayInt *>(this);
5453     }
5454 }
5455
5456 /*!
5457  * Copies all the data from another DataArrayInt. For more info see
5458  * \ref MEDCouplingArrayBasicsCopyDeepAssign.
5459  *  \param [in] other - another instance of DataArrayInt to copy data from.
5460  *  \throw If the \a other is not allocated.
5461  */
5462 void DataArrayInt::cpyFrom(const DataArrayInt& other) throw(INTERP_KERNEL::Exception)
5463 {
5464   other.checkAllocated();
5465   int nbOfTuples=other.getNumberOfTuples();
5466   int nbOfComp=other.getNumberOfComponents();
5467   allocIfNecessary(nbOfTuples,nbOfComp);
5468   std::size_t nbOfElems=(std::size_t)nbOfTuples*nbOfComp;
5469   int *pt=getPointer();
5470   const int *ptI=other.getConstPointer();
5471   for(std::size_t i=0;i<nbOfElems;i++)
5472     pt[i]=ptI[i];
5473   copyStringInfoFrom(other);
5474 }
5475
5476 /*!
5477  * This method reserve nbOfElems elements in memory ( nbOfElems*4 bytes ) \b without impacting the number of tuples in \a this.
5478  * If \a this has already been allocated, this method checks that \a this has only one component. If not an INTERP_KERNEL::Exception will be thrown.
5479  * If \a this has not already been allocated, number of components is set to one.
5480  * This method allows to reduce number of reallocations on invokation of DataArrayInt::pushBackSilent and DataArrayInt::pushBackValsSilent on \a this.
5481  * 
5482  * \sa DataArrayInt::pack, DataArrayInt::pushBackSilent, DataArrayInt::pushBackValsSilent
5483  */
5484 void DataArrayInt::reserve(std::size_t nbOfElems) throw(INTERP_KERNEL::Exception)
5485 {
5486   int nbCompo=getNumberOfComponents();
5487   if(nbCompo==1)
5488     {
5489       _mem.reserve(nbOfElems);
5490     }
5491   else if(nbCompo==0)
5492     {
5493       _mem.reserve(nbOfElems);
5494       _info_on_compo.resize(1);
5495     }
5496   else
5497     throw INTERP_KERNEL::Exception("DataArrayInt::reserve : not available for DataArrayInt with number of components different than 1 !");
5498 }
5499
5500 /*!
5501  * This method adds at the end of \a this the single value \a val. This method do \b not update its time label to avoid useless incrementation
5502  * of counter. So the caller is expected to call TimeLabel::declareAsNew on \a this at the end of the push session.
5503  *
5504  * \param [in] val the value to be added in \a this
5505  * \throw If \a this has already been allocated with number of components different from one.
5506  * \sa DataArrayInt::pushBackValsSilent
5507  */
5508 void DataArrayInt::pushBackSilent(int val) throw(INTERP_KERNEL::Exception)
5509 {
5510   int nbCompo=getNumberOfComponents();
5511   if(nbCompo==1)
5512     _mem.pushBack(val);
5513   else if(nbCompo==0)
5514     {
5515       _info_on_compo.resize(1);
5516       _mem.pushBack(val);
5517     }
5518   else
5519     throw INTERP_KERNEL::Exception("DataArrayInt::pushBackSilent : not available for DataArrayInt with number of components different than 1 !");
5520 }
5521
5522 /*!
5523  * This method adds at the end of \a this a serie of values [\c valsBg,\c valsEnd). This method do \b not update its time label to avoid useless incrementation
5524  * of counter. So the caller is expected to call TimeLabel::declareAsNew on \a this at the end of the push session.
5525  *
5526  *  \param [in] valsBg - an array of values to push at the end of \this.
5527  *  \param [in] valsEnd - specifies the end of the array \a valsBg, so that
5528  *              the last value of \a valsBg is \a valsEnd[ -1 ].
5529  * \throw If \a this has already been allocated with number of components different from one.
5530  * \sa DataArrayInt::pushBackSilent
5531  */
5532 void DataArrayInt::pushBackValsSilent(const int *valsBg, const int *valsEnd) throw(INTERP_KERNEL::Exception)
5533 {
5534   int nbCompo=getNumberOfComponents();
5535   if(nbCompo==1)
5536     _mem.insertAtTheEnd(valsBg,valsEnd);
5537   else if(nbCompo==0)
5538     {
5539       _info_on_compo.resize(1);
5540       _mem.insertAtTheEnd(valsBg,valsEnd);
5541     }
5542   else
5543     throw INTERP_KERNEL::Exception("DataArrayInt::pushBackValsSilent : not available for DataArrayInt with number of components different than 1 !");
5544 }
5545
5546 /*!
5547  * This method returns silently ( without updating time label in \a this ) the last value, if any and suppress it.
5548  * \throw If \a this is already empty.
5549  * \throw If \a this has number of components different from one.
5550  */
5551 int DataArrayInt::popBackSilent() throw(INTERP_KERNEL::Exception)
5552 {
5553   if(getNumberOfComponents()==1)
5554     return _mem.popBack();
5555   else
5556     throw INTERP_KERNEL::Exception("DataArrayInt::popBackSilent : not available for DataArrayInt with number of components different than 1 !");
5557 }
5558
5559 /*!
5560  * This method \b do \b not modify content of \a this. It only modify its memory footprint if the allocated memory is to high regarding real data to store.
5561  *
5562  * \sa DataArrayInt::getHeapMemorySize, DataArrayInt::reserve
5563  */
5564 void DataArrayInt::pack() const throw(INTERP_KERNEL::Exception)
5565 {
5566   _mem.pack();
5567 }
5568
5569 /*!
5570  * Allocates the raw data in memory. If exactly as same memory as needed already
5571  * allocated, it is not re-allocated.
5572  *  \param [in] nbOfTuple - number of tuples of data to allocate.
5573  *  \param [in] nbOfCompo - number of components of data to allocate.
5574  *  \throw If \a nbOfTuple < 0 or \a nbOfCompo < 0.
5575  */
5576 void DataArrayInt::allocIfNecessary(int nbOfTuple, int nbOfCompo) throw(INTERP_KERNEL::Exception)
5577 {
5578   if(isAllocated())
5579     {
5580       if(nbOfTuple!=getNumberOfTuples() || nbOfCompo!=getNumberOfComponents())
5581         alloc(nbOfTuple,nbOfCompo);
5582     }
5583   else
5584     alloc(nbOfTuple,nbOfCompo);
5585 }
5586
5587 /*!
5588  * Allocates the raw data in memory. If the memory was already allocated, then it is
5589  * freed and re-allocated. See an example of this method use
5590  * \ref MEDCouplingArraySteps1WC "here".
5591  *  \param [in] nbOfTuple - number of tuples of data to allocate.
5592  *  \param [in] nbOfCompo - number of components of data to allocate.
5593  *  \throw If \a nbOfTuple < 0 or \a nbOfCompo < 0.
5594  */
5595 void DataArrayInt::alloc(int nbOfTuple, int nbOfCompo) throw(INTERP_KERNEL::Exception)
5596 {
5597   if(nbOfTuple<0 || nbOfCompo<0)
5598     throw INTERP_KERNEL::Exception("DataArrayInt::alloc : request for negative length of data !");
5599   _info_on_compo.resize(nbOfCompo);
5600   _mem.alloc(nbOfCompo*(std::size_t)nbOfTuple);
5601   declareAsNew();
5602 }
5603
5604 /*!
5605  * Assign zero to all values in \a this array. To know more on filling arrays see
5606  * \ref MEDCouplingArrayFill.
5607  * \throw If \a this is not allocated.
5608  */
5609 void DataArrayInt::fillWithZero() throw(INTERP_KERNEL::Exception)
5610 {
5611   checkAllocated();
5612   _mem.fillWithValue(0);
5613   declareAsNew();
5614 }
5615
5616 /*!
5617  * Assign \a val to all values in \a this array. To know more on filling arrays see
5618  * \ref MEDCouplingArrayFill.
5619  *  \param [in] val - the value to fill with.
5620  *  \throw If \a this is not allocated.
5621  */
5622 void DataArrayInt::fillWithValue(int val) throw(INTERP_KERNEL::Exception)
5623 {
5624   checkAllocated();
5625   _mem.fillWithValue(val);
5626   declareAsNew();
5627 }
5628
5629 /*!
5630  * Set all values in \a this array so that the i-th element equals to \a init + i
5631  * (i starts from zero). To know more on filling arrays see \ref MEDCouplingArrayFill.
5632  *  \param [in] init - value to assign to the first element of array.
5633  *  \throw If \a this->getNumberOfComponents() != 1
5634  *  \throw If \a this is not allocated.
5635  */
5636 void DataArrayInt::iota(int init) throw(INTERP_KERNEL::Exception)
5637 {
5638   checkAllocated();
5639   if(getNumberOfComponents()!=1)
5640     throw INTERP_KERNEL::Exception("DataArrayInt::iota : works only for arrays with only one component, you can call 'rearrange' method before !");
5641   int *ptr=getPointer();
5642   int ntuples=getNumberOfTuples();
5643   for(int i=0;i<ntuples;i++)
5644     ptr[i]=init+i;
5645   declareAsNew();
5646 }
5647
5648 /*!
5649  * Returns a textual and human readable representation of \a this instance of
5650  * DataArrayInt. This text is shown when a DataArrayInt is printed in Python.
5651  *  \return std::string - text describing \a this DataArrayInt.
5652  */
5653 std::string DataArrayInt::repr() const throw(INTERP_KERNEL::Exception)
5654 {
5655   std::ostringstream ret;
5656   reprStream(ret);
5657   return ret.str();
5658 }
5659
5660 std::string DataArrayInt::reprZip() const throw(INTERP_KERNEL::Exception)
5661 {
5662   std::ostringstream ret;
5663   reprZipStream(ret);
5664   return ret.str();
5665 }
5666
5667 void DataArrayInt::writeVTK(std::ostream& ofs, int indent, const char *type, const char *nameInFile) const throw(INTERP_KERNEL::Exception)
5668 {
5669   checkAllocated();
5670   std::string idt(indent,' ');
5671   ofs << idt << "<DataArray type=\"" << type << "\" Name=\"" << nameInFile << "\" NumberOfComponents=\"" << getNumberOfComponents() << "\"";
5672   ofs << " format=\"ascii\" RangeMin=\"" << getMinValueInArray() << "\" RangeMax=\"" << getMaxValueInArray() << "\">\n" << idt;
5673   std::copy(begin(),end(),std::ostream_iterator<int>(ofs," "));
5674   ofs << std::endl << idt << "</DataArray>\n";
5675 }
5676
5677 void DataArrayInt::reprStream(std::ostream& stream) const throw(INTERP_KERNEL::Exception)
5678 {
5679   stream << "Name of int array : \"" << _name << "\"\n";
5680   reprWithoutNameStream(stream);
5681 }
5682
5683 void DataArrayInt::reprZipStream(std::ostream& stream) const throw(INTERP_KERNEL::Exception)
5684 {
5685   stream << "Name of int array : \"" << _name << "\"\n";
5686   reprZipWithoutNameStream(stream);
5687 }
5688
5689 void DataArrayInt::reprWithoutNameStream(std::ostream& stream) const throw(INTERP_KERNEL::Exception)
5690 {
5691   DataArray::reprWithoutNameStream(stream);
5692   _mem.repr(getNumberOfComponents(),stream);
5693 }
5694
5695 void DataArrayInt::reprZipWithoutNameStream(std::ostream& stream) const throw(INTERP_KERNEL::Exception)
5696 {
5697   DataArray::reprWithoutNameStream(stream);
5698   _mem.reprZip(getNumberOfComponents(),stream);
5699 }
5700
5701 void DataArrayInt::reprCppStream(const char *varName, std::ostream& stream) const throw(INTERP_KERNEL::Exception)
5702 {
5703   int nbTuples=getNumberOfTuples(),nbComp=getNumberOfComponents();
5704   const int *data=getConstPointer();
5705   stream << "DataArrayInt *" << varName << "=DataArrayInt::New();" << std::endl;
5706   if(nbTuples*nbComp>=1)
5707     {
5708       stream << "const int " << varName << "Data[" << nbTuples*nbComp << "]={";
5709       std::copy(data,data+nbTuples*nbComp-1,std::ostream_iterator<int>(stream,","));
5710       stream << data[nbTuples*nbComp-1] << "};" << std::endl;
5711       stream << varName << "->useArray(" << varName << "Data,false,CPP_DEALLOC," << nbTuples << "," << nbComp << ");" << std::endl;
5712     }
5713   else
5714     stream << varName << "->alloc(" << nbTuples << "," << nbComp << ");" << std::endl;
5715   stream << varName << "->setName(\"" << getName() << "\");" << std::endl;
5716 }
5717
5718 /*!
5719  * Method that gives a quick overvien of \a this for python.
5720  */
5721 void DataArrayInt::reprQuickOverview(std::ostream& stream) const throw(INTERP_KERNEL::Exception)
5722 {
5723   static const std::size_t MAX_NB_OF_BYTE_IN_REPR=300;
5724   stream << "DataArrayInt C++ instance at " << this << ". ";
5725   if(isAllocated())
5726     {
5727       int nbOfCompo=(int)_info_on_compo.size();
5728       if(nbOfCompo>=1)
5729         {
5730           int nbOfTuples=getNumberOfTuples();
5731           stream << "Number of tuples : " << nbOfTuples << ". Number of components : " << nbOfCompo << "." << std::endl;
5732           reprQuickOverviewData(stream,MAX_NB_OF_BYTE_IN_REPR);
5733         }
5734       else
5735         stream << "Number of components : 0.";
5736     }
5737   else
5738     stream << "*** No data allocated ****";
5739 }
5740
5741 void DataArrayInt::reprQuickOverviewData(std::ostream& stream, std::size_t maxNbOfByteInRepr) const throw(INTERP_KERNEL::Exception)
5742 {
5743   const int *data=begin();
5744   int nbOfTuples=getNumberOfTuples();
5745   int nbOfCompo=(int)_info_on_compo.size();
5746   std::ostringstream oss2; oss2 << "[";
5747   std::string oss2Str(oss2.str());
5748   bool isFinished=true;
5749   for(int i=0;i<nbOfTuples && isFinished;i++)
5750     {
5751       if(nbOfCompo>1)
5752         {
5753           oss2 << "(";
5754           for(int j=0;j<nbOfCompo;j++,data++)
5755             {
5756               oss2 << *data;
5757               if(j!=nbOfCompo-1) oss2 << ", ";
5758             }
5759           oss2 << ")";
5760         }
5761       else
5762         oss2 << *data++;
5763       if(i!=nbOfTuples-1) oss2 << ", ";
5764       std::string oss3Str(oss2.str());
5765       if(oss3Str.length()<maxNbOfByteInRepr)
5766         oss2Str=oss3Str;
5767       else
5768         isFinished=false;
5769     }
5770   stream << oss2Str;
5771   if(!isFinished)
5772     stream << "... ";
5773   stream << "]";
5774 }
5775
5776 /*!
5777  * Modifies \a this one-dimensional array so that each value \a v = \a indArrBg[ \a v ],
5778  * i.e. a current value is used as in index to get a new value from \a indArrBg.
5779  *  \param [in] indArrBg - pointer to the first element of array of new values to assign
5780  *         to \a this array.
5781  *  \param [in] indArrEnd - specifies the end of the array \a indArrBg, so that
5782  *              the last value of \a indArrBg is \a indArrEnd[ -1 ].
5783  *  \throw If \a this->getNumberOfComponents() != 1
5784  *  \throw If any value of \a this can't be used as a valid index for 
5785  *         [\a indArrBg, \a indArrEnd).
5786  */
5787 void DataArrayInt::transformWithIndArr(const int *indArrBg, const int *indArrEnd) throw(INTERP_KERNEL::Exception)
5788 {
5789   checkAllocated();
5790   if(getNumberOfComponents()!=1)
5791     throw INTERP_KERNEL::Exception("Call transformWithIndArr method on DataArrayInt with only one component, you can call 'rearrange' method before !");
5792   int nbElemsIn=(int)std::distance(indArrBg,indArrEnd);
5793   int nbOfTuples=getNumberOfTuples();
5794   int *pt=getPointer();
5795   for(int i=0;i<nbOfTuples;i++,pt++)
5796     {
5797       if(*pt>=0 && *pt<nbElemsIn)
5798         *pt=indArrBg[*pt];
5799       else
5800         {
5801           std::ostringstream oss; oss << "DataArrayInt::transformWithIndArr : error on tuple #" << i << " value is " << *pt << " and indirectionnal array as a size equal to " << nbElemsIn;
5802           throw INTERP_KERNEL::Exception(oss.str().c_str());
5803         }
5804     }
5805   declareAsNew();
5806 }
5807
5808 /*!
5809  * Computes distribution of values of \a this one-dimensional array between given value
5810  * ranges (casts). This method is typically useful for entity number spliting by types,
5811  * for example. 
5812  *  \warning The values contained in \a arrBg should be sorted ascendently. No
5813  *           check of this is be done. If not, the result is not warranted. 
5814  *  \param [in] arrBg - the array of ascending values defining the value ranges. The i-th
5815  *         value of \a arrBg (\a arrBg[ i ]) gives the lowest value of the i-th range,
5816  *         and the greatest value of the i-th range equals to \a arrBg[ i+1 ] - 1. \a
5817  *         arrBg containing \a n values defines \a n-1 ranges. The last value of \a arrBg
5818  *         should be more than every value in \a this array.
5819  *  \param [in] arrEnd - specifies the end of the array \a arrBg, so that
5820  *              the last value of \a arrBg is \a arrEnd[ -1 ].
5821  *  \param [out] castArr - a new instance of DataArrayInt, of same size as \a this array
5822  *         (same number of tuples and components), the caller is to delete 
5823  *         using decrRef() as it is no more needed.
5824  *         This array contains indices of ranges for every value of \a this array. I.e.
5825  *         the i-th value of \a castArr gives the index of range the i-th value of \a this
5826  *         belongs to. Or, in other words, this parameter contains for each tuple in \a
5827  *         this in which cast it holds.
5828  *  \param [out] rankInsideCast - a new instance of DataArrayInt, of same size as \a this
5829  *         array, the caller is to delete using decrRef() as it is no more needed.
5830  *         This array contains ranks of values of \a this array within ranges
5831  *         they belongs to. I.e. the i-th value of \a rankInsideCast gives the rank of
5832  *         the i-th value of \a this array within the \a castArr[ i ]-th range, to which
5833  *         the i-th value of \a this belongs to. Or, in other words, this param contains 
5834  *         for each tuple its rank inside its cast. The rank is computed as difference
5835  *         between the value and the lowest value of range.
5836  *  \param [out] castsPresent - a new instance of DataArrayInt, containing indices of
5837  *         ranges (casts) to which at least one value of \a this array belongs.
5838  *         Or, in other words, this param contains the casts that \a this contains.
5839  *         The caller is to delete this array using decrRef() as it is no more needed.
5840  *
5841  * \b Example: If \a this contains [6,5,0,3,2,7,8,1,4] and \a arrBg contains [0,4,9] then
5842  *            the output of this method will be : 
5843  * - \a castArr       : [1,1,0,0,0,1,1,0,1]
5844  * - \a rankInsideCast: [2,1,0,3,2,3,4,1,0]
5845  * - \a castsPresent  : [0,1]
5846  *
5847  * I.e. values of \a this array belong to 2 ranges: #0 and #1. Value 6 belongs to the
5848  * range #1 and its rank within this range is 2; etc.
5849  *
5850  *  \throw If \a this->getNumberOfComponents() != 1.
5851  *  \throw If \a arrEnd - arrBg < 2.
5852  *  \throw If any value of \a this is not less than \a arrEnd[-1].
5853  */
5854 void DataArrayInt::splitByValueRange(const int *arrBg, const int *arrEnd,
5855                                      DataArrayInt *& castArr, DataArrayInt *& rankInsideCast, DataArrayInt *& castsPresent) const throw(INTERP_KERNEL::Exception)
5856 {
5857   checkAllocated();
5858   if(getNumberOfComponents()!=1)
5859     throw INTERP_KERNEL::Exception("Call splitByValueRange  method on DataArrayInt with only one component, you can call 'rearrange' method before !");
5860   int nbOfTuples=getNumberOfTuples();
5861   std::size_t nbOfCast=std::distance(arrBg,arrEnd);
5862   if(nbOfCast<2)
5863     throw INTERP_KERNEL::Exception("DataArrayInt::splitByValueRange : The input array giving the cast range values should be of size >=2 !");
5864   nbOfCast--;
5865   const int *work=getConstPointer();
5866   typedef std::reverse_iterator<const int *> rintstart;
5867   rintstart bg(arrEnd);//OK no problem because size of 'arr' is greater or equal 2
5868   rintstart end2(arrBg);
5869   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret1=DataArrayInt::New();
5870   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret2=DataArrayInt::New();
5871   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret3=DataArrayInt::New();
5872   ret1->alloc(nbOfTuples,1);
5873   ret2->alloc(nbOfTuples,1);
5874   int *ret1Ptr=ret1->getPointer();
5875   int *ret2Ptr=ret2->getPointer();
5876   std::set<std::size_t> castsDetected;
5877   for(int i=0;i<nbOfTuples;i++)
5878     {
5879       rintstart res=std::find_if(bg,end2,std::bind2nd(std::less_equal<int>(), work[i]));
5880       std::size_t pos=std::distance(bg,res);
5881       std::size_t pos2=nbOfCast-pos;
5882       if(pos2<nbOfCast)
5883         {
5884           ret1Ptr[i]=(int)pos2;
5885           ret2Ptr[i]=work[i]-arrBg[pos2];
5886           castsDetected.insert(pos2);
5887         }
5888       else
5889         {
5890           std::ostringstream oss; oss << "DataArrayInt::splitByValueRange : At rank #" << i << " the value is " << work[i] << " whereas the last value is " << *bg;
5891           throw INTERP_KERNEL::Exception(oss.str().c_str());
5892         }
5893     }
5894   ret3->alloc((int)castsDetected.size(),1);
5895   std::copy(castsDetected.begin(),castsDetected.end(),ret3->getPointer());
5896   castArr=ret1.retn();
5897   rankInsideCast=ret2.retn();
5898   castsPresent=ret3.retn();
5899 }
5900
5901 /*!
5902  * Creates a one-dimensional DataArrayInt (\a res) whose contents are computed from 
5903  * values of \a this (\a a) and the given (\a indArr) arrays as follows:
5904  * \a res[ \a indArr[ \a a[ i ]]] = i. I.e. for each value in place i \a v = \a a[ i ],
5905  * new value in place \a indArr[ \a v ] is i.
5906  *  \param [in] indArrBg - the array holding indices within the result array to assign
5907  *         indices of values of \a this array pointing to values of \a indArrBg.
5908  *  \param [in] indArrEnd - specifies the end of the array \a indArrBg, so that
5909  *              the last value of \a indArrBg is \a indArrEnd[ -1 ].
5910  *  \return DataArrayInt * - the new instance of DataArrayInt.
5911  *          The caller is to delete this result array using decrRef() as it is no more
5912  *          needed.
5913  *  \throw If \a this->getNumberOfComponents() != 1.
5914  *  \throw If any value of \a this array is not a valid index for \a indArrBg array.
5915  *  \throw If any value of \a indArrBg is not a valid index for \a this array.
5916  */
5917 DataArrayInt *DataArrayInt::transformWithIndArrR(const int *indArrBg, const int *indArrEnd) const throw(INTERP_KERNEL::Exception)
5918 {
5919   checkAllocated();
5920   if(getNumberOfComponents()!=1)
5921     throw INTERP_KERNEL::Exception("Call transformWithIndArrR method on DataArrayInt with only one component, you can call 'rearrange' method before !");
5922   int nbElemsIn=(int)std::distance(indArrBg,indArrEnd);
5923   int nbOfTuples=getNumberOfTuples();
5924   const int *pt=getConstPointer();
5925   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
5926   ret->alloc(nbOfTuples,1);
5927   ret->fillWithValue(-1);
5928   int *tmp=ret->getPointer();
5929   for(int i=0;i<nbOfTuples;i++,pt++)
5930     {
5931       if(*pt>=0 && *pt<nbElemsIn)
5932         {
5933           int pos=indArrBg[*pt];
5934           if(pos>=0 && pos<nbOfTuples)
5935             tmp[pos]=i;
5936           else
5937             {
5938               std::ostringstream oss; oss << "DataArrayInt::transformWithIndArrR : error on tuple #" << i << " value of new pos is " << pos << " ( indArrBg[" << *pt << "]) ! Should be in [0," << nbOfTuples << ") !";
5939               throw INTERP_KERNEL::Exception(oss.str().c_str());
5940             }
5941         }
5942       else
5943         {
5944           std::ostringstream oss; oss << "DataArrayInt::transformWithIndArrR : error on tuple #" << i << " value is " << *pt << " and indirectionnal array as a size equal to " << nbElemsIn << " !";
5945           throw INTERP_KERNEL::Exception(oss.str().c_str());
5946         }
5947     }
5948   return ret.retn();
5949 }
5950
5951 /*!
5952  * Creates a one-dimensional DataArrayInt of given length, whose contents are computed
5953  * from values of \a this array, which is supposed to contain a renumbering map in 
5954  * "Old to New" mode. The result array contains a renumbering map in "New to Old" mode.
5955  * To know how to use the renumbering maps see \ref MEDCouplingArrayRenumbering.
5956  *  \param [in] newNbOfElem - the number of tuples in the result array.
5957  *  \return DataArrayInt * - the new instance of DataArrayInt.
5958  *          The caller is to delete this result array using decrRef() as it is no more
5959  *          needed.
5960  * 
5961  *  \ref cpp_mcdataarrayint_invertarrayo2n2n2o "Here is a C++ example".<br>
5962  *  \ref py_mcdataarrayint_invertarrayo2n2n2o  "Here is a Python example".
5963  */
5964 DataArrayInt *DataArrayInt::invertArrayO2N2N2O(int newNbOfElem) const
5965 {
5966   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
5967   ret->alloc(newNbOfElem,1);
5968   int nbOfOldNodes=getNumberOfTuples();
5969   const int *old2New=getConstPointer();
5970   int *pt=ret->getPointer();
5971   for(int i=0;i!=nbOfOldNodes;i++)
5972     if(old2New[i]!=-1)
5973       pt[old2New[i]]=i;
5974   return ret.retn();
5975 }
5976
5977 /*!
5978  * This method is similar to DataArrayInt::invertArrayO2N2N2O except that 
5979  * Example : If \a this contains [0,1,2,0,3,4,5,4,6,4] this method will return [0,1,2,4,5,6,8] whereas DataArrayInt::invertArrayO2N2N2O returns [3,1,2,4,9,6,8]
5980  */
5981 DataArrayInt *DataArrayInt::invertArrayO2N2N2OBis(int newNbOfElem) const throw(INTERP_KERNEL::Exception)
5982 {
5983   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
5984   ret->alloc(newNbOfElem,1);
5985   int nbOfOldNodes=getNumberOfTuples();
5986   const int *old2New=getConstPointer();
5987   int *pt=ret->getPointer();
5988   for(int i=nbOfOldNodes-1;i>=0;i--)
5989     if(old2New[i]!=-1)
5990       pt[old2New[i]]=i;
5991   return ret.retn();
5992 }
5993
5994 /*!
5995  * Creates a one-dimensional DataArrayInt of given length, whose contents are computed
5996  * from values of \a this array, which is supposed to contain a renumbering map in 
5997  * "New to Old" mode. The result array contains a renumbering map in "Old to New" mode.
5998  * To know how to use the renumbering maps see \ref MEDCouplingArrayRenumbering.
5999  *  \param [in] newNbOfElem - the number of tuples in the result array.
6000  *  \return DataArrayInt * - the new instance of DataArrayInt.
6001  *          The caller is to delete this result array using decrRef() as it is no more
6002  *          needed.
6003  * 
6004  *  \ref cpp_mcdataarrayint_invertarrayn2o2o2n "Here is a C++ example".
6005  *
6006  *  \ref py_mcdataarrayint_invertarrayn2o2o2n "Here is a Python example".
6007  */
6008 DataArrayInt *DataArrayInt::invertArrayN2O2O2N(int oldNbOfElem) const
6009 {
6010   checkAllocated();
6011   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6012   ret->alloc(oldNbOfElem,1);
6013   const int *new2Old=getConstPointer();
6014   int *pt=ret->getPointer();
6015   std::fill(pt,pt+oldNbOfElem,-1);
6016   int nbOfNewElems=getNumberOfTuples();
6017   for(int i=0;i<nbOfNewElems;i++)
6018     pt[new2Old[i]]=i;
6019   return ret.retn();
6020 }
6021
6022 /*!
6023  * Equivalent to DataArrayInt::isEqual except that if false the reason of
6024  * mismatch is given.
6025  * 
6026  * \param [in] other the instance to be compared with \a this
6027  * \param [out] reason In case of inequality returns the reason.
6028  * \sa DataArrayInt::isEqual
6029  */
6030 bool DataArrayInt::isEqualIfNotWhy(const DataArrayInt& other, std::string& reason) const throw(INTERP_KERNEL::Exception)
6031 {
6032   if(!areInfoEqualsIfNotWhy(other,reason))
6033     return false;
6034   return _mem.isEqual(other._mem,0,reason);
6035 }
6036
6037 /*!
6038  * Checks if \a this and another DataArrayInt are fully equal. For more info see
6039  * \ref MEDCouplingArrayBasicsCompare.
6040  *  \param [in] other - an instance of DataArrayInt to compare with \a this one.
6041  *  \return bool - \a true if the two arrays are equal, \a false else.
6042  */
6043 bool DataArrayInt::isEqual(const DataArrayInt& other) const throw(INTERP_KERNEL::Exception)
6044 {
6045   std::string tmp;
6046   return isEqualIfNotWhy(other,tmp);
6047 }
6048
6049 /*!
6050  * Checks if values of \a this and another DataArrayInt are equal. For more info see
6051  * \ref MEDCouplingArrayBasicsCompare.
6052  *  \param [in] other - an instance of DataArrayInt to compare with \a this one.
6053  *  \return bool - \a true if the values of two arrays are equal, \a false else.
6054  */
6055 bool DataArrayInt::isEqualWithoutConsideringStr(const DataArrayInt& other) const throw(INTERP_KERNEL::Exception)
6056 {
6057   std::string tmp;
6058   return _mem.isEqual(other._mem,0,tmp);
6059 }
6060
6061 /*!
6062  * Checks if values of \a this and another DataArrayInt are equal. Comparison is
6063  * performed on sorted value sequences.
6064  * For more info see\ref MEDCouplingArrayBasicsCompare.
6065  *  \param [in] other - an instance of DataArrayInt to compare with \a this one.
6066  *  \return bool - \a true if the sorted values of two arrays are equal, \a false else.
6067  */
6068 bool DataArrayInt::isEqualWithoutConsideringStrAndOrder(const DataArrayInt& other) const throw(INTERP_KERNEL::Exception)
6069 {
6070   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> a=deepCpy();
6071   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> b=other.deepCpy();
6072   a->sort();
6073   b->sort();
6074   return a->isEqualWithoutConsideringStr(*b);
6075 }
6076
6077 /*!
6078  * Sorts values of the array.
6079  *  \param [in] asc - \a true means ascending order, \a false, descending.
6080  *  \throw If \a this is not allocated.
6081  *  \throw If \a this->getNumberOfComponents() != 1.
6082  */
6083 void DataArrayInt::sort(bool asc) throw(INTERP_KERNEL::Exception)
6084 {
6085   checkAllocated();
6086   if(getNumberOfComponents()!=1)
6087     throw INTERP_KERNEL::Exception("DataArrayInt::sort : only supported with 'this' array with ONE component !");
6088   _mem.sort(asc);
6089   declareAsNew();
6090 }
6091
6092 /*!
6093  * Reverse the array values.
6094  *  \throw If \a this->getNumberOfComponents() < 1.
6095  *  \throw If \a this is not allocated.
6096  */
6097 void DataArrayInt::reverse() throw(INTERP_KERNEL::Exception)
6098 {
6099   checkAllocated();
6100   _mem.reverse(getNumberOfComponents());
6101   declareAsNew();
6102 }
6103
6104 /*!
6105  * Checks that \a this array is consistently **increasing** or **decreasing** in value.
6106  * If not an exception is thrown.
6107  *  \param [in] increasing - if \a true, the array values should be increasing.
6108  *  \throw If sequence of values is not strictly monotonic in agreement with \a
6109  *         increasing arg.
6110  *  \throw If \a this->getNumberOfComponents() != 1.
6111  *  \throw If \a this is not allocated.
6112  */
6113 void DataArrayInt::checkMonotonic(bool increasing) const throw(INTERP_KERNEL::Exception)
6114 {
6115   if(!isMonotonic(increasing))
6116     {
6117       if (increasing)
6118         throw INTERP_KERNEL::Exception("DataArrayInt::checkMonotonic : 'this' is not INCREASING monotonic !");
6119       else
6120         throw INTERP_KERNEL::Exception("DataArrayInt::checkMonotonic : 'this' is not DECREASING monotonic !");
6121     }
6122 }
6123
6124 /*!
6125  * Checks that \a this array is consistently **increasing** or **decreasing** in value.
6126  *  \param [in] increasing - if \a true, array values should be increasing.
6127  *  \return bool - \a true if values change in accordance with \a increasing arg.
6128  *  \throw If \a this->getNumberOfComponents() != 1.
6129  *  \throw If \a this is not allocated.
6130  */
6131 bool DataArrayInt::isMonotonic(bool increasing) const throw(INTERP_KERNEL::Exception)
6132 {
6133   checkAllocated();
6134   if(getNumberOfComponents()!=1)
6135     throw INTERP_KERNEL::Exception("DataArrayInt::isMonotonic : only supported with 'this' array with ONE component !");
6136   int nbOfElements=getNumberOfTuples();
6137   const int *ptr=getConstPointer();
6138   if(nbOfElements==0)
6139     return true;
6140   int ref=ptr[0];
6141   if(increasing)
6142     {
6143       for(int i=1;i<nbOfElements;i++)
6144         {
6145           if(ptr[i]>=ref)
6146             ref=ptr[i];
6147           else
6148             return false;
6149         }
6150     }
6151   else
6152     {
6153       for(int i=1;i<nbOfElements;i++)
6154         {
6155           if(ptr[i]<=ref)
6156             ref=ptr[i];
6157           else
6158             return false;
6159         }
6160     }
6161   return true;
6162 }
6163
6164 /*!
6165  * This method check that array consistently INCREASING or DECREASING in value.
6166  */
6167 bool DataArrayInt::isStrictlyMonotonic(bool increasing) const throw(INTERP_KERNEL::Exception)
6168 {
6169   checkAllocated();
6170   if(getNumberOfComponents()!=1)
6171     throw INTERP_KERNEL::Exception("DataArrayInt::isStrictlyMonotonic : only supported with 'this' array with ONE component !");
6172   int nbOfElements=getNumberOfTuples();
6173   const int *ptr=getConstPointer();
6174   if(nbOfElements==0)
6175     return true;
6176   int ref=ptr[0];
6177   if(increasing)
6178     {
6179       for(int i=1;i<nbOfElements;i++)
6180         {
6181           if(ptr[i]>ref)
6182             ref=ptr[i];
6183           else
6184             return false;
6185         }
6186     }
6187   else
6188     {
6189       for(int i=1;i<nbOfElements;i++)
6190         {
6191           if(ptr[i]<ref)
6192             ref=ptr[i];
6193           else
6194             return false;
6195         }
6196     }
6197   return true;
6198 }
6199
6200 /*!
6201  * This method check that array consistently INCREASING or DECREASING in value.
6202  */
6203 void DataArrayInt::checkStrictlyMonotonic(bool increasing) const throw(INTERP_KERNEL::Exception)
6204 {
6205   if(!isStrictlyMonotonic(increasing))
6206     {
6207       if (increasing)
6208         throw INTERP_KERNEL::Exception("DataArrayInt::checkStrictlyMonotonic : 'this' is not strictly INCREASING monotonic !");
6209       else
6210         throw INTERP_KERNEL::Exception("DataArrayInt::checkStrictlyMonotonic : 'this' is not strictly DECREASING monotonic !");
6211     }
6212 }
6213
6214 /*!
6215  * Creates a new one-dimensional DataArrayInt of the same size as \a this and a given
6216  * one-dimensional arrays that must be of the same length. The result array describes
6217  * correspondence between \a this and \a other arrays, so that 
6218  * <em> other.getIJ(i,0) == this->getIJ(ret->getIJ(i),0)</em>. If such a permutation is
6219  * not possible because some element in \a other is not in \a this, an exception is thrown.
6220  *  \param [in] other - an array to compute permutation to.
6221  *  \return DataArrayInt * - a new instance of DataArrayInt, which is a permutation array
6222  * from \a this to \a other. The caller is to delete this array using decrRef() as it is
6223  * no more needed.
6224  *  \throw If \a this->getNumberOfComponents() != 1.
6225  *  \throw If \a other->getNumberOfComponents() != 1.
6226  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples().
6227  *  \throw If \a other includes a value which is not in \a this array.
6228  * 
6229  *  \ref cpp_mcdataarrayint_buildpermutationarr "Here is a C++ example".
6230  *
6231  *  \ref py_mcdataarrayint_buildpermutationarr "Here is a Python example".
6232  */
6233 DataArrayInt *DataArrayInt::buildPermutationArr(const DataArrayInt& other) const throw(INTERP_KERNEL::Exception)
6234 {
6235   checkAllocated();
6236   if(getNumberOfComponents()!=1 || other.getNumberOfComponents()!=1)
6237     throw INTERP_KERNEL::Exception("DataArrayInt::buildPermutationArr : 'this' and 'other' have to have exactly ONE component !");
6238   int nbTuple=getNumberOfTuples();
6239   other.checkAllocated();
6240   if(nbTuple!=other.getNumberOfTuples())
6241     throw INTERP_KERNEL::Exception("DataArrayInt::buildPermutationArr : 'this' and 'other' must have the same number of tuple !");
6242   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6243   ret->alloc(nbTuple,1);
6244   ret->fillWithValue(-1);
6245   const int *pt=getConstPointer();
6246   std::map<int,int> mm;
6247   for(int i=0;i<nbTuple;i++)
6248     mm[pt[i]]=i;
6249   pt=other.getConstPointer();
6250   int *retToFill=ret->getPointer();
6251   for(int i=0;i<nbTuple;i++)
6252     {
6253       std::map<int,int>::const_iterator it=mm.find(pt[i]);
6254       if(it==mm.end())
6255         {
6256           std::ostringstream oss; oss << "DataArrayInt::buildPermutationArr : Arrays mismatch : element (" << pt[i] << ") in 'other' not findable in 'this' !";
6257           throw INTERP_KERNEL::Exception(oss.str().c_str());
6258         }
6259       retToFill[i]=(*it).second;
6260     }
6261   return ret.retn();
6262 }
6263
6264 /*!
6265  * Sets a C array to be used as raw data of \a this. The previously set info
6266  *  of components is retained and re-sized. 
6267  * For more info see \ref MEDCouplingArraySteps1.
6268  *  \param [in] array - the C array to be used as raw data of \a this.
6269  *  \param [in] ownership - if \a true, \a array will be deallocated at destruction of \a this.
6270  *  \param [in] type - specifies how to deallocate \a array. If \a type == ParaMEDMEM::CPP_DEALLOC,
6271  *                     \c delete [] \c array; will be called. If \a type == ParaMEDMEM::C_DEALLOC,
6272  *                     \c free(\c array ) will be called.
6273  *  \param [in] nbOfTuple - new number of tuples in \a this.
6274  *  \param [in] nbOfCompo - new number of components in \a this.
6275  */
6276 void DataArrayInt::useArray(const int *array, bool ownership,  DeallocType type, int nbOfTuple, int nbOfCompo) throw(INTERP_KERNEL::Exception)
6277 {
6278   _info_on_compo.resize(nbOfCompo);
6279   _mem.useArray(array,ownership,type,nbOfTuple*nbOfCompo);
6280   declareAsNew();
6281 }
6282
6283 void DataArrayInt::useExternalArrayWithRWAccess(const int *array, int nbOfTuple, int nbOfCompo) throw(INTERP_KERNEL::Exception)
6284 {
6285   _info_on_compo.resize(nbOfCompo);
6286   _mem.useExternalArrayWithRWAccess(array,nbOfTuple*nbOfCompo);
6287   declareAsNew();
6288 }
6289
6290 /*!
6291  * Returns a new DataArrayInt holding the same values as \a this array but differently
6292  * arranged in memory. If \a this array holds 2 components of 3 values:
6293  * \f$ x_0,x_1,x_2,y_0,y_1,y_2 \f$, then the result array holds these values arranged
6294  * as follows: \f$ x_0,y_0,x_1,y_1,x_2,y_2 \f$.
6295  *  \warning Do not confuse this method with transpose()!
6296  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
6297  *          is to delete using decrRef() as it is no more needed.
6298  *  \throw If \a this is not allocated.
6299  */
6300 DataArrayInt *DataArrayInt::fromNoInterlace() const throw(INTERP_KERNEL::Exception)
6301 {
6302   checkAllocated();
6303   if(_mem.isNull())
6304     throw INTERP_KERNEL::Exception("DataArrayInt::fromNoInterlace : Not defined array !");
6305   int *tab=_mem.fromNoInterlace(getNumberOfComponents());
6306   DataArrayInt *ret=DataArrayInt::New();
6307   ret->useArray(tab,true,C_DEALLOC,getNumberOfTuples(),getNumberOfComponents());
6308   return ret;
6309 }
6310
6311 /*!
6312  * Returns a new DataArrayInt holding the same values as \a this array but differently
6313  * arranged in memory. If \a this array holds 2 components of 3 values:
6314  * \f$ x_0,y_0,x_1,y_1,x_2,y_2 \f$, then the result array holds these values arranged
6315  * as follows: \f$ x_0,x_1,x_2,y_0,y_1,y_2 \f$.
6316  *  \warning Do not confuse this method with transpose()!
6317  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
6318  *          is to delete using decrRef() as it is no more needed.
6319  *  \throw If \a this is not allocated.
6320  */
6321 DataArrayInt *DataArrayInt::toNoInterlace() const throw(INTERP_KERNEL::Exception)
6322 {
6323   checkAllocated();
6324   if(_mem.isNull())
6325     throw INTERP_KERNEL::Exception("DataArrayInt::toNoInterlace : Not defined array !");
6326   int *tab=_mem.toNoInterlace(getNumberOfComponents());
6327   DataArrayInt *ret=DataArrayInt::New();
6328   ret->useArray(tab,true,C_DEALLOC,getNumberOfTuples(),getNumberOfComponents());
6329   return ret;
6330 }
6331
6332 /*!
6333  * Permutes values of \a this array as required by \a old2New array. The values are
6334  * permuted so that \c new[ \a old2New[ i ]] = \c old[ i ]. Number of tuples remains
6335  * the same as in \this one.
6336  * If a permutation reduction is needed, substr() or selectByTupleId() should be used.
6337  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
6338  *  \param [in] old2New - C array of length equal to \a this->getNumberOfTuples()
6339  *     giving a new position for i-th old value.
6340  */
6341 void DataArrayInt::renumberInPlace(const int *old2New) throw(INTERP_KERNEL::Exception)
6342 {
6343   checkAllocated();
6344   int nbTuples=getNumberOfTuples();
6345   int nbOfCompo=getNumberOfComponents();
6346   int *tmp=new int[nbTuples*nbOfCompo];
6347   const int *iptr=getConstPointer();
6348   for(int i=0;i<nbTuples;i++)
6349     std::copy(iptr+nbOfCompo*i,iptr+nbOfCompo*(i+1),tmp+nbOfCompo*old2New[i]);
6350   std::copy(tmp,tmp+nbTuples*nbOfCompo,getPointer());
6351   delete [] tmp;
6352   declareAsNew();
6353 }
6354
6355 /*!
6356  * Permutes values of \a this array as required by \a new2Old array. The values are
6357  * permuted so that \c new[ i ] = \c old[ \a new2Old[ i ]]. Number of tuples remains
6358  * the same as in \this one.
6359  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
6360  *  \param [in] new2Old - C array of length equal to \a this->getNumberOfTuples()
6361  *     giving a previous position of i-th new value.
6362  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
6363  *          is to delete using decrRef() as it is no more needed.
6364  */
6365 void DataArrayInt::renumberInPlaceR(const int *new2Old) throw(INTERP_KERNEL::Exception)
6366 {
6367   checkAllocated();
6368   int nbTuples=getNumberOfTuples();
6369   int nbOfCompo=getNumberOfComponents();
6370   int *tmp=new int[nbTuples*nbOfCompo];
6371   const int *iptr=getConstPointer();
6372   for(int i=0;i<nbTuples;i++)
6373     std::copy(iptr+nbOfCompo*new2Old[i],iptr+nbOfCompo*(new2Old[i]+1),tmp+nbOfCompo*i);
6374   std::copy(tmp,tmp+nbTuples*nbOfCompo,getPointer());
6375   delete [] tmp;
6376   declareAsNew();
6377 }
6378
6379 /*!
6380  * Returns a copy of \a this array with values permuted as required by \a old2New array.
6381  * The values are permuted so that  \c new[ \a old2New[ i ]] = \c old[ i ].
6382  * Number of tuples in the result array remains the same as in \this one.
6383  * If a permutation reduction is needed, renumberAndReduce() should be used.
6384  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
6385  *  \param [in] old2New - C array of length equal to \a this->getNumberOfTuples()
6386  *          giving a new position for i-th old value.
6387  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
6388  *          is to delete using decrRef() as it is no more needed.
6389  *  \throw If \a this is not allocated.
6390  */
6391 DataArrayInt *DataArrayInt::renumber(const int *old2New) const throw(INTERP_KERNEL::Exception)
6392 {
6393   checkAllocated();
6394   int nbTuples=getNumberOfTuples();
6395   int nbOfCompo=getNumberOfComponents();
6396   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6397   ret->alloc(nbTuples,nbOfCompo);
6398   ret->copyStringInfoFrom(*this);
6399   const int *iptr=getConstPointer();
6400   int *optr=ret->getPointer();
6401   for(int i=0;i<nbTuples;i++)
6402     std::copy(iptr+nbOfCompo*i,iptr+nbOfCompo*(i+1),optr+nbOfCompo*old2New[i]);
6403   ret->copyStringInfoFrom(*this);
6404   return ret.retn();
6405 }
6406
6407 /*!
6408  * Returns a copy of \a this array with values permuted as required by \a new2Old array.
6409  * The values are permuted so that  \c new[ i ] = \c old[ \a new2Old[ i ]]. Number of
6410  * tuples in the result array remains the same as in \this one.
6411  * If a permutation reduction is needed, substr() or selectByTupleId() should be used.
6412  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
6413  *  \param [in] new2Old - C array of length equal to \a this->getNumberOfTuples()
6414  *     giving a previous position of i-th new value.
6415  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
6416  *          is to delete using decrRef() as it is no more needed.
6417  */
6418 DataArrayInt *DataArrayInt::renumberR(const int *new2Old) const throw(INTERP_KERNEL::Exception)
6419 {
6420   checkAllocated();
6421   int nbTuples=getNumberOfTuples();
6422   int nbOfCompo=getNumberOfComponents();
6423   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6424   ret->alloc(nbTuples,nbOfCompo);
6425   ret->copyStringInfoFrom(*this);
6426   const int *iptr=getConstPointer();
6427   int *optr=ret->getPointer();
6428   for(int i=0;i<nbTuples;i++)
6429     std::copy(iptr+nbOfCompo*new2Old[i],iptr+nbOfCompo*(new2Old[i]+1),optr+nbOfCompo*i);
6430   ret->copyStringInfoFrom(*this);
6431   return ret.retn();
6432 }
6433
6434 /*!
6435  * Returns a shorten and permuted copy of \a this array. The new DataArrayInt is
6436  * of size \a newNbOfTuple and it's values are permuted as required by \a old2New array.
6437  * The values are permuted so that  \c new[ \a old2New[ i ]] = \c old[ i ] for all
6438  * \a old2New[ i ] >= 0. In other words every i-th tuple in \a this array, for which 
6439  * \a old2New[ i ] is negative, is missing from the result array.
6440  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
6441  *  \param [in] old2New - C array of length equal to \a this->getNumberOfTuples()
6442  *     giving a new position for i-th old tuple and giving negative position for
6443  *     for i-th old tuple that should be omitted.
6444  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
6445  *          is to delete using decrRef() as it is no more needed.
6446  */
6447 DataArrayInt *DataArrayInt::renumberAndReduce(const int *old2New, int newNbOfTuple) const throw(INTERP_KERNEL::Exception)
6448 {
6449   checkAllocated();
6450   int nbTuples=getNumberOfTuples();
6451   int nbOfCompo=getNumberOfComponents();
6452   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6453   ret->alloc(newNbOfTuple,nbOfCompo);
6454   const int *iptr=getConstPointer();
6455   int *optr=ret->getPointer();
6456   for(int i=0;i<nbTuples;i++)
6457     {
6458       int w=old2New[i];
6459       if(w>=0)
6460         std::copy(iptr+i*nbOfCompo,iptr+(i+1)*nbOfCompo,optr+w*nbOfCompo);
6461     }
6462   ret->copyStringInfoFrom(*this);
6463   return ret.retn();
6464 }
6465
6466 /*!
6467  * Returns a shorten and permuted copy of \a this array. The new DataArrayInt is
6468  * of size \a new2OldEnd - \a new2OldBg and it's values are permuted as required by
6469  * \a new2OldBg array.
6470  * The values are permuted so that  \c new[ i ] = \c old[ \a new2OldBg[ i ]].
6471  * This method is equivalent to renumberAndReduce() except that convention in input is
6472  * \c new2old and \b not \c old2new.
6473  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
6474  *  \param [in] new2OldBg - pointer to the beginning of a permutation array that gives a
6475  *              tuple index in \a this array to fill the i-th tuple in the new array.
6476  *  \param [in] new2OldEnd - specifies the end of the permutation array that starts at
6477  *              \a new2OldBg, so that pointer to a tuple index (\a pi) varies as this:
6478  *              \a new2OldBg <= \a pi < \a new2OldEnd.
6479  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
6480  *          is to delete using decrRef() as it is no more needed.
6481  */
6482 DataArrayInt *DataArrayInt::selectByTupleId(const int *new2OldBg, const int *new2OldEnd) const
6483 {
6484   checkAllocated();
6485   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6486   int nbComp=getNumberOfComponents();
6487   ret->alloc((int)std::distance(new2OldBg,new2OldEnd),nbComp);
6488   ret->copyStringInfoFrom(*this);
6489   int *pt=ret->getPointer();
6490   const int *srcPt=getConstPointer();
6491   int i=0;
6492   for(const int *w=new2OldBg;w!=new2OldEnd;w++,i++)
6493     std::copy(srcPt+(*w)*nbComp,srcPt+((*w)+1)*nbComp,pt+i*nbComp);
6494   ret->copyStringInfoFrom(*this);
6495   return ret.retn();
6496 }
6497
6498 /*!
6499  * Returns a shorten and permuted copy of \a this array. The new DataArrayInt is
6500  * of size \a new2OldEnd - \a new2OldBg and it's values are permuted as required by
6501  * \a new2OldBg array.
6502  * The values are permuted so that  \c new[ i ] = \c old[ \a new2OldBg[ i ]].
6503  * This method is equivalent to renumberAndReduce() except that convention in input is
6504  * \c new2old and \b not \c old2new.
6505  * This method is equivalent to selectByTupleId() except that it prevents coping data
6506  * from behind the end of \a this array.
6507  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
6508  *  \param [in] new2OldBg - pointer to the beginning of a permutation array that gives a
6509  *              tuple index in \a this array to fill the i-th tuple in the new array.
6510  *  \param [in] new2OldEnd - specifies the end of the permutation array that starts at
6511  *              \a new2OldBg, so that pointer to a tuple index (\a pi) varies as this:
6512  *              \a new2OldBg <= \a pi < \a new2OldEnd.
6513  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
6514  *          is to delete using decrRef() as it is no more needed.
6515  *  \throw If \a new2OldEnd - \a new2OldBg > \a this->getNumberOfTuples().
6516  */
6517 DataArrayInt *DataArrayInt::selectByTupleIdSafe(const int *new2OldBg, const int *new2OldEnd) const throw(INTERP_KERNEL::Exception)
6518 {
6519   checkAllocated();
6520   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6521   int nbComp=getNumberOfComponents();
6522   int oldNbOfTuples=getNumberOfTuples();
6523   ret->alloc((int)std::distance(new2OldBg,new2OldEnd),nbComp);
6524   ret->copyStringInfoFrom(*this);
6525   int *pt=ret->getPointer();
6526   const int *srcPt=getConstPointer();
6527   int i=0;
6528   for(const int *w=new2OldBg;w!=new2OldEnd;w++,i++)
6529     if(*w>=0 && *w<oldNbOfTuples)
6530       std::copy(srcPt+(*w)*nbComp,srcPt+((*w)+1)*nbComp,pt+i*nbComp);
6531     else
6532       throw INTERP_KERNEL::Exception("DataArrayInt::selectByTupleIdSafe : some ids has been detected to be out of [0,this->getNumberOfTuples) !");
6533   ret->copyStringInfoFrom(*this);
6534   return ret.retn();
6535 }
6536
6537 /*!
6538  * Returns a shorten copy of \a this array. The new DataArrayInt contains every
6539  * (\a bg + \c i * \a step)-th tuple of \a this array located before the \a end2-th
6540  * tuple. Indices of the selected tuples are the same as ones returned by the Python
6541  * command \c range( \a bg, \a end2, \a step ).
6542  * This method is equivalent to selectByTupleIdSafe() except that the input array is
6543  * not constructed explicitly.
6544  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
6545  *  \param [in] bg - index of the first tuple to copy from \a this array.
6546  *  \param [in] end2 - index of the tuple before which the tuples to copy are located.
6547  *  \param [in] step - index increment to get index of the next tuple to copy.
6548  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
6549  *          is to delete using decrRef() as it is no more needed.
6550  *  \sa DataArrayInt::substr.
6551  */
6552 DataArrayInt *DataArrayInt::selectByTupleId2(int bg, int end2, int step) const throw(INTERP_KERNEL::Exception)
6553 {
6554   checkAllocated();
6555   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6556   int nbComp=getNumberOfComponents();
6557   int newNbOfTuples=GetNumberOfItemGivenBESRelative(bg,end2,step,"DataArrayInt::selectByTupleId2 : ");
6558   ret->alloc(newNbOfTuples,nbComp);
6559   int *pt=ret->getPointer();
6560   const int *srcPt=getConstPointer()+bg*nbComp;
6561   for(int i=0;i<newNbOfTuples;i++,srcPt+=step*nbComp)
6562     std::copy(srcPt,srcPt+nbComp,pt+i*nbComp);
6563   ret->copyStringInfoFrom(*this);
6564   return ret.retn();
6565 }
6566
6567 /*!
6568  * Returns a shorten copy of \a this array. The new DataArrayInt contains ranges
6569  * of tuples specified by \a ranges parameter.
6570  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
6571  *  \param [in] ranges - std::vector of std::pair's each of which defines a range
6572  *              of tuples in [\c begin,\c end) format.
6573  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
6574  *          is to delete using decrRef() as it is no more needed.
6575  *  \throw If \a end < \a begin.
6576  *  \throw If \a end > \a this->getNumberOfTuples().
6577  *  \throw If \a this is not allocated.
6578  */
6579 DataArray *DataArrayInt::selectByTupleRanges(const std::vector<std::pair<int,int> >& ranges) const throw(INTERP_KERNEL::Exception)
6580 {
6581   checkAllocated();
6582   int nbOfComp=getNumberOfComponents();
6583   int nbOfTuplesThis=getNumberOfTuples();
6584   if(ranges.empty())
6585     {
6586       MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6587       ret->alloc(0,nbOfComp);
6588       ret->copyStringInfoFrom(*this);
6589       return ret.retn();
6590     }
6591   int ref=ranges.front().first;
6592   int nbOfTuples=0;
6593   bool isIncreasing=true;
6594   for(std::vector<std::pair<int,int> >::const_iterator it=ranges.begin();it!=ranges.end();it++)
6595     {
6596       if((*it).first<=(*it).second)
6597         {
6598           if((*it).first>=0 && (*it).second<=nbOfTuplesThis)
6599             {
6600               nbOfTuples+=(*it).second-(*it).first;
6601               if(isIncreasing)
6602                 isIncreasing=ref<=(*it).first;
6603               ref=(*it).second;
6604             }
6605           else
6606             {
6607               std::ostringstream oss; oss << "DataArrayInt::selectByTupleRanges : on range #" << std::distance(ranges.begin(),it);
6608               oss << " (" << (*it).first << "," << (*it).second << ") is greater than number of tuples of this :" << nbOfTuples << " !";
6609               throw INTERP_KERNEL::Exception(oss.str().c_str());
6610             }
6611         }
6612       else
6613         {
6614           std::ostringstream oss; oss << "DataArrayInt::selectByTupleRanges : on range #" << std::distance(ranges.begin(),it);
6615           oss << " (" << (*it).first << "," << (*it).second << ") end is before begin !";
6616           throw INTERP_KERNEL::Exception(oss.str().c_str());
6617         }
6618     }
6619   if(isIncreasing && nbOfTuplesThis==nbOfTuples)
6620     return deepCpy();
6621   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6622   ret->alloc(nbOfTuples,nbOfComp);
6623   ret->copyStringInfoFrom(*this);
6624   const int *src=getConstPointer();
6625   int *work=ret->getPointer();
6626   for(std::vector<std::pair<int,int> >::const_iterator it=ranges.begin();it!=ranges.end();it++)
6627     work=std::copy(src+(*it).first*nbOfComp,src+(*it).second*nbOfComp,work);
6628   return ret.retn();
6629 }
6630
6631 /*!
6632  * Returns a new DataArrayInt containing a renumbering map in "Old to New" mode.
6633  * This map, if applied to \a this array, would make it sorted. For example, if
6634  * \a this array contents are [9,10,0,6,4,11,3,7] then the contents of the result array
6635  * are [5,6,0,3,2,7,1,4]; if this result array (\a res) is used as an argument in call
6636  * \a this->renumber(\a res) then the returned array contains [0,3,4,6,7,9,10,11].
6637  * This method is useful for renumbering (in MED file for example). For more info
6638  * on renumbering see \ref MEDCouplingArrayRenumbering.
6639  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
6640  *          array using decrRef() as it is no more needed.
6641  *  \throw If \a this is not allocated.
6642  *  \throw If \a this->getNumberOfComponents() != 1.
6643  *  \throw If there are equal values in \a this array.
6644  */
6645 DataArrayInt *DataArrayInt::checkAndPreparePermutation() const throw(INTERP_KERNEL::Exception)
6646 {
6647   checkAllocated();
6648   if(getNumberOfComponents()!=1)
6649     throw INTERP_KERNEL::Exception("DataArrayInt::checkAndPreparePermutation : number of components must == 1 !");
6650   int nbTuples=getNumberOfTuples();
6651   const int *pt=getConstPointer();
6652   int *pt2=CheckAndPreparePermutation(pt,pt+nbTuples);
6653   DataArrayInt *ret=DataArrayInt::New();
6654   ret->useArray(pt2,true,C_DEALLOC,nbTuples,1);
6655   return ret;
6656 }
6657
6658 /*!
6659  * Returns two arrays describing a surjective mapping from \a this set of values (\a A)
6660  * onto a set of values of size \a targetNb (\a B). The surjective function is 
6661  * \a B[ \a A[ i ]] = i. That is to say that for each \a id in [0,\a targetNb), where \a
6662  * targetNb < \a this->getNumberOfTuples(), there exists at least one tupleId (\a tid) so
6663  * that <em> this->getIJ( tid, 0 ) == id</em>. <br>
6664  * The first of out arrays returns indices of elements of \a this array, grouped by their
6665  * place in the set \a B. The second out array is the index of the first one; it shows how
6666  * many elements of \a A are mapped into each element of \a B. <br>
6667  * For more info on
6668  * mapping and its usage in renumbering see \ref MEDCouplingArrayRenumbering. <br>
6669  * \b Example:
6670  * - \a this: [0,3,2,3,2,2,1,2]
6671  * - \a targetNb: 4
6672  * - \a arr:  [0,  6,  2,4,5,7,  1,3]
6673  * - \a arrI: [0,1,2,6,8]
6674  *
6675  * This result means: <br>
6676  * the element of \a B 0 encounters within \a A once (\a arrI[ 0+1 ] - \a arrI[ 0 ]) and
6677  * its index within \a A is 0 ( \a arr[ 0:1 ] == \a arr[ \a arrI[ 0 ] : \a arrI[ 0+1 ]]);<br>
6678  * the element of \a B 2 encounters within \a A 4 times (\a arrI[ 2+1 ] - \a arrI[ 2 ]) and
6679  * its indices within \a A are [2,4,5,7] ( \a arr[ 2:6 ] == \a arr[ \a arrI[ 2 ] : 
6680  * \a arrI[ 2+1 ]]); <br> etc.
6681  *  \param [in] targetNb - the size of the set \a B. \a targetNb must be equal or more
6682  *         than the maximal value of \a A.
6683  *  \param [out] arr - a new instance of DataArrayInt returning indices of
6684  *         elements of \a this, grouped by their place in the set \a B. The caller is to delete
6685  *         this array using decrRef() as it is no more needed.
6686  *  \param [out] arrI - a new instance of DataArrayInt returning size of groups of equal
6687  *         elements of \a this. The caller is to delete this array using decrRef() as it
6688  *         is no more needed.
6689  *  \throw If \a this is not allocated.
6690  *  \throw If \a this->getNumberOfComponents() != 1.
6691  *  \throw If any value in \a this is more or equal to \a targetNb.
6692  */
6693 void DataArrayInt::changeSurjectiveFormat(int targetNb, DataArrayInt *&arr, DataArrayInt *&arrI) const throw(INTERP_KERNEL::Exception)
6694 {
6695   checkAllocated();
6696   if(getNumberOfComponents()!=1)
6697     throw INTERP_KERNEL::Exception("DataArrayInt::changeSurjectiveFormat : number of components must == 1 !");
6698   int nbOfTuples=getNumberOfTuples();
6699   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New());
6700   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> retI(DataArrayInt::New());
6701   retI->alloc(targetNb+1,1);
6702   const int *input=getConstPointer();
6703   std::vector< std::vector<int> > tmp(targetNb);
6704   for(int i=0;i<nbOfTuples;i++)
6705     {
6706       int tmp2=input[i];
6707       if(tmp2>=0 && tmp2<targetNb)
6708         tmp[tmp2].push_back(i);
6709       else
6710         {
6711           std::ostringstream oss; oss << "DataArrayInt::changeSurjectiveFormat : At pos " << i << " presence of element " << tmp2 << " ! should be in [0," << targetNb << ") !";
6712           throw INTERP_KERNEL::Exception(oss.str().c_str());
6713         }
6714     }
6715   int *retIPtr=retI->getPointer();
6716   *retIPtr=0;
6717   for(std::vector< std::vector<int> >::const_iterator it1=tmp.begin();it1!=tmp.end();it1++,retIPtr++)
6718     retIPtr[1]=retIPtr[0]+(int)((*it1).size());
6719   if(nbOfTuples!=retI->getIJ(targetNb,0))
6720     throw INTERP_KERNEL::Exception("DataArrayInt::changeSurjectiveFormat : big problem should never happen !");
6721   ret->alloc(nbOfTuples,1);
6722   int *retPtr=ret->getPointer();
6723   for(std::vector< std::vector<int> >::const_iterator it1=tmp.begin();it1!=tmp.end();it1++)
6724     retPtr=std::copy((*it1).begin(),(*it1).end(),retPtr);
6725   arr=ret.retn();
6726   arrI=retI.retn();
6727 }
6728
6729
6730 /*!
6731  * Returns a new DataArrayInt containing a renumbering map in "Old to New" mode computed
6732  * from a zip representation of a surjective format (returned e.g. by
6733  * \ref ParaMEDMEM::DataArrayDouble::findCommonTuples() "DataArrayDouble::findCommonTuples()"
6734  * for example). The result array minimizes the permutation. <br>
6735  * For more info on renumbering see \ref MEDCouplingArrayRenumbering. <br>
6736  * \b Example: <br>
6737  * - \a nbOfOldTuples: 10 
6738  * - \a arr          : [0,3, 5,7,9]
6739  * - \a arrIBg       : [0,2,5]
6740  * - \a newNbOfTuples: 7
6741  * - result array    : [0,1,2,0,3,4,5,4,6,4]
6742  *
6743  *  \param [in] nbOfOldTuples - number of tuples in the initial array \a arr.
6744  *  \param [in] arr - the array of tuple indices grouped by \a arrIBg array.
6745  *  \param [in] arrIBg - the array dividing all indices stored in \a arr into groups of
6746  *         (indices of) equal values. Its every element (except the last one) points to
6747  *         the first element of a group of equal values.
6748  *  \param [in] arrIEnd - specifies the end of \a arrIBg, so that the last element of \a
6749  *          arrIBg is \a arrIEnd[ -1 ].
6750  *  \param [out] newNbOfTuples - number of tuples after surjection application.
6751  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
6752  *          array using decrRef() as it is no more needed.
6753  *  \throw If any value of \a arr breaks condition ( 0 <= \a arr[ i ] < \a nbOfOldTuples ).
6754  */
6755 DataArrayInt *DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2(int nbOfOldTuples, const int *arr, const int *arrIBg, const int *arrIEnd, int &newNbOfTuples) throw(INTERP_KERNEL::Exception)
6756 {
6757   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6758   ret->alloc(nbOfOldTuples,1);
6759   int *pt=ret->getPointer();
6760   std::fill(pt,pt+nbOfOldTuples,-1);
6761   int nbOfGrps=((int)std::distance(arrIBg,arrIEnd))-1;
6762   const int *cIPtr=arrIBg;
6763   for(int i=0;i<nbOfGrps;i++)
6764     pt[arr[cIPtr[i]]]=-(i+2);
6765   int newNb=0;
6766   for(int iNode=0;iNode<nbOfOldTuples;iNode++)
6767     {
6768       if(pt[iNode]<0)
6769         {
6770           if(pt[iNode]==-1)
6771             pt[iNode]=newNb++;
6772           else
6773             {
6774               int grpId=-(pt[iNode]+2);
6775               for(int j=cIPtr[grpId];j<cIPtr[grpId+1];j++)
6776                 {
6777                   if(arr[j]>=0 && arr[j]<nbOfOldTuples)
6778                     pt[arr[j]]=newNb;
6779                   else
6780                     {
6781                       std::ostringstream oss; oss << "DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2 : With element #" << j << " value is " << arr[j] << " should be in [0," << nbOfOldTuples << ") !";
6782                       throw INTERP_KERNEL::Exception(oss.str().c_str());
6783                     }
6784                 }
6785               newNb++;
6786             }
6787         }
6788     }
6789   newNbOfTuples=newNb;
6790   return ret.retn();
6791 }
6792
6793 /*!
6794  * Returns a new DataArrayInt containing a renumbering map in "New to Old" mode,
6795  * which if applied to \a this array would make it sorted ascendingly.
6796  * For more info on renumbering see \ref MEDCouplingArrayRenumbering. <br>
6797  * \b Example: <br>
6798  * - \a this: [2,0,1,1,0,1,2,0,1,1,0,0]
6799  * - result: [10,0,5,6,1,7,11,2,8,9,3,4]
6800  * - after applying result to \a this: [0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2] 
6801  *
6802  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
6803  *          array using decrRef() as it is no more needed.
6804  *  \throw If \a this is not allocated.
6805  *  \throw If \a this->getNumberOfComponents() != 1.
6806  */
6807 DataArrayInt *DataArrayInt::buildPermArrPerLevel() const throw(INTERP_KERNEL::Exception)
6808 {
6809   checkAllocated();
6810   if(getNumberOfComponents()!=1)
6811     throw INTERP_KERNEL::Exception("DataArrayInt::buildPermArrPerLevel : number of components must == 1 !");
6812   int nbOfTuples=getNumberOfTuples();
6813   const int *pt=getConstPointer();
6814   std::map<int,int> m;
6815   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6816   ret->alloc(nbOfTuples,1);
6817   int *opt=ret->getPointer();
6818   for(int i=0;i<nbOfTuples;i++,pt++,opt++)
6819     {
6820       int val=*pt;
6821       std::map<int,int>::iterator it=m.find(val);
6822       if(it!=m.end())
6823         {
6824           *opt=(*it).second;
6825           (*it).second++;
6826         }
6827       else
6828         {
6829           *opt=0;
6830           m.insert(std::pair<int,int>(val,1));
6831         }
6832     }
6833   int sum=0;
6834   for(std::map<int,int>::iterator it=m.begin();it!=m.end();it++)
6835     {
6836       int vt=(*it).second;
6837       (*it).second=sum;
6838       sum+=vt;
6839     }
6840   pt=getConstPointer();
6841   opt=ret->getPointer();
6842   for(int i=0;i<nbOfTuples;i++,pt++,opt++)
6843     *opt+=m[*pt];
6844   //
6845   return ret.retn();
6846 }
6847
6848 /*!
6849  * Checks if contents of \a this array are equal to that of an array filled with
6850  * iota(). This method is particularly useful for DataArrayInt instances that represent
6851  * a renumbering array to check the real need in renumbering. 
6852  *  \return bool - \a true if \a this array contents == \a range( \a this->getNumberOfTuples())
6853  *  \throw If \a this is not allocated.
6854  *  \throw If \a this->getNumberOfComponents() != 1.
6855  */
6856 bool DataArrayInt::isIdentity() const throw(INTERP_KERNEL::Exception)
6857 {
6858   checkAllocated();
6859   if(getNumberOfComponents()!=1)
6860     return false;
6861   int nbOfTuples=getNumberOfTuples();
6862   const int *pt=getConstPointer();
6863   for(int i=0;i<nbOfTuples;i++,pt++)
6864     if(*pt!=i)
6865       return false;
6866   return true;
6867 }
6868
6869 /*!
6870  * Checks if all values in \a this array are equal to \a val.
6871  *  \param [in] val - value to check equality of array values to.
6872  *  \return bool - \a true if all values are \a val.
6873  *  \throw If \a this is not allocated.
6874  *  \throw If \a this->getNumberOfComponents() != 1
6875  */
6876 bool DataArrayInt::isUniform(int val) const throw(INTERP_KERNEL::Exception)
6877 {
6878   checkAllocated();
6879   if(getNumberOfComponents()!=1)
6880     throw INTERP_KERNEL::Exception("DataArrayInt::isUniform : must be applied on DataArrayInt with only one component, you can call 'rearrange' method before !");
6881   int nbOfTuples=getNumberOfTuples();
6882   const int *w=getConstPointer();
6883   const int *end2=w+nbOfTuples;
6884   for(;w!=end2;w++)
6885     if(*w!=val)
6886       return false;
6887   return true;
6888 }
6889
6890 /*!
6891  * Creates a new DataArrayDouble and assigns all (textual and numerical) data of \a this
6892  * array to the new one.
6893  *  \return DataArrayDouble * - the new instance of DataArrayInt.
6894  */
6895 DataArrayDouble *DataArrayInt::convertToDblArr() const
6896 {
6897   checkAllocated();
6898   DataArrayDouble *ret=DataArrayDouble::New();
6899   ret->alloc(getNumberOfTuples(),getNumberOfComponents());
6900   std::size_t nbOfVals=getNbOfElems();
6901   const int *src=getConstPointer();
6902   double *dest=ret->getPointer();
6903   std::copy(src,src+nbOfVals,dest);
6904   ret->copyStringInfoFrom(*this);
6905   return ret;
6906 }
6907
6908 /*!
6909  * Returns a shorten copy of \a this array. The new DataArrayInt contains all
6910  * tuples starting from the \a tupleIdBg-th tuple and including all tuples located before
6911  * the \a tupleIdEnd-th one. This methods has a similar behavior as std::string::substr().
6912  * This method is a specialization of selectByTupleId2().
6913  *  \param [in] tupleIdBg - index of the first tuple to copy from \a this array.
6914  *  \param [in] tupleIdEnd - index of the tuple before which the tuples to copy are located.
6915  *          If \a tupleIdEnd == -1, all the tuples till the end of \a this array are copied.
6916  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
6917  *          is to delete using decrRef() as it is no more needed.
6918  *  \throw If \a tupleIdBg < 0.
6919  *  \throw If \a tupleIdBg > \a this->getNumberOfTuples().
6920     \throw If \a tupleIdEnd != -1 && \a tupleIdEnd < \a this->getNumberOfTuples().
6921  *  \sa DataArrayInt::selectByTupleId2
6922  */
6923 DataArrayInt *DataArrayInt::substr(int tupleIdBg, int tupleIdEnd) const throw(INTERP_KERNEL::Exception)
6924 {
6925   checkAllocated();
6926   int nbt=getNumberOfTuples();
6927   if(tupleIdBg<0)
6928     throw INTERP_KERNEL::Exception("DataArrayInt::substr : The tupleIdBg parameter must be greater than 0 !");
6929   if(tupleIdBg>nbt)
6930     throw INTERP_KERNEL::Exception("DataArrayInt::substr : The tupleIdBg parameter is greater than number of tuples !");
6931   int trueEnd=tupleIdEnd;
6932   if(tupleIdEnd!=-1)
6933     {
6934       if(tupleIdEnd>nbt)
6935         throw INTERP_KERNEL::Exception("DataArrayInt::substr : The tupleIdBg parameter is greater or equal than number of tuples !");
6936     }
6937   else
6938     trueEnd=nbt;
6939   int nbComp=getNumberOfComponents();
6940   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6941   ret->alloc(trueEnd-tupleIdBg,nbComp);
6942   ret->copyStringInfoFrom(*this);
6943   std::copy(getConstPointer()+tupleIdBg*nbComp,getConstPointer()+trueEnd*nbComp,ret->getPointer());
6944   return ret.retn();
6945 }
6946
6947 /*!
6948  * Changes the number of components within \a this array so that its raw data **does
6949  * not** change, instead splitting this data into tuples changes.
6950  *  \warning This method erases all (name and unit) component info set before!
6951  *  \param [in] newNbOfComp - number of components for \a this array to have.
6952  *  \throw If \a this is not allocated
6953  *  \throw If getNbOfElems() % \a newNbOfCompo != 0.
6954  *  \throw If \a newNbOfCompo is lower than 1.
6955  *  \throw If the rearrange method would lead to a number of tuples higher than 2147483647 (maximal capacity of int32 !).
6956  *  \warning This method erases all (name and unit) component info set before!
6957  */
6958 void DataArrayInt::rearrange(int newNbOfCompo) throw(INTERP_KERNEL::Exception)
6959 {
6960   checkAllocated();
6961   if(newNbOfCompo<1)
6962     throw INTERP_KERNEL::Exception("DataArrayInt::rearrange : input newNbOfCompo must be > 0 !");
6963   std::size_t nbOfElems=getNbOfElems();
6964   if(nbOfElems%newNbOfCompo!=0)
6965     throw INTERP_KERNEL::Exception("DataArrayInt::rearrange : nbOfElems%newNbOfCompo!=0 !");
6966   if(nbOfElems/newNbOfCompo>(std::size_t)std::numeric_limits<int>::max())
6967     throw INTERP_KERNEL::Exception("DataArrayInt::rearrange : the rearrangement leads to too high number of tuples (> 2147483647) !");
6968   _info_on_compo.clear();
6969   _info_on_compo.resize(newNbOfCompo);
6970   declareAsNew();
6971 }
6972
6973 /*!
6974  * Changes the number of components within \a this array to be equal to its number
6975  * of tuples, and inversely its number of tuples to become equal to its number of 
6976  * components. So that its raw data **does not** change, instead splitting this
6977  * data into tuples changes.
6978  *  \warning This method erases all (name and unit) component info set before!
6979  *  \warning Do not confuse this method with fromNoInterlace() and toNoInterlace()!
6980  *  \throw If \a this is not allocated.
6981  *  \sa rearrange()
6982  */
6983 void DataArrayInt::transpose() throw(INTERP_KERNEL::Exception)
6984 {
6985   checkAllocated();
6986   int nbOfTuples=getNumberOfTuples();
6987   rearrange(nbOfTuples);
6988 }
6989
6990 /*!
6991  * Returns a shorten or extended copy of \a this array. If \a newNbOfComp is less
6992  * than \a this->getNumberOfComponents() then the result array is shorten as each tuple
6993  * is truncated to have \a newNbOfComp components, keeping first components. If \a
6994  * newNbOfComp is more than \a this->getNumberOfComponents() then the result array is
6995  * expanded as each tuple is populated with \a dftValue to have \a newNbOfComp
6996  * components.  
6997  *  \param [in] newNbOfComp - number of components for the new array to have.
6998  *  \param [in] dftValue - value assigned to new values added to the new array.
6999  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
7000  *          is to delete using decrRef() as it is no more needed.
7001  *  \throw If \a this is not allocated.
7002  */
7003 DataArrayInt *DataArrayInt::changeNbOfComponents(int newNbOfComp, int dftValue) const throw(INTERP_KERNEL::Exception)
7004 {
7005   checkAllocated();
7006   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
7007   ret->alloc(getNumberOfTuples(),newNbOfComp);
7008   const int *oldc=getConstPointer();
7009   int *nc=ret->getPointer();
7010   int nbOfTuples=getNumberOfTuples();
7011   int oldNbOfComp=getNumberOfComponents();
7012   int dim=std::min(oldNbOfComp,newNbOfComp);
7013   for(int i=0;i<nbOfTuples;i++)
7014     {
7015       int j=0;
7016       for(;j<dim;j++)
7017         nc[newNbOfComp*i+j]=oldc[i*oldNbOfComp+j];
7018       for(;j<newNbOfComp;j++)
7019         nc[newNbOfComp*i+j]=dftValue;
7020     }
7021   ret->setName(getName().c_str());
7022   for(int i=0;i<dim;i++)
7023     ret->setInfoOnComponent(i,getInfoOnComponent(i).c_str());
7024   ret->setName(getName().c_str());
7025   return ret.retn();
7026 }
7027
7028 /*!
7029  * Changes number of tuples in the array. If the new number of tuples is smaller
7030  * than the current number the array is truncated, otherwise the array is extended.
7031  *  \param [in] nbOfTuples - new number of tuples. 
7032  *  \throw If \a this is not allocated.
7033  */
7034 void DataArrayInt::reAlloc(int nbOfTuples) throw(INTERP_KERNEL::Exception)
7035 {
7036   checkAllocated();
7037   _mem.reAlloc(getNumberOfComponents()*(std::size_t)nbOfTuples);
7038   declareAsNew();
7039 }
7040
7041
7042 /*!
7043  * Returns a copy of \a this array composed of selected components.
7044  * The new DataArrayInt has the same number of tuples but includes components
7045  * specified by \a compoIds parameter. So that getNbOfElems() of the result array
7046  * can be either less, same or more than \a this->getNbOfElems().
7047  *  \param [in] compoIds - sequence of zero based indices of components to include
7048  *              into the new array.
7049  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
7050  *          is to delete using decrRef() as it is no more needed.
7051  *  \throw If \a this is not allocated.
7052  *  \throw If a component index (\a i) is not valid: 
7053  *         \a i < 0 || \a i >= \a this->getNumberOfComponents().
7054  *
7055  *  \ref py_mcdataarrayint_keepselectedcomponents "Here is a Python example".
7056  */
7057 DataArray *DataArrayInt::keepSelectedComponents(const std::vector<int>& compoIds) const throw(INTERP_KERNEL::Exception)
7058 {
7059   checkAllocated();
7060   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New());
7061   int newNbOfCompo=(int)compoIds.size();
7062   int oldNbOfCompo=getNumberOfComponents();
7063   for(std::vector<int>::const_iterator it=compoIds.begin();it!=compoIds.end();it++)
7064     DataArray::CheckValueInRange(oldNbOfCompo,(*it),"keepSelectedComponents invalid requested component");
7065   int nbOfTuples=getNumberOfTuples();
7066   ret->alloc(nbOfTuples,newNbOfCompo);
7067   ret->copyPartOfStringInfoFrom(*this,compoIds);
7068   const int *oldc=getConstPointer();
7069   int *nc=ret->getPointer();
7070   for(int i=0;i<nbOfTuples;i++)
7071     for(int j=0;j<newNbOfCompo;j++,nc++)
7072       *nc=oldc[i*oldNbOfCompo+compoIds[j]];
7073   return ret.retn();
7074 }
7075
7076 /*!
7077  * Appends components of another array to components of \a this one, tuple by tuple.
7078  * So that the number of tuples of \a this array remains the same and the number of 
7079  * components increases.
7080  *  \param [in] other - the DataArrayInt to append to \a this one.
7081  *  \throw If \a this is not allocated.
7082  *  \throw If \a this and \a other arrays have different number of tuples.
7083  *
7084  *  \ref cpp_mcdataarrayint_meldwith "Here is a C++ example".
7085  *
7086  *  \ref py_mcdataarrayint_meldwith "Here is a Python example".
7087  */
7088 void DataArrayInt::meldWith(const DataArrayInt *other) throw(INTERP_KERNEL::Exception)
7089 {
7090   if(!other)
7091     throw INTERP_KERNEL::Exception("DataArrayInt::meldWith : DataArrayInt pointer in input is NULL !");
7092   checkAllocated();
7093   other->checkAllocated();
7094   int nbOfTuples=getNumberOfTuples();
7095   if(nbOfTuples!=other->getNumberOfTuples())
7096     throw INTERP_KERNEL::Exception("DataArrayInt::meldWith : mismatch of number of tuples !");
7097   int nbOfComp1=getNumberOfComponents();
7098   int nbOfComp2=other->getNumberOfComponents();
7099   int *newArr=(int *)malloc(nbOfTuples*(nbOfComp1+nbOfComp2)*sizeof(int));
7100   int *w=newArr;
7101   const int *inp1=getConstPointer();
7102   const int *inp2=other->getConstPointer();
7103   for(int i=0;i<nbOfTuples;i++,inp1+=nbOfComp1,inp2+=nbOfComp2)
7104     {
7105       w=std::copy(inp1,inp1+nbOfComp1,w);
7106       w=std::copy(inp2,inp2+nbOfComp2,w);
7107     }
7108   useArray(newArr,true,C_DEALLOC,nbOfTuples,nbOfComp1+nbOfComp2);
7109   std::vector<int> compIds(nbOfComp2);
7110   for(int i=0;i<nbOfComp2;i++)
7111     compIds[i]=nbOfComp1+i;
7112   copyPartOfStringInfoFrom2(compIds,*other);
7113 }
7114
7115 /*!
7116  * Copy all components in a specified order from another DataArrayInt.
7117  * The specified components become the first ones in \a this array.
7118  * Both numerical and textual data is copied. The number of tuples in \a this and
7119  * the other array can be different.
7120  *  \param [in] a - the array to copy data from.
7121  *  \param [in] compoIds - sequence of zero based indices of components, data of which is
7122  *              to be copied.
7123  *  \throw If \a a is NULL.
7124  *  \throw If \a compoIds.size() != \a a->getNumberOfComponents().
7125  *  \throw If \a compoIds[i] < 0 or \a compoIds[i] > \a this->getNumberOfComponents().
7126  *
7127  *  \ref py_mcdataarrayint_setselectedcomponents "Here is a Python example".
7128  */
7129 void DataArrayInt::setSelectedComponents(const DataArrayInt *a, const std::vector<int>& compoIds) throw(INTERP_KERNEL::Exception)
7130 {
7131   if(!a)
7132     throw INTERP_KERNEL::Exception("DataArrayInt::setSelectedComponents : input DataArrayInt is NULL !");
7133   checkAllocated();
7134   a->checkAllocated();
7135   copyPartOfStringInfoFrom2(compoIds,*a);
7136   std::size_t partOfCompoSz=compoIds.size();
7137   int nbOfCompo=getNumberOfComponents();
7138   int nbOfTuples=std::min(getNumberOfTuples(),a->getNumberOfTuples());
7139   const int *ac=a->getConstPointer();
7140   int *nc=getPointer();
7141   for(int i=0;i<nbOfTuples;i++)
7142     for(std::size_t j=0;j<partOfCompoSz;j++,ac++)
7143       nc[nbOfCompo*i+compoIds[j]]=*ac;
7144 }
7145
7146 /*!
7147  * Copy all values from another DataArrayInt into specified tuples and components
7148  * of \a this array. Textual data is not copied.
7149  * The tree parameters defining set of indices of tuples and components are similar to
7150  * the tree parameters of the Python function \c range(\c start,\c stop,\c step).
7151  *  \param [in] a - the array to copy values from.
7152  *  \param [in] bgTuples - index of the first tuple of \a this array to assign values to.
7153  *  \param [in] endTuples - index of the tuple before which the tuples to assign to
7154  *              are located.
7155  *  \param [in] stepTuples - index increment to get index of the next tuple to assign to.
7156  *  \param [in] bgComp - index of the first component of \a this array to assign values to.
7157  *  \param [in] endComp - index of the component before which the components to assign
7158  *              to are located.
7159  *  \param [in] stepComp - index increment to get index of the next component to assign to.
7160  *  \param [in] strictCompoCompare - if \a true (by default), then \a a->getNumberOfComponents() 
7161  *              must be equal to the number of columns to assign to, else an
7162  *              exception is thrown; if \a false, then it is only required that \a
7163  *              a->getNbOfElems() equals to number of values to assign to (this condition
7164  *              must be respected even if \a strictCompoCompare is \a true). The number of 
7165  *              values to assign to is given by following Python expression:
7166  *              \a nbTargetValues = 
7167  *              \c len(\c range(\a bgTuples,\a endTuples,\a stepTuples)) *
7168  *              \c len(\c range(\a bgComp,\a endComp,\a stepComp)).
7169  *  \throw If \a a is NULL.
7170  *  \throw If \a a is not allocated.
7171  *  \throw If \a this is not allocated.
7172  *  \throw If parameters specifying tuples and components to assign to do not give a
7173  *            non-empty range of increasing indices.
7174  *  \throw If \a a->getNbOfElems() != \a nbTargetValues.
7175  *  \throw If \a strictCompoCompare == \a true && \a a->getNumberOfComponents() !=
7176  *            \c len(\c range(\a bgComp,\a endComp,\a stepComp)).
7177  *
7178  *  \ref py_mcdataarrayint_setpartofvalues1 "Here is a Python example".
7179  */
7180 void DataArrayInt::setPartOfValues1(const DataArrayInt *a, int bgTuples, int endTuples, int stepTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare) throw(INTERP_KERNEL::Exception)
7181 {
7182   if(!a)
7183     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValues1 : DataArrayInt pointer in input is NULL !");
7184   const char msg[]="DataArrayInt::setPartOfValues1";
7185   checkAllocated();
7186   a->checkAllocated();
7187   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
7188   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
7189   int nbComp=getNumberOfComponents();
7190   int nbOfTuples=getNumberOfTuples();
7191   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
7192   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
7193   bool assignTech=true;
7194   if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
7195     {
7196       if(strictCompoCompare)
7197         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
7198     }
7199   else
7200     {
7201       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
7202       assignTech=false;
7203     }
7204   int *pt=getPointer()+bgTuples*nbComp+bgComp;
7205   const int *srcPt=a->getConstPointer();
7206   if(assignTech)
7207     {
7208       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
7209         for(int j=0;j<newNbOfComp;j++,srcPt++)
7210           pt[j*stepComp]=*srcPt;
7211     }
7212   else
7213     {
7214       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
7215         {
7216           const int *srcPt2=srcPt;
7217           for(int j=0;j<newNbOfComp;j++,srcPt2++)
7218             pt[j*stepComp]=*srcPt2;
7219         }
7220     }
7221 }
7222
7223 /*!
7224  * Assign a given value to values at specified tuples and components of \a this array.
7225  * The tree parameters defining set of indices of tuples and components are similar to
7226  * the tree parameters of the Python function \c range(\c start,\c stop,\c step)..
7227  *  \param [in] a - the value to assign.
7228  *  \param [in] bgTuples - index of the first tuple of \a this array to assign to.
7229  *  \param [in] endTuples - index of the tuple before which the tuples to assign to
7230  *              are located.
7231  *  \param [in] stepTuples - index increment to get index of the next tuple to assign to.
7232  *  \param [in] bgComp - index of the first component of \a this array to assign to.
7233  *  \param [in] endComp - index of the component before which the components to assign
7234  *              to are located.
7235  *  \param [in] stepComp - index increment to get index of the next component to assign to.
7236  *  \throw If \a this is not allocated.
7237  *  \throw If parameters specifying tuples and components to assign to, do not give a
7238  *            non-empty range of increasing indices or indices are out of a valid range
7239  *            for \this array.
7240  *
7241  *  \ref py_mcdataarrayint_setpartofvaluessimple1 "Here is a Python example".
7242  */
7243 void DataArrayInt::setPartOfValuesSimple1(int a, int bgTuples, int endTuples, int stepTuples, int bgComp, int endComp, int stepComp) throw(INTERP_KERNEL::Exception)
7244 {
7245   const char msg[]="DataArrayInt::setPartOfValuesSimple1";
7246   checkAllocated();
7247   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
7248   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
7249   int nbComp=getNumberOfComponents();
7250   int nbOfTuples=getNumberOfTuples();
7251   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
7252   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
7253   int *pt=getPointer()+bgTuples*nbComp+bgComp;
7254   for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
7255     for(int j=0;j<newNbOfComp;j++)
7256       pt[j*stepComp]=a;
7257 }
7258
7259
7260 /*!
7261  * Copy all values from another DataArrayInt (\a a) into specified tuples and 
7262  * components of \a this array. Textual data is not copied.
7263  * The tuples and components to assign to are defined by C arrays of indices.
7264  * There are two *modes of usage*:
7265  * - If \a a->getNbOfElems() equals to number of values to assign to, then every value
7266  *   of \a a is assigned to its own location within \a this array. 
7267  * - If \a a includes one tuple, then all values of \a a are assigned to the specified
7268  *   components of every specified tuple of \a this array. In this mode it is required
7269  *   that \a a->getNumberOfComponents() equals to the number of specified components.
7270  * 
7271  *  \param [in] a - the array to copy values from.
7272  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
7273  *              assign values of \a a to.
7274  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
7275  *              pointer to a tuple index <em>(pi)</em> varies as this: 
7276  *              \a bgTuples <= \a pi < \a endTuples.
7277  *  \param [in] bgComp - pointer to an array of component indices of \a this array to
7278  *              assign values of \a a to.
7279  *  \param [in] endComp - specifies the end of the array \a bgTuples, so that
7280  *              pointer to a component index <em>(pi)</em> varies as this: 
7281  *              \a bgComp <= \a pi < \a endComp.
7282  *  \param [in] strictCompoCompare - this parameter is checked only if the
7283  *               *mode of usage* is the first; if it is \a true (default), 
7284  *               then \a a->getNumberOfComponents() must be equal 
7285  *               to the number of specified columns, else this is not required.
7286  *  \throw If \a a is NULL.
7287  *  \throw If \a a is not allocated.
7288  *  \throw If \a this is not allocated.
7289  *  \throw If any index of tuple/component given by <em>bgTuples / bgComp</em> is
7290  *         out of a valid range for \a this array.
7291  *  \throw In the first *mode of usage*, if <em>strictCompoCompare == true </em> and
7292  *         if <em> a->getNumberOfComponents() != (endComp - bgComp) </em>.
7293  *  \throw In the second *mode of usage*, if \a a->getNumberOfTuples() != 1 or
7294  *         <em> a->getNumberOfComponents() != (endComp - bgComp)</em>.
7295  *
7296  *  \ref py_mcdataarrayint_setpartofvalues2 "Here is a Python example".
7297  */
7298 void DataArrayInt::setPartOfValues2(const DataArrayInt *a, const int *bgTuples, const int *endTuples, const int *bgComp, const int *endComp, bool strictCompoCompare) throw(INTERP_KERNEL::Exception)
7299 {
7300   if(!a)
7301     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValues2 : DataArrayInt pointer in input is NULL !");
7302   const char msg[]="DataArrayInt::setPartOfValues2";
7303   checkAllocated();
7304   a->checkAllocated();
7305   int nbComp=getNumberOfComponents();
7306   int nbOfTuples=getNumberOfTuples();
7307   for(const int *z=bgComp;z!=endComp;z++)
7308     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
7309   int newNbOfTuples=(int)std::distance(bgTuples,endTuples);
7310   int newNbOfComp=(int)std::distance(bgComp,endComp);
7311   bool assignTech=true;
7312   if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
7313     {
7314       if(strictCompoCompare)
7315         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
7316     }
7317   else
7318     {
7319       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
7320       assignTech=false;
7321     }
7322   int *pt=getPointer();
7323   const int *srcPt=a->getConstPointer();
7324   if(assignTech)
7325     {    
7326       for(const int *w=bgTuples;w!=endTuples;w++)
7327         {
7328           DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
7329           for(const int *z=bgComp;z!=endComp;z++,srcPt++)
7330             {    
7331               pt[(std::size_t)(*w)*nbComp+(*z)]=*srcPt;
7332             }
7333         }
7334     }
7335   else
7336     {
7337       for(const int *w=bgTuples;w!=endTuples;w++)
7338         {
7339           const int *srcPt2=srcPt;
7340           DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
7341           for(const int *z=bgComp;z!=endComp;z++,srcPt2++)
7342             {    
7343               pt[(std::size_t)(*w)*nbComp+(*z)]=*srcPt2;
7344             }
7345         }
7346     }
7347 }
7348
7349 /*!
7350  * Assign a given value to values at specified tuples and components of \a this array.
7351  * The tuples and components to assign to are defined by C arrays of indices.
7352  *  \param [in] a - the value to assign.
7353  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
7354  *              assign \a a to.
7355  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
7356  *              pointer to a tuple index (\a pi) varies as this: 
7357  *              \a bgTuples <= \a pi < \a endTuples.
7358  *  \param [in] bgComp - pointer to an array of component indices of \a this array to
7359  *              assign \a a to.
7360  *  \param [in] endComp - specifies the end of the array \a bgTuples, so that
7361  *              pointer to a component index (\a pi) varies as this: 
7362  *              \a bgComp <= \a pi < \a endComp.
7363  *  \throw If \a this is not allocated.
7364  *  \throw If any index of tuple/component given by <em>bgTuples / bgComp</em> is
7365  *         out of a valid range for \a this array.
7366  *
7367  *  \ref py_mcdataarrayint_setpartofvaluessimple2 "Here is a Python example".
7368  */
7369 void DataArrayInt::setPartOfValuesSimple2(int a, const int *bgTuples, const int *endTuples, const int *bgComp, const int *endComp) throw(INTERP_KERNEL::Exception)
7370 {
7371   checkAllocated();
7372   int nbComp=getNumberOfComponents();
7373   int nbOfTuples=getNumberOfTuples();
7374   for(const int *z=bgComp;z!=endComp;z++)
7375     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
7376   int *pt=getPointer();
7377   for(const int *w=bgTuples;w!=endTuples;w++)
7378     for(const int *z=bgComp;z!=endComp;z++)
7379       {
7380         DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
7381         pt[(std::size_t)(*w)*nbComp+(*z)]=a;
7382       }
7383 }
7384
7385 /*!
7386  * Copy all values from another DataArrayInt (\a a) into specified tuples and 
7387  * components of \a this array. Textual data is not copied.
7388  * The tuples to assign to are defined by a C array of indices.
7389  * The components to assign to are defined by three values similar to parameters of
7390  * the Python function \c range(\c start,\c stop,\c step).
7391  * There are two *modes of usage*:
7392  * - If \a a->getNbOfElems() equals to number of values to assign to, then every value
7393  *   of \a a is assigned to its own location within \a this array. 
7394  * - If \a a includes one tuple, then all values of \a a are assigned to the specified
7395  *   components of every specified tuple of \a this array. In this mode it is required
7396  *   that \a a->getNumberOfComponents() equals to the number of specified components.
7397  *
7398  *  \param [in] a - the array to copy values from.
7399  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
7400  *              assign values of \a a to.
7401  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
7402  *              pointer to a tuple index <em>(pi)</em> varies as this: 
7403  *              \a bgTuples <= \a pi < \a endTuples.
7404  *  \param [in] bgComp - index of the first component of \a this array to assign to.
7405  *  \param [in] endComp - index of the component before which the components to assign
7406  *              to are located.
7407  *  \param [in] stepComp - index increment to get index of the next component to assign to.
7408  *  \param [in] strictCompoCompare - this parameter is checked only in the first
7409  *               *mode of usage*; if \a strictCompoCompare is \a true (default), 
7410  *               then \a a->getNumberOfComponents() must be equal 
7411  *               to the number of specified columns, else this is not required.
7412  *  \throw If \a a is NULL.
7413  *  \throw If \a a is not allocated.
7414  *  \throw If \a this is not allocated.
7415  *  \throw If any index of tuple given by \a bgTuples is out of a valid range for 
7416  *         \a this array.
7417  *  \throw In the first *mode of usage*, if <em>strictCompoCompare == true </em> and
7418  *         if <em> a->getNumberOfComponents()</em> is unequal to the number of components
7419  *         defined by <em>(bgComp,endComp,stepComp)</em>.
7420  *  \throw In the second *mode of usage*, if \a a->getNumberOfTuples() != 1 or
7421  *         <em> a->getNumberOfComponents()</em> is unequal to the number of components
7422  *         defined by <em>(bgComp,endComp,stepComp)</em>.
7423  *  \throw If parameters specifying components to assign to, do not give a
7424  *            non-empty range of increasing indices or indices are out of a valid range
7425  *            for \this array.
7426  *
7427  *  \ref py_mcdataarrayint_setpartofvalues3 "Here is a Python example".
7428  */
7429 void DataArrayInt::setPartOfValues3(const DataArrayInt *a, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare) throw(INTERP_KERNEL::Exception)
7430 {
7431   if(!a)
7432     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValues3 : DataArrayInt pointer in input is NULL !");
7433   const char msg[]="DataArrayInt::setPartOfValues3";
7434   checkAllocated();
7435   a->checkAllocated();
7436   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
7437   int nbComp=getNumberOfComponents();
7438   int nbOfTuples=getNumberOfTuples();
7439   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
7440   int newNbOfTuples=(int)std::distance(bgTuples,endTuples);
7441   bool assignTech=true;
7442   if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
7443     {
7444       if(strictCompoCompare)
7445         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
7446     }
7447   else
7448     {
7449       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
7450       assignTech=false;
7451     }
7452   int *pt=getPointer()+bgComp;
7453   const int *srcPt=a->getConstPointer();
7454   if(assignTech)
7455     {
7456       for(const int *w=bgTuples;w!=endTuples;w++)
7457         for(int j=0;j<newNbOfComp;j++,srcPt++)
7458           {
7459             DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
7460             pt[(std::size_t)(*w)*nbComp+j*stepComp]=*srcPt;
7461           }
7462     }
7463   else
7464     {
7465       for(const int *w=bgTuples;w!=endTuples;w++)
7466         {
7467           const int *srcPt2=srcPt;
7468           for(int j=0;j<newNbOfComp;j++,srcPt2++)
7469             {
7470               DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
7471               pt[(std::size_t)(*w)*nbComp+j*stepComp]=*srcPt2;
7472             }
7473         }
7474     }
7475 }
7476
7477 /*!
7478  * Assign a given value to values at specified tuples and components of \a this array.
7479  * The tuples to assign to are defined by a C array of indices.
7480  * The components to assign to are defined by three values similar to parameters of
7481  * the Python function \c range(\c start,\c stop,\c step).
7482  *  \param [in] a - the value to assign.
7483  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
7484  *              assign \a a to.
7485  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
7486  *              pointer to a tuple index <em>(pi)</em> varies as this: 
7487  *              \a bgTuples <= \a pi < \a endTuples.
7488  *  \param [in] bgComp - index of the first component of \a this array to assign to.
7489  *  \param [in] endComp - index of the component before which the components to assign
7490  *              to are located.
7491  *  \param [in] stepComp - index increment to get index of the next component to assign to.
7492  *  \throw If \a this is not allocated.
7493  *  \throw If any index of tuple given by \a bgTuples is out of a valid range for 
7494  *         \a this array.
7495  *  \throw If parameters specifying components to assign to, do not give a
7496  *            non-empty range of increasing indices or indices are out of a valid range
7497  *            for \this array.
7498  *
7499  *  \ref py_mcdataarrayint_setpartofvaluessimple3 "Here is a Python example".
7500  */
7501 void DataArrayInt::setPartOfValuesSimple3(int a, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp) throw(INTERP_KERNEL::Exception)
7502 {
7503   const char msg[]="DataArrayInt::setPartOfValuesSimple3";
7504   checkAllocated();
7505   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
7506   int nbComp=getNumberOfComponents();
7507   int nbOfTuples=getNumberOfTuples();
7508   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
7509   int *pt=getPointer()+bgComp;
7510   for(const int *w=bgTuples;w!=endTuples;w++)
7511     for(int j=0;j<newNbOfComp;j++)
7512       {
7513         DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
7514         pt[(std::size_t)(*w)*nbComp+j*stepComp]=a;
7515       }
7516 }
7517
7518 void DataArrayInt::setPartOfValues4(const DataArrayInt *a, int bgTuples, int endTuples, int stepTuples, const int *bgComp, const int *endComp, bool strictCompoCompare) throw(INTERP_KERNEL::Exception)
7519 {
7520   if(!a)
7521     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValues4 : input DataArrayInt is NULL !");
7522   const char msg[]="DataArrayInt::setPartOfValues4";
7523   checkAllocated();
7524   a->checkAllocated();
7525   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
7526   int newNbOfComp=(int)std::distance(bgComp,endComp);
7527   int nbComp=getNumberOfComponents();
7528   for(const int *z=bgComp;z!=endComp;z++)
7529     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
7530   int nbOfTuples=getNumberOfTuples();
7531   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
7532   bool assignTech=true;
7533   if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
7534     {
7535       if(strictCompoCompare)
7536         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
7537     }
7538   else
7539     {
7540       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
7541       assignTech=false;
7542     }
7543   const int *srcPt=a->getConstPointer();
7544   int *pt=getPointer()+bgTuples*nbComp;
7545   if(assignTech)
7546     {
7547       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
7548         for(const int *z=bgComp;z!=endComp;z++,srcPt++)
7549           pt[*z]=*srcPt;
7550     }
7551   else
7552     {
7553       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
7554         {
7555           const int *srcPt2=srcPt;
7556           for(const int *z=bgComp;z!=endComp;z++,srcPt2++)
7557             pt[*z]=*srcPt2;
7558         }
7559     }
7560 }
7561
7562 void DataArrayInt::setPartOfValuesSimple4(int a, int bgTuples, int endTuples, int stepTuples, const int *bgComp, const int *endComp) throw(INTERP_KERNEL::Exception)
7563 {
7564   const char msg[]="DataArrayInt::setPartOfValuesSimple4";
7565   checkAllocated();
7566   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
7567   int nbComp=getNumberOfComponents();
7568   for(const int *z=bgComp;z!=endComp;z++)
7569     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
7570   int nbOfTuples=getNumberOfTuples();
7571   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
7572   int *pt=getPointer()+bgTuples*nbComp;
7573   for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
7574     for(const int *z=bgComp;z!=endComp;z++)
7575       pt[*z]=a;
7576 }
7577
7578 /*!
7579  * Copy some tuples from another DataArrayInt into specified tuples
7580  * of \a this array. Textual data is not copied. Both arrays must have equal number of
7581  * components.
7582  * Both the tuples to assign and the tuples to assign to are defined by a DataArrayInt.
7583  * All components of selected tuples are copied.
7584  *  \param [in] a - the array to copy values from.
7585  *  \param [in] tuplesSelec - the array specifying both source tuples of \a a and
7586  *              target tuples of \a this. \a tuplesSelec has two components, and the
7587  *              first component specifies index of the source tuple and the second
7588  *              one specifies index of the target tuple.
7589  *  \throw If \a this is not allocated.
7590  *  \throw If \a a is NULL.
7591  *  \throw If \a a is not allocated.
7592  *  \throw If \a tuplesSelec is NULL.
7593  *  \throw If \a tuplesSelec is not allocated.
7594  *  \throw If <em>this->getNumberOfComponents() != a->getNumberOfComponents()</em>.
7595  *  \throw If \a tuplesSelec->getNumberOfComponents() != 2.
7596  *  \throw If any tuple index given by \a tuplesSelec is out of a valid range for 
7597  *         the corresponding (\a this or \a a) array.
7598  */
7599 void DataArrayInt::setPartOfValuesAdv(const DataArrayInt *a, const DataArrayInt *tuplesSelec) throw(INTERP_KERNEL::Exception)
7600 {
7601   if(!a || !tuplesSelec)
7602     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValuesAdv : DataArrayInt pointer in input is NULL !");
7603   checkAllocated();
7604   a->checkAllocated();
7605   tuplesSelec->checkAllocated();
7606   int nbOfComp=getNumberOfComponents();
7607   if(nbOfComp!=a->getNumberOfComponents())
7608     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValuesAdv : This and a do not have the same number of components !");
7609   if(tuplesSelec->getNumberOfComponents()!=2)
7610     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValuesAdv : Expecting to have a tuple selector DataArrayInt instance with exactly 2 components !");
7611   int thisNt=getNumberOfTuples();
7612   int aNt=a->getNumberOfTuples();
7613   int *valsToSet=getPointer();
7614   const int *valsSrc=a->getConstPointer();
7615   for(const int *tuple=tuplesSelec->begin();tuple!=tuplesSelec->end();tuple+=2)
7616     {
7617       if(tuple[1]>=0 && tuple[1]<aNt)
7618         {
7619           if(tuple[0]>=0 && tuple[0]<thisNt)
7620             std::copy(valsSrc+nbOfComp*tuple[1],valsSrc+nbOfComp*(tuple[1]+1),valsToSet+nbOfComp*tuple[0]);
7621           else
7622             {
7623               std::ostringstream oss; oss << "DataArrayInt::setPartOfValuesAdv : Tuple #" << std::distance(tuplesSelec->begin(),tuple)/2;
7624               oss << " of 'tuplesSelec' request of tuple id #" << tuple[0] << " in 'this' ! It should be in [0," << thisNt << ") !";
7625               throw INTERP_KERNEL::Exception(oss.str().c_str());
7626             }
7627         }
7628       else
7629         {
7630           std::ostringstream oss; oss << "DataArrayInt::setPartOfValuesAdv : Tuple #" << std::distance(tuplesSelec->begin(),tuple)/2;
7631           oss << " of 'tuplesSelec' request of tuple id #" << tuple[1] << " in 'a' ! It should be in [0," << aNt << ") !";
7632           throw INTERP_KERNEL::Exception(oss.str().c_str());
7633         }
7634     }
7635 }
7636
7637 /*!
7638  * Copy some tuples from another DataArrayInt (\a a) into contiguous tuples
7639  * of \a this array. Textual data is not copied. Both arrays must have equal number of
7640  * components.
7641  * The tuples to assign to are defined by index of the first tuple, and
7642  * their number is defined by \a tuplesSelec->getNumberOfTuples().
7643  * The tuples to copy are defined by values of a DataArrayInt.
7644  * All components of selected tuples are copied.
7645  *  \param [in] tupleIdStart - index of the first tuple of \a this array to assign
7646  *              values to.
7647  *  \param [in] a - the array to copy values from.
7648  *  \param [in] tuplesSelec - the array specifying tuples of \a a to copy.
7649  *  \throw If \a this is not allocated.
7650  *  \throw If \a a is NULL.
7651  *  \throw If \a a is not allocated.
7652  *  \throw If \a tuplesSelec is NULL.
7653  *  \throw If \a tuplesSelec is not allocated.
7654  *  \throw If <em>this->getNumberOfComponents() != a->getNumberOfComponents()</em>.
7655  *  \throw If \a tuplesSelec->getNumberOfComponents() != 1.
7656  *  \throw If <em>tupleIdStart + tuplesSelec->getNumberOfTuples() > this->getNumberOfTuples().</em>
7657  *  \throw If any tuple index given by \a tuplesSelec is out of a valid range for 
7658  *         \a a array.
7659  */
7660 void DataArrayInt::setContigPartOfSelectedValues(int tupleIdStart, const DataArray *aBase, const DataArrayInt *tuplesSelec) throw(INTERP_KERNEL::Exception)
7661 {
7662   if(!aBase || !tuplesSelec)
7663     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues : input DataArray is NULL !");
7664   const DataArrayInt *a=dynamic_cast<const DataArrayInt *>(aBase);
7665   if(!a)
7666     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues : input DataArray aBase is not a DataArrayInt !");
7667   checkAllocated();
7668   a->checkAllocated();
7669   tuplesSelec->checkAllocated();
7670   int nbOfComp=getNumberOfComponents();
7671   if(nbOfComp!=a->getNumberOfComponents())
7672     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues : This and a do not have the same number of components !");
7673   if(tuplesSelec->getNumberOfComponents()!=1)
7674     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues : Expecting to have a tuple selector DataArrayInt instance with exactly 1 component !");
7675   int thisNt=getNumberOfTuples();
7676   int aNt=a->getNumberOfTuples();
7677   int nbOfTupleToWrite=tuplesSelec->getNumberOfTuples();
7678   int *valsToSet=getPointer()+tupleIdStart*nbOfComp;
7679   if(tupleIdStart+nbOfTupleToWrite>thisNt)
7680     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues : invalid number range of values to write !");
7681   const int *valsSrc=a->getConstPointer();
7682   for(const int *tuple=tuplesSelec->begin();tuple!=tuplesSelec->end();tuple++,valsToSet+=nbOfComp)
7683     {
7684       if(*tuple>=0 && *tuple<aNt)
7685         {
7686           std::copy(valsSrc+nbOfComp*(*tuple),valsSrc+nbOfComp*(*tuple+1),valsToSet);
7687         }
7688       else
7689         {
7690           std::ostringstream oss; oss << "DataArrayInt::setContigPartOfSelectedValues : Tuple #" << std::distance(tuplesSelec->begin(),tuple);
7691           oss << " of 'tuplesSelec' request of tuple id #" << *tuple << " in 'a' ! It should be in [0," << aNt << ") !";
7692           throw INTERP_KERNEL::Exception(oss.str().c_str());
7693         }
7694     }
7695 }
7696
7697 /*!
7698  * Copy some tuples from another DataArrayInt (\a a) into contiguous tuples
7699  * of \a this array. Textual data is not copied. Both arrays must have equal number of
7700  * components.
7701  * The tuples to copy are defined by three values similar to parameters of
7702  * the Python function \c range(\c start,\c stop,\c step).
7703  * The tuples to assign to are defined by index of the first tuple, and
7704  * their number is defined by number of tuples to copy.
7705  * All components of selected tuples are copied.
7706  *  \param [in] tupleIdStart - index of the first tuple of \a this array to assign
7707  *              values to.
7708  *  \param [in] a - the array to copy values from.
7709  *  \param [in] bg - index of the first tuple to copy of the array \a a.
7710  *  \param [in] end2 - index of the tuple of \a a before which the tuples to copy
7711  *              are located.
7712  *  \param [in] step - index increment to get index of the next tuple to copy.
7713  *  \throw If \a this is not allocated.
7714  *  \throw If \a a is NULL.
7715  *  \throw If \a a is not allocated.
7716  *  \throw If <em>this->getNumberOfComponents() != a->getNumberOfComponents()</em>.
7717  *  \throw If <em>tupleIdStart + len(range(bg,end2,step)) > this->getNumberOfTuples().</em>
7718  *  \throw If parameters specifying tuples to copy, do not give a
7719  *            non-empty range of increasing indices or indices are out of a valid range
7720  *            for the array \a a.
7721  */
7722 void DataArrayInt::setContigPartOfSelectedValues2(int tupleIdStart, const DataArray *aBase, int bg, int end2, int step) throw(INTERP_KERNEL::Exception)
7723 {
7724   if(!aBase)
7725     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues2 : input DataArray is NULL !");
7726   const DataArrayInt *a=dynamic_cast<const DataArrayInt *>(aBase);
7727   if(!a)
7728     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues2 : input DataArray aBase is not a DataArrayInt !");
7729   checkAllocated();
7730   a->checkAllocated();
7731   int nbOfComp=getNumberOfComponents();
7732   const char msg[]="DataArrayInt::setContigPartOfSelectedValues2";
7733   int nbOfTupleToWrite=DataArray::GetNumberOfItemGivenBES(bg,end2,step,msg);
7734   if(nbOfComp!=a->getNumberOfComponents())
7735     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues2 : This and a do not have the same number of components !");
7736   int thisNt=getNumberOfTuples();
7737   int aNt=a->getNumberOfTuples();
7738   int *valsToSet=getPointer()+tupleIdStart*nbOfComp;
7739   if(tupleIdStart+nbOfTupleToWrite>thisNt)
7740     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues2 : invalid number range of values to write !");
7741   if(end2>aNt)
7742     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues2 : invalid range of values to read !");
7743   const int *valsSrc=a->getConstPointer()+bg*nbOfComp;
7744   for(int i=0;i<nbOfTupleToWrite;i++,valsToSet+=nbOfComp,valsSrc+=step*nbOfComp)
7745     {
7746       std::copy(valsSrc,valsSrc+nbOfComp,valsToSet);
7747     }
7748 }
7749
7750 /*!
7751  * Returns a value located at specified tuple and component.
7752  * This method is equivalent to DataArrayInt::getIJ() except that validity of
7753  * parameters is checked. So this method is safe but expensive if used to go through
7754  * all values of \a this.
7755  *  \param [in] tupleId - index of tuple of interest.
7756  *  \param [in] compoId - index of component of interest.
7757  *  \return double - value located by \a tupleId and \a compoId.
7758  *  \throw If \a this is not allocated.
7759  *  \throw If condition <em>( 0 <= tupleId < this->getNumberOfTuples() )</em> is violated.
7760  *  \throw If condition <em>( 0 <= compoId < this->getNumberOfComponents() )</em> is violated.
7761  */
7762 int DataArrayInt::getIJSafe(int tupleId, int compoId) const throw(INTERP_KERNEL::Exception)
7763 {
7764   checkAllocated();
7765   if(tupleId<0 || tupleId>=getNumberOfTuples())
7766     {
7767       std::ostringstream oss; oss << "DataArrayInt::getIJSafe : request for tupleId " << tupleId << " should be in [0," << getNumberOfTuples() << ") !";
7768       throw INTERP_KERNEL::Exception(oss.str().c_str());
7769     }
7770   if(compoId<0 || compoId>=getNumberOfComponents())
7771     {
7772       std::ostringstream oss; oss << "DataArrayInt::getIJSafe : request for compoId " << compoId << " should be in [0," << getNumberOfComponents() << ") !";
7773       throw INTERP_KERNEL::Exception(oss.str().c_str());
7774     }
7775   return _mem[tupleId*_info_on_compo.size()+compoId];
7776 }
7777
7778 /*!
7779  * Returns the last value of \a this. 
7780  *  \return double - the last value of \a this array.
7781  *  \throw If \a this is not allocated.
7782  *  \throw If \a this->getNumberOfComponents() != 1.
7783  *  \throw If \a this->getNumberOfTuples() < 1.
7784  */
7785 int DataArrayInt::back() const throw(INTERP_KERNEL::Exception)
7786 {
7787   checkAllocated();
7788   if(getNumberOfComponents()!=1)
7789     throw INTERP_KERNEL::Exception("DataArrayInt::back : number of components not equal to one !");
7790   int nbOfTuples=getNumberOfTuples();
7791   if(nbOfTuples<1)
7792     throw INTERP_KERNEL::Exception("DataArrayInt::back : number of tuples must be >= 1 !");
7793   return *(getConstPointer()+nbOfTuples-1);
7794 }
7795
7796 /*!
7797  * Assign pointer to one array to a pointer to another appay. Reference counter of
7798  * \a arrayToSet is incremented / decremented.
7799  *  \param [in] newArray - the pointer to array to assign to \a arrayToSet.
7800  *  \param [in,out] arrayToSet - the pointer to array to assign to.
7801  */
7802 void DataArrayInt::SetArrayIn(DataArrayInt *newArray, DataArrayInt* &arrayToSet)
7803 {
7804   if(newArray!=arrayToSet)
7805     {
7806       if(arrayToSet)
7807         arrayToSet->decrRef();
7808       arrayToSet=newArray;
7809       if(arrayToSet)
7810         arrayToSet->incrRef();
7811     }
7812 }
7813
7814 DataArrayIntIterator *DataArrayInt::iterator() throw(INTERP_KERNEL::Exception)
7815 {
7816   return new DataArrayIntIterator(this);
7817 }
7818
7819 /*!
7820  * Creates a new DataArrayInt containing IDs (indices) of tuples holding value equal to a
7821  * given one.
7822  *  \param [in] val - the value to find within \a this.
7823  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
7824  *          array using decrRef() as it is no more needed.
7825  *  \throw If \a this is not allocated.
7826  *  \throw If \a this->getNumberOfComponents() != 1.
7827  */
7828 DataArrayInt *DataArrayInt::getIdsEqual(int val) const throw(INTERP_KERNEL::Exception)
7829 {
7830   checkAllocated();
7831   if(getNumberOfComponents()!=1)
7832     throw INTERP_KERNEL::Exception("DataArrayInt::getIdsEqual : the array must have only one component, you can call 'rearrange' method before !");
7833   const int *cptr=getConstPointer();
7834   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
7835   int nbOfTuples=getNumberOfTuples();
7836   for(int i=0;i<nbOfTuples;i++,cptr++)
7837     if(*cptr==val)
7838       ret->pushBackSilent(i);
7839   return ret.retn();
7840 }
7841
7842 /*!
7843  * Creates a new DataArrayInt containing IDs (indices) of tuples holding value \b not
7844  * equal to a given one. 
7845  *  \param [in] val - the value to ignore within \a this.
7846  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
7847  *          array using decrRef() as it is no more needed.
7848  *  \throw If \a this is not allocated.
7849  *  \throw If \a this->getNumberOfComponents() != 1.
7850  */
7851 DataArrayInt *DataArrayInt::getIdsNotEqual(int val) const throw(INTERP_KERNEL::Exception)
7852 {
7853   checkAllocated();
7854   if(getNumberOfComponents()!=1)
7855     throw INTERP_KERNEL::Exception("DataArrayInt::getIdsNotEqual : the array must have only one component, you can call 'rearrange' method before !");
7856   const int *cptr=getConstPointer();
7857   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
7858   int nbOfTuples=getNumberOfTuples();
7859   for(int i=0;i<nbOfTuples;i++,cptr++)
7860     if(*cptr!=val)
7861       ret->pushBackSilent(i);
7862   return ret.retn();
7863 }
7864
7865
7866 /*!
7867  * Assigns \a newValue to all elements holding \a oldValue within \a this
7868  * one-dimensional array.
7869  *  \param [in] oldValue - the value to replace.
7870  *  \param [in] newValue - the value to assign.
7871  *  \return int - number of replacements performed.
7872  *  \throw If \a this is not allocated.
7873  *  \throw If \a this->getNumberOfComponents() != 1.
7874  */
7875 int DataArrayInt::changeValue(int oldValue, int newValue) throw(INTERP_KERNEL::Exception)
7876 {
7877   checkAllocated();
7878   if(getNumberOfComponents()!=1)
7879     throw INTERP_KERNEL::Exception("DataArrayInt::changeValue : the array must have only one component, you can call 'rearrange' method before !");
7880   int *start=getPointer();
7881   int *end2=start+getNbOfElems();
7882   int ret=0;
7883   for(int *val=start;val!=end2;val++)
7884     {
7885       if(*val==oldValue)
7886         {
7887           *val=newValue;
7888           ret++;
7889         }
7890     }
7891   return ret;
7892 }
7893
7894 /*!
7895  * Creates a new DataArrayInt containing IDs (indices) of tuples holding value equal to
7896  * one of given values.
7897  *  \param [in] valsBg - an array of values to find within \a this array.
7898  *  \param [in] valsEnd - specifies the end of the array \a valsBg, so that
7899  *              the last value of \a valsBg is \a valsEnd[ -1 ].
7900  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
7901  *          array using decrRef() as it is no more needed.
7902  *  \throw If \a this->getNumberOfComponents() != 1.
7903  */
7904 DataArrayInt *DataArrayInt::getIdsEqualList(const int *valsBg, const int *valsEnd) const throw(INTERP_KERNEL::Exception)
7905 {
7906   if(getNumberOfComponents()!=1)
7907     throw INTERP_KERNEL::Exception("DataArrayInt::getIdsEqualList : the array must have only one component, you can call 'rearrange' method before !");
7908   std::set<int> vals2(valsBg,valsEnd);
7909   const int *cptr=getConstPointer();
7910   std::vector<int> res;
7911   int nbOfTuples=getNumberOfTuples();
7912   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
7913   for(int i=0;i<nbOfTuples;i++,cptr++)
7914     if(vals2.find(*cptr)!=vals2.end())
7915       ret->pushBackSilent(i);
7916   return ret.retn();
7917 }
7918
7919 /*!
7920  * Creates a new DataArrayInt containing IDs (indices) of tuples holding values \b not
7921  * equal to any of given values.
7922  *  \param [in] valsBg - an array of values to ignore within \a this array.
7923  *  \param [in] valsEnd - specifies the end of the array \a valsBg, so that
7924  *              the last value of \a valsBg is \a valsEnd[ -1 ].
7925  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
7926  *          array using decrRef() as it is no more needed.
7927  *  \throw If \a this->getNumberOfComponents() != 1.
7928  */
7929 DataArrayInt *DataArrayInt::getIdsNotEqualList(const int *valsBg, const int *valsEnd) const throw(INTERP_KERNEL::Exception)
7930 {
7931   if(getNumberOfComponents()!=1)
7932     throw INTERP_KERNEL::Exception("DataArrayInt::getIdsNotEqualList : the array must have only one component, you can call 'rearrange' method before !");
7933   std::set<int> vals2(valsBg,valsEnd);
7934   const int *cptr=getConstPointer();
7935   std::vector<int> res;
7936   int nbOfTuples=getNumberOfTuples();
7937   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
7938   for(int i=0;i<nbOfTuples;i++,cptr++)
7939     if(vals2.find(*cptr)==vals2.end())
7940       ret->pushBackSilent(i);
7941   return ret.retn();
7942 }
7943
7944 /*!
7945  * This method is an extension of DataArrayInt::locateValue method because this method works for DataArrayInt with
7946  * any number of components excepted 0 (an INTERP_KERNEL::Exception is thrown in this case).
7947  * This method searches in \b this is there is a tuple that matched the input parameter \b tupl.
7948  * If any the tuple id is returned. If not -1 is returned.
7949  * 
7950  * This method throws an INTERP_KERNEL::Exception if the number of components in \b this mismatches with the size of
7951  * the input vector. An INTERP_KERNEL::Exception is thrown too if \b this is not allocated.
7952  *
7953  * \return tuple id where \b tupl is. -1 if no such tuple exists in \b this.
7954  * \sa DataArrayInt::search, DataArrayInt::presenceOfTuple.
7955  */
7956 int DataArrayInt::locateTuple(const std::vector<int>& tupl) const throw(INTERP_KERNEL::Exception)
7957 {
7958   checkAllocated();
7959   int nbOfCompo=getNumberOfComponents();
7960   if(nbOfCompo==0)
7961     throw INTERP_KERNEL::Exception("DataArrayInt::locateTuple : 0 components in 'this' !");
7962   if(nbOfCompo!=(int)tupl.size())
7963     {
7964       std::ostringstream oss; oss << "DataArrayInt::locateTuple : 'this' contains " << nbOfCompo << " components and searching for a tuple of length " << tupl.size() << " !";
7965       throw INTERP_KERNEL::Exception(oss.str().c_str());
7966     }
7967   const int *cptr=getConstPointer();
7968   std::size_t nbOfVals=getNbOfElems();
7969   for(const int *work=cptr;work!=cptr+nbOfVals;)
7970     {
7971       work=std::search(work,cptr+nbOfVals,tupl.begin(),tupl.end());
7972       if(work!=cptr+nbOfVals)
7973         {
7974           if(std::distance(cptr,work)%nbOfCompo!=0)
7975             work++;
7976           else
7977             return std::distance(cptr,work)/nbOfCompo;
7978         }
7979     }
7980   return -1;
7981 }
7982
7983 /*!
7984  * This method searches the sequence specified in input parameter \b vals in \b this.
7985  * This works only for DataArrayInt having number of components equal to one (if not an INTERP_KERNEL::Exception will be thrown).
7986  * This method differs from DataArrayInt::locateTuple in that the position is internal raw data is not considered here contrary to DataArrayInt::locateTuple.
7987  * \sa DataArrayInt::locateTuple
7988  */
7989 int DataArrayInt::search(const std::vector<int>& vals) const throw(INTERP_KERNEL::Exception)
7990 {
7991   checkAllocated();
7992   int nbOfCompo=getNumberOfComponents();
7993   if(nbOfCompo!=1)
7994     throw INTERP_KERNEL::Exception("DataArrayInt::search : works only for DataArrayInt instance with one component !");
7995   const int *cptr=getConstPointer();
7996   std::size_t nbOfVals=getNbOfElems();
7997   const int *loc=std::search(cptr,cptr+nbOfVals,vals.begin(),vals.end());
7998   if(loc!=cptr+nbOfVals)
7999     return std::distance(cptr,loc);
8000   return -1;
8001 }
8002
8003 /*!
8004  * This method expects to be called when number of components of this is equal to one.
8005  * This method returns the tuple id, if it exists, of the first tuple equal to \b value.
8006  * If not any tuple contains \b value -1 is returned.
8007  * \sa DataArrayInt::presenceOfValue
8008  */
8009 int DataArrayInt::locateValue(int value) const throw(INTERP_KERNEL::Exception)
8010 {
8011   checkAllocated();
8012   if(getNumberOfComponents()!=1)
8013     throw INTERP_KERNEL::Exception("DataArrayInt::presenceOfValue : the array must have only one component, you can call 'rearrange' method before !");
8014   const int *cptr=getConstPointer();
8015   int nbOfTuples=getNumberOfTuples();
8016   const int *ret=std::find(cptr,cptr+nbOfTuples,value);
8017   if(ret!=cptr+nbOfTuples)
8018     return std::distance(cptr,ret);
8019   return -1;
8020 }
8021
8022 /*!
8023  * This method expects to be called when number of components of this is equal to one.
8024  * This method returns the tuple id, if it exists, of the first tuple so that the value is contained in \b vals.
8025  * If not any tuple contains one of the values contained in 'vals' false is returned.
8026  * \sa DataArrayInt::presenceOfValue
8027  */
8028 int DataArrayInt::locateValue(const std::vector<int>& vals) const throw(INTERP_KERNEL::Exception)
8029 {
8030   checkAllocated();
8031   if(getNumberOfComponents()!=1)
8032     throw INTERP_KERNEL::Exception("DataArrayInt::presenceOfValue : the array must have only one component, you can call 'rearrange' method before !");
8033   std::set<int> vals2(vals.begin(),vals.end());
8034   const int *cptr=getConstPointer();
8035   int nbOfTuples=getNumberOfTuples();
8036   for(const int *w=cptr;w!=cptr+nbOfTuples;w++)
8037     if(vals2.find(*w)!=vals2.end())
8038       return std::distance(cptr,w);
8039   return -1;
8040 }
8041
8042 /*!
8043  * This method returns the number of values in \a this that are equals to input parameter \a value.
8044  * This method only works for single component array.
8045  *
8046  * \return a value in [ 0, \c this->getNumberOfTuples() )
8047  *
8048  * \throw If \a this is not allocated
8049  *
8050  */
8051 int DataArrayInt::count(int value) const throw(INTERP_KERNEL::Exception)
8052 {
8053   int ret=0;
8054   checkAllocated();
8055   if(getNumberOfComponents()!=1)
8056     throw INTERP_KERNEL::Exception("DataArrayInt::count : must be applied on DataArrayInt with only one component, you can call 'rearrange' method before !");
8057   const int *vals=begin();
8058   int nbOfTuples=getNumberOfTuples();
8059   for(int i=0;i<nbOfTuples;i++,vals++)
8060     if(*vals==value)
8061       ret++;
8062   return ret;
8063 }
8064
8065 /*!
8066  * This method is an extension of DataArrayInt::presenceOfValue method because this method works for DataArrayInt with
8067  * any number of components excepted 0 (an INTERP_KERNEL::Exception is thrown in this case).
8068  * This method searches in \b this is there is a tuple that matched the input parameter \b tupl.
8069  * This method throws an INTERP_KERNEL::Exception if the number of components in \b this mismatches with the size of
8070  * the input vector. An INTERP_KERNEL::Exception is thrown too if \b this is not allocated.
8071  * \sa DataArrayInt::locateTuple
8072  */
8073 bool DataArrayInt::presenceOfTuple(const std::vector<int>& tupl) const throw(INTERP_KERNEL::Exception)
8074 {
8075   return locateTuple(tupl)!=-1;
8076 }
8077
8078
8079 /*!
8080  * Returns \a true if a given value is present within \a this one-dimensional array.
8081  *  \param [in] value - the value to find within \a this array.
8082  *  \return bool - \a true in case if \a value is present within \a this array.
8083  *  \throw If \a this is not allocated.
8084  *  \throw If \a this->getNumberOfComponents() != 1.
8085  *  \sa locateValue()
8086  */
8087 bool DataArrayInt::presenceOfValue(int value) const throw(INTERP_KERNEL::Exception)
8088 {
8089   return locateValue(value)!=-1;
8090 }
8091
8092 /*!
8093  * This method expects to be called when number of components of this is equal to one.
8094  * This method returns true if it exists a tuple so that the value is contained in \b vals.
8095  * If not any tuple contains one of the values contained in 'vals' false is returned.
8096  * \sa DataArrayInt::locateValue
8097  */
8098 bool DataArrayInt::presenceOfValue(const std::vector<int>& vals) const throw(INTERP_KERNEL::Exception)
8099 {
8100   return locateValue(vals)!=-1;
8101 }
8102
8103 /*!
8104  * Accumulates values of each component of \a this array.
8105  *  \param [out] res - an array of length \a this->getNumberOfComponents(), allocated 
8106  *         by the caller, that is filled by this method with sum value for each
8107  *         component.
8108  *  \throw If \a this is not allocated.
8109  */
8110 void DataArrayInt::accumulate(int *res) const throw(INTERP_KERNEL::Exception)
8111 {
8112   checkAllocated();
8113   const int *ptr=getConstPointer();
8114   int nbTuple=getNumberOfTuples();
8115   int nbComps=getNumberOfComponents();
8116   std::fill(res,res+nbComps,0);
8117   for(int i=0;i<nbTuple;i++)
8118     std::transform(ptr+i*nbComps,ptr+(i+1)*nbComps,res,res,std::plus<int>());
8119 }
8120
8121 int DataArrayInt::accumulate(int compId) const throw(INTERP_KERNEL::Exception)
8122 {
8123   checkAllocated();
8124   const int *ptr=getConstPointer();
8125   int nbTuple=getNumberOfTuples();
8126   int nbComps=getNumberOfComponents();
8127   if(compId<0 || compId>=nbComps)
8128     throw INTERP_KERNEL::Exception("DataArrayInt::accumulate : Invalid compId specified : No such nb of components !");
8129   int ret=0;
8130   for(int i=0;i<nbTuple;i++)
8131     ret+=ptr[i*nbComps+compId];
8132   return ret;
8133 }
8134
8135 /*!
8136  * This method accumulate using addition tuples in \a this using input index array [ \a bgOfIndex, \a endOfIndex ).
8137  * The returned array will have same number of components than \a this and number of tuples equal to
8138  * \c std::distance(bgOfIndex,endOfIndex) \b minus \b one.
8139  *
8140  * The input index array is expected to be ascendingly sorted in which the all referenced ids should be in [0, \c this->getNumberOfTuples).
8141  *
8142  * \param [in] bgOfIndex - begin (included) of the input index array.
8143  * \param [in] endOfIndex - end (excluded) of the input index array.
8144  * \return DataArrayInt * - the new instance having the same number of components than \a this.
8145  * 
8146  * \throw If bgOfIndex or end is NULL.
8147  * \throw If input index array is not ascendingly sorted.
8148  * \throw If there is an id in [ \a bgOfIndex, \a endOfIndex ) not in [0, \c this->getNumberOfTuples).
8149  * \throw If std::distance(bgOfIndex,endOfIndex)==0.
8150  */
8151 DataArrayInt *DataArrayInt::accumulatePerChunck(const int *bgOfIndex, const int *endOfIndex) const throw(INTERP_KERNEL::Exception)
8152 {
8153   if(!bgOfIndex || !endOfIndex)
8154     throw INTERP_KERNEL::Exception("DataArrayInt::accumulatePerChunck : input pointer NULL !");
8155   checkAllocated();
8156   int nbCompo=getNumberOfComponents();
8157   int nbOfTuples=getNumberOfTuples();
8158   int sz=(int)std::distance(bgOfIndex,endOfIndex);
8159   if(sz<1)
8160     throw INTERP_KERNEL::Exception("DataArrayInt::accumulatePerChunck : invalid size of input index array !");
8161   sz--;
8162   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(sz,nbCompo);
8163   const int *w=bgOfIndex;
8164   if(*w<0 || *w>=nbOfTuples)
8165     throw INTERP_KERNEL::Exception("DataArrayInt::accumulatePerChunck : The first element of the input index not in [0,nbOfTuples) !");
8166   const int *srcPt=begin()+(*w)*nbCompo;
8167   int *tmp=ret->getPointer();
8168   for(int i=0;i<sz;i++,tmp+=nbCompo,w++)
8169     {
8170       std::fill(tmp,tmp+nbCompo,0.);
8171       if(w[1]>=w[0])
8172         {
8173           for(int j=w[0];j<w[1];j++,srcPt+=nbCompo)
8174             {
8175               if(j>=0 && j<nbOfTuples)
8176                 std::transform(srcPt,srcPt+nbCompo,tmp,tmp,std::plus<int>());
8177               else
8178                 {
8179                   std::ostringstream oss; oss << "DataArrayInt::accumulatePerChunck : At rank #" << i << " the input index array points to id " << j << " should be in [0," << nbOfTuples << ") !";
8180                   throw INTERP_KERNEL::Exception(oss.str().c_str());
8181                 }
8182             }
8183         }
8184       else
8185         {
8186           std::ostringstream oss; oss << "DataArrayInt::accumulatePerChunck : At rank #" << i << " the input index array is not in ascendingly sorted.";
8187           throw INTERP_KERNEL::Exception(oss.str().c_str());
8188         }
8189     }
8190   ret->copyStringInfoFrom(*this);
8191   return ret.retn();
8192 }
8193
8194 /*!
8195  * Returns a new DataArrayInt by concatenating two given arrays, so that (1) the number
8196  * of tuples in the result array is <em> a1->getNumberOfTuples() + a2->getNumberOfTuples() -
8197  * offsetA2</em> and (2)
8198  * the number of component in the result array is same as that of each of given arrays.
8199  * First \a offsetA2 tuples of \a a2 are skipped and thus are missing from the result array.
8200  * Info on components is copied from the first of the given arrays. Number of components
8201  * in the given arrays must be the same.
8202  *  \param [in] a1 - an array to include in the result array.
8203  *  \param [in] a2 - another array to include in the result array.
8204  *  \param [in] offsetA2 - number of tuples of \a a2 to skip.
8205  *  \return DataArrayInt * - the new instance of DataArrayInt.
8206  *          The caller is to delete this result array using decrRef() as it is no more
8207  *          needed.
8208  *  \throw If either \a a1 or \a a2 is NULL.
8209  *  \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents().
8210  */
8211 DataArrayInt *DataArrayInt::Aggregate(const DataArrayInt *a1, const DataArrayInt *a2, int offsetA2)
8212 {
8213   if(!a1 || !a2)
8214     throw INTERP_KERNEL::Exception("DataArrayInt::Aggregate : input DataArrayInt instance is NULL !");
8215   int nbOfComp=a1->getNumberOfComponents();
8216   if(nbOfComp!=a2->getNumberOfComponents())
8217     throw INTERP_KERNEL::Exception("Nb of components mismatch for array Aggregation !");
8218   int nbOfTuple1=a1->getNumberOfTuples();
8219   int nbOfTuple2=a2->getNumberOfTuples();
8220   DataArrayInt *ret=DataArrayInt::New();
8221   ret->alloc(nbOfTuple1+nbOfTuple2-offsetA2,nbOfComp);
8222   int *pt=std::copy(a1->getConstPointer(),a1->getConstPointer()+nbOfTuple1*nbOfComp,ret->getPointer());
8223   std::copy(a2->getConstPointer()+offsetA2*nbOfComp,a2->getConstPointer()+nbOfTuple2*nbOfComp,pt);
8224   ret->copyStringInfoFrom(*a1);
8225   return ret;
8226 }
8227
8228 /*!
8229  * Returns a new DataArrayInt by concatenating all given arrays, so that (1) the number
8230  * of tuples in the result array is a sum of the number of tuples of given arrays and (2)
8231  * the number of component in the result array is same as that of each of given arrays.
8232  * Info on components is copied from the first of the given arrays. Number of components
8233  * in the given arrays must be  the same.
8234  *  \param [in] arr - a sequence of arrays to include in the result array.
8235  *  \return DataArrayInt * - the new instance of DataArrayInt.
8236  *          The caller is to delete this result array using decrRef() as it is no more
8237  *          needed.
8238  *  \throw If all arrays within \a arr are NULL.
8239  *  \throw If getNumberOfComponents() of arrays within \a arr.
8240  */
8241 DataArrayInt *DataArrayInt::Aggregate(const std::vector<const DataArrayInt *>& arr) throw(INTERP_KERNEL::Exception)
8242 {
8243   std::vector<const DataArrayInt *> a;
8244   for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
8245     if(*it4)
8246       a.push_back(*it4);
8247   if(a.empty())
8248     throw INTERP_KERNEL::Exception("DataArrayInt::Aggregate : input list must be NON EMPTY !");
8249   std::vector<const DataArrayInt *>::const_iterator it=a.begin();
8250   int nbOfComp=(*it)->getNumberOfComponents();
8251   int nbt=(*it++)->getNumberOfTuples();
8252   for(int i=1;it!=a.end();it++,i++)
8253     {
8254       if((*it)->getNumberOfComponents()!=nbOfComp)
8255         throw INTERP_KERNEL::Exception("DataArrayInt::Aggregate : Nb of components mismatch for array aggregation !");
8256       nbt+=(*it)->getNumberOfTuples();
8257     }
8258   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
8259   ret->alloc(nbt,nbOfComp);
8260   int *pt=ret->getPointer();
8261   for(it=a.begin();it!=a.end();it++)
8262     pt=std::copy((*it)->getConstPointer(),(*it)->getConstPointer()+(*it)->getNbOfElems(),pt);
8263   ret->copyStringInfoFrom(*(a[0]));
8264   return ret.retn();
8265 }
8266
8267 /*!
8268  * Returns the maximal value and its location within \a this one-dimensional array.
8269  *  \param [out] tupleId - index of the tuple holding the maximal value.
8270  *  \return int - the maximal value among all values of \a this array.
8271  *  \throw If \a this->getNumberOfComponents() != 1
8272  *  \throw If \a this->getNumberOfTuples() < 1
8273  */
8274 int DataArrayInt::getMaxValue(int& tupleId) const throw(INTERP_KERNEL::Exception)
8275 {
8276   checkAllocated();
8277   if(getNumberOfComponents()!=1)
8278     throw INTERP_KERNEL::Exception("DataArrayInt::getMaxValue : must be applied on DataArrayInt with only one component !");
8279   int nbOfTuples=getNumberOfTuples();
8280   if(nbOfTuples<=0)
8281     throw INTERP_KERNEL::Exception("DataArrayInt::getMaxValue : array exists but number of tuples must be > 0 !");
8282   const int *vals=getConstPointer();
8283   const int *loc=std::max_element(vals,vals+nbOfTuples);
8284   tupleId=(int)std::distance(vals,loc);
8285   return *loc;
8286 }
8287
8288 /*!
8289  * Returns the maximal value within \a this array that is allowed to have more than
8290  *  one component.
8291  *  \return int - the maximal value among all values of \a this array.
8292  *  \throw If \a this is not allocated.
8293  */
8294 int DataArrayInt::getMaxValueInArray() const throw(INTERP_KERNEL::Exception)
8295 {
8296   checkAllocated();
8297   const int *loc=std::max_element(begin(),end());
8298   return *loc;
8299 }
8300
8301 /*!
8302  * Returns the minimal value and its location within \a this one-dimensional array.
8303  *  \param [out] tupleId - index of the tuple holding the minimal value.
8304  *  \return int - the minimal value among all values of \a this array.
8305  *  \throw If \a this->getNumberOfComponents() != 1
8306  *  \throw If \a this->getNumberOfTuples() < 1
8307  */
8308 int DataArrayInt::getMinValue(int& tupleId) const throw(INTERP_KERNEL::Exception)
8309 {
8310   checkAllocated();
8311   if(getNumberOfComponents()!=1)
8312     throw INTERP_KERNEL::Exception("DataArrayInt::getMaxValue : must be applied on DataArrayInt with only one component !");
8313   int nbOfTuples=getNumberOfTuples();
8314   if(nbOfTuples<=0)
8315     throw INTERP_KERNEL::Exception("DataArrayInt::getMaxValue : array exists but number of tuples must be > 0 !");
8316   const int *vals=getConstPointer();
8317   const int *loc=std::min_element(vals,vals+nbOfTuples);
8318   tupleId=(int)std::distance(vals,loc);
8319   return *loc;
8320 }
8321
8322 /*!
8323  * Returns the minimal value within \a this array that is allowed to have more than
8324  *  one component.
8325  *  \return int - the minimal value among all values of \a this array.
8326  *  \throw If \a this is not allocated.
8327  */
8328 int DataArrayInt::getMinValueInArray() const throw(INTERP_KERNEL::Exception)
8329 {
8330   checkAllocated();
8331   const int *loc=std::min_element(begin(),end());
8332   return *loc;
8333 }
8334
8335 /*!
8336  * Converts every value of \a this array to its absolute value.
8337  *  \throw If \a this is not allocated.
8338  */
8339 void DataArrayInt::abs() throw(INTERP_KERNEL::Exception)
8340 {
8341   checkAllocated();
8342   int *ptr=getPointer();
8343   std::size_t nbOfElems=getNbOfElems();
8344   std::transform(ptr,ptr+nbOfElems,ptr,std::ptr_fun<int,int>(std::abs));
8345   declareAsNew();
8346 }
8347
8348 /*!
8349  * Apply a liner function to a given component of \a this array, so that
8350  * an array element <em>(x)</em> becomes \f$ a * x + b \f$.
8351  *  \param [in] a - the first coefficient of the function.
8352  *  \param [in] b - the second coefficient of the function.
8353  *  \param [in] compoId - the index of component to modify.
8354  *  \throw If \a this is not allocated.
8355  */
8356 void DataArrayInt::applyLin(int a, int b, int compoId) throw(INTERP_KERNEL::Exception)
8357 {
8358   checkAllocated();
8359   int *ptr=getPointer()+compoId;
8360   int nbOfComp=getNumberOfComponents();
8361   int nbOfTuple=getNumberOfTuples();
8362   for(int i=0;i<nbOfTuple;i++,ptr+=nbOfComp)
8363     *ptr=a*(*ptr)+b;
8364   declareAsNew();
8365 }
8366
8367 /*!
8368  * Apply a liner function to all elements of \a this array, so that
8369  * an element _x_ becomes \f$ a * x + b \f$.
8370  *  \param [in] a - the first coefficient of the function.
8371  *  \param [in] b - the second coefficient of the function.
8372  *  \throw If \a this is not allocated.
8373  */
8374 void DataArrayInt::applyLin(int a, int b) throw(INTERP_KERNEL::Exception)
8375 {
8376   checkAllocated();
8377   int *ptr=getPointer();
8378   std::size_t nbOfElems=getNbOfElems();
8379   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
8380     *ptr=a*(*ptr)+b;
8381   declareAsNew();
8382 }
8383
8384 /*!
8385  * Returns a full copy of \a this array except that sign of all elements is reversed.
8386  *  \return DataArrayInt * - the new instance of DataArrayInt containing the
8387  *          same number of tuples and component as \a this array.
8388  *          The caller is to delete this result array using decrRef() as it is no more
8389  *          needed.
8390  *  \throw If \a this is not allocated.
8391  */
8392 DataArrayInt *DataArrayInt::negate() const throw(INTERP_KERNEL::Exception)
8393 {
8394   checkAllocated();
8395   DataArrayInt *newArr=DataArrayInt::New();
8396   int nbOfTuples=getNumberOfTuples();
8397   int nbOfComp=getNumberOfComponents();
8398   newArr->alloc(nbOfTuples,nbOfComp);
8399   const int *cptr=getConstPointer();
8400   std::transform(cptr,cptr+nbOfTuples*nbOfComp,newArr->getPointer(),std::negate<int>());
8401   newArr->copyStringInfoFrom(*this);
8402   return newArr;
8403 }
8404
8405 /*!
8406  * Modify all elements of \a this array, so that
8407  * an element _x_ becomes \f$ numerator / x \f$.
8408  *  \warning If an exception is thrown because of presence of 0 element in \a this 
8409  *           array, all elements processed before detection of the zero element remain
8410  *           modified.
8411  *  \param [in] numerator - the numerator used to modify array elements.
8412  *  \throw If \a this is not allocated.
8413  *  \throw If there is an element equal to 0 in \a this array.
8414  */
8415 void DataArrayInt::applyInv(int numerator) throw(INTERP_KERNEL::Exception)
8416 {
8417   checkAllocated();
8418   int *ptr=getPointer();
8419   std::size_t nbOfElems=getNbOfElems();
8420   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
8421     {
8422       if(*ptr!=0)
8423         {
8424           *ptr=numerator/(*ptr);
8425         }
8426       else
8427         {
8428           std::ostringstream oss; oss << "DataArrayInt::applyInv : presence of null value in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
8429           oss << " !";
8430           throw INTERP_KERNEL::Exception(oss.str().c_str());
8431         }
8432     }
8433   declareAsNew();
8434 }
8435
8436 /*!
8437  * Modify all elements of \a this array, so that
8438  * an element _x_ becomes \f$ x / val \f$.
8439  *  \param [in] val - the denominator used to modify array elements.
8440  *  \throw If \a this is not allocated.
8441  *  \throw If \a val == 0.
8442  */
8443 void DataArrayInt::applyDivideBy(int val) throw(INTERP_KERNEL::Exception)
8444 {
8445   if(val==0)
8446     throw INTERP_KERNEL::Exception("DataArrayInt::applyDivideBy : Trying to divide by 0 !");
8447   checkAllocated();
8448   int *ptr=getPointer();
8449   std::size_t nbOfElems=getNbOfElems();
8450   std::transform(ptr,ptr+nbOfElems,ptr,std::bind2nd(std::divides<int>(),val));
8451   declareAsNew();
8452 }
8453
8454 /*!
8455  * Modify all elements of \a this array, so that
8456  * an element _x_ becomes  <em> x % val </em>.
8457  *  \param [in] val - the divisor used to modify array elements.
8458  *  \throw If \a this is not allocated.
8459  *  \throw If \a val <= 0.
8460  */
8461 void DataArrayInt::applyModulus(int val) throw(INTERP_KERNEL::Exception)
8462 {
8463   if(val<=0)
8464     throw INTERP_KERNEL::Exception("DataArrayInt::applyDivideBy : Trying to operate modulus on value <= 0 !");
8465   checkAllocated();
8466   int *ptr=getPointer();
8467   std::size_t nbOfElems=getNbOfElems();
8468   std::transform(ptr,ptr+nbOfElems,ptr,std::bind2nd(std::modulus<int>(),val));
8469   declareAsNew();
8470 }
8471
8472 /*!
8473  * This method works only on data array with one component.
8474  * This method returns a newly allocated array storing stored ascendantly tuple ids in \b this so that
8475  * this[*id] in [\b vmin,\b vmax)
8476  * 
8477  * \param [in] vmin begin of range. This value is included in range (included).
8478  * \param [out] vmax end of range. This value is \b not included in range (excluded).
8479  * \return a newly allocated data array that the caller should deal with.
8480  */
8481 DataArrayInt *DataArrayInt::getIdsInRange(int vmin, int vmax) const throw(INTERP_KERNEL::Exception)
8482 {
8483   checkAllocated();
8484   if(getNumberOfComponents()!=1)
8485     throw INTERP_KERNEL::Exception("DataArrayInt::getIdsInRange : this must have exactly one component !");
8486   const int *cptr=getConstPointer();
8487   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(0,1);
8488   int nbOfTuples=getNumberOfTuples();
8489   for(int i=0;i<nbOfTuples;i++,cptr++)
8490     if(*cptr>=vmin && *cptr<vmax)
8491       ret->pushBackSilent(i);
8492   return ret.retn();
8493 }
8494
8495 /*!
8496  * Modify all elements of \a this array, so that
8497  * an element _x_ becomes <em> val % x </em>.
8498  *  \warning If an exception is thrown because of presence of an element <= 0 in \a this 
8499  *           array, all elements processed before detection of the zero element remain
8500  *           modified.
8501  *  \param [in] val - the divident used to modify array elements.
8502  *  \throw If \a this is not allocated.
8503  *  \throw If there is an element equal to or less than 0 in \a this array.
8504  */
8505 void DataArrayInt::applyRModulus(int val) throw(INTERP_KERNEL::Exception)
8506 {
8507   checkAllocated();
8508   int *ptr=getPointer();
8509   std::size_t nbOfElems=getNbOfElems();
8510   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
8511     {
8512       if(*ptr>0)
8513         {
8514           *ptr=val%(*ptr);
8515         }
8516       else
8517         {
8518           std::ostringstream oss; oss << "DataArrayInt::applyRModulus : presence of value <=0 in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
8519           oss << " !";
8520           throw INTERP_KERNEL::Exception(oss.str().c_str());
8521         }
8522     }
8523   declareAsNew();
8524 }
8525
8526 /*!
8527  * Modify all elements of \a this array, so that
8528  * an element _x_ becomes <em> val ^ x </em>.
8529  *  \param [in] val - the value used to apply pow on all array elements.
8530  *  \throw If \a this is not allocated.
8531  *  \throw If \a val < 0.
8532  */
8533 void DataArrayInt::applyPow(int val) throw(INTERP_KERNEL::Exception)
8534 {
8535   checkAllocated();
8536   if(val<0)
8537     throw INTERP_KERNEL::Exception("DataArrayInt::applyPow : input pow in < 0 !");
8538   int *ptr=getPointer();
8539   std::size_t nbOfElems=getNbOfElems();
8540   if(val==0)
8541     {
8542       std::fill(ptr,ptr+nbOfElems,1.);
8543       return ;
8544     }
8545   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
8546     {
8547       int tmp=1;
8548       for(int j=0;j<val;j++)
8549         tmp*=*ptr;
8550       *ptr=tmp;
8551     }
8552   declareAsNew();
8553 }
8554
8555 /*!
8556  * Modify all elements of \a this array, so that
8557  * an element _x_ becomes \f$ val ^ x \f$.
8558  *  \param [in] val - the value used to apply pow on all array elements.
8559  *  \throw If \a this is not allocated.
8560  *  \throw If there is an element < 0 in \a this array.
8561  *  \warning If an exception is thrown because of presence of 0 element in \a this 
8562  *           array, all elements processed before detection of the zero element remain
8563  *           modified.
8564  */
8565 void DataArrayInt::applyRPow(int val) throw(INTERP_KERNEL::Exception)
8566 {
8567   checkAllocated();
8568   int *ptr=getPointer();
8569   std::size_t nbOfElems=getNbOfElems();
8570   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
8571     {
8572       if(*ptr>=0)
8573         {
8574           int tmp=1;
8575           for(int j=0;j<*ptr;j++)
8576             tmp*=val;
8577           *ptr=tmp;
8578         }
8579       else
8580         {
8581           std::ostringstream oss; oss << "DataArrayInt::applyRPow : presence of negative value in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
8582           oss << " !";
8583           throw INTERP_KERNEL::Exception(oss.str().c_str());
8584         }
8585     }
8586   declareAsNew();
8587 }
8588
8589 /*!
8590  * Returns a new DataArrayInt by aggregating two given arrays, so that (1) the number
8591  * of components in the result array is a sum of the number of components of given arrays
8592  * and (2) the number of tuples in the result array is same as that of each of given
8593  * arrays. In other words the i-th tuple of result array includes all components of
8594  * i-th tuples of all given arrays.
8595  * Number of tuples in the given arrays must be the same.
8596  *  \param [in] a1 - an array to include in the result array.
8597  *  \param [in] a2 - another array to include in the result array.
8598  *  \return DataArrayInt * - the new instance of DataArrayInt.
8599  *          The caller is to delete this result array using decrRef() as it is no more
8600  *          needed.
8601  *  \throw If both \a a1 and \a a2 are NULL.
8602  *  \throw If any given array is not allocated.
8603  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
8604  */
8605 DataArrayInt *DataArrayInt::Meld(const DataArrayInt *a1, const DataArrayInt *a2) throw(INTERP_KERNEL::Exception)
8606 {
8607   std::vector<const DataArrayInt *> arr(2);
8608   arr[0]=a1; arr[1]=a2;
8609   return Meld(arr);
8610 }
8611
8612 /*!
8613  * Returns a new DataArrayInt by aggregating all given arrays, so that (1) the number
8614  * of components in the result array is a sum of the number of components of given arrays
8615  * and (2) the number of tuples in the result array is same as that of each of given
8616  * arrays. In other words the i-th tuple of result array includes all components of
8617  * i-th tuples of all given arrays.
8618  * Number of tuples in the given arrays must be  the same.
8619  *  \param [in] arr - a sequence of arrays to include in the result array.
8620  *  \return DataArrayInt * - the new instance of DataArrayInt.
8621  *          The caller is to delete this result array using decrRef() as it is no more
8622  *          needed.
8623  *  \throw If all arrays within \a arr are NULL.
8624  *  \throw If any given array is not allocated.
8625  *  \throw If getNumberOfTuples() of arrays within \a arr is different.
8626  */
8627 DataArrayInt *DataArrayInt::Meld(const std::vector<const DataArrayInt *>& arr) throw(INTERP_KERNEL::Exception)
8628 {
8629   std::vector<const DataArrayInt *> a;
8630   for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
8631     if(*it4)
8632       a.push_back(*it4);
8633   if(a.empty())
8634     throw INTERP_KERNEL::Exception("DataArrayInt::Meld : array must be NON empty !");
8635   std::vector<const DataArrayInt *>::const_iterator it;
8636   for(it=a.begin();it!=a.end();it++)
8637     (*it)->checkAllocated();
8638   it=a.begin();
8639   int nbOfTuples=(*it)->getNumberOfTuples();
8640   std::vector<int> nbc(a.size());
8641   std::vector<const int *> pts(a.size());
8642   nbc[0]=(*it)->getNumberOfComponents();
8643   pts[0]=(*it++)->getConstPointer();
8644   for(int i=1;it!=a.end();it++,i++)
8645     {
8646       if(nbOfTuples!=(*it)->getNumberOfTuples())
8647         throw INTERP_KERNEL::Exception("DataArrayInt::meld : mismatch of number of tuples !");
8648       nbc[i]=(*it)->getNumberOfComponents();
8649       pts[i]=(*it)->getConstPointer();
8650     }
8651   int totalNbOfComp=std::accumulate(nbc.begin(),nbc.end(),0);
8652   DataArrayInt *ret=DataArrayInt::New();
8653   ret->alloc(nbOfTuples,totalNbOfComp);
8654   int *retPtr=ret->getPointer();
8655   for(int i=0;i<nbOfTuples;i++)
8656     for(int j=0;j<(int)a.size();j++)
8657       {
8658         retPtr=std::copy(pts[j],pts[j]+nbc[j],retPtr);
8659         pts[j]+=nbc[j];
8660       }
8661   int k=0;
8662   for(int i=0;i<(int)a.size();i++)
8663     for(int j=0;j<nbc[i];j++,k++)
8664       ret->setInfoOnComponent(k,a[i]->getInfoOnComponent(j).c_str());
8665   return ret;
8666 }
8667
8668 /*!
8669  * Returns a new DataArrayInt which is a minimal partition of elements of \a groups.
8670  * The i-th item of the result array is an ID of a set of elements belonging to a
8671  * unique set of groups, which the i-th element is a part of. This set of elements
8672  * belonging to a unique set of groups is called \a family, so the result array contains
8673  * IDs of families each element belongs to.
8674  *
8675  * \b Example: if we have two groups of elements: \a group1 [0,4] and \a group2 [ 0,1,2 ],
8676  * then there are 3 families:
8677  * - \a family1 (with ID 1) contains element [0] belonging to ( \a group1 + \a group2 ),
8678  * - \a family2 (with ID 2) contains elements [4] belonging to ( \a group1 ),
8679  * - \a family3 (with ID 3) contains element [1,2] belonging to ( \a group2 ), <br>
8680  * and the result array contains IDs of families [ 1,3,3,0,2 ]. <br> Note a family ID 0 which
8681  * stands for the element #3 which is in none of groups.
8682  *
8683  *  \param [in] groups - sequence of groups of element IDs.
8684  *  \param [in] newNb - total number of elements; it must be more than max ID of element
8685  *         in \a groups.
8686  *  \param [out] fidsOfGroups - IDs of families the elements of each group belong to.
8687  *  \return DataArrayInt * - a new instance of DataArrayInt containing IDs of families
8688  *         each element with ID from range [0, \a newNb ) belongs to. The caller is to
8689  *         delete this array using decrRef() as it is no more needed.
8690  *  \throw If any element ID in \a groups violates condition ( 0 <= ID < \a newNb ).
8691  */
8692 DataArrayInt *DataArrayInt::MakePartition(const std::vector<const DataArrayInt *>& groups, int newNb, std::vector< std::vector<int> >& fidsOfGroups) throw(INTERP_KERNEL::Exception)
8693 {
8694   std::vector<const DataArrayInt *> groups2;
8695   for(std::vector<const DataArrayInt *>::const_iterator it4=groups.begin();it4!=groups.end();it4++)
8696     if(*it4)
8697       groups2.push_back(*it4);
8698   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
8699   ret->alloc(newNb,1);
8700   int *retPtr=ret->getPointer();
8701   std::fill(retPtr,retPtr+newNb,0);
8702   int fid=1;
8703   for(std::vector<const DataArrayInt *>::const_iterator iter=groups2.begin();iter!=groups2.end();iter++)
8704     {
8705       const int *ptr=(*iter)->getConstPointer();
8706       std::size_t nbOfElem=(*iter)->getNbOfElems();
8707       int sfid=fid;
8708       for(int j=0;j<sfid;j++)
8709         {
8710           bool found=false;
8711           for(std::size_t i=0;i<nbOfElem;i++)
8712             {
8713               if(ptr[i]>=0 && ptr[i]<newNb)
8714                 {
8715                   if(retPtr[ptr[i]]==j)
8716                     {
8717                       retPtr[ptr[i]]=fid;
8718                       found=true;
8719                     }
8720                 }
8721               else
8722                 {
8723                   std::ostringstream oss; oss << "DataArrayInt::MakePartition : In group \"" << (*iter)->getName() << "\" in tuple #" << i << " value = " << ptr[i] << " ! Should be in [0," << newNb;
8724                   oss << ") !";
8725                   throw INTERP_KERNEL::Exception(oss.str().c_str());
8726                 }
8727             }
8728           if(found)
8729             fid++;
8730         }
8731     }
8732   fidsOfGroups.clear();
8733   fidsOfGroups.resize(groups2.size());
8734   int grId=0;
8735   for(std::vector<const DataArrayInt *>::const_iterator iter=groups2.begin();iter!=groups2.end();iter++,grId++)
8736     {
8737       std::set<int> tmp;
8738       const int *ptr=(*iter)->getConstPointer();
8739       std::size_t nbOfElem=(*iter)->getNbOfElems();
8740       for(const int *p=ptr;p!=ptr+nbOfElem;p++)
8741         tmp.insert(retPtr[*p]);
8742       fidsOfGroups[grId].insert(fidsOfGroups[grId].end(),tmp.begin(),tmp.end());
8743     }
8744   return ret.retn();
8745 }
8746
8747 /*!
8748  * Returns a new DataArrayInt which contains all elements of given one-dimensional
8749  * arrays. The result array does not contain any duplicates and its values
8750  * are sorted in ascending order.
8751  *  \param [in] arr - sequence of DataArrayInt's to unite.
8752  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
8753  *         array using decrRef() as it is no more needed.
8754  *  \throw If any \a arr[i] is not allocated.
8755  *  \throw If \a arr[i]->getNumberOfComponents() != 1.
8756  */
8757 DataArrayInt *DataArrayInt::BuildUnion(const std::vector<const DataArrayInt *>& arr) throw(INTERP_KERNEL::Exception)
8758 {
8759   std::vector<const DataArrayInt *> a;
8760   for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
8761     if(*it4)
8762       a.push_back(*it4);
8763   for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
8764     {
8765       (*it)->checkAllocated();
8766       if((*it)->getNumberOfComponents()!=1)
8767         throw INTERP_KERNEL::Exception("DataArrayInt::BuildUnion : only single component allowed !");
8768     }
8769   //
8770   std::set<int> r;
8771   for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
8772     {
8773       const int *pt=(*it)->getConstPointer();
8774       int nbOfTuples=(*it)->getNumberOfTuples();
8775       r.insert(pt,pt+nbOfTuples);
8776     }
8777   DataArrayInt *ret=DataArrayInt::New();
8778   ret->alloc((int)r.size(),1);
8779   std::copy(r.begin(),r.end(),ret->getPointer());
8780   return ret;
8781 }
8782
8783 /*!
8784  * Returns a new DataArrayInt which contains elements present in each of given one-dimensional
8785  * arrays. The result array does not contain any duplicates and its values
8786  * are sorted in ascending order.
8787  *  \param [in] arr - sequence of DataArrayInt's to intersect.
8788  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
8789  *         array using decrRef() as it is no more needed.
8790  *  \throw If any \a arr[i] is not allocated.
8791  *  \throw If \a arr[i]->getNumberOfComponents() != 1.
8792  */
8793 DataArrayInt *DataArrayInt::BuildIntersection(const std::vector<const DataArrayInt *>& arr) throw(INTERP_KERNEL::Exception)
8794 {
8795   std::vector<const DataArrayInt *> a;
8796   for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
8797     if(*it4)
8798       a.push_back(*it4);
8799   for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
8800     {
8801       (*it)->checkAllocated();
8802       if((*it)->getNumberOfComponents()!=1)
8803         throw INTERP_KERNEL::Exception("DataArrayInt::BuildIntersection : only single component allowed !");
8804     }
8805   //
8806   std::set<int> r;
8807   for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
8808     {
8809       const int *pt=(*it)->getConstPointer();
8810       int nbOfTuples=(*it)->getNumberOfTuples();
8811       std::set<int> s1(pt,pt+nbOfTuples);
8812       if(it!=a.begin())
8813         {
8814           std::set<int> r2;
8815           std::set_intersection(r.begin(),r.end(),s1.begin(),s1.end(),inserter(r2,r2.end()));
8816           r=r2;
8817         }
8818       else
8819         r=s1;
8820     }
8821   DataArrayInt *ret=DataArrayInt::New();
8822   ret->alloc((int)r.size(),1);
8823   std::copy(r.begin(),r.end(),ret->getPointer());
8824   return ret;
8825 }
8826
8827 /*!
8828  * Returns a new DataArrayInt which contains a complement of elements of \a this
8829  * one-dimensional array. I.e. the result array contains all elements from the range [0,
8830  * \a nbOfElement) not present in \a this array.
8831  *  \param [in] nbOfElement - maximal size of the result array.
8832  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
8833  *         array using decrRef() as it is no more needed.
8834  *  \throw If \a this is not allocated.
8835  *  \throw If \a this->getNumberOfComponents() != 1.
8836  *  \throw If any element \a x of \a this array violates condition ( 0 <= \a x < \a
8837  *         nbOfElement ).
8838  */
8839 DataArrayInt *DataArrayInt::buildComplement(int nbOfElement) const throw(INTERP_KERNEL::Exception)
8840 {
8841    checkAllocated();
8842    if(getNumberOfComponents()!=1)
8843      throw INTERP_KERNEL::Exception("DataArrayInt::buildComplement : only single component allowed !");
8844    std::vector<bool> tmp(nbOfElement);
8845    const int *pt=getConstPointer();
8846    int nbOfTuples=getNumberOfTuples();
8847    for(const int *w=pt;w!=pt+nbOfTuples;w++)
8848      if(*w>=0 && *w<nbOfElement)
8849        tmp[*w]=true;
8850      else
8851        throw INTERP_KERNEL::Exception("DataArrayInt::buildComplement : an element is not in valid range : [0,nbOfElement) !");
8852    int nbOfRetVal=(int)std::count(tmp.begin(),tmp.end(),false);
8853    DataArrayInt *ret=DataArrayInt::New();
8854    ret->alloc(nbOfRetVal,1);
8855    int j=0;
8856    int *retPtr=ret->getPointer();
8857    for(int i=0;i<nbOfElement;i++)
8858      if(!tmp[i])
8859        retPtr[j++]=i;
8860    return ret;
8861 }
8862
8863 /*!
8864  * Returns a new DataArrayInt containing elements of \a this one-dimensional missing
8865  * from an \a other one-dimensional array.
8866  *  \param [in] other - a DataArrayInt containing elements not to include in the result array.
8867  *  \return DataArrayInt * - a new instance of DataArrayInt with one component. The
8868  *         caller is to delete this array using decrRef() as it is no more needed.
8869  *  \throw If \a other is NULL.
8870  *  \throw If \a other is not allocated.
8871  *  \throw If \a other->getNumberOfComponents() != 1.
8872  *  \throw If \a this is not allocated.
8873  *  \throw If \a this->getNumberOfComponents() != 1.
8874  *  \sa DataArrayInt::buildSubstractionOptimized()
8875  */
8876 DataArrayInt *DataArrayInt::buildSubstraction(const DataArrayInt *other) const throw(INTERP_KERNEL::Exception)
8877 {
8878   if(!other)
8879     throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstraction : DataArrayInt pointer in input is NULL !");
8880   checkAllocated();
8881   other->checkAllocated();
8882   if(getNumberOfComponents()!=1)
8883      throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstraction : only single component allowed !");
8884   if(other->getNumberOfComponents()!=1)
8885      throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstraction : only single component allowed for other type !");
8886   const int *pt=getConstPointer();
8887   int nbOfTuples=getNumberOfTuples();
8888   std::set<int> s1(pt,pt+nbOfTuples);
8889   pt=other->getConstPointer();
8890   nbOfTuples=other->getNumberOfTuples();
8891   std::set<int> s2(pt,pt+nbOfTuples);
8892   std::vector<int> r;
8893   std::set_difference(s1.begin(),s1.end(),s2.begin(),s2.end(),std::back_insert_iterator< std::vector<int> >(r));
8894   DataArrayInt *ret=DataArrayInt::New();
8895   ret->alloc((int)r.size(),1);
8896   std::copy(r.begin(),r.end(),ret->getPointer());
8897   return ret;
8898 }
8899
8900 /*!
8901  * \a this is expected to have one component and to be sorted ascendingly (as for \a other).
8902  * \a other is expected to be a part of \a this. If not DataArrayInt::buildSubstraction should be called instead.
8903  * 
8904  * \param [in] other an array with one component and expected to be sorted ascendingly.
8905  * \ret list of ids in \a this but not in \a other.
8906  * \sa DataArrayInt::buildSubstraction
8907  */
8908 DataArrayInt *DataArrayInt::buildSubstractionOptimized(const DataArrayInt *other) const throw(INTERP_KERNEL::Exception)
8909 {
8910   static const char *MSG="DataArrayInt::buildSubstractionOptimized : only single component allowed !";
8911   if(!other) throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstractionOptimized : NULL input array !");
8912   checkAllocated(); other->checkAllocated();
8913   if(getNumberOfComponents()!=1) throw INTERP_KERNEL::Exception(MSG);
8914   if(other->getNumberOfComponents()!=1) throw INTERP_KERNEL::Exception(MSG);
8915   const int *pt1Bg(begin()),*pt1End(end()),*pt2Bg(other->begin()),*pt2End(other->end()),*work1(pt1Bg),*work2(pt2Bg);
8916   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
8917   for(;work1!=pt1End;work1++)
8918     {
8919       if(work2!=pt2End && *work1==*work2)
8920         work2++;
8921       else
8922         ret->pushBackSilent(*work1);
8923     }
8924   return ret.retn();
8925 }
8926
8927
8928 /*!
8929  * Returns a new DataArrayInt which contains all elements of \a this and a given
8930  * one-dimensional arrays. The result array does not contain any duplicates
8931  * and its values are sorted in ascending order.
8932  *  \param [in] other - an array to unite with \a this one.
8933  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
8934  *         array using decrRef() as it is no more needed.
8935  *  \throw If \a this or \a other is not allocated.
8936  *  \throw If \a this->getNumberOfComponents() != 1.
8937  *  \throw If \a other->getNumberOfComponents() != 1.
8938  */
8939 DataArrayInt *DataArrayInt::buildUnion(const DataArrayInt *other) const throw(INTERP_KERNEL::Exception)
8940 {
8941   std::vector<const DataArrayInt *>arrs(2);
8942   arrs[0]=this; arrs[1]=other;
8943   return BuildUnion(arrs);
8944 }
8945
8946
8947 /*!
8948  * Returns a new DataArrayInt which contains elements present in both \a this and a given
8949  * one-dimensional arrays. The result array does not contain any duplicates
8950  * and its values are sorted in ascending order.
8951  *  \param [in] other - an array to intersect with \a this one.
8952  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
8953  *         array using decrRef() as it is no more needed.
8954  *  \throw If \a this or \a other is not allocated.
8955  *  \throw If \a this->getNumberOfComponents() != 1.
8956  *  \throw If \a other->getNumberOfComponents() != 1.
8957  */
8958 DataArrayInt *DataArrayInt::buildIntersection(const DataArrayInt *other) const throw(INTERP_KERNEL::Exception)
8959 {
8960   std::vector<const DataArrayInt *>arrs(2);
8961   arrs[0]=this; arrs[1]=other;
8962   return BuildIntersection(arrs);
8963 }
8964
8965 /*!
8966  * This method can be applied on allocated with one component DataArrayInt instance.
8967  * This method is typically relevant for sorted arrays. All consecutive duplicated items in \a this will appear only once in returned DataArrayInt instance.
8968  * Example : if \a this contains [1,2,2,3,3,3,3,4,5,5,7,7,7,19] the returned array will contain [1,2,3,4,5,7,19]
8969  * 
8970  * \return a newly allocated array that contain the result of the unique operation applied on \a this.
8971  * \throw if \a this is not allocated or if \a this has not exactly one component.
8972  */
8973 DataArrayInt *DataArrayInt::buildUnique() const throw(INTERP_KERNEL::Exception)
8974 {
8975   checkAllocated();
8976   if(getNumberOfComponents()!=1)
8977      throw INTERP_KERNEL::Exception("DataArrayInt::buildUnique : only single component allowed !");
8978   int nbOfTuples=getNumberOfTuples();
8979   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp=deepCpy();
8980   int *data=tmp->getPointer();
8981   int *last=std::unique(data,data+nbOfTuples);
8982   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
8983   ret->alloc(std::distance(data,last),1);
8984   std::copy(data,last,ret->getPointer());
8985   return ret.retn();
8986 }
8987
8988 /*!
8989  * Returns a new DataArrayInt which contains size of every of groups described by \a this
8990  * "index" array. Such "index" array is returned for example by 
8991  * \ref ParaMEDMEM::MEDCouplingUMesh::buildDescendingConnectivity
8992  * "MEDCouplingUMesh::buildDescendingConnectivity" and
8993  * \ref ParaMEDMEM::MEDCouplingUMesh::getNodalConnectivityIndex
8994  * "MEDCouplingUMesh::getNodalConnectivityIndex" etc.
8995  *  \return DataArrayInt * - a new instance of DataArrayInt, whose number of tuples
8996  *          equals to \a this->getNumberOfComponents() - 1, and number of components is 1.
8997  *          The caller is to delete this array using decrRef() as it is no more needed. 
8998  *  \throw If \a this is not allocated.
8999  *  \throw If \a this->getNumberOfComponents() != 1.
9000  *  \throw If \a this->getNumberOfTuples() < 2.
9001  *
9002  *  \b Example: <br> 
9003  *         - this contains [1,3,6,7,7,9,15]
9004  *         - result array contains [2,3,1,0,2,6],
9005  *          where 2 = 3 - 1, 3 = 6 - 3, 1 = 7 - 6 etc.
9006  */
9007 DataArrayInt *DataArrayInt::deltaShiftIndex() const throw(INTERP_KERNEL::Exception)
9008 {
9009   checkAllocated();
9010   if(getNumberOfComponents()!=1)
9011      throw INTERP_KERNEL::Exception("DataArrayInt::deltaShiftIndex : only single component allowed !");
9012   int nbOfTuples=getNumberOfTuples();
9013   if(nbOfTuples<2)
9014     throw INTERP_KERNEL::Exception("DataArrayInt::deltaShiftIndex : 1 tuple at least must be present in 'this' !");
9015   const int *ptr=getConstPointer();
9016   DataArrayInt *ret=DataArrayInt::New();
9017   ret->alloc(nbOfTuples-1,1);
9018   int *out=ret->getPointer();
9019   std::transform(ptr+1,ptr+nbOfTuples,ptr,out,std::minus<int>());
9020   return ret;
9021 }
9022
9023 /*!
9024  * Modifies \a this one-dimensional array so that value of each element \a x
9025  * of \a this array (\a a) is computed as \f$ x_i = \sum_{j=0}^{i-1} a[ j ] \f$.
9026  * Or: for each i>0 new[i]=new[i-1]+old[i-1] for i==0 new[i]=0. Number of tuples
9027  * and components remains the same.<br>
9028  * This method is useful for allToAllV in MPI with contiguous policy. This method
9029  * differs from computeOffsets2() in that the number of tuples is \b not changed by
9030  * this one.
9031  *  \throw If \a this is not allocated.
9032  *  \throw If \a this->getNumberOfComponents() != 1.
9033  *
9034  *  \b Example: <br>
9035  *          - Before \a this contains [3,5,1,2,0,8]
9036  *          - After \a this contains  [0,3,8,9,11,11]<br>
9037  *          Note that the last element 19 = 11 + 8 is missing because size of \a this
9038  *          array is retained and thus there is no space to store the last element.
9039  */
9040 void DataArrayInt::computeOffsets() throw(INTERP_KERNEL::Exception)
9041 {
9042   checkAllocated();
9043   if(getNumberOfComponents()!=1)
9044      throw INTERP_KERNEL::Exception("DataArrayInt::computeOffsets : only single component allowed !");
9045   int nbOfTuples=getNumberOfTuples();
9046   if(nbOfTuples==0)
9047     return ;
9048   int *work=getPointer();
9049   int tmp=work[0];
9050   work[0]=0;
9051   for(int i=1;i<nbOfTuples;i++)
9052     {
9053       int tmp2=work[i];
9054       work[i]=work[i-1]+tmp;
9055       tmp=tmp2;
9056     }
9057   declareAsNew();
9058 }
9059
9060
9061 /*!
9062  * Modifies \a this one-dimensional array so that value of each element \a x
9063  * of \a this array (\a a) is computed as \f$ x_i = \sum_{j=0}^{i-1} a[ j ] \f$.
9064  * Or: for each i>0 new[i]=new[i-1]+old[i-1] for i==0 new[i]=0. Number
9065  * components remains the same and number of tuples is inceamented by one.<br>
9066  * This method is useful for allToAllV in MPI with contiguous policy. This method
9067  * differs from computeOffsets() in that the number of tuples is changed by this one.
9068  *  \throw If \a this is not allocated.
9069  *  \throw If \a this->getNumberOfComponents() != 1.
9070  *
9071  *  \b Example: <br>
9072  *          - Before \a this contains [3,5,1,2,0,8]
9073  *          - After \a this contains  [0,3,8,9,11,11,19]<br>
9074  */
9075 void DataArrayInt::computeOffsets2() throw(INTERP_KERNEL::Exception)
9076 {
9077   checkAllocated();
9078   if(getNumberOfComponents()!=1)
9079     throw INTERP_KERNEL::Exception("DataArrayInt::computeOffsets2 : only single component allowed !");
9080   int nbOfTuples=getNumberOfTuples();
9081   int *ret=(int *)malloc((nbOfTuples+1)*sizeof(int));
9082   if(nbOfTuples==0)
9083     return ;
9084   const int *work=getConstPointer();
9085   ret[0]=0;
9086   for(int i=0;i<nbOfTuples;i++)
9087     ret[i+1]=work[i]+ret[i];
9088   useArray(ret,true,C_DEALLOC,nbOfTuples+1,1);
9089   declareAsNew();
9090 }
9091
9092 /*!
9093  * Returns two new DataArrayInt instances whose contents is computed from that of \a this and \a listOfIds arrays as follows.
9094  * \a this is expected to be an offset format ( as returned by DataArrayInt::computeOffsets2 ) that is to say with one component
9095  * and ** sorted strictly increasingly **. \a listOfIds is expected to be sorted ascendingly (not strictly needed for \a listOfIds).
9096  * This methods searches in \a this, considered as a set of contiguous \c this->getNumberOfComponents() ranges, all ids in \a listOfIds
9097  * filling completely one of the ranges in \a this.
9098  *
9099  * \param [in] listOfIds a list of ids that has to be sorted ascendingly.
9100  * \param [out] rangeIdsFetched the range ids fetched
9101  * \param [out] idsInInputListThatFetch contains the list of ids in \a listOfIds that are \b fully included in a range in \a this. So
9102  *              \a idsInInputListThatFetch is a part of input \a listOfIds.
9103  *
9104  * \sa DataArrayInt::computeOffsets2
9105  *
9106  *  \b Example: <br>
9107  *          - \a this : [0,3,7,9,15,18]
9108  *          - \a listOfIds contains  [0,1,2,3,7,8,15,16,17]
9109  *          - \a rangeIdsFetched result array: [0,2,4]
9110  *          - \a idsInInputListThatFetch result array: [0,1,2,7,8,15,16,17]
9111  * In this example id 3 in input \a listOfIds is alone so it do not appear in output \a idsInInputListThatFetch.
9112  * <br>
9113  */
9114 void DataArrayInt::searchRangesInListOfIds(const DataArrayInt *listOfIds, DataArrayInt *& rangeIdsFetched, DataArrayInt *& idsInInputListThatFetch) const throw(INTERP_KERNEL::Exception)
9115 {
9116   if(!listOfIds)
9117     throw INTERP_KERNEL::Exception("DataArrayInt::searchRangesInListOfIds : input list of ids is null !");
9118   listOfIds->checkAllocated(); checkAllocated();
9119   if(listOfIds->getNumberOfComponents()!=1)
9120     throw INTERP_KERNEL::Exception("DataArrayInt::searchRangesInListOfIds : input list of ids must have exactly one component !");
9121   if(getNumberOfComponents()!=1)
9122     throw INTERP_KERNEL::Exception("DataArrayInt::searchRangesInListOfIds : this must have exactly one component !");
9123   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret0=DataArrayInt::New(); ret0->alloc(0,1);
9124   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret1=DataArrayInt::New(); ret1->alloc(0,1);
9125   const int *tupEnd(listOfIds->end()),*offBg(begin()),*offEnd(end()-1);
9126   const int *tupPtr(listOfIds->begin()),*offPtr(offBg);
9127   while(tupPtr!=tupEnd && offPtr!=offEnd)
9128     {
9129       if(*tupPtr==*offPtr)
9130         {
9131           int i=offPtr[0];
9132           while(i<offPtr[1] && *tupPtr==i && tupPtr!=tupEnd) { i++; tupPtr++; }
9133           if(i==offPtr[1])
9134             {
9135               ret0->pushBackSilent((int)std::distance(offBg,offPtr));
9136               ret1->pushBackValsSilent(tupPtr-(offPtr[1]-offPtr[0]),tupPtr);
9137               offPtr++;
9138             }
9139         }
9140       else
9141         { if(*tupPtr<*offPtr) tupPtr++; else offPtr++; }
9142     }
9143   rangeIdsFetched=ret0.retn();
9144   idsInInputListThatFetch=ret1.retn();
9145 }
9146
9147 /*!
9148  * Returns a new DataArrayInt whose contents is computed from that of \a this and \a
9149  * offsets arrays as follows. \a offsets is a one-dimensional array considered as an
9150  * "index" array of a "iota" array, thus, whose each element gives an index of a group
9151  * beginning within the "iota" array. And \a this is a one-dimensional array
9152  * considered as a selector of groups described by \a offsets to include into the result array.
9153  *  \throw If \a offsets is NULL.
9154  *  \throw If \a offsets is not allocated.
9155  *  \throw If \a offsets->getNumberOfComponents() != 1.
9156  *  \throw If \a offsets is not monotonically increasing.
9157  *  \throw If \a this is not allocated.
9158  *  \throw If \a this->getNumberOfComponents() != 1.
9159  *  \throw If any element of \a this is not a valid index for \a offsets array.
9160  *
9161  *  \b Example: <br>
9162  *          - \a this: [0,2,3]
9163  *          - \a offsets: [0,3,6,10,14,20]
9164  *          - result array: [0,1,2,6,7,8,9,10,11,12,13] == <br>
9165  *            \c range(0,3) + \c range(6,10) + \c range(10,14) ==<br>
9166  *            \c range( \a offsets[ \a this[0] ], offsets[ \a this[0]+1 ]) + 
9167  *            \c range( \a offsets[ \a this[1] ], offsets[ \a this[1]+1 ]) + 
9168  *            \c range( \a offsets[ \a this[2] ], offsets[ \a this[2]+1 ])
9169  */
9170 DataArrayInt *DataArrayInt::buildExplicitArrByRanges(const DataArrayInt *offsets) const throw(INTERP_KERNEL::Exception)
9171 {
9172   if(!offsets)
9173     throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrByRanges : DataArrayInt pointer in input is NULL !");
9174   checkAllocated();
9175   if(getNumberOfComponents()!=1)
9176      throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrByRanges : only single component allowed !");
9177   offsets->checkAllocated();
9178   if(offsets->getNumberOfComponents()!=1)
9179      throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrByRanges : input array should have only single component !");
9180   int othNbTuples=offsets->getNumberOfTuples()-1;
9181   int nbOfTuples=getNumberOfTuples();
9182   int retNbOftuples=0;
9183   const int *work=getConstPointer();
9184   const int *offPtr=offsets->getConstPointer();
9185   for(int i=0;i<nbOfTuples;i++)
9186     {
9187       int val=work[i];
9188       if(val>=0 && val<othNbTuples)
9189         {
9190           int delta=offPtr[val+1]-offPtr[val];
9191           if(delta>=0)
9192             retNbOftuples+=delta;
9193           else
9194             {
9195               std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrByRanges : Tuple #" << val << " of offset array has a delta < 0 !";
9196               throw INTERP_KERNEL::Exception(oss.str().c_str());
9197             }
9198         }
9199       else
9200         {
9201           std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrByRanges : Tuple #" << i << " in this contains " << val;
9202           oss << " whereas offsets array is of size " << othNbTuples+1 << " !";
9203           throw INTERP_KERNEL::Exception(oss.str().c_str());
9204         }
9205     }
9206   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
9207   ret->alloc(retNbOftuples,1);
9208   int *retPtr=ret->getPointer();
9209   for(int i=0;i<nbOfTuples;i++)
9210     {
9211       int val=work[i];
9212       int start=offPtr[val];
9213       int off=offPtr[val+1]-start;
9214       for(int j=0;j<off;j++,retPtr++)
9215         *retPtr=start+j;
9216     }
9217   return ret.retn();
9218 }
9219
9220 /*!
9221  * 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.
9222  * 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
9223  * in tuple **i** of returned DataArrayInt.
9224  * If ranges overlapped (in theory it should not) this method do not detect it and always returns the first range.
9225  *
9226  * 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)]
9227  * The return DataArrayInt will contain : **[0,4,1,2,2,3]**
9228  * 
9229  * \param [in] ranges typically come from output of MEDCouplingUMesh::ComputeRangesFromTypeDistribution. Each range is specified like this : 1st component is
9230  *             for lower value included and 2nd component is the upper value of corresponding range **excluded**.
9231  * \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
9232  *        is thrown if no ranges in \a ranges contains value in \a this.
9233  * 
9234  * \sa DataArrayInt::findIdInRangeForEachTuple
9235  */
9236 DataArrayInt *DataArrayInt::findRangeIdForEachTuple(const DataArrayInt *ranges) const throw(INTERP_KERNEL::Exception)
9237 {
9238   if(!ranges)
9239     throw INTERP_KERNEL::Exception("DataArrayInt::findRangeIdForEachTuple : null input pointer !");
9240   if(ranges->getNumberOfComponents()!=2)
9241     throw INTERP_KERNEL::Exception("DataArrayInt::findRangeIdForEachTuple : input DataArrayInt instance should have 2 components !");
9242   checkAllocated();
9243   if(getNumberOfComponents()!=1)
9244     throw INTERP_KERNEL::Exception("DataArrayInt::findRangeIdForEachTuple : this should have only one component !");
9245   int nbTuples=getNumberOfTuples();
9246   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbTuples,1);
9247   int nbOfRanges=ranges->getNumberOfTuples();
9248   const int *rangesPtr=ranges->getConstPointer();
9249   int *retPtr=ret->getPointer();
9250   const int *inPtr=getConstPointer();
9251   for(int i=0;i<nbTuples;i++,retPtr++)
9252     {
9253       int val=inPtr[i];
9254       bool found=false;
9255       for(int j=0;j<nbOfRanges && !found;j++)
9256         if(val>=rangesPtr[2*j] && val<rangesPtr[2*j+1])
9257           { *retPtr=j; found=true; }
9258       if(found)
9259         continue;
9260       else
9261         {
9262           std::ostringstream oss; oss << "DataArrayInt::findRangeIdForEachTuple : tuple #" << i << " not found by any ranges !";
9263           throw INTERP_KERNEL::Exception(oss.str().c_str());
9264         }
9265     }
9266   return ret.retn();
9267 }
9268
9269 /*!
9270  * 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.
9271  * 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
9272  * in tuple **i** of returned DataArrayInt.
9273  * If ranges overlapped (in theory it should not) this method do not detect it and always returns the sub position of the first range.
9274  *
9275  * 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)]
9276  * The return DataArrayInt will contain : **[1,2,4,0,2,2]**
9277  * This method is often called in pair with DataArrayInt::findRangeIdForEachTuple method.
9278  * 
9279  * \param [in] ranges typically come from output of MEDCouplingUMesh::ComputeRangesFromTypeDistribution. Each range is specified like this : 1st component is
9280  *             for lower value included and 2nd component is the upper value of corresponding range **excluded**.
9281  * \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
9282  *        is thrown if no ranges in \a ranges contains value in \a this.
9283  * \sa DataArrayInt::findRangeIdForEachTuple
9284  */
9285 DataArrayInt *DataArrayInt::findIdInRangeForEachTuple(const DataArrayInt *ranges) const throw(INTERP_KERNEL::Exception)
9286 {
9287   if(!ranges)
9288     throw INTERP_KERNEL::Exception("DataArrayInt::findIdInRangeForEachTuple : null input pointer !");
9289   if(ranges->getNumberOfComponents()!=2)
9290     throw INTERP_KERNEL::Exception("DataArrayInt::findIdInRangeForEachTuple : input DataArrayInt instance should have 2 components !");
9291   checkAllocated();
9292   if(getNumberOfComponents()!=1)
9293     throw INTERP_KERNEL::Exception("DataArrayInt::findIdInRangeForEachTuple : this should have only one component !");
9294   int nbTuples=getNumberOfTuples();
9295   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbTuples,1);
9296   int nbOfRanges=ranges->getNumberOfTuples();
9297   const int *rangesPtr=ranges->getConstPointer();
9298   int *retPtr=ret->getPointer();
9299   const int *inPtr=getConstPointer();
9300   for(int i=0;i<nbTuples;i++,retPtr++)
9301     {
9302       int val=inPtr[i];
9303       bool found=false;
9304       for(int j=0;j<nbOfRanges && !found;j++)
9305         if(val>=rangesPtr[2*j] && val<rangesPtr[2*j+1])
9306           { *retPtr=val-rangesPtr[2*j]; found=true; }
9307       if(found)
9308         continue;
9309       else
9310         {
9311           std::ostringstream oss; oss << "DataArrayInt::findIdInRangeForEachTuple : tuple #" << i << " not found by any ranges !";
9312           throw INTERP_KERNEL::Exception(oss.str().c_str());
9313         }
9314     }
9315   return ret.retn();
9316 }
9317
9318 /*!
9319  * 
9320  * \param [in] nbTimes specifies the nb of times each tuples in \a this will be duplicated contiguouly in returned DataArrayInt instance.
9321  *             \a nbTimes  should be at least equal to 1.
9322  * \return a newly allocated DataArrayInt having one component and number of tuples equal to \a nbTimes * \c this->getNumberOfTuples.
9323  * \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.
9324  */
9325 DataArrayInt *DataArrayInt::duplicateEachTupleNTimes(int nbTimes) const throw(INTERP_KERNEL::Exception)
9326 {
9327   checkAllocated();
9328   if(getNumberOfComponents()!=1)
9329     throw INTERP_KERNEL::Exception("DataArrayInt::duplicateEachTupleNTimes : this should have only one component !");
9330   if(nbTimes<1)
9331     throw INTERP_KERNEL::Exception("DataArrayInt::duplicateEachTupleNTimes : nb times should be >= 1 !");
9332   int nbTuples=getNumberOfTuples();
9333   const int *inPtr=getConstPointer();
9334   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbTimes*nbTuples,1);
9335   int *retPtr=ret->getPointer();
9336   for(int i=0;i<nbTuples;i++,inPtr++)
9337     {
9338       int val=*inPtr;
9339       for(int j=0;j<nbTimes;j++,retPtr++)
9340         *retPtr=val;
9341     }
9342   ret->copyStringInfoFrom(*this);
9343   return ret.retn();
9344 }
9345
9346 /*!
9347  * This method returns all different values found in \a this. This method throws if \a this has not been allocated.
9348  * But the number of components can be different from one.
9349  * \return a newly allocated array (that should be dealt by the caller) containing different values in \a this.
9350  */
9351 DataArrayInt *DataArrayInt::getDifferentValues() const throw(INTERP_KERNEL::Exception)
9352 {
9353   checkAllocated();
9354   std::set<int> ret;
9355   ret.insert(begin(),end());
9356   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret2=DataArrayInt::New(); ret2->alloc((int)ret.size(),1);
9357   std::copy(ret.begin(),ret.end(),ret2->getPointer());
9358   return ret2.retn();
9359 }
9360
9361 /*!
9362  * This method is a refinement of DataArrayInt::getDifferentValues because it returns not only different values in \a this but also, for each of
9363  * them it tells which tuple id have this id.
9364  * This method works only on arrays with one component (if it is not the case call DataArrayInt::rearrange(1) ).
9365  * This method returns two arrays having same size.
9366  * The instances of DataArrayInt in the returned vector have be specially allocated and computed by this method. Each of them should be dealt by the caller of this method.
9367  * Example : if this is equal to [1,0,1,2,0,2,2,-3,2] -> differentIds=[-3,0,1,2] and returned array will be equal to [[7],[1,4],[0,2],[3,5,6,8]]
9368  */
9369 std::vector<DataArrayInt *> DataArrayInt::partitionByDifferentValues(std::vector<int>& differentIds) const throw(INTERP_KERNEL::Exception)
9370 {
9371   checkAllocated();
9372   if(getNumberOfComponents()!=1)
9373     throw INTERP_KERNEL::Exception("DataArrayInt::partitionByDifferentValues : this should have only one component !");
9374   int id=0;
9375   std::map<int,int> m,m2,m3;
9376   for(const int *w=begin();w!=end();w++)
9377     m[*w]++;
9378   differentIds.resize(m.size());
9379   std::vector<DataArrayInt *> ret(m.size());
9380   std::vector<int *> retPtr(m.size());
9381   for(std::map<int,int>::const_iterator it=m.begin();it!=m.end();it++,id++)
9382     {
9383       m2[(*it).first]=id;
9384       ret[id]=DataArrayInt::New();
9385       ret[id]->alloc((*it).second,1);
9386       retPtr[id]=ret[id]->getPointer();
9387       differentIds[id]=(*it).first;
9388     }
9389   id=0;
9390   for(const int *w=begin();w!=end();w++,id++)
9391     {
9392       retPtr[m2[*w]][m3[*w]++]=id;
9393     }
9394   return ret;
9395 }
9396
9397 /*!
9398  * Returns a new DataArrayInt that is a sum of two given arrays. There are 3
9399  * valid cases.
9400  * 1.  The arrays have same number of tuples and components. Then each value of
9401  *   the result array (_a_) is a sum of the corresponding values of \a a1 and \a a2,
9402  *   i.e.: _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ i, j ].
9403  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
9404  *   component. Then
9405  *   _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ i, 0 ].
9406  * 3.  The arrays have same number of components and one array, say _a2_, has one
9407  *   tuple. Then
9408  *   _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ 0, j ].
9409  *
9410  * Info on components is copied either from the first array (in the first case) or from
9411  * the array with maximal number of elements (getNbOfElems()).
9412  *  \param [in] a1 - an array to sum up.
9413  *  \param [in] a2 - another array to sum up.
9414  *  \return DataArrayInt * - the new instance of DataArrayInt.
9415  *          The caller is to delete this result array using decrRef() as it is no more
9416  *          needed.
9417  *  \throw If either \a a1 or \a a2 is NULL.
9418  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
9419  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
9420  *         none of them has number of tuples or components equal to 1.
9421  */
9422 DataArrayInt *DataArrayInt::Add(const DataArrayInt *a1, const DataArrayInt *a2) throw(INTERP_KERNEL::Exception)
9423 {
9424   if(!a1 || !a2)
9425     throw INTERP_KERNEL::Exception("DataArrayInt::Add : input DataArrayInt instance is NULL !");
9426   int nbOfTuple=a1->getNumberOfTuples();
9427   int nbOfTuple2=a2->getNumberOfTuples();
9428   int nbOfComp=a1->getNumberOfComponents();
9429   int nbOfComp2=a2->getNumberOfComponents();
9430   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=0;
9431   if(nbOfTuple==nbOfTuple2)
9432     {
9433       if(nbOfComp==nbOfComp2)
9434         {
9435           ret=DataArrayInt::New();
9436           ret->alloc(nbOfTuple,nbOfComp);
9437           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::plus<int>());
9438           ret->copyStringInfoFrom(*a1);
9439         }
9440       else
9441         {
9442           int nbOfCompMin,nbOfCompMax;
9443           const DataArrayInt *aMin, *aMax;
9444           if(nbOfComp>nbOfComp2)
9445             {
9446               nbOfCompMin=nbOfComp2; nbOfCompMax=nbOfComp;
9447               aMin=a2; aMax=a1;
9448             }
9449           else
9450             {
9451               nbOfCompMin=nbOfComp; nbOfCompMax=nbOfComp2;
9452               aMin=a1; aMax=a2;
9453             }
9454           if(nbOfCompMin==1)
9455             {
9456               ret=DataArrayInt::New();
9457               ret->alloc(nbOfTuple,nbOfCompMax);
9458               const int *aMinPtr=aMin->getConstPointer();
9459               const int *aMaxPtr=aMax->getConstPointer();
9460               int *res=ret->getPointer();
9461               for(int i=0;i<nbOfTuple;i++)
9462                 res=std::transform(aMaxPtr+i*nbOfCompMax,aMaxPtr+(i+1)*nbOfCompMax,res,std::bind2nd(std::plus<int>(),aMinPtr[i]));
9463               ret->copyStringInfoFrom(*aMax);
9464             }
9465           else
9466             throw INTERP_KERNEL::Exception("Nb of components mismatch for array Add !");
9467         }
9468     }
9469   else if((nbOfTuple==1 && nbOfTuple2>1) || (nbOfTuple>1 && nbOfTuple2==1))
9470     {
9471       if(nbOfComp==nbOfComp2)
9472         {
9473           int nbOfTupleMax=std::max(nbOfTuple,nbOfTuple2);
9474           const DataArrayInt *aMin=nbOfTuple>nbOfTuple2?a2:a1;
9475           const DataArrayInt *aMax=nbOfTuple>nbOfTuple2?a1:a2;
9476           const int *aMinPtr=aMin->getConstPointer(),*aMaxPtr=aMax->getConstPointer();
9477           ret=DataArrayInt::New();
9478           ret->alloc(nbOfTupleMax,nbOfComp);
9479           int *res=ret->getPointer();
9480           for(int i=0;i<nbOfTupleMax;i++)
9481             res=std::transform(aMaxPtr+i*nbOfComp,aMaxPtr+(i+1)*nbOfComp,aMinPtr,res,std::plus<int>());
9482           ret->copyStringInfoFrom(*aMax);
9483         }
9484       else
9485         throw INTERP_KERNEL::Exception("Nb of components mismatch for array Add !");
9486     }
9487   else
9488     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Add !");
9489   return ret.retn();
9490 }
9491
9492 /*!
9493  * Adds values of another DataArrayInt to values of \a this one. There are 3
9494  * valid cases.
9495  * 1.  The arrays have same number of tuples and components. Then each value of
9496  *   \a other array is added to the corresponding value of \a this array, i.e.:
9497  *   _a_ [ i, j ] += _other_ [ i, j ].
9498  * 2.  The arrays have same number of tuples and \a other array has one component. Then
9499  *   _a_ [ i, j ] += _other_ [ i, 0 ].
9500  * 3.  The arrays have same number of components and \a other array has one tuple. Then
9501  *   _a_ [ i, j ] += _a2_ [ 0, j ].
9502  *
9503  *  \param [in] other - an array to add to \a this one.
9504  *  \throw If \a other is NULL.
9505  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
9506  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
9507  *         \a other has number of both tuples and components not equal to 1.
9508  */
9509 void DataArrayInt::addEqual(const DataArrayInt *other) throw(INTERP_KERNEL::Exception)
9510 {
9511   if(!other)
9512     throw INTERP_KERNEL::Exception("DataArrayInt::addEqual : input DataArrayInt instance is NULL !");
9513   const char *msg="Nb of tuples mismatch for DataArrayInt::addEqual  !";
9514   checkAllocated(); other->checkAllocated();
9515   int nbOfTuple=getNumberOfTuples();
9516   int nbOfTuple2=other->getNumberOfTuples();
9517   int nbOfComp=getNumberOfComponents();
9518   int nbOfComp2=other->getNumberOfComponents();
9519   if(nbOfTuple==nbOfTuple2)
9520     {
9521       if(nbOfComp==nbOfComp2)
9522         {
9523           std::transform(begin(),end(),other->begin(),getPointer(),std::plus<int>());
9524         }
9525       else if(nbOfComp2==1)
9526         {
9527           int *ptr=getPointer();
9528           const int *ptrc=other->getConstPointer();
9529           for(int i=0;i<nbOfTuple;i++)
9530             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::plus<int>(),*ptrc++));
9531         }
9532       else
9533         throw INTERP_KERNEL::Exception(msg);
9534     }
9535   else if(nbOfTuple2==1)
9536     {
9537       if(nbOfComp2==nbOfComp)
9538         {
9539           int *ptr=getPointer();
9540           const int *ptrc=other->getConstPointer();
9541           for(int i=0;i<nbOfTuple;i++)
9542             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::plus<int>());
9543         }
9544       else
9545         throw INTERP_KERNEL::Exception(msg);
9546     }
9547   else
9548     throw INTERP_KERNEL::Exception(msg);
9549   declareAsNew();
9550 }
9551
9552 /*!
9553  * Returns a new DataArrayInt that is a subtraction of two given arrays. There are 3
9554  * valid cases.
9555  * 1.  The arrays have same number of tuples and components. Then each value of
9556  *   the result array (_a_) is a subtraction of the corresponding values of \a a1 and
9557  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ i, j ].
9558  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
9559  *   component. Then
9560  *   _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ i, 0 ].
9561  * 3.  The arrays have same number of components and one array, say _a2_, has one
9562  *   tuple. Then
9563  *   _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ 0, j ].
9564  *
9565  * Info on components is copied either from the first array (in the first case) or from
9566  * the array with maximal number of elements (getNbOfElems()).
9567  *  \param [in] a1 - an array to subtract from.
9568  *  \param [in] a2 - an array to subtract.
9569  *  \return DataArrayInt * - the new instance of DataArrayInt.
9570  *          The caller is to delete this result array using decrRef() as it is no more
9571  *          needed.
9572  *  \throw If either \a a1 or \a a2 is NULL.
9573  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
9574  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
9575  *         none of them has number of tuples or components equal to 1.
9576  */
9577 DataArrayInt *DataArrayInt::Substract(const DataArrayInt *a1, const DataArrayInt *a2) throw(INTERP_KERNEL::Exception)
9578 {
9579   if(!a1 || !a2)
9580     throw INTERP_KERNEL::Exception("DataArrayInt::Substract : input DataArrayInt instance is NULL !");
9581   int nbOfTuple1=a1->getNumberOfTuples();
9582   int nbOfTuple2=a2->getNumberOfTuples();
9583   int nbOfComp1=a1->getNumberOfComponents();
9584   int nbOfComp2=a2->getNumberOfComponents();
9585   if(nbOfTuple2==nbOfTuple1)
9586     {
9587       if(nbOfComp1==nbOfComp2)
9588         {
9589           MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
9590           ret->alloc(nbOfTuple2,nbOfComp1);
9591           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::minus<int>());
9592           ret->copyStringInfoFrom(*a1);
9593           return ret.retn();
9594         }
9595       else if(nbOfComp2==1)
9596         {
9597           MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
9598           ret->alloc(nbOfTuple1,nbOfComp1);
9599           const int *a2Ptr=a2->getConstPointer();
9600           const int *a1Ptr=a1->getConstPointer();
9601           int *res=ret->getPointer();
9602           for(int i=0;i<nbOfTuple1;i++)
9603             res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::minus<int>(),a2Ptr[i]));
9604           ret->copyStringInfoFrom(*a1);
9605           return ret.retn();
9606         }
9607       else
9608         {
9609           a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Substract !");
9610           return 0;
9611         }
9612     }
9613   else if(nbOfTuple2==1)
9614     {
9615       a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Substract !");
9616       MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
9617       ret->alloc(nbOfTuple1,nbOfComp1);
9618       const int *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
9619       int *pt=ret->getPointer();
9620       for(int i=0;i<nbOfTuple1;i++)
9621         pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::minus<int>());
9622       ret->copyStringInfoFrom(*a1);
9623       return ret.retn();
9624     }
9625   else
9626     {
9627       a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Substract !");//will always throw an exception
9628       return 0;
9629     }
9630 }
9631
9632 /*!
9633  * Subtract values of another DataArrayInt from values of \a this one. There are 3
9634  * valid cases.
9635  * 1.  The arrays have same number of tuples and components. Then each value of
9636  *   \a other array is subtracted from the corresponding value of \a this array, i.e.:
9637  *   _a_ [ i, j ] -= _other_ [ i, j ].
9638  * 2.  The arrays have same number of tuples and \a other array has one component. Then
9639  *   _a_ [ i, j ] -= _other_ [ i, 0 ].
9640  * 3.  The arrays have same number of components and \a other array has one tuple. Then
9641  *   _a_ [ i, j ] -= _a2_ [ 0, j ].
9642  *
9643  *  \param [in] other - an array to subtract from \a this one.
9644  *  \throw If \a other is NULL.
9645  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
9646  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
9647  *         \a other has number of both tuples and components not equal to 1.
9648  */
9649 void DataArrayInt::substractEqual(const DataArrayInt *other) throw(INTERP_KERNEL::Exception)
9650 {
9651   if(!other)
9652     throw INTERP_KERNEL::Exception("DataArrayInt::substractEqual : input DataArrayInt instance is NULL !");
9653   const char *msg="Nb of tuples mismatch for DataArrayInt::substractEqual  !";
9654   checkAllocated(); other->checkAllocated();
9655   int nbOfTuple=getNumberOfTuples();
9656   int nbOfTuple2=other->getNumberOfTuples();
9657   int nbOfComp=getNumberOfComponents();
9658   int nbOfComp2=other->getNumberOfComponents();
9659   if(nbOfTuple==nbOfTuple2)
9660     {
9661       if(nbOfComp==nbOfComp2)
9662         {
9663           std::transform(begin(),end(),other->begin(),getPointer(),std::minus<int>());
9664         }
9665       else if(nbOfComp2==1)
9666         {
9667           int *ptr=getPointer();
9668           const int *ptrc=other->getConstPointer();
9669           for(int i=0;i<nbOfTuple;i++)
9670             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::minus<int>(),*ptrc++));
9671         }
9672       else
9673         throw INTERP_KERNEL::Exception(msg);
9674     }
9675   else if(nbOfTuple2==1)
9676     {
9677       int *ptr=getPointer();
9678       const int *ptrc=other->getConstPointer();
9679       for(int i=0;i<nbOfTuple;i++)
9680         std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::minus<int>());
9681     }
9682   else
9683     throw INTERP_KERNEL::Exception(msg);
9684   declareAsNew();
9685 }
9686
9687 /*!
9688  * Returns a new DataArrayInt that is a product of two given arrays. There are 3
9689  * valid cases.
9690  * 1.  The arrays have same number of tuples and components. Then each value of
9691  *   the result array (_a_) is a product of the corresponding values of \a a1 and
9692  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ i, j ].
9693  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
9694  *   component. Then
9695  *   _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ i, 0 ].
9696  * 3.  The arrays have same number of components and one array, say _a2_, has one
9697  *   tuple. Then
9698  *   _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ 0, j ].
9699  *
9700  * Info on components is copied either from the first array (in the first case) or from
9701  * the array with maximal number of elements (getNbOfElems()).
9702  *  \param [in] a1 - a factor array.
9703  *  \param [in] a2 - another factor array.
9704  *  \return DataArrayInt * - the new instance of DataArrayInt.
9705  *          The caller is to delete this result array using decrRef() as it is no more
9706  *          needed.
9707  *  \throw If either \a a1 or \a a2 is NULL.
9708  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
9709  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
9710  *         none of them has number of tuples or components equal to 1.
9711  */
9712 DataArrayInt *DataArrayInt::Multiply(const DataArrayInt *a1, const DataArrayInt *a2) throw(INTERP_KERNEL::Exception)
9713 {
9714   if(!a1 || !a2)
9715     throw INTERP_KERNEL::Exception("DataArrayInt::Multiply : input DataArrayInt instance is NULL !");
9716   int nbOfTuple=a1->getNumberOfTuples();
9717   int nbOfTuple2=a2->getNumberOfTuples();
9718   int nbOfComp=a1->getNumberOfComponents();
9719   int nbOfComp2=a2->getNumberOfComponents();
9720   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=0;
9721   if(nbOfTuple==nbOfTuple2)
9722     {
9723       if(nbOfComp==nbOfComp2)
9724         {
9725           ret=DataArrayInt::New();
9726           ret->alloc(nbOfTuple,nbOfComp);
9727           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::multiplies<int>());
9728           ret->copyStringInfoFrom(*a1);
9729         }
9730       else
9731         {
9732           int nbOfCompMin,nbOfCompMax;
9733           const DataArrayInt *aMin, *aMax;
9734           if(nbOfComp>nbOfComp2)
9735             {
9736               nbOfCompMin=nbOfComp2; nbOfCompMax=nbOfComp;
9737               aMin=a2; aMax=a1;
9738             }
9739           else
9740             {
9741               nbOfCompMin=nbOfComp; nbOfCompMax=nbOfComp2;
9742               aMin=a1; aMax=a2;
9743             }
9744           if(nbOfCompMin==1)
9745             {
9746               ret=DataArrayInt::New();
9747               ret->alloc(nbOfTuple,nbOfCompMax);
9748               const int *aMinPtr=aMin->getConstPointer();
9749               const int *aMaxPtr=aMax->getConstPointer();
9750               int *res=ret->getPointer();
9751               for(int i=0;i<nbOfTuple;i++)
9752                 res=std::transform(aMaxPtr+i*nbOfCompMax,aMaxPtr+(i+1)*nbOfCompMax,res,std::bind2nd(std::multiplies<int>(),aMinPtr[i]));
9753               ret->copyStringInfoFrom(*aMax);
9754             }
9755           else
9756             throw INTERP_KERNEL::Exception("Nb of components mismatch for array Multiply !");
9757         }
9758     }
9759   else if((nbOfTuple==1 && nbOfTuple2>1) || (nbOfTuple>1 && nbOfTuple2==1))
9760     {
9761       if(nbOfComp==nbOfComp2)
9762         {
9763           int nbOfTupleMax=std::max(nbOfTuple,nbOfTuple2);
9764           const DataArrayInt *aMin=nbOfTuple>nbOfTuple2?a2:a1;
9765           const DataArrayInt *aMax=nbOfTuple>nbOfTuple2?a1:a2;
9766           const int *aMinPtr=aMin->getConstPointer(),*aMaxPtr=aMax->getConstPointer();
9767           ret=DataArrayInt::New();
9768           ret->alloc(nbOfTupleMax,nbOfComp);
9769           int *res=ret->getPointer();
9770           for(int i=0;i<nbOfTupleMax;i++)
9771             res=std::transform(aMaxPtr+i*nbOfComp,aMaxPtr+(i+1)*nbOfComp,aMinPtr,res,std::multiplies<int>());
9772           ret->copyStringInfoFrom(*aMax);
9773         }
9774       else
9775         throw INTERP_KERNEL::Exception("Nb of components mismatch for array Multiply !");
9776     }
9777   else
9778     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Multiply !");
9779   return ret.retn();
9780 }
9781
9782
9783 /*!
9784  * Multiply values of another DataArrayInt to values of \a this one. There are 3
9785  * valid cases.
9786  * 1.  The arrays have same number of tuples and components. Then each value of
9787  *   \a other array is multiplied to the corresponding value of \a this array, i.e.:
9788  *   _a_ [ i, j ] *= _other_ [ i, j ].
9789  * 2.  The arrays have same number of tuples and \a other array has one component. Then
9790  *   _a_ [ i, j ] *= _other_ [ i, 0 ].
9791  * 3.  The arrays have same number of components and \a other array has one tuple. Then
9792  *   _a_ [ i, j ] *= _a2_ [ 0, j ].
9793  *
9794  *  \param [in] other - an array to multiply to \a this one.
9795  *  \throw If \a other is NULL.
9796  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
9797  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
9798  *         \a other has number of both tuples and components not equal to 1.
9799  */
9800 void DataArrayInt::multiplyEqual(const DataArrayInt *other) throw(INTERP_KERNEL::Exception)
9801 {
9802   if(!other)
9803     throw INTERP_KERNEL::Exception("DataArrayInt::multiplyEqual : input DataArrayInt instance is NULL !");
9804   const char *msg="Nb of tuples mismatch for DataArrayInt::multiplyEqual !";
9805   checkAllocated(); other->checkAllocated();
9806   int nbOfTuple=getNumberOfTuples();
9807   int nbOfTuple2=other->getNumberOfTuples();
9808   int nbOfComp=getNumberOfComponents();
9809   int nbOfComp2=other->getNumberOfComponents();
9810   if(nbOfTuple==nbOfTuple2)
9811     {
9812       if(nbOfComp==nbOfComp2)
9813         {
9814           std::transform(begin(),end(),other->begin(),getPointer(),std::multiplies<int>());
9815         }
9816       else if(nbOfComp2==1)
9817         {
9818           int *ptr=getPointer();
9819           const int *ptrc=other->getConstPointer();
9820           for(int i=0;i<nbOfTuple;i++)
9821             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::multiplies<int>(),*ptrc++));    
9822         }
9823       else
9824         throw INTERP_KERNEL::Exception(msg);
9825     }
9826   else if(nbOfTuple2==1)
9827     {
9828       if(nbOfComp2==nbOfComp)
9829         {
9830           int *ptr=getPointer();
9831           const int *ptrc=other->getConstPointer();
9832           for(int i=0;i<nbOfTuple;i++)
9833             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::multiplies<int>());
9834         }
9835       else
9836         throw INTERP_KERNEL::Exception(msg);
9837     }
9838   else
9839     throw INTERP_KERNEL::Exception(msg);
9840   declareAsNew();
9841 }
9842
9843
9844 /*!
9845  * Returns a new DataArrayInt that is a division of two given arrays. There are 3
9846  * valid cases.
9847  * 1.  The arrays have same number of tuples and components. Then each value of
9848  *   the result array (_a_) is a division of the corresponding values of \a a1 and
9849  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ i, j ].
9850  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
9851  *   component. Then
9852  *   _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ i, 0 ].
9853  * 3.  The arrays have same number of components and one array, say _a2_, has one
9854  *   tuple. Then
9855  *   _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ 0, j ].
9856  *
9857  * Info on components is copied either from the first array (in the first case) or from
9858  * the array with maximal number of elements (getNbOfElems()).
9859  *  \warning No check of division by zero is performed!
9860  *  \param [in] a1 - a numerator array.
9861  *  \param [in] a2 - a denominator array.
9862  *  \return DataArrayInt * - the new instance of DataArrayInt.
9863  *          The caller is to delete this result array using decrRef() as it is no more
9864  *          needed.
9865  *  \throw If either \a a1 or \a a2 is NULL.
9866  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
9867  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
9868  *         none of them has number of tuples or components equal to 1.
9869  */
9870 DataArrayInt *DataArrayInt::Divide(const DataArrayInt *a1, const DataArrayInt *a2) throw(INTERP_KERNEL::Exception)
9871 {
9872   if(!a1 || !a2)
9873     throw INTERP_KERNEL::Exception("DataArrayInt::Divide : input DataArrayInt instance is NULL !");
9874   int nbOfTuple1=a1->getNumberOfTuples();
9875   int nbOfTuple2=a2->getNumberOfTuples();
9876   int nbOfComp1=a1->getNumberOfComponents();
9877   int nbOfComp2=a2->getNumberOfComponents();
9878   if(nbOfTuple2==nbOfTuple1)
9879     {
9880       if(nbOfComp1==nbOfComp2)
9881         {
9882           MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
9883           ret->alloc(nbOfTuple2,nbOfComp1);
9884           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::divides<int>());
9885           ret->copyStringInfoFrom(*a1);
9886           return ret.retn();
9887         }
9888       else if(nbOfComp2==1)
9889         {
9890           MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
9891           ret->alloc(nbOfTuple1,nbOfComp1);
9892           const int *a2Ptr=a2->getConstPointer();
9893           const int *a1Ptr=a1->getConstPointer();
9894           int *res=ret->getPointer();
9895           for(int i=0;i<nbOfTuple1;i++)
9896             res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::divides<int>(),a2Ptr[i]));
9897           ret->copyStringInfoFrom(*a1);
9898           return ret.retn();
9899         }
9900       else
9901         {
9902           a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Divide !");
9903           return 0;
9904         }
9905     }
9906   else if(nbOfTuple2==1)
9907     {
9908       a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Divide !");
9909       MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
9910       ret->alloc(nbOfTuple1,nbOfComp1);
9911       const int *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
9912       int *pt=ret->getPointer();
9913       for(int i=0;i<nbOfTuple1;i++)
9914         pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::divides<int>());
9915       ret->copyStringInfoFrom(*a1);
9916       return ret.retn();
9917     }
9918   else
9919     {
9920       a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Divide !");//will always throw an exception
9921       return 0;
9922     }
9923 }
9924
9925 /*!
9926  * Divide values of \a this array by values of another DataArrayInt. There are 3
9927  * valid cases.
9928  * 1.  The arrays have same number of tuples and components. Then each value of
9929  *    \a this array is divided by the corresponding value of \a other one, i.e.:
9930  *   _a_ [ i, j ] /= _other_ [ i, j ].
9931  * 2.  The arrays have same number of tuples and \a other array has one component. Then
9932  *   _a_ [ i, j ] /= _other_ [ i, 0 ].
9933  * 3.  The arrays have same number of components and \a other array has one tuple. Then
9934  *   _a_ [ i, j ] /= _a2_ [ 0, j ].
9935  *
9936  *  \warning No check of division by zero is performed!
9937  *  \param [in] other - an array to divide \a this one by.
9938  *  \throw If \a other is NULL.
9939  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
9940  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
9941  *         \a other has number of both tuples and components not equal to 1.
9942  */
9943 void DataArrayInt::divideEqual(const DataArrayInt *other) throw(INTERP_KERNEL::Exception)
9944 {
9945   if(!other)
9946     throw INTERP_KERNEL::Exception("DataArrayInt::divideEqual : input DataArrayInt instance is NULL !");
9947   const char *msg="Nb of tuples mismatch for DataArrayInt::divideEqual !";
9948   checkAllocated(); other->checkAllocated();
9949   int nbOfTuple=getNumberOfTuples();
9950   int nbOfTuple2=other->getNumberOfTuples();
9951   int nbOfComp=getNumberOfComponents();
9952   int nbOfComp2=other->getNumberOfComponents();
9953   if(nbOfTuple==nbOfTuple2)
9954     {
9955       if(nbOfComp==nbOfComp2)
9956         {
9957           std::transform(begin(),end(),other->begin(),getPointer(),std::divides<int>());
9958         }
9959       else if(nbOfComp2==1)
9960         {
9961           int *ptr=getPointer();
9962           const int *ptrc=other->getConstPointer();
9963           for(int i=0;i<nbOfTuple;i++)
9964             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::divides<int>(),*ptrc++));
9965         }
9966       else
9967         throw INTERP_KERNEL::Exception(msg);
9968     }
9969   else if(nbOfTuple2==1)
9970     {
9971       if(nbOfComp2==nbOfComp)
9972         {
9973           int *ptr=getPointer();
9974           const int *ptrc=other->getConstPointer();
9975           for(int i=0;i<nbOfTuple;i++)
9976             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::divides<int>());
9977         }
9978       else
9979         throw INTERP_KERNEL::Exception(msg);
9980     }
9981   else
9982     throw INTERP_KERNEL::Exception(msg);
9983   declareAsNew();
9984 }
9985
9986
9987 /*!
9988  * Returns a new DataArrayInt that is a modulus of two given arrays. There are 3
9989  * valid cases.
9990  * 1.  The arrays have same number of tuples and components. Then each value of
9991  *   the result array (_a_) is a division of the corresponding values of \a a1 and
9992  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] % _a2_ [ i, j ].
9993  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
9994  *   component. Then
9995  *   _a_ [ i, j ] = _a1_ [ i, j ] % _a2_ [ i, 0 ].
9996  * 3.  The arrays have same number of components and one array, say _a2_, has one
9997  *   tuple. Then
9998  *   _a_ [ i, j ] = _a1_ [ i, j ] % _a2_ [ 0, j ].
9999  *
10000  * Info on components is copied either from the first array (in the first case) or from
10001  * the array with maximal number of elements (getNbOfElems()).
10002  *  \warning No check of division by zero is performed!
10003  *  \param [in] a1 - a dividend array.
10004  *  \param [in] a2 - a divisor array.
10005  *  \return DataArrayInt * - the new instance of DataArrayInt.
10006  *          The caller is to delete this result array using decrRef() as it is no more
10007  *          needed.
10008  *  \throw If either \a a1 or \a a2 is NULL.
10009  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
10010  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
10011  *         none of them has number of tuples or components equal to 1.
10012  */
10013 DataArrayInt *DataArrayInt::Modulus(const DataArrayInt *a1, const DataArrayInt *a2) throw(INTERP_KERNEL::Exception)
10014 {
10015     if(!a1 || !a2)
10016     throw INTERP_KERNEL::Exception("DataArrayInt::Modulus : input DataArrayInt instance is NULL !");
10017   int nbOfTuple1=a1->getNumberOfTuples();
10018   int nbOfTuple2=a2->getNumberOfTuples();
10019   int nbOfComp1=a1->getNumberOfComponents();
10020   int nbOfComp2=a2->getNumberOfComponents();
10021   if(nbOfTuple2==nbOfTuple1)
10022     {
10023       if(nbOfComp1==nbOfComp2)
10024         {
10025           MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
10026           ret->alloc(nbOfTuple2,nbOfComp1);
10027           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::modulus<int>());
10028           ret->copyStringInfoFrom(*a1);
10029           return ret.retn();
10030         }
10031       else if(nbOfComp2==1)
10032         {
10033           MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
10034           ret->alloc(nbOfTuple1,nbOfComp1);
10035           const int *a2Ptr=a2->getConstPointer();
10036           const int *a1Ptr=a1->getConstPointer();
10037           int *res=ret->getPointer();
10038           for(int i=0;i<nbOfTuple1;i++)
10039             res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::modulus<int>(),a2Ptr[i]));
10040           ret->copyStringInfoFrom(*a1);
10041           return ret.retn();
10042         }
10043       else
10044         {
10045           a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Modulus !");
10046           return 0;
10047         }
10048     }
10049   else if(nbOfTuple2==1)
10050     {
10051       a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Modulus !");
10052       MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
10053       ret->alloc(nbOfTuple1,nbOfComp1);
10054       const int *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
10055       int *pt=ret->getPointer();
10056       for(int i=0;i<nbOfTuple1;i++)
10057         pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::modulus<int>());
10058       ret->copyStringInfoFrom(*a1);
10059       return ret.retn();
10060     }
10061   else
10062     {
10063       a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Modulus !");//will always throw an exception
10064       return 0;
10065     }
10066 }
10067
10068 /*!
10069  * Modify \a this array so that each value becomes a modulus of division of this value by
10070  * a value of another DataArrayInt. There are 3 valid cases.
10071  * 1.  The arrays have same number of tuples and components. Then each value of
10072  *    \a this array is divided by the corresponding value of \a other one, i.e.:
10073  *   _a_ [ i, j ] %= _other_ [ i, j ].
10074  * 2.  The arrays have same number of tuples and \a other array has one component. Then
10075  *   _a_ [ i, j ] %= _other_ [ i, 0 ].
10076  * 3.  The arrays have same number of components and \a other array has one tuple. Then
10077  *   _a_ [ i, j ] %= _a2_ [ 0, j ].
10078  *
10079  *  \warning No check of division by zero is performed!
10080  *  \param [in] other - a divisor array.
10081  *  \throw If \a other is NULL.
10082  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
10083  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
10084  *         \a other has number of both tuples and components not equal to 1.
10085  */
10086 void DataArrayInt::modulusEqual(const DataArrayInt *other) throw(INTERP_KERNEL::Exception)
10087 {
10088   if(!other)
10089     throw INTERP_KERNEL::Exception("DataArrayInt::modulusEqual : input DataArrayInt instance is NULL !");
10090   const char *msg="Nb of tuples mismatch for DataArrayInt::modulusEqual !";
10091   checkAllocated(); other->checkAllocated();
10092   int nbOfTuple=getNumberOfTuples();
10093   int nbOfTuple2=other->getNumberOfTuples();
10094   int nbOfComp=getNumberOfComponents();
10095   int nbOfComp2=other->getNumberOfComponents();
10096   if(nbOfTuple==nbOfTuple2)
10097     {
10098       if(nbOfComp==nbOfComp2)
10099         {
10100           std::transform(begin(),end(),other->begin(),getPointer(),std::modulus<int>());
10101         }
10102       else if(nbOfComp2==1)
10103         {
10104           if(nbOfComp2==nbOfComp)
10105             {
10106               int *ptr=getPointer();
10107               const int *ptrc=other->getConstPointer();
10108               for(int i=0;i<nbOfTuple;i++)
10109                 std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::modulus<int>(),*ptrc++));
10110             }
10111           else
10112             throw INTERP_KERNEL::Exception(msg);
10113         }
10114       else
10115         throw INTERP_KERNEL::Exception(msg);
10116     }
10117   else if(nbOfTuple2==1)
10118     {
10119       int *ptr=getPointer();
10120       const int *ptrc=other->getConstPointer();
10121       for(int i=0;i<nbOfTuple;i++)
10122         std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::modulus<int>());
10123     }
10124   else
10125     throw INTERP_KERNEL::Exception(msg);
10126   declareAsNew();
10127 }
10128
10129 /*!
10130  * Returns a new DataArrayInt that is the result of pow of two given arrays. There are 3
10131  * valid cases.
10132  *
10133  *  \param [in] a1 - an array to pow up.
10134  *  \param [in] a2 - another array to sum up.
10135  *  \return DataArrayInt * - the new instance of DataArrayInt.
10136  *          The caller is to delete this result array using decrRef() as it is no more
10137  *          needed.
10138  *  \throw If either \a a1 or \a a2 is NULL.
10139  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
10140  *  \throw If \a a1->getNumberOfComponents() != 1 or \a a2->getNumberOfComponents() != 1.
10141  *  \throw If there is a negative value in \a a2.
10142  */
10143 DataArrayInt *DataArrayInt::Pow(const DataArrayInt *a1, const DataArrayInt *a2) throw(INTERP_KERNEL::Exception)
10144 {
10145   if(!a1 || !a2)
10146     throw INTERP_KERNEL::Exception("DataArrayInt::Pow : at least one of input instances is null !");
10147   int nbOfTuple=a1->getNumberOfTuples();
10148   int nbOfTuple2=a2->getNumberOfTuples();
10149   int nbOfComp=a1->getNumberOfComponents();
10150   int nbOfComp2=a2->getNumberOfComponents();
10151   if(nbOfTuple!=nbOfTuple2)
10152     throw INTERP_KERNEL::Exception("DataArrayInt::Pow : number of tuples mismatches !");
10153   if(nbOfComp!=1 || nbOfComp2!=1)
10154     throw INTERP_KERNEL::Exception("DataArrayInt::Pow : number of components of both arrays must be equal to 1 !");
10155   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbOfTuple,1);
10156   const int *ptr1(a1->begin()),*ptr2(a2->begin());
10157   int *ptr=ret->getPointer();
10158   for(int i=0;i<nbOfTuple;i++,ptr1++,ptr2++,ptr++)
10159     {
10160       if(*ptr2>=0)
10161         {
10162           int tmp=1;
10163           for(int j=0;j<*ptr2;j++)
10164             tmp*=*ptr1;
10165           *ptr=tmp;
10166         }
10167       else
10168         {
10169           std::ostringstream oss; oss << "DataArrayInt::Pow : on tuple #" << i << " of a2 value is < 0 (" << *ptr2 << ") !";
10170           throw INTERP_KERNEL::Exception(oss.str().c_str());
10171         }
10172     }
10173   return ret.retn();
10174 }
10175
10176 /*!
10177  * Apply pow on values of another DataArrayInt to values of \a this one.
10178  *
10179  *  \param [in] other - an array to pow to \a this one.
10180  *  \throw If \a other is NULL.
10181  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples()
10182  *  \throw If \a this->getNumberOfComponents() != 1 or \a other->getNumberOfComponents() != 1
10183  *  \throw If there is a negative value in \a other.
10184  */
10185 void DataArrayInt::powEqual(const DataArrayInt *other) throw(INTERP_KERNEL::Exception)
10186 {
10187   if(!other)
10188     throw INTERP_KERNEL::Exception("DataArrayInt::powEqual : input instance is null !");
10189   int nbOfTuple=getNumberOfTuples();
10190   int nbOfTuple2=other->getNumberOfTuples();
10191   int nbOfComp=getNumberOfComponents();
10192   int nbOfComp2=other->getNumberOfComponents();
10193   if(nbOfTuple!=nbOfTuple2)
10194     throw INTERP_KERNEL::Exception("DataArrayInt::powEqual : number of tuples mismatches !");
10195   if(nbOfComp!=1 || nbOfComp2!=1)
10196     throw INTERP_KERNEL::Exception("DataArrayInt::powEqual : number of components of both arrays must be equal to 1 !");
10197   int *ptr=getPointer();
10198   const int *ptrc=other->begin();
10199   for(int i=0;i<nbOfTuple;i++,ptrc++,ptr++)
10200     {
10201       if(*ptrc>=0)
10202         {
10203           int tmp=1;
10204           for(int j=0;j<*ptrc;j++)
10205             tmp*=*ptr;
10206           *ptr=tmp;
10207         }
10208       else
10209         {
10210           std::ostringstream oss; oss << "DataArrayInt::powEqual : on tuple #" << i << " of other value is < 0 (" << *ptrc << ") !";
10211           throw INTERP_KERNEL::Exception(oss.str().c_str());
10212         }
10213     }
10214   declareAsNew();
10215 }
10216
10217 /*!
10218  * Returns a C array which is a renumbering map in "Old to New" mode for the input array.
10219  * This map, if applied to \a start array, would make it sorted. For example, if
10220  * \a start array contents are [9,10,0,6,4,11,3,7] then the contents of the result array is
10221  * [5,6,0,3,2,7,1,4].
10222  *  \param [in] start - pointer to the first element of the array for which the
10223  *         permutation map is computed.
10224  *  \param [in] end - pointer specifying the end of the array \a start, so that
10225  *         the last value of \a start is \a end[ -1 ].
10226  *  \return int * - the result permutation array that the caller is to delete as it is no
10227  *         more needed.
10228  *  \throw If there are equal values in the input array.
10229  */
10230 int *DataArrayInt::CheckAndPreparePermutation(const int *start, const int *end)
10231 {
10232   std::size_t sz=std::distance(start,end);
10233   int *ret=(int *)malloc(sz*sizeof(int));
10234   int *work=new int[sz];
10235   std::copy(start,end,work);
10236   std::sort(work,work+sz);
10237   if(std::unique(work,work+sz)!=work+sz)
10238     {
10239       delete [] work;
10240       free(ret);
10241       throw INTERP_KERNEL::Exception("Some elements are equals in the specified array !");
10242     }
10243   std::map<int,int> m;
10244   for(int *workPt=work;workPt!=work+sz;workPt++)
10245     m[*workPt]=(int)std::distance(work,workPt);
10246   int *iter2=ret;
10247   for(const int *iter=start;iter!=end;iter++,iter2++)
10248     *iter2=m[*iter];
10249   delete [] work;
10250   return ret;
10251 }
10252
10253 /*!
10254  * Returns a new DataArrayInt containing an arithmetic progression
10255  * that is equal to the sequence returned by Python \c range(\a begin,\a  end,\a  step )
10256  * function.
10257  *  \param [in] begin - the start value of the result sequence.
10258  *  \param [in] end - limiting value, so that every value of the result array is less than
10259  *              \a end.
10260  *  \param [in] step - specifies the increment or decrement.
10261  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
10262  *          array using decrRef() as it is no more needed.
10263  *  \throw If \a step == 0.
10264  *  \throw If \a end < \a begin && \a step > 0.
10265  *  \throw If \a end > \a begin && \a step < 0.
10266  */
10267 DataArrayInt *DataArrayInt::Range(int begin, int end, int step) throw(INTERP_KERNEL::Exception)
10268 {
10269   int nbOfTuples=GetNumberOfItemGivenBESRelative(begin,end,step,"DataArrayInt::Range");
10270   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
10271   ret->alloc(nbOfTuples,1);
10272   int *ptr=ret->getPointer();
10273   if(step>0)
10274     {
10275       for(int i=begin;i<end;i+=step,ptr++)
10276         *ptr=i;
10277     }
10278   else
10279     {
10280       for(int i=begin;i>end;i+=step,ptr++)
10281         *ptr=i;
10282     }
10283   return ret.retn();
10284 }
10285
10286 /*!
10287  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
10288  * Server side.
10289  */
10290 void DataArrayInt::getTinySerializationIntInformation(std::vector<int>& tinyInfo) const
10291 {
10292   tinyInfo.resize(2);
10293   if(isAllocated())
10294     {
10295       tinyInfo[0]=getNumberOfTuples();
10296       tinyInfo[1]=getNumberOfComponents();
10297     }
10298   else
10299     {
10300       tinyInfo[0]=-1;
10301       tinyInfo[1]=-1;
10302     }
10303 }
10304
10305 /*!
10306  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
10307  * Server side.
10308  */
10309 void DataArrayInt::getTinySerializationStrInformation(std::vector<std::string>& tinyInfo) const
10310 {
10311   if(isAllocated())
10312     {
10313       int nbOfCompo=getNumberOfComponents();
10314       tinyInfo.resize(nbOfCompo+1);
10315       tinyInfo[0]=getName();
10316       for(int i=0;i<nbOfCompo;i++)
10317         tinyInfo[i+1]=getInfoOnComponent(i);
10318     }
10319   else
10320     {
10321       tinyInfo.resize(1);
10322       tinyInfo[0]=getName();
10323     }
10324 }
10325
10326 /*!
10327  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
10328  * This method returns if a feeding is needed.
10329  */
10330 bool DataArrayInt::resizeForUnserialization(const std::vector<int>& tinyInfoI)
10331 {
10332   int nbOfTuple=tinyInfoI[0];
10333   int nbOfComp=tinyInfoI[1];
10334   if(nbOfTuple!=-1 || nbOfComp!=-1)
10335     {
10336       alloc(nbOfTuple,nbOfComp);
10337       return true;
10338     }
10339   return false;
10340 }
10341
10342 /*!
10343  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
10344  * This method returns if a feeding is needed.
10345  */
10346 void DataArrayInt::finishUnserialization(const std::vector<int>& tinyInfoI, const std::vector<std::string>& tinyInfoS)
10347 {
10348   setName(tinyInfoS[0].c_str());
10349   if(isAllocated())
10350     {
10351       int nbOfCompo=getNumberOfComponents();
10352       for(int i=0;i<nbOfCompo;i++)
10353         setInfoOnComponent(i,tinyInfoS[i+1].c_str());
10354     }
10355 }
10356
10357 DataArrayIntIterator::DataArrayIntIterator(DataArrayInt *da):_da(da),_pt(0),_tuple_id(0),_nb_comp(0),_nb_tuple(0)
10358 {
10359   if(_da)
10360     {
10361       _da->incrRef();
10362       if(_da->isAllocated())
10363         {
10364           _nb_comp=da->getNumberOfComponents();
10365           _nb_tuple=da->getNumberOfTuples();
10366           _pt=da->getPointer();
10367         }
10368     }
10369 }
10370
10371 DataArrayIntIterator::~DataArrayIntIterator()
10372 {
10373   if(_da)
10374     _da->decrRef();
10375 }
10376
10377 DataArrayIntTuple *DataArrayIntIterator::nextt() throw(INTERP_KERNEL::Exception)
10378 {
10379   if(_tuple_id<_nb_tuple)
10380     {
10381       _tuple_id++;
10382       DataArrayIntTuple *ret=new DataArrayIntTuple(_pt,_nb_comp);
10383       _pt+=_nb_comp;
10384       return ret;
10385     }
10386   else
10387     return 0;
10388 }
10389
10390 DataArrayIntTuple::DataArrayIntTuple(int *pt, int nbOfComp):_pt(pt),_nb_of_compo(nbOfComp)
10391 {
10392 }
10393
10394 std::string DataArrayIntTuple::repr() const throw(INTERP_KERNEL::Exception)
10395 {
10396   std::ostringstream oss; oss << "(";
10397   for(int i=0;i<_nb_of_compo-1;i++)
10398     oss << _pt[i] << ", ";
10399   oss << _pt[_nb_of_compo-1] << ")";
10400   return oss.str();
10401 }
10402
10403 int DataArrayIntTuple::intValue() const throw(INTERP_KERNEL::Exception)
10404 {
10405   if(_nb_of_compo==1)
10406     return *_pt;
10407   throw INTERP_KERNEL::Exception("DataArrayIntTuple::intValue : DataArrayIntTuple instance has not exactly 1 component -> Not possible to convert it into an integer !");
10408 }
10409
10410 /*!
10411  * This method returns a newly allocated instance the caller should dealed with by a ParaMEDMEM::DataArrayInt::decrRef.
10412  * This method performs \b no copy of data. The content is only referenced using ParaMEDMEM::DataArrayInt::useArray with ownership set to \b false.
10413  * 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
10414  * \b nbOfCompo=1 and \bnbOfTuples==this->_nb_of_elem.
10415  */
10416 DataArrayInt *DataArrayIntTuple::buildDAInt(int nbOfTuples, int nbOfCompo) const throw(INTERP_KERNEL::Exception)
10417 {
10418   if((_nb_of_compo==nbOfCompo && nbOfTuples==1) || (_nb_of_compo==nbOfTuples && nbOfCompo==1))
10419     {
10420       DataArrayInt *ret=DataArrayInt::New();
10421       ret->useExternalArrayWithRWAccess(_pt,nbOfTuples,nbOfCompo);
10422       return ret;
10423     }
10424   else
10425     {
10426       std::ostringstream oss; oss << "DataArrayIntTuple::buildDAInt : unable to build a requested DataArrayInt instance with nbofTuple=" << nbOfTuples << " and nbOfCompo=" << nbOfCompo;
10427       oss << ".\nBecause the number of elements in this is " << _nb_of_compo << " !";
10428       throw INTERP_KERNEL::Exception(oss.str().c_str());
10429     }
10430 }