Salome HOME
debugs
[tools/medcoupling.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     {
1295       int v=old2New[i];
1296       if(v>=0 && v<nbTuples)
1297         std::copy(iptr+nbOfCompo*i,iptr+nbOfCompo*(i+1),tmp+nbOfCompo*v);
1298       else
1299         {
1300           std::ostringstream oss; oss << "DataArrayDouble::renumberInPlace : At place #" << i << " value is " << v << " ! Should be in [0," << nbTuples << ") !";
1301           throw INTERP_KERNEL::Exception(oss.str().c_str());
1302         }
1303     }
1304   std::copy(tmp,tmp+nbTuples*nbOfCompo,getPointer());
1305   delete [] tmp;
1306   declareAsNew();
1307 }
1308
1309 /*!
1310  * Permutes values of \a this array as required by \a new2Old array. The values are
1311  * permuted so that \c new[ i ] = \c old[ \a new2Old[ i ]]. Number of tuples remains
1312  * the same as in \this one.
1313  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
1314  *  \param [in] new2Old - C array of length equal to \a this->getNumberOfTuples()
1315  *     giving a previous position of i-th new value.
1316  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1317  *          is to delete using decrRef() as it is no more needed.
1318  */
1319 void DataArrayDouble::renumberInPlaceR(const int *new2Old) throw(INTERP_KERNEL::Exception)
1320 {
1321   checkAllocated();
1322   int nbTuples=getNumberOfTuples();
1323   int nbOfCompo=getNumberOfComponents();
1324   double *tmp=new double[nbTuples*nbOfCompo];
1325   const double *iptr=getConstPointer();
1326   for(int i=0;i<nbTuples;i++)
1327     {
1328       int v=new2Old[i];
1329       if(v>=0 && v<nbTuples)
1330         std::copy(iptr+nbOfCompo*v,iptr+nbOfCompo*(v+1),tmp+nbOfCompo*i);
1331       else
1332         {
1333           std::ostringstream oss; oss << "DataArrayDouble::renumberInPlaceR : At place #" << i << " value is " << v << " ! Should be in [0," << nbTuples << ") !";
1334           throw INTERP_KERNEL::Exception(oss.str().c_str());
1335         }
1336     }
1337   std::copy(tmp,tmp+nbTuples*nbOfCompo,getPointer());
1338   delete [] tmp;
1339   declareAsNew();
1340 }
1341
1342 /*!
1343  * Returns a copy of \a this array with values permuted as required by \a old2New array.
1344  * The values are permuted so that  \c new[ \a old2New[ i ]] = \c old[ i ].
1345  * Number of tuples in the result array remains the same as in \this one.
1346  * If a permutation reduction is needed, renumberAndReduce() should be used.
1347  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
1348  *  \param [in] old2New - C array of length equal to \a this->getNumberOfTuples()
1349  *          giving a new position for i-th old value.
1350  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1351  *          is to delete using decrRef() as it is no more needed.
1352  *  \throw If \a this is not allocated.
1353  */
1354 DataArrayDouble *DataArrayDouble::renumber(const int *old2New) const throw(INTERP_KERNEL::Exception)
1355 {
1356   checkAllocated();
1357   int nbTuples=getNumberOfTuples();
1358   int nbOfCompo=getNumberOfComponents();
1359   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
1360   ret->alloc(nbTuples,nbOfCompo);
1361   ret->copyStringInfoFrom(*this);
1362   const double *iptr=getConstPointer();
1363   double *optr=ret->getPointer();
1364   for(int i=0;i<nbTuples;i++)
1365     std::copy(iptr+nbOfCompo*i,iptr+nbOfCompo*(i+1),optr+nbOfCompo*old2New[i]);
1366   ret->copyStringInfoFrom(*this);
1367   return ret.retn();
1368 }
1369
1370 /*!
1371  * Returns a copy of \a this array with values permuted as required by \a new2Old array.
1372  * The values are permuted so that  \c new[ i ] = \c old[ \a new2Old[ i ]]. Number of
1373  * tuples in the result array remains the same as in \this one.
1374  * If a permutation reduction is needed, substr() or selectByTupleId() should be used.
1375  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
1376  *  \param [in] new2Old - C array of length equal to \a this->getNumberOfTuples()
1377  *     giving a previous position of i-th new value.
1378  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1379  *          is to delete using decrRef() as it is no more needed.
1380  */
1381 DataArrayDouble *DataArrayDouble::renumberR(const int *new2Old) const throw(INTERP_KERNEL::Exception)
1382 {
1383   checkAllocated();
1384   int nbTuples=getNumberOfTuples();
1385   int nbOfCompo=getNumberOfComponents();
1386   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
1387   ret->alloc(nbTuples,nbOfCompo);
1388   ret->copyStringInfoFrom(*this);
1389   const double *iptr=getConstPointer();
1390   double *optr=ret->getPointer();
1391   for(int i=0;i<nbTuples;i++)
1392     std::copy(iptr+nbOfCompo*new2Old[i],iptr+nbOfCompo*(new2Old[i]+1),optr+i*nbOfCompo);
1393   ret->copyStringInfoFrom(*this);
1394   return ret.retn();
1395 }
1396
1397 /*!
1398  * Returns a shorten and permuted copy of \a this array. The new DataArrayDouble is
1399  * of size \a newNbOfTuple and it's values are permuted as required by \a old2New array.
1400  * The values are permuted so that  \c new[ \a old2New[ i ]] = \c old[ i ] for all
1401  * \a old2New[ i ] >= 0. In other words every i-th tuple in \a this array, for which 
1402  * \a old2New[ i ] is negative, is missing from the result array.
1403  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
1404  *  \param [in] old2New - C array of length equal to \a this->getNumberOfTuples()
1405  *     giving a new position for i-th old tuple and giving negative position for
1406  *     for i-th old tuple that should be omitted.
1407  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1408  *          is to delete using decrRef() as it is no more needed.
1409  */
1410 DataArrayDouble *DataArrayDouble::renumberAndReduce(const int *old2New, int newNbOfTuple) const throw(INTERP_KERNEL::Exception)
1411 {
1412   checkAllocated();
1413   int nbTuples=getNumberOfTuples();
1414   int nbOfCompo=getNumberOfComponents();
1415   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
1416   ret->alloc(newNbOfTuple,nbOfCompo);
1417   const double *iptr=getConstPointer();
1418   double *optr=ret->getPointer();
1419   for(int i=0;i<nbTuples;i++)
1420     {
1421       int w=old2New[i];
1422       if(w>=0)
1423         std::copy(iptr+i*nbOfCompo,iptr+(i+1)*nbOfCompo,optr+w*nbOfCompo);
1424     }
1425   ret->copyStringInfoFrom(*this);
1426   return ret.retn();
1427 }
1428
1429 /*!
1430  * Returns a shorten and permuted copy of \a this array. The new DataArrayDouble is
1431  * of size \a new2OldEnd - \a new2OldBg and it's values are permuted as required by
1432  * \a new2OldBg array.
1433  * The values are permuted so that  \c new[ i ] = \c old[ \a new2OldBg[ i ]].
1434  * This method is equivalent to renumberAndReduce() except that convention in input is
1435  * \c new2old and \b not \c old2new.
1436  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
1437  *  \param [in] new2OldBg - pointer to the beginning of a permutation array that gives a
1438  *              tuple index in \a this array to fill the i-th tuple in the new array.
1439  *  \param [in] new2OldEnd - specifies the end of the permutation array that starts at
1440  *              \a new2OldBg, so that pointer to a tuple index (\a pi) varies as this:
1441  *              \a new2OldBg <= \a pi < \a new2OldEnd.
1442  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1443  *          is to delete using decrRef() as it is no more needed.
1444  */
1445 DataArrayDouble *DataArrayDouble::selectByTupleId(const int *new2OldBg, const int *new2OldEnd) const
1446 {
1447   checkAllocated();
1448   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
1449   int nbComp=getNumberOfComponents();
1450   ret->alloc((int)std::distance(new2OldBg,new2OldEnd),nbComp);
1451   ret->copyStringInfoFrom(*this);
1452   double *pt=ret->getPointer();
1453   const double *srcPt=getConstPointer();
1454   int i=0;
1455   for(const int *w=new2OldBg;w!=new2OldEnd;w++,i++)
1456     std::copy(srcPt+(*w)*nbComp,srcPt+((*w)+1)*nbComp,pt+i*nbComp);
1457   ret->copyStringInfoFrom(*this);
1458   return ret.retn();
1459 }
1460
1461 /*!
1462  * Returns a shorten and permuted copy of \a this array. The new DataArrayDouble is
1463  * of size \a new2OldEnd - \a new2OldBg and it's values are permuted as required by
1464  * \a new2OldBg array.
1465  * The values are permuted so that  \c new[ i ] = \c old[ \a new2OldBg[ i ]].
1466  * This method is equivalent to renumberAndReduce() except that convention in input is
1467  * \c new2old and \b not \c old2new.
1468  * This method is equivalent to selectByTupleId() except that it prevents coping data
1469  * from behind the end of \a this array.
1470  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
1471  *  \param [in] new2OldBg - pointer to the beginning of a permutation array that gives a
1472  *              tuple index in \a this array to fill the i-th tuple in the new array.
1473  *  \param [in] new2OldEnd - specifies the end of the permutation array that starts at
1474  *              \a new2OldBg, so that pointer to a tuple index (\a pi) varies as this:
1475  *              \a new2OldBg <= \a pi < \a new2OldEnd.
1476  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1477  *          is to delete using decrRef() as it is no more needed.
1478  *  \throw If \a new2OldEnd - \a new2OldBg > \a this->getNumberOfTuples().
1479  */
1480 DataArrayDouble *DataArrayDouble::selectByTupleIdSafe(const int *new2OldBg, const int *new2OldEnd) const throw(INTERP_KERNEL::Exception)
1481 {
1482   checkAllocated();
1483   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
1484   int nbComp=getNumberOfComponents();
1485   int oldNbOfTuples=getNumberOfTuples();
1486   ret->alloc((int)std::distance(new2OldBg,new2OldEnd),nbComp);
1487   ret->copyStringInfoFrom(*this);
1488   double *pt=ret->getPointer();
1489   const double *srcPt=getConstPointer();
1490   int i=0;
1491   for(const int *w=new2OldBg;w!=new2OldEnd;w++,i++)
1492     if(*w>=0 && *w<oldNbOfTuples)
1493       std::copy(srcPt+(*w)*nbComp,srcPt+((*w)+1)*nbComp,pt+i*nbComp);
1494     else
1495       throw INTERP_KERNEL::Exception("DataArrayDouble::selectByTupleIdSafe : some ids has been detected to be out of [0,this->getNumberOfTuples) !");
1496   ret->copyStringInfoFrom(*this);
1497   return ret.retn();
1498 }
1499
1500 /*!
1501  * Returns a shorten copy of \a this array. The new DataArrayDouble contains every
1502  * (\a bg + \c i * \a step)-th tuple of \a this array located before the \a end2-th
1503  * tuple. Indices of the selected tuples are the same as ones returned by the Python
1504  * command \c range( \a bg, \a end2, \a step ).
1505  * This method is equivalent to selectByTupleIdSafe() except that the input array is
1506  * not constructed explicitly.
1507  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
1508  *  \param [in] bg - index of the first tuple to copy from \a this array.
1509  *  \param [in] end2 - index of the tuple before which the tuples to copy are located.
1510  *  \param [in] step - index increment to get index of the next tuple to copy.
1511  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1512  *          is to delete using decrRef() as it is no more needed.
1513  *  \sa DataArrayDouble::substr.
1514  */
1515 DataArrayDouble *DataArrayDouble::selectByTupleId2(int bg, int end2, int step) const throw(INTERP_KERNEL::Exception)
1516 {
1517   checkAllocated();
1518   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
1519   int nbComp=getNumberOfComponents();
1520   int newNbOfTuples=GetNumberOfItemGivenBESRelative(bg,end2,step,"DataArrayDouble::selectByTupleId2 : ");
1521   ret->alloc(newNbOfTuples,nbComp);
1522   double *pt=ret->getPointer();
1523   const double *srcPt=getConstPointer()+bg*nbComp;
1524   for(int i=0;i<newNbOfTuples;i++,srcPt+=step*nbComp)
1525     std::copy(srcPt,srcPt+nbComp,pt+i*nbComp);
1526   ret->copyStringInfoFrom(*this);
1527   return ret.retn();
1528 }
1529
1530 /*!
1531  * Returns a shorten copy of \a this array. The new DataArrayDouble contains ranges
1532  * of tuples specified by \a ranges parameter.
1533  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
1534  *  \param [in] ranges - std::vector of std::pair's each of which defines a range
1535  *              of tuples in [\c begin,\c end) format.
1536  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1537  *          is to delete using decrRef() as it is no more needed.
1538  *  \throw If \a end < \a begin.
1539  *  \throw If \a end > \a this->getNumberOfTuples().
1540  *  \throw If \a this is not allocated.
1541  */
1542 DataArray *DataArrayDouble::selectByTupleRanges(const std::vector<std::pair<int,int> >& ranges) const throw(INTERP_KERNEL::Exception)
1543 {
1544   checkAllocated();
1545   int nbOfComp=getNumberOfComponents();
1546   int nbOfTuplesThis=getNumberOfTuples();
1547   if(ranges.empty())
1548     {
1549       DataArrayDouble *ret=DataArrayDouble::New();
1550       ret->alloc(0,nbOfComp);
1551       ret->copyStringInfoFrom(*this);
1552       return ret;
1553     }
1554   int ref=ranges.front().first;
1555   int nbOfTuples=0;
1556   bool isIncreasing=true;
1557   for(std::vector<std::pair<int,int> >::const_iterator it=ranges.begin();it!=ranges.end();it++)
1558     {
1559       if((*it).first<=(*it).second)
1560         {
1561           if((*it).first>=0 && (*it).second<=nbOfTuplesThis)
1562             {
1563               nbOfTuples+=(*it).second-(*it).first;
1564               if(isIncreasing)
1565                 isIncreasing=ref<=(*it).first;
1566               ref=(*it).second;
1567             }
1568           else
1569             {
1570               std::ostringstream oss; oss << "DataArrayDouble::selectByTupleRanges : on range #" << std::distance(ranges.begin(),it);
1571               oss << " (" << (*it).first << "," << (*it).second << ") is greater than number of tuples of this :" << nbOfTuples << " !";
1572               throw INTERP_KERNEL::Exception(oss.str().c_str());
1573             }
1574         }
1575       else
1576         {
1577           std::ostringstream oss; oss << "DataArrayDouble::selectByTupleRanges : on range #" << std::distance(ranges.begin(),it);
1578           oss << " (" << (*it).first << "," << (*it).second << ") end is before begin !";
1579           throw INTERP_KERNEL::Exception(oss.str().c_str());
1580         }
1581     }
1582   if(isIncreasing && nbOfTuplesThis==nbOfTuples)
1583     return deepCpy();
1584   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
1585   ret->alloc(nbOfTuples,nbOfComp);
1586   ret->copyStringInfoFrom(*this);
1587   const double *src=getConstPointer();
1588   double *work=ret->getPointer();
1589   for(std::vector<std::pair<int,int> >::const_iterator it=ranges.begin();it!=ranges.end();it++)
1590     work=std::copy(src+(*it).first*nbOfComp,src+(*it).second*nbOfComp,work);
1591   return ret.retn();
1592 }
1593
1594 /*!
1595  * Returns a shorten copy of \a this array. The new DataArrayDouble contains all
1596  * tuples starting from the \a tupleIdBg-th tuple and including all tuples located before
1597  * the \a tupleIdEnd-th one. This methods has a similar behavior as std::string::substr().
1598  * This method is a specialization of selectByTupleId2().
1599  *  \param [in] tupleIdBg - index of the first tuple to copy from \a this array.
1600  *  \param [in] tupleIdEnd - index of the tuple before which the tuples to copy are located.
1601  *          If \a tupleIdEnd == -1, all the tuples till the end of \a this array are copied.
1602  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1603  *          is to delete using decrRef() as it is no more needed.
1604  *  \throw If \a tupleIdBg < 0.
1605  *  \throw If \a tupleIdBg > \a this->getNumberOfTuples().
1606     \throw If \a tupleIdEnd != -1 && \a tupleIdEnd < \a this->getNumberOfTuples().
1607  *  \sa DataArrayDouble::selectByTupleId2
1608  */
1609 DataArrayDouble *DataArrayDouble::substr(int tupleIdBg, int tupleIdEnd) const throw(INTERP_KERNEL::Exception)
1610 {
1611   checkAllocated();
1612   int nbt=getNumberOfTuples();
1613   if(tupleIdBg<0)
1614     throw INTERP_KERNEL::Exception("DataArrayDouble::substr : The tupleIdBg parameter must be greater than 0 !");
1615   if(tupleIdBg>nbt)
1616     throw INTERP_KERNEL::Exception("DataArrayDouble::substr : The tupleIdBg parameter is greater than number of tuples !");
1617   int trueEnd=tupleIdEnd;
1618   if(tupleIdEnd!=-1)
1619     {
1620       if(tupleIdEnd>nbt)
1621         throw INTERP_KERNEL::Exception("DataArrayDouble::substr : The tupleIdBg parameter is greater or equal than number of tuples !");
1622     }
1623   else
1624     trueEnd=nbt;
1625   int nbComp=getNumberOfComponents();
1626   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
1627   ret->alloc(trueEnd-tupleIdBg,nbComp);
1628   ret->copyStringInfoFrom(*this);
1629   std::copy(getConstPointer()+tupleIdBg*nbComp,getConstPointer()+trueEnd*nbComp,ret->getPointer());
1630   return ret.retn();
1631 }
1632
1633 /*!
1634  * Returns a shorten or extended copy of \a this array. If \a newNbOfComp is less
1635  * than \a this->getNumberOfComponents() then the result array is shorten as each tuple
1636  * is truncated to have \a newNbOfComp components, keeping first components. If \a
1637  * newNbOfComp is more than \a this->getNumberOfComponents() then the result array is
1638  * expanded as each tuple is populated with \a dftValue to have \a newNbOfComp
1639  * components.  
1640  *  \param [in] newNbOfComp - number of components for the new array to have.
1641  *  \param [in] dftValue - value assigned to new values added to the new array.
1642  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1643  *          is to delete using decrRef() as it is no more needed.
1644  *  \throw If \a this is not allocated.
1645  */
1646 DataArrayDouble *DataArrayDouble::changeNbOfComponents(int newNbOfComp, double dftValue) const throw(INTERP_KERNEL::Exception)
1647 {
1648   checkAllocated();
1649   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
1650   ret->alloc(getNumberOfTuples(),newNbOfComp);
1651   const double *oldc=getConstPointer();
1652   double *nc=ret->getPointer();
1653   int nbOfTuples=getNumberOfTuples();
1654   int oldNbOfComp=getNumberOfComponents();
1655   int dim=std::min(oldNbOfComp,newNbOfComp);
1656   for(int i=0;i<nbOfTuples;i++)
1657     {
1658       int j=0;
1659       for(;j<dim;j++)
1660         nc[newNbOfComp*i+j]=oldc[i*oldNbOfComp+j];
1661       for(;j<newNbOfComp;j++)
1662         nc[newNbOfComp*i+j]=dftValue;
1663     }
1664   ret->setName(getName().c_str());
1665   for(int i=0;i<dim;i++)
1666     ret->setInfoOnComponent(i,getInfoOnComponent(i).c_str());
1667   ret->setName(getName().c_str());
1668   return ret.retn();
1669 }
1670
1671 /*!
1672  * Changes the number of components within \a this array so that its raw data **does
1673  * not** change, instead splitting this data into tuples changes.
1674  *  \warning This method erases all (name and unit) component info set before!
1675  *  \param [in] newNbOfComp - number of components for \a this array to have.
1676  *  \throw If \a this is not allocated
1677  *  \throw If getNbOfElems() % \a newNbOfCompo != 0.
1678  *  \throw If \a newNbOfCompo is lower than 1.
1679  *  \throw If the rearrange method would lead to a number of tuples higher than 2147483647 (maximal capacity of int32 !).
1680  *  \warning This method erases all (name and unit) component info set before!
1681  */
1682 void DataArrayDouble::rearrange(int newNbOfCompo) throw(INTERP_KERNEL::Exception)
1683 {
1684   checkAllocated();
1685   if(newNbOfCompo<1)
1686     throw INTERP_KERNEL::Exception("DataArrayDouble::rearrange : input newNbOfCompo must be > 0 !");
1687   std::size_t nbOfElems=getNbOfElems();
1688   if(nbOfElems%newNbOfCompo!=0)
1689     throw INTERP_KERNEL::Exception("DataArrayDouble::rearrange : nbOfElems%newNbOfCompo!=0 !");
1690   if(nbOfElems/newNbOfCompo>(std::size_t)std::numeric_limits<int>::max())
1691     throw INTERP_KERNEL::Exception("DataArrayDouble::rearrange : the rearrangement leads to too high number of tuples (> 2147483647) !");
1692   _info_on_compo.clear();
1693   _info_on_compo.resize(newNbOfCompo);
1694   declareAsNew();
1695 }
1696
1697 /*!
1698  * Changes the number of components within \a this array to be equal to its number
1699  * of tuples, and inversely its number of tuples to become equal to its number of 
1700  * components. So that its raw data **does not** change, instead splitting this
1701  * data into tuples changes.
1702  *  \warning This method erases all (name and unit) component info set before!
1703  *  \warning Do not confuse this method with fromNoInterlace() and toNoInterlace()!
1704  *  \throw If \a this is not allocated.
1705  *  \sa rearrange()
1706  */
1707 void DataArrayDouble::transpose() throw(INTERP_KERNEL::Exception)
1708 {
1709   checkAllocated();
1710   int nbOfTuples=getNumberOfTuples();
1711   rearrange(nbOfTuples);
1712 }
1713
1714 /*!
1715  * Returns a copy of \a this array composed of selected components.
1716  * The new DataArrayDouble has the same number of tuples but includes components
1717  * specified by \a compoIds parameter. So that getNbOfElems() of the result array
1718  * can be either less, same or more than \a this->getNbOfElems().
1719  *  \param [in] compoIds - sequence of zero based indices of components to include
1720  *              into the new array.
1721  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1722  *          is to delete using decrRef() as it is no more needed.
1723  *  \throw If \a this is not allocated.
1724  *  \throw If a component index (\a i) is not valid: 
1725  *         \a i < 0 || \a i >= \a this->getNumberOfComponents().
1726  *
1727  *  \ref py_mcdataarraydouble_KeepSelectedComponents "Here is a Python example".
1728  */
1729 DataArray *DataArrayDouble::keepSelectedComponents(const std::vector<int>& compoIds) const throw(INTERP_KERNEL::Exception)
1730 {
1731   checkAllocated();
1732   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret(DataArrayDouble::New());
1733   std::size_t newNbOfCompo=compoIds.size();
1734   int oldNbOfCompo=getNumberOfComponents();
1735   for(std::vector<int>::const_iterator it=compoIds.begin();it!=compoIds.end();it++)
1736     if((*it)<0 || (*it)>=oldNbOfCompo)
1737       {
1738         std::ostringstream oss; oss << "DataArrayDouble::keepSelectedComponents : invalid requested component : " << *it << " whereas it should be in [0," << oldNbOfCompo << ") !";
1739         throw INTERP_KERNEL::Exception(oss.str().c_str());
1740       }
1741   int nbOfTuples=getNumberOfTuples();
1742   ret->alloc(nbOfTuples,(int)newNbOfCompo);
1743   ret->copyPartOfStringInfoFrom(*this,compoIds);
1744   const double *oldc=getConstPointer();
1745   double *nc=ret->getPointer();
1746   for(int i=0;i<nbOfTuples;i++)
1747     for(std::size_t j=0;j<newNbOfCompo;j++,nc++)
1748       *nc=oldc[i*oldNbOfCompo+compoIds[j]];
1749   return ret.retn();
1750 }
1751
1752 /*!
1753  * Appends components of another array to components of \a this one, tuple by tuple.
1754  * So that the number of tuples of \a this array remains the same and the number of 
1755  * components increases.
1756  *  \param [in] other - the DataArrayDouble to append to \a this one.
1757  *  \throw If \a this is not allocated.
1758  *  \throw If \a this and \a other arrays have different number of tuples.
1759  *
1760  *  \ref cpp_mcdataarraydouble_meldwith "Here is a C++ example".
1761  *
1762  *  \ref py_mcdataarraydouble_meldwith "Here is a Python example".
1763  */
1764 void DataArrayDouble::meldWith(const DataArrayDouble *other) throw(INTERP_KERNEL::Exception)
1765 {
1766   checkAllocated();
1767   other->checkAllocated();
1768   int nbOfTuples=getNumberOfTuples();
1769   if(nbOfTuples!=other->getNumberOfTuples())
1770     throw INTERP_KERNEL::Exception("DataArrayDouble::meldWith : mismatch of number of tuples !");
1771   int nbOfComp1=getNumberOfComponents();
1772   int nbOfComp2=other->getNumberOfComponents();
1773   double *newArr=(double *)malloc((nbOfTuples*(nbOfComp1+nbOfComp2))*sizeof(double));
1774   double *w=newArr;
1775   const double *inp1=getConstPointer();
1776   const double *inp2=other->getConstPointer();
1777   for(int i=0;i<nbOfTuples;i++,inp1+=nbOfComp1,inp2+=nbOfComp2)
1778     {
1779       w=std::copy(inp1,inp1+nbOfComp1,w);
1780       w=std::copy(inp2,inp2+nbOfComp2,w);
1781     }
1782   useArray(newArr,true,C_DEALLOC,nbOfTuples,nbOfComp1+nbOfComp2);
1783   std::vector<int> compIds(nbOfComp2);
1784   for(int i=0;i<nbOfComp2;i++)
1785     compIds[i]=nbOfComp1+i;
1786   copyPartOfStringInfoFrom2(compIds,*other);
1787 }
1788
1789 /*!
1790  * Searches for tuples coincident within \a prec tolerance. Each tuple is considered
1791  * as coordinates of a point in getNumberOfComponents()-dimensional space. The
1792  * distance separating two points is computed with the infinite norm.
1793  *
1794  * Indices of coincident tuples are stored in output arrays.
1795  * A pair of arrays (\a comm, \a commIndex) is called "Surjective Format 2".
1796  *
1797  * This method is typically used by MEDCouplingPointSet::findCommonNodes() and
1798  * MEDCouplingUMesh::mergeNodes().
1799  *  \param [in] prec - minimal absolute distance between two tuples (infinite norm) at which they are
1800  *              considered not coincident.
1801  *  \param [in] limitTupleId - limit tuple id. If all tuples within a group of coincident
1802  *              tuples have id strictly lower than \a limitTupleId then they are not returned.
1803  *  \param [out] comm - the array holding ids (== indices) of coincident tuples. 
1804  *               \a comm->getNumberOfComponents() == 1. 
1805  *               \a comm->getNumberOfTuples() == \a commIndex->back().
1806  *  \param [out] commIndex - the array dividing all indices stored in \a comm into
1807  *               groups of (indices of) coincident tuples. Its every value is a tuple
1808  *               index where a next group of tuples begins. For example the second
1809  *               group of tuples in \a comm is described by following range of indices:
1810  *               [ \a commIndex[1], \a commIndex[2] ). \a commIndex->getNumberOfTuples()-1
1811  *               gives the number of groups of coincident tuples.
1812  *  \throw If \a this is not allocated.
1813  *  \throw If the number of components is not in [1,2,3].
1814  *
1815  *  \ref cpp_mcdataarraydouble_findcommontuples "Here is a C++ example".
1816  *
1817  *  \ref py_mcdataarraydouble_findcommontuples  "Here is a Python example".
1818  *  \sa DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2().
1819  */
1820 void DataArrayDouble::findCommonTuples(double prec, int limitTupleId, DataArrayInt *&comm, DataArrayInt *&commIndex) const throw(INTERP_KERNEL::Exception)
1821 {
1822   checkAllocated();
1823   int nbOfCompo=getNumberOfComponents();
1824   if ((nbOfCompo<1) || (nbOfCompo>3)) //test before work
1825     throw INTERP_KERNEL::Exception("DataArrayDouble::findCommonTuples : Unexpected spacedim of coords. Must be 1, 2 or 3.");
1826   
1827   int nbOfTuples=getNumberOfTuples();
1828   //
1829   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> c(DataArrayInt::New()),cI(DataArrayInt::New()); c->alloc(0,1); cI->pushBackSilent(0);
1830   switch(nbOfCompo)
1831     {
1832     case 3:
1833       findCommonTuplesAlg<3>(begin(),nbOfTuples,limitTupleId,prec,c,cI);
1834       break;
1835     case 2:
1836       findCommonTuplesAlg<2>(begin(),nbOfTuples,limitTupleId,prec,c,cI);
1837       break;
1838     case 1:
1839       findCommonTuplesAlg<1>(begin(),nbOfTuples,limitTupleId,prec,c,cI);
1840       break;
1841     default:
1842       throw INTERP_KERNEL::Exception("DataArrayDouble::findCommonTuples : nb of components managed are 1,2 and 3 ! not implemented for other number of components !");
1843     }
1844   comm=c.retn();
1845   commIndex=cI.retn();
1846 }
1847
1848 /*!
1849  * 
1850  * \param [in] nbTimes specifies the nb of times each tuples in \a this will be duplicated contiguouly in returned DataArrayDouble instance.
1851  *             \a nbTimes  should be at least equal to 1.
1852  * \return a newly allocated DataArrayDouble having one component and number of tuples equal to \a nbTimes * \c this->getNumberOfTuples.
1853  * \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.
1854  */
1855 DataArrayDouble *DataArrayDouble::duplicateEachTupleNTimes(int nbTimes) const throw(INTERP_KERNEL::Exception)
1856 {
1857   checkAllocated();
1858   if(getNumberOfComponents()!=1)
1859     throw INTERP_KERNEL::Exception("DataArrayDouble::duplicateEachTupleNTimes : this should have only one component !");
1860   if(nbTimes<1)
1861     throw INTERP_KERNEL::Exception("DataArrayDouble::duplicateEachTupleNTimes : nb times should be >= 1 !");
1862   int nbTuples=getNumberOfTuples();
1863   const double *inPtr=getConstPointer();
1864   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New(); ret->alloc(nbTimes*nbTuples,1);
1865   double *retPtr=ret->getPointer();
1866   for(int i=0;i<nbTuples;i++,inPtr++)
1867     {
1868       double val=*inPtr;
1869       for(int j=0;j<nbTimes;j++,retPtr++)
1870         *retPtr=val;
1871     }
1872   ret->copyStringInfoFrom(*this);
1873   return ret.retn();
1874 }
1875
1876 /*!
1877  * This methods returns the minimal distance between the two set of points \a this and \a other.
1878  * So \a this and \a other have to have the same number of components. If not an INTERP_KERNEL::Exception will be thrown.
1879  * This method works only if number of components of \a this (equal to those of \a other) is in 1, 2 or 3.
1880  *
1881  * \param [out] thisTupleId the tuple id in \a this corresponding to the returned minimal distance
1882  * \param [out] otherTupleId the tuple id in \a other corresponding to the returned minimal distance
1883  * \return the minimal distance between the two set of points \a this and \a other.
1884  * \sa DataArrayDouble::findClosestTupleId
1885  */
1886 double DataArrayDouble::minimalDistanceTo(const DataArrayDouble *other, int& thisTupleId, int& otherTupleId) const throw(INTERP_KERNEL::Exception)
1887 {
1888   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> part1=findClosestTupleId(other);
1889   int nbOfCompo(getNumberOfComponents());
1890   int otherNbTuples(other->getNumberOfTuples());
1891   const double *thisPt(begin()),*otherPt(other->begin());
1892   const int *part1Pt(part1->begin());
1893   double ret=std::numeric_limits<double>::max();
1894   for(int i=0;i<otherNbTuples;i++,part1Pt++,otherPt+=nbOfCompo)
1895     {
1896       double tmp(0.);
1897       for(int j=0;j<nbOfCompo;j++)
1898         tmp+=(otherPt[j]-thisPt[nbOfCompo*(*part1Pt)+j])*(otherPt[j]-thisPt[nbOfCompo*(*part1Pt)+j]);
1899       if(tmp<ret)
1900         { ret=tmp; thisTupleId=*part1Pt; otherTupleId=i; }
1901     }
1902   return sqrt(ret);
1903 }
1904
1905 /*!
1906  * This methods returns for each tuple in \a other which tuple in \a this is the closest.
1907  * So \a this and \a other have to have the same number of components. If not an INTERP_KERNEL::Exception will be thrown.
1908  * This method works only if number of components of \a this (equal to those of \a other) is in 1, 2 or 3.
1909  *
1910  * \return a newly allocated (new object to be dealt by the caller) DataArrayInt having \c other->getNumberOfTuples() tuples and one components.
1911  * \sa DataArrayDouble::minimalDistanceTo
1912  */
1913 DataArrayInt *DataArrayDouble::findClosestTupleId(const DataArrayDouble *other) const throw(INTERP_KERNEL::Exception)
1914 {
1915   if(!other)
1916     throw INTERP_KERNEL::Exception("DataArrayDouble::findClosestTupleId : other instance is NULL !");
1917   checkAllocated(); other->checkAllocated();
1918   int nbOfCompo=getNumberOfComponents();
1919   if(nbOfCompo!=other->getNumberOfComponents())
1920     {
1921       std::ostringstream oss; oss << "DataArrayDouble::findClosestTupleId : number of components in this is " << nbOfCompo;
1922       oss << ", whereas number of components in other is " << other->getNumberOfComponents() << "! Should be equal !";
1923       throw INTERP_KERNEL::Exception(oss.str().c_str());
1924     }
1925   int nbOfTuples=other->getNumberOfTuples();
1926   int thisNbOfTuples=getNumberOfTuples();
1927   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbOfTuples,1);
1928   double bounds[6];
1929   getMinMaxPerComponent(bounds);
1930   switch(nbOfCompo)
1931     {
1932     case 3:
1933       {
1934         double xDelta(fabs(bounds[1]-bounds[0])),yDelta(fabs(bounds[3]-bounds[2])),zDelta(fabs(bounds[5]-bounds[4]));
1935         double delta=std::max(xDelta,yDelta); delta=std::max(delta,zDelta);
1936         double characSize=pow((delta*delta*delta)/((double)thisNbOfTuples),1./3.);
1937         BBTreePts<3,int> myTree(begin(),0,0,getNumberOfTuples(),characSize*1e-12);
1938         FindClosestTupleIdAlg<3>(myTree,3.*characSize*characSize,other->begin(),nbOfTuples,begin(),thisNbOfTuples,ret->getPointer());
1939         break;
1940       }
1941     case 2:
1942       {
1943         double xDelta(fabs(bounds[1]-bounds[0])),yDelta(fabs(bounds[3]-bounds[2]));
1944         double delta=std::max(xDelta,yDelta);
1945         double characSize=sqrt(delta/(double)thisNbOfTuples);
1946         BBTreePts<2,int> myTree(begin(),0,0,getNumberOfTuples(),characSize*1e-12);
1947         FindClosestTupleIdAlg<2>(myTree,2.*characSize*characSize,other->begin(),nbOfTuples,begin(),thisNbOfTuples,ret->getPointer());
1948         break;
1949       }
1950     case 1:
1951       {
1952         double characSize=fabs(bounds[1]-bounds[0])/thisNbOfTuples;
1953         BBTreePts<1,int> myTree(begin(),0,0,getNumberOfTuples(),characSize*1e-12);
1954         FindClosestTupleIdAlg<1>(myTree,1.*characSize*characSize,other->begin(),nbOfTuples,begin(),thisNbOfTuples,ret->getPointer());
1955         break;
1956       }
1957     default:
1958       throw INTERP_KERNEL::Exception("Unexpected spacedim of coords for findClosestTupleId. Must be 1, 2 or 3.");
1959     }
1960   return ret.retn();
1961 }
1962
1963 /*!
1964  * Returns a copy of \a this array by excluding coincident tuples. Each tuple is
1965  * considered as coordinates of a point in getNumberOfComponents()-dimensional
1966  * space. The distance between tuples is computed using norm2. If several tuples are
1967  * not far each from other than \a prec, only one of them remains in the result
1968  * array. The order of tuples in the result array is same as in \a this one except
1969  * that coincident tuples are excluded.
1970  *  \param [in] prec - minimal absolute distance between two tuples at which they are
1971  *              considered not coincident.
1972  *  \param [in] limitTupleId - limit tuple id. If all tuples within a group of coincident
1973  *              tuples have id strictly lower than \a limitTupleId then they are not excluded.
1974  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1975  *          is to delete using decrRef() as it is no more needed.
1976  *  \throw If \a this is not allocated.
1977  *  \throw If the number of components is not in [1,2,3].
1978  *
1979  *  \ref py_mcdataarraydouble_getdifferentvalues "Here is a Python example".
1980  */
1981 DataArrayDouble *DataArrayDouble::getDifferentValues(double prec, int limitTupleId) const throw(INTERP_KERNEL::Exception)
1982 {
1983   checkAllocated();
1984   DataArrayInt *c0=0,*cI0=0;
1985   findCommonTuples(prec,limitTupleId,c0,cI0);
1986   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> c(c0),cI(cI0);
1987   int newNbOfTuples=-1;
1988   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> o2n=DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2(getNumberOfTuples(),c0->begin(),cI0->begin(),cI0->end(),newNbOfTuples);
1989   return renumberAndReduce(o2n->getConstPointer(),newNbOfTuples);
1990 }
1991
1992 /*!
1993  * Copy all components in a specified order from another DataArrayDouble.
1994  * Both numerical and textual data is copied. The number of tuples in \a this and
1995  * the other array can be different.
1996  *  \param [in] a - the array to copy data from.
1997  *  \param [in] compoIds - sequence of zero based indices of components, data of which is
1998  *              to be copied.
1999  *  \throw If \a a is NULL.
2000  *  \throw If \a compoIds.size() != \a a->getNumberOfComponents().
2001  *  \throw If \a compoIds[i] < 0 or \a compoIds[i] > \a this->getNumberOfComponents().
2002  *
2003  *  \ref py_mcdataarraydouble_setselectedcomponents "Here is a Python example".
2004  */
2005 void DataArrayDouble::setSelectedComponents(const DataArrayDouble *a, const std::vector<int>& compoIds) throw(INTERP_KERNEL::Exception)
2006 {
2007   if(!a)
2008     throw INTERP_KERNEL::Exception("DataArrayDouble::setSelectedComponents : input DataArrayDouble is NULL !");
2009   checkAllocated();
2010   copyPartOfStringInfoFrom2(compoIds,*a);
2011   std::size_t partOfCompoSz=compoIds.size();
2012   int nbOfCompo=getNumberOfComponents();
2013   int nbOfTuples=std::min(getNumberOfTuples(),a->getNumberOfTuples());
2014   const double *ac=a->getConstPointer();
2015   double *nc=getPointer();
2016   for(int i=0;i<nbOfTuples;i++)
2017     for(std::size_t j=0;j<partOfCompoSz;j++,ac++)
2018       nc[nbOfCompo*i+compoIds[j]]=*ac;
2019 }
2020
2021 /*!
2022  * Copy all values from another DataArrayDouble into specified tuples and components
2023  * of \a this array. Textual data is not copied.
2024  * The tree parameters defining set of indices of tuples and components are similar to
2025  * the tree parameters of the Python function \c range(\c start,\c stop,\c step).
2026  *  \param [in] a - the array to copy values from.
2027  *  \param [in] bgTuples - index of the first tuple of \a this array to assign values to.
2028  *  \param [in] endTuples - index of the tuple before which the tuples to assign to
2029  *              are located.
2030  *  \param [in] stepTuples - index increment to get index of the next tuple to assign to.
2031  *  \param [in] bgComp - index of the first component of \a this array to assign values to.
2032  *  \param [in] endComp - index of the component before which the components to assign
2033  *              to are located.
2034  *  \param [in] stepComp - index increment to get index of the next component to assign to.
2035  *  \param [in] strictCompoCompare - if \a true (by default), then \a a->getNumberOfComponents() 
2036  *              must be equal to the number of columns to assign to, else an
2037  *              exception is thrown; if \a false, then it is only required that \a
2038  *              a->getNbOfElems() equals to number of values to assign to (this condition
2039  *              must be respected even if \a strictCompoCompare is \a true). The number of 
2040  *              values to assign to is given by following Python expression:
2041  *              \a nbTargetValues = 
2042  *              \c len(\c range(\a bgTuples,\a endTuples,\a stepTuples)) *
2043  *              \c len(\c range(\a bgComp,\a endComp,\a stepComp)).
2044  *  \throw If \a a is NULL.
2045  *  \throw If \a a is not allocated.
2046  *  \throw If \a this is not allocated.
2047  *  \throw If parameters specifying tuples and components to assign to do not give a
2048  *            non-empty range of increasing indices.
2049  *  \throw If \a a->getNbOfElems() != \a nbTargetValues.
2050  *  \throw If \a strictCompoCompare == \a true && \a a->getNumberOfComponents() !=
2051  *            \c len(\c range(\a bgComp,\a endComp,\a stepComp)).
2052  *
2053  *  \ref py_mcdataarraydouble_setpartofvalues1 "Here is a Python example".
2054  */
2055 void DataArrayDouble::setPartOfValues1(const DataArrayDouble *a, int bgTuples, int endTuples, int stepTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare) throw(INTERP_KERNEL::Exception)
2056 {
2057   if(!a)
2058     throw INTERP_KERNEL::Exception("DataArrayDouble::setPartOfValues1 : input DataArrayDouble is NULL !");
2059   const char msg[]="DataArrayDouble::setPartOfValues1";
2060   checkAllocated();
2061   a->checkAllocated();
2062   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
2063   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
2064   int nbComp=getNumberOfComponents();
2065   int nbOfTuples=getNumberOfTuples();
2066   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
2067   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
2068   bool assignTech=true;
2069   if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
2070     {
2071       if(strictCompoCompare)
2072         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
2073     }
2074   else
2075     {
2076       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
2077       assignTech=false;
2078     }
2079   const double *srcPt=a->getConstPointer();
2080   double *pt=getPointer()+bgTuples*nbComp+bgComp;
2081   if(assignTech)
2082     {
2083       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
2084         for(int j=0;j<newNbOfComp;j++,srcPt++)
2085           pt[j*stepComp]=*srcPt;
2086     }
2087   else
2088     {
2089       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
2090         {
2091           const double *srcPt2=srcPt;
2092           for(int j=0;j<newNbOfComp;j++,srcPt2++)
2093             pt[j*stepComp]=*srcPt2;
2094         }
2095     }
2096 }
2097
2098 /*!
2099  * Assign a given value to values at specified tuples and components of \a this array.
2100  * The tree parameters defining set of indices of tuples and components are similar to
2101  * the tree parameters of the Python function \c range(\c start,\c stop,\c step)..
2102  *  \param [in] a - the value to assign.
2103  *  \param [in] bgTuples - index of the first tuple of \a this array to assign to.
2104  *  \param [in] endTuples - index of the tuple before which the tuples to assign to
2105  *              are located.
2106  *  \param [in] stepTuples - index increment to get index of the next tuple to assign to.
2107  *  \param [in] bgComp - index of the first component of \a this array to assign to.
2108  *  \param [in] endComp - index of the component before which the components to assign
2109  *              to are located.
2110  *  \param [in] stepComp - index increment to get index of the next component to assign to.
2111  *  \throw If \a this is not allocated.
2112  *  \throw If parameters specifying tuples and components to assign to, do not give a
2113  *            non-empty range of increasing indices or indices are out of a valid range
2114  *            for \this array.
2115  *
2116  *  \ref py_mcdataarraydouble_setpartofvaluessimple1 "Here is a Python example".
2117  */
2118 void DataArrayDouble::setPartOfValuesSimple1(double a, int bgTuples, int endTuples, int stepTuples, int bgComp, int endComp, int stepComp) throw(INTERP_KERNEL::Exception)
2119 {
2120   const char msg[]="DataArrayDouble::setPartOfValuesSimple1";
2121   checkAllocated();
2122   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
2123   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
2124   int nbComp=getNumberOfComponents();
2125   int nbOfTuples=getNumberOfTuples();
2126   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
2127   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
2128   double *pt=getPointer()+bgTuples*nbComp+bgComp;
2129   for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
2130     for(int j=0;j<newNbOfComp;j++)
2131       pt[j*stepComp]=a;
2132 }
2133
2134 /*!
2135  * Copy all values from another DataArrayDouble (\a a) into specified tuples and 
2136  * components of \a this array. Textual data is not copied.
2137  * The tuples and components to assign to are defined by C arrays of indices.
2138  * There are two *modes of usage*:
2139  * - If \a a->getNbOfElems() equals to number of values to assign to, then every value
2140  *   of \a a is assigned to its own location within \a this array. 
2141  * - If \a a includes one tuple, then all values of \a a are assigned to the specified
2142  *   components of every specified tuple of \a this array. In this mode it is required
2143  *   that \a a->getNumberOfComponents() equals to the number of specified components.
2144  *
2145  *  \param [in] a - the array to copy values from.
2146  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
2147  *              assign values of \a a to.
2148  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
2149  *              pointer to a tuple index <em>(pi)</em> varies as this: 
2150  *              \a bgTuples <= \a pi < \a endTuples.
2151  *  \param [in] bgComp - pointer to an array of component indices of \a this array to
2152  *              assign values of \a a to.
2153  *  \param [in] endComp - specifies the end of the array \a bgTuples, so that
2154  *              pointer to a component index <em>(pi)</em> varies as this: 
2155  *              \a bgComp <= \a pi < \a endComp.
2156  *  \param [in] strictCompoCompare - this parameter is checked only if the
2157  *               *mode of usage* is the first; if it is \a true (default), 
2158  *               then \a a->getNumberOfComponents() must be equal 
2159  *               to the number of specified columns, else this is not required.
2160  *  \throw If \a a is NULL.
2161  *  \throw If \a a is not allocated.
2162  *  \throw If \a this is not allocated.
2163  *  \throw If any index of tuple/component given by <em>bgTuples / bgComp</em> is
2164  *         out of a valid range for \a this array.
2165  *  \throw In the first *mode of usage*, if <em>strictCompoCompare == true </em> and
2166  *         if <em> a->getNumberOfComponents() != (endComp - bgComp) </em>.
2167  *  \throw In the second *mode of usage*, if \a a->getNumberOfTuples() != 1 or
2168  *         <em> a->getNumberOfComponents() != (endComp - bgComp)</em>.
2169  *
2170  *  \ref py_mcdataarraydouble_setpartofvalues2 "Here is a Python example".
2171  */
2172 void DataArrayDouble::setPartOfValues2(const DataArrayDouble *a, const int *bgTuples, const int *endTuples, const int *bgComp, const int *endComp, bool strictCompoCompare) throw(INTERP_KERNEL::Exception)
2173 {
2174   if(!a)
2175     throw INTERP_KERNEL::Exception("DataArrayDouble::setPartOfValues2 : input DataArrayDouble is NULL !");
2176   const char msg[]="DataArrayDouble::setPartOfValues2";
2177   checkAllocated();
2178   a->checkAllocated();
2179   int nbComp=getNumberOfComponents();
2180   int nbOfTuples=getNumberOfTuples();
2181   for(const int *z=bgComp;z!=endComp;z++)
2182     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
2183   int newNbOfTuples=(int)std::distance(bgTuples,endTuples);
2184   int newNbOfComp=(int)std::distance(bgComp,endComp);
2185   bool assignTech=true;
2186   if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
2187     {
2188       if(strictCompoCompare)
2189         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
2190     }
2191   else
2192     {
2193       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
2194       assignTech=false;
2195     }
2196   double *pt=getPointer();
2197   const double *srcPt=a->getConstPointer();
2198   if(assignTech)
2199     {    
2200       for(const int *w=bgTuples;w!=endTuples;w++)
2201         {
2202           DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
2203           for(const int *z=bgComp;z!=endComp;z++,srcPt++)
2204             {    
2205               pt[(std::size_t)(*w)*nbComp+(*z)]=*srcPt;
2206             }
2207         }
2208     }
2209   else
2210     {
2211       for(const int *w=bgTuples;w!=endTuples;w++)
2212         {
2213           const double *srcPt2=srcPt;
2214           DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
2215           for(const int *z=bgComp;z!=endComp;z++,srcPt2++)
2216             {    
2217               pt[(std::size_t)(*w)*nbComp+(*z)]=*srcPt2;
2218             }
2219         }
2220     }
2221 }
2222
2223 /*!
2224  * Assign a given value to values at specified tuples and components of \a this array.
2225  * The tuples and components to assign to are defined by C arrays of indices.
2226  *  \param [in] a - the value to assign.
2227  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
2228  *              assign \a a to.
2229  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
2230  *              pointer to a tuple index (\a pi) varies as this: 
2231  *              \a bgTuples <= \a pi < \a endTuples.
2232  *  \param [in] bgComp - pointer to an array of component indices of \a this array to
2233  *              assign \a a to.
2234  *  \param [in] endComp - specifies the end of the array \a bgTuples, so that
2235  *              pointer to a component index (\a pi) varies as this: 
2236  *              \a bgComp <= \a pi < \a endComp.
2237  *  \throw If \a this is not allocated.
2238  *  \throw If any index of tuple/component given by <em>bgTuples / bgComp</em> is
2239  *         out of a valid range for \a this array.
2240  *
2241  *  \ref py_mcdataarraydouble_setpartofvaluessimple2 "Here is a Python example".
2242  */
2243 void DataArrayDouble::setPartOfValuesSimple2(double a, const int *bgTuples, const int *endTuples, const int *bgComp, const int *endComp) throw(INTERP_KERNEL::Exception)
2244 {
2245   checkAllocated();
2246   int nbComp=getNumberOfComponents();
2247   int nbOfTuples=getNumberOfTuples();
2248   for(const int *z=bgComp;z!=endComp;z++)
2249     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
2250   double *pt=getPointer();
2251   for(const int *w=bgTuples;w!=endTuples;w++)
2252     for(const int *z=bgComp;z!=endComp;z++)
2253       {
2254         DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
2255         pt[(std::size_t)(*w)*nbComp+(*z)]=a;
2256       }
2257 }
2258
2259 /*!
2260  * Copy all values from another DataArrayDouble (\a a) into specified tuples and 
2261  * components of \a this array. Textual data is not copied.
2262  * The tuples to assign to are defined by a C array of indices.
2263  * The components to assign to are defined by three values similar to parameters of
2264  * the Python function \c range(\c start,\c stop,\c step).
2265  * There are two *modes of usage*:
2266  * - If \a a->getNbOfElems() equals to number of values to assign to, then every value
2267  *   of \a a is assigned to its own location within \a this array. 
2268  * - If \a a includes one tuple, then all values of \a a are assigned to the specified
2269  *   components of every specified tuple of \a this array. In this mode it is required
2270  *   that \a a->getNumberOfComponents() equals to the number of specified components.
2271  *
2272  *  \param [in] a - the array to copy values from.
2273  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
2274  *              assign values of \a a to.
2275  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
2276  *              pointer to a tuple index <em>(pi)</em> varies as this: 
2277  *              \a bgTuples <= \a pi < \a endTuples.
2278  *  \param [in] bgComp - index of the first component of \a this array to assign to.
2279  *  \param [in] endComp - index of the component before which the components to assign
2280  *              to are located.
2281  *  \param [in] stepComp - index increment to get index of the next component to assign to.
2282  *  \param [in] strictCompoCompare - this parameter is checked only in the first
2283  *               *mode of usage*; if \a strictCompoCompare is \a true (default), 
2284  *               then \a a->getNumberOfComponents() must be equal 
2285  *               to the number of specified columns, else this is not required.
2286  *  \throw If \a a is NULL.
2287  *  \throw If \a a is not allocated.
2288  *  \throw If \a this is not allocated.
2289  *  \throw If any index of tuple given by \a bgTuples is out of a valid range for 
2290  *         \a this array.
2291  *  \throw In the first *mode of usage*, if <em>strictCompoCompare == true </em> and
2292  *         if <em> a->getNumberOfComponents()</em> is unequal to the number of components
2293  *         defined by <em>(bgComp,endComp,stepComp)</em>.
2294  *  \throw In the second *mode of usage*, if \a a->getNumberOfTuples() != 1 or
2295  *         <em> a->getNumberOfComponents()</em> is unequal to the number of components
2296  *         defined by <em>(bgComp,endComp,stepComp)</em>.
2297  *  \throw If parameters specifying components to assign to, do not give a
2298  *            non-empty range of increasing indices or indices are out of a valid range
2299  *            for \this array.
2300  *
2301  *  \ref py_mcdataarraydouble_setpartofvalues3 "Here is a Python example".
2302  */
2303 void DataArrayDouble::setPartOfValues3(const DataArrayDouble *a, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare) throw(INTERP_KERNEL::Exception)
2304 {
2305   if(!a)
2306     throw INTERP_KERNEL::Exception("DataArrayDouble::setPartOfValues3 : input DataArrayDouble is NULL !");
2307   const char msg[]="DataArrayDouble::setPartOfValues3";
2308   checkAllocated();
2309   a->checkAllocated();
2310   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
2311   int nbComp=getNumberOfComponents();
2312   int nbOfTuples=getNumberOfTuples();
2313   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
2314   int newNbOfTuples=(int)std::distance(bgTuples,endTuples);
2315   bool assignTech=true;
2316   if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
2317     {
2318       if(strictCompoCompare)
2319         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
2320     }
2321   else
2322     {
2323       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
2324       assignTech=false;
2325     }
2326   double *pt=getPointer()+bgComp;
2327   const double *srcPt=a->getConstPointer();
2328   if(assignTech)
2329     {
2330       for(const int *w=bgTuples;w!=endTuples;w++)
2331         for(int j=0;j<newNbOfComp;j++,srcPt++)
2332           {
2333             DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
2334             pt[(std::size_t)(*w)*nbComp+j*stepComp]=*srcPt;
2335           }
2336     }
2337   else
2338     {
2339       for(const int *w=bgTuples;w!=endTuples;w++)
2340         {
2341           const double *srcPt2=srcPt;
2342           for(int j=0;j<newNbOfComp;j++,srcPt2++)
2343             {
2344               DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
2345               pt[(std::size_t)(*w)*nbComp+j*stepComp]=*srcPt2;
2346             }
2347         }
2348     }
2349 }
2350
2351 /*!
2352  * Assign a given value to values at specified tuples and components of \a this array.
2353  * The tuples to assign to are defined by a C array of indices.
2354  * The components to assign to are defined by three values similar to parameters of
2355  * the Python function \c range(\c start,\c stop,\c step).
2356  *  \param [in] a - the value to assign.
2357  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
2358  *              assign \a a to.
2359  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
2360  *              pointer to a tuple index <em>(pi)</em> varies as this: 
2361  *              \a bgTuples <= \a pi < \a endTuples.
2362  *  \param [in] bgComp - index of the first component of \a this array to assign to.
2363  *  \param [in] endComp - index of the component before which the components to assign
2364  *              to are located.
2365  *  \param [in] stepComp - index increment to get index of the next component to assign to.
2366  *  \throw If \a this is not allocated.
2367  *  \throw If any index of tuple given by \a bgTuples is out of a valid range for 
2368  *         \a this array.
2369  *  \throw If parameters specifying components to assign to, do not give a
2370  *            non-empty range of increasing indices or indices are out of a valid range
2371  *            for \this array.
2372  *
2373  *  \ref py_mcdataarraydouble_setpartofvaluessimple3 "Here is a Python example".
2374  */
2375 void DataArrayDouble::setPartOfValuesSimple3(double a, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp) throw(INTERP_KERNEL::Exception)
2376 {
2377   const char msg[]="DataArrayDouble::setPartOfValuesSimple3";
2378   checkAllocated();
2379   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
2380   int nbComp=getNumberOfComponents();
2381   int nbOfTuples=getNumberOfTuples();
2382   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
2383   double *pt=getPointer()+bgComp;
2384   for(const int *w=bgTuples;w!=endTuples;w++)
2385     for(int j=0;j<newNbOfComp;j++)
2386       {
2387         DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
2388         pt[(std::size_t)(*w)*nbComp+j*stepComp]=a;
2389       }
2390 }
2391
2392 /*!
2393  * Copy all values from another DataArrayDouble into specified tuples and components
2394  * of \a this array. Textual data is not copied.
2395  * The tree parameters defining set of indices of tuples and components are similar to
2396  * the tree parameters of the Python function \c range(\c start,\c stop,\c step).
2397  *  \param [in] a - the array to copy values from.
2398  *  \param [in] bgTuples - index of the first tuple of \a this array to assign values to.
2399  *  \param [in] endTuples - index of the tuple before which the tuples to assign to
2400  *              are located.
2401  *  \param [in] stepTuples - index increment to get index of the next tuple to assign to.
2402  *  \param [in] bgComp - pointer to an array of component indices of \a this array to
2403  *              assign \a a to.
2404  *  \param [in] endComp - specifies the end of the array \a bgTuples, so that
2405  *              pointer to a component index (\a pi) varies as this: 
2406  *              \a bgComp <= \a pi < \a endComp.
2407  *  \param [in] strictCompoCompare - if \a true (by default), then \a a->getNumberOfComponents() 
2408  *              must be equal to the number of columns to assign to, else an
2409  *              exception is thrown; if \a false, then it is only required that \a
2410  *              a->getNbOfElems() equals to number of values to assign to (this condition
2411  *              must be respected even if \a strictCompoCompare is \a true). The number of 
2412  *              values to assign to is given by following Python expression:
2413  *              \a nbTargetValues = 
2414  *              \c len(\c range(\a bgTuples,\a endTuples,\a stepTuples)) *
2415  *              \c len(\c range(\a bgComp,\a endComp,\a stepComp)).
2416  *  \throw If \a a is NULL.
2417  *  \throw If \a a is not allocated.
2418  *  \throw If \a this is not allocated.
2419  *  \throw If parameters specifying tuples and components to assign to do not give a
2420  *            non-empty range of increasing indices.
2421  *  \throw If \a a->getNbOfElems() != \a nbTargetValues.
2422  *  \throw If \a strictCompoCompare == \a true && \a a->getNumberOfComponents() !=
2423  *            \c len(\c range(\a bgComp,\a endComp,\a stepComp)).
2424  *
2425  */
2426 void DataArrayDouble::setPartOfValues4(const DataArrayDouble *a, int bgTuples, int endTuples, int stepTuples, const int *bgComp, const int *endComp, bool strictCompoCompare) throw(INTERP_KERNEL::Exception)
2427 {
2428   if(!a)
2429     throw INTERP_KERNEL::Exception("DataArrayDouble::setPartOfValues4 : input DataArrayDouble is NULL !");
2430   const char msg[]="DataArrayDouble::setPartOfValues4";
2431   checkAllocated();
2432   a->checkAllocated();
2433   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
2434   int newNbOfComp=(int)std::distance(bgComp,endComp);
2435   int nbComp=getNumberOfComponents();
2436   for(const int *z=bgComp;z!=endComp;z++)
2437     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
2438   int nbOfTuples=getNumberOfTuples();
2439   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
2440   bool assignTech=true;
2441   if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
2442     {
2443       if(strictCompoCompare)
2444         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
2445     }
2446   else
2447     {
2448       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
2449       assignTech=false;
2450     }
2451   const double *srcPt=a->getConstPointer();
2452   double *pt=getPointer()+bgTuples*nbComp;
2453   if(assignTech)
2454     {
2455       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
2456         for(const int *z=bgComp;z!=endComp;z++,srcPt++)
2457           pt[*z]=*srcPt;
2458     }
2459   else
2460     {
2461       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
2462         {
2463           const double *srcPt2=srcPt;
2464           for(const int *z=bgComp;z!=endComp;z++,srcPt2++)
2465             pt[*z]=*srcPt2;
2466         }
2467     }
2468 }
2469
2470 void DataArrayDouble::setPartOfValuesSimple4(double a, int bgTuples, int endTuples, int stepTuples, const int *bgComp, const int *endComp) throw(INTERP_KERNEL::Exception)
2471 {
2472   const char msg[]="DataArrayDouble::setPartOfValuesSimple4";
2473   checkAllocated();
2474   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
2475   int nbComp=getNumberOfComponents();
2476   for(const int *z=bgComp;z!=endComp;z++)
2477     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
2478   int nbOfTuples=getNumberOfTuples();
2479   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
2480   double *pt=getPointer()+bgTuples*nbComp;
2481   for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
2482     for(const int *z=bgComp;z!=endComp;z++)
2483       pt[*z]=a;
2484 }
2485
2486 /*!
2487  * Copy some tuples from another DataArrayDouble into specified tuples
2488  * of \a this array. Textual data is not copied. Both arrays must have equal number of
2489  * components.
2490  * Both the tuples to assign and the tuples to assign to are defined by a DataArrayInt.
2491  * All components of selected tuples are copied.
2492  *  \param [in] a - the array to copy values from.
2493  *  \param [in] tuplesSelec - the array specifying both source tuples of \a a and
2494  *              target tuples of \a this. \a tuplesSelec has two components, and the
2495  *              first component specifies index of the source tuple and the second
2496  *              one specifies index of the target tuple.
2497  *  \throw If \a this is not allocated.
2498  *  \throw If \a a is NULL.
2499  *  \throw If \a a is not allocated.
2500  *  \throw If \a tuplesSelec is NULL.
2501  *  \throw If \a tuplesSelec is not allocated.
2502  *  \throw If <em>this->getNumberOfComponents() != a->getNumberOfComponents()</em>.
2503  *  \throw If \a tuplesSelec->getNumberOfComponents() != 2.
2504  *  \throw If any tuple index given by \a tuplesSelec is out of a valid range for 
2505  *         the corresponding (\a this or \a a) array.
2506  */
2507 void DataArrayDouble::setPartOfValuesAdv(const DataArrayDouble *a, const DataArrayInt *tuplesSelec) throw(INTERP_KERNEL::Exception)
2508 {
2509   if(!a || !tuplesSelec)
2510     throw INTERP_KERNEL::Exception("DataArrayDouble::setPartOfValuesAdv : input DataArrayDouble is NULL !");
2511   checkAllocated();
2512   a->checkAllocated();
2513   tuplesSelec->checkAllocated();
2514   int nbOfComp=getNumberOfComponents();
2515   if(nbOfComp!=a->getNumberOfComponents())
2516     throw INTERP_KERNEL::Exception("DataArrayDouble::setPartOfValuesAdv : This and a do not have the same number of components !");
2517   if(tuplesSelec->getNumberOfComponents()!=2)
2518     throw INTERP_KERNEL::Exception("DataArrayDouble::setPartOfValuesAdv : Expecting to have a tuple selector DataArrayInt instance with exactly 2 components !");
2519   int thisNt=getNumberOfTuples();
2520   int aNt=a->getNumberOfTuples();
2521   double *valsToSet=getPointer();
2522   const double *valsSrc=a->getConstPointer();
2523   for(const int *tuple=tuplesSelec->begin();tuple!=tuplesSelec->end();tuple+=2)
2524     {
2525       if(tuple[1]>=0 && tuple[1]<aNt)
2526         {
2527           if(tuple[0]>=0 && tuple[0]<thisNt)
2528             std::copy(valsSrc+nbOfComp*tuple[1],valsSrc+nbOfComp*(tuple[1]+1),valsToSet+nbOfComp*tuple[0]);
2529           else
2530             {
2531               std::ostringstream oss; oss << "DataArrayDouble::setPartOfValuesAdv : Tuple #" << std::distance(tuplesSelec->begin(),tuple)/2;
2532               oss << " of 'tuplesSelec' request of tuple id #" << tuple[0] << " in 'this' ! It should be in [0," << thisNt << ") !";
2533               throw INTERP_KERNEL::Exception(oss.str().c_str());
2534             }
2535         }
2536       else
2537         {
2538           std::ostringstream oss; oss << "DataArrayDouble::setPartOfValuesAdv : Tuple #" << std::distance(tuplesSelec->begin(),tuple)/2;
2539           oss << " of 'tuplesSelec' request of tuple id #" << tuple[1] << " in 'a' ! It should be in [0," << aNt << ") !";
2540           throw INTERP_KERNEL::Exception(oss.str().c_str());
2541         }
2542     }
2543 }
2544
2545 /*!
2546  * Copy some tuples from another DataArrayDouble (\a a) into contiguous tuples
2547  * of \a this array. Textual data is not copied. Both arrays must have equal number of
2548  * components.
2549  * The tuples to assign to are defined by index of the first tuple, and
2550  * their number is defined by \a tuplesSelec->getNumberOfTuples().
2551  * The tuples to copy are defined by values of a DataArrayInt.
2552  * All components of selected tuples are copied.
2553  *  \param [in] tupleIdStart - index of the first tuple of \a this array to assign
2554  *              values to.
2555  *  \param [in] a - the array to copy values from.
2556  *  \param [in] tuplesSelec - the array specifying tuples of \a a to copy.
2557  *  \throw If \a this is not allocated.
2558  *  \throw If \a a is NULL.
2559  *  \throw If \a a is not allocated.
2560  *  \throw If \a tuplesSelec is NULL.
2561  *  \throw If \a tuplesSelec is not allocated.
2562  *  \throw If <em>this->getNumberOfComponents() != a->getNumberOfComponents()</em>.
2563  *  \throw If \a tuplesSelec->getNumberOfComponents() != 1.
2564  *  \throw If <em>tupleIdStart + tuplesSelec->getNumberOfTuples() > this->getNumberOfTuples().</em>
2565  *  \throw If any tuple index given by \a tuplesSelec is out of a valid range for 
2566  *         \a a array.
2567  */
2568 void DataArrayDouble::setContigPartOfSelectedValues(int tupleIdStart, const DataArray *aBase, const DataArrayInt *tuplesSelec) throw(INTERP_KERNEL::Exception)
2569 {
2570   if(!aBase || !tuplesSelec)
2571     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues : input DataArray is NULL !");
2572   const DataArrayDouble *a=dynamic_cast<const DataArrayDouble *>(aBase);
2573   if(!a)
2574     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues : input DataArray aBase is not a DataArrayDouble !");
2575   checkAllocated();
2576   a->checkAllocated();
2577   tuplesSelec->checkAllocated();
2578   int nbOfComp=getNumberOfComponents();
2579   if(nbOfComp!=a->getNumberOfComponents())
2580     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues : This and a do not have the same number of components !");
2581   if(tuplesSelec->getNumberOfComponents()!=1)
2582     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues : Expecting to have a tuple selector DataArrayInt instance with exactly 1 component !");
2583   int thisNt=getNumberOfTuples();
2584   int aNt=a->getNumberOfTuples();
2585   int nbOfTupleToWrite=tuplesSelec->getNumberOfTuples();
2586   double *valsToSet=getPointer()+tupleIdStart*nbOfComp;
2587   if(tupleIdStart+nbOfTupleToWrite>thisNt)
2588     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues : invalid number range of values to write !");
2589   const double *valsSrc=a->getConstPointer();
2590   for(const int *tuple=tuplesSelec->begin();tuple!=tuplesSelec->end();tuple++,valsToSet+=nbOfComp)
2591     {
2592       if(*tuple>=0 && *tuple<aNt)
2593         {
2594           std::copy(valsSrc+nbOfComp*(*tuple),valsSrc+nbOfComp*(*tuple+1),valsToSet);
2595         }
2596       else
2597         {
2598           std::ostringstream oss; oss << "DataArrayDouble::setContigPartOfSelectedValues : Tuple #" << std::distance(tuplesSelec->begin(),tuple);
2599           oss << " of 'tuplesSelec' request of tuple id #" << *tuple << " in 'a' ! It should be in [0," << aNt << ") !";
2600           throw INTERP_KERNEL::Exception(oss.str().c_str());
2601         }
2602     }
2603 }
2604
2605 /*!
2606  * Copy some tuples from another DataArrayDouble (\a a) into contiguous tuples
2607  * of \a this array. Textual data is not copied. Both arrays must have equal number of
2608  * components.
2609  * The tuples to copy are defined by three values similar to parameters of
2610  * the Python function \c range(\c start,\c stop,\c step).
2611  * The tuples to assign to are defined by index of the first tuple, and
2612  * their number is defined by number of tuples to copy.
2613  * All components of selected tuples are copied.
2614  *  \param [in] tupleIdStart - index of the first tuple of \a this array to assign
2615  *              values to.
2616  *  \param [in] a - the array to copy values from.
2617  *  \param [in] bg - index of the first tuple to copy of the array \a a.
2618  *  \param [in] end2 - index of the tuple of \a a before which the tuples to copy
2619  *              are located.
2620  *  \param [in] step - index increment to get index of the next tuple to copy.
2621  *  \throw If \a this is not allocated.
2622  *  \throw If \a a is NULL.
2623  *  \throw If \a a is not allocated.
2624  *  \throw If <em>this->getNumberOfComponents() != a->getNumberOfComponents()</em>.
2625  *  \throw If <em>tupleIdStart + len(range(bg,end2,step)) > this->getNumberOfTuples().</em>
2626  *  \throw If parameters specifying tuples to copy, do not give a
2627  *            non-empty range of increasing indices or indices are out of a valid range
2628  *            for the array \a a.
2629  */
2630 void DataArrayDouble::setContigPartOfSelectedValues2(int tupleIdStart, const DataArray *aBase, int bg, int end2, int step) throw(INTERP_KERNEL::Exception)
2631 {
2632   if(!aBase)
2633     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues2 : input DataArray is NULL !");
2634   const DataArrayDouble *a=dynamic_cast<const DataArrayDouble *>(aBase);
2635   if(!a)
2636     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues2 : input DataArray aBase is not a DataArrayDouble !");
2637   checkAllocated();
2638   a->checkAllocated();
2639   int nbOfComp=getNumberOfComponents();
2640   const char msg[]="DataArrayDouble::setContigPartOfSelectedValues2";
2641   int nbOfTupleToWrite=DataArray::GetNumberOfItemGivenBES(bg,end2,step,msg);
2642   if(nbOfComp!=a->getNumberOfComponents())
2643     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues2 : This and a do not have the same number of components !");
2644   int thisNt=getNumberOfTuples();
2645   int aNt=a->getNumberOfTuples();
2646   double *valsToSet=getPointer()+tupleIdStart*nbOfComp;
2647   if(tupleIdStart+nbOfTupleToWrite>thisNt)
2648     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues2 : invalid number range of values to write !");
2649   if(end2>aNt)
2650     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues2 : invalid range of values to read !");
2651   const double *valsSrc=a->getConstPointer()+bg*nbOfComp;
2652   for(int i=0;i<nbOfTupleToWrite;i++,valsToSet+=nbOfComp,valsSrc+=step*nbOfComp)
2653     {
2654       std::copy(valsSrc,valsSrc+nbOfComp,valsToSet);
2655     }
2656 }
2657
2658 /*!
2659  * Returns a value located at specified tuple and component.
2660  * This method is equivalent to DataArrayDouble::getIJ() except that validity of
2661  * parameters is checked. So this method is safe but expensive if used to go through
2662  * all values of \a this.
2663  *  \param [in] tupleId - index of tuple of interest.
2664  *  \param [in] compoId - index of component of interest.
2665  *  \return double - value located by \a tupleId and \a compoId.
2666  *  \throw If \a this is not allocated.
2667  *  \throw If condition <em>( 0 <= tupleId < this->getNumberOfTuples() )</em> is violated.
2668  *  \throw If condition <em>( 0 <= compoId < this->getNumberOfComponents() )</em> is violated.
2669  */
2670 double DataArrayDouble::getIJSafe(int tupleId, int compoId) const throw(INTERP_KERNEL::Exception)
2671 {
2672   checkAllocated();
2673   if(tupleId<0 || tupleId>=getNumberOfTuples())
2674     {
2675       std::ostringstream oss; oss << "DataArrayDouble::getIJSafe : request for tupleId " << tupleId << " should be in [0," << getNumberOfTuples() << ") !";
2676       throw INTERP_KERNEL::Exception(oss.str().c_str());
2677     }
2678   if(compoId<0 || compoId>=getNumberOfComponents())
2679     {
2680       std::ostringstream oss; oss << "DataArrayDouble::getIJSafe : request for compoId " << compoId << " should be in [0," << getNumberOfComponents() << ") !";
2681       throw INTERP_KERNEL::Exception(oss.str().c_str());
2682     }
2683   return _mem[tupleId*_info_on_compo.size()+compoId];
2684 }
2685
2686 /*!
2687  * Returns the last value of \a this. 
2688  *  \return double - the last value of \a this array.
2689  *  \throw If \a this is not allocated.
2690  *  \throw If \a this->getNumberOfComponents() != 1.
2691  *  \throw If \a this->getNumberOfTuples() < 1.
2692  */
2693 double DataArrayDouble::back() const throw(INTERP_KERNEL::Exception)
2694 {
2695   checkAllocated();
2696   if(getNumberOfComponents()!=1)
2697     throw INTERP_KERNEL::Exception("DataArrayDouble::back : number of components not equal to one !");
2698   int nbOfTuples=getNumberOfTuples();
2699   if(nbOfTuples<1)
2700     throw INTERP_KERNEL::Exception("DataArrayDouble::back : number of tuples must be >= 1 !");
2701   return *(getConstPointer()+nbOfTuples-1);
2702 }
2703
2704 void DataArrayDouble::SetArrayIn(DataArrayDouble *newArray, DataArrayDouble* &arrayToSet)
2705 {
2706   if(newArray!=arrayToSet)
2707     {
2708       if(arrayToSet)
2709         arrayToSet->decrRef();
2710       arrayToSet=newArray;
2711       if(arrayToSet)
2712         arrayToSet->incrRef();
2713     }
2714 }
2715
2716 /*!
2717  * Sets a C array to be used as raw data of \a this. The previously set info
2718  *  of components is retained and re-sized. 
2719  * For more info see \ref MEDCouplingArraySteps1.
2720  *  \param [in] array - the C array to be used as raw data of \a this.
2721  *  \param [in] ownership - if \a true, \a array will be deallocated at destruction of \a this.
2722  *  \param [in] type - specifies how to deallocate \a array. If \a type == ParaMEDMEM::CPP_DEALLOC,
2723  *                     \c delete [] \c array; will be called. If \a type == ParaMEDMEM::C_DEALLOC,
2724  *                     \c free(\c array ) will be called.
2725  *  \param [in] nbOfTuple - new number of tuples in \a this.
2726  *  \param [in] nbOfCompo - new number of components in \a this.
2727  */
2728 void DataArrayDouble::useArray(const double *array, bool ownership, DeallocType type, int nbOfTuple, int nbOfCompo) throw(INTERP_KERNEL::Exception)
2729 {
2730   _info_on_compo.resize(nbOfCompo);
2731   _mem.useArray(array,ownership,type,(std::size_t)nbOfTuple*nbOfCompo);
2732   declareAsNew();
2733 }
2734
2735 void DataArrayDouble::useExternalArrayWithRWAccess(const double *array, int nbOfTuple, int nbOfCompo) throw(INTERP_KERNEL::Exception)
2736 {
2737   _info_on_compo.resize(nbOfCompo);
2738   _mem.useExternalArrayWithRWAccess(array,(std::size_t)nbOfTuple*nbOfCompo);
2739   declareAsNew();
2740 }
2741
2742 /*!
2743  * Checks if 0.0 value is present in \a this array. If it is the case, an exception
2744  * is thrown.
2745  * \throw If zero is found in \a this array.
2746  */
2747 void DataArrayDouble::checkNoNullValues() const throw(INTERP_KERNEL::Exception)
2748 {
2749   const double *tmp=getConstPointer();
2750   std::size_t nbOfElems=getNbOfElems();
2751   const double *where=std::find(tmp,tmp+nbOfElems,0.);
2752   if(where!=tmp+nbOfElems)
2753     throw INTERP_KERNEL::Exception("A value 0.0 have been detected !");
2754 }
2755
2756 /*!
2757  * Computes minimal and maximal value in each component. An output array is filled
2758  * with \c 2 * \a this->getNumberOfComponents() values, so the caller is to allocate
2759  * enough memory before calling this method.
2760  *  \param [out] bounds - array of size at least 2 *\a this->getNumberOfComponents().
2761  *               It is filled as follows:<br>
2762  *               \a bounds[0] = \c min_of_component_0 <br>
2763  *               \a bounds[1] = \c max_of_component_0 <br>
2764  *               \a bounds[2] = \c min_of_component_1 <br>
2765  *               \a bounds[3] = \c max_of_component_1 <br>
2766  *               ...
2767  */
2768 void DataArrayDouble::getMinMaxPerComponent(double *bounds) const throw(INTERP_KERNEL::Exception)
2769 {
2770   checkAllocated();
2771   int dim=getNumberOfComponents();
2772   for (int idim=0; idim<dim; idim++)
2773     {
2774       bounds[idim*2]=std::numeric_limits<double>::max();
2775       bounds[idim*2+1]=-std::numeric_limits<double>::max();
2776     } 
2777   const double *ptr=getConstPointer();
2778   int nbOfTuples=getNumberOfTuples();
2779   for(int i=0;i<nbOfTuples;i++)
2780     {
2781       for(int idim=0;idim<dim;idim++)
2782         {
2783           if(bounds[idim*2]>ptr[i*dim+idim])
2784             {
2785               bounds[idim*2]=ptr[i*dim+idim];
2786             }
2787           if(bounds[idim*2+1]<ptr[i*dim+idim])
2788             {
2789               bounds[idim*2+1]=ptr[i*dim+idim];
2790             }
2791         }
2792     }
2793 }
2794
2795 /*!
2796  * This method retrieves a newly allocated DataArrayDouble instance having same number of tuples than \a this and twice number of components than \a this
2797  * to store both the min and max per component of each tuples. 
2798  * \param [in] epsilon the width of the bbox (identical in each direction) - 0.0 by default
2799  *
2800  * \return a newly created DataArrayDouble instance having \c this->getNumberOfTuples() tuples and 2 * \c this->getNumberOfComponent() components
2801  *
2802  * \throw If \a this is not allocated yet.
2803  */
2804 DataArrayDouble *DataArrayDouble::computeBBoxPerTuple(double epsilon)const throw(INTERP_KERNEL::Exception)
2805 {
2806   checkAllocated();
2807   const double *dataPtr=getConstPointer();
2808   int nbOfCompo=getNumberOfComponents();
2809   int nbTuples=getNumberOfTuples();
2810   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> bbox=DataArrayDouble::New();
2811   bbox->alloc(nbTuples,2*nbOfCompo);
2812   double *bboxPtr=bbox->getPointer();
2813   for(int i=0;i<nbTuples;i++)
2814     {
2815       for(int j=0;j<nbOfCompo;j++)
2816         {
2817           bboxPtr[2*nbOfCompo*i+2*j]=dataPtr[nbOfCompo*i+j]-epsilon;
2818           bboxPtr[2*nbOfCompo*i+2*j+1]=dataPtr[nbOfCompo*i+j]+epsilon;
2819         }
2820     }
2821   return bbox.retn();
2822 }
2823
2824 /*!
2825  * For each tuples **t** in \a other, this method retrieves tuples in \a this that are equal to **t**.
2826  * Two tuples are considered equal if the euclidian distance between the two tuples is lower than \a eps.
2827  * 
2828  * \param [in] other a DataArrayDouble having same number of components than \a this.
2829  * \param [in] eps absolute precision representing distance (using infinite norm) between 2 tuples behind which 2 tuples are considered equal.
2830  * \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.
2831  *             \a cI allows to extract information in \a c.
2832  * \param [out] cI is an indirection array that allows to extract the data contained in \a c.
2833  *
2834  * \throw In case of:
2835  *  - \a this is not allocated
2836  *  - \a other is not allocated or null
2837  *  - \a this and \a other do not have the same number of components
2838  *  - if number of components of \a this is not in [1,2,3]
2839  *
2840  * \sa MEDCouplingPointSet::getNodeIdsNearPoints, DataArrayDouble::getDifferentValues
2841  */
2842 void DataArrayDouble::computeTupleIdsNearTuples(const DataArrayDouble *other, double eps, DataArrayInt *& c, DataArrayInt *& cI) const throw(INTERP_KERNEL::Exception)
2843 {
2844   if(!other)
2845     throw INTERP_KERNEL::Exception("DataArrayDouble::computeTupleIdsNearTuples : input pointer other is null !");
2846   checkAllocated();
2847   other->checkAllocated();
2848   int nbOfCompo=getNumberOfComponents();
2849   int otherNbOfCompo=other->getNumberOfComponents();
2850   if(nbOfCompo!=otherNbOfCompo)
2851     throw INTERP_KERNEL::Exception("DataArrayDouble::computeTupleIdsNearTuples : number of components should be equal between this and other !");
2852   int nbOfTuplesOther=other->getNumberOfTuples();
2853   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cArr(DataArrayInt::New()),cIArr(DataArrayInt::New()); cArr->alloc(0,1); cIArr->pushBackSilent(0);
2854   switch(nbOfCompo)
2855     {
2856     case 3:
2857       {
2858         BBTreePts<3,int> myTree(begin(),0,0,getNumberOfTuples(),eps);
2859         FindTupleIdsNearTuplesAlg<3>(myTree,other->getConstPointer(),nbOfTuplesOther,eps,cArr,cIArr);
2860         break;
2861       }
2862     case 2:
2863       {
2864         BBTreePts<2,int> myTree(begin(),0,0,getNumberOfTuples(),eps);
2865         FindTupleIdsNearTuplesAlg<2>(myTree,other->getConstPointer(),nbOfTuplesOther,eps,cArr,cIArr);
2866         break;
2867       }
2868     case 1:
2869       {
2870         BBTreePts<1,int> myTree(begin(),0,0,getNumberOfTuples(),eps);
2871         FindTupleIdsNearTuplesAlg<1>(myTree,other->getConstPointer(),nbOfTuplesOther,eps,cArr,cIArr);
2872         break;
2873       }
2874     default:
2875       throw INTERP_KERNEL::Exception("Unexpected spacedim of coords for computeTupleIdsNearTuples. Must be 1, 2 or 3.");
2876     }
2877   c=cArr.retn(); cI=cIArr.retn();
2878 }
2879
2880 /*!
2881  * 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
2882  * around origin of 'radius' 1.
2883  * 
2884  * \param [in] eps absolute epsilon. under that value of delta between max and min no scale is performed.
2885  */
2886 void DataArrayDouble::recenterForMaxPrecision(double eps) throw(INTERP_KERNEL::Exception)
2887 {
2888   checkAllocated();
2889   int dim=getNumberOfComponents();
2890   std::vector<double> bounds(2*dim);
2891   getMinMaxPerComponent(&bounds[0]);
2892   for(int i=0;i<dim;i++)
2893     {
2894       double delta=bounds[2*i+1]-bounds[2*i];
2895       double offset=(bounds[2*i]+bounds[2*i+1])/2.;
2896       if(delta>eps)
2897         applyLin(1./delta,-offset/delta,i);
2898       else
2899         applyLin(1.,-offset,i);
2900     }
2901 }
2902
2903 /*!
2904  * Returns the maximal value and its location within \a this one-dimensional array.
2905  *  \param [out] tupleId - index of the tuple holding the maximal value.
2906  *  \return double - the maximal value among all values of \a this array.
2907  *  \throw If \a this->getNumberOfComponents() != 1
2908  *  \throw If \a this->getNumberOfTuples() < 1
2909  */
2910 double DataArrayDouble::getMaxValue(int& tupleId) const throw(INTERP_KERNEL::Exception)
2911 {
2912   checkAllocated();
2913   if(getNumberOfComponents()!=1)
2914     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 !");
2915   int nbOfTuples=getNumberOfTuples();
2916   if(nbOfTuples<=0)
2917     throw INTERP_KERNEL::Exception("DataArrayDouble::getMaxValue : array exists but number of tuples must be > 0 !");
2918   const double *vals=getConstPointer();
2919   const double *loc=std::max_element(vals,vals+nbOfTuples);
2920   tupleId=(int)std::distance(vals,loc);
2921   return *loc;
2922 }
2923
2924 /*!
2925  * Returns the maximal value within \a this array that is allowed to have more than
2926  *  one component.
2927  *  \return double - the maximal value among all values of \a this array.
2928  *  \throw If \a this is not allocated.
2929  */
2930 double DataArrayDouble::getMaxValueInArray() const throw(INTERP_KERNEL::Exception)
2931 {
2932   checkAllocated();
2933   const double *loc=std::max_element(begin(),end());
2934   return *loc;
2935 }
2936
2937 /*!
2938  * Returns the maximal value and all its locations within \a this one-dimensional array.
2939  *  \param [out] tupleIds - a new instance of DataArrayInt containg indices of
2940  *               tuples holding the maximal value. The caller is to delete it using
2941  *               decrRef() as it is no more needed.
2942  *  \return double - the maximal value among all values of \a this array.
2943  *  \throw If \a this->getNumberOfComponents() != 1
2944  *  \throw If \a this->getNumberOfTuples() < 1
2945  */
2946 double DataArrayDouble::getMaxValue2(DataArrayInt*& tupleIds) const throw(INTERP_KERNEL::Exception)
2947 {
2948   int tmp;
2949   tupleIds=0;
2950   double ret=getMaxValue(tmp);
2951   tupleIds=getIdsInRange(ret,ret);
2952   return ret;
2953 }
2954
2955 /*!
2956  * Returns the minimal value and its location within \a this one-dimensional array.
2957  *  \param [out] tupleId - index of the tuple holding the minimal value.
2958  *  \return double - the minimal value among all values of \a this array.
2959  *  \throw If \a this->getNumberOfComponents() != 1
2960  *  \throw If \a this->getNumberOfTuples() < 1
2961  */
2962 double DataArrayDouble::getMinValue(int& tupleId) const throw(INTERP_KERNEL::Exception)
2963 {
2964   checkAllocated();
2965   if(getNumberOfComponents()!=1)
2966     throw INTERP_KERNEL::Exception("DataArrayDouble::getMinValue : must be applied on DataArrayDouble with only one component, you can call 'rearrange' method before call 'getMinValueInArray' method !");
2967   int nbOfTuples=getNumberOfTuples();
2968   if(nbOfTuples<=0)
2969     throw INTERP_KERNEL::Exception("DataArrayDouble::getMinValue : array exists but number of tuples must be > 0 !");
2970   const double *vals=getConstPointer();
2971   const double *loc=std::min_element(vals,vals+nbOfTuples);
2972   tupleId=(int)std::distance(vals,loc);
2973   return *loc;
2974 }
2975
2976 /*!
2977  * Returns the minimal value within \a this array that is allowed to have more than
2978  *  one component.
2979  *  \return double - the minimal value among all values of \a this array.
2980  *  \throw If \a this is not allocated.
2981  */
2982 double DataArrayDouble::getMinValueInArray() const throw(INTERP_KERNEL::Exception)
2983 {
2984   checkAllocated();
2985   const double *loc=std::min_element(begin(),end());
2986   return *loc;
2987 }
2988
2989 /*!
2990  * Returns the minimal value and all its locations within \a this one-dimensional array.
2991  *  \param [out] tupleIds - a new instance of DataArrayInt containg indices of
2992  *               tuples holding the minimal value. The caller is to delete it using
2993  *               decrRef() as it is no more needed.
2994  *  \return double - the minimal value among all values of \a this array.
2995  *  \throw If \a this->getNumberOfComponents() != 1
2996  *  \throw If \a this->getNumberOfTuples() < 1
2997  */
2998 double DataArrayDouble::getMinValue2(DataArrayInt*& tupleIds) const throw(INTERP_KERNEL::Exception)
2999 {
3000   int tmp;
3001   tupleIds=0;
3002   double ret=getMinValue(tmp);
3003   tupleIds=getIdsInRange(ret,ret);
3004   return ret;
3005 }
3006
3007 /*!
3008  * 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.
3009  * This method only works for single component array.
3010  *
3011  * \return a value in [ 0, \c this->getNumberOfTuples() )
3012  *
3013  * \throw If \a this is not allocated
3014  *
3015  */
3016 int DataArrayDouble::count(double value, double eps) const throw(INTERP_KERNEL::Exception)
3017 {
3018   int ret=0;
3019   checkAllocated();
3020   if(getNumberOfComponents()!=1)
3021     throw INTERP_KERNEL::Exception("DataArrayDouble::count : must be applied on DataArrayDouble with only one component, you can call 'rearrange' method before !");
3022   const double *vals=begin();
3023   int nbOfTuples=getNumberOfTuples();
3024   for(int i=0;i<nbOfTuples;i++,vals++)
3025     if(fabs(*vals-value)<=eps)
3026       ret++;
3027   return ret;
3028 }
3029
3030 /*!
3031  * Returns the average value of \a this one-dimensional array.
3032  *  \return double - the average value over all values of \a this array.
3033  *  \throw If \a this->getNumberOfComponents() != 1
3034  *  \throw If \a this->getNumberOfTuples() < 1
3035  */
3036 double DataArrayDouble::getAverageValue() const throw(INTERP_KERNEL::Exception)
3037 {
3038   if(getNumberOfComponents()!=1)
3039     throw INTERP_KERNEL::Exception("DataArrayDouble::getAverageValue : must be applied on DataArrayDouble with only one component, you can call 'rearrange' method before !");
3040   int nbOfTuples=getNumberOfTuples();
3041   if(nbOfTuples<=0)
3042     throw INTERP_KERNEL::Exception("DataArrayDouble::getAverageValue : array exists but number of tuples must be > 0 !");
3043   const double *vals=getConstPointer();
3044   double ret=std::accumulate(vals,vals+nbOfTuples,0.);
3045   return ret/nbOfTuples;
3046 }
3047
3048 /*!
3049  * Returns the Euclidean norm of the vector defined by \a this array.
3050  *  \return double - the value of the Euclidean norm, i.e.
3051  *          the square root of the inner product of vector.
3052  *  \throw If \a this is not allocated.
3053  */
3054 double DataArrayDouble::norm2() const throw(INTERP_KERNEL::Exception)
3055 {
3056   checkAllocated();
3057   double ret=0.;
3058   std::size_t nbOfElems=getNbOfElems();
3059   const double *pt=getConstPointer();
3060   for(std::size_t i=0;i<nbOfElems;i++,pt++)
3061     ret+=(*pt)*(*pt);
3062   return sqrt(ret);
3063 }
3064
3065 /*!
3066  * Returns the maximum norm of the vector defined by \a this array.
3067  *  \return double - the value of the maximum norm, i.e.
3068  *          the maximal absolute value among values of \a this array.
3069  *  \throw If \a this is not allocated.
3070  */
3071 double DataArrayDouble::normMax() const throw(INTERP_KERNEL::Exception)
3072 {
3073   checkAllocated();
3074   double ret=-1.;
3075   std::size_t nbOfElems=getNbOfElems();
3076   const double *pt=getConstPointer();
3077   for(std::size_t i=0;i<nbOfElems;i++,pt++)
3078     {
3079       double val=std::abs(*pt);
3080       if(val>ret)
3081         ret=val;
3082     }
3083   return ret;
3084 }
3085
3086 /*!
3087  * Accumulates values of each component of \a this array.
3088  *  \param [out] res - an array of length \a this->getNumberOfComponents(), allocated 
3089  *         by the caller, that is filled by this method with sum value for each
3090  *         component.
3091  *  \throw If \a this is not allocated.
3092  */
3093 void DataArrayDouble::accumulate(double *res) const throw(INTERP_KERNEL::Exception)
3094 {
3095   checkAllocated();
3096   const double *ptr=getConstPointer();
3097   int nbTuple=getNumberOfTuples();
3098   int nbComps=getNumberOfComponents();
3099   std::fill(res,res+nbComps,0.);
3100   for(int i=0;i<nbTuple;i++)
3101     std::transform(ptr+i*nbComps,ptr+(i+1)*nbComps,res,res,std::plus<double>());
3102 }
3103
3104 /*!
3105  * This method returns the min distance from an external tuple defined by [ \a tupleBg , \a tupleEnd ) to \a this and
3106  * the first tuple in \a this that matches the returned distance. If there is no tuples in \a this an exception will be thrown.
3107  *
3108  *
3109  * \a this is expected to be allocated and expected to have a number of components equal to the distance from \a tupleBg to
3110  * \a tupleEnd. If not an exception will be thrown.
3111  *
3112  * \param [in] tupleBg start pointer (included) of input external tuple
3113  * \param [in] tupleEnd end pointer (not included) of input external tuple
3114  * \param [out] tupleId the tuple id in \a this that matches the min of distance between \a this and input external tuple
3115  * \return the min distance.
3116  * \sa MEDCouplingUMesh::distanceToPoint
3117  */
3118 double DataArrayDouble::distanceToTuple(const double *tupleBg, const double *tupleEnd, int& tupleId) const throw(INTERP_KERNEL::Exception)
3119 {
3120   checkAllocated();
3121   int nbTuple=getNumberOfTuples();
3122   int nbComps=getNumberOfComponents();
3123   if(nbComps!=(int)std::distance(tupleBg,tupleEnd))
3124     { 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()); }
3125   if(nbTuple==0)
3126     throw INTERP_KERNEL::Exception("DataArrayDouble::distanceToTuple : no tuple in this ! No distance to compute !");
3127   double ret0=std::numeric_limits<double>::max();
3128   tupleId=-1;
3129   const double *work=getConstPointer();
3130   for(int i=0;i<nbTuple;i++)
3131     {
3132       double val=0.;
3133       for(int j=0;j<nbComps;j++,work++) 
3134         val+=(*work-tupleBg[j])*((*work-tupleBg[j]));
3135       if(val>=ret0)
3136         continue;
3137       else
3138         { ret0=val; tupleId=i; }
3139     }
3140   return sqrt(ret0);
3141 }
3142
3143 /*!
3144  * Accumulate values of the given component of \a this array.
3145  *  \param [in] compId - the index of the component of interest.
3146  *  \return double - a sum value of \a compId-th component.
3147  *  \throw If \a this is not allocated.
3148  *  \throw If \a the condition ( 0 <= \a compId < \a this->getNumberOfComponents() ) is
3149  *         not respected.
3150  */
3151 double DataArrayDouble::accumulate(int compId) const throw(INTERP_KERNEL::Exception)
3152 {
3153   checkAllocated();
3154   const double *ptr=getConstPointer();
3155   int nbTuple=getNumberOfTuples();
3156   int nbComps=getNumberOfComponents();
3157   if(compId<0 || compId>=nbComps)
3158     throw INTERP_KERNEL::Exception("DataArrayDouble::accumulate : Invalid compId specified : No such nb of components !");
3159   double ret=0.;
3160   for(int i=0;i<nbTuple;i++)
3161     ret+=ptr[i*nbComps+compId];
3162   return ret;
3163 }
3164
3165 /*!
3166  * This method accumulate using addition tuples in \a this using input index array [ \a bgOfIndex, \a endOfIndex ).
3167  * The returned array will have same number of components than \a this and number of tuples equal to
3168  * \c std::distance(bgOfIndex,endOfIndex) \b minus \b one.
3169  *
3170  * The input index array is expected to be ascendingly sorted in which the all referenced ids should be in [0, \c this->getNumberOfTuples).
3171  * 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.
3172  *
3173  * \param [in] bgOfIndex - begin (included) of the input index array.
3174  * \param [in] endOfIndex - end (excluded) of the input index array.
3175  * \return DataArrayDouble * - the new instance having the same number of components than \a this.
3176  * 
3177  * \throw If bgOfIndex or end is NULL.
3178  * \throw If input index array is not ascendingly sorted.
3179  * \throw If there is an id in [ \a bgOfIndex, \a endOfIndex ) not in [0, \c this->getNumberOfTuples).
3180  * \throw If std::distance(bgOfIndex,endOfIndex)==0.
3181  */
3182 DataArrayDouble *DataArrayDouble::accumulatePerChunck(const int *bgOfIndex, const int *endOfIndex) const throw(INTERP_KERNEL::Exception)
3183 {
3184   if(!bgOfIndex || !endOfIndex)
3185     throw INTERP_KERNEL::Exception("DataArrayDouble::accumulatePerChunck : input pointer NULL !");
3186   checkAllocated();
3187   int nbCompo=getNumberOfComponents();
3188   int nbOfTuples=getNumberOfTuples();
3189   int sz=(int)std::distance(bgOfIndex,endOfIndex);
3190   if(sz<1)
3191     throw INTERP_KERNEL::Exception("DataArrayDouble::accumulatePerChunck : invalid size of input index array !");
3192   sz--;
3193   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New(); ret->alloc(sz,nbCompo);
3194   const int *w=bgOfIndex;
3195   if(*w<0 || *w>=nbOfTuples)
3196     throw INTERP_KERNEL::Exception("DataArrayDouble::accumulatePerChunck : The first element of the input index not in [0,nbOfTuples) !");
3197   const double *srcPt=begin()+(*w)*nbCompo;
3198   double *tmp=ret->getPointer();
3199   for(int i=0;i<sz;i++,tmp+=nbCompo,w++)
3200     {
3201       std::fill(tmp,tmp+nbCompo,0.);
3202       if(w[1]>=w[0])
3203         {
3204           for(int j=w[0];j<w[1];j++,srcPt+=nbCompo)
3205             {
3206               if(j>=0 && j<nbOfTuples)
3207                 std::transform(srcPt,srcPt+nbCompo,tmp,tmp,std::plus<double>());
3208               else
3209                 {
3210                   std::ostringstream oss; oss << "DataArrayDouble::accumulatePerChunck : At rank #" << i << " the input index array points to id " << j << " should be in [0," << nbOfTuples << ") !";
3211                   throw INTERP_KERNEL::Exception(oss.str().c_str());
3212                 }
3213             }
3214         }
3215       else
3216         {
3217           std::ostringstream oss; oss << "DataArrayDouble::accumulatePerChunck : At rank #" << i << " the input index array is not in ascendingly sorted.";
3218           throw INTERP_KERNEL::Exception(oss.str().c_str());
3219         }
3220     }
3221   ret->copyStringInfoFrom(*this);
3222   return ret.retn();
3223 }
3224
3225 /*!
3226  * Converts each 2D point defined by the tuple of \a this array from the Polar to the
3227  * Cartesian coordinate system. The two components of the tuple of \a this array are 
3228  * considered to contain (1) radius and (2) angle of the point in the Polar CS.
3229  *  \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
3230  *          contains X and Y coordinates of the point in the Cartesian CS. The caller
3231  *          is to delete this array using decrRef() as it is no more needed. The array
3232  *          does not contain any textual info on components.
3233  *  \throw If \a this->getNumberOfComponents() != 2.
3234  */
3235 DataArrayDouble *DataArrayDouble::fromPolarToCart() const throw(INTERP_KERNEL::Exception)
3236 {
3237   checkAllocated();
3238   int nbOfComp=getNumberOfComponents();
3239   if(nbOfComp!=2)
3240     throw INTERP_KERNEL::Exception("DataArrayDouble::fromPolarToCart : must be an array with exactly 2 components !");
3241   int nbOfTuple=getNumberOfTuples();
3242   DataArrayDouble *ret=DataArrayDouble::New();
3243   ret->alloc(nbOfTuple,2);
3244   double *w=ret->getPointer();
3245   const double *wIn=getConstPointer();
3246   for(int i=0;i<nbOfTuple;i++,w+=2,wIn+=2)
3247     {
3248       w[0]=wIn[0]*cos(wIn[1]);
3249       w[1]=wIn[0]*sin(wIn[1]);
3250     }
3251   return ret;
3252 }
3253
3254 /*!
3255  * Converts each 3D point defined by the tuple of \a this array from the Cylindrical to
3256  * the Cartesian coordinate system. The three components of the tuple of \a this array 
3257  * are considered to contain (1) radius, (2) azimuth and (3) altitude of the point in
3258  * the Cylindrical CS.
3259  *  \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
3260  *          contains X, Y and Z coordinates of the point in the Cartesian CS. The info
3261  *          on the third component is copied from \a this array. The caller
3262  *          is to delete this array using decrRef() as it is no more needed. 
3263  *  \throw If \a this->getNumberOfComponents() != 3.
3264  */
3265 DataArrayDouble *DataArrayDouble::fromCylToCart() const throw(INTERP_KERNEL::Exception)
3266 {
3267   checkAllocated();
3268   int nbOfComp=getNumberOfComponents();
3269   if(nbOfComp!=3)
3270     throw INTERP_KERNEL::Exception("DataArrayDouble::fromCylToCart : must be an array with exactly 3 components !");
3271   int nbOfTuple=getNumberOfTuples();
3272   DataArrayDouble *ret=DataArrayDouble::New();
3273   ret->alloc(getNumberOfTuples(),3);
3274   double *w=ret->getPointer();
3275   const double *wIn=getConstPointer();
3276   for(int i=0;i<nbOfTuple;i++,w+=3,wIn+=3)
3277     {
3278       w[0]=wIn[0]*cos(wIn[1]);
3279       w[1]=wIn[0]*sin(wIn[1]);
3280       w[2]=wIn[2];
3281     }
3282   ret->setInfoOnComponent(2,getInfoOnComponent(2).c_str());
3283   return ret;
3284 }
3285
3286 /*!
3287  * Converts each 3D point defined by the tuple of \a this array from the Spherical to
3288  * the Cartesian coordinate system. The three components of the tuple of \a this array 
3289  * are considered to contain (1) radius, (2) polar angle and (3) azimuthal angle of the
3290  * point in the Cylindrical CS.
3291  *  \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
3292  *          contains X, Y and Z coordinates of the point in the Cartesian CS. The info
3293  *          on the third component is copied from \a this array. The caller
3294  *          is to delete this array using decrRef() as it is no more needed.
3295  *  \throw If \a this->getNumberOfComponents() != 3.
3296  */
3297 DataArrayDouble *DataArrayDouble::fromSpherToCart() const throw(INTERP_KERNEL::Exception)
3298 {
3299   checkAllocated();
3300   int nbOfComp=getNumberOfComponents();
3301   if(nbOfComp!=3)
3302     throw INTERP_KERNEL::Exception("DataArrayDouble::fromSpherToCart : must be an array with exactly 3 components !");
3303   int nbOfTuple=getNumberOfTuples();
3304   DataArrayDouble *ret=DataArrayDouble::New();
3305   ret->alloc(getNumberOfTuples(),3);
3306   double *w=ret->getPointer();
3307   const double *wIn=getConstPointer();
3308   for(int i=0;i<nbOfTuple;i++,w+=3,wIn+=3)
3309     {
3310       w[0]=wIn[0]*cos(wIn[2])*sin(wIn[1]);
3311       w[1]=wIn[0]*sin(wIn[2])*sin(wIn[1]);
3312       w[2]=wIn[0]*cos(wIn[1]);
3313     }
3314   return ret;
3315 }
3316
3317 /*!
3318  * Computes the doubly contracted product of every tensor defined by the tuple of \a this
3319  * array contating 6 components.
3320  *  \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
3321  *          is calculated from the tuple <em>(t)</em> of \a this array as follows:
3322  *          \f$ t[0]^2+t[1]^2+t[2]^2+2*t[3]^2+2*t[4]^2+2*t[5]^2\f$.
3323  *         The caller is to delete this result array using decrRef() as it is no more needed. 
3324  *  \throw If \a this->getNumberOfComponents() != 6.
3325  */
3326 DataArrayDouble *DataArrayDouble::doublyContractedProduct() const throw(INTERP_KERNEL::Exception)
3327 {
3328   checkAllocated();
3329   int nbOfComp=getNumberOfComponents();
3330   if(nbOfComp!=6)
3331     throw INTERP_KERNEL::Exception("DataArrayDouble::doublyContractedProduct : must be an array with exactly 6 components !");
3332   DataArrayDouble *ret=DataArrayDouble::New();
3333   int nbOfTuple=getNumberOfTuples();
3334   ret->alloc(nbOfTuple,1);
3335   const double *src=getConstPointer();
3336   double *dest=ret->getPointer();
3337   for(int i=0;i<nbOfTuple;i++,dest++,src+=6)
3338     *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];
3339   return ret;
3340 }
3341
3342 /*!
3343  * Computes the determinant of every square matrix defined by the tuple of \a this
3344  * array, which contains either 4, 6 or 9 components. The case of 6 components
3345  * corresponds to that of the upper triangular matrix.
3346  *  \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
3347  *          is the determinant of matrix of the corresponding tuple of \a this array.
3348  *          The caller is to delete this result array using decrRef() as it is no more
3349  *          needed. 
3350  *  \throw If \a this->getNumberOfComponents() is not in [4,6,9].
3351  */
3352 DataArrayDouble *DataArrayDouble::determinant() const throw(INTERP_KERNEL::Exception)
3353 {
3354   checkAllocated();
3355   DataArrayDouble *ret=DataArrayDouble::New();
3356   int nbOfTuple=getNumberOfTuples();
3357   ret->alloc(nbOfTuple,1);
3358   const double *src=getConstPointer();
3359   double *dest=ret->getPointer();
3360   switch(getNumberOfComponents())
3361     {
3362     case 6:
3363       for(int i=0;i<nbOfTuple;i++,dest++,src+=6)
3364         *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];
3365       return ret;
3366     case 4:
3367       for(int i=0;i<nbOfTuple;i++,dest++,src+=4)
3368         *dest=src[0]*src[3]-src[1]*src[2];
3369       return ret;
3370     case 9:
3371       for(int i=0;i<nbOfTuple;i++,dest++,src+=9)
3372         *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];
3373       return ret;
3374     default:
3375       ret->decrRef();
3376       throw INTERP_KERNEL::Exception("DataArrayDouble::determinant : Invalid number of components ! must be in 4,6,9 !");
3377     }
3378 }
3379
3380 /*!
3381  * Computes 3 eigenvalues of every upper triangular matrix defined by the tuple of
3382  * \a this array, which contains 6 components.
3383  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing 3
3384  *          components, whose each tuple contains the eigenvalues of the matrix of
3385  *          corresponding tuple of \a this array. 
3386  *          The caller is to delete this result array using decrRef() as it is no more
3387  *          needed. 
3388  *  \throw If \a this->getNumberOfComponents() != 6.
3389  */
3390 DataArrayDouble *DataArrayDouble::eigenValues() const throw(INTERP_KERNEL::Exception)
3391 {
3392   checkAllocated();
3393   int nbOfComp=getNumberOfComponents();
3394   if(nbOfComp!=6)
3395     throw INTERP_KERNEL::Exception("DataArrayDouble::eigenValues : must be an array with exactly 6 components !");
3396   DataArrayDouble *ret=DataArrayDouble::New();
3397   int nbOfTuple=getNumberOfTuples();
3398   ret->alloc(nbOfTuple,3);
3399   const double *src=getConstPointer();
3400   double *dest=ret->getPointer();
3401   for(int i=0;i<nbOfTuple;i++,dest+=3,src+=6)
3402     INTERP_KERNEL::computeEigenValues6(src,dest);
3403   return ret;
3404 }
3405
3406 /*!
3407  * Computes 3 eigenvectors of every upper triangular matrix defined by the tuple of
3408  * \a this array, which contains 6 components.
3409  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing 9
3410  *          components, whose each tuple contains 3 eigenvectors of the matrix of
3411  *          corresponding tuple of \a this array.
3412  *          The caller is to delete this result array using decrRef() as it is no more
3413  *          needed.
3414  *  \throw If \a this->getNumberOfComponents() != 6.
3415  */
3416 DataArrayDouble *DataArrayDouble::eigenVectors() const throw(INTERP_KERNEL::Exception)
3417 {
3418   checkAllocated();
3419   int nbOfComp=getNumberOfComponents();
3420   if(nbOfComp!=6)
3421     throw INTERP_KERNEL::Exception("DataArrayDouble::eigenVectors : must be an array with exactly 6 components !");
3422   DataArrayDouble *ret=DataArrayDouble::New();
3423   int nbOfTuple=getNumberOfTuples();
3424   ret->alloc(nbOfTuple,9);
3425   const double *src=getConstPointer();
3426   double *dest=ret->getPointer();
3427   for(int i=0;i<nbOfTuple;i++,src+=6)
3428     {
3429       double tmp[3];
3430       INTERP_KERNEL::computeEigenValues6(src,tmp);
3431       for(int j=0;j<3;j++,dest+=3)
3432         INTERP_KERNEL::computeEigenVectorForEigenValue6(src,tmp[j],1e-12,dest);
3433     }
3434   return ret;
3435 }
3436
3437 /*!
3438  * Computes the inverse matrix of every matrix defined by the tuple of \a this
3439  * array, which contains either 4, 6 or 9 components. The case of 6 components
3440  * corresponds to that of the upper triangular matrix.
3441  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
3442  *          same number of components as \a this one, whose each tuple is the inverse
3443  *          matrix of the matrix of corresponding tuple of \a this array. 
3444  *          The caller is to delete this result array using decrRef() as it is no more
3445  *          needed. 
3446  *  \throw If \a this->getNumberOfComponents() is not in [4,6,9].
3447  */
3448 DataArrayDouble *DataArrayDouble::inverse() const throw(INTERP_KERNEL::Exception)
3449 {
3450   checkAllocated();
3451   int nbOfComp=getNumberOfComponents();
3452   if(nbOfComp!=6 && nbOfComp!=9 && nbOfComp!=4)
3453     throw INTERP_KERNEL::Exception("DataArrayDouble::inversion : must be an array with 4,6 or 9 components !");
3454   DataArrayDouble *ret=DataArrayDouble::New();
3455   int nbOfTuple=getNumberOfTuples();
3456   ret->alloc(nbOfTuple,nbOfComp);
3457   const double *src=getConstPointer();
3458   double *dest=ret->getPointer();
3459 if(nbOfComp==6)
3460     for(int i=0;i<nbOfTuple;i++,dest+=6,src+=6)
3461       {
3462         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];
3463         dest[0]=(src[1]*src[2]-src[4]*src[4])/det;
3464         dest[1]=(src[0]*src[2]-src[5]*src[5])/det;
3465         dest[2]=(src[0]*src[1]-src[3]*src[3])/det;
3466         dest[3]=(src[5]*src[4]-src[3]*src[2])/det;
3467         dest[4]=(src[5]*src[3]-src[0]*src[4])/det;
3468         dest[5]=(src[3]*src[4]-src[1]*src[5])/det;
3469       }
3470   else if(nbOfComp==4)
3471     for(int i=0;i<nbOfTuple;i++,dest+=4,src+=4)
3472       {
3473         double det=src[0]*src[3]-src[1]*src[2];
3474         dest[0]=src[3]/det;
3475         dest[1]=-src[1]/det;
3476         dest[2]=-src[2]/det;
3477         dest[3]=src[0]/det;
3478       }
3479   else
3480     for(int i=0;i<nbOfTuple;i++,dest+=9,src+=9)
3481       {
3482         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];
3483         dest[0]=(src[4]*src[8]-src[7]*src[5])/det;
3484         dest[1]=(src[7]*src[2]-src[1]*src[8])/det;
3485         dest[2]=(src[1]*src[5]-src[4]*src[2])/det;
3486         dest[3]=(src[6]*src[5]-src[3]*src[8])/det;
3487         dest[4]=(src[0]*src[8]-src[6]*src[2])/det;
3488         dest[5]=(src[2]*src[3]-src[0]*src[5])/det;
3489         dest[6]=(src[3]*src[7]-src[6]*src[4])/det;
3490         dest[7]=(src[6]*src[1]-src[0]*src[7])/det;
3491         dest[8]=(src[0]*src[4]-src[1]*src[3])/det;
3492       }
3493   return ret;
3494 }
3495
3496 /*!
3497  * Computes the trace of every matrix defined by the tuple of \a this
3498  * array, which contains either 4, 6 or 9 components. The case of 6 components
3499  * corresponds to that of the upper triangular matrix.
3500  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing 
3501  *          1 component, whose each tuple is the trace of
3502  *          the matrix of corresponding tuple of \a this array. 
3503  *          The caller is to delete this result array using decrRef() as it is no more
3504  *          needed. 
3505  *  \throw If \a this->getNumberOfComponents() is not in [4,6,9].
3506  */
3507 DataArrayDouble *DataArrayDouble::trace() const throw(INTERP_KERNEL::Exception)
3508 {
3509   checkAllocated();
3510   int nbOfComp=getNumberOfComponents();
3511   if(nbOfComp!=6 && nbOfComp!=9 && nbOfComp!=4)
3512     throw INTERP_KERNEL::Exception("DataArrayDouble::trace : must be an array with 4,6 or 9 components !");
3513   DataArrayDouble *ret=DataArrayDouble::New();
3514   int nbOfTuple=getNumberOfTuples();
3515   ret->alloc(nbOfTuple,1);
3516   const double *src=getConstPointer();
3517   double *dest=ret->getPointer();
3518   if(nbOfComp==6)
3519     for(int i=0;i<nbOfTuple;i++,dest++,src+=6)
3520       *dest=src[0]+src[1]+src[2];
3521   else if(nbOfComp==4)
3522     for(int i=0;i<nbOfTuple;i++,dest++,src+=4)
3523       *dest=src[0]+src[3];
3524   else
3525     for(int i=0;i<nbOfTuple;i++,dest++,src+=9)
3526       *dest=src[0]+src[4]+src[8];
3527   return ret;
3528 }
3529
3530 /*!
3531  * Computes the stress deviator tensor of every stress tensor defined by the tuple of
3532  * \a this array, which contains 6 components.
3533  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
3534  *          same number of components and tuples as \a this array.
3535  *          The caller is to delete this result array using decrRef() as it is no more
3536  *          needed.
3537  *  \throw If \a this->getNumberOfComponents() != 6.
3538  */
3539 DataArrayDouble *DataArrayDouble::deviator() const throw(INTERP_KERNEL::Exception)
3540 {
3541   checkAllocated();
3542   int nbOfComp=getNumberOfComponents();
3543   if(nbOfComp!=6)
3544     throw INTERP_KERNEL::Exception("DataArrayDouble::deviator : must be an array with exactly 6 components !");
3545   DataArrayDouble *ret=DataArrayDouble::New();
3546   int nbOfTuple=getNumberOfTuples();
3547   ret->alloc(nbOfTuple,6);
3548   const double *src=getConstPointer();
3549   double *dest=ret->getPointer();
3550   for(int i=0;i<nbOfTuple;i++,dest+=6,src+=6)
3551     {
3552       double tr=(src[0]+src[1]+src[2])/3.;
3553       dest[0]=src[0]-tr;
3554       dest[1]=src[1]-tr;
3555       dest[2]=src[2]-tr;
3556       dest[3]=src[3];
3557       dest[4]=src[4];
3558       dest[5]=src[5];
3559     }
3560   return ret;
3561 }
3562
3563 /*!
3564  * Computes the magnitude of every vector defined by the tuple of
3565  * \a this array.
3566  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
3567  *          same number of tuples as \a this array and one component.
3568  *          The caller is to delete this result array using decrRef() as it is no more
3569  *          needed.
3570  *  \throw If \a this is not allocated.
3571  */
3572 DataArrayDouble *DataArrayDouble::magnitude() const throw(INTERP_KERNEL::Exception)
3573 {
3574   checkAllocated();
3575   int nbOfComp=getNumberOfComponents();
3576   DataArrayDouble *ret=DataArrayDouble::New();
3577   int nbOfTuple=getNumberOfTuples();
3578   ret->alloc(nbOfTuple,1);
3579   const double *src=getConstPointer();
3580   double *dest=ret->getPointer();
3581   for(int i=0;i<nbOfTuple;i++,dest++)
3582     {
3583       double sum=0.;
3584       for(int j=0;j<nbOfComp;j++,src++)
3585         sum+=(*src)*(*src);
3586       *dest=sqrt(sum);
3587     }
3588   return ret;
3589 }
3590
3591 /*!
3592  * Computes the maximal value within every tuple of \a this array.
3593  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
3594  *          same number of tuples as \a this array and one component.
3595  *          The caller is to delete this result array using decrRef() as it is no more
3596  *          needed.
3597  *  \throw If \a this is not allocated.
3598  *  \sa DataArrayDouble::maxPerTupleWithCompoId
3599  */
3600 DataArrayDouble *DataArrayDouble::maxPerTuple() const throw(INTERP_KERNEL::Exception)
3601 {
3602   checkAllocated();
3603   int nbOfComp=getNumberOfComponents();
3604   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
3605   int nbOfTuple=getNumberOfTuples();
3606   ret->alloc(nbOfTuple,1);
3607   const double *src=getConstPointer();
3608   double *dest=ret->getPointer();
3609   for(int i=0;i<nbOfTuple;i++,dest++,src+=nbOfComp)
3610     *dest=*std::max_element(src,src+nbOfComp);
3611   return ret.retn();
3612 }
3613
3614 /*!
3615  * Computes the maximal value within every tuple of \a this array and it returns the first component
3616  * id for each tuple that corresponds to the maximal value within the tuple.
3617  * 
3618  *  \param [out] compoIdOfMaxPerTuple - the new new instance of DataArrayInt containing the
3619  *          same number of tuples and only one component.
3620  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
3621  *          same number of tuples as \a this array and one component.
3622  *          The caller is to delete this result array using decrRef() as it is no more
3623  *          needed.
3624  *  \throw If \a this is not allocated.
3625  *  \sa DataArrayDouble::maxPerTuple
3626  */
3627 DataArrayDouble *DataArrayDouble::maxPerTupleWithCompoId(DataArrayInt* &compoIdOfMaxPerTuple) const throw(INTERP_KERNEL::Exception)
3628 {
3629   checkAllocated();
3630   int nbOfComp=getNumberOfComponents();
3631   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret0=DataArrayDouble::New();
3632   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret1=DataArrayInt::New();
3633   int nbOfTuple=getNumberOfTuples();
3634   ret0->alloc(nbOfTuple,1); ret1->alloc(nbOfTuple,1);
3635   const double *src=getConstPointer();
3636   double *dest=ret0->getPointer(); int *dest1=ret1->getPointer();
3637   for(int i=0;i<nbOfTuple;i++,dest++,dest1++,src+=nbOfComp)
3638     {
3639       const double *loc=std::max_element(src,src+nbOfComp);
3640       *dest=*loc;
3641       *dest1=(int)std::distance(src,loc);
3642     }
3643   compoIdOfMaxPerTuple=ret1.retn();
3644   return ret0.retn();
3645 }
3646
3647 /*!
3648  * This method returns a newly allocated DataArrayDouble instance having one component and \c this->getNumberOfTuples() * \c this->getNumberOfTuples() tuples.
3649  * \n This returned array contains the euclidian distance for each tuple in \a this. 
3650  * \n So the returned array can be seen as a dense symmetrical matrix whose diagonal elements are equal to 0.
3651  * \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)
3652  *
3653  * \warning use this method with care because it can leads to big amount of consumed memory !
3654  * 
3655  * \return A newly allocated (huge) ParaMEDMEM::DataArrayDouble instance that the caller should deal with.
3656  *
3657  * \throw If \a this is not allocated.
3658  *
3659  * \sa DataArrayDouble::buildEuclidianDistanceDenseMatrixWith
3660  */
3661 DataArrayDouble *DataArrayDouble::buildEuclidianDistanceDenseMatrix() const throw(INTERP_KERNEL::Exception)
3662 {
3663   checkAllocated();
3664   int nbOfComp=getNumberOfComponents();
3665   int nbOfTuples=getNumberOfTuples();
3666   const double *inData=getConstPointer();
3667   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
3668   ret->alloc(nbOfTuples*nbOfTuples,1);
3669   double *outData=ret->getPointer();
3670   for(int i=0;i<nbOfTuples;i++)
3671     {
3672       outData[i*nbOfTuples+i]=0.;
3673       for(int j=i+1;j<nbOfTuples;j++)
3674         {
3675           double dist=0.;
3676           for(int k=0;k<nbOfComp;k++)
3677             { double delta=inData[i*nbOfComp+k]-inData[j*nbOfComp+k]; dist+=delta*delta; }
3678           dist=sqrt(dist);
3679           outData[i*nbOfTuples+j]=dist;
3680           outData[j*nbOfTuples+i]=dist;
3681         }
3682     }
3683   return ret.retn();
3684 }
3685
3686 /*!
3687  * This method returns a newly allocated DataArrayDouble instance having one component and \c this->getNumberOfTuples() * \c other->getNumberOfTuples() tuples.
3688  * \n This returned array contains the euclidian distance for each tuple in \a other with each tuple in \a this. 
3689  * \n So the returned array can be seen as a dense rectangular matrix with \c other->getNumberOfTuples() rows and \c this->getNumberOfTuples() columns.
3690  * \n Output rectangular matrix is sorted along rows.
3691  * \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)
3692  *
3693  * \warning use this method with care because it can leads to big amount of consumed memory !
3694  * 
3695  * \param [in] other DataArrayDouble instance having same number of components than \a this.
3696  * \return A newly allocated (huge) ParaMEDMEM::DataArrayDouble instance that the caller should deal with.
3697  *
3698  * \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.
3699  *
3700  * \sa DataArrayDouble::buildEuclidianDistanceDenseMatrix
3701  */
3702 DataArrayDouble *DataArrayDouble::buildEuclidianDistanceDenseMatrixWith(const DataArrayDouble *other) const throw(INTERP_KERNEL::Exception)
3703 {
3704   if(!other)
3705     throw INTERP_KERNEL::Exception("DataArrayDouble::buildEuclidianDistanceDenseMatrixWith : input parameter is null !");
3706   checkAllocated();
3707   other->checkAllocated();
3708   int nbOfComp=getNumberOfComponents();
3709   int otherNbOfComp=other->getNumberOfComponents();
3710   if(nbOfComp!=otherNbOfComp)
3711     {
3712       std::ostringstream oss; oss << "DataArrayDouble::buildEuclidianDistanceDenseMatrixWith : this nb of compo=" << nbOfComp << " and other nb of compo=" << otherNbOfComp << ". It should match !";
3713       throw INTERP_KERNEL::Exception(oss.str().c_str());
3714     }
3715   int nbOfTuples=getNumberOfTuples();
3716   int otherNbOfTuples=other->getNumberOfTuples();
3717   const double *inData=getConstPointer();
3718   const double *inDataOther=other->getConstPointer();
3719   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
3720   ret->alloc(otherNbOfTuples*nbOfTuples,1);
3721   double *outData=ret->getPointer();
3722   for(int i=0;i<otherNbOfTuples;i++,inDataOther+=nbOfComp)
3723     {
3724       for(int j=0;j<nbOfTuples;j++)
3725         {
3726           double dist=0.;
3727           for(int k=0;k<nbOfComp;k++)
3728             { double delta=inDataOther[k]-inData[j*nbOfComp+k]; dist+=delta*delta; }
3729           dist=sqrt(dist);
3730           outData[i*nbOfTuples+j]=dist;
3731         }
3732     }
3733   return ret.retn();
3734 }
3735
3736 /*!
3737  * Sorts value within every tuple of \a this array.
3738  *  \param [in] asc - if \a true, the values are sorted in ascending order, else,
3739  *              in descending order.
3740  *  \throw If \a this is not allocated.
3741  */
3742 void DataArrayDouble::sortPerTuple(bool asc) throw(INTERP_KERNEL::Exception)
3743 {
3744   checkAllocated();
3745   double *pt=getPointer();
3746   int nbOfTuple=getNumberOfTuples();
3747   int nbOfComp=getNumberOfComponents();
3748   if(asc)
3749     for(int i=0;i<nbOfTuple;i++,pt+=nbOfComp)
3750       std::sort(pt,pt+nbOfComp);
3751   else
3752     for(int i=0;i<nbOfTuple;i++,pt+=nbOfComp)
3753       std::sort(pt,pt+nbOfComp,std::greater<double>());
3754   declareAsNew();
3755 }
3756
3757 /*!
3758  * Converts every value of \a this array to its absolute value.
3759  *  \throw If \a this is not allocated.
3760  */
3761 void DataArrayDouble::abs() throw(INTERP_KERNEL::Exception)
3762 {
3763   checkAllocated();
3764   double *ptr=getPointer();
3765   std::size_t nbOfElems=getNbOfElems();
3766   std::transform(ptr,ptr+nbOfElems,ptr,std::ptr_fun<double,double>(fabs));
3767   declareAsNew();
3768 }
3769
3770 /*!
3771  * Apply a liner function to a given component of \a this array, so that
3772  * an array element <em>(x)</em> becomes \f$ a * x + b \f$.
3773  *  \param [in] a - the first coefficient of the function.
3774  *  \param [in] b - the second coefficient of the function.
3775  *  \param [in] compoId - the index of component to modify.
3776  *  \throw If \a this is not allocated.
3777  */
3778 void DataArrayDouble::applyLin(double a, double b, int compoId) throw(INTERP_KERNEL::Exception)
3779 {
3780   checkAllocated();
3781   double *ptr=getPointer()+compoId;
3782   int nbOfComp=getNumberOfComponents();
3783   int nbOfTuple=getNumberOfTuples();
3784   for(int i=0;i<nbOfTuple;i++,ptr+=nbOfComp)
3785     *ptr=a*(*ptr)+b;
3786   declareAsNew();
3787 }
3788
3789 /*!
3790  * Apply a liner function to all elements of \a this array, so that
3791  * an element _x_ becomes \f$ a * x + b \f$.
3792  *  \param [in] a - the first coefficient of the function.
3793  *  \param [in] b - the second coefficient of the function.
3794  *  \throw If \a this is not allocated.
3795  */
3796 void DataArrayDouble::applyLin(double a, double b) throw(INTERP_KERNEL::Exception)
3797 {
3798   checkAllocated();
3799   double *ptr=getPointer();
3800   std::size_t nbOfElems=getNbOfElems();
3801   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
3802     *ptr=a*(*ptr)+b;
3803   declareAsNew();
3804 }
3805
3806 /*!
3807  * Modify all elements of \a this array, so that
3808  * an element _x_ becomes \f$ numerator / x \f$.
3809  *  \warning If an exception is thrown because of presence of 0.0 element in \a this 
3810  *           array, all elements processed before detection of the zero element remain
3811  *           modified.
3812  *  \param [in] numerator - the numerator used to modify array elements.
3813  *  \throw If \a this is not allocated.
3814  *  \throw If there is an element equal to 0.0 in \a this array.
3815  */
3816 void DataArrayDouble::applyInv(double numerator) throw(INTERP_KERNEL::Exception)
3817 {
3818   checkAllocated();
3819   double *ptr=getPointer();
3820   std::size_t nbOfElems=getNbOfElems();
3821   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
3822     {
3823       if(std::abs(*ptr)>std::numeric_limits<double>::min())
3824         {
3825           *ptr=numerator/(*ptr);
3826         }
3827       else
3828         {
3829           std::ostringstream oss; oss << "DataArrayDouble::applyInv : presence of null value in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
3830           oss << " !";
3831           throw INTERP_KERNEL::Exception(oss.str().c_str());
3832         }
3833     }
3834   declareAsNew();
3835 }
3836
3837 /*!
3838  * Returns a full copy of \a this array except that sign of all elements is reversed.
3839  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
3840  *          same number of tuples and component as \a this array.
3841  *          The caller is to delete this result array using decrRef() as it is no more
3842  *          needed.
3843  *  \throw If \a this is not allocated.
3844  */
3845 DataArrayDouble *DataArrayDouble::negate() const throw(INTERP_KERNEL::Exception)
3846 {
3847   checkAllocated();
3848   DataArrayDouble *newArr=DataArrayDouble::New();
3849   int nbOfTuples=getNumberOfTuples();
3850   int nbOfComp=getNumberOfComponents();
3851   newArr->alloc(nbOfTuples,nbOfComp);
3852   const double *cptr=getConstPointer();
3853   std::transform(cptr,cptr+nbOfTuples*nbOfComp,newArr->getPointer(),std::negate<double>());
3854   newArr->copyStringInfoFrom(*this);
3855   return newArr;
3856 }
3857
3858 /*!
3859  * Modify all elements of \a this array, so that
3860  * an element _x_ becomes <em> val ^ x </em>. Contrary to DataArrayInt::applyPow
3861  * all values in \a this have to be >= 0 if val is \b not integer.
3862  *  \param [in] val - the value used to apply pow on all array elements.
3863  *  \throw If \a this is not allocated.
3864  *  \warning If an exception is thrown because of presence of 0 element in \a this 
3865  *           array and \a val is \b not integer, all elements processed before detection of the zero element remain
3866  *           modified.
3867  */
3868 void DataArrayDouble::applyPow(double val) throw(INTERP_KERNEL::Exception)
3869 {
3870   checkAllocated();
3871   double *ptr=getPointer();
3872   std::size_t nbOfElems=getNbOfElems();
3873   int val2=(int)val;
3874   bool isInt=((double)val2)==val;
3875   if(!isInt)
3876     {
3877       for(std::size_t i=0;i<nbOfElems;i++,ptr++)
3878         {
3879           if(*ptr>=0)
3880             *ptr=pow(*ptr,val);
3881           else
3882             {
3883               std::ostringstream oss; oss << "DataArrayDouble::applyPow (double) : At elem # " << i << " value is " << *ptr << " ! must be >=0. !";
3884               throw INTERP_KERNEL::Exception(oss.str().c_str());
3885             }
3886         }
3887     }
3888   else
3889     {
3890       for(std::size_t i=0;i<nbOfElems;i++,ptr++)
3891         *ptr=pow(*ptr,val2);
3892     }
3893   declareAsNew();
3894 }
3895
3896 /*!
3897  * Modify all elements of \a this array, so that
3898  * an element _x_ becomes \f$ val ^ x \f$.
3899  *  \param [in] val - the value used to apply pow on all array elements.
3900  *  \throw If \a this is not allocated.
3901  *  \throw If \a val < 0.
3902  *  \warning If an exception is thrown because of presence of 0 element in \a this 
3903  *           array, all elements processed before detection of the zero element remain
3904  *           modified.
3905  */
3906 void DataArrayDouble::applyRPow(double val) throw(INTERP_KERNEL::Exception)
3907 {
3908   checkAllocated();
3909   if(val<0.)
3910     throw INTERP_KERNEL::Exception("DataArrayDouble::applyRPow : the input value has to be >= 0 !");
3911   double *ptr=getPointer();
3912   std::size_t nbOfElems=getNbOfElems();
3913   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
3914     *ptr=pow(val,*ptr);
3915   declareAsNew();
3916 }
3917
3918 /*!
3919  * Returns a new DataArrayDouble created from \a this one by applying \a
3920  * FunctionToEvaluate to every tuple of \a this array. Textual data is not copied.
3921  * For more info see \ref MEDCouplingArrayApplyFunc
3922  *  \param [in] nbOfComp - number of components in the result array.
3923  *  \param [in] func - the \a FunctionToEvaluate declared as 
3924  *              \c bool (*\a func)(\c const \c double *\a pos, \c double *\a res), 
3925  *              where \a pos points to the first component of a tuple of \a this array
3926  *              and \a res points to the first component of a tuple of the result array.
3927  *              Note that length (number of components) of \a pos can differ from
3928  *              that of \a res.
3929  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
3930  *          same number of tuples as \a this array.
3931  *          The caller is to delete this result array using decrRef() as it is no more
3932  *          needed.
3933  *  \throw If \a this is not allocated.
3934  *  \throw If \a func returns \a false.
3935  */
3936 DataArrayDouble *DataArrayDouble::applyFunc(int nbOfComp, FunctionToEvaluate func) const throw(INTERP_KERNEL::Exception)
3937 {
3938   checkAllocated();
3939   DataArrayDouble *newArr=DataArrayDouble::New();
3940   int nbOfTuples=getNumberOfTuples();
3941   int oldNbOfComp=getNumberOfComponents();
3942   newArr->alloc(nbOfTuples,nbOfComp);
3943   const double *ptr=getConstPointer();
3944   double *ptrToFill=newArr->getPointer();
3945   for(int i=0;i<nbOfTuples;i++)
3946     {
3947       if(!func(ptr+i*oldNbOfComp,ptrToFill+i*nbOfComp))
3948         {
3949           std::ostringstream oss; oss << "For tuple # " << i << " with value (";
3950           std::copy(ptr+oldNbOfComp*i,ptr+oldNbOfComp*(i+1),std::ostream_iterator<double>(oss,", "));
3951           oss << ") : Evaluation of function failed !";
3952           newArr->decrRef();
3953           throw INTERP_KERNEL::Exception(oss.str().c_str());
3954         }
3955     }
3956   return newArr;
3957 }
3958
3959 /*!
3960  * Returns a new DataArrayDouble created from \a this one by applying a function to every
3961  * tuple of \a this array. Textual data is not copied.
3962  * For more info see \ref MEDCouplingArrayApplyFunc1.
3963  *  \param [in] nbOfComp - number of components in the result array.
3964  *  \param [in] func - the expression defining how to transform a tuple of \a this array.
3965  *              Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
3966  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
3967  *          same number of tuples as \a this array and \a nbOfComp components.
3968  *          The caller is to delete this result array using decrRef() as it is no more
3969  *          needed.
3970  *  \throw If \a this is not allocated.
3971  *  \throw If computing \a func fails.
3972  */
3973 DataArrayDouble *DataArrayDouble::applyFunc(int nbOfComp, const char *func) const throw(INTERP_KERNEL::Exception)
3974 {
3975   checkAllocated();
3976   INTERP_KERNEL::ExprParser expr(func);
3977   expr.parse();
3978   std::set<std::string> vars;
3979   expr.getTrueSetOfVars(vars);
3980   int oldNbOfComp=getNumberOfComponents();
3981   if((int)vars.size()>oldNbOfComp)
3982     {
3983       std::ostringstream oss; oss << "The field has " << oldNbOfComp << " components and there are ";
3984       oss << vars.size() << " variables : ";
3985       std::copy(vars.begin(),vars.end(),std::ostream_iterator<std::string>(oss," "));
3986       throw INTERP_KERNEL::Exception(oss.str().c_str());
3987     }
3988   std::vector<std::string> varsV(vars.begin(),vars.end());
3989   expr.prepareExprEvaluation(varsV,oldNbOfComp,nbOfComp);
3990   //
3991   DataArrayDouble *newArr=DataArrayDouble::New();
3992   int nbOfTuples=getNumberOfTuples();
3993   newArr->alloc(nbOfTuples,nbOfComp);
3994   const double *ptr=getConstPointer();
3995   double *ptrToFill=newArr->getPointer();
3996   for(int i=0;i<nbOfTuples;i++)
3997     {
3998       try
3999         {
4000           expr.evaluateExpr(nbOfComp,ptr+i*oldNbOfComp,ptrToFill+i*nbOfComp);
4001         }
4002       catch(INTERP_KERNEL::Exception& e)
4003         {
4004           std::ostringstream oss; oss << "For tuple # " << i << " with value (";
4005           std::copy(ptr+oldNbOfComp*i,ptr+oldNbOfComp*(i+1),std::ostream_iterator<double>(oss,", "));
4006           oss << ") : Evaluation of function failed !" << e.what();
4007           newArr->decrRef();
4008           throw INTERP_KERNEL::Exception(oss.str().c_str());
4009         }
4010     }
4011   return newArr;
4012 }
4013
4014 /*!
4015  * Returns a new DataArrayDouble created from \a this one by applying a function to every
4016  * tuple of \a this array. Textual data is not copied.
4017  * For more info see \ref MEDCouplingArrayApplyFunc0.
4018  *  \param [in] func - the expression defining how to transform a tuple of \a this array.
4019  *              Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
4020  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
4021  *          same number of tuples and components as \a this array.
4022  *          The caller is to delete this result array using decrRef() as it is no more
4023  *          needed.
4024  *  \throw If \a this is not allocated.
4025  *  \throw If computing \a func fails.
4026  */
4027 DataArrayDouble *DataArrayDouble::applyFunc(const char *func) const throw(INTERP_KERNEL::Exception)
4028 {
4029   checkAllocated();
4030   INTERP_KERNEL::ExprParser expr(func);
4031   expr.parse();
4032   expr.prepareExprEvaluationVec();
4033   //
4034   DataArrayDouble *newArr=DataArrayDouble::New();
4035   int nbOfTuples=getNumberOfTuples();
4036   int nbOfComp=getNumberOfComponents();
4037   newArr->alloc(nbOfTuples,nbOfComp);
4038   const double *ptr=getConstPointer();
4039   double *ptrToFill=newArr->getPointer();
4040   for(int i=0;i<nbOfTuples;i++)
4041     {
4042       try
4043         {
4044           expr.evaluateExpr(nbOfComp,ptr+i*nbOfComp,ptrToFill+i*nbOfComp);
4045         }
4046       catch(INTERP_KERNEL::Exception& e)
4047         {
4048           std::ostringstream oss; oss << "For tuple # " << i << " with value (";
4049           std::copy(ptr+nbOfComp*i,ptr+nbOfComp*(i+1),std::ostream_iterator<double>(oss,", "));
4050           oss << ") : Evaluation of function failed ! " << e.what();
4051           newArr->decrRef();
4052           throw INTERP_KERNEL::Exception(oss.str().c_str());
4053         }
4054     }
4055   return newArr;
4056 }
4057
4058 /*!
4059  * Returns a new DataArrayDouble created from \a this one by applying a function to every
4060  * tuple of \a this array. Textual data is not copied.
4061  * For more info see \ref MEDCouplingArrayApplyFunc2.
4062  *  \param [in] nbOfComp - number of components in the result array.
4063  *  \param [in] func - the expression defining how to transform a tuple of \a this array.
4064  *              Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
4065  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
4066  *          same number of tuples as \a this array.
4067  *          The caller is to delete this result array using decrRef() as it is no more
4068  *          needed.
4069  *  \throw If \a this is not allocated.
4070  *  \throw If \a func contains vars that are not in \a this->getInfoOnComponent().
4071  *  \throw If computing \a func fails.
4072  */
4073 DataArrayDouble *DataArrayDouble::applyFunc2(int nbOfComp, const char *func) const throw(INTERP_KERNEL::Exception)
4074 {
4075   checkAllocated();
4076   INTERP_KERNEL::ExprParser expr(func);
4077   expr.parse();
4078   std::set<std::string> vars;
4079   expr.getTrueSetOfVars(vars);
4080   int oldNbOfComp=getNumberOfComponents();
4081   if((int)vars.size()>oldNbOfComp)
4082     {
4083       std::ostringstream oss; oss << "The field has " << oldNbOfComp << " components and there are ";
4084       oss << vars.size() << " variables : ";
4085       std::copy(vars.begin(),vars.end(),std::ostream_iterator<std::string>(oss," "));
4086       throw INTERP_KERNEL::Exception(oss.str().c_str());
4087     }
4088   expr.prepareExprEvaluation(getVarsOnComponent(),oldNbOfComp,nbOfComp);
4089   //
4090   DataArrayDouble *newArr=DataArrayDouble::New();
4091   int nbOfTuples=getNumberOfTuples();
4092   newArr->alloc(nbOfTuples,nbOfComp);
4093   const double *ptr=getConstPointer();
4094   double *ptrToFill=newArr->getPointer();
4095   for(int i=0;i<nbOfTuples;i++)
4096     {
4097       try
4098         {
4099           expr.evaluateExpr(nbOfComp,ptr+i*oldNbOfComp,ptrToFill+i*nbOfComp);
4100         }
4101       catch(INTERP_KERNEL::Exception& e)
4102         {
4103           std::ostringstream oss; oss << "For tuple # " << i << " with value (";
4104           std::copy(ptr+oldNbOfComp*i,ptr+oldNbOfComp*(i+1),std::ostream_iterator<double>(oss,", "));
4105           oss << ") : Evaluation of function failed !" << e.what();
4106           newArr->decrRef();
4107           throw INTERP_KERNEL::Exception(oss.str().c_str());
4108         }
4109     }
4110   return newArr;
4111 }
4112
4113 /*!
4114  * Returns a new DataArrayDouble created from \a this one by applying a function to every
4115  * tuple of \a this array. Textual data is not copied.
4116  * For more info see \ref MEDCouplingArrayApplyFunc3.
4117  *  \param [in] nbOfComp - number of components in the result array.
4118  *  \param [in] varsOrder - sequence of vars defining their order.
4119  *  \param [in] func - the expression defining how to transform a tuple of \a this array.
4120  *              Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
4121  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
4122  *          same number of tuples as \a this array.
4123  *          The caller is to delete this result array using decrRef() as it is no more
4124  *          needed.
4125  *  \throw If \a this is not allocated.
4126  *  \throw If \a func contains vars not in \a varsOrder.
4127  *  \throw If computing \a func fails.
4128  */
4129 DataArrayDouble *DataArrayDouble::applyFunc3(int nbOfComp, const std::vector<std::string>& varsOrder, const char *func) const throw(INTERP_KERNEL::Exception)
4130 {
4131   checkAllocated();
4132   INTERP_KERNEL::ExprParser expr(func);
4133   expr.parse();
4134   std::set<std::string> vars;
4135   expr.getTrueSetOfVars(vars);
4136   int oldNbOfComp=getNumberOfComponents();
4137   if((int)vars.size()>oldNbOfComp)
4138     {
4139       std::ostringstream oss; oss << "The field has " << oldNbOfComp << " components and there are ";
4140       oss << vars.size() << " variables : ";
4141       std::copy(vars.begin(),vars.end(),std::ostream_iterator<std::string>(oss," "));
4142       throw INTERP_KERNEL::Exception(oss.str().c_str());
4143     }
4144   expr.prepareExprEvaluation(varsOrder,oldNbOfComp,nbOfComp);
4145   //
4146   DataArrayDouble *newArr=DataArrayDouble::New();
4147   int nbOfTuples=getNumberOfTuples();
4148   newArr->alloc(nbOfTuples,nbOfComp);
4149   const double *ptr=getConstPointer();
4150   double *ptrToFill=newArr->getPointer();
4151   for(int i=0;i<nbOfTuples;i++)
4152     {
4153       try
4154         {
4155           expr.evaluateExpr(nbOfComp,ptr+i*oldNbOfComp,ptrToFill+i*nbOfComp);
4156         }
4157       catch(INTERP_KERNEL::Exception& e)
4158         {
4159           std::ostringstream oss; oss << "For tuple # " << i << " with value (";
4160           std::copy(ptr+oldNbOfComp*i,ptr+oldNbOfComp*(i+1),std::ostream_iterator<double>(oss,", "));
4161           oss << ") : Evaluation of function failed !" << e.what();
4162           newArr->decrRef();
4163           throw INTERP_KERNEL::Exception(oss.str().c_str());
4164         }
4165     }
4166   return newArr;
4167 }
4168
4169 void DataArrayDouble::applyFuncFast32(const char *func) throw(INTERP_KERNEL::Exception)
4170 {
4171   checkAllocated();
4172   INTERP_KERNEL::ExprParser expr(func);
4173   expr.parse();
4174   char *funcStr=expr.compileX86();
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 void DataArrayDouble::applyFuncFast64(const char *func) throw(INTERP_KERNEL::Exception)
4188 {
4189   checkAllocated();
4190   INTERP_KERNEL::ExprParser expr(func);
4191   expr.parse();
4192   char *funcStr=expr.compileX86_64();
4193   MYFUNCPTR funcPtr;
4194   *((void **)&funcPtr)=funcStr;//he he...
4195   //
4196   double *ptr=getPointer();
4197   int nbOfComp=getNumberOfComponents();
4198   int nbOfTuples=getNumberOfTuples();
4199   int nbOfElems=nbOfTuples*nbOfComp;
4200   for(int i=0;i<nbOfElems;i++,ptr++)
4201     *ptr=funcPtr(*ptr);
4202   declareAsNew();
4203 }
4204
4205 DataArrayDoubleIterator *DataArrayDouble::iterator() throw(INTERP_KERNEL::Exception)
4206 {
4207   return new DataArrayDoubleIterator(this);
4208 }
4209
4210 /*!
4211  * Returns a new DataArrayInt contating indices of tuples of \a this one-dimensional
4212  * array whose values are within a given range. Textual data is not copied.
4213  *  \param [in] vmin - a lowest acceptable value (included).
4214  *  \param [in] vmax - a greatest acceptable value (included).
4215  *  \return DataArrayInt * - the new instance of DataArrayInt.
4216  *          The caller is to delete this result array using decrRef() as it is no more
4217  *          needed.
4218  *  \throw If \a this->getNumberOfComponents() != 1.
4219  *
4220  *  \ref cpp_mcdataarraydouble_getidsinrange "Here is a C++ example".<br>
4221  *  \ref py_mcdataarraydouble_getidsinrange "Here is a Python example".
4222  */
4223 DataArrayInt *DataArrayDouble::getIdsInRange(double vmin, double vmax) const throw(INTERP_KERNEL::Exception)
4224 {
4225   checkAllocated();
4226   if(getNumberOfComponents()!=1)
4227     throw INTERP_KERNEL::Exception("DataArrayDouble::getIdsInRange : this must have exactly one component !");
4228   const double *cptr=getConstPointer();
4229   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(0,1);
4230   int nbOfTuples=getNumberOfTuples();
4231   for(int i=0;i<nbOfTuples;i++,cptr++)
4232     if(*cptr>=vmin && *cptr<=vmax)
4233       ret->pushBackSilent(i);
4234   return ret.retn();
4235 }
4236
4237 /*!
4238  * Returns a new DataArrayDouble by concatenating two given arrays, so that (1) the number
4239  * of tuples in the result array is a sum of the number of tuples of given arrays and (2)
4240  * the number of component in the result array is same as that of each of given arrays.
4241  * Info on components is copied from the first of the given arrays. Number of components
4242  * in the given arrays must be  the same.
4243  *  \param [in] a1 - an array to include in the result array.
4244  *  \param [in] a2 - another array to include in the result array.
4245  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4246  *          The caller is to delete this result array using decrRef() as it is no more
4247  *          needed.
4248  *  \throw If both \a a1 and \a a2 are NULL.
4249  *  \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents().
4250  */
4251 DataArrayDouble *DataArrayDouble::Aggregate(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception)
4252 {
4253   std::vector<const DataArrayDouble *> tmp(2);
4254   tmp[0]=a1; tmp[1]=a2;
4255   return Aggregate(tmp);
4256 }
4257
4258 /*!
4259  * Returns a new DataArrayDouble by concatenating all given arrays, so that (1) the number
4260  * of tuples in the result array is a sum of the number of tuples of given arrays and (2)
4261  * the number of component in the result array is same as that of each of given arrays.
4262  * Info on components is copied from the first of the given arrays. Number of components
4263  * in the given arrays must be  the same.
4264  *  \param [in] arr - a sequence of arrays to include in the result array.
4265  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4266  *          The caller is to delete this result array using decrRef() as it is no more
4267  *          needed.
4268  *  \throw If all arrays within \a arr are NULL.
4269  *  \throw If getNumberOfComponents() of arrays within \a arr.
4270  */
4271 DataArrayDouble *DataArrayDouble::Aggregate(const std::vector<const DataArrayDouble *>& arr) throw(INTERP_KERNEL::Exception)
4272 {
4273   std::vector<const DataArrayDouble *> a;
4274   for(std::vector<const DataArrayDouble *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
4275     if(*it4)
4276       a.push_back(*it4);
4277   if(a.empty())
4278     throw INTERP_KERNEL::Exception("DataArrayDouble::Aggregate : input list must contain at least one NON EMPTY DataArrayDouble !");
4279   std::vector<const DataArrayDouble *>::const_iterator it=a.begin();
4280   int nbOfComp=(*it)->getNumberOfComponents();
4281   int nbt=(*it++)->getNumberOfTuples();
4282   for(int i=1;it!=a.end();it++,i++)
4283     {
4284       if((*it)->getNumberOfComponents()!=nbOfComp)
4285         throw INTERP_KERNEL::Exception("DataArrayDouble::Aggregate : Nb of components mismatch for array aggregation !");
4286       nbt+=(*it)->getNumberOfTuples();
4287     }
4288   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
4289   ret->alloc(nbt,nbOfComp);
4290   double *pt=ret->getPointer();
4291   for(it=a.begin();it!=a.end();it++)
4292     pt=std::copy((*it)->getConstPointer(),(*it)->getConstPointer()+(*it)->getNbOfElems(),pt);
4293   ret->copyStringInfoFrom(*(a[0]));
4294   return ret.retn();
4295 }
4296
4297 /*!
4298  * Returns a new DataArrayDouble by aggregating two given arrays, so that (1) the number
4299  * of components in the result array is a sum of the number of components of given arrays
4300  * and (2) the number of tuples in the result array is same as that of each of given
4301  * arrays. In other words the i-th tuple of result array includes all components of
4302  * i-th tuples of all given arrays.
4303  * Number of tuples in the given arrays must be  the same.
4304  *  \param [in] a1 - an array to include in the result array.
4305  *  \param [in] a2 - another array to include in the result array.
4306  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4307  *          The caller is to delete this result array using decrRef() as it is no more
4308  *          needed.
4309  *  \throw If both \a a1 and \a a2 are NULL.
4310  *  \throw If any given array is not allocated.
4311  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
4312  */
4313 DataArrayDouble *DataArrayDouble::Meld(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception)
4314 {
4315   std::vector<const DataArrayDouble *> arr(2);
4316   arr[0]=a1; arr[1]=a2;
4317   return Meld(arr);
4318 }
4319
4320 /*!
4321  * Returns a new DataArrayDouble by aggregating all given arrays, so that (1) the number
4322  * of components in the result array is a sum of the number of components of given arrays
4323  * and (2) the number of tuples in the result array is same as that of each of given
4324  * arrays. In other words the i-th tuple of result array includes all components of
4325  * i-th tuples of all given arrays.
4326  * Number of tuples in the given arrays must be  the same.
4327  *  \param [in] arr - a sequence of arrays to include in the result array.
4328  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4329  *          The caller is to delete this result array using decrRef() as it is no more
4330  *          needed.
4331  *  \throw If all arrays within \a arr are NULL.
4332  *  \throw If any given array is not allocated.
4333  *  \throw If getNumberOfTuples() of arrays within \a arr is different.
4334  */
4335 DataArrayDouble *DataArrayDouble::Meld(const std::vector<const DataArrayDouble *>& arr) throw(INTERP_KERNEL::Exception)
4336 {
4337   std::vector<const DataArrayDouble *> a;
4338   for(std::vector<const DataArrayDouble *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
4339     if(*it4)
4340       a.push_back(*it4);
4341   if(a.empty())
4342     throw INTERP_KERNEL::Exception("DataArrayDouble::Meld : input list must contain at least one NON EMPTY DataArrayDouble !");
4343   std::vector<const DataArrayDouble *>::const_iterator it;
4344   for(it=a.begin();it!=a.end();it++)
4345     (*it)->checkAllocated();
4346   it=a.begin();
4347   int nbOfTuples=(*it)->getNumberOfTuples();
4348   std::vector<int> nbc(a.size());
4349   std::vector<const double *> pts(a.size());
4350   nbc[0]=(*it)->getNumberOfComponents();
4351   pts[0]=(*it++)->getConstPointer();
4352   for(int i=1;it!=a.end();it++,i++)
4353     {
4354       if(nbOfTuples!=(*it)->getNumberOfTuples())
4355         throw INTERP_KERNEL::Exception("DataArrayDouble::Meld : mismatch of number of tuples !");
4356       nbc[i]=(*it)->getNumberOfComponents();
4357       pts[i]=(*it)->getConstPointer();
4358     }
4359   int totalNbOfComp=std::accumulate(nbc.begin(),nbc.end(),0);
4360   DataArrayDouble *ret=DataArrayDouble::New();
4361   ret->alloc(nbOfTuples,totalNbOfComp);
4362   double *retPtr=ret->getPointer();
4363   for(int i=0;i<nbOfTuples;i++)
4364     for(int j=0;j<(int)a.size();j++)
4365       {
4366         retPtr=std::copy(pts[j],pts[j]+nbc[j],retPtr);
4367         pts[j]+=nbc[j];
4368       }
4369   int k=0;
4370   for(int i=0;i<(int)a.size();i++)
4371     for(int j=0;j<nbc[i];j++,k++)
4372       ret->setInfoOnComponent(k,a[i]->getInfoOnComponent(j).c_str());
4373   return ret;
4374 }
4375
4376 /*!
4377  * Returns a new DataArrayDouble containing a dot product of two given arrays, so that
4378  * the i-th tuple of the result array is a sum of products of j-th components of i-th
4379  * tuples of given arrays (\f$ a_i = \sum_{j=1}^n a1_j * a2_j \f$).
4380  * Info on components and name is copied from the first of the given arrays.
4381  * Number of tuples and components in the given arrays must be the same.
4382  *  \param [in] a1 - a given array.
4383  *  \param [in] a2 - another given array.
4384  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4385  *          The caller is to delete this result array using decrRef() as it is no more
4386  *          needed.
4387  *  \throw If either \a a1 or \a a2 is NULL.
4388  *  \throw If any given array is not allocated.
4389  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
4390  *  \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents()
4391  */
4392 DataArrayDouble *DataArrayDouble::Dot(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception)
4393 {
4394   if(!a1 || !a2)
4395     throw INTERP_KERNEL::Exception("DataArrayDouble::Dot : input DataArrayDouble instance is NULL !");
4396   a1->checkAllocated();
4397   a2->checkAllocated();
4398   int nbOfComp=a1->getNumberOfComponents();
4399   if(nbOfComp!=a2->getNumberOfComponents())
4400     throw INTERP_KERNEL::Exception("Nb of components mismatch for array Dot !");
4401   int nbOfTuple=a1->getNumberOfTuples();
4402   if(nbOfTuple!=a2->getNumberOfTuples())
4403     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Dot !");
4404   DataArrayDouble *ret=DataArrayDouble::New();
4405   ret->alloc(nbOfTuple,1);
4406   double *retPtr=ret->getPointer();
4407   const double *a1Ptr=a1->getConstPointer();
4408   const double *a2Ptr=a2->getConstPointer();
4409   for(int i=0;i<nbOfTuple;i++)
4410     {
4411       double sum=0.;
4412       for(int j=0;j<nbOfComp;j++)
4413         sum+=a1Ptr[i*nbOfComp+j]*a2Ptr[i*nbOfComp+j];
4414       retPtr[i]=sum;
4415     }
4416   ret->setInfoOnComponent(0,a1->getInfoOnComponent(0).c_str());
4417   ret->setName(a1->getName().c_str());
4418   return ret;
4419 }
4420
4421 /*!
4422  * Returns a new DataArrayDouble containing a cross product of two given arrays, so that
4423  * the i-th tuple of the result array contains 3 components of a vector which is a cross
4424  * product of two vectors defined by the i-th tuples of given arrays.
4425  * Info on components is copied from the first of the given arrays.
4426  * Number of tuples in the given arrays must be the same.
4427  * Number of components in the given arrays must be 3.
4428  *  \param [in] a1 - a given array.
4429  *  \param [in] a2 - another given array.
4430  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4431  *          The caller is to delete this result array using decrRef() as it is no more
4432  *          needed.
4433  *  \throw If either \a a1 or \a a2 is NULL.
4434  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
4435  *  \throw If \a a1->getNumberOfComponents() != 3
4436  *  \throw If \a a2->getNumberOfComponents() != 3
4437  */
4438 DataArrayDouble *DataArrayDouble::CrossProduct(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception)
4439 {
4440   if(!a1 || !a2)
4441     throw INTERP_KERNEL::Exception("DataArrayDouble::CrossProduct : input DataArrayDouble instance is NULL !");
4442   int nbOfComp=a1->getNumberOfComponents();
4443   if(nbOfComp!=a2->getNumberOfComponents())
4444     throw INTERP_KERNEL::Exception("Nb of components mismatch for array crossProduct !");
4445   if(nbOfComp!=3)
4446     throw INTERP_KERNEL::Exception("Nb of components must be equal to 3 for array crossProduct !");
4447   int nbOfTuple=a1->getNumberOfTuples();
4448   if(nbOfTuple!=a2->getNumberOfTuples())
4449     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array crossProduct !");
4450   DataArrayDouble *ret=DataArrayDouble::New();
4451   ret->alloc(nbOfTuple,3);
4452   double *retPtr=ret->getPointer();
4453   const double *a1Ptr=a1->getConstPointer();
4454   const double *a2Ptr=a2->getConstPointer();
4455   for(int i=0;i<nbOfTuple;i++)
4456     {
4457       retPtr[3*i]=a1Ptr[3*i+1]*a2Ptr[3*i+2]-a1Ptr[3*i+2]*a2Ptr[3*i+1];
4458       retPtr[3*i+1]=a1Ptr[3*i+2]*a2Ptr[3*i]-a1Ptr[3*i]*a2Ptr[3*i+2];
4459       retPtr[3*i+2]=a1Ptr[3*i]*a2Ptr[3*i+1]-a1Ptr[3*i+1]*a2Ptr[3*i];
4460     }
4461   ret->copyStringInfoFrom(*a1);
4462   return ret;
4463 }
4464
4465 /*!
4466  * Returns a new DataArrayDouble containing maximal values of two given arrays.
4467  * Info on components is copied from the first of the given arrays.
4468  * Number of tuples and components in the given arrays must be the same.
4469  *  \param [in] a1 - an array to compare values with another one.
4470  *  \param [in] a2 - another array to compare values with the first one.
4471  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4472  *          The caller is to delete this result array using decrRef() as it is no more
4473  *          needed.
4474  *  \throw If either \a a1 or \a a2 is NULL.
4475  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
4476  *  \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents()
4477  */
4478 DataArrayDouble *DataArrayDouble::Max(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception)
4479 {
4480   if(!a1 || !a2)
4481     throw INTERP_KERNEL::Exception("DataArrayDouble::Max : input DataArrayDouble instance is NULL !");
4482   int nbOfComp=a1->getNumberOfComponents();
4483   if(nbOfComp!=a2->getNumberOfComponents())
4484     throw INTERP_KERNEL::Exception("Nb of components mismatch for array Max !");
4485   int nbOfTuple=a1->getNumberOfTuples();
4486   if(nbOfTuple!=a2->getNumberOfTuples())
4487     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Max !");
4488   DataArrayDouble *ret=DataArrayDouble::New();
4489   ret->alloc(nbOfTuple,nbOfComp);
4490   double *retPtr=ret->getPointer();
4491   const double *a1Ptr=a1->getConstPointer();
4492   const double *a2Ptr=a2->getConstPointer();
4493   int nbElem=nbOfTuple*nbOfComp;
4494   for(int i=0;i<nbElem;i++)
4495     retPtr[i]=std::max(a1Ptr[i],a2Ptr[i]);
4496   ret->copyStringInfoFrom(*a1);
4497   return ret;
4498 }
4499
4500 /*!
4501  * Returns a new DataArrayDouble containing minimal values of two given arrays.
4502  * Info on components is copied from the first of the given arrays.
4503  * Number of tuples and components in the given arrays must be the same.
4504  *  \param [in] a1 - an array to compare values with another one.
4505  *  \param [in] a2 - another array to compare values with the first one.
4506  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4507  *          The caller is to delete this result array using decrRef() as it is no more
4508  *          needed.
4509  *  \throw If either \a a1 or \a a2 is NULL.
4510  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
4511  *  \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents()
4512  */
4513 DataArrayDouble *DataArrayDouble::Min(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception)
4514 {
4515   if(!a1 || !a2)
4516     throw INTERP_KERNEL::Exception("DataArrayDouble::Min : input DataArrayDouble instance is NULL !");
4517   int nbOfComp=a1->getNumberOfComponents();
4518   if(nbOfComp!=a2->getNumberOfComponents())
4519     throw INTERP_KERNEL::Exception("Nb of components mismatch for array min !");
4520   int nbOfTuple=a1->getNumberOfTuples();
4521   if(nbOfTuple!=a2->getNumberOfTuples())
4522     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array min !");
4523   DataArrayDouble *ret=DataArrayDouble::New();
4524   ret->alloc(nbOfTuple,nbOfComp);
4525   double *retPtr=ret->getPointer();
4526   const double *a1Ptr=a1->getConstPointer();
4527   const double *a2Ptr=a2->getConstPointer();
4528   int nbElem=nbOfTuple*nbOfComp;
4529   for(int i=0;i<nbElem;i++)
4530     retPtr[i]=std::min(a1Ptr[i],a2Ptr[i]);
4531   ret->copyStringInfoFrom(*a1);
4532   return ret;
4533 }
4534
4535 /*!
4536  * Returns a new DataArrayDouble that is a sum of two given arrays. There are 3
4537  * valid cases.
4538  * 1.  The arrays have same number of tuples and components. Then each value of
4539  *   the result array (_a_) is a sum of the corresponding values of \a a1 and \a a2,
4540  *   i.e.: _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ i, j ].
4541  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
4542  *   component. Then
4543  *   _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ i, 0 ].
4544  * 3.  The arrays have same number of components and one array, say _a2_, has one
4545  *   tuple. Then
4546  *   _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ 0, j ].
4547  *
4548  * Info on components is copied either from the first array (in the first case) or from
4549  * the array with maximal number of elements (getNbOfElems()).
4550  *  \param [in] a1 - an array to sum up.
4551  *  \param [in] a2 - another array to sum up.
4552  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4553  *          The caller is to delete this result array using decrRef() as it is no more
4554  *          needed.
4555  *  \throw If either \a a1 or \a a2 is NULL.
4556  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
4557  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
4558  *         none of them has number of tuples or components equal to 1.
4559  */
4560 DataArrayDouble *DataArrayDouble::Add(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception)
4561 {
4562   if(!a1 || !a2)
4563     throw INTERP_KERNEL::Exception("DataArrayDouble::Add : input DataArrayDouble instance is NULL !");
4564   int nbOfTuple=a1->getNumberOfTuples();
4565   int nbOfTuple2=a2->getNumberOfTuples();
4566   int nbOfComp=a1->getNumberOfComponents();
4567   int nbOfComp2=a2->getNumberOfComponents();
4568   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=0;
4569   if(nbOfTuple==nbOfTuple2)
4570     {
4571       if(nbOfComp==nbOfComp2)
4572         {
4573           ret=DataArrayDouble::New();
4574           ret->alloc(nbOfTuple,nbOfComp);
4575           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::plus<double>());
4576           ret->copyStringInfoFrom(*a1);
4577         }
4578       else
4579         {
4580           int nbOfCompMin,nbOfCompMax;
4581           const DataArrayDouble *aMin, *aMax;
4582           if(nbOfComp>nbOfComp2)
4583             {
4584               nbOfCompMin=nbOfComp2; nbOfCompMax=nbOfComp;
4585               aMin=a2; aMax=a1;
4586             }
4587           else
4588             {
4589               nbOfCompMin=nbOfComp; nbOfCompMax=nbOfComp2;
4590               aMin=a1; aMax=a2;
4591             }
4592           if(nbOfCompMin==1)
4593             {
4594               ret=DataArrayDouble::New();
4595               ret->alloc(nbOfTuple,nbOfCompMax);
4596               const double *aMinPtr=aMin->getConstPointer();
4597               const double *aMaxPtr=aMax->getConstPointer();
4598               double *res=ret->getPointer();
4599               for(int i=0;i<nbOfTuple;i++)
4600                 res=std::transform(aMaxPtr+i*nbOfCompMax,aMaxPtr+(i+1)*nbOfCompMax,res,std::bind2nd(std::plus<double>(),aMinPtr[i]));
4601               ret->copyStringInfoFrom(*aMax);
4602             }
4603           else
4604             throw INTERP_KERNEL::Exception("Nb of components mismatch for array Add !");
4605         }
4606     }
4607   else if((nbOfTuple==1 && nbOfTuple2>1) || (nbOfTuple>1 && nbOfTuple2==1))
4608     {
4609       if(nbOfComp==nbOfComp2)
4610         {
4611           int nbOfTupleMax=std::max(nbOfTuple,nbOfTuple2);
4612           const DataArrayDouble *aMin=nbOfTuple>nbOfTuple2?a2:a1;
4613           const DataArrayDouble *aMax=nbOfTuple>nbOfTuple2?a1:a2;
4614           const double *aMinPtr=aMin->getConstPointer(),*aMaxPtr=aMax->getConstPointer();
4615           ret=DataArrayDouble::New();
4616           ret->alloc(nbOfTupleMax,nbOfComp);
4617           double *res=ret->getPointer();
4618           for(int i=0;i<nbOfTupleMax;i++)
4619             res=std::transform(aMaxPtr+i*nbOfComp,aMaxPtr+(i+1)*nbOfComp,aMinPtr,res,std::plus<double>());
4620           ret->copyStringInfoFrom(*aMax);
4621         }
4622       else
4623         throw INTERP_KERNEL::Exception("Nb of components mismatch for array Add !");
4624     }
4625   else
4626     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Add !");
4627   return ret.retn();
4628 }
4629
4630 /*!
4631  * Adds values of another DataArrayDouble to values of \a this one. There are 3
4632  * valid cases.
4633  * 1.  The arrays have same number of tuples and components. Then each value of
4634  *   \a other array is added to the corresponding value of \a this array, i.e.:
4635  *   _a_ [ i, j ] += _other_ [ i, j ].
4636  * 2.  The arrays have same number of tuples and \a other array has one component. Then
4637  *   _a_ [ i, j ] += _other_ [ i, 0 ].
4638  * 3.  The arrays have same number of components and \a other array has one tuple. Then
4639  *   _a_ [ i, j ] += _a2_ [ 0, j ].
4640  *
4641  *  \param [in] other - an array to add to \a this one.
4642  *  \throw If \a other is NULL.
4643  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
4644  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
4645  *         \a other has number of both tuples and components not equal to 1.
4646  */
4647 void DataArrayDouble::addEqual(const DataArrayDouble *other) throw(INTERP_KERNEL::Exception)
4648 {
4649   if(!other)
4650     throw INTERP_KERNEL::Exception("DataArrayDouble::addEqual : input DataArrayDouble instance is NULL !");
4651   const char *msg="Nb of tuples mismatch for DataArrayDouble::addEqual  !";
4652   checkAllocated();
4653   other->checkAllocated();
4654   int nbOfTuple=getNumberOfTuples();
4655   int nbOfTuple2=other->getNumberOfTuples();
4656   int nbOfComp=getNumberOfComponents();
4657   int nbOfComp2=other->getNumberOfComponents();
4658   if(nbOfTuple==nbOfTuple2)
4659     {
4660       if(nbOfComp==nbOfComp2)
4661         {
4662           std::transform(begin(),end(),other->begin(),getPointer(),std::plus<double>());
4663         }
4664       else if(nbOfComp2==1)
4665         {
4666           double *ptr=getPointer();
4667           const double *ptrc=other->getConstPointer();
4668           for(int i=0;i<nbOfTuple;i++)
4669             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::plus<double>(),*ptrc++));
4670         }
4671       else
4672         throw INTERP_KERNEL::Exception(msg);
4673     }
4674   else if(nbOfTuple2==1)
4675     {
4676       if(nbOfComp2==nbOfComp)
4677         {
4678           double *ptr=getPointer();
4679           const double *ptrc=other->getConstPointer();
4680           for(int i=0;i<nbOfTuple;i++)
4681             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::plus<double>());
4682         }
4683       else
4684         throw INTERP_KERNEL::Exception(msg);
4685     }
4686   else
4687     throw INTERP_KERNEL::Exception(msg);
4688   declareAsNew();
4689 }
4690
4691 /*!
4692  * Returns a new DataArrayDouble that is a subtraction of two given arrays. There are 3
4693  * valid cases.
4694  * 1.  The arrays have same number of tuples and components. Then each value of
4695  *   the result array (_a_) is a subtraction of the corresponding values of \a a1 and
4696  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ i, j ].
4697  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
4698  *   component. Then
4699  *   _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ i, 0 ].
4700  * 3.  The arrays have same number of components and one array, say _a2_, has one
4701  *   tuple. Then
4702  *   _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ 0, j ].
4703  *
4704  * Info on components is copied either from the first array (in the first case) or from
4705  * the array with maximal number of elements (getNbOfElems()).
4706  *  \param [in] a1 - an array to subtract from.
4707  *  \param [in] a2 - an array to subtract.
4708  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4709  *          The caller is to delete this result array using decrRef() as it is no more
4710  *          needed.
4711  *  \throw If either \a a1 or \a a2 is NULL.
4712  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
4713  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
4714  *         none of them has number of tuples or components equal to 1.
4715  */
4716 DataArrayDouble *DataArrayDouble::Substract(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception)
4717 {
4718   if(!a1 || !a2)
4719     throw INTERP_KERNEL::Exception("DataArrayDouble::Substract : input DataArrayDouble instance is NULL !");
4720   int nbOfTuple1=a1->getNumberOfTuples();
4721   int nbOfTuple2=a2->getNumberOfTuples();
4722   int nbOfComp1=a1->getNumberOfComponents();
4723   int nbOfComp2=a2->getNumberOfComponents();
4724   if(nbOfTuple2==nbOfTuple1)
4725     {
4726       if(nbOfComp1==nbOfComp2)
4727         {
4728           MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
4729           ret->alloc(nbOfTuple2,nbOfComp1);
4730           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::minus<double>());
4731           ret->copyStringInfoFrom(*a1);
4732           return ret.retn();
4733         }
4734       else if(nbOfComp2==1)
4735         {
4736           MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
4737           ret->alloc(nbOfTuple1,nbOfComp1);
4738           const double *a2Ptr=a2->getConstPointer();
4739           const double *a1Ptr=a1->getConstPointer();
4740           double *res=ret->getPointer();
4741           for(int i=0;i<nbOfTuple1;i++)
4742             res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::minus<double>(),a2Ptr[i]));
4743           ret->copyStringInfoFrom(*a1);
4744           return ret.retn();
4745         }
4746       else
4747         {
4748           a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Substract !");
4749           return 0;
4750         }
4751     }
4752   else if(nbOfTuple2==1)
4753     {
4754       a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Substract !");
4755       MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
4756       ret->alloc(nbOfTuple1,nbOfComp1);
4757       const double *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
4758       double *pt=ret->getPointer();
4759       for(int i=0;i<nbOfTuple1;i++)
4760         pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::minus<double>());
4761       ret->copyStringInfoFrom(*a1);
4762       return ret.retn();
4763     }
4764   else
4765     {
4766       a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Substract !");//will always throw an exception
4767       return 0;
4768     }
4769 }
4770
4771 /*!
4772  * Subtract values of another DataArrayDouble from values of \a this one. There are 3
4773  * valid cases.
4774  * 1.  The arrays have same number of tuples and components. Then each value of
4775  *   \a other array is subtracted from the corresponding value of \a this array, i.e.:
4776  *   _a_ [ i, j ] -= _other_ [ i, j ].
4777  * 2.  The arrays have same number of tuples and \a other array has one component. Then
4778  *   _a_ [ i, j ] -= _other_ [ i, 0 ].
4779  * 3.  The arrays have same number of components and \a other array has one tuple. Then
4780  *   _a_ [ i, j ] -= _a2_ [ 0, j ].
4781  *
4782  *  \param [in] other - an array to subtract from \a this one.
4783  *  \throw If \a other is NULL.
4784  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
4785  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
4786  *         \a other has number of both tuples and components not equal to 1.
4787  */
4788 void DataArrayDouble::substractEqual(const DataArrayDouble *other) throw(INTERP_KERNEL::Exception)
4789 {
4790   if(!other)
4791     throw INTERP_KERNEL::Exception("DataArrayDouble::substractEqual : input DataArrayDouble instance is NULL !");
4792   const char *msg="Nb of tuples mismatch for DataArrayDouble::substractEqual  !";
4793   checkAllocated();
4794   other->checkAllocated();
4795   int nbOfTuple=getNumberOfTuples();
4796   int nbOfTuple2=other->getNumberOfTuples();
4797   int nbOfComp=getNumberOfComponents();
4798   int nbOfComp2=other->getNumberOfComponents();
4799   if(nbOfTuple==nbOfTuple2)
4800     {
4801       if(nbOfComp==nbOfComp2)
4802         {
4803           std::transform(begin(),end(),other->begin(),getPointer(),std::minus<double>());
4804         }
4805       else if(nbOfComp2==1)
4806         {
4807           double *ptr=getPointer();
4808           const double *ptrc=other->getConstPointer();
4809           for(int i=0;i<nbOfTuple;i++)
4810             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::minus<double>(),*ptrc++)); 
4811         }
4812       else
4813         throw INTERP_KERNEL::Exception(msg);
4814     }
4815   else if(nbOfTuple2==1)
4816     {
4817       if(nbOfComp2==nbOfComp)
4818         {
4819           double *ptr=getPointer();
4820           const double *ptrc=other->getConstPointer();
4821           for(int i=0;i<nbOfTuple;i++)
4822             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::minus<double>());
4823         }
4824       else
4825         throw INTERP_KERNEL::Exception(msg);
4826     }
4827   else
4828     throw INTERP_KERNEL::Exception(msg);
4829   declareAsNew();
4830 }
4831
4832 /*!
4833  * Returns a new DataArrayDouble that is a product of two given arrays. There are 3
4834  * valid cases.
4835  * 1.  The arrays have same number of tuples and components. Then each value of
4836  *   the result array (_a_) is a product of the corresponding values of \a a1 and
4837  *   \a a2, i.e. _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ i, j ].
4838  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
4839  *   component. Then
4840  *   _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ i, 0 ].
4841  * 3.  The arrays have same number of components and one array, say _a2_, has one
4842  *   tuple. Then
4843  *   _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ 0, j ].
4844  *
4845  * Info on components is copied either from the first array (in the first case) or from
4846  * the array with maximal number of elements (getNbOfElems()).
4847  *  \param [in] a1 - a factor array.
4848  *  \param [in] a2 - another factor array.
4849  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4850  *          The caller is to delete this result array using decrRef() as it is no more
4851  *          needed.
4852  *  \throw If either \a a1 or \a a2 is NULL.
4853  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
4854  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
4855  *         none of them has number of tuples or components equal to 1.
4856  */
4857 DataArrayDouble *DataArrayDouble::Multiply(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception)
4858 {
4859   if(!a1 || !a2)
4860     throw INTERP_KERNEL::Exception("DataArrayDouble::Multiply : input DataArrayDouble instance is NULL !");
4861   int nbOfTuple=a1->getNumberOfTuples();
4862   int nbOfTuple2=a2->getNumberOfTuples();
4863   int nbOfComp=a1->getNumberOfComponents();
4864   int nbOfComp2=a2->getNumberOfComponents();
4865   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=0;
4866   if(nbOfTuple==nbOfTuple2)
4867     {
4868       if(nbOfComp==nbOfComp2)
4869         {
4870           ret=DataArrayDouble::New();
4871           ret->alloc(nbOfTuple,nbOfComp);
4872           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::multiplies<double>());
4873           ret->copyStringInfoFrom(*a1);
4874         }
4875       else
4876         {
4877           int nbOfCompMin,nbOfCompMax;
4878           const DataArrayDouble *aMin, *aMax;
4879           if(nbOfComp>nbOfComp2)
4880             {
4881               nbOfCompMin=nbOfComp2; nbOfCompMax=nbOfComp;
4882               aMin=a2; aMax=a1;
4883             }
4884           else
4885             {
4886               nbOfCompMin=nbOfComp; nbOfCompMax=nbOfComp2;
4887               aMin=a1; aMax=a2;
4888             }
4889           if(nbOfCompMin==1)
4890             {
4891               ret=DataArrayDouble::New();
4892               ret->alloc(nbOfTuple,nbOfCompMax);
4893               const double *aMinPtr=aMin->getConstPointer();
4894               const double *aMaxPtr=aMax->getConstPointer();
4895               double *res=ret->getPointer();
4896               for(int i=0;i<nbOfTuple;i++)
4897                 res=std::transform(aMaxPtr+i*nbOfCompMax,aMaxPtr+(i+1)*nbOfCompMax,res,std::bind2nd(std::multiplies<double>(),aMinPtr[i]));
4898               ret->copyStringInfoFrom(*aMax);
4899             }
4900           else
4901             throw INTERP_KERNEL::Exception("Nb of components mismatch for array Multiply !");
4902         }
4903     }
4904   else if((nbOfTuple==1 && nbOfTuple2>1) || (nbOfTuple>1 && nbOfTuple2==1))
4905     {
4906       if(nbOfComp==nbOfComp2)
4907         {
4908           int nbOfTupleMax=std::max(nbOfTuple,nbOfTuple2);
4909           const DataArrayDouble *aMin=nbOfTuple>nbOfTuple2?a2:a1;
4910           const DataArrayDouble *aMax=nbOfTuple>nbOfTuple2?a1:a2;
4911           const double *aMinPtr=aMin->getConstPointer(),*aMaxPtr=aMax->getConstPointer();
4912           ret=DataArrayDouble::New();
4913           ret->alloc(nbOfTupleMax,nbOfComp);
4914           double *res=ret->getPointer();
4915           for(int i=0;i<nbOfTupleMax;i++)
4916             res=std::transform(aMaxPtr+i*nbOfComp,aMaxPtr+(i+1)*nbOfComp,aMinPtr,res,std::multiplies<double>());
4917           ret->copyStringInfoFrom(*aMax);
4918         }
4919       else
4920         throw INTERP_KERNEL::Exception("Nb of components mismatch for array Multiply !");
4921     }
4922   else
4923     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Multiply !");
4924   return ret.retn();
4925 }
4926
4927 /*!
4928  * Multiply values of another DataArrayDouble to values of \a this one. There are 3
4929  * valid cases.
4930  * 1.  The arrays have same number of tuples and components. Then each value of
4931  *   \a other array is multiplied to the corresponding value of \a this array, i.e.
4932  *   _this_ [ i, j ] *= _other_ [ i, j ].
4933  * 2.  The arrays have same number of tuples and \a other array has one component. Then
4934  *   _this_ [ i, j ] *= _other_ [ i, 0 ].
4935  * 3.  The arrays have same number of components and \a other array has one tuple. Then
4936  *   _this_ [ i, j ] *= _a2_ [ 0, j ].
4937  *
4938  *  \param [in] other - an array to multiply to \a this one.
4939  *  \throw If \a other is NULL.
4940  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
4941  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
4942  *         \a other has number of both tuples and components not equal to 1.
4943  */
4944 void DataArrayDouble::multiplyEqual(const DataArrayDouble *other) throw(INTERP_KERNEL::Exception)
4945 {
4946   if(!other)
4947     throw INTERP_KERNEL::Exception("DataArrayDouble::multiplyEqual : input DataArrayDouble instance is NULL !");
4948   const char *msg="Nb of tuples mismatch for DataArrayDouble::multiplyEqual !";
4949   checkAllocated();
4950   other->checkAllocated();
4951   int nbOfTuple=getNumberOfTuples();
4952   int nbOfTuple2=other->getNumberOfTuples();
4953   int nbOfComp=getNumberOfComponents();
4954   int nbOfComp2=other->getNumberOfComponents();
4955   if(nbOfTuple==nbOfTuple2)
4956     {
4957       if(nbOfComp==nbOfComp2)
4958         {
4959           std::transform(begin(),end(),other->begin(),getPointer(),std::multiplies<double>());
4960         }
4961       else if(nbOfComp2==1)
4962         {
4963           double *ptr=getPointer();
4964           const double *ptrc=other->getConstPointer();
4965           for(int i=0;i<nbOfTuple;i++)
4966             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::multiplies<double>(),*ptrc++));
4967         }
4968       else
4969         throw INTERP_KERNEL::Exception(msg);
4970     }
4971   else if(nbOfTuple2==1)
4972     {
4973       if(nbOfComp2==nbOfComp)
4974         {
4975           double *ptr=getPointer();
4976           const double *ptrc=other->getConstPointer();
4977           for(int i=0;i<nbOfTuple;i++)
4978             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::multiplies<double>());
4979         }
4980       else
4981         throw INTERP_KERNEL::Exception(msg);
4982     }
4983   else
4984     throw INTERP_KERNEL::Exception(msg);
4985   declareAsNew();
4986 }
4987
4988 /*!
4989  * Returns a new DataArrayDouble that is a division of two given arrays. There are 3
4990  * valid cases.
4991  * 1.  The arrays have same number of tuples and components. Then each value of
4992  *   the result array (_a_) is a division of the corresponding values of \a a1 and
4993  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ i, j ].
4994  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
4995  *   component. Then
4996  *   _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ i, 0 ].
4997  * 3.  The arrays have same number of components and one array, say _a2_, has one
4998  *   tuple. Then
4999  *   _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ 0, j ].
5000  *
5001  * Info on components is copied either from the first array (in the first case) or from
5002  * the array with maximal number of elements (getNbOfElems()).
5003  *  \warning No check of division by zero is performed!
5004  *  \param [in] a1 - a numerator array.
5005  *  \param [in] a2 - a denominator array.
5006  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
5007  *          The caller is to delete this result array using decrRef() as it is no more
5008  *          needed.
5009  *  \throw If either \a a1 or \a a2 is NULL.
5010  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
5011  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
5012  *         none of them has number of tuples or components equal to 1.
5013  */
5014 DataArrayDouble *DataArrayDouble::Divide(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception)
5015 {
5016   if(!a1 || !a2)
5017     throw INTERP_KERNEL::Exception("DataArrayDouble::Divide : input DataArrayDouble instance is NULL !");
5018   int nbOfTuple1=a1->getNumberOfTuples();
5019   int nbOfTuple2=a2->getNumberOfTuples();
5020   int nbOfComp1=a1->getNumberOfComponents();
5021   int nbOfComp2=a2->getNumberOfComponents();
5022   if(nbOfTuple2==nbOfTuple1)
5023     {
5024       if(nbOfComp1==nbOfComp2)
5025         {
5026           MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
5027           ret->alloc(nbOfTuple2,nbOfComp1);
5028           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::divides<double>());
5029           ret->copyStringInfoFrom(*a1);
5030           return ret.retn();
5031         }
5032       else if(nbOfComp2==1)
5033         {
5034           MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
5035           ret->alloc(nbOfTuple1,nbOfComp1);
5036           const double *a2Ptr=a2->getConstPointer();
5037           const double *a1Ptr=a1->getConstPointer();
5038           double *res=ret->getPointer();
5039           for(int i=0;i<nbOfTuple1;i++)
5040             res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::divides<double>(),a2Ptr[i]));
5041           ret->copyStringInfoFrom(*a1);
5042           return ret.retn();
5043         }
5044       else
5045         {
5046           a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Divide !");
5047           return 0;
5048         }
5049     }
5050   else if(nbOfTuple2==1)
5051     {
5052       a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Divide !");
5053       MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
5054       ret->alloc(nbOfTuple1,nbOfComp1);
5055       const double *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
5056       double *pt=ret->getPointer();
5057       for(int i=0;i<nbOfTuple1;i++)
5058         pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::divides<double>());
5059       ret->copyStringInfoFrom(*a1);
5060       return ret.retn();
5061     }
5062   else
5063     {
5064       a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Divide !");//will always throw an exception
5065       return 0;
5066     }
5067 }
5068
5069 /*!
5070  * Divide values of \a this array by values of another DataArrayDouble. There are 3
5071  * valid cases.
5072  * 1.  The arrays have same number of tuples and components. Then each value of
5073  *    \a this array is divided by the corresponding value of \a other one, i.e.:
5074  *   _a_ [ i, j ] /= _other_ [ i, j ].
5075  * 2.  The arrays have same number of tuples and \a other array has one component. Then
5076  *   _a_ [ i, j ] /= _other_ [ i, 0 ].
5077  * 3.  The arrays have same number of components and \a other array has one tuple. Then
5078  *   _a_ [ i, j ] /= _a2_ [ 0, j ].
5079  *
5080  *  \warning No check of division by zero is performed!
5081  *  \param [in] other - an array to divide \a this one by.
5082  *  \throw If \a other is NULL.
5083  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
5084  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
5085  *         \a other has number of both tuples and components not equal to 1.
5086  */
5087 void DataArrayDouble::divideEqual(const DataArrayDouble *other) throw(INTERP_KERNEL::Exception)
5088 {
5089   if(!other)
5090     throw INTERP_KERNEL::Exception("DataArrayDouble::divideEqual : input DataArrayDouble instance is NULL !");
5091   const char *msg="Nb of tuples mismatch for DataArrayDouble::divideEqual !";
5092   checkAllocated();
5093   other->checkAllocated();
5094   int nbOfTuple=getNumberOfTuples();
5095   int nbOfTuple2=other->getNumberOfTuples();
5096   int nbOfComp=getNumberOfComponents();
5097   int nbOfComp2=other->getNumberOfComponents();
5098   if(nbOfTuple==nbOfTuple2)
5099     {
5100       if(nbOfComp==nbOfComp2)
5101         {
5102           std::transform(begin(),end(),other->begin(),getPointer(),std::divides<double>());
5103         }
5104       else if(nbOfComp2==1)
5105         {
5106           double *ptr=getPointer();
5107           const double *ptrc=other->getConstPointer();
5108           for(int i=0;i<nbOfTuple;i++)
5109             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::divides<double>(),*ptrc++));
5110         }
5111       else
5112         throw INTERP_KERNEL::Exception(msg);
5113     }
5114   else if(nbOfTuple2==1)
5115     {
5116       if(nbOfComp2==nbOfComp)
5117         {
5118           double *ptr=getPointer();
5119           const double *ptrc=other->getConstPointer();
5120           for(int i=0;i<nbOfTuple;i++)
5121             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::divides<double>());
5122         }
5123       else
5124         throw INTERP_KERNEL::Exception(msg);
5125     }
5126   else
5127     throw INTERP_KERNEL::Exception(msg);
5128   declareAsNew();
5129 }
5130
5131 /*!
5132  * Returns a new DataArrayDouble that is the result of pow of two given arrays. There are 3
5133  * valid cases.
5134  *
5135  *  \param [in] a1 - an array to pow up.
5136  *  \param [in] a2 - another array to sum up.
5137  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
5138  *          The caller is to delete this result array using decrRef() as it is no more
5139  *          needed.
5140  *  \throw If either \a a1 or \a a2 is NULL.
5141  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
5142  *  \throw If \a a1->getNumberOfComponents() != 1 or \a a2->getNumberOfComponents() != 1.
5143  *  \throw If there is a negative value in \a a1.
5144  */
5145 DataArrayDouble *DataArrayDouble::Pow(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception)
5146 {
5147   if(!a1 || !a2)
5148     throw INTERP_KERNEL::Exception("DataArrayDouble::Pow : at least one of input instances is null !");
5149   int nbOfTuple=a1->getNumberOfTuples();
5150   int nbOfTuple2=a2->getNumberOfTuples();
5151   int nbOfComp=a1->getNumberOfComponents();
5152   int nbOfComp2=a2->getNumberOfComponents();
5153   if(nbOfTuple!=nbOfTuple2)
5154     throw INTERP_KERNEL::Exception("DataArrayDouble::Pow : number of tuples mismatches !");
5155   if(nbOfComp!=1 || nbOfComp2!=1)
5156     throw INTERP_KERNEL::Exception("DataArrayDouble::Pow : number of components of both arrays must be equal to 1 !");
5157   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New(); ret->alloc(nbOfTuple,1);
5158   const double *ptr1(a1->begin()),*ptr2(a2->begin());
5159   double *ptr=ret->getPointer();
5160   for(int i=0;i<nbOfTuple;i++,ptr1++,ptr2++,ptr++)
5161     {
5162       if(*ptr1>=0)
5163         {
5164           *ptr=pow(*ptr1,*ptr2);
5165         }
5166       else
5167         {
5168           std::ostringstream oss; oss << "DataArrayDouble::Pow : on tuple #" << i << " of a1 value is < 0 (" << *ptr1 << ") !";
5169           throw INTERP_KERNEL::Exception(oss.str().c_str());
5170         }
5171     }
5172   return ret.retn();
5173 }
5174
5175 /*!
5176  * Apply pow on values of another DataArrayDouble to values of \a this one.
5177  *
5178  *  \param [in] other - an array to pow to \a this one.
5179  *  \throw If \a other is NULL.
5180  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples()
5181  *  \throw If \a this->getNumberOfComponents() != 1 or \a other->getNumberOfComponents() != 1
5182  *  \throw If there is a negative value in \a this.
5183  */
5184 void DataArrayDouble::powEqual(const DataArrayDouble *other) throw(INTERP_KERNEL::Exception)
5185 {
5186   if(!other)
5187     throw INTERP_KERNEL::Exception("DataArrayDouble::powEqual : input instance is null !");
5188   int nbOfTuple=getNumberOfTuples();
5189   int nbOfTuple2=other->getNumberOfTuples();
5190   int nbOfComp=getNumberOfComponents();
5191   int nbOfComp2=other->getNumberOfComponents();
5192   if(nbOfTuple!=nbOfTuple2)
5193     throw INTERP_KERNEL::Exception("DataArrayDouble::powEqual : number of tuples mismatches !");
5194   if(nbOfComp!=1 || nbOfComp2!=1)
5195     throw INTERP_KERNEL::Exception("DataArrayDouble::powEqual : number of components of both arrays must be equal to 1 !");
5196   double *ptr=getPointer();
5197   const double *ptrc=other->begin();
5198   for(int i=0;i<nbOfTuple;i++,ptrc++,ptr++)
5199     {
5200       if(*ptr>=0)
5201         *ptr=pow(*ptr,*ptrc);
5202       else
5203         {
5204           std::ostringstream oss; oss << "DataArrayDouble::powEqual : on tuple #" << i << " of this value is < 0 (" << *ptr << ") !";
5205           throw INTERP_KERNEL::Exception(oss.str().c_str());
5206         }
5207     }
5208   declareAsNew();
5209 }
5210
5211 /*!
5212  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
5213  * Server side.
5214  */
5215 void DataArrayDouble::getTinySerializationIntInformation(std::vector<int>& tinyInfo) const
5216 {
5217   tinyInfo.resize(2);
5218   if(isAllocated())
5219     {
5220       tinyInfo[0]=getNumberOfTuples();
5221       tinyInfo[1]=getNumberOfComponents();
5222     }
5223   else
5224     {
5225       tinyInfo[0]=-1;
5226       tinyInfo[1]=-1;
5227     }
5228 }
5229
5230 /*!
5231  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
5232  * Server side.
5233  */
5234 void DataArrayDouble::getTinySerializationStrInformation(std::vector<std::string>& tinyInfo) const
5235 {
5236   if(isAllocated())
5237     {
5238       int nbOfCompo=getNumberOfComponents();
5239       tinyInfo.resize(nbOfCompo+1);
5240       tinyInfo[0]=getName();
5241       for(int i=0;i<nbOfCompo;i++)
5242         tinyInfo[i+1]=getInfoOnComponent(i);
5243     }
5244   else
5245     {
5246       tinyInfo.resize(1);
5247       tinyInfo[0]=getName();
5248     }
5249 }
5250
5251 /*!
5252  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
5253  * This method returns if a feeding is needed.
5254  */
5255 bool DataArrayDouble::resizeForUnserialization(const std::vector<int>& tinyInfoI)
5256 {
5257   int nbOfTuple=tinyInfoI[0];
5258   int nbOfComp=tinyInfoI[1];
5259   if(nbOfTuple!=-1 || nbOfComp!=-1)
5260     {
5261       alloc(nbOfTuple,nbOfComp);
5262       return true;
5263     }
5264   return false;
5265 }
5266
5267 /*!
5268  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
5269  */
5270 void DataArrayDouble::finishUnserialization(const std::vector<int>& tinyInfoI, const std::vector<std::string>& tinyInfoS)
5271 {
5272   setName(tinyInfoS[0].c_str());
5273   if(isAllocated())
5274     {
5275       int nbOfCompo=getNumberOfComponents();
5276       for(int i=0;i<nbOfCompo;i++)
5277         setInfoOnComponent(i,tinyInfoS[i+1].c_str());
5278     }
5279 }
5280
5281 DataArrayDoubleIterator::DataArrayDoubleIterator(DataArrayDouble *da):_da(da),_tuple_id(0),_nb_comp(0),_nb_tuple(0)
5282 {
5283   if(_da)
5284     {
5285       _da->incrRef();
5286       if(_da->isAllocated())
5287         {
5288           _nb_comp=da->getNumberOfComponents();
5289           _nb_tuple=da->getNumberOfTuples();
5290           _pt=da->getPointer();
5291         }
5292     }
5293 }
5294
5295 DataArrayDoubleIterator::~DataArrayDoubleIterator()
5296 {
5297   if(_da)
5298     _da->decrRef();
5299 }
5300
5301 DataArrayDoubleTuple *DataArrayDoubleIterator::nextt() throw(INTERP_KERNEL::Exception)
5302 {
5303   if(_tuple_id<_nb_tuple)
5304     {
5305       _tuple_id++;
5306       DataArrayDoubleTuple *ret=new DataArrayDoubleTuple(_pt,_nb_comp);
5307       _pt+=_nb_comp;
5308       return ret;
5309     }
5310   else
5311     return 0;
5312 }
5313
5314 DataArrayDoubleTuple::DataArrayDoubleTuple(double *pt, int nbOfComp):_pt(pt),_nb_of_compo(nbOfComp)
5315 {
5316 }
5317
5318
5319 std::string DataArrayDoubleTuple::repr() const throw(INTERP_KERNEL::Exception)
5320 {
5321   std::ostringstream oss; oss.precision(17); oss << "(";
5322   for(int i=0;i<_nb_of_compo-1;i++)
5323     oss << _pt[i] << ", ";
5324   oss << _pt[_nb_of_compo-1] << ")";
5325   return oss.str();
5326 }
5327
5328 double DataArrayDoubleTuple::doubleValue() const throw(INTERP_KERNEL::Exception)
5329 {
5330   if(_nb_of_compo==1)
5331     return *_pt;
5332   throw INTERP_KERNEL::Exception("DataArrayDoubleTuple::doubleValue : DataArrayDoubleTuple instance has not exactly 1 component -> Not possible to convert it into a double precision float !");
5333 }
5334
5335 /*!
5336  * This method returns a newly allocated instance the caller should dealed with by a ParaMEDMEM::DataArrayDouble::decrRef.
5337  * This method performs \b no copy of data. The content is only referenced using ParaMEDMEM::DataArrayDouble::useArray with ownership set to \b false.
5338  * 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
5339  * \b nbOfCompo=1 and \bnbOfTuples==this->_nb_of_elem.
5340  */
5341 DataArrayDouble *DataArrayDoubleTuple::buildDADouble(int nbOfTuples, int nbOfCompo) const throw(INTERP_KERNEL::Exception)
5342 {
5343   if((_nb_of_compo==nbOfCompo && nbOfTuples==1) || (_nb_of_compo==nbOfTuples && nbOfCompo==1))
5344     {
5345       DataArrayDouble *ret=DataArrayDouble::New();
5346       ret->useExternalArrayWithRWAccess(_pt,nbOfTuples,nbOfCompo);
5347       return ret;
5348     }
5349   else
5350     {
5351       std::ostringstream oss; oss << "DataArrayDoubleTuple::buildDADouble : unable to build a requested DataArrayDouble instance with nbofTuple=" << nbOfTuples << " and nbOfCompo=" << nbOfCompo;
5352       oss << ".\nBecause the number of elements in this is " << _nb_of_compo << " !";
5353       throw INTERP_KERNEL::Exception(oss.str().c_str());
5354     }
5355 }
5356
5357 /*!
5358  * Returns a new instance of DataArrayInt. The caller is to delete this array
5359  * using decrRef() as it is no more needed. 
5360  */
5361 DataArrayInt *DataArrayInt::New()
5362 {
5363   return new DataArrayInt;
5364 }
5365
5366 /*!
5367  * Checks if raw data is allocated. Read more on the raw data
5368  * in \ref MEDCouplingArrayBasicsTuplesAndCompo "DataArrays infos" for more information.
5369  *  \return bool - \a true if the raw data is allocated, \a false else.
5370  */
5371 bool DataArrayInt::isAllocated() const throw(INTERP_KERNEL::Exception)
5372 {
5373   return getConstPointer()!=0;
5374 }
5375
5376 /*!
5377  * Checks if raw data is allocated and throws an exception if it is not the case.
5378  *  \throw If the raw data is not allocated.
5379  */
5380 void DataArrayInt::checkAllocated() const throw(INTERP_KERNEL::Exception)
5381 {
5382   if(!isAllocated())
5383     throw INTERP_KERNEL::Exception("DataArrayInt::checkAllocated : Array is defined but not allocated ! Call alloc or setValues method first !");
5384 }
5385
5386 std::size_t DataArrayInt::getHeapMemorySize() const
5387 {
5388   std::size_t sz=_mem.getNbOfElemAllocated();
5389   sz*=sizeof(int);
5390   return DataArray::getHeapMemorySize()+sz;
5391 }
5392
5393 /*!
5394  * Returns the only one value in \a this, if and only if number of elements
5395  * (nb of tuples * nb of components) is equal to 1, and that \a this is allocated.
5396  *  \return double - the sole value stored in \a this array.
5397  *  \throw If at least one of conditions stated above is not fulfilled.
5398  */
5399 int DataArrayInt::intValue() const throw(INTERP_KERNEL::Exception)
5400 {
5401   if(isAllocated())
5402     {
5403       if(getNbOfElems()==1)
5404         {
5405           return *getConstPointer();
5406         }
5407       else
5408         throw INTERP_KERNEL::Exception("DataArrayInt::intValue : DataArrayInt instance is allocated but number of elements is not equal to 1 !");
5409     }
5410   else
5411     throw INTERP_KERNEL::Exception("DataArrayInt::intValue : DataArrayInt instance is not allocated !");
5412 }
5413
5414 /*!
5415  * Returns an integer value characterizing \a this array, which is useful for a quick
5416  * comparison of many instances of DataArrayInt.
5417  *  \return int - the hash value.
5418  *  \throw If \a this is not allocated.
5419  */
5420 int DataArrayInt::getHashCode() const throw(INTERP_KERNEL::Exception)
5421 {
5422   checkAllocated();
5423   std::size_t nbOfElems=getNbOfElems();
5424   int ret=nbOfElems*65536;
5425   int delta=3;
5426   if(nbOfElems>48)
5427     delta=nbOfElems/8;
5428   int ret0=0;
5429   const int *pt=begin();
5430   for(std::size_t i=0;i<nbOfElems;i+=delta)
5431     ret0+=pt[i] & 0x1FFF;
5432   return ret+ret0;
5433 }
5434
5435 /*!
5436  * Checks the number of tuples.
5437  *  \return bool - \a true if getNumberOfTuples() == 0, \a false else.
5438  *  \throw If \a this is not allocated.
5439  */
5440 bool DataArrayInt::empty() const throw(INTERP_KERNEL::Exception)
5441 {
5442   checkAllocated();
5443   return getNumberOfTuples()==0;
5444 }
5445
5446 /*!
5447  * Returns a full copy of \a this. For more info on copying data arrays see
5448  * \ref MEDCouplingArrayBasicsCopyDeep.
5449  *  \return DataArrayInt * - a new instance of DataArrayInt.
5450  */
5451 DataArrayInt *DataArrayInt::deepCpy() const throw(INTERP_KERNEL::Exception)
5452 {
5453   return new DataArrayInt(*this);
5454 }
5455
5456 /*!
5457  * Returns either a \a deep or \a shallow copy of this array. For more info see
5458  * \ref MEDCouplingArrayBasicsCopyDeep and \ref MEDCouplingArrayBasicsCopyShallow.
5459  *  \param [in] dCpy - if \a true, a deep copy is returned, else, a shallow one.
5460  *  \return DataArrayInt * - either a new instance of DataArrayInt (if \a dCpy
5461  *          == \a true) or \a this instance (if \a dCpy == \a false).
5462  */
5463 DataArrayInt *DataArrayInt::performCpy(bool dCpy) const throw(INTERP_KERNEL::Exception)
5464 {
5465   if(dCpy)
5466     return deepCpy();
5467   else
5468     {
5469       incrRef();
5470       return const_cast<DataArrayInt *>(this);
5471     }
5472 }
5473
5474 /*!
5475  * Copies all the data from another DataArrayInt. For more info see
5476  * \ref MEDCouplingArrayBasicsCopyDeepAssign.
5477  *  \param [in] other - another instance of DataArrayInt to copy data from.
5478  *  \throw If the \a other is not allocated.
5479  */
5480 void DataArrayInt::cpyFrom(const DataArrayInt& other) throw(INTERP_KERNEL::Exception)
5481 {
5482   other.checkAllocated();
5483   int nbOfTuples=other.getNumberOfTuples();
5484   int nbOfComp=other.getNumberOfComponents();
5485   allocIfNecessary(nbOfTuples,nbOfComp);
5486   std::size_t nbOfElems=(std::size_t)nbOfTuples*nbOfComp;
5487   int *pt=getPointer();
5488   const int *ptI=other.getConstPointer();
5489   for(std::size_t i=0;i<nbOfElems;i++)
5490     pt[i]=ptI[i];
5491   copyStringInfoFrom(other);
5492 }
5493
5494 /*!
5495  * This method reserve nbOfElems elements in memory ( nbOfElems*4 bytes ) \b without impacting the number of tuples in \a this.
5496  * 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.
5497  * If \a this has not already been allocated, number of components is set to one.
5498  * This method allows to reduce number of reallocations on invokation of DataArrayInt::pushBackSilent and DataArrayInt::pushBackValsSilent on \a this.
5499  * 
5500  * \sa DataArrayInt::pack, DataArrayInt::pushBackSilent, DataArrayInt::pushBackValsSilent
5501  */
5502 void DataArrayInt::reserve(std::size_t nbOfElems) throw(INTERP_KERNEL::Exception)
5503 {
5504   int nbCompo=getNumberOfComponents();
5505   if(nbCompo==1)
5506     {
5507       _mem.reserve(nbOfElems);
5508     }
5509   else if(nbCompo==0)
5510     {
5511       _mem.reserve(nbOfElems);
5512       _info_on_compo.resize(1);
5513     }
5514   else
5515     throw INTERP_KERNEL::Exception("DataArrayInt::reserve : not available for DataArrayInt with number of components different than 1 !");
5516 }
5517
5518 /*!
5519  * 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
5520  * of counter. So the caller is expected to call TimeLabel::declareAsNew on \a this at the end of the push session.
5521  *
5522  * \param [in] val the value to be added in \a this
5523  * \throw If \a this has already been allocated with number of components different from one.
5524  * \sa DataArrayInt::pushBackValsSilent
5525  */
5526 void DataArrayInt::pushBackSilent(int val) throw(INTERP_KERNEL::Exception)
5527 {
5528   int nbCompo=getNumberOfComponents();
5529   if(nbCompo==1)
5530     _mem.pushBack(val);
5531   else if(nbCompo==0)
5532     {
5533       _info_on_compo.resize(1);
5534       _mem.pushBack(val);
5535     }
5536   else
5537     throw INTERP_KERNEL::Exception("DataArrayInt::pushBackSilent : not available for DataArrayInt with number of components different than 1 !");
5538 }
5539
5540 /*!
5541  * 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
5542  * of counter. So the caller is expected to call TimeLabel::declareAsNew on \a this at the end of the push session.
5543  *
5544  *  \param [in] valsBg - an array of values to push at the end of \this.
5545  *  \param [in] valsEnd - specifies the end of the array \a valsBg, so that
5546  *              the last value of \a valsBg is \a valsEnd[ -1 ].
5547  * \throw If \a this has already been allocated with number of components different from one.
5548  * \sa DataArrayInt::pushBackSilent
5549  */
5550 void DataArrayInt::pushBackValsSilent(const int *valsBg, const int *valsEnd) throw(INTERP_KERNEL::Exception)
5551 {
5552   int nbCompo=getNumberOfComponents();
5553   if(nbCompo==1)
5554     _mem.insertAtTheEnd(valsBg,valsEnd);
5555   else if(nbCompo==0)
5556     {
5557       _info_on_compo.resize(1);
5558       _mem.insertAtTheEnd(valsBg,valsEnd);
5559     }
5560   else
5561     throw INTERP_KERNEL::Exception("DataArrayInt::pushBackValsSilent : not available for DataArrayInt with number of components different than 1 !");
5562 }
5563
5564 /*!
5565  * This method returns silently ( without updating time label in \a this ) the last value, if any and suppress it.
5566  * \throw If \a this is already empty.
5567  * \throw If \a this has number of components different from one.
5568  */
5569 int DataArrayInt::popBackSilent() throw(INTERP_KERNEL::Exception)
5570 {
5571   if(getNumberOfComponents()==1)
5572     return _mem.popBack();
5573   else
5574     throw INTERP_KERNEL::Exception("DataArrayInt::popBackSilent : not available for DataArrayInt with number of components different than 1 !");
5575 }
5576
5577 /*!
5578  * 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.
5579  *
5580  * \sa DataArrayInt::getHeapMemorySize, DataArrayInt::reserve
5581  */
5582 void DataArrayInt::pack() const throw(INTERP_KERNEL::Exception)
5583 {
5584   _mem.pack();
5585 }
5586
5587 /*!
5588  * Allocates the raw data in memory. If exactly as same memory as needed already
5589  * allocated, it is not re-allocated.
5590  *  \param [in] nbOfTuple - number of tuples of data to allocate.
5591  *  \param [in] nbOfCompo - number of components of data to allocate.
5592  *  \throw If \a nbOfTuple < 0 or \a nbOfCompo < 0.
5593  */
5594 void DataArrayInt::allocIfNecessary(int nbOfTuple, int nbOfCompo) throw(INTERP_KERNEL::Exception)
5595 {
5596   if(isAllocated())
5597     {
5598       if(nbOfTuple!=getNumberOfTuples() || nbOfCompo!=getNumberOfComponents())
5599         alloc(nbOfTuple,nbOfCompo);
5600     }
5601   else
5602     alloc(nbOfTuple,nbOfCompo);
5603 }
5604
5605 /*!
5606  * Allocates the raw data in memory. If the memory was already allocated, then it is
5607  * freed and re-allocated. See an example of this method use
5608  * \ref MEDCouplingArraySteps1WC "here".
5609  *  \param [in] nbOfTuple - number of tuples of data to allocate.
5610  *  \param [in] nbOfCompo - number of components of data to allocate.
5611  *  \throw If \a nbOfTuple < 0 or \a nbOfCompo < 0.
5612  */
5613 void DataArrayInt::alloc(int nbOfTuple, int nbOfCompo) throw(INTERP_KERNEL::Exception)
5614 {
5615   if(nbOfTuple<0 || nbOfCompo<0)
5616     throw INTERP_KERNEL::Exception("DataArrayInt::alloc : request for negative length of data !");
5617   _info_on_compo.resize(nbOfCompo);
5618   _mem.alloc(nbOfCompo*(std::size_t)nbOfTuple);
5619   declareAsNew();
5620 }
5621
5622 /*!
5623  * Assign zero to all values in \a this array. To know more on filling arrays see
5624  * \ref MEDCouplingArrayFill.
5625  * \throw If \a this is not allocated.
5626  */
5627 void DataArrayInt::fillWithZero() throw(INTERP_KERNEL::Exception)
5628 {
5629   checkAllocated();
5630   _mem.fillWithValue(0);
5631   declareAsNew();
5632 }
5633
5634 /*!
5635  * Assign \a val to all values in \a this array. To know more on filling arrays see
5636  * \ref MEDCouplingArrayFill.
5637  *  \param [in] val - the value to fill with.
5638  *  \throw If \a this is not allocated.
5639  */
5640 void DataArrayInt::fillWithValue(int val) throw(INTERP_KERNEL::Exception)
5641 {
5642   checkAllocated();
5643   _mem.fillWithValue(val);
5644   declareAsNew();
5645 }
5646
5647 /*!
5648  * Set all values in \a this array so that the i-th element equals to \a init + i
5649  * (i starts from zero). To know more on filling arrays see \ref MEDCouplingArrayFill.
5650  *  \param [in] init - value to assign to the first element of array.
5651  *  \throw If \a this->getNumberOfComponents() != 1
5652  *  \throw If \a this is not allocated.
5653  */
5654 void DataArrayInt::iota(int init) throw(INTERP_KERNEL::Exception)
5655 {
5656   checkAllocated();
5657   if(getNumberOfComponents()!=1)
5658     throw INTERP_KERNEL::Exception("DataArrayInt::iota : works only for arrays with only one component, you can call 'rearrange' method before !");
5659   int *ptr=getPointer();
5660   int ntuples=getNumberOfTuples();
5661   for(int i=0;i<ntuples;i++)
5662     ptr[i]=init+i;
5663   declareAsNew();
5664 }
5665
5666 /*!
5667  * Returns a textual and human readable representation of \a this instance of
5668  * DataArrayInt. This text is shown when a DataArrayInt is printed in Python.
5669  *  \return std::string - text describing \a this DataArrayInt.
5670  */
5671 std::string DataArrayInt::repr() const throw(INTERP_KERNEL::Exception)
5672 {
5673   std::ostringstream ret;
5674   reprStream(ret);
5675   return ret.str();
5676 }
5677
5678 std::string DataArrayInt::reprZip() const throw(INTERP_KERNEL::Exception)
5679 {
5680   std::ostringstream ret;
5681   reprZipStream(ret);
5682   return ret.str();
5683 }
5684
5685 void DataArrayInt::writeVTK(std::ostream& ofs, int indent, const char *type, const char *nameInFile) const throw(INTERP_KERNEL::Exception)
5686 {
5687   checkAllocated();
5688   std::string idt(indent,' ');
5689   ofs << idt << "<DataArray type=\"" << type << "\" Name=\"" << nameInFile << "\" NumberOfComponents=\"" << getNumberOfComponents() << "\"";
5690   ofs << " format=\"ascii\" RangeMin=\"" << getMinValueInArray() << "\" RangeMax=\"" << getMaxValueInArray() << "\">\n" << idt;
5691   std::copy(begin(),end(),std::ostream_iterator<int>(ofs," "));
5692   ofs << std::endl << idt << "</DataArray>\n";
5693 }
5694
5695 void DataArrayInt::reprStream(std::ostream& stream) const throw(INTERP_KERNEL::Exception)
5696 {
5697   stream << "Name of int array : \"" << _name << "\"\n";
5698   reprWithoutNameStream(stream);
5699 }
5700
5701 void DataArrayInt::reprZipStream(std::ostream& stream) const throw(INTERP_KERNEL::Exception)
5702 {
5703   stream << "Name of int array : \"" << _name << "\"\n";
5704   reprZipWithoutNameStream(stream);
5705 }
5706
5707 void DataArrayInt::reprWithoutNameStream(std::ostream& stream) const throw(INTERP_KERNEL::Exception)
5708 {
5709   DataArray::reprWithoutNameStream(stream);
5710   _mem.repr(getNumberOfComponents(),stream);
5711 }
5712
5713 void DataArrayInt::reprZipWithoutNameStream(std::ostream& stream) const throw(INTERP_KERNEL::Exception)
5714 {
5715   DataArray::reprWithoutNameStream(stream);
5716   _mem.reprZip(getNumberOfComponents(),stream);
5717 }
5718
5719 void DataArrayInt::reprCppStream(const char *varName, std::ostream& stream) const throw(INTERP_KERNEL::Exception)
5720 {
5721   int nbTuples=getNumberOfTuples(),nbComp=getNumberOfComponents();
5722   const int *data=getConstPointer();
5723   stream << "DataArrayInt *" << varName << "=DataArrayInt::New();" << std::endl;
5724   if(nbTuples*nbComp>=1)
5725     {
5726       stream << "const int " << varName << "Data[" << nbTuples*nbComp << "]={";
5727       std::copy(data,data+nbTuples*nbComp-1,std::ostream_iterator<int>(stream,","));
5728       stream << data[nbTuples*nbComp-1] << "};" << std::endl;
5729       stream << varName << "->useArray(" << varName << "Data,false,CPP_DEALLOC," << nbTuples << "," << nbComp << ");" << std::endl;
5730     }
5731   else
5732     stream << varName << "->alloc(" << nbTuples << "," << nbComp << ");" << std::endl;
5733   stream << varName << "->setName(\"" << getName() << "\");" << std::endl;
5734 }
5735
5736 /*!
5737  * Method that gives a quick overvien of \a this for python.
5738  */
5739 void DataArrayInt::reprQuickOverview(std::ostream& stream) const throw(INTERP_KERNEL::Exception)
5740 {
5741   static const std::size_t MAX_NB_OF_BYTE_IN_REPR=300;
5742   stream << "DataArrayInt C++ instance at " << this << ". ";
5743   if(isAllocated())
5744     {
5745       int nbOfCompo=(int)_info_on_compo.size();
5746       if(nbOfCompo>=1)
5747         {
5748           int nbOfTuples=getNumberOfTuples();
5749           stream << "Number of tuples : " << nbOfTuples << ". Number of components : " << nbOfCompo << "." << std::endl;
5750           reprQuickOverviewData(stream,MAX_NB_OF_BYTE_IN_REPR);
5751         }
5752       else
5753         stream << "Number of components : 0.";
5754     }
5755   else
5756     stream << "*** No data allocated ****";
5757 }
5758
5759 void DataArrayInt::reprQuickOverviewData(std::ostream& stream, std::size_t maxNbOfByteInRepr) const throw(INTERP_KERNEL::Exception)
5760 {
5761   const int *data=begin();
5762   int nbOfTuples=getNumberOfTuples();
5763   int nbOfCompo=(int)_info_on_compo.size();
5764   std::ostringstream oss2; oss2 << "[";
5765   std::string oss2Str(oss2.str());
5766   bool isFinished=true;
5767   for(int i=0;i<nbOfTuples && isFinished;i++)
5768     {
5769       if(nbOfCompo>1)
5770         {
5771           oss2 << "(";
5772           for(int j=0;j<nbOfCompo;j++,data++)
5773             {
5774               oss2 << *data;
5775               if(j!=nbOfCompo-1) oss2 << ", ";
5776             }
5777           oss2 << ")";
5778         }
5779       else
5780         oss2 << *data++;
5781       if(i!=nbOfTuples-1) oss2 << ", ";
5782       std::string oss3Str(oss2.str());
5783       if(oss3Str.length()<maxNbOfByteInRepr)
5784         oss2Str=oss3Str;
5785       else
5786         isFinished=false;
5787     }
5788   stream << oss2Str;
5789   if(!isFinished)
5790     stream << "... ";
5791   stream << "]";
5792 }
5793
5794 /*!
5795  * Modifies \a this one-dimensional array so that each value \a v = \a indArrBg[ \a v ],
5796  * i.e. a current value is used as in index to get a new value from \a indArrBg.
5797  *  \param [in] indArrBg - pointer to the first element of array of new values to assign
5798  *         to \a this array.
5799  *  \param [in] indArrEnd - specifies the end of the array \a indArrBg, so that
5800  *              the last value of \a indArrBg is \a indArrEnd[ -1 ].
5801  *  \throw If \a this->getNumberOfComponents() != 1
5802  *  \throw If any value of \a this can't be used as a valid index for 
5803  *         [\a indArrBg, \a indArrEnd).
5804  */
5805 void DataArrayInt::transformWithIndArr(const int *indArrBg, const int *indArrEnd) throw(INTERP_KERNEL::Exception)
5806 {
5807   checkAllocated();
5808   if(getNumberOfComponents()!=1)
5809     throw INTERP_KERNEL::Exception("Call transformWithIndArr method on DataArrayInt with only one component, you can call 'rearrange' method before !");
5810   int nbElemsIn=(int)std::distance(indArrBg,indArrEnd);
5811   int nbOfTuples=getNumberOfTuples();
5812   int *pt=getPointer();
5813   for(int i=0;i<nbOfTuples;i++,pt++)
5814     {
5815       if(*pt>=0 && *pt<nbElemsIn)
5816         *pt=indArrBg[*pt];
5817       else
5818         {
5819           std::ostringstream oss; oss << "DataArrayInt::transformWithIndArr : error on tuple #" << i << " value is " << *pt << " and indirectionnal array as a size equal to " << nbElemsIn;
5820           throw INTERP_KERNEL::Exception(oss.str().c_str());
5821         }
5822     }
5823   declareAsNew();
5824 }
5825
5826 /*!
5827  * Computes distribution of values of \a this one-dimensional array between given value
5828  * ranges (casts). This method is typically useful for entity number spliting by types,
5829  * for example. 
5830  *  \warning The values contained in \a arrBg should be sorted ascendently. No
5831  *           check of this is be done. If not, the result is not warranted. 
5832  *  \param [in] arrBg - the array of ascending values defining the value ranges. The i-th
5833  *         value of \a arrBg (\a arrBg[ i ]) gives the lowest value of the i-th range,
5834  *         and the greatest value of the i-th range equals to \a arrBg[ i+1 ] - 1. \a
5835  *         arrBg containing \a n values defines \a n-1 ranges. The last value of \a arrBg
5836  *         should be more than every value in \a this array.
5837  *  \param [in] arrEnd - specifies the end of the array \a arrBg, so that
5838  *              the last value of \a arrBg is \a arrEnd[ -1 ].
5839  *  \param [out] castArr - a new instance of DataArrayInt, of same size as \a this array
5840  *         (same number of tuples and components), the caller is to delete 
5841  *         using decrRef() as it is no more needed.
5842  *         This array contains indices of ranges for every value of \a this array. I.e.
5843  *         the i-th value of \a castArr gives the index of range the i-th value of \a this
5844  *         belongs to. Or, in other words, this parameter contains for each tuple in \a
5845  *         this in which cast it holds.
5846  *  \param [out] rankInsideCast - a new instance of DataArrayInt, of same size as \a this
5847  *         array, the caller is to delete using decrRef() as it is no more needed.
5848  *         This array contains ranks of values of \a this array within ranges
5849  *         they belongs to. I.e. the i-th value of \a rankInsideCast gives the rank of
5850  *         the i-th value of \a this array within the \a castArr[ i ]-th range, to which
5851  *         the i-th value of \a this belongs to. Or, in other words, this param contains 
5852  *         for each tuple its rank inside its cast. The rank is computed as difference
5853  *         between the value and the lowest value of range.
5854  *  \param [out] castsPresent - a new instance of DataArrayInt, containing indices of
5855  *         ranges (casts) to which at least one value of \a this array belongs.
5856  *         Or, in other words, this param contains the casts that \a this contains.
5857  *         The caller is to delete this array using decrRef() as it is no more needed.
5858  *
5859  * \b Example: If \a this contains [6,5,0,3,2,7,8,1,4] and \a arrBg contains [0,4,9] then
5860  *            the output of this method will be : 
5861  * - \a castArr       : [1,1,0,0,0,1,1,0,1]
5862  * - \a rankInsideCast: [2,1,0,3,2,3,4,1,0]
5863  * - \a castsPresent  : [0,1]
5864  *
5865  * I.e. values of \a this array belong to 2 ranges: #0 and #1. Value 6 belongs to the
5866  * range #1 and its rank within this range is 2; etc.
5867  *
5868  *  \throw If \a this->getNumberOfComponents() != 1.
5869  *  \throw If \a arrEnd - arrBg < 2.
5870  *  \throw If any value of \a this is not less than \a arrEnd[-1].
5871  */
5872 void DataArrayInt::splitByValueRange(const int *arrBg, const int *arrEnd,
5873                                      DataArrayInt *& castArr, DataArrayInt *& rankInsideCast, DataArrayInt *& castsPresent) const throw(INTERP_KERNEL::Exception)
5874 {
5875   checkAllocated();
5876   if(getNumberOfComponents()!=1)
5877     throw INTERP_KERNEL::Exception("Call splitByValueRange  method on DataArrayInt with only one component, you can call 'rearrange' method before !");
5878   int nbOfTuples=getNumberOfTuples();
5879   std::size_t nbOfCast=std::distance(arrBg,arrEnd);
5880   if(nbOfCast<2)
5881     throw INTERP_KERNEL::Exception("DataArrayInt::splitByValueRange : The input array giving the cast range values should be of size >=2 !");
5882   nbOfCast--;
5883   const int *work=getConstPointer();
5884   typedef std::reverse_iterator<const int *> rintstart;
5885   rintstart bg(arrEnd);//OK no problem because size of 'arr' is greater or equal 2
5886   rintstart end2(arrBg);
5887   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret1=DataArrayInt::New();
5888   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret2=DataArrayInt::New();
5889   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret3=DataArrayInt::New();
5890   ret1->alloc(nbOfTuples,1);
5891   ret2->alloc(nbOfTuples,1);
5892   int *ret1Ptr=ret1->getPointer();
5893   int *ret2Ptr=ret2->getPointer();
5894   std::set<std::size_t> castsDetected;
5895   for(int i=0;i<nbOfTuples;i++)
5896     {
5897       rintstart res=std::find_if(bg,end2,std::bind2nd(std::less_equal<int>(), work[i]));
5898       std::size_t pos=std::distance(bg,res);
5899       std::size_t pos2=nbOfCast-pos;
5900       if(pos2<nbOfCast)
5901         {
5902           ret1Ptr[i]=(int)pos2;
5903           ret2Ptr[i]=work[i]-arrBg[pos2];
5904           castsDetected.insert(pos2);
5905         }
5906       else
5907         {
5908           std::ostringstream oss; oss << "DataArrayInt::splitByValueRange : At rank #" << i << " the value is " << work[i] << " should be in [0," << *bg << ") !";
5909           throw INTERP_KERNEL::Exception(oss.str().c_str());
5910         }
5911     }
5912   ret3->alloc((int)castsDetected.size(),1);
5913   std::copy(castsDetected.begin(),castsDetected.end(),ret3->getPointer());
5914   castArr=ret1.retn();
5915   rankInsideCast=ret2.retn();
5916   castsPresent=ret3.retn();
5917 }
5918
5919 /*!
5920  * Creates a one-dimensional DataArrayInt (\a res) whose contents are computed from 
5921  * values of \a this (\a a) and the given (\a indArr) arrays as follows:
5922  * \a res[ \a indArr[ \a a[ i ]]] = i. I.e. for each value in place i \a v = \a a[ i ],
5923  * new value in place \a indArr[ \a v ] is i.
5924  *  \param [in] indArrBg - the array holding indices within the result array to assign
5925  *         indices of values of \a this array pointing to values of \a indArrBg.
5926  *  \param [in] indArrEnd - specifies the end of the array \a indArrBg, so that
5927  *              the last value of \a indArrBg is \a indArrEnd[ -1 ].
5928  *  \return DataArrayInt * - the new instance of DataArrayInt.
5929  *          The caller is to delete this result array using decrRef() as it is no more
5930  *          needed.
5931  *  \throw If \a this->getNumberOfComponents() != 1.
5932  *  \throw If any value of \a this array is not a valid index for \a indArrBg array.
5933  *  \throw If any value of \a indArrBg is not a valid index for \a this array.
5934  */
5935 DataArrayInt *DataArrayInt::transformWithIndArrR(const int *indArrBg, const int *indArrEnd) const throw(INTERP_KERNEL::Exception)
5936 {
5937   checkAllocated();
5938   if(getNumberOfComponents()!=1)
5939     throw INTERP_KERNEL::Exception("Call transformWithIndArrR method on DataArrayInt with only one component, you can call 'rearrange' method before !");
5940   int nbElemsIn=(int)std::distance(indArrBg,indArrEnd);
5941   int nbOfTuples=getNumberOfTuples();
5942   const int *pt=getConstPointer();
5943   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
5944   ret->alloc(nbOfTuples,1);
5945   ret->fillWithValue(-1);
5946   int *tmp=ret->getPointer();
5947   for(int i=0;i<nbOfTuples;i++,pt++)
5948     {
5949       if(*pt>=0 && *pt<nbElemsIn)
5950         {
5951           int pos=indArrBg[*pt];
5952           if(pos>=0 && pos<nbOfTuples)
5953             tmp[pos]=i;
5954           else
5955             {
5956               std::ostringstream oss; oss << "DataArrayInt::transformWithIndArrR : error on tuple #" << i << " value of new pos is " << pos << " ( indArrBg[" << *pt << "]) ! Should be in [0," << nbOfTuples << ") !";
5957               throw INTERP_KERNEL::Exception(oss.str().c_str());
5958             }
5959         }
5960       else
5961         {
5962           std::ostringstream oss; oss << "DataArrayInt::transformWithIndArrR : error on tuple #" << i << " value is " << *pt << " and indirectionnal array as a size equal to " << nbElemsIn << " !";
5963           throw INTERP_KERNEL::Exception(oss.str().c_str());
5964         }
5965     }
5966   return ret.retn();
5967 }
5968
5969 /*!
5970  * Creates a one-dimensional DataArrayInt of given length, whose contents are computed
5971  * from values of \a this array, which is supposed to contain a renumbering map in 
5972  * "Old to New" mode. The result array contains a renumbering map in "New to Old" mode.
5973  * To know how to use the renumbering maps see \ref MEDCouplingArrayRenumbering.
5974  *  \param [in] newNbOfElem - the number of tuples in the result array.
5975  *  \return DataArrayInt * - the new instance of DataArrayInt.
5976  *          The caller is to delete this result array using decrRef() as it is no more
5977  *          needed.
5978  * 
5979  *  \ref cpp_mcdataarrayint_invertarrayo2n2n2o "Here is a C++ example".<br>
5980  *  \ref py_mcdataarrayint_invertarrayo2n2n2o  "Here is a Python example".
5981  */
5982 DataArrayInt *DataArrayInt::invertArrayO2N2N2O(int newNbOfElem) const
5983 {
5984   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
5985   ret->alloc(newNbOfElem,1);
5986   int nbOfOldNodes=getNumberOfTuples();
5987   const int *old2New=getConstPointer();
5988   int *pt=ret->getPointer();
5989   for(int i=0;i!=nbOfOldNodes;i++)
5990     if(old2New[i]!=-1)
5991       pt[old2New[i]]=i;
5992   return ret.retn();
5993 }
5994
5995 /*!
5996  * This method is similar to DataArrayInt::invertArrayO2N2N2O except that 
5997  * 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]
5998  */
5999 DataArrayInt *DataArrayInt::invertArrayO2N2N2OBis(int newNbOfElem) const throw(INTERP_KERNEL::Exception)
6000 {
6001   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6002   ret->alloc(newNbOfElem,1);
6003   int nbOfOldNodes=getNumberOfTuples();
6004   const int *old2New=getConstPointer();
6005   int *pt=ret->getPointer();
6006   for(int i=nbOfOldNodes-1;i>=0;i--)
6007     if(old2New[i]!=-1)
6008       pt[old2New[i]]=i;
6009   return ret.retn();
6010 }
6011
6012 /*!
6013  * Creates a one-dimensional DataArrayInt of given length, whose contents are computed
6014  * from values of \a this array, which is supposed to contain a renumbering map in 
6015  * "New to Old" mode. The result array contains a renumbering map in "Old to New" mode.
6016  * To know how to use the renumbering maps see \ref MEDCouplingArrayRenumbering.
6017  *  \param [in] newNbOfElem - the number of tuples in the result array.
6018  *  \return DataArrayInt * - the new instance of DataArrayInt.
6019  *          The caller is to delete this result array using decrRef() as it is no more
6020  *          needed.
6021  * 
6022  *  \ref cpp_mcdataarrayint_invertarrayn2o2o2n "Here is a C++ example".
6023  *
6024  *  \ref py_mcdataarrayint_invertarrayn2o2o2n "Here is a Python example".
6025  */
6026 DataArrayInt *DataArrayInt::invertArrayN2O2O2N(int oldNbOfElem) const
6027 {
6028   checkAllocated();
6029   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6030   ret->alloc(oldNbOfElem,1);
6031   const int *new2Old=getConstPointer();
6032   int *pt=ret->getPointer();
6033   std::fill(pt,pt+oldNbOfElem,-1);
6034   int nbOfNewElems=getNumberOfTuples();
6035   for(int i=0;i<nbOfNewElems;i++)
6036     pt[new2Old[i]]=i;
6037   return ret.retn();
6038 }
6039
6040 /*!
6041  * Equivalent to DataArrayInt::isEqual except that if false the reason of
6042  * mismatch is given.
6043  * 
6044  * \param [in] other the instance to be compared with \a this
6045  * \param [out] reason In case of inequality returns the reason.
6046  * \sa DataArrayInt::isEqual
6047  */
6048 bool DataArrayInt::isEqualIfNotWhy(const DataArrayInt& other, std::string& reason) const throw(INTERP_KERNEL::Exception)
6049 {
6050   if(!areInfoEqualsIfNotWhy(other,reason))
6051     return false;
6052   return _mem.isEqual(other._mem,0,reason);
6053 }
6054
6055 /*!
6056  * Checks if \a this and another DataArrayInt are fully equal. For more info see
6057  * \ref MEDCouplingArrayBasicsCompare.
6058  *  \param [in] other - an instance of DataArrayInt to compare with \a this one.
6059  *  \return bool - \a true if the two arrays are equal, \a false else.
6060  */
6061 bool DataArrayInt::isEqual(const DataArrayInt& other) const throw(INTERP_KERNEL::Exception)
6062 {
6063   std::string tmp;
6064   return isEqualIfNotWhy(other,tmp);
6065 }
6066
6067 /*!
6068  * Checks if values of \a this and another DataArrayInt are equal. For more info see
6069  * \ref MEDCouplingArrayBasicsCompare.
6070  *  \param [in] other - an instance of DataArrayInt to compare with \a this one.
6071  *  \return bool - \a true if the values of two arrays are equal, \a false else.
6072  */
6073 bool DataArrayInt::isEqualWithoutConsideringStr(const DataArrayInt& other) const throw(INTERP_KERNEL::Exception)
6074 {
6075   std::string tmp;
6076   return _mem.isEqual(other._mem,0,tmp);
6077 }
6078
6079 /*!
6080  * Checks if values of \a this and another DataArrayInt are equal. Comparison is
6081  * performed on sorted value sequences.
6082  * For more info see\ref MEDCouplingArrayBasicsCompare.
6083  *  \param [in] other - an instance of DataArrayInt to compare with \a this one.
6084  *  \return bool - \a true if the sorted values of two arrays are equal, \a false else.
6085  */
6086 bool DataArrayInt::isEqualWithoutConsideringStrAndOrder(const DataArrayInt& other) const throw(INTERP_KERNEL::Exception)
6087 {
6088   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> a=deepCpy();
6089   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> b=other.deepCpy();
6090   a->sort();
6091   b->sort();
6092   return a->isEqualWithoutConsideringStr(*b);
6093 }
6094
6095 /*!
6096  * Sorts values of the array.
6097  *  \param [in] asc - \a true means ascending order, \a false, descending.
6098  *  \throw If \a this is not allocated.
6099  *  \throw If \a this->getNumberOfComponents() != 1.
6100  */
6101 void DataArrayInt::sort(bool asc) throw(INTERP_KERNEL::Exception)
6102 {
6103   checkAllocated();
6104   if(getNumberOfComponents()!=1)
6105     throw INTERP_KERNEL::Exception("DataArrayInt::sort : only supported with 'this' array with ONE component !");
6106   _mem.sort(asc);
6107   declareAsNew();
6108 }
6109
6110 /*!
6111  * Reverse the array values.
6112  *  \throw If \a this->getNumberOfComponents() < 1.
6113  *  \throw If \a this is not allocated.
6114  */
6115 void DataArrayInt::reverse() throw(INTERP_KERNEL::Exception)
6116 {
6117   checkAllocated();
6118   _mem.reverse(getNumberOfComponents());
6119   declareAsNew();
6120 }
6121
6122 /*!
6123  * Checks that \a this array is consistently **increasing** or **decreasing** in value.
6124  * If not an exception is thrown.
6125  *  \param [in] increasing - if \a true, the array values should be increasing.
6126  *  \throw If sequence of values is not strictly monotonic in agreement with \a
6127  *         increasing arg.
6128  *  \throw If \a this->getNumberOfComponents() != 1.
6129  *  \throw If \a this is not allocated.
6130  */
6131 void DataArrayInt::checkMonotonic(bool increasing) const throw(INTERP_KERNEL::Exception)
6132 {
6133   if(!isMonotonic(increasing))
6134     {
6135       if (increasing)
6136         throw INTERP_KERNEL::Exception("DataArrayInt::checkMonotonic : 'this' is not INCREASING monotonic !");
6137       else
6138         throw INTERP_KERNEL::Exception("DataArrayInt::checkMonotonic : 'this' is not DECREASING monotonic !");
6139     }
6140 }
6141
6142 /*!
6143  * Checks that \a this array is consistently **increasing** or **decreasing** in value.
6144  *  \param [in] increasing - if \a true, array values should be increasing.
6145  *  \return bool - \a true if values change in accordance with \a increasing arg.
6146  *  \throw If \a this->getNumberOfComponents() != 1.
6147  *  \throw If \a this is not allocated.
6148  */
6149 bool DataArrayInt::isMonotonic(bool increasing) const throw(INTERP_KERNEL::Exception)
6150 {
6151   checkAllocated();
6152   if(getNumberOfComponents()!=1)
6153     throw INTERP_KERNEL::Exception("DataArrayInt::isMonotonic : only supported with 'this' array with ONE component !");
6154   int nbOfElements=getNumberOfTuples();
6155   const int *ptr=getConstPointer();
6156   if(nbOfElements==0)
6157     return true;
6158   int ref=ptr[0];
6159   if(increasing)
6160     {
6161       for(int i=1;i<nbOfElements;i++)
6162         {
6163           if(ptr[i]>=ref)
6164             ref=ptr[i];
6165           else
6166             return false;
6167         }
6168     }
6169   else
6170     {
6171       for(int i=1;i<nbOfElements;i++)
6172         {
6173           if(ptr[i]<=ref)
6174             ref=ptr[i];
6175           else
6176             return false;
6177         }
6178     }
6179   return true;
6180 }
6181
6182 /*!
6183  * This method check that array consistently INCREASING or DECREASING in value.
6184  */
6185 bool DataArrayInt::isStrictlyMonotonic(bool increasing) const throw(INTERP_KERNEL::Exception)
6186 {
6187   checkAllocated();
6188   if(getNumberOfComponents()!=1)
6189     throw INTERP_KERNEL::Exception("DataArrayInt::isStrictlyMonotonic : only supported with 'this' array with ONE component !");
6190   int nbOfElements=getNumberOfTuples();
6191   const int *ptr=getConstPointer();
6192   if(nbOfElements==0)
6193     return true;
6194   int ref=ptr[0];
6195   if(increasing)
6196     {
6197       for(int i=1;i<nbOfElements;i++)
6198         {
6199           if(ptr[i]>ref)
6200             ref=ptr[i];
6201           else
6202             return false;
6203         }
6204     }
6205   else
6206     {
6207       for(int i=1;i<nbOfElements;i++)
6208         {
6209           if(ptr[i]<ref)
6210             ref=ptr[i];
6211           else
6212             return false;
6213         }
6214     }
6215   return true;
6216 }
6217
6218 /*!
6219  * This method check that array consistently INCREASING or DECREASING in value.
6220  */
6221 void DataArrayInt::checkStrictlyMonotonic(bool increasing) const throw(INTERP_KERNEL::Exception)
6222 {
6223   if(!isStrictlyMonotonic(increasing))
6224     {
6225       if (increasing)
6226         throw INTERP_KERNEL::Exception("DataArrayInt::checkStrictlyMonotonic : 'this' is not strictly INCREASING monotonic !");
6227       else
6228         throw INTERP_KERNEL::Exception("DataArrayInt::checkStrictlyMonotonic : 'this' is not strictly DECREASING monotonic !");
6229     }
6230 }
6231
6232 /*!
6233  * Creates a new one-dimensional DataArrayInt of the same size as \a this and a given
6234  * one-dimensional arrays that must be of the same length. The result array describes
6235  * correspondence between \a this and \a other arrays, so that 
6236  * <em> other.getIJ(i,0) == this->getIJ(ret->getIJ(i),0)</em>. If such a permutation is
6237  * not possible because some element in \a other is not in \a this, an exception is thrown.
6238  *  \param [in] other - an array to compute permutation to.
6239  *  \return DataArrayInt * - a new instance of DataArrayInt, which is a permutation array
6240  * from \a this to \a other. The caller is to delete this array using decrRef() as it is
6241  * no more needed.
6242  *  \throw If \a this->getNumberOfComponents() != 1.
6243  *  \throw If \a other->getNumberOfComponents() != 1.
6244  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples().
6245  *  \throw If \a other includes a value which is not in \a this array.
6246  * 
6247  *  \ref cpp_mcdataarrayint_buildpermutationarr "Here is a C++ example".
6248  *
6249  *  \ref py_mcdataarrayint_buildpermutationarr "Here is a Python example".
6250  */
6251 DataArrayInt *DataArrayInt::buildPermutationArr(const DataArrayInt& other) const throw(INTERP_KERNEL::Exception)
6252 {
6253   checkAllocated();
6254   if(getNumberOfComponents()!=1 || other.getNumberOfComponents()!=1)
6255     throw INTERP_KERNEL::Exception("DataArrayInt::buildPermutationArr : 'this' and 'other' have to have exactly ONE component !");
6256   int nbTuple=getNumberOfTuples();
6257   other.checkAllocated();
6258   if(nbTuple!=other.getNumberOfTuples())
6259     throw INTERP_KERNEL::Exception("DataArrayInt::buildPermutationArr : 'this' and 'other' must have the same number of tuple !");
6260   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6261   ret->alloc(nbTuple,1);
6262   ret->fillWithValue(-1);
6263   const int *pt=getConstPointer();
6264   std::map<int,int> mm;
6265   for(int i=0;i<nbTuple;i++)
6266     mm[pt[i]]=i;
6267   pt=other.getConstPointer();
6268   int *retToFill=ret->getPointer();
6269   for(int i=0;i<nbTuple;i++)
6270     {
6271       std::map<int,int>::const_iterator it=mm.find(pt[i]);
6272       if(it==mm.end())
6273         {
6274           std::ostringstream oss; oss << "DataArrayInt::buildPermutationArr : Arrays mismatch : element (" << pt[i] << ") in 'other' not findable in 'this' !";
6275           throw INTERP_KERNEL::Exception(oss.str().c_str());
6276         }
6277       retToFill[i]=(*it).second;
6278     }
6279   return ret.retn();
6280 }
6281
6282 /*!
6283  * Sets a C array to be used as raw data of \a this. The previously set info
6284  *  of components is retained and re-sized. 
6285  * For more info see \ref MEDCouplingArraySteps1.
6286  *  \param [in] array - the C array to be used as raw data of \a this.
6287  *  \param [in] ownership - if \a true, \a array will be deallocated at destruction of \a this.
6288  *  \param [in] type - specifies how to deallocate \a array. If \a type == ParaMEDMEM::CPP_DEALLOC,
6289  *                     \c delete [] \c array; will be called. If \a type == ParaMEDMEM::C_DEALLOC,
6290  *                     \c free(\c array ) will be called.
6291  *  \param [in] nbOfTuple - new number of tuples in \a this.
6292  *  \param [in] nbOfCompo - new number of components in \a this.
6293  */
6294 void DataArrayInt::useArray(const int *array, bool ownership,  DeallocType type, int nbOfTuple, int nbOfCompo) throw(INTERP_KERNEL::Exception)
6295 {
6296   _info_on_compo.resize(nbOfCompo);
6297   _mem.useArray(array,ownership,type,nbOfTuple*nbOfCompo);
6298   declareAsNew();
6299 }
6300
6301 void DataArrayInt::useExternalArrayWithRWAccess(const int *array, int nbOfTuple, int nbOfCompo) throw(INTERP_KERNEL::Exception)
6302 {
6303   _info_on_compo.resize(nbOfCompo);
6304   _mem.useExternalArrayWithRWAccess(array,nbOfTuple*nbOfCompo);
6305   declareAsNew();
6306 }
6307
6308 /*!
6309  * Returns a new DataArrayInt holding the same values as \a this array but differently
6310  * arranged in memory. If \a this array holds 2 components of 3 values:
6311  * \f$ x_0,x_1,x_2,y_0,y_1,y_2 \f$, then the result array holds these values arranged
6312  * as follows: \f$ x_0,y_0,x_1,y_1,x_2,y_2 \f$.
6313  *  \warning Do not confuse this method with transpose()!
6314  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
6315  *          is to delete using decrRef() as it is no more needed.
6316  *  \throw If \a this is not allocated.
6317  */
6318 DataArrayInt *DataArrayInt::fromNoInterlace() const throw(INTERP_KERNEL::Exception)
6319 {
6320   checkAllocated();
6321   if(_mem.isNull())
6322     throw INTERP_KERNEL::Exception("DataArrayInt::fromNoInterlace : Not defined array !");
6323   int *tab=_mem.fromNoInterlace(getNumberOfComponents());
6324   DataArrayInt *ret=DataArrayInt::New();
6325   ret->useArray(tab,true,C_DEALLOC,getNumberOfTuples(),getNumberOfComponents());
6326   return ret;
6327 }
6328
6329 /*!
6330  * Returns a new DataArrayInt holding the same values as \a this array but differently
6331  * arranged in memory. If \a this array holds 2 components of 3 values:
6332  * \f$ x_0,y_0,x_1,y_1,x_2,y_2 \f$, then the result array holds these values arranged
6333  * as follows: \f$ x_0,x_1,x_2,y_0,y_1,y_2 \f$.
6334  *  \warning Do not confuse this method with transpose()!
6335  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
6336  *          is to delete using decrRef() as it is no more needed.
6337  *  \throw If \a this is not allocated.
6338  */
6339 DataArrayInt *DataArrayInt::toNoInterlace() const throw(INTERP_KERNEL::Exception)
6340 {
6341   checkAllocated();
6342   if(_mem.isNull())
6343     throw INTERP_KERNEL::Exception("DataArrayInt::toNoInterlace : Not defined array !");
6344   int *tab=_mem.toNoInterlace(getNumberOfComponents());
6345   DataArrayInt *ret=DataArrayInt::New();
6346   ret->useArray(tab,true,C_DEALLOC,getNumberOfTuples(),getNumberOfComponents());
6347   return ret;
6348 }
6349
6350 /*!
6351  * Permutes values of \a this array as required by \a old2New array. The values are
6352  * permuted so that \c new[ \a old2New[ i ]] = \c old[ i ]. Number of tuples remains
6353  * the same as in \this one.
6354  * If a permutation reduction is needed, substr() or selectByTupleId() should be used.
6355  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
6356  *  \param [in] old2New - C array of length equal to \a this->getNumberOfTuples()
6357  *     giving a new position for i-th old value.
6358  */
6359 void DataArrayInt::renumberInPlace(const int *old2New) throw(INTERP_KERNEL::Exception)
6360 {
6361   checkAllocated();
6362   int nbTuples=getNumberOfTuples();
6363   int nbOfCompo=getNumberOfComponents();
6364   int *tmp=new int[nbTuples*nbOfCompo];
6365   const int *iptr=getConstPointer();
6366   for(int i=0;i<nbTuples;i++)
6367     {
6368       int v=old2New[i];
6369       if(v>=0 && v<nbTuples)
6370         std::copy(iptr+nbOfCompo*i,iptr+nbOfCompo*(i+1),tmp+nbOfCompo*v);
6371       else
6372         {
6373           std::ostringstream oss; oss << "DataArrayInt::renumberInPlace : At place #" << i << " value is " << v << " ! Should be in [0," << nbTuples << ") !";
6374           throw INTERP_KERNEL::Exception(oss.str().c_str());
6375         }
6376     }
6377   std::copy(tmp,tmp+nbTuples*nbOfCompo,getPointer());
6378   delete [] tmp;
6379   declareAsNew();
6380 }
6381
6382 /*!
6383  * Permutes values of \a this array as required by \a new2Old array. The values are
6384  * permuted so that \c new[ i ] = \c old[ \a new2Old[ i ]]. Number of tuples remains
6385  * the same as in \this one.
6386  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
6387  *  \param [in] new2Old - C array of length equal to \a this->getNumberOfTuples()
6388  *     giving a previous position of i-th new value.
6389  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
6390  *          is to delete using decrRef() as it is no more needed.
6391  */
6392 void DataArrayInt::renumberInPlaceR(const int *new2Old) throw(INTERP_KERNEL::Exception)
6393 {
6394   checkAllocated();
6395   int nbTuples=getNumberOfTuples();
6396   int nbOfCompo=getNumberOfComponents();
6397   int *tmp=new int[nbTuples*nbOfCompo];
6398   const int *iptr=getConstPointer();
6399   for(int i=0;i<nbTuples;i++)
6400     {
6401       int v=new2Old[i];
6402       if(v>=0 && v<nbTuples)
6403         std::copy(iptr+nbOfCompo*v,iptr+nbOfCompo*(v+1),tmp+nbOfCompo*i);
6404       else
6405         {
6406           std::ostringstream oss; oss << "DataArrayInt::renumberInPlaceR : At place #" << i << " value is " << v << " ! Should be in [0," << nbTuples << ") !";
6407           throw INTERP_KERNEL::Exception(oss.str().c_str());
6408         }
6409     }
6410   std::copy(tmp,tmp+nbTuples*nbOfCompo,getPointer());
6411   delete [] tmp;
6412   declareAsNew();
6413 }
6414
6415 /*!
6416  * Returns a copy of \a this array with values permuted as required by \a old2New array.
6417  * The values are permuted so that  \c new[ \a old2New[ i ]] = \c old[ i ].
6418  * Number of tuples in the result array remains the same as in \this one.
6419  * If a permutation reduction is needed, renumberAndReduce() should be used.
6420  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
6421  *  \param [in] old2New - C array of length equal to \a this->getNumberOfTuples()
6422  *          giving a new position for i-th old value.
6423  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
6424  *          is to delete using decrRef() as it is no more needed.
6425  *  \throw If \a this is not allocated.
6426  */
6427 DataArrayInt *DataArrayInt::renumber(const int *old2New) const throw(INTERP_KERNEL::Exception)
6428 {
6429   checkAllocated();
6430   int nbTuples=getNumberOfTuples();
6431   int nbOfCompo=getNumberOfComponents();
6432   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6433   ret->alloc(nbTuples,nbOfCompo);
6434   ret->copyStringInfoFrom(*this);
6435   const int *iptr=getConstPointer();
6436   int *optr=ret->getPointer();
6437   for(int i=0;i<nbTuples;i++)
6438     std::copy(iptr+nbOfCompo*i,iptr+nbOfCompo*(i+1),optr+nbOfCompo*old2New[i]);
6439   ret->copyStringInfoFrom(*this);
6440   return ret.retn();
6441 }
6442
6443 /*!
6444  * Returns a copy of \a this array with values permuted as required by \a new2Old array.
6445  * The values are permuted so that  \c new[ i ] = \c old[ \a new2Old[ i ]]. Number of
6446  * tuples in the result array remains the same as in \this one.
6447  * If a permutation reduction is needed, substr() or selectByTupleId() should be used.
6448  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
6449  *  \param [in] new2Old - C array of length equal to \a this->getNumberOfTuples()
6450  *     giving a previous position of i-th new value.
6451  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
6452  *          is to delete using decrRef() as it is no more needed.
6453  */
6454 DataArrayInt *DataArrayInt::renumberR(const int *new2Old) const throw(INTERP_KERNEL::Exception)
6455 {
6456   checkAllocated();
6457   int nbTuples=getNumberOfTuples();
6458   int nbOfCompo=getNumberOfComponents();
6459   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6460   ret->alloc(nbTuples,nbOfCompo);
6461   ret->copyStringInfoFrom(*this);
6462   const int *iptr=getConstPointer();
6463   int *optr=ret->getPointer();
6464   for(int i=0;i<nbTuples;i++)
6465     std::copy(iptr+nbOfCompo*new2Old[i],iptr+nbOfCompo*(new2Old[i]+1),optr+nbOfCompo*i);
6466   ret->copyStringInfoFrom(*this);
6467   return ret.retn();
6468 }
6469
6470 /*!
6471  * Returns a shorten and permuted copy of \a this array. The new DataArrayInt is
6472  * of size \a newNbOfTuple and it's values are permuted as required by \a old2New array.
6473  * The values are permuted so that  \c new[ \a old2New[ i ]] = \c old[ i ] for all
6474  * \a old2New[ i ] >= 0. In other words every i-th tuple in \a this array, for which 
6475  * \a old2New[ i ] is negative, is missing from the result array.
6476  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
6477  *  \param [in] old2New - C array of length equal to \a this->getNumberOfTuples()
6478  *     giving a new position for i-th old tuple and giving negative position for
6479  *     for i-th old tuple that should be omitted.
6480  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
6481  *          is to delete using decrRef() as it is no more needed.
6482  */
6483 DataArrayInt *DataArrayInt::renumberAndReduce(const int *old2New, int newNbOfTuple) const throw(INTERP_KERNEL::Exception)
6484 {
6485   checkAllocated();
6486   int nbTuples=getNumberOfTuples();
6487   int nbOfCompo=getNumberOfComponents();
6488   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6489   ret->alloc(newNbOfTuple,nbOfCompo);
6490   const int *iptr=getConstPointer();
6491   int *optr=ret->getPointer();
6492   for(int i=0;i<nbTuples;i++)
6493     {
6494       int w=old2New[i];
6495       if(w>=0)
6496         std::copy(iptr+i*nbOfCompo,iptr+(i+1)*nbOfCompo,optr+w*nbOfCompo);
6497     }
6498   ret->copyStringInfoFrom(*this);
6499   return ret.retn();
6500 }
6501
6502 /*!
6503  * Returns a shorten and permuted copy of \a this array. The new DataArrayInt is
6504  * of size \a new2OldEnd - \a new2OldBg and it's values are permuted as required by
6505  * \a new2OldBg array.
6506  * The values are permuted so that  \c new[ i ] = \c old[ \a new2OldBg[ i ]].
6507  * This method is equivalent to renumberAndReduce() except that convention in input is
6508  * \c new2old and \b not \c old2new.
6509  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
6510  *  \param [in] new2OldBg - pointer to the beginning of a permutation array that gives a
6511  *              tuple index in \a this array to fill the i-th tuple in the new array.
6512  *  \param [in] new2OldEnd - specifies the end of the permutation array that starts at
6513  *              \a new2OldBg, so that pointer to a tuple index (\a pi) varies as this:
6514  *              \a new2OldBg <= \a pi < \a new2OldEnd.
6515  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
6516  *          is to delete using decrRef() as it is no more needed.
6517  */
6518 DataArrayInt *DataArrayInt::selectByTupleId(const int *new2OldBg, const int *new2OldEnd) const
6519 {
6520   checkAllocated();
6521   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6522   int nbComp=getNumberOfComponents();
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     std::copy(srcPt+(*w)*nbComp,srcPt+((*w)+1)*nbComp,pt+i*nbComp);
6530   ret->copyStringInfoFrom(*this);
6531   return ret.retn();
6532 }
6533
6534 /*!
6535  * Returns a shorten and permuted copy of \a this array. The new DataArrayInt is
6536  * of size \a new2OldEnd - \a new2OldBg and it's values are permuted as required by
6537  * \a new2OldBg array.
6538  * The values are permuted so that  \c new[ i ] = \c old[ \a new2OldBg[ i ]].
6539  * This method is equivalent to renumberAndReduce() except that convention in input is
6540  * \c new2old and \b not \c old2new.
6541  * This method is equivalent to selectByTupleId() except that it prevents coping data
6542  * from behind the end of \a this array.
6543  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
6544  *  \param [in] new2OldBg - pointer to the beginning of a permutation array that gives a
6545  *              tuple index in \a this array to fill the i-th tuple in the new array.
6546  *  \param [in] new2OldEnd - specifies the end of the permutation array that starts at
6547  *              \a new2OldBg, so that pointer to a tuple index (\a pi) varies as this:
6548  *              \a new2OldBg <= \a pi < \a new2OldEnd.
6549  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
6550  *          is to delete using decrRef() as it is no more needed.
6551  *  \throw If \a new2OldEnd - \a new2OldBg > \a this->getNumberOfTuples().
6552  */
6553 DataArrayInt *DataArrayInt::selectByTupleIdSafe(const int *new2OldBg, const int *new2OldEnd) const throw(INTERP_KERNEL::Exception)
6554 {
6555   checkAllocated();
6556   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6557   int nbComp=getNumberOfComponents();
6558   int oldNbOfTuples=getNumberOfTuples();
6559   ret->alloc((int)std::distance(new2OldBg,new2OldEnd),nbComp);
6560   ret->copyStringInfoFrom(*this);
6561   int *pt=ret->getPointer();
6562   const int *srcPt=getConstPointer();
6563   int i=0;
6564   for(const int *w=new2OldBg;w!=new2OldEnd;w++,i++)
6565     if(*w>=0 && *w<oldNbOfTuples)
6566       std::copy(srcPt+(*w)*nbComp,srcPt+((*w)+1)*nbComp,pt+i*nbComp);
6567     else
6568       throw INTERP_KERNEL::Exception("DataArrayInt::selectByTupleIdSafe : some ids has been detected to be out of [0,this->getNumberOfTuples) !");
6569   ret->copyStringInfoFrom(*this);
6570   return ret.retn();
6571 }
6572
6573 /*!
6574  * Returns a shorten copy of \a this array. The new DataArrayInt contains every
6575  * (\a bg + \c i * \a step)-th tuple of \a this array located before the \a end2-th
6576  * tuple. Indices of the selected tuples are the same as ones returned by the Python
6577  * command \c range( \a bg, \a end2, \a step ).
6578  * This method is equivalent to selectByTupleIdSafe() except that the input array is
6579  * not constructed explicitly.
6580  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
6581  *  \param [in] bg - index of the first tuple to copy from \a this array.
6582  *  \param [in] end2 - index of the tuple before which the tuples to copy are located.
6583  *  \param [in] step - index increment to get index of the next tuple to copy.
6584  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
6585  *          is to delete using decrRef() as it is no more needed.
6586  *  \sa DataArrayInt::substr.
6587  */
6588 DataArrayInt *DataArrayInt::selectByTupleId2(int bg, int end2, int step) const throw(INTERP_KERNEL::Exception)
6589 {
6590   checkAllocated();
6591   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6592   int nbComp=getNumberOfComponents();
6593   int newNbOfTuples=GetNumberOfItemGivenBESRelative(bg,end2,step,"DataArrayInt::selectByTupleId2 : ");
6594   ret->alloc(newNbOfTuples,nbComp);
6595   int *pt=ret->getPointer();
6596   const int *srcPt=getConstPointer()+bg*nbComp;
6597   for(int i=0;i<newNbOfTuples;i++,srcPt+=step*nbComp)
6598     std::copy(srcPt,srcPt+nbComp,pt+i*nbComp);
6599   ret->copyStringInfoFrom(*this);
6600   return ret.retn();
6601 }
6602
6603 /*!
6604  * Returns a shorten copy of \a this array. The new DataArrayInt contains ranges
6605  * of tuples specified by \a ranges parameter.
6606  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
6607  *  \param [in] ranges - std::vector of std::pair's each of which defines a range
6608  *              of tuples in [\c begin,\c end) format.
6609  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
6610  *          is to delete using decrRef() as it is no more needed.
6611  *  \throw If \a end < \a begin.
6612  *  \throw If \a end > \a this->getNumberOfTuples().
6613  *  \throw If \a this is not allocated.
6614  */
6615 DataArray *DataArrayInt::selectByTupleRanges(const std::vector<std::pair<int,int> >& ranges) const throw(INTERP_KERNEL::Exception)
6616 {
6617   checkAllocated();
6618   int nbOfComp=getNumberOfComponents();
6619   int nbOfTuplesThis=getNumberOfTuples();
6620   if(ranges.empty())
6621     {
6622       MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6623       ret->alloc(0,nbOfComp);
6624       ret->copyStringInfoFrom(*this);
6625       return ret.retn();
6626     }
6627   int ref=ranges.front().first;
6628   int nbOfTuples=0;
6629   bool isIncreasing=true;
6630   for(std::vector<std::pair<int,int> >::const_iterator it=ranges.begin();it!=ranges.end();it++)
6631     {
6632       if((*it).first<=(*it).second)
6633         {
6634           if((*it).first>=0 && (*it).second<=nbOfTuplesThis)
6635             {
6636               nbOfTuples+=(*it).second-(*it).first;
6637               if(isIncreasing)
6638                 isIncreasing=ref<=(*it).first;
6639               ref=(*it).second;
6640             }
6641           else
6642             {
6643               std::ostringstream oss; oss << "DataArrayInt::selectByTupleRanges : on range #" << std::distance(ranges.begin(),it);
6644               oss << " (" << (*it).first << "," << (*it).second << ") is greater than number of tuples of this :" << nbOfTuples << " !";
6645               throw INTERP_KERNEL::Exception(oss.str().c_str());
6646             }
6647         }
6648       else
6649         {
6650           std::ostringstream oss; oss << "DataArrayInt::selectByTupleRanges : on range #" << std::distance(ranges.begin(),it);
6651           oss << " (" << (*it).first << "," << (*it).second << ") end is before begin !";
6652           throw INTERP_KERNEL::Exception(oss.str().c_str());
6653         }
6654     }
6655   if(isIncreasing && nbOfTuplesThis==nbOfTuples)
6656     return deepCpy();
6657   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6658   ret->alloc(nbOfTuples,nbOfComp);
6659   ret->copyStringInfoFrom(*this);
6660   const int *src=getConstPointer();
6661   int *work=ret->getPointer();
6662   for(std::vector<std::pair<int,int> >::const_iterator it=ranges.begin();it!=ranges.end();it++)
6663     work=std::copy(src+(*it).first*nbOfComp,src+(*it).second*nbOfComp,work);
6664   return ret.retn();
6665 }
6666
6667 /*!
6668  * Returns a new DataArrayInt containing a renumbering map in "Old to New" mode.
6669  * This map, if applied to \a this array, would make it sorted. For example, if
6670  * \a this array contents are [9,10,0,6,4,11,3,7] then the contents of the result array
6671  * are [5,6,0,3,2,7,1,4]; if this result array (\a res) is used as an argument in call
6672  * \a this->renumber(\a res) then the returned array contains [0,3,4,6,7,9,10,11].
6673  * This method is useful for renumbering (in MED file for example). For more info
6674  * on renumbering see \ref MEDCouplingArrayRenumbering.
6675  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
6676  *          array using decrRef() as it is no more needed.
6677  *  \throw If \a this is not allocated.
6678  *  \throw If \a this->getNumberOfComponents() != 1.
6679  *  \throw If there are equal values in \a this array.
6680  */
6681 DataArrayInt *DataArrayInt::checkAndPreparePermutation() const throw(INTERP_KERNEL::Exception)
6682 {
6683   checkAllocated();
6684   if(getNumberOfComponents()!=1)
6685     throw INTERP_KERNEL::Exception("DataArrayInt::checkAndPreparePermutation : number of components must == 1 !");
6686   int nbTuples=getNumberOfTuples();
6687   const int *pt=getConstPointer();
6688   int *pt2=CheckAndPreparePermutation(pt,pt+nbTuples);
6689   DataArrayInt *ret=DataArrayInt::New();
6690   ret->useArray(pt2,true,C_DEALLOC,nbTuples,1);
6691   return ret;
6692 }
6693
6694 /*!
6695  * Returns two arrays describing a surjective mapping from \a this set of values (\a A)
6696  * onto a set of values of size \a targetNb (\a B). The surjective function is 
6697  * \a B[ \a A[ i ]] = i. That is to say that for each \a id in [0,\a targetNb), where \a
6698  * targetNb < \a this->getNumberOfTuples(), there exists at least one tupleId (\a tid) so
6699  * that <em> this->getIJ( tid, 0 ) == id</em>. <br>
6700  * The first of out arrays returns indices of elements of \a this array, grouped by their
6701  * place in the set \a B. The second out array is the index of the first one; it shows how
6702  * many elements of \a A are mapped into each element of \a B. <br>
6703  * For more info on
6704  * mapping and its usage in renumbering see \ref MEDCouplingArrayRenumbering. <br>
6705  * \b Example:
6706  * - \a this: [0,3,2,3,2,2,1,2]
6707  * - \a targetNb: 4
6708  * - \a arr:  [0,  6,  2,4,5,7,  1,3]
6709  * - \a arrI: [0,1,2,6,8]
6710  *
6711  * This result means: <br>
6712  * the element of \a B 0 encounters within \a A once (\a arrI[ 0+1 ] - \a arrI[ 0 ]) and
6713  * its index within \a A is 0 ( \a arr[ 0:1 ] == \a arr[ \a arrI[ 0 ] : \a arrI[ 0+1 ]]);<br>
6714  * the element of \a B 2 encounters within \a A 4 times (\a arrI[ 2+1 ] - \a arrI[ 2 ]) and
6715  * its indices within \a A are [2,4,5,7] ( \a arr[ 2:6 ] == \a arr[ \a arrI[ 2 ] : 
6716  * \a arrI[ 2+1 ]]); <br> etc.
6717  *  \param [in] targetNb - the size of the set \a B. \a targetNb must be equal or more
6718  *         than the maximal value of \a A.
6719  *  \param [out] arr - a new instance of DataArrayInt returning indices of
6720  *         elements of \a this, grouped by their place in the set \a B. The caller is to delete
6721  *         this array using decrRef() as it is no more needed.
6722  *  \param [out] arrI - a new instance of DataArrayInt returning size of groups of equal
6723  *         elements of \a this. The caller is to delete this array using decrRef() as it
6724  *         is no more needed.
6725  *  \throw If \a this is not allocated.
6726  *  \throw If \a this->getNumberOfComponents() != 1.
6727  *  \throw If any value in \a this is more or equal to \a targetNb.
6728  */
6729 void DataArrayInt::changeSurjectiveFormat(int targetNb, DataArrayInt *&arr, DataArrayInt *&arrI) const throw(INTERP_KERNEL::Exception)
6730 {
6731   checkAllocated();
6732   if(getNumberOfComponents()!=1)
6733     throw INTERP_KERNEL::Exception("DataArrayInt::changeSurjectiveFormat : number of components must == 1 !");
6734   int nbOfTuples=getNumberOfTuples();
6735   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New());
6736   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> retI(DataArrayInt::New());
6737   retI->alloc(targetNb+1,1);
6738   const int *input=getConstPointer();
6739   std::vector< std::vector<int> > tmp(targetNb);
6740   for(int i=0;i<nbOfTuples;i++)
6741     {
6742       int tmp2=input[i];
6743       if(tmp2>=0 && tmp2<targetNb)
6744         tmp[tmp2].push_back(i);
6745       else
6746         {
6747           std::ostringstream oss; oss << "DataArrayInt::changeSurjectiveFormat : At pos " << i << " presence of element " << tmp2 << " ! should be in [0," << targetNb << ") !";
6748           throw INTERP_KERNEL::Exception(oss.str().c_str());
6749         }
6750     }
6751   int *retIPtr=retI->getPointer();
6752   *retIPtr=0;
6753   for(std::vector< std::vector<int> >::const_iterator it1=tmp.begin();it1!=tmp.end();it1++,retIPtr++)
6754     retIPtr[1]=retIPtr[0]+(int)((*it1).size());
6755   if(nbOfTuples!=retI->getIJ(targetNb,0))
6756     throw INTERP_KERNEL::Exception("DataArrayInt::changeSurjectiveFormat : big problem should never happen !");
6757   ret->alloc(nbOfTuples,1);
6758   int *retPtr=ret->getPointer();
6759   for(std::vector< std::vector<int> >::const_iterator it1=tmp.begin();it1!=tmp.end();it1++)
6760     retPtr=std::copy((*it1).begin(),(*it1).end(),retPtr);
6761   arr=ret.retn();
6762   arrI=retI.retn();
6763 }
6764
6765
6766 /*!
6767  * Returns a new DataArrayInt containing a renumbering map in "Old to New" mode computed
6768  * from a zip representation of a surjective format (returned e.g. by
6769  * \ref ParaMEDMEM::DataArrayDouble::findCommonTuples() "DataArrayDouble::findCommonTuples()"
6770  * for example). The result array minimizes the permutation. <br>
6771  * For more info on renumbering see \ref MEDCouplingArrayRenumbering. <br>
6772  * \b Example: <br>
6773  * - \a nbOfOldTuples: 10 
6774  * - \a arr          : [0,3, 5,7,9]
6775  * - \a arrIBg       : [0,2,5]
6776  * - \a newNbOfTuples: 7
6777  * - result array    : [0,1,2,0,3,4,5,4,6,4]
6778  *
6779  *  \param [in] nbOfOldTuples - number of tuples in the initial array \a arr.
6780  *  \param [in] arr - the array of tuple indices grouped by \a arrIBg array.
6781  *  \param [in] arrIBg - the array dividing all indices stored in \a arr into groups of
6782  *         (indices of) equal values. Its every element (except the last one) points to
6783  *         the first element of a group of equal values.
6784  *  \param [in] arrIEnd - specifies the end of \a arrIBg, so that the last element of \a
6785  *          arrIBg is \a arrIEnd[ -1 ].
6786  *  \param [out] newNbOfTuples - number of tuples after surjection application.
6787  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
6788  *          array using decrRef() as it is no more needed.
6789  *  \throw If any value of \a arr breaks condition ( 0 <= \a arr[ i ] < \a nbOfOldTuples ).
6790  */
6791 DataArrayInt *DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2(int nbOfOldTuples, const int *arr, const int *arrIBg, const int *arrIEnd, int &newNbOfTuples) throw(INTERP_KERNEL::Exception)
6792 {
6793   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6794   ret->alloc(nbOfOldTuples,1);
6795   int *pt=ret->getPointer();
6796   std::fill(pt,pt+nbOfOldTuples,-1);
6797   int nbOfGrps=((int)std::distance(arrIBg,arrIEnd))-1;
6798   const int *cIPtr=arrIBg;
6799   for(int i=0;i<nbOfGrps;i++)
6800     pt[arr[cIPtr[i]]]=-(i+2);
6801   int newNb=0;
6802   for(int iNode=0;iNode<nbOfOldTuples;iNode++)
6803     {
6804       if(pt[iNode]<0)
6805         {
6806           if(pt[iNode]==-1)
6807             pt[iNode]=newNb++;
6808           else
6809             {
6810               int grpId=-(pt[iNode]+2);
6811               for(int j=cIPtr[grpId];j<cIPtr[grpId+1];j++)
6812                 {
6813                   if(arr[j]>=0 && arr[j]<nbOfOldTuples)
6814                     pt[arr[j]]=newNb;
6815                   else
6816                     {
6817                       std::ostringstream oss; oss << "DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2 : With element #" << j << " value is " << arr[j] << " should be in [0," << nbOfOldTuples << ") !";
6818                       throw INTERP_KERNEL::Exception(oss.str().c_str());
6819                     }
6820                 }
6821               newNb++;
6822             }
6823         }
6824     }
6825   newNbOfTuples=newNb;
6826   return ret.retn();
6827 }
6828
6829 /*!
6830  * Returns a new DataArrayInt containing a renumbering map in "New to Old" mode,
6831  * which if applied to \a this array would make it sorted ascendingly.
6832  * For more info on renumbering see \ref MEDCouplingArrayRenumbering. <br>
6833  * \b Example: <br>
6834  * - \a this: [2,0,1,1,0,1,2,0,1,1,0,0]
6835  * - result: [10,0,5,6,1,7,11,2,8,9,3,4]
6836  * - after applying result to \a this: [0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2] 
6837  *
6838  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
6839  *          array using decrRef() as it is no more needed.
6840  *  \throw If \a this is not allocated.
6841  *  \throw If \a this->getNumberOfComponents() != 1.
6842  */
6843 DataArrayInt *DataArrayInt::buildPermArrPerLevel() const throw(INTERP_KERNEL::Exception)
6844 {
6845   checkAllocated();
6846   if(getNumberOfComponents()!=1)
6847     throw INTERP_KERNEL::Exception("DataArrayInt::buildPermArrPerLevel : number of components must == 1 !");
6848   int nbOfTuples=getNumberOfTuples();
6849   const int *pt=getConstPointer();
6850   std::map<int,int> m;
6851   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6852   ret->alloc(nbOfTuples,1);
6853   int *opt=ret->getPointer();
6854   for(int i=0;i<nbOfTuples;i++,pt++,opt++)
6855     {
6856       int val=*pt;
6857       std::map<int,int>::iterator it=m.find(val);
6858       if(it!=m.end())
6859         {
6860           *opt=(*it).second;
6861           (*it).second++;
6862         }
6863       else
6864         {
6865           *opt=0;
6866           m.insert(std::pair<int,int>(val,1));
6867         }
6868     }
6869   int sum=0;
6870   for(std::map<int,int>::iterator it=m.begin();it!=m.end();it++)
6871     {
6872       int vt=(*it).second;
6873       (*it).second=sum;
6874       sum+=vt;
6875     }
6876   pt=getConstPointer();
6877   opt=ret->getPointer();
6878   for(int i=0;i<nbOfTuples;i++,pt++,opt++)
6879     *opt+=m[*pt];
6880   //
6881   return ret.retn();
6882 }
6883
6884 /*!
6885  * Checks if contents of \a this array are equal to that of an array filled with
6886  * iota(). This method is particularly useful for DataArrayInt instances that represent
6887  * a renumbering array to check the real need in renumbering. 
6888  *  \return bool - \a true if \a this array contents == \a range( \a this->getNumberOfTuples())
6889  *  \throw If \a this is not allocated.
6890  *  \throw If \a this->getNumberOfComponents() != 1.
6891  */
6892 bool DataArrayInt::isIdentity() const throw(INTERP_KERNEL::Exception)
6893 {
6894   checkAllocated();
6895   if(getNumberOfComponents()!=1)
6896     return false;
6897   int nbOfTuples=getNumberOfTuples();
6898   const int *pt=getConstPointer();
6899   for(int i=0;i<nbOfTuples;i++,pt++)
6900     if(*pt!=i)
6901       return false;
6902   return true;
6903 }
6904
6905 /*!
6906  * Checks if all values in \a this array are equal to \a val.
6907  *  \param [in] val - value to check equality of array values to.
6908  *  \return bool - \a true if all values are \a val.
6909  *  \throw If \a this is not allocated.
6910  *  \throw If \a this->getNumberOfComponents() != 1
6911  */
6912 bool DataArrayInt::isUniform(int val) const throw(INTERP_KERNEL::Exception)
6913 {
6914   checkAllocated();
6915   if(getNumberOfComponents()!=1)
6916     throw INTERP_KERNEL::Exception("DataArrayInt::isUniform : must be applied on DataArrayInt with only one component, you can call 'rearrange' method before !");
6917   int nbOfTuples=getNumberOfTuples();
6918   const int *w=getConstPointer();
6919   const int *end2=w+nbOfTuples;
6920   for(;w!=end2;w++)
6921     if(*w!=val)
6922       return false;
6923   return true;
6924 }
6925
6926 /*!
6927  * Creates a new DataArrayDouble and assigns all (textual and numerical) data of \a this
6928  * array to the new one.
6929  *  \return DataArrayDouble * - the new instance of DataArrayInt.
6930  */
6931 DataArrayDouble *DataArrayInt::convertToDblArr() const
6932 {
6933   checkAllocated();
6934   DataArrayDouble *ret=DataArrayDouble::New();
6935   ret->alloc(getNumberOfTuples(),getNumberOfComponents());
6936   std::size_t nbOfVals=getNbOfElems();
6937   const int *src=getConstPointer();
6938   double *dest=ret->getPointer();
6939   std::copy(src,src+nbOfVals,dest);
6940   ret->copyStringInfoFrom(*this);
6941   return ret;
6942 }
6943
6944 /*!
6945  * Returns a shorten copy of \a this array. The new DataArrayInt contains all
6946  * tuples starting from the \a tupleIdBg-th tuple and including all tuples located before
6947  * the \a tupleIdEnd-th one. This methods has a similar behavior as std::string::substr().
6948  * This method is a specialization of selectByTupleId2().
6949  *  \param [in] tupleIdBg - index of the first tuple to copy from \a this array.
6950  *  \param [in] tupleIdEnd - index of the tuple before which the tuples to copy are located.
6951  *          If \a tupleIdEnd == -1, all the tuples till the end of \a this array are copied.
6952  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
6953  *          is to delete using decrRef() as it is no more needed.
6954  *  \throw If \a tupleIdBg < 0.
6955  *  \throw If \a tupleIdBg > \a this->getNumberOfTuples().
6956     \throw If \a tupleIdEnd != -1 && \a tupleIdEnd < \a this->getNumberOfTuples().
6957  *  \sa DataArrayInt::selectByTupleId2
6958  */
6959 DataArrayInt *DataArrayInt::substr(int tupleIdBg, int tupleIdEnd) const throw(INTERP_KERNEL::Exception)
6960 {
6961   checkAllocated();
6962   int nbt=getNumberOfTuples();
6963   if(tupleIdBg<0)
6964     throw INTERP_KERNEL::Exception("DataArrayInt::substr : The tupleIdBg parameter must be greater than 0 !");
6965   if(tupleIdBg>nbt)
6966     throw INTERP_KERNEL::Exception("DataArrayInt::substr : The tupleIdBg parameter is greater than number of tuples !");
6967   int trueEnd=tupleIdEnd;
6968   if(tupleIdEnd!=-1)
6969     {
6970       if(tupleIdEnd>nbt)
6971         throw INTERP_KERNEL::Exception("DataArrayInt::substr : The tupleIdBg parameter is greater or equal than number of tuples !");
6972     }
6973   else
6974     trueEnd=nbt;
6975   int nbComp=getNumberOfComponents();
6976   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6977   ret->alloc(trueEnd-tupleIdBg,nbComp);
6978   ret->copyStringInfoFrom(*this);
6979   std::copy(getConstPointer()+tupleIdBg*nbComp,getConstPointer()+trueEnd*nbComp,ret->getPointer());
6980   return ret.retn();
6981 }
6982
6983 /*!
6984  * Changes the number of components within \a this array so that its raw data **does
6985  * not** change, instead splitting this data into tuples changes.
6986  *  \warning This method erases all (name and unit) component info set before!
6987  *  \param [in] newNbOfComp - number of components for \a this array to have.
6988  *  \throw If \a this is not allocated
6989  *  \throw If getNbOfElems() % \a newNbOfCompo != 0.
6990  *  \throw If \a newNbOfCompo is lower than 1.
6991  *  \throw If the rearrange method would lead to a number of tuples higher than 2147483647 (maximal capacity of int32 !).
6992  *  \warning This method erases all (name and unit) component info set before!
6993  */
6994 void DataArrayInt::rearrange(int newNbOfCompo) throw(INTERP_KERNEL::Exception)
6995 {
6996   checkAllocated();
6997   if(newNbOfCompo<1)
6998     throw INTERP_KERNEL::Exception("DataArrayInt::rearrange : input newNbOfCompo must be > 0 !");
6999   std::size_t nbOfElems=getNbOfElems();
7000   if(nbOfElems%newNbOfCompo!=0)
7001     throw INTERP_KERNEL::Exception("DataArrayInt::rearrange : nbOfElems%newNbOfCompo!=0 !");
7002   if(nbOfElems/newNbOfCompo>(std::size_t)std::numeric_limits<int>::max())
7003     throw INTERP_KERNEL::Exception("DataArrayInt::rearrange : the rearrangement leads to too high number of tuples (> 2147483647) !");
7004   _info_on_compo.clear();
7005   _info_on_compo.resize(newNbOfCompo);
7006   declareAsNew();
7007 }
7008
7009 /*!
7010  * Changes the number of components within \a this array to be equal to its number
7011  * of tuples, and inversely its number of tuples to become equal to its number of 
7012  * components. So that its raw data **does not** change, instead splitting this
7013  * data into tuples changes.
7014  *  \warning This method erases all (name and unit) component info set before!
7015  *  \warning Do not confuse this method with fromNoInterlace() and toNoInterlace()!
7016  *  \throw If \a this is not allocated.
7017  *  \sa rearrange()
7018  */
7019 void DataArrayInt::transpose() throw(INTERP_KERNEL::Exception)
7020 {
7021   checkAllocated();
7022   int nbOfTuples=getNumberOfTuples();
7023   rearrange(nbOfTuples);
7024 }
7025
7026 /*!
7027  * Returns a shorten or extended copy of \a this array. If \a newNbOfComp is less
7028  * than \a this->getNumberOfComponents() then the result array is shorten as each tuple
7029  * is truncated to have \a newNbOfComp components, keeping first components. If \a
7030  * newNbOfComp is more than \a this->getNumberOfComponents() then the result array is
7031  * expanded as each tuple is populated with \a dftValue to have \a newNbOfComp
7032  * components.  
7033  *  \param [in] newNbOfComp - number of components for the new array to have.
7034  *  \param [in] dftValue - value assigned to new values added to the new array.
7035  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
7036  *          is to delete using decrRef() as it is no more needed.
7037  *  \throw If \a this is not allocated.
7038  */
7039 DataArrayInt *DataArrayInt::changeNbOfComponents(int newNbOfComp, int dftValue) const throw(INTERP_KERNEL::Exception)
7040 {
7041   checkAllocated();
7042   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
7043   ret->alloc(getNumberOfTuples(),newNbOfComp);
7044   const int *oldc=getConstPointer();
7045   int *nc=ret->getPointer();
7046   int nbOfTuples=getNumberOfTuples();
7047   int oldNbOfComp=getNumberOfComponents();
7048   int dim=std::min(oldNbOfComp,newNbOfComp);
7049   for(int i=0;i<nbOfTuples;i++)
7050     {
7051       int j=0;
7052       for(;j<dim;j++)
7053         nc[newNbOfComp*i+j]=oldc[i*oldNbOfComp+j];
7054       for(;j<newNbOfComp;j++)
7055         nc[newNbOfComp*i+j]=dftValue;
7056     }
7057   ret->setName(getName().c_str());
7058   for(int i=0;i<dim;i++)
7059     ret->setInfoOnComponent(i,getInfoOnComponent(i).c_str());
7060   ret->setName(getName().c_str());
7061   return ret.retn();
7062 }
7063
7064 /*!
7065  * Changes number of tuples in the array. If the new number of tuples is smaller
7066  * than the current number the array is truncated, otherwise the array is extended.
7067  *  \param [in] nbOfTuples - new number of tuples. 
7068  *  \throw If \a this is not allocated.
7069  */
7070 void DataArrayInt::reAlloc(int nbOfTuples) throw(INTERP_KERNEL::Exception)
7071 {
7072   checkAllocated();
7073   _mem.reAlloc(getNumberOfComponents()*(std::size_t)nbOfTuples);
7074   declareAsNew();
7075 }
7076
7077
7078 /*!
7079  * Returns a copy of \a this array composed of selected components.
7080  * The new DataArrayInt has the same number of tuples but includes components
7081  * specified by \a compoIds parameter. So that getNbOfElems() of the result array
7082  * can be either less, same or more than \a this->getNbOfElems().
7083  *  \param [in] compoIds - sequence of zero based indices of components to include
7084  *              into the new array.
7085  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
7086  *          is to delete using decrRef() as it is no more needed.
7087  *  \throw If \a this is not allocated.
7088  *  \throw If a component index (\a i) is not valid: 
7089  *         \a i < 0 || \a i >= \a this->getNumberOfComponents().
7090  *
7091  *  \ref py_mcdataarrayint_keepselectedcomponents "Here is a Python example".
7092  */
7093 DataArray *DataArrayInt::keepSelectedComponents(const std::vector<int>& compoIds) const throw(INTERP_KERNEL::Exception)
7094 {
7095   checkAllocated();
7096   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New());
7097   int newNbOfCompo=(int)compoIds.size();
7098   int oldNbOfCompo=getNumberOfComponents();
7099   for(std::vector<int>::const_iterator it=compoIds.begin();it!=compoIds.end();it++)
7100     DataArray::CheckValueInRange(oldNbOfCompo,(*it),"keepSelectedComponents invalid requested component");
7101   int nbOfTuples=getNumberOfTuples();
7102   ret->alloc(nbOfTuples,newNbOfCompo);
7103   ret->copyPartOfStringInfoFrom(*this,compoIds);
7104   const int *oldc=getConstPointer();
7105   int *nc=ret->getPointer();
7106   for(int i=0;i<nbOfTuples;i++)
7107     for(int j=0;j<newNbOfCompo;j++,nc++)
7108       *nc=oldc[i*oldNbOfCompo+compoIds[j]];
7109   return ret.retn();
7110 }
7111
7112 /*!
7113  * Appends components of another array to components of \a this one, tuple by tuple.
7114  * So that the number of tuples of \a this array remains the same and the number of 
7115  * components increases.
7116  *  \param [in] other - the DataArrayInt to append to \a this one.
7117  *  \throw If \a this is not allocated.
7118  *  \throw If \a this and \a other arrays have different number of tuples.
7119  *
7120  *  \ref cpp_mcdataarrayint_meldwith "Here is a C++ example".
7121  *
7122  *  \ref py_mcdataarrayint_meldwith "Here is a Python example".
7123  */
7124 void DataArrayInt::meldWith(const DataArrayInt *other) throw(INTERP_KERNEL::Exception)
7125 {
7126   if(!other)
7127     throw INTERP_KERNEL::Exception("DataArrayInt::meldWith : DataArrayInt pointer in input is NULL !");
7128   checkAllocated();
7129   other->checkAllocated();
7130   int nbOfTuples=getNumberOfTuples();
7131   if(nbOfTuples!=other->getNumberOfTuples())
7132     throw INTERP_KERNEL::Exception("DataArrayInt::meldWith : mismatch of number of tuples !");
7133   int nbOfComp1=getNumberOfComponents();
7134   int nbOfComp2=other->getNumberOfComponents();
7135   int *newArr=(int *)malloc(nbOfTuples*(nbOfComp1+nbOfComp2)*sizeof(int));
7136   int *w=newArr;
7137   const int *inp1=getConstPointer();
7138   const int *inp2=other->getConstPointer();
7139   for(int i=0;i<nbOfTuples;i++,inp1+=nbOfComp1,inp2+=nbOfComp2)
7140     {
7141       w=std::copy(inp1,inp1+nbOfComp1,w);
7142       w=std::copy(inp2,inp2+nbOfComp2,w);
7143     }
7144   useArray(newArr,true,C_DEALLOC,nbOfTuples,nbOfComp1+nbOfComp2);
7145   std::vector<int> compIds(nbOfComp2);
7146   for(int i=0;i<nbOfComp2;i++)
7147     compIds[i]=nbOfComp1+i;
7148   copyPartOfStringInfoFrom2(compIds,*other);
7149 }
7150
7151 /*!
7152  * Copy all components in a specified order from another DataArrayInt.
7153  * The specified components become the first ones in \a this array.
7154  * Both numerical and textual data is copied. The number of tuples in \a this and
7155  * the other array can be different.
7156  *  \param [in] a - the array to copy data from.
7157  *  \param [in] compoIds - sequence of zero based indices of components, data of which is
7158  *              to be copied.
7159  *  \throw If \a a is NULL.
7160  *  \throw If \a compoIds.size() != \a a->getNumberOfComponents().
7161  *  \throw If \a compoIds[i] < 0 or \a compoIds[i] > \a this->getNumberOfComponents().
7162  *
7163  *  \ref py_mcdataarrayint_setselectedcomponents "Here is a Python example".
7164  */
7165 void DataArrayInt::setSelectedComponents(const DataArrayInt *a, const std::vector<int>& compoIds) throw(INTERP_KERNEL::Exception)
7166 {
7167   if(!a)
7168     throw INTERP_KERNEL::Exception("DataArrayInt::setSelectedComponents : input DataArrayInt is NULL !");
7169   checkAllocated();
7170   a->checkAllocated();
7171   copyPartOfStringInfoFrom2(compoIds,*a);
7172   std::size_t partOfCompoSz=compoIds.size();
7173   int nbOfCompo=getNumberOfComponents();
7174   int nbOfTuples=std::min(getNumberOfTuples(),a->getNumberOfTuples());
7175   const int *ac=a->getConstPointer();
7176   int *nc=getPointer();
7177   for(int i=0;i<nbOfTuples;i++)
7178     for(std::size_t j=0;j<partOfCompoSz;j++,ac++)
7179       nc[nbOfCompo*i+compoIds[j]]=*ac;
7180 }
7181
7182 /*!
7183  * Copy all values from another DataArrayInt into specified tuples and components
7184  * of \a this array. Textual data is not copied.
7185  * The tree parameters defining set of indices of tuples and components are similar to
7186  * the tree parameters of the Python function \c range(\c start,\c stop,\c step).
7187  *  \param [in] a - the array to copy values from.
7188  *  \param [in] bgTuples - index of the first tuple of \a this array to assign values to.
7189  *  \param [in] endTuples - index of the tuple before which the tuples to assign to
7190  *              are located.
7191  *  \param [in] stepTuples - index increment to get index of the next tuple to assign to.
7192  *  \param [in] bgComp - index of the first component of \a this array to assign values to.
7193  *  \param [in] endComp - index of the component before which the components to assign
7194  *              to are located.
7195  *  \param [in] stepComp - index increment to get index of the next component to assign to.
7196  *  \param [in] strictCompoCompare - if \a true (by default), then \a a->getNumberOfComponents() 
7197  *              must be equal to the number of columns to assign to, else an
7198  *              exception is thrown; if \a false, then it is only required that \a
7199  *              a->getNbOfElems() equals to number of values to assign to (this condition
7200  *              must be respected even if \a strictCompoCompare is \a true). The number of 
7201  *              values to assign to is given by following Python expression:
7202  *              \a nbTargetValues = 
7203  *              \c len(\c range(\a bgTuples,\a endTuples,\a stepTuples)) *
7204  *              \c len(\c range(\a bgComp,\a endComp,\a stepComp)).
7205  *  \throw If \a a is NULL.
7206  *  \throw If \a a is not allocated.
7207  *  \throw If \a this is not allocated.
7208  *  \throw If parameters specifying tuples and components to assign to do not give a
7209  *            non-empty range of increasing indices.
7210  *  \throw If \a a->getNbOfElems() != \a nbTargetValues.
7211  *  \throw If \a strictCompoCompare == \a true && \a a->getNumberOfComponents() !=
7212  *            \c len(\c range(\a bgComp,\a endComp,\a stepComp)).
7213  *
7214  *  \ref py_mcdataarrayint_setpartofvalues1 "Here is a Python example".
7215  */
7216 void DataArrayInt::setPartOfValues1(const DataArrayInt *a, int bgTuples, int endTuples, int stepTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare) throw(INTERP_KERNEL::Exception)
7217 {
7218   if(!a)
7219     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValues1 : DataArrayInt pointer in input is NULL !");
7220   const char msg[]="DataArrayInt::setPartOfValues1";
7221   checkAllocated();
7222   a->checkAllocated();
7223   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
7224   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
7225   int nbComp=getNumberOfComponents();
7226   int nbOfTuples=getNumberOfTuples();
7227   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
7228   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
7229   bool assignTech=true;
7230   if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
7231     {
7232       if(strictCompoCompare)
7233         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
7234     }
7235   else
7236     {
7237       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
7238       assignTech=false;
7239     }
7240   int *pt=getPointer()+bgTuples*nbComp+bgComp;
7241   const int *srcPt=a->getConstPointer();
7242   if(assignTech)
7243     {
7244       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
7245         for(int j=0;j<newNbOfComp;j++,srcPt++)
7246           pt[j*stepComp]=*srcPt;
7247     }
7248   else
7249     {
7250       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
7251         {
7252           const int *srcPt2=srcPt;
7253           for(int j=0;j<newNbOfComp;j++,srcPt2++)
7254             pt[j*stepComp]=*srcPt2;
7255         }
7256     }
7257 }
7258
7259 /*!
7260  * Assign a given value to values at specified tuples and components of \a this array.
7261  * The tree parameters defining set of indices of tuples and components are similar to
7262  * the tree parameters of the Python function \c range(\c start,\c stop,\c step)..
7263  *  \param [in] a - the value to assign.
7264  *  \param [in] bgTuples - index of the first tuple of \a this array to assign to.
7265  *  \param [in] endTuples - index of the tuple before which the tuples to assign to
7266  *              are located.
7267  *  \param [in] stepTuples - index increment to get index of the next tuple to assign to.
7268  *  \param [in] bgComp - index of the first component of \a this array to assign to.
7269  *  \param [in] endComp - index of the component before which the components to assign
7270  *              to are located.
7271  *  \param [in] stepComp - index increment to get index of the next component to assign to.
7272  *  \throw If \a this is not allocated.
7273  *  \throw If parameters specifying tuples and components to assign to, do not give a
7274  *            non-empty range of increasing indices or indices are out of a valid range
7275  *            for \this array.
7276  *
7277  *  \ref py_mcdataarrayint_setpartofvaluessimple1 "Here is a Python example".
7278  */
7279 void DataArrayInt::setPartOfValuesSimple1(int a, int bgTuples, int endTuples, int stepTuples, int bgComp, int endComp, int stepComp) throw(INTERP_KERNEL::Exception)
7280 {
7281   const char msg[]="DataArrayInt::setPartOfValuesSimple1";
7282   checkAllocated();
7283   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
7284   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
7285   int nbComp=getNumberOfComponents();
7286   int nbOfTuples=getNumberOfTuples();
7287   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
7288   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
7289   int *pt=getPointer()+bgTuples*nbComp+bgComp;
7290   for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
7291     for(int j=0;j<newNbOfComp;j++)
7292       pt[j*stepComp]=a;
7293 }
7294
7295
7296 /*!
7297  * Copy all values from another DataArrayInt (\a a) into specified tuples and 
7298  * components of \a this array. Textual data is not copied.
7299  * The tuples and components to assign to are defined by C arrays of indices.
7300  * There are two *modes of usage*:
7301  * - If \a a->getNbOfElems() equals to number of values to assign to, then every value
7302  *   of \a a is assigned to its own location within \a this array. 
7303  * - If \a a includes one tuple, then all values of \a a are assigned to the specified
7304  *   components of every specified tuple of \a this array. In this mode it is required
7305  *   that \a a->getNumberOfComponents() equals to the number of specified components.
7306  * 
7307  *  \param [in] a - the array to copy values from.
7308  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
7309  *              assign values of \a a to.
7310  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
7311  *              pointer to a tuple index <em>(pi)</em> varies as this: 
7312  *              \a bgTuples <= \a pi < \a endTuples.
7313  *  \param [in] bgComp - pointer to an array of component indices of \a this array to
7314  *              assign values of \a a to.
7315  *  \param [in] endComp - specifies the end of the array \a bgTuples, so that
7316  *              pointer to a component index <em>(pi)</em> varies as this: 
7317  *              \a bgComp <= \a pi < \a endComp.
7318  *  \param [in] strictCompoCompare - this parameter is checked only if the
7319  *               *mode of usage* is the first; if it is \a true (default), 
7320  *               then \a a->getNumberOfComponents() must be equal 
7321  *               to the number of specified columns, else this is not required.
7322  *  \throw If \a a is NULL.
7323  *  \throw If \a a is not allocated.
7324  *  \throw If \a this is not allocated.
7325  *  \throw If any index of tuple/component given by <em>bgTuples / bgComp</em> is
7326  *         out of a valid range for \a this array.
7327  *  \throw In the first *mode of usage*, if <em>strictCompoCompare == true </em> and
7328  *         if <em> a->getNumberOfComponents() != (endComp - bgComp) </em>.
7329  *  \throw In the second *mode of usage*, if \a a->getNumberOfTuples() != 1 or
7330  *         <em> a->getNumberOfComponents() != (endComp - bgComp)</em>.
7331  *
7332  *  \ref py_mcdataarrayint_setpartofvalues2 "Here is a Python example".
7333  */
7334 void DataArrayInt::setPartOfValues2(const DataArrayInt *a, const int *bgTuples, const int *endTuples, const int *bgComp, const int *endComp, bool strictCompoCompare) throw(INTERP_KERNEL::Exception)
7335 {
7336   if(!a)
7337     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValues2 : DataArrayInt pointer in input is NULL !");
7338   const char msg[]="DataArrayInt::setPartOfValues2";
7339   checkAllocated();
7340   a->checkAllocated();
7341   int nbComp=getNumberOfComponents();
7342   int nbOfTuples=getNumberOfTuples();
7343   for(const int *z=bgComp;z!=endComp;z++)
7344     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
7345   int newNbOfTuples=(int)std::distance(bgTuples,endTuples);
7346   int newNbOfComp=(int)std::distance(bgComp,endComp);
7347   bool assignTech=true;
7348   if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
7349     {
7350       if(strictCompoCompare)
7351         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
7352     }
7353   else
7354     {
7355       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
7356       assignTech=false;
7357     }
7358   int *pt=getPointer();
7359   const int *srcPt=a->getConstPointer();
7360   if(assignTech)
7361     {    
7362       for(const int *w=bgTuples;w!=endTuples;w++)
7363         {
7364           DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
7365           for(const int *z=bgComp;z!=endComp;z++,srcPt++)
7366             {    
7367               pt[(std::size_t)(*w)*nbComp+(*z)]=*srcPt;
7368             }
7369         }
7370     }
7371   else
7372     {
7373       for(const int *w=bgTuples;w!=endTuples;w++)
7374         {
7375           const int *srcPt2=srcPt;
7376           DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
7377           for(const int *z=bgComp;z!=endComp;z++,srcPt2++)
7378             {    
7379               pt[(std::size_t)(*w)*nbComp+(*z)]=*srcPt2;
7380             }
7381         }
7382     }
7383 }
7384
7385 /*!
7386  * Assign a given value to values at specified tuples and components of \a this array.
7387  * The tuples and components to assign to are defined by C arrays of indices.
7388  *  \param [in] a - the value to assign.
7389  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
7390  *              assign \a a to.
7391  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
7392  *              pointer to a tuple index (\a pi) varies as this: 
7393  *              \a bgTuples <= \a pi < \a endTuples.
7394  *  \param [in] bgComp - pointer to an array of component indices of \a this array to
7395  *              assign \a a to.
7396  *  \param [in] endComp - specifies the end of the array \a bgTuples, so that
7397  *              pointer to a component index (\a pi) varies as this: 
7398  *              \a bgComp <= \a pi < \a endComp.
7399  *  \throw If \a this is not allocated.
7400  *  \throw If any index of tuple/component given by <em>bgTuples / bgComp</em> is
7401  *         out of a valid range for \a this array.
7402  *
7403  *  \ref py_mcdataarrayint_setpartofvaluessimple2 "Here is a Python example".
7404  */
7405 void DataArrayInt::setPartOfValuesSimple2(int a, const int *bgTuples, const int *endTuples, const int *bgComp, const int *endComp) throw(INTERP_KERNEL::Exception)
7406 {
7407   checkAllocated();
7408   int nbComp=getNumberOfComponents();
7409   int nbOfTuples=getNumberOfTuples();
7410   for(const int *z=bgComp;z!=endComp;z++)
7411     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
7412   int *pt=getPointer();
7413   for(const int *w=bgTuples;w!=endTuples;w++)
7414     for(const int *z=bgComp;z!=endComp;z++)
7415       {
7416         DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
7417         pt[(std::size_t)(*w)*nbComp+(*z)]=a;
7418       }
7419 }
7420
7421 /*!
7422  * Copy all values from another DataArrayInt (\a a) into specified tuples and 
7423  * components of \a this array. Textual data is not copied.
7424  * The tuples to assign to are defined by a C array of indices.
7425  * The components to assign to are defined by three values similar to parameters of
7426  * the Python function \c range(\c start,\c stop,\c step).
7427  * There are two *modes of usage*:
7428  * - If \a a->getNbOfElems() equals to number of values to assign to, then every value
7429  *   of \a a is assigned to its own location within \a this array. 
7430  * - If \a a includes one tuple, then all values of \a a are assigned to the specified
7431  *   components of every specified tuple of \a this array. In this mode it is required
7432  *   that \a a->getNumberOfComponents() equals to the number of specified components.
7433  *
7434  *  \param [in] a - the array to copy values from.
7435  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
7436  *              assign values of \a a to.
7437  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
7438  *              pointer to a tuple index <em>(pi)</em> varies as this: 
7439  *              \a bgTuples <= \a pi < \a endTuples.
7440  *  \param [in] bgComp - index of the first component of \a this array to assign to.
7441  *  \param [in] endComp - index of the component before which the components to assign
7442  *              to are located.
7443  *  \param [in] stepComp - index increment to get index of the next component to assign to.
7444  *  \param [in] strictCompoCompare - this parameter is checked only in the first
7445  *               *mode of usage*; if \a strictCompoCompare is \a true (default), 
7446  *               then \a a->getNumberOfComponents() must be equal 
7447  *               to the number of specified columns, else this is not required.
7448  *  \throw If \a a is NULL.
7449  *  \throw If \a a is not allocated.
7450  *  \throw If \a this is not allocated.
7451  *  \throw If any index of tuple given by \a bgTuples is out of a valid range for 
7452  *         \a this array.
7453  *  \throw In the first *mode of usage*, if <em>strictCompoCompare == true </em> and
7454  *         if <em> a->getNumberOfComponents()</em> is unequal to the number of components
7455  *         defined by <em>(bgComp,endComp,stepComp)</em>.
7456  *  \throw In the second *mode of usage*, if \a a->getNumberOfTuples() != 1 or
7457  *         <em> a->getNumberOfComponents()</em> is unequal to the number of components
7458  *         defined by <em>(bgComp,endComp,stepComp)</em>.
7459  *  \throw If parameters specifying components to assign to, do not give a
7460  *            non-empty range of increasing indices or indices are out of a valid range
7461  *            for \this array.
7462  *
7463  *  \ref py_mcdataarrayint_setpartofvalues3 "Here is a Python example".
7464  */
7465 void DataArrayInt::setPartOfValues3(const DataArrayInt *a, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare) throw(INTERP_KERNEL::Exception)
7466 {
7467   if(!a)
7468     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValues3 : DataArrayInt pointer in input is NULL !");
7469   const char msg[]="DataArrayInt::setPartOfValues3";
7470   checkAllocated();
7471   a->checkAllocated();
7472   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
7473   int nbComp=getNumberOfComponents();
7474   int nbOfTuples=getNumberOfTuples();
7475   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
7476   int newNbOfTuples=(int)std::distance(bgTuples,endTuples);
7477   bool assignTech=true;
7478   if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
7479     {
7480       if(strictCompoCompare)
7481         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
7482     }
7483   else
7484     {
7485       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
7486       assignTech=false;
7487     }
7488   int *pt=getPointer()+bgComp;
7489   const int *srcPt=a->getConstPointer();
7490   if(assignTech)
7491     {
7492       for(const int *w=bgTuples;w!=endTuples;w++)
7493         for(int j=0;j<newNbOfComp;j++,srcPt++)
7494           {
7495             DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
7496             pt[(std::size_t)(*w)*nbComp+j*stepComp]=*srcPt;
7497           }
7498     }
7499   else
7500     {
7501       for(const int *w=bgTuples;w!=endTuples;w++)
7502         {
7503           const int *srcPt2=srcPt;
7504           for(int j=0;j<newNbOfComp;j++,srcPt2++)
7505             {
7506               DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
7507               pt[(std::size_t)(*w)*nbComp+j*stepComp]=*srcPt2;
7508             }
7509         }
7510     }
7511 }
7512
7513 /*!
7514  * Assign a given value to values at specified tuples and components of \a this array.
7515  * The tuples to assign to are defined by a C array of indices.
7516  * The components to assign to are defined by three values similar to parameters of
7517  * the Python function \c range(\c start,\c stop,\c step).
7518  *  \param [in] a - the value to assign.
7519  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
7520  *              assign \a a to.
7521  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
7522  *              pointer to a tuple index <em>(pi)</em> varies as this: 
7523  *              \a bgTuples <= \a pi < \a endTuples.
7524  *  \param [in] bgComp - index of the first component of \a this array to assign to.
7525  *  \param [in] endComp - index of the component before which the components to assign
7526  *              to are located.
7527  *  \param [in] stepComp - index increment to get index of the next component to assign to.
7528  *  \throw If \a this is not allocated.
7529  *  \throw If any index of tuple given by \a bgTuples is out of a valid range for 
7530  *         \a this array.
7531  *  \throw If parameters specifying components to assign to, do not give a
7532  *            non-empty range of increasing indices or indices are out of a valid range
7533  *            for \this array.
7534  *
7535  *  \ref py_mcdataarrayint_setpartofvaluessimple3 "Here is a Python example".
7536  */
7537 void DataArrayInt::setPartOfValuesSimple3(int a, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp) throw(INTERP_KERNEL::Exception)
7538 {
7539   const char msg[]="DataArrayInt::setPartOfValuesSimple3";
7540   checkAllocated();
7541   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
7542   int nbComp=getNumberOfComponents();
7543   int nbOfTuples=getNumberOfTuples();
7544   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
7545   int *pt=getPointer()+bgComp;
7546   for(const int *w=bgTuples;w!=endTuples;w++)
7547     for(int j=0;j<newNbOfComp;j++)
7548       {
7549         DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
7550         pt[(std::size_t)(*w)*nbComp+j*stepComp]=a;
7551       }
7552 }
7553
7554 void DataArrayInt::setPartOfValues4(const DataArrayInt *a, int bgTuples, int endTuples, int stepTuples, const int *bgComp, const int *endComp, bool strictCompoCompare) throw(INTERP_KERNEL::Exception)
7555 {
7556   if(!a)
7557     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValues4 : input DataArrayInt is NULL !");
7558   const char msg[]="DataArrayInt::setPartOfValues4";
7559   checkAllocated();
7560   a->checkAllocated();
7561   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
7562   int newNbOfComp=(int)std::distance(bgComp,endComp);
7563   int nbComp=getNumberOfComponents();
7564   for(const int *z=bgComp;z!=endComp;z++)
7565     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
7566   int nbOfTuples=getNumberOfTuples();
7567   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
7568   bool assignTech=true;
7569   if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
7570     {
7571       if(strictCompoCompare)
7572         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
7573     }
7574   else
7575     {
7576       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
7577       assignTech=false;
7578     }
7579   const int *srcPt=a->getConstPointer();
7580   int *pt=getPointer()+bgTuples*nbComp;
7581   if(assignTech)
7582     {
7583       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
7584         for(const int *z=bgComp;z!=endComp;z++,srcPt++)
7585           pt[*z]=*srcPt;
7586     }
7587   else
7588     {
7589       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
7590         {
7591           const int *srcPt2=srcPt;
7592           for(const int *z=bgComp;z!=endComp;z++,srcPt2++)
7593             pt[*z]=*srcPt2;
7594         }
7595     }
7596 }
7597
7598 void DataArrayInt::setPartOfValuesSimple4(int a, int bgTuples, int endTuples, int stepTuples, const int *bgComp, const int *endComp) throw(INTERP_KERNEL::Exception)
7599 {
7600   const char msg[]="DataArrayInt::setPartOfValuesSimple4";
7601   checkAllocated();
7602   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
7603   int nbComp=getNumberOfComponents();
7604   for(const int *z=bgComp;z!=endComp;z++)
7605     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
7606   int nbOfTuples=getNumberOfTuples();
7607   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
7608   int *pt=getPointer()+bgTuples*nbComp;
7609   for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
7610     for(const int *z=bgComp;z!=endComp;z++)
7611       pt[*z]=a;
7612 }
7613
7614 /*!
7615  * Copy some tuples from another DataArrayInt into specified tuples
7616  * of \a this array. Textual data is not copied. Both arrays must have equal number of
7617  * components.
7618  * Both the tuples to assign and the tuples to assign to are defined by a DataArrayInt.
7619  * All components of selected tuples are copied.
7620  *  \param [in] a - the array to copy values from.
7621  *  \param [in] tuplesSelec - the array specifying both source tuples of \a a and
7622  *              target tuples of \a this. \a tuplesSelec has two components, and the
7623  *              first component specifies index of the source tuple and the second
7624  *              one specifies index of the target tuple.
7625  *  \throw If \a this is not allocated.
7626  *  \throw If \a a is NULL.
7627  *  \throw If \a a is not allocated.
7628  *  \throw If \a tuplesSelec is NULL.
7629  *  \throw If \a tuplesSelec is not allocated.
7630  *  \throw If <em>this->getNumberOfComponents() != a->getNumberOfComponents()</em>.
7631  *  \throw If \a tuplesSelec->getNumberOfComponents() != 2.
7632  *  \throw If any tuple index given by \a tuplesSelec is out of a valid range for 
7633  *         the corresponding (\a this or \a a) array.
7634  */
7635 void DataArrayInt::setPartOfValuesAdv(const DataArrayInt *a, const DataArrayInt *tuplesSelec) throw(INTERP_KERNEL::Exception)
7636 {
7637   if(!a || !tuplesSelec)
7638     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValuesAdv : DataArrayInt pointer in input is NULL !");
7639   checkAllocated();
7640   a->checkAllocated();
7641   tuplesSelec->checkAllocated();
7642   int nbOfComp=getNumberOfComponents();
7643   if(nbOfComp!=a->getNumberOfComponents())
7644     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValuesAdv : This and a do not have the same number of components !");
7645   if(tuplesSelec->getNumberOfComponents()!=2)
7646     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValuesAdv : Expecting to have a tuple selector DataArrayInt instance with exactly 2 components !");
7647   int thisNt=getNumberOfTuples();
7648   int aNt=a->getNumberOfTuples();
7649   int *valsToSet=getPointer();
7650   const int *valsSrc=a->getConstPointer();
7651   for(const int *tuple=tuplesSelec->begin();tuple!=tuplesSelec->end();tuple+=2)
7652     {
7653       if(tuple[1]>=0 && tuple[1]<aNt)
7654         {
7655           if(tuple[0]>=0 && tuple[0]<thisNt)
7656             std::copy(valsSrc+nbOfComp*tuple[1],valsSrc+nbOfComp*(tuple[1]+1),valsToSet+nbOfComp*tuple[0]);
7657           else
7658             {
7659               std::ostringstream oss; oss << "DataArrayInt::setPartOfValuesAdv : Tuple #" << std::distance(tuplesSelec->begin(),tuple)/2;
7660               oss << " of 'tuplesSelec' request of tuple id #" << tuple[0] << " in 'this' ! It should be in [0," << thisNt << ") !";
7661               throw INTERP_KERNEL::Exception(oss.str().c_str());
7662             }
7663         }
7664       else
7665         {
7666           std::ostringstream oss; oss << "DataArrayInt::setPartOfValuesAdv : Tuple #" << std::distance(tuplesSelec->begin(),tuple)/2;
7667           oss << " of 'tuplesSelec' request of tuple id #" << tuple[1] << " in 'a' ! It should be in [0," << aNt << ") !";
7668           throw INTERP_KERNEL::Exception(oss.str().c_str());
7669         }
7670     }
7671 }
7672
7673 /*!
7674  * Copy some tuples from another DataArrayInt (\a a) into contiguous tuples
7675  * of \a this array. Textual data is not copied. Both arrays must have equal number of
7676  * components.
7677  * The tuples to assign to are defined by index of the first tuple, and
7678  * their number is defined by \a tuplesSelec->getNumberOfTuples().
7679  * The tuples to copy are defined by values of a DataArrayInt.
7680  * All components of selected tuples are copied.
7681  *  \param [in] tupleIdStart - index of the first tuple of \a this array to assign
7682  *              values to.
7683  *  \param [in] a - the array to copy values from.
7684  *  \param [in] tuplesSelec - the array specifying tuples of \a a to copy.
7685  *  \throw If \a this is not allocated.
7686  *  \throw If \a a is NULL.
7687  *  \throw If \a a is not allocated.
7688  *  \throw If \a tuplesSelec is NULL.
7689  *  \throw If \a tuplesSelec is not allocated.
7690  *  \throw If <em>this->getNumberOfComponents() != a->getNumberOfComponents()</em>.
7691  *  \throw If \a tuplesSelec->getNumberOfComponents() != 1.
7692  *  \throw If <em>tupleIdStart + tuplesSelec->getNumberOfTuples() > this->getNumberOfTuples().</em>
7693  *  \throw If any tuple index given by \a tuplesSelec is out of a valid range for 
7694  *         \a a array.
7695  */
7696 void DataArrayInt::setContigPartOfSelectedValues(int tupleIdStart, const DataArray *aBase, const DataArrayInt *tuplesSelec) throw(INTERP_KERNEL::Exception)
7697 {
7698   if(!aBase || !tuplesSelec)
7699     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues : input DataArray is NULL !");
7700   const DataArrayInt *a=dynamic_cast<const DataArrayInt *>(aBase);
7701   if(!a)
7702     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues : input DataArray aBase is not a DataArrayInt !");
7703   checkAllocated();
7704   a->checkAllocated();
7705   tuplesSelec->checkAllocated();
7706   int nbOfComp=getNumberOfComponents();
7707   if(nbOfComp!=a->getNumberOfComponents())
7708     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues : This and a do not have the same number of components !");
7709   if(tuplesSelec->getNumberOfComponents()!=1)
7710     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues : Expecting to have a tuple selector DataArrayInt instance with exactly 1 component !");
7711   int thisNt=getNumberOfTuples();
7712   int aNt=a->getNumberOfTuples();
7713   int nbOfTupleToWrite=tuplesSelec->getNumberOfTuples();
7714   int *valsToSet=getPointer()+tupleIdStart*nbOfComp;
7715   if(tupleIdStart+nbOfTupleToWrite>thisNt)
7716     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues : invalid number range of values to write !");
7717   const int *valsSrc=a->getConstPointer();
7718   for(const int *tuple=tuplesSelec->begin();tuple!=tuplesSelec->end();tuple++,valsToSet+=nbOfComp)
7719     {
7720       if(*tuple>=0 && *tuple<aNt)
7721         {
7722           std::copy(valsSrc+nbOfComp*(*tuple),valsSrc+nbOfComp*(*tuple+1),valsToSet);
7723         }
7724       else
7725         {
7726           std::ostringstream oss; oss << "DataArrayInt::setContigPartOfSelectedValues : Tuple #" << std::distance(tuplesSelec->begin(),tuple);
7727           oss << " of 'tuplesSelec' request of tuple id #" << *tuple << " in 'a' ! It should be in [0," << aNt << ") !";
7728           throw INTERP_KERNEL::Exception(oss.str().c_str());
7729         }
7730     }
7731 }
7732
7733 /*!
7734  * Copy some tuples from another DataArrayInt (\a a) into contiguous tuples
7735  * of \a this array. Textual data is not copied. Both arrays must have equal number of
7736  * components.
7737  * The tuples to copy are defined by three values similar to parameters of
7738  * the Python function \c range(\c start,\c stop,\c step).
7739  * The tuples to assign to are defined by index of the first tuple, and
7740  * their number is defined by number of tuples to copy.
7741  * All components of selected tuples are copied.
7742  *  \param [in] tupleIdStart - index of the first tuple of \a this array to assign
7743  *              values to.
7744  *  \param [in] a - the array to copy values from.
7745  *  \param [in] bg - index of the first tuple to copy of the array \a a.
7746  *  \param [in] end2 - index of the tuple of \a a before which the tuples to copy
7747  *              are located.
7748  *  \param [in] step - index increment to get index of the next tuple to copy.
7749  *  \throw If \a this is not allocated.
7750  *  \throw If \a a is NULL.
7751  *  \throw If \a a is not allocated.
7752  *  \throw If <em>this->getNumberOfComponents() != a->getNumberOfComponents()</em>.
7753  *  \throw If <em>tupleIdStart + len(range(bg,end2,step)) > this->getNumberOfTuples().</em>
7754  *  \throw If parameters specifying tuples to copy, do not give a
7755  *            non-empty range of increasing indices or indices are out of a valid range
7756  *            for the array \a a.
7757  */
7758 void DataArrayInt::setContigPartOfSelectedValues2(int tupleIdStart, const DataArray *aBase, int bg, int end2, int step) throw(INTERP_KERNEL::Exception)
7759 {
7760   if(!aBase)
7761     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues2 : input DataArray is NULL !");
7762   const DataArrayInt *a=dynamic_cast<const DataArrayInt *>(aBase);
7763   if(!a)
7764     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues2 : input DataArray aBase is not a DataArrayInt !");
7765   checkAllocated();
7766   a->checkAllocated();
7767   int nbOfComp=getNumberOfComponents();
7768   const char msg[]="DataArrayInt::setContigPartOfSelectedValues2";
7769   int nbOfTupleToWrite=DataArray::GetNumberOfItemGivenBES(bg,end2,step,msg);
7770   if(nbOfComp!=a->getNumberOfComponents())
7771     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues2 : This and a do not have the same number of components !");
7772   int thisNt=getNumberOfTuples();
7773   int aNt=a->getNumberOfTuples();
7774   int *valsToSet=getPointer()+tupleIdStart*nbOfComp;
7775   if(tupleIdStart+nbOfTupleToWrite>thisNt)
7776     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues2 : invalid number range of values to write !");
7777   if(end2>aNt)
7778     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues2 : invalid range of values to read !");
7779   const int *valsSrc=a->getConstPointer()+bg*nbOfComp;
7780   for(int i=0;i<nbOfTupleToWrite;i++,valsToSet+=nbOfComp,valsSrc+=step*nbOfComp)
7781     {
7782       std::copy(valsSrc,valsSrc+nbOfComp,valsToSet);
7783     }
7784 }
7785
7786 /*!
7787  * Returns a value located at specified tuple and component.
7788  * This method is equivalent to DataArrayInt::getIJ() except that validity of
7789  * parameters is checked. So this method is safe but expensive if used to go through
7790  * all values of \a this.
7791  *  \param [in] tupleId - index of tuple of interest.
7792  *  \param [in] compoId - index of component of interest.
7793  *  \return double - value located by \a tupleId and \a compoId.
7794  *  \throw If \a this is not allocated.
7795  *  \throw If condition <em>( 0 <= tupleId < this->getNumberOfTuples() )</em> is violated.
7796  *  \throw If condition <em>( 0 <= compoId < this->getNumberOfComponents() )</em> is violated.
7797  */
7798 int DataArrayInt::getIJSafe(int tupleId, int compoId) const throw(INTERP_KERNEL::Exception)
7799 {
7800   checkAllocated();
7801   if(tupleId<0 || tupleId>=getNumberOfTuples())
7802     {
7803       std::ostringstream oss; oss << "DataArrayInt::getIJSafe : request for tupleId " << tupleId << " should be in [0," << getNumberOfTuples() << ") !";
7804       throw INTERP_KERNEL::Exception(oss.str().c_str());
7805     }
7806   if(compoId<0 || compoId>=getNumberOfComponents())
7807     {
7808       std::ostringstream oss; oss << "DataArrayInt::getIJSafe : request for compoId " << compoId << " should be in [0," << getNumberOfComponents() << ") !";
7809       throw INTERP_KERNEL::Exception(oss.str().c_str());
7810     }
7811   return _mem[tupleId*_info_on_compo.size()+compoId];
7812 }
7813
7814 /*!
7815  * Returns the last value of \a this. 
7816  *  \return double - the last value of \a this array.
7817  *  \throw If \a this is not allocated.
7818  *  \throw If \a this->getNumberOfComponents() != 1.
7819  *  \throw If \a this->getNumberOfTuples() < 1.
7820  */
7821 int DataArrayInt::back() const throw(INTERP_KERNEL::Exception)
7822 {
7823   checkAllocated();
7824   if(getNumberOfComponents()!=1)
7825     throw INTERP_KERNEL::Exception("DataArrayInt::back : number of components not equal to one !");
7826   int nbOfTuples=getNumberOfTuples();
7827   if(nbOfTuples<1)
7828     throw INTERP_KERNEL::Exception("DataArrayInt::back : number of tuples must be >= 1 !");
7829   return *(getConstPointer()+nbOfTuples-1);
7830 }
7831
7832 /*!
7833  * Assign pointer to one array to a pointer to another appay. Reference counter of
7834  * \a arrayToSet is incremented / decremented.
7835  *  \param [in] newArray - the pointer to array to assign to \a arrayToSet.
7836  *  \param [in,out] arrayToSet - the pointer to array to assign to.
7837  */
7838 void DataArrayInt::SetArrayIn(DataArrayInt *newArray, DataArrayInt* &arrayToSet)
7839 {
7840   if(newArray!=arrayToSet)
7841     {
7842       if(arrayToSet)
7843         arrayToSet->decrRef();
7844       arrayToSet=newArray;
7845       if(arrayToSet)
7846         arrayToSet->incrRef();
7847     }
7848 }
7849
7850 DataArrayIntIterator *DataArrayInt::iterator() throw(INTERP_KERNEL::Exception)
7851 {
7852   return new DataArrayIntIterator(this);
7853 }
7854
7855 /*!
7856  * Creates a new DataArrayInt containing IDs (indices) of tuples holding value equal to a
7857  * given one.
7858  *  \param [in] val - the value to find within \a this.
7859  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
7860  *          array using decrRef() as it is no more needed.
7861  *  \throw If \a this is not allocated.
7862  *  \throw If \a this->getNumberOfComponents() != 1.
7863  */
7864 DataArrayInt *DataArrayInt::getIdsEqual(int val) const throw(INTERP_KERNEL::Exception)
7865 {
7866   checkAllocated();
7867   if(getNumberOfComponents()!=1)
7868     throw INTERP_KERNEL::Exception("DataArrayInt::getIdsEqual : the array must have only one component, you can call 'rearrange' method before !");
7869   const int *cptr=getConstPointer();
7870   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
7871   int nbOfTuples=getNumberOfTuples();
7872   for(int i=0;i<nbOfTuples;i++,cptr++)
7873     if(*cptr==val)
7874       ret->pushBackSilent(i);
7875   return ret.retn();
7876 }
7877
7878 /*!
7879  * Creates a new DataArrayInt containing IDs (indices) of tuples holding value \b not
7880  * equal to a given one. 
7881  *  \param [in] val - the value to ignore within \a this.
7882  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
7883  *          array using decrRef() as it is no more needed.
7884  *  \throw If \a this is not allocated.
7885  *  \throw If \a this->getNumberOfComponents() != 1.
7886  */
7887 DataArrayInt *DataArrayInt::getIdsNotEqual(int val) const throw(INTERP_KERNEL::Exception)
7888 {
7889   checkAllocated();
7890   if(getNumberOfComponents()!=1)
7891     throw INTERP_KERNEL::Exception("DataArrayInt::getIdsNotEqual : the array must have only one component, you can call 'rearrange' method before !");
7892   const int *cptr=getConstPointer();
7893   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
7894   int nbOfTuples=getNumberOfTuples();
7895   for(int i=0;i<nbOfTuples;i++,cptr++)
7896     if(*cptr!=val)
7897       ret->pushBackSilent(i);
7898   return ret.retn();
7899 }
7900
7901
7902 /*!
7903  * Assigns \a newValue to all elements holding \a oldValue within \a this
7904  * one-dimensional array.
7905  *  \param [in] oldValue - the value to replace.
7906  *  \param [in] newValue - the value to assign.
7907  *  \return int - number of replacements performed.
7908  *  \throw If \a this is not allocated.
7909  *  \throw If \a this->getNumberOfComponents() != 1.
7910  */
7911 int DataArrayInt::changeValue(int oldValue, int newValue) throw(INTERP_KERNEL::Exception)
7912 {
7913   checkAllocated();
7914   if(getNumberOfComponents()!=1)
7915     throw INTERP_KERNEL::Exception("DataArrayInt::changeValue : the array must have only one component, you can call 'rearrange' method before !");
7916   int *start=getPointer();
7917   int *end2=start+getNbOfElems();
7918   int ret=0;
7919   for(int *val=start;val!=end2;val++)
7920     {
7921       if(*val==oldValue)
7922         {
7923           *val=newValue;
7924           ret++;
7925         }
7926     }
7927   return ret;
7928 }
7929
7930 /*!
7931  * Creates a new DataArrayInt containing IDs (indices) of tuples holding value equal to
7932  * one of given values.
7933  *  \param [in] valsBg - an array of values to find within \a this array.
7934  *  \param [in] valsEnd - specifies the end of the array \a valsBg, so that
7935  *              the last value of \a valsBg is \a valsEnd[ -1 ].
7936  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
7937  *          array using decrRef() as it is no more needed.
7938  *  \throw If \a this->getNumberOfComponents() != 1.
7939  */
7940 DataArrayInt *DataArrayInt::getIdsEqualList(const int *valsBg, const int *valsEnd) const throw(INTERP_KERNEL::Exception)
7941 {
7942   if(getNumberOfComponents()!=1)
7943     throw INTERP_KERNEL::Exception("DataArrayInt::getIdsEqualList : the array must have only one component, you can call 'rearrange' method before !");
7944   std::set<int> vals2(valsBg,valsEnd);
7945   const int *cptr=getConstPointer();
7946   std::vector<int> res;
7947   int nbOfTuples=getNumberOfTuples();
7948   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
7949   for(int i=0;i<nbOfTuples;i++,cptr++)
7950     if(vals2.find(*cptr)!=vals2.end())
7951       ret->pushBackSilent(i);
7952   return ret.retn();
7953 }
7954
7955 /*!
7956  * Creates a new DataArrayInt containing IDs (indices) of tuples holding values \b not
7957  * equal to any of given values.
7958  *  \param [in] valsBg - an array of values to ignore within \a this array.
7959  *  \param [in] valsEnd - specifies the end of the array \a valsBg, so that
7960  *              the last value of \a valsBg is \a valsEnd[ -1 ].
7961  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
7962  *          array using decrRef() as it is no more needed.
7963  *  \throw If \a this->getNumberOfComponents() != 1.
7964  */
7965 DataArrayInt *DataArrayInt::getIdsNotEqualList(const int *valsBg, const int *valsEnd) const throw(INTERP_KERNEL::Exception)
7966 {
7967   if(getNumberOfComponents()!=1)
7968     throw INTERP_KERNEL::Exception("DataArrayInt::getIdsNotEqualList : the array must have only one component, you can call 'rearrange' method before !");
7969   std::set<int> vals2(valsBg,valsEnd);
7970   const int *cptr=getConstPointer();
7971   std::vector<int> res;
7972   int nbOfTuples=getNumberOfTuples();
7973   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
7974   for(int i=0;i<nbOfTuples;i++,cptr++)
7975     if(vals2.find(*cptr)==vals2.end())
7976       ret->pushBackSilent(i);
7977   return ret.retn();
7978 }
7979
7980 /*!
7981  * This method is an extension of DataArrayInt::locateValue method because this method works for DataArrayInt with
7982  * any number of components excepted 0 (an INTERP_KERNEL::Exception is thrown in this case).
7983  * This method searches in \b this is there is a tuple that matched the input parameter \b tupl.
7984  * If any the tuple id is returned. If not -1 is returned.
7985  * 
7986  * This method throws an INTERP_KERNEL::Exception if the number of components in \b this mismatches with the size of
7987  * the input vector. An INTERP_KERNEL::Exception is thrown too if \b this is not allocated.
7988  *
7989  * \return tuple id where \b tupl is. -1 if no such tuple exists in \b this.
7990  * \sa DataArrayInt::search, DataArrayInt::presenceOfTuple.
7991  */
7992 int DataArrayInt::locateTuple(const std::vector<int>& tupl) const throw(INTERP_KERNEL::Exception)
7993 {
7994   checkAllocated();
7995   int nbOfCompo=getNumberOfComponents();
7996   if(nbOfCompo==0)
7997     throw INTERP_KERNEL::Exception("DataArrayInt::locateTuple : 0 components in 'this' !");
7998   if(nbOfCompo!=(int)tupl.size())
7999     {
8000       std::ostringstream oss; oss << "DataArrayInt::locateTuple : 'this' contains " << nbOfCompo << " components and searching for a tuple of length " << tupl.size() << " !";
8001       throw INTERP_KERNEL::Exception(oss.str().c_str());
8002     }
8003   const int *cptr=getConstPointer();
8004   std::size_t nbOfVals=getNbOfElems();
8005   for(const int *work=cptr;work!=cptr+nbOfVals;)
8006     {
8007       work=std::search(work,cptr+nbOfVals,tupl.begin(),tupl.end());
8008       if(work!=cptr+nbOfVals)
8009         {
8010           if(std::distance(cptr,work)%nbOfCompo!=0)
8011             work++;
8012           else
8013             return std::distance(cptr,work)/nbOfCompo;
8014         }
8015     }
8016   return -1;
8017 }
8018
8019 /*!
8020  * This method searches the sequence specified in input parameter \b vals in \b this.
8021  * This works only for DataArrayInt having number of components equal to one (if not an INTERP_KERNEL::Exception will be thrown).
8022  * This method differs from DataArrayInt::locateTuple in that the position is internal raw data is not considered here contrary to DataArrayInt::locateTuple.
8023  * \sa DataArrayInt::locateTuple
8024  */
8025 int DataArrayInt::search(const std::vector<int>& vals) const throw(INTERP_KERNEL::Exception)
8026 {
8027   checkAllocated();
8028   int nbOfCompo=getNumberOfComponents();
8029   if(nbOfCompo!=1)
8030     throw INTERP_KERNEL::Exception("DataArrayInt::search : works only for DataArrayInt instance with one component !");
8031   const int *cptr=getConstPointer();
8032   std::size_t nbOfVals=getNbOfElems();
8033   const int *loc=std::search(cptr,cptr+nbOfVals,vals.begin(),vals.end());
8034   if(loc!=cptr+nbOfVals)
8035     return std::distance(cptr,loc);
8036   return -1;
8037 }
8038
8039 /*!
8040  * This method expects to be called when number of components of this is equal to one.
8041  * This method returns the tuple id, if it exists, of the first tuple equal to \b value.
8042  * If not any tuple contains \b value -1 is returned.
8043  * \sa DataArrayInt::presenceOfValue
8044  */
8045 int DataArrayInt::locateValue(int value) const throw(INTERP_KERNEL::Exception)
8046 {
8047   checkAllocated();
8048   if(getNumberOfComponents()!=1)
8049     throw INTERP_KERNEL::Exception("DataArrayInt::presenceOfValue : the array must have only one component, you can call 'rearrange' method before !");
8050   const int *cptr=getConstPointer();
8051   int nbOfTuples=getNumberOfTuples();
8052   const int *ret=std::find(cptr,cptr+nbOfTuples,value);
8053   if(ret!=cptr+nbOfTuples)
8054     return std::distance(cptr,ret);
8055   return -1;
8056 }
8057
8058 /*!
8059  * This method expects to be called when number of components of this is equal to one.
8060  * This method returns the tuple id, if it exists, of the first tuple so that the value is contained in \b vals.
8061  * If not any tuple contains one of the values contained in 'vals' false is returned.
8062  * \sa DataArrayInt::presenceOfValue
8063  */
8064 int DataArrayInt::locateValue(const std::vector<int>& vals) const throw(INTERP_KERNEL::Exception)
8065 {
8066   checkAllocated();
8067   if(getNumberOfComponents()!=1)
8068     throw INTERP_KERNEL::Exception("DataArrayInt::presenceOfValue : the array must have only one component, you can call 'rearrange' method before !");
8069   std::set<int> vals2(vals.begin(),vals.end());
8070   const int *cptr=getConstPointer();
8071   int nbOfTuples=getNumberOfTuples();
8072   for(const int *w=cptr;w!=cptr+nbOfTuples;w++)
8073     if(vals2.find(*w)!=vals2.end())
8074       return std::distance(cptr,w);
8075   return -1;
8076 }
8077
8078 /*!
8079  * This method returns the number of values in \a this that are equals to input parameter \a value.
8080  * This method only works for single component array.
8081  *
8082  * \return a value in [ 0, \c this->getNumberOfTuples() )
8083  *
8084  * \throw If \a this is not allocated
8085  *
8086  */
8087 int DataArrayInt::count(int value) const throw(INTERP_KERNEL::Exception)
8088 {
8089   int ret=0;
8090   checkAllocated();
8091   if(getNumberOfComponents()!=1)
8092     throw INTERP_KERNEL::Exception("DataArrayInt::count : must be applied on DataArrayInt with only one component, you can call 'rearrange' method before !");
8093   const int *vals=begin();
8094   int nbOfTuples=getNumberOfTuples();
8095   for(int i=0;i<nbOfTuples;i++,vals++)
8096     if(*vals==value)
8097       ret++;
8098   return ret;
8099 }
8100
8101 /*!
8102  * This method is an extension of DataArrayInt::presenceOfValue method because this method works for DataArrayInt with
8103  * any number of components excepted 0 (an INTERP_KERNEL::Exception is thrown in this case).
8104  * This method searches in \b this is there is a tuple that matched the input parameter \b tupl.
8105  * This method throws an INTERP_KERNEL::Exception if the number of components in \b this mismatches with the size of
8106  * the input vector. An INTERP_KERNEL::Exception is thrown too if \b this is not allocated.
8107  * \sa DataArrayInt::locateTuple
8108  */
8109 bool DataArrayInt::presenceOfTuple(const std::vector<int>& tupl) const throw(INTERP_KERNEL::Exception)
8110 {
8111   return locateTuple(tupl)!=-1;
8112 }
8113
8114
8115 /*!
8116  * Returns \a true if a given value is present within \a this one-dimensional array.
8117  *  \param [in] value - the value to find within \a this array.
8118  *  \return bool - \a true in case if \a value is present within \a this array.
8119  *  \throw If \a this is not allocated.
8120  *  \throw If \a this->getNumberOfComponents() != 1.
8121  *  \sa locateValue()
8122  */
8123 bool DataArrayInt::presenceOfValue(int value) const throw(INTERP_KERNEL::Exception)
8124 {
8125   return locateValue(value)!=-1;
8126 }
8127
8128 /*!
8129  * This method expects to be called when number of components of this is equal to one.
8130  * This method returns true if it exists a tuple so that the value is contained in \b vals.
8131  * If not any tuple contains one of the values contained in 'vals' false is returned.
8132  * \sa DataArrayInt::locateValue
8133  */
8134 bool DataArrayInt::presenceOfValue(const std::vector<int>& vals) const throw(INTERP_KERNEL::Exception)
8135 {
8136   return locateValue(vals)!=-1;
8137 }
8138
8139 /*!
8140  * Accumulates values of each component of \a this array.
8141  *  \param [out] res - an array of length \a this->getNumberOfComponents(), allocated 
8142  *         by the caller, that is filled by this method with sum value for each
8143  *         component.
8144  *  \throw If \a this is not allocated.
8145  */
8146 void DataArrayInt::accumulate(int *res) const throw(INTERP_KERNEL::Exception)
8147 {
8148   checkAllocated();
8149   const int *ptr=getConstPointer();
8150   int nbTuple=getNumberOfTuples();
8151   int nbComps=getNumberOfComponents();
8152   std::fill(res,res+nbComps,0);
8153   for(int i=0;i<nbTuple;i++)
8154     std::transform(ptr+i*nbComps,ptr+(i+1)*nbComps,res,res,std::plus<int>());
8155 }
8156
8157 int DataArrayInt::accumulate(int compId) const throw(INTERP_KERNEL::Exception)
8158 {
8159   checkAllocated();
8160   const int *ptr=getConstPointer();
8161   int nbTuple=getNumberOfTuples();
8162   int nbComps=getNumberOfComponents();
8163   if(compId<0 || compId>=nbComps)
8164     throw INTERP_KERNEL::Exception("DataArrayInt::accumulate : Invalid compId specified : No such nb of components !");
8165   int ret=0;
8166   for(int i=0;i<nbTuple;i++)
8167     ret+=ptr[i*nbComps+compId];
8168   return ret;
8169 }
8170
8171 /*!
8172  * This method accumulate using addition tuples in \a this using input index array [ \a bgOfIndex, \a endOfIndex ).
8173  * The returned array will have same number of components than \a this and number of tuples equal to
8174  * \c std::distance(bgOfIndex,endOfIndex) \b minus \b one.
8175  *
8176  * The input index array is expected to be ascendingly sorted in which the all referenced ids should be in [0, \c this->getNumberOfTuples).
8177  *
8178  * \param [in] bgOfIndex - begin (included) of the input index array.
8179  * \param [in] endOfIndex - end (excluded) of the input index array.
8180  * \return DataArrayInt * - the new instance having the same number of components than \a this.
8181  * 
8182  * \throw If bgOfIndex or end is NULL.
8183  * \throw If input index array is not ascendingly sorted.
8184  * \throw If there is an id in [ \a bgOfIndex, \a endOfIndex ) not in [0, \c this->getNumberOfTuples).
8185  * \throw If std::distance(bgOfIndex,endOfIndex)==0.
8186  */
8187 DataArrayInt *DataArrayInt::accumulatePerChunck(const int *bgOfIndex, const int *endOfIndex) const throw(INTERP_KERNEL::Exception)
8188 {
8189   if(!bgOfIndex || !endOfIndex)
8190     throw INTERP_KERNEL::Exception("DataArrayInt::accumulatePerChunck : input pointer NULL !");
8191   checkAllocated();
8192   int nbCompo=getNumberOfComponents();
8193   int nbOfTuples=getNumberOfTuples();
8194   int sz=(int)std::distance(bgOfIndex,endOfIndex);
8195   if(sz<1)
8196     throw INTERP_KERNEL::Exception("DataArrayInt::accumulatePerChunck : invalid size of input index array !");
8197   sz--;
8198   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(sz,nbCompo);
8199   const int *w=bgOfIndex;
8200   if(*w<0 || *w>=nbOfTuples)
8201     throw INTERP_KERNEL::Exception("DataArrayInt::accumulatePerChunck : The first element of the input index not in [0,nbOfTuples) !");
8202   const int *srcPt=begin()+(*w)*nbCompo;
8203   int *tmp=ret->getPointer();
8204   for(int i=0;i<sz;i++,tmp+=nbCompo,w++)
8205     {
8206       std::fill(tmp,tmp+nbCompo,0.);
8207       if(w[1]>=w[0])
8208         {
8209           for(int j=w[0];j<w[1];j++,srcPt+=nbCompo)
8210             {
8211               if(j>=0 && j<nbOfTuples)
8212                 std::transform(srcPt,srcPt+nbCompo,tmp,tmp,std::plus<int>());
8213               else
8214                 {
8215                   std::ostringstream oss; oss << "DataArrayInt::accumulatePerChunck : At rank #" << i << " the input index array points to id " << j << " should be in [0," << nbOfTuples << ") !";
8216                   throw INTERP_KERNEL::Exception(oss.str().c_str());
8217                 }
8218             }
8219         }
8220       else
8221         {
8222           std::ostringstream oss; oss << "DataArrayInt::accumulatePerChunck : At rank #" << i << " the input index array is not in ascendingly sorted.";
8223           throw INTERP_KERNEL::Exception(oss.str().c_str());
8224         }
8225     }
8226   ret->copyStringInfoFrom(*this);
8227   return ret.retn();
8228 }
8229
8230 /*!
8231  * Returns a new DataArrayInt by concatenating two given arrays, so that (1) the number
8232  * of tuples in the result array is <em> a1->getNumberOfTuples() + a2->getNumberOfTuples() -
8233  * offsetA2</em> and (2)
8234  * the number of component in the result array is same as that of each of given arrays.
8235  * First \a offsetA2 tuples of \a a2 are skipped and thus are missing from the result array.
8236  * Info on components is copied from the first of the given arrays. Number of components
8237  * in the given arrays must be the same.
8238  *  \param [in] a1 - an array to include in the result array.
8239  *  \param [in] a2 - another array to include in the result array.
8240  *  \param [in] offsetA2 - number of tuples of \a a2 to skip.
8241  *  \return DataArrayInt * - the new instance of DataArrayInt.
8242  *          The caller is to delete this result array using decrRef() as it is no more
8243  *          needed.
8244  *  \throw If either \a a1 or \a a2 is NULL.
8245  *  \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents().
8246  */
8247 DataArrayInt *DataArrayInt::Aggregate(const DataArrayInt *a1, const DataArrayInt *a2, int offsetA2)
8248 {
8249   if(!a1 || !a2)
8250     throw INTERP_KERNEL::Exception("DataArrayInt::Aggregate : input DataArrayInt instance is NULL !");
8251   int nbOfComp=a1->getNumberOfComponents();
8252   if(nbOfComp!=a2->getNumberOfComponents())
8253     throw INTERP_KERNEL::Exception("Nb of components mismatch for array Aggregation !");
8254   int nbOfTuple1=a1->getNumberOfTuples();
8255   int nbOfTuple2=a2->getNumberOfTuples();
8256   DataArrayInt *ret=DataArrayInt::New();
8257   ret->alloc(nbOfTuple1+nbOfTuple2-offsetA2,nbOfComp);
8258   int *pt=std::copy(a1->getConstPointer(),a1->getConstPointer()+nbOfTuple1*nbOfComp,ret->getPointer());
8259   std::copy(a2->getConstPointer()+offsetA2*nbOfComp,a2->getConstPointer()+nbOfTuple2*nbOfComp,pt);
8260   ret->copyStringInfoFrom(*a1);
8261   return ret;
8262 }
8263
8264 /*!
8265  * Returns a new DataArrayInt by concatenating all given arrays, so that (1) the number
8266  * of tuples in the result array is a sum of the number of tuples of given arrays and (2)
8267  * the number of component in the result array is same as that of each of given arrays.
8268  * Info on components is copied from the first of the given arrays. Number of components
8269  * in the given arrays must be  the same.
8270  *  \param [in] arr - a sequence of arrays to include in the result array.
8271  *  \return DataArrayInt * - the new instance of DataArrayInt.
8272  *          The caller is to delete this result array using decrRef() as it is no more
8273  *          needed.
8274  *  \throw If all arrays within \a arr are NULL.
8275  *  \throw If getNumberOfComponents() of arrays within \a arr.
8276  */
8277 DataArrayInt *DataArrayInt::Aggregate(const std::vector<const DataArrayInt *>& arr) throw(INTERP_KERNEL::Exception)
8278 {
8279   std::vector<const DataArrayInt *> a;
8280   for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
8281     if(*it4)
8282       a.push_back(*it4);
8283   if(a.empty())
8284     throw INTERP_KERNEL::Exception("DataArrayInt::Aggregate : input list must be NON EMPTY !");
8285   std::vector<const DataArrayInt *>::const_iterator it=a.begin();
8286   int nbOfComp=(*it)->getNumberOfComponents();
8287   int nbt=(*it++)->getNumberOfTuples();
8288   for(int i=1;it!=a.end();it++,i++)
8289     {
8290       if((*it)->getNumberOfComponents()!=nbOfComp)
8291         throw INTERP_KERNEL::Exception("DataArrayInt::Aggregate : Nb of components mismatch for array aggregation !");
8292       nbt+=(*it)->getNumberOfTuples();
8293     }
8294   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
8295   ret->alloc(nbt,nbOfComp);
8296   int *pt=ret->getPointer();
8297   for(it=a.begin();it!=a.end();it++)
8298     pt=std::copy((*it)->getConstPointer(),(*it)->getConstPointer()+(*it)->getNbOfElems(),pt);
8299   ret->copyStringInfoFrom(*(a[0]));
8300   return ret.retn();
8301 }
8302
8303 /*!
8304  * Returns the maximal value and its location within \a this one-dimensional array.
8305  *  \param [out] tupleId - index of the tuple holding the maximal value.
8306  *  \return int - the maximal value among all values of \a this array.
8307  *  \throw If \a this->getNumberOfComponents() != 1
8308  *  \throw If \a this->getNumberOfTuples() < 1
8309  */
8310 int DataArrayInt::getMaxValue(int& tupleId) const throw(INTERP_KERNEL::Exception)
8311 {
8312   checkAllocated();
8313   if(getNumberOfComponents()!=1)
8314     throw INTERP_KERNEL::Exception("DataArrayInt::getMaxValue : must be applied on DataArrayInt with only one component !");
8315   int nbOfTuples=getNumberOfTuples();
8316   if(nbOfTuples<=0)
8317     throw INTERP_KERNEL::Exception("DataArrayInt::getMaxValue : array exists but number of tuples must be > 0 !");
8318   const int *vals=getConstPointer();
8319   const int *loc=std::max_element(vals,vals+nbOfTuples);
8320   tupleId=(int)std::distance(vals,loc);
8321   return *loc;
8322 }
8323
8324 /*!
8325  * Returns the maximal value within \a this array that is allowed to have more than
8326  *  one component.
8327  *  \return int - the maximal value among all values of \a this array.
8328  *  \throw If \a this is not allocated.
8329  */
8330 int DataArrayInt::getMaxValueInArray() const throw(INTERP_KERNEL::Exception)
8331 {
8332   checkAllocated();
8333   const int *loc=std::max_element(begin(),end());
8334   return *loc;
8335 }
8336
8337 /*!
8338  * Returns the minimal value and its location within \a this one-dimensional array.
8339  *  \param [out] tupleId - index of the tuple holding the minimal value.
8340  *  \return int - the minimal value among all values of \a this array.
8341  *  \throw If \a this->getNumberOfComponents() != 1
8342  *  \throw If \a this->getNumberOfTuples() < 1
8343  */
8344 int DataArrayInt::getMinValue(int& tupleId) const throw(INTERP_KERNEL::Exception)
8345 {
8346   checkAllocated();
8347   if(getNumberOfComponents()!=1)
8348     throw INTERP_KERNEL::Exception("DataArrayInt::getMaxValue : must be applied on DataArrayInt with only one component !");
8349   int nbOfTuples=getNumberOfTuples();
8350   if(nbOfTuples<=0)
8351     throw INTERP_KERNEL::Exception("DataArrayInt::getMaxValue : array exists but number of tuples must be > 0 !");
8352   const int *vals=getConstPointer();
8353   const int *loc=std::min_element(vals,vals+nbOfTuples);
8354   tupleId=(int)std::distance(vals,loc);
8355   return *loc;
8356 }
8357
8358 /*!
8359  * Returns the minimal value within \a this array that is allowed to have more than
8360  *  one component.
8361  *  \return int - the minimal value among all values of \a this array.
8362  *  \throw If \a this is not allocated.
8363  */
8364 int DataArrayInt::getMinValueInArray() const throw(INTERP_KERNEL::Exception)
8365 {
8366   checkAllocated();
8367   const int *loc=std::min_element(begin(),end());
8368   return *loc;
8369 }
8370
8371 /*!
8372  * Converts every value of \a this array to its absolute value.
8373  *  \throw If \a this is not allocated.
8374  */
8375 void DataArrayInt::abs() throw(INTERP_KERNEL::Exception)
8376 {
8377   checkAllocated();
8378   int *ptr=getPointer();
8379   std::size_t nbOfElems=getNbOfElems();
8380   std::transform(ptr,ptr+nbOfElems,ptr,std::ptr_fun<int,int>(std::abs));
8381   declareAsNew();
8382 }
8383
8384 /*!
8385  * Apply a liner function to a given component of \a this array, so that
8386  * an array element <em>(x)</em> becomes \f$ a * x + b \f$.
8387  *  \param [in] a - the first coefficient of the function.
8388  *  \param [in] b - the second coefficient of the function.
8389  *  \param [in] compoId - the index of component to modify.
8390  *  \throw If \a this is not allocated.
8391  */
8392 void DataArrayInt::applyLin(int a, int b, int compoId) throw(INTERP_KERNEL::Exception)
8393 {
8394   checkAllocated();
8395   int *ptr=getPointer()+compoId;
8396   int nbOfComp=getNumberOfComponents();
8397   int nbOfTuple=getNumberOfTuples();
8398   for(int i=0;i<nbOfTuple;i++,ptr+=nbOfComp)
8399     *ptr=a*(*ptr)+b;
8400   declareAsNew();
8401 }
8402
8403 /*!
8404  * Apply a liner function to all elements of \a this array, so that
8405  * an element _x_ becomes \f$ a * x + b \f$.
8406  *  \param [in] a - the first coefficient of the function.
8407  *  \param [in] b - the second coefficient of the function.
8408  *  \throw If \a this is not allocated.
8409  */
8410 void DataArrayInt::applyLin(int a, int b) throw(INTERP_KERNEL::Exception)
8411 {
8412   checkAllocated();
8413   int *ptr=getPointer();
8414   std::size_t nbOfElems=getNbOfElems();
8415   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
8416     *ptr=a*(*ptr)+b;
8417   declareAsNew();
8418 }
8419
8420 /*!
8421  * Returns a full copy of \a this array except that sign of all elements is reversed.
8422  *  \return DataArrayInt * - the new instance of DataArrayInt containing the
8423  *          same number of tuples and component as \a this array.
8424  *          The caller is to delete this result array using decrRef() as it is no more
8425  *          needed.
8426  *  \throw If \a this is not allocated.
8427  */
8428 DataArrayInt *DataArrayInt::negate() const throw(INTERP_KERNEL::Exception)
8429 {
8430   checkAllocated();
8431   DataArrayInt *newArr=DataArrayInt::New();
8432   int nbOfTuples=getNumberOfTuples();
8433   int nbOfComp=getNumberOfComponents();
8434   newArr->alloc(nbOfTuples,nbOfComp);
8435   const int *cptr=getConstPointer();
8436   std::transform(cptr,cptr+nbOfTuples*nbOfComp,newArr->getPointer(),std::negate<int>());
8437   newArr->copyStringInfoFrom(*this);
8438   return newArr;
8439 }
8440
8441 /*!
8442  * Modify all elements of \a this array, so that
8443  * an element _x_ becomes \f$ numerator / x \f$.
8444  *  \warning If an exception is thrown because of presence of 0 element in \a this 
8445  *           array, all elements processed before detection of the zero element remain
8446  *           modified.
8447  *  \param [in] numerator - the numerator used to modify array elements.
8448  *  \throw If \a this is not allocated.
8449  *  \throw If there is an element equal to 0 in \a this array.
8450  */
8451 void DataArrayInt::applyInv(int numerator) throw(INTERP_KERNEL::Exception)
8452 {
8453   checkAllocated();
8454   int *ptr=getPointer();
8455   std::size_t nbOfElems=getNbOfElems();
8456   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
8457     {
8458       if(*ptr!=0)
8459         {
8460           *ptr=numerator/(*ptr);
8461         }
8462       else
8463         {
8464           std::ostringstream oss; oss << "DataArrayInt::applyInv : presence of null value in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
8465           oss << " !";
8466           throw INTERP_KERNEL::Exception(oss.str().c_str());
8467         }
8468     }
8469   declareAsNew();
8470 }
8471
8472 /*!
8473  * Modify all elements of \a this array, so that
8474  * an element _x_ becomes \f$ x / val \f$.
8475  *  \param [in] val - the denominator used to modify array elements.
8476  *  \throw If \a this is not allocated.
8477  *  \throw If \a val == 0.
8478  */
8479 void DataArrayInt::applyDivideBy(int val) throw(INTERP_KERNEL::Exception)
8480 {
8481   if(val==0)
8482     throw INTERP_KERNEL::Exception("DataArrayInt::applyDivideBy : Trying to divide by 0 !");
8483   checkAllocated();
8484   int *ptr=getPointer();
8485   std::size_t nbOfElems=getNbOfElems();
8486   std::transform(ptr,ptr+nbOfElems,ptr,std::bind2nd(std::divides<int>(),val));
8487   declareAsNew();
8488 }
8489
8490 /*!
8491  * Modify all elements of \a this array, so that
8492  * an element _x_ becomes  <em> x % val </em>.
8493  *  \param [in] val - the divisor used to modify array elements.
8494  *  \throw If \a this is not allocated.
8495  *  \throw If \a val <= 0.
8496  */
8497 void DataArrayInt::applyModulus(int val) throw(INTERP_KERNEL::Exception)
8498 {
8499   if(val<=0)
8500     throw INTERP_KERNEL::Exception("DataArrayInt::applyDivideBy : Trying to operate modulus on value <= 0 !");
8501   checkAllocated();
8502   int *ptr=getPointer();
8503   std::size_t nbOfElems=getNbOfElems();
8504   std::transform(ptr,ptr+nbOfElems,ptr,std::bind2nd(std::modulus<int>(),val));
8505   declareAsNew();
8506 }
8507
8508 /*!
8509  * This method works only on data array with one component.
8510  * This method returns a newly allocated array storing stored ascendantly tuple ids in \b this so that
8511  * this[*id] in [\b vmin,\b vmax)
8512  * 
8513  * \param [in] vmin begin of range. This value is included in range (included).
8514  * \param [in] vmax end of range. This value is \b not included in range (excluded).
8515  * \return a newly allocated data array that the caller should deal with.
8516  */
8517 DataArrayInt *DataArrayInt::getIdsInRange(int vmin, int vmax) const throw(INTERP_KERNEL::Exception)
8518 {
8519   checkAllocated();
8520   if(getNumberOfComponents()!=1)
8521     throw INTERP_KERNEL::Exception("DataArrayInt::getIdsInRange : this must have exactly one component !");
8522   const int *cptr=getConstPointer();
8523   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(0,1);
8524   int nbOfTuples=getNumberOfTuples();
8525   for(int i=0;i<nbOfTuples;i++,cptr++)
8526     if(*cptr>=vmin && *cptr<vmax)
8527       ret->pushBackSilent(i);
8528   return ret.retn();
8529 }
8530
8531 /*!
8532  * This method works only on data array with one component.
8533  * This method checks that all ids in \b this are in [ \b vmin, \b vmax ). If there is at least one element in \a this not in [ \b vmin, \b vmax ) an exception will be thrown.
8534  * 
8535  * \param [in] vmin begin of range. This value is included in range (included).
8536  * \param [in] vmax end of range. This value is \b not included in range (excluded).
8537  * \return if all ids in \a this are so that (*this)[i]==i for all i in [ 0, \c this->getNumberOfTuples() ).
8538  */
8539 bool DataArrayInt::checkAllIdsInRange(int vmin, int vmax) const throw(INTERP_KERNEL::Exception)
8540 {
8541   checkAllocated();
8542   if(getNumberOfComponents()!=1)
8543     throw INTERP_KERNEL::Exception("DataArrayInt::checkAllIdsInRange : this must have exactly one component !");
8544   int nbOfTuples=getNumberOfTuples();
8545   bool ret=true;
8546   const int *cptr=getConstPointer();
8547   for(int i=0;i<nbOfTuples;i++,cptr++)
8548     {
8549       if(*cptr>=vmin && *cptr<vmax)
8550         { ret=ret && *cptr==i; }
8551       else
8552         {
8553           std::ostringstream oss; oss << "DataArrayInt::checkAllIdsInRange : tuple #" << i << " has value " << *cptr << " should be in [" << vmin << "," << vmax << ") !";
8554           throw INTERP_KERNEL::Exception(oss.str().c_str());
8555         }
8556     }
8557   return ret;
8558 }
8559
8560 /*!
8561  * Modify all elements of \a this array, so that
8562  * an element _x_ becomes <em> val % x </em>.
8563  *  \warning If an exception is thrown because of presence of an element <= 0 in \a this 
8564  *           array, all elements processed before detection of the zero element remain
8565  *           modified.
8566  *  \param [in] val - the divident used to modify array elements.
8567  *  \throw If \a this is not allocated.
8568  *  \throw If there is an element equal to or less than 0 in \a this array.
8569  */
8570 void DataArrayInt::applyRModulus(int val) throw(INTERP_KERNEL::Exception)
8571 {
8572   checkAllocated();
8573   int *ptr=getPointer();
8574   std::size_t nbOfElems=getNbOfElems();
8575   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
8576     {
8577       if(*ptr>0)
8578         {
8579           *ptr=val%(*ptr);
8580         }
8581       else
8582         {
8583           std::ostringstream oss; oss << "DataArrayInt::applyRModulus : presence of value <=0 in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
8584           oss << " !";
8585           throw INTERP_KERNEL::Exception(oss.str().c_str());
8586         }
8587     }
8588   declareAsNew();
8589 }
8590
8591 /*!
8592  * Modify all elements of \a this array, so that
8593  * an element _x_ becomes <em> val ^ x </em>.
8594  *  \param [in] val - the value used to apply pow on all array elements.
8595  *  \throw If \a this is not allocated.
8596  *  \throw If \a val < 0.
8597  */
8598 void DataArrayInt::applyPow(int val) throw(INTERP_KERNEL::Exception)
8599 {
8600   checkAllocated();
8601   if(val<0)
8602     throw INTERP_KERNEL::Exception("DataArrayInt::applyPow : input pow in < 0 !");
8603   int *ptr=getPointer();
8604   std::size_t nbOfElems=getNbOfElems();
8605   if(val==0)
8606     {
8607       std::fill(ptr,ptr+nbOfElems,1.);
8608       return ;
8609     }
8610   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
8611     {
8612       int tmp=1;
8613       for(int j=0;j<val;j++)
8614         tmp*=*ptr;
8615       *ptr=tmp;
8616     }
8617   declareAsNew();
8618 }
8619
8620 /*!
8621  * Modify all elements of \a this array, so that
8622  * an element _x_ becomes \f$ val ^ x \f$.
8623  *  \param [in] val - the value used to apply pow on all array elements.
8624  *  \throw If \a this is not allocated.
8625  *  \throw If there is an element < 0 in \a this array.
8626  *  \warning If an exception is thrown because of presence of 0 element in \a this 
8627  *           array, all elements processed before detection of the zero element remain
8628  *           modified.
8629  */
8630 void DataArrayInt::applyRPow(int val) throw(INTERP_KERNEL::Exception)
8631 {
8632   checkAllocated();
8633   int *ptr=getPointer();
8634   std::size_t nbOfElems=getNbOfElems();
8635   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
8636     {
8637       if(*ptr>=0)
8638         {
8639           int tmp=1;
8640           for(int j=0;j<*ptr;j++)
8641             tmp*=val;
8642           *ptr=tmp;
8643         }
8644       else
8645         {
8646           std::ostringstream oss; oss << "DataArrayInt::applyRPow : presence of negative value in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
8647           oss << " !";
8648           throw INTERP_KERNEL::Exception(oss.str().c_str());
8649         }
8650     }
8651   declareAsNew();
8652 }
8653
8654 /*!
8655  * Returns a new DataArrayInt by aggregating two given arrays, so that (1) the number
8656  * of components in the result array is a sum of the number of components of given arrays
8657  * and (2) the number of tuples in the result array is same as that of each of given
8658  * arrays. In other words the i-th tuple of result array includes all components of
8659  * i-th tuples of all given arrays.
8660  * Number of tuples in the given arrays must be the same.
8661  *  \param [in] a1 - an array to include in the result array.
8662  *  \param [in] a2 - another array to include in the result array.
8663  *  \return DataArrayInt * - the new instance of DataArrayInt.
8664  *          The caller is to delete this result array using decrRef() as it is no more
8665  *          needed.
8666  *  \throw If both \a a1 and \a a2 are NULL.
8667  *  \throw If any given array is not allocated.
8668  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
8669  */
8670 DataArrayInt *DataArrayInt::Meld(const DataArrayInt *a1, const DataArrayInt *a2) throw(INTERP_KERNEL::Exception)
8671 {
8672   std::vector<const DataArrayInt *> arr(2);
8673   arr[0]=a1; arr[1]=a2;
8674   return Meld(arr);
8675 }
8676
8677 /*!
8678  * Returns a new DataArrayInt by aggregating all given arrays, so that (1) the number
8679  * of components in the result array is a sum of the number of components of given arrays
8680  * and (2) the number of tuples in the result array is same as that of each of given
8681  * arrays. In other words the i-th tuple of result array includes all components of
8682  * i-th tuples of all given arrays.
8683  * Number of tuples in the given arrays must be  the same.
8684  *  \param [in] arr - a sequence of arrays to include in the result array.
8685  *  \return DataArrayInt * - the new instance of DataArrayInt.
8686  *          The caller is to delete this result array using decrRef() as it is no more
8687  *          needed.
8688  *  \throw If all arrays within \a arr are NULL.
8689  *  \throw If any given array is not allocated.
8690  *  \throw If getNumberOfTuples() of arrays within \a arr is different.
8691  */
8692 DataArrayInt *DataArrayInt::Meld(const std::vector<const DataArrayInt *>& arr) throw(INTERP_KERNEL::Exception)
8693 {
8694   std::vector<const DataArrayInt *> a;
8695   for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
8696     if(*it4)
8697       a.push_back(*it4);
8698   if(a.empty())
8699     throw INTERP_KERNEL::Exception("DataArrayInt::Meld : array must be NON empty !");
8700   std::vector<const DataArrayInt *>::const_iterator it;
8701   for(it=a.begin();it!=a.end();it++)
8702     (*it)->checkAllocated();
8703   it=a.begin();
8704   int nbOfTuples=(*it)->getNumberOfTuples();
8705   std::vector<int> nbc(a.size());
8706   std::vector<const int *> pts(a.size());
8707   nbc[0]=(*it)->getNumberOfComponents();
8708   pts[0]=(*it++)->getConstPointer();
8709   for(int i=1;it!=a.end();it++,i++)
8710     {
8711       if(nbOfTuples!=(*it)->getNumberOfTuples())
8712         throw INTERP_KERNEL::Exception("DataArrayInt::meld : mismatch of number of tuples !");
8713       nbc[i]=(*it)->getNumberOfComponents();
8714       pts[i]=(*it)->getConstPointer();
8715     }
8716   int totalNbOfComp=std::accumulate(nbc.begin(),nbc.end(),0);
8717   DataArrayInt *ret=DataArrayInt::New();
8718   ret->alloc(nbOfTuples,totalNbOfComp);
8719   int *retPtr=ret->getPointer();
8720   for(int i=0;i<nbOfTuples;i++)
8721     for(int j=0;j<(int)a.size();j++)
8722       {
8723         retPtr=std::copy(pts[j],pts[j]+nbc[j],retPtr);
8724         pts[j]+=nbc[j];
8725       }
8726   int k=0;
8727   for(int i=0;i<(int)a.size();i++)
8728     for(int j=0;j<nbc[i];j++,k++)
8729       ret->setInfoOnComponent(k,a[i]->getInfoOnComponent(j).c_str());
8730   return ret;
8731 }
8732
8733 /*!
8734  * Returns a new DataArrayInt which is a minimal partition of elements of \a groups.
8735  * The i-th item of the result array is an ID of a set of elements belonging to a
8736  * unique set of groups, which the i-th element is a part of. This set of elements
8737  * belonging to a unique set of groups is called \a family, so the result array contains
8738  * IDs of families each element belongs to.
8739  *
8740  * \b Example: if we have two groups of elements: \a group1 [0,4] and \a group2 [ 0,1,2 ],
8741  * then there are 3 families:
8742  * - \a family1 (with ID 1) contains element [0] belonging to ( \a group1 + \a group2 ),
8743  * - \a family2 (with ID 2) contains elements [4] belonging to ( \a group1 ),
8744  * - \a family3 (with ID 3) contains element [1,2] belonging to ( \a group2 ), <br>
8745  * and the result array contains IDs of families [ 1,3,3,0,2 ]. <br> Note a family ID 0 which
8746  * stands for the element #3 which is in none of groups.
8747  *
8748  *  \param [in] groups - sequence of groups of element IDs.
8749  *  \param [in] newNb - total number of elements; it must be more than max ID of element
8750  *         in \a groups.
8751  *  \param [out] fidsOfGroups - IDs of families the elements of each group belong to.
8752  *  \return DataArrayInt * - a new instance of DataArrayInt containing IDs of families
8753  *         each element with ID from range [0, \a newNb ) belongs to. The caller is to
8754  *         delete this array using decrRef() as it is no more needed.
8755  *  \throw If any element ID in \a groups violates condition ( 0 <= ID < \a newNb ).
8756  */
8757 DataArrayInt *DataArrayInt::MakePartition(const std::vector<const DataArrayInt *>& groups, int newNb, std::vector< std::vector<int> >& fidsOfGroups) throw(INTERP_KERNEL::Exception)
8758 {
8759   std::vector<const DataArrayInt *> groups2;
8760   for(std::vector<const DataArrayInt *>::const_iterator it4=groups.begin();it4!=groups.end();it4++)
8761     if(*it4)
8762       groups2.push_back(*it4);
8763   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
8764   ret->alloc(newNb,1);
8765   int *retPtr=ret->getPointer();
8766   std::fill(retPtr,retPtr+newNb,0);
8767   int fid=1;
8768   for(std::vector<const DataArrayInt *>::const_iterator iter=groups2.begin();iter!=groups2.end();iter++)
8769     {
8770       const int *ptr=(*iter)->getConstPointer();
8771       std::size_t nbOfElem=(*iter)->getNbOfElems();
8772       int sfid=fid;
8773       for(int j=0;j<sfid;j++)
8774         {
8775           bool found=false;
8776           for(std::size_t i=0;i<nbOfElem;i++)
8777             {
8778               if(ptr[i]>=0 && ptr[i]<newNb)
8779                 {
8780                   if(retPtr[ptr[i]]==j)
8781                     {
8782                       retPtr[ptr[i]]=fid;
8783                       found=true;
8784                     }
8785                 }
8786               else
8787                 {
8788                   std::ostringstream oss; oss << "DataArrayInt::MakePartition : In group \"" << (*iter)->getName() << "\" in tuple #" << i << " value = " << ptr[i] << " ! Should be in [0," << newNb;
8789                   oss << ") !";
8790                   throw INTERP_KERNEL::Exception(oss.str().c_str());
8791                 }
8792             }
8793           if(found)
8794             fid++;
8795         }
8796     }
8797   fidsOfGroups.clear();
8798   fidsOfGroups.resize(groups2.size());
8799   int grId=0;
8800   for(std::vector<const DataArrayInt *>::const_iterator iter=groups2.begin();iter!=groups2.end();iter++,grId++)
8801     {
8802       std::set<int> tmp;
8803       const int *ptr=(*iter)->getConstPointer();
8804       std::size_t nbOfElem=(*iter)->getNbOfElems();
8805       for(const int *p=ptr;p!=ptr+nbOfElem;p++)
8806         tmp.insert(retPtr[*p]);
8807       fidsOfGroups[grId].insert(fidsOfGroups[grId].end(),tmp.begin(),tmp.end());
8808     }
8809   return ret.retn();
8810 }
8811
8812 /*!
8813  * Returns a new DataArrayInt which contains all elements of given one-dimensional
8814  * arrays. The result array does not contain any duplicates and its values
8815  * are sorted in ascending order.
8816  *  \param [in] arr - sequence of DataArrayInt's to unite.
8817  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
8818  *         array using decrRef() as it is no more needed.
8819  *  \throw If any \a arr[i] is not allocated.
8820  *  \throw If \a arr[i]->getNumberOfComponents() != 1.
8821  */
8822 DataArrayInt *DataArrayInt::BuildUnion(const std::vector<const DataArrayInt *>& arr) throw(INTERP_KERNEL::Exception)
8823 {
8824   std::vector<const DataArrayInt *> a;
8825   for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
8826     if(*it4)
8827       a.push_back(*it4);
8828   for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
8829     {
8830       (*it)->checkAllocated();
8831       if((*it)->getNumberOfComponents()!=1)
8832         throw INTERP_KERNEL::Exception("DataArrayInt::BuildUnion : only single component allowed !");
8833     }
8834   //
8835   std::set<int> r;
8836   for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
8837     {
8838       const int *pt=(*it)->getConstPointer();
8839       int nbOfTuples=(*it)->getNumberOfTuples();
8840       r.insert(pt,pt+nbOfTuples);
8841     }
8842   DataArrayInt *ret=DataArrayInt::New();
8843   ret->alloc((int)r.size(),1);
8844   std::copy(r.begin(),r.end(),ret->getPointer());
8845   return ret;
8846 }
8847
8848 /*!
8849  * Returns a new DataArrayInt which contains elements present in each of given one-dimensional
8850  * arrays. The result array does not contain any duplicates and its values
8851  * are sorted in ascending order.
8852  *  \param [in] arr - sequence of DataArrayInt's to intersect.
8853  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
8854  *         array using decrRef() as it is no more needed.
8855  *  \throw If any \a arr[i] is not allocated.
8856  *  \throw If \a arr[i]->getNumberOfComponents() != 1.
8857  */
8858 DataArrayInt *DataArrayInt::BuildIntersection(const std::vector<const DataArrayInt *>& arr) throw(INTERP_KERNEL::Exception)
8859 {
8860   std::vector<const DataArrayInt *> a;
8861   for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
8862     if(*it4)
8863       a.push_back(*it4);
8864   for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
8865     {
8866       (*it)->checkAllocated();
8867       if((*it)->getNumberOfComponents()!=1)
8868         throw INTERP_KERNEL::Exception("DataArrayInt::BuildIntersection : only single component allowed !");
8869     }
8870   //
8871   std::set<int> r;
8872   for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
8873     {
8874       const int *pt=(*it)->getConstPointer();
8875       int nbOfTuples=(*it)->getNumberOfTuples();
8876       std::set<int> s1(pt,pt+nbOfTuples);
8877       if(it!=a.begin())
8878         {
8879           std::set<int> r2;
8880           std::set_intersection(r.begin(),r.end(),s1.begin(),s1.end(),inserter(r2,r2.end()));
8881           r=r2;
8882         }
8883       else
8884         r=s1;
8885     }
8886   DataArrayInt *ret=DataArrayInt::New();
8887   ret->alloc((int)r.size(),1);
8888   std::copy(r.begin(),r.end(),ret->getPointer());
8889   return ret;
8890 }
8891
8892 /*!
8893  * Returns a new DataArrayInt which contains a complement of elements of \a this
8894  * one-dimensional array. I.e. the result array contains all elements from the range [0,
8895  * \a nbOfElement) not present in \a this array.
8896  *  \param [in] nbOfElement - maximal size of the result array.
8897  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
8898  *         array using decrRef() as it is no more needed.
8899  *  \throw If \a this is not allocated.
8900  *  \throw If \a this->getNumberOfComponents() != 1.
8901  *  \throw If any element \a x of \a this array violates condition ( 0 <= \a x < \a
8902  *         nbOfElement ).
8903  */
8904 DataArrayInt *DataArrayInt::buildComplement(int nbOfElement) const throw(INTERP_KERNEL::Exception)
8905 {
8906    checkAllocated();
8907    if(getNumberOfComponents()!=1)
8908      throw INTERP_KERNEL::Exception("DataArrayInt::buildComplement : only single component allowed !");
8909    std::vector<bool> tmp(nbOfElement);
8910    const int *pt=getConstPointer();
8911    int nbOfTuples=getNumberOfTuples();
8912    for(const int *w=pt;w!=pt+nbOfTuples;w++)
8913      if(*w>=0 && *w<nbOfElement)
8914        tmp[*w]=true;
8915      else
8916        throw INTERP_KERNEL::Exception("DataArrayInt::buildComplement : an element is not in valid range : [0,nbOfElement) !");
8917    int nbOfRetVal=(int)std::count(tmp.begin(),tmp.end(),false);
8918    DataArrayInt *ret=DataArrayInt::New();
8919    ret->alloc(nbOfRetVal,1);
8920    int j=0;
8921    int *retPtr=ret->getPointer();
8922    for(int i=0;i<nbOfElement;i++)
8923      if(!tmp[i])
8924        retPtr[j++]=i;
8925    return ret;
8926 }
8927
8928 /*!
8929  * Returns a new DataArrayInt containing elements of \a this one-dimensional missing
8930  * from an \a other one-dimensional array.
8931  *  \param [in] other - a DataArrayInt containing elements not to include in the result array.
8932  *  \return DataArrayInt * - a new instance of DataArrayInt with one component. The
8933  *         caller is to delete this array using decrRef() as it is no more needed.
8934  *  \throw If \a other is NULL.
8935  *  \throw If \a other is not allocated.
8936  *  \throw If \a other->getNumberOfComponents() != 1.
8937  *  \throw If \a this is not allocated.
8938  *  \throw If \a this->getNumberOfComponents() != 1.
8939  *  \sa DataArrayInt::buildSubstractionOptimized()
8940  */
8941 DataArrayInt *DataArrayInt::buildSubstraction(const DataArrayInt *other) const throw(INTERP_KERNEL::Exception)
8942 {
8943   if(!other)
8944     throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstraction : DataArrayInt pointer in input is NULL !");
8945   checkAllocated();
8946   other->checkAllocated();
8947   if(getNumberOfComponents()!=1)
8948      throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstraction : only single component allowed !");
8949   if(other->getNumberOfComponents()!=1)
8950      throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstraction : only single component allowed for other type !");
8951   const int *pt=getConstPointer();
8952   int nbOfTuples=getNumberOfTuples();
8953   std::set<int> s1(pt,pt+nbOfTuples);
8954   pt=other->getConstPointer();
8955   nbOfTuples=other->getNumberOfTuples();
8956   std::set<int> s2(pt,pt+nbOfTuples);
8957   std::vector<int> r;
8958   std::set_difference(s1.begin(),s1.end(),s2.begin(),s2.end(),std::back_insert_iterator< std::vector<int> >(r));
8959   DataArrayInt *ret=DataArrayInt::New();
8960   ret->alloc((int)r.size(),1);
8961   std::copy(r.begin(),r.end(),ret->getPointer());
8962   return ret;
8963 }
8964
8965 /*!
8966  * \a this is expected to have one component and to be sorted ascendingly (as for \a other).
8967  * \a other is expected to be a part of \a this. If not DataArrayInt::buildSubstraction should be called instead.
8968  * 
8969  * \param [in] other an array with one component and expected to be sorted ascendingly.
8970  * \ret list of ids in \a this but not in \a other.
8971  * \sa DataArrayInt::buildSubstraction
8972  */
8973 DataArrayInt *DataArrayInt::buildSubstractionOptimized(const DataArrayInt *other) const throw(INTERP_KERNEL::Exception)
8974 {
8975   static const char *MSG="DataArrayInt::buildSubstractionOptimized : only single component allowed !";
8976   if(!other) throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstractionOptimized : NULL input array !");
8977   checkAllocated(); other->checkAllocated();
8978   if(getNumberOfComponents()!=1) throw INTERP_KERNEL::Exception(MSG);
8979   if(other->getNumberOfComponents()!=1) throw INTERP_KERNEL::Exception(MSG);
8980   const int *pt1Bg(begin()),*pt1End(end()),*pt2Bg(other->begin()),*pt2End(other->end()),*work1(pt1Bg),*work2(pt2Bg);
8981   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
8982   for(;work1!=pt1End;work1++)
8983     {
8984       if(work2!=pt2End && *work1==*work2)
8985         work2++;
8986       else
8987         ret->pushBackSilent(*work1);
8988     }
8989   return ret.retn();
8990 }
8991
8992
8993 /*!
8994  * Returns a new DataArrayInt which contains all elements of \a this and a given
8995  * one-dimensional arrays. The result array does not contain any duplicates
8996  * and its values are sorted in ascending order.
8997  *  \param [in] other - an array to unite with \a this one.
8998  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
8999  *         array using decrRef() as it is no more needed.
9000  *  \throw If \a this or \a other is not allocated.
9001  *  \throw If \a this->getNumberOfComponents() != 1.
9002  *  \throw If \a other->getNumberOfComponents() != 1.
9003  */
9004 DataArrayInt *DataArrayInt::buildUnion(const DataArrayInt *other) const throw(INTERP_KERNEL::Exception)
9005 {
9006   std::vector<const DataArrayInt *>arrs(2);
9007   arrs[0]=this; arrs[1]=other;
9008   return BuildUnion(arrs);
9009 }
9010
9011
9012 /*!
9013  * Returns a new DataArrayInt which contains elements present in both \a this and a given
9014  * one-dimensional arrays. The result array does not contain any duplicates
9015  * and its values are sorted in ascending order.
9016  *  \param [in] other - an array to intersect with \a this one.
9017  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
9018  *         array using decrRef() as it is no more needed.
9019  *  \throw If \a this or \a other is not allocated.
9020  *  \throw If \a this->getNumberOfComponents() != 1.
9021  *  \throw If \a other->getNumberOfComponents() != 1.
9022  */
9023 DataArrayInt *DataArrayInt::buildIntersection(const DataArrayInt *other) const throw(INTERP_KERNEL::Exception)
9024 {
9025   std::vector<const DataArrayInt *>arrs(2);
9026   arrs[0]=this; arrs[1]=other;
9027   return BuildIntersection(arrs);
9028 }
9029
9030 /*!
9031  * This method can be applied on allocated with one component DataArrayInt instance.
9032  * This method is typically relevant for sorted arrays. All consecutive duplicated items in \a this will appear only once in returned DataArrayInt instance.
9033  * 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]
9034  * 
9035  * \return a newly allocated array that contain the result of the unique operation applied on \a this.
9036  * \throw if \a this is not allocated or if \a this has not exactly one component.
9037  */
9038 DataArrayInt *DataArrayInt::buildUnique() const throw(INTERP_KERNEL::Exception)
9039 {
9040   checkAllocated();
9041   if(getNumberOfComponents()!=1)
9042      throw INTERP_KERNEL::Exception("DataArrayInt::buildUnique : only single component allowed !");
9043   int nbOfTuples=getNumberOfTuples();
9044   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp=deepCpy();
9045   int *data=tmp->getPointer();
9046   int *last=std::unique(data,data+nbOfTuples);
9047   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
9048   ret->alloc(std::distance(data,last),1);
9049   std::copy(data,last,ret->getPointer());
9050   return ret.retn();
9051 }
9052
9053 /*!
9054  * Returns a new DataArrayInt which contains size of every of groups described by \a this
9055  * "index" array. Such "index" array is returned for example by 
9056  * \ref ParaMEDMEM::MEDCouplingUMesh::buildDescendingConnectivity
9057  * "MEDCouplingUMesh::buildDescendingConnectivity" and
9058  * \ref ParaMEDMEM::MEDCouplingUMesh::getNodalConnectivityIndex
9059  * "MEDCouplingUMesh::getNodalConnectivityIndex" etc.
9060  *  \return DataArrayInt * - a new instance of DataArrayInt, whose number of tuples
9061  *          equals to \a this->getNumberOfComponents() - 1, and number of components is 1.
9062  *          The caller is to delete this array using decrRef() as it is no more needed. 
9063  *  \throw If \a this is not allocated.
9064  *  \throw If \a this->getNumberOfComponents() != 1.
9065  *  \throw If \a this->getNumberOfTuples() < 2.
9066  *
9067  *  \b Example: <br> 
9068  *         - this contains [1,3,6,7,7,9,15]
9069  *         - result array contains [2,3,1,0,2,6],
9070  *          where 2 = 3 - 1, 3 = 6 - 3, 1 = 7 - 6 etc.
9071  */
9072 DataArrayInt *DataArrayInt::deltaShiftIndex() const throw(INTERP_KERNEL::Exception)
9073 {
9074   checkAllocated();
9075   if(getNumberOfComponents()!=1)
9076      throw INTERP_KERNEL::Exception("DataArrayInt::deltaShiftIndex : only single component allowed !");
9077   int nbOfTuples=getNumberOfTuples();
9078   if(nbOfTuples<2)
9079     throw INTERP_KERNEL::Exception("DataArrayInt::deltaShiftIndex : 1 tuple at least must be present in 'this' !");
9080   const int *ptr=getConstPointer();
9081   DataArrayInt *ret=DataArrayInt::New();
9082   ret->alloc(nbOfTuples-1,1);
9083   int *out=ret->getPointer();
9084   std::transform(ptr+1,ptr+nbOfTuples,ptr,out,std::minus<int>());
9085   return ret;
9086 }
9087
9088 /*!
9089  * Modifies \a this one-dimensional array so that value of each element \a x
9090  * of \a this array (\a a) is computed as \f$ x_i = \sum_{j=0}^{i-1} a[ j ] \f$.
9091  * Or: for each i>0 new[i]=new[i-1]+old[i-1] for i==0 new[i]=0. Number of tuples
9092  * and components remains the same.<br>
9093  * This method is useful for allToAllV in MPI with contiguous policy. This method
9094  * differs from computeOffsets2() in that the number of tuples is \b not changed by
9095  * this one.
9096  *  \throw If \a this is not allocated.
9097  *  \throw If \a this->getNumberOfComponents() != 1.
9098  *
9099  *  \b Example: <br>
9100  *          - Before \a this contains [3,5,1,2,0,8]
9101  *          - After \a this contains  [0,3,8,9,11,11]<br>
9102  *          Note that the last element 19 = 11 + 8 is missing because size of \a this
9103  *          array is retained and thus there is no space to store the last element.
9104  */
9105 void DataArrayInt::computeOffsets() throw(INTERP_KERNEL::Exception)
9106 {
9107   checkAllocated();
9108   if(getNumberOfComponents()!=1)
9109      throw INTERP_KERNEL::Exception("DataArrayInt::computeOffsets : only single component allowed !");
9110   int nbOfTuples=getNumberOfTuples();
9111   if(nbOfTuples==0)
9112     return ;
9113   int *work=getPointer();
9114   int tmp=work[0];
9115   work[0]=0;
9116   for(int i=1;i<nbOfTuples;i++)
9117     {
9118       int tmp2=work[i];
9119       work[i]=work[i-1]+tmp;
9120       tmp=tmp2;
9121     }
9122   declareAsNew();
9123 }
9124
9125
9126 /*!
9127  * Modifies \a this one-dimensional array so that value of each element \a x
9128  * of \a this array (\a a) is computed as \f$ x_i = \sum_{j=0}^{i-1} a[ j ] \f$.
9129  * Or: for each i>0 new[i]=new[i-1]+old[i-1] for i==0 new[i]=0. Number
9130  * components remains the same and number of tuples is inceamented by one.<br>
9131  * This method is useful for allToAllV in MPI with contiguous policy. This method
9132  * differs from computeOffsets() in that the number of tuples is changed by this one.
9133  *  \throw If \a this is not allocated.
9134  *  \throw If \a this->getNumberOfComponents() != 1.
9135  *
9136  *  \b Example: <br>
9137  *          - Before \a this contains [3,5,1,2,0,8]
9138  *          - After \a this contains  [0,3,8,9,11,11,19]<br>
9139  */
9140 void DataArrayInt::computeOffsets2() throw(INTERP_KERNEL::Exception)
9141 {
9142   checkAllocated();
9143   if(getNumberOfComponents()!=1)
9144     throw INTERP_KERNEL::Exception("DataArrayInt::computeOffsets2 : only single component allowed !");
9145   int nbOfTuples=getNumberOfTuples();
9146   int *ret=(int *)malloc((nbOfTuples+1)*sizeof(int));
9147   if(nbOfTuples==0)
9148     return ;
9149   const int *work=getConstPointer();
9150   ret[0]=0;
9151   for(int i=0;i<nbOfTuples;i++)
9152     ret[i+1]=work[i]+ret[i];
9153   useArray(ret,true,C_DEALLOC,nbOfTuples+1,1);
9154   declareAsNew();
9155 }
9156
9157 /*!
9158  * Returns two new DataArrayInt instances whose contents is computed from that of \a this and \a listOfIds arrays as follows.
9159  * \a this is expected to be an offset format ( as returned by DataArrayInt::computeOffsets2 ) that is to say with one component
9160  * and ** sorted strictly increasingly **. \a listOfIds is expected to be sorted ascendingly (not strictly needed for \a listOfIds).
9161  * This methods searches in \a this, considered as a set of contiguous \c this->getNumberOfComponents() ranges, all ids in \a listOfIds
9162  * filling completely one of the ranges in \a this.
9163  *
9164  * \param [in] listOfIds a list of ids that has to be sorted ascendingly.
9165  * \param [out] rangeIdsFetched the range ids fetched
9166  * \param [out] idsInInputListThatFetch contains the list of ids in \a listOfIds that are \b fully included in a range in \a this. So
9167  *              \a idsInInputListThatFetch is a part of input \a listOfIds.
9168  *
9169  * \sa DataArrayInt::computeOffsets2
9170  *
9171  *  \b Example: <br>
9172  *          - \a this : [0,3,7,9,15,18]
9173  *          - \a listOfIds contains  [0,1,2,3,7,8,15,16,17]
9174  *          - \a rangeIdsFetched result array: [0,2,4]
9175  *          - \a idsInInputListThatFetch result array: [0,1,2,7,8,15,16,17]
9176  * In this example id 3 in input \a listOfIds is alone so it do not appear in output \a idsInInputListThatFetch.
9177  * <br>
9178  */
9179 void DataArrayInt::searchRangesInListOfIds(const DataArrayInt *listOfIds, DataArrayInt *& rangeIdsFetched, DataArrayInt *& idsInInputListThatFetch) const throw(INTERP_KERNEL::Exception)
9180 {
9181   if(!listOfIds)
9182     throw INTERP_KERNEL::Exception("DataArrayInt::searchRangesInListOfIds : input list of ids is null !");
9183   listOfIds->checkAllocated(); checkAllocated();
9184   if(listOfIds->getNumberOfComponents()!=1)
9185     throw INTERP_KERNEL::Exception("DataArrayInt::searchRangesInListOfIds : input list of ids must have exactly one component !");
9186   if(getNumberOfComponents()!=1)
9187     throw INTERP_KERNEL::Exception("DataArrayInt::searchRangesInListOfIds : this must have exactly one component !");
9188   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret0=DataArrayInt::New(); ret0->alloc(0,1);
9189   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret1=DataArrayInt::New(); ret1->alloc(0,1);
9190   const int *tupEnd(listOfIds->end()),*offBg(begin()),*offEnd(end()-1);
9191   const int *tupPtr(listOfIds->begin()),*offPtr(offBg);
9192   while(tupPtr!=tupEnd && offPtr!=offEnd)
9193     {
9194       if(*tupPtr==*offPtr)
9195         {
9196           int i=offPtr[0];
9197           while(i<offPtr[1] && *tupPtr==i && tupPtr!=tupEnd) { i++; tupPtr++; }
9198           if(i==offPtr[1])
9199             {
9200               ret0->pushBackSilent((int)std::distance(offBg,offPtr));
9201               ret1->pushBackValsSilent(tupPtr-(offPtr[1]-offPtr[0]),tupPtr);
9202               offPtr++;
9203             }
9204         }
9205       else
9206         { if(*tupPtr<*offPtr) tupPtr++; else offPtr++; }
9207     }
9208   rangeIdsFetched=ret0.retn();
9209   idsInInputListThatFetch=ret1.retn();
9210 }
9211
9212 /*!
9213  * Returns a new DataArrayInt whose contents is computed from that of \a this and \a
9214  * offsets arrays as follows. \a offsets is a one-dimensional array considered as an
9215  * "index" array of a "iota" array, thus, whose each element gives an index of a group
9216  * beginning within the "iota" array. And \a this is a one-dimensional array
9217  * considered as a selector of groups described by \a offsets to include into the result array.
9218  *  \throw If \a offsets is NULL.
9219  *  \throw If \a offsets is not allocated.
9220  *  \throw If \a offsets->getNumberOfComponents() != 1.
9221  *  \throw If \a offsets is not monotonically increasing.
9222  *  \throw If \a this is not allocated.
9223  *  \throw If \a this->getNumberOfComponents() != 1.
9224  *  \throw If any element of \a this is not a valid index for \a offsets array.
9225  *
9226  *  \b Example: <br>
9227  *          - \a this: [0,2,3]
9228  *          - \a offsets: [0,3,6,10,14,20]
9229  *          - result array: [0,1,2,6,7,8,9,10,11,12,13] == <br>
9230  *            \c range(0,3) + \c range(6,10) + \c range(10,14) ==<br>
9231  *            \c range( \a offsets[ \a this[0] ], offsets[ \a this[0]+1 ]) + 
9232  *            \c range( \a offsets[ \a this[1] ], offsets[ \a this[1]+1 ]) + 
9233  *            \c range( \a offsets[ \a this[2] ], offsets[ \a this[2]+1 ])
9234  */
9235 DataArrayInt *DataArrayInt::buildExplicitArrByRanges(const DataArrayInt *offsets) const throw(INTERP_KERNEL::Exception)
9236 {
9237   if(!offsets)
9238     throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrByRanges : DataArrayInt pointer in input is NULL !");
9239   checkAllocated();
9240   if(getNumberOfComponents()!=1)
9241      throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrByRanges : only single component allowed !");
9242   offsets->checkAllocated();
9243   if(offsets->getNumberOfComponents()!=1)
9244      throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrByRanges : input array should have only single component !");
9245   int othNbTuples=offsets->getNumberOfTuples()-1;
9246   int nbOfTuples=getNumberOfTuples();
9247   int retNbOftuples=0;
9248   const int *work=getConstPointer();
9249   const int *offPtr=offsets->getConstPointer();
9250   for(int i=0;i<nbOfTuples;i++)
9251     {
9252       int val=work[i];
9253       if(val>=0 && val<othNbTuples)
9254         {
9255           int delta=offPtr[val+1]-offPtr[val];
9256           if(delta>=0)
9257             retNbOftuples+=delta;
9258           else
9259             {
9260               std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrByRanges : Tuple #" << val << " of offset array has a delta < 0 !";
9261               throw INTERP_KERNEL::Exception(oss.str().c_str());
9262             }
9263         }
9264       else
9265         {
9266           std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrByRanges : Tuple #" << i << " in this contains " << val;
9267           oss << " whereas offsets array is of size " << othNbTuples+1 << " !";
9268           throw INTERP_KERNEL::Exception(oss.str().c_str());
9269         }
9270     }
9271   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
9272   ret->alloc(retNbOftuples,1);
9273   int *retPtr=ret->getPointer();
9274   for(int i=0;i<nbOfTuples;i++)
9275     {
9276       int val=work[i];
9277       int start=offPtr[val];
9278       int off=offPtr[val+1]-start;
9279       for(int j=0;j<off;j++,retPtr++)
9280         *retPtr=start+j;
9281     }
9282   return ret.retn();
9283 }
9284
9285 /*!
9286  * 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.
9287  * 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
9288  * in tuple **i** of returned DataArrayInt.
9289  * If ranges overlapped (in theory it should not) this method do not detect it and always returns the first range.
9290  *
9291  * 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)]
9292  * The return DataArrayInt will contain : **[0,4,1,2,2,3]**
9293  * 
9294  * \param [in] ranges typically come from output of MEDCouplingUMesh::ComputeRangesFromTypeDistribution. Each range is specified like this : 1st component is
9295  *             for lower value included and 2nd component is the upper value of corresponding range **excluded**.
9296  * \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
9297  *        is thrown if no ranges in \a ranges contains value in \a this.
9298  * 
9299  * \sa DataArrayInt::findIdInRangeForEachTuple
9300  */
9301 DataArrayInt *DataArrayInt::findRangeIdForEachTuple(const DataArrayInt *ranges) const throw(INTERP_KERNEL::Exception)
9302 {
9303   if(!ranges)
9304     throw INTERP_KERNEL::Exception("DataArrayInt::findRangeIdForEachTuple : null input pointer !");
9305   if(ranges->getNumberOfComponents()!=2)
9306     throw INTERP_KERNEL::Exception("DataArrayInt::findRangeIdForEachTuple : input DataArrayInt instance should have 2 components !");
9307   checkAllocated();
9308   if(getNumberOfComponents()!=1)
9309     throw INTERP_KERNEL::Exception("DataArrayInt::findRangeIdForEachTuple : this should have only one component !");
9310   int nbTuples=getNumberOfTuples();
9311   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbTuples,1);
9312   int nbOfRanges=ranges->getNumberOfTuples();
9313   const int *rangesPtr=ranges->getConstPointer();
9314   int *retPtr=ret->getPointer();
9315   const int *inPtr=getConstPointer();
9316   for(int i=0;i<nbTuples;i++,retPtr++)
9317     {
9318       int val=inPtr[i];
9319       bool found=false;
9320       for(int j=0;j<nbOfRanges && !found;j++)
9321         if(val>=rangesPtr[2*j] && val<rangesPtr[2*j+1])
9322           { *retPtr=j; found=true; }
9323       if(found)
9324         continue;
9325       else
9326         {
9327           std::ostringstream oss; oss << "DataArrayInt::findRangeIdForEachTuple : tuple #" << i << " not found by any ranges !";
9328           throw INTERP_KERNEL::Exception(oss.str().c_str());
9329         }
9330     }
9331   return ret.retn();
9332 }
9333
9334 /*!
9335  * 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.
9336  * 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
9337  * in tuple **i** of returned DataArrayInt.
9338  * If ranges overlapped (in theory it should not) this method do not detect it and always returns the sub position of the first range.
9339  *
9340  * 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)]
9341  * The return DataArrayInt will contain : **[1,2,4,0,2,2]**
9342  * This method is often called in pair with DataArrayInt::findRangeIdForEachTuple method.
9343  * 
9344  * \param [in] ranges typically come from output of MEDCouplingUMesh::ComputeRangesFromTypeDistribution. Each range is specified like this : 1st component is
9345  *             for lower value included and 2nd component is the upper value of corresponding range **excluded**.
9346  * \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
9347  *        is thrown if no ranges in \a ranges contains value in \a this.
9348  * \sa DataArrayInt::findRangeIdForEachTuple
9349  */
9350 DataArrayInt *DataArrayInt::findIdInRangeForEachTuple(const DataArrayInt *ranges) const throw(INTERP_KERNEL::Exception)
9351 {
9352   if(!ranges)
9353     throw INTERP_KERNEL::Exception("DataArrayInt::findIdInRangeForEachTuple : null input pointer !");
9354   if(ranges->getNumberOfComponents()!=2)
9355     throw INTERP_KERNEL::Exception("DataArrayInt::findIdInRangeForEachTuple : input DataArrayInt instance should have 2 components !");
9356   checkAllocated();
9357   if(getNumberOfComponents()!=1)
9358     throw INTERP_KERNEL::Exception("DataArrayInt::findIdInRangeForEachTuple : this should have only one component !");
9359   int nbTuples=getNumberOfTuples();
9360   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbTuples,1);
9361   int nbOfRanges=ranges->getNumberOfTuples();
9362   const int *rangesPtr=ranges->getConstPointer();
9363   int *retPtr=ret->getPointer();
9364   const int *inPtr=getConstPointer();
9365   for(int i=0;i<nbTuples;i++,retPtr++)
9366     {
9367       int val=inPtr[i];
9368       bool found=false;
9369       for(int j=0;j<nbOfRanges && !found;j++)
9370         if(val>=rangesPtr[2*j] && val<rangesPtr[2*j+1])
9371           { *retPtr=val-rangesPtr[2*j]; found=true; }
9372       if(found)
9373         continue;
9374       else
9375         {
9376           std::ostringstream oss; oss << "DataArrayInt::findIdInRangeForEachTuple : tuple #" << i << " not found by any ranges !";
9377           throw INTERP_KERNEL::Exception(oss.str().c_str());
9378         }
9379     }
9380   return ret.retn();
9381 }
9382
9383 /*!
9384  * 
9385  * \param [in] nbTimes specifies the nb of times each tuples in \a this will be duplicated contiguouly in returned DataArrayInt instance.
9386  *             \a nbTimes  should be at least equal to 1.
9387  * \return a newly allocated DataArrayInt having one component and number of tuples equal to \a nbTimes * \c this->getNumberOfTuples.
9388  * \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.
9389  */
9390 DataArrayInt *DataArrayInt::duplicateEachTupleNTimes(int nbTimes) const throw(INTERP_KERNEL::Exception)
9391 {
9392   checkAllocated();
9393   if(getNumberOfComponents()!=1)
9394     throw INTERP_KERNEL::Exception("DataArrayInt::duplicateEachTupleNTimes : this should have only one component !");
9395   if(nbTimes<1)
9396     throw INTERP_KERNEL::Exception("DataArrayInt::duplicateEachTupleNTimes : nb times should be >= 1 !");
9397   int nbTuples=getNumberOfTuples();
9398   const int *inPtr=getConstPointer();
9399   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbTimes*nbTuples,1);
9400   int *retPtr=ret->getPointer();
9401   for(int i=0;i<nbTuples;i++,inPtr++)
9402     {
9403       int val=*inPtr;
9404       for(int j=0;j<nbTimes;j++,retPtr++)
9405         *retPtr=val;
9406     }
9407   ret->copyStringInfoFrom(*this);
9408   return ret.retn();
9409 }
9410
9411 /*!
9412  * This method returns all different values found in \a this. This method throws if \a this has not been allocated.
9413  * But the number of components can be different from one.
9414  * \return a newly allocated array (that should be dealt by the caller) containing different values in \a this.
9415  */
9416 DataArrayInt *DataArrayInt::getDifferentValues() const throw(INTERP_KERNEL::Exception)
9417 {
9418   checkAllocated();
9419   std::set<int> ret;
9420   ret.insert(begin(),end());
9421   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret2=DataArrayInt::New(); ret2->alloc((int)ret.size(),1);
9422   std::copy(ret.begin(),ret.end(),ret2->getPointer());
9423   return ret2.retn();
9424 }
9425
9426 /*!
9427  * This method is a refinement of DataArrayInt::getDifferentValues because it returns not only different values in \a this but also, for each of
9428  * them it tells which tuple id have this id.
9429  * This method works only on arrays with one component (if it is not the case call DataArrayInt::rearrange(1) ).
9430  * This method returns two arrays having same size.
9431  * 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.
9432  * 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]]
9433  */
9434 std::vector<DataArrayInt *> DataArrayInt::partitionByDifferentValues(std::vector<int>& differentIds) const throw(INTERP_KERNEL::Exception)
9435 {
9436   checkAllocated();
9437   if(getNumberOfComponents()!=1)
9438     throw INTERP_KERNEL::Exception("DataArrayInt::partitionByDifferentValues : this should have only one component !");
9439   int id=0;
9440   std::map<int,int> m,m2,m3;
9441   for(const int *w=begin();w!=end();w++)
9442     m[*w]++;
9443   differentIds.resize(m.size());
9444   std::vector<DataArrayInt *> ret(m.size());
9445   std::vector<int *> retPtr(m.size());
9446   for(std::map<int,int>::const_iterator it=m.begin();it!=m.end();it++,id++)
9447     {
9448       m2[(*it).first]=id;
9449       ret[id]=DataArrayInt::New();
9450       ret[id]->alloc((*it).second,1);
9451       retPtr[id]=ret[id]->getPointer();
9452       differentIds[id]=(*it).first;
9453     }
9454   id=0;
9455   for(const int *w=begin();w!=end();w++,id++)
9456     {
9457       retPtr[m2[*w]][m3[*w]++]=id;
9458     }
9459   return ret;
9460 }
9461
9462 /*!
9463  * Returns a new DataArrayInt that is a sum of two given arrays. There are 3
9464  * valid cases.
9465  * 1.  The arrays have same number of tuples and components. Then each value of
9466  *   the result array (_a_) is a sum of the corresponding values of \a a1 and \a a2,
9467  *   i.e.: _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ i, j ].
9468  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
9469  *   component. Then
9470  *   _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ i, 0 ].
9471  * 3.  The arrays have same number of components and one array, say _a2_, has one
9472  *   tuple. Then
9473  *   _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ 0, j ].
9474  *
9475  * Info on components is copied either from the first array (in the first case) or from
9476  * the array with maximal number of elements (getNbOfElems()).
9477  *  \param [in] a1 - an array to sum up.
9478  *  \param [in] a2 - another array to sum up.
9479  *  \return DataArrayInt * - the new instance of DataArrayInt.
9480  *          The caller is to delete this result array using decrRef() as it is no more
9481  *          needed.
9482  *  \throw If either \a a1 or \a a2 is NULL.
9483  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
9484  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
9485  *         none of them has number of tuples or components equal to 1.
9486  */
9487 DataArrayInt *DataArrayInt::Add(const DataArrayInt *a1, const DataArrayInt *a2) throw(INTERP_KERNEL::Exception)
9488 {
9489   if(!a1 || !a2)
9490     throw INTERP_KERNEL::Exception("DataArrayInt::Add : input DataArrayInt instance is NULL !");
9491   int nbOfTuple=a1->getNumberOfTuples();
9492   int nbOfTuple2=a2->getNumberOfTuples();
9493   int nbOfComp=a1->getNumberOfComponents();
9494   int nbOfComp2=a2->getNumberOfComponents();
9495   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=0;
9496   if(nbOfTuple==nbOfTuple2)
9497     {
9498       if(nbOfComp==nbOfComp2)
9499         {
9500           ret=DataArrayInt::New();
9501           ret->alloc(nbOfTuple,nbOfComp);
9502           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::plus<int>());
9503           ret->copyStringInfoFrom(*a1);
9504         }
9505       else
9506         {
9507           int nbOfCompMin,nbOfCompMax;
9508           const DataArrayInt *aMin, *aMax;
9509           if(nbOfComp>nbOfComp2)
9510             {
9511               nbOfCompMin=nbOfComp2; nbOfCompMax=nbOfComp;
9512               aMin=a2; aMax=a1;
9513             }
9514           else
9515             {
9516               nbOfCompMin=nbOfComp; nbOfCompMax=nbOfComp2;
9517               aMin=a1; aMax=a2;
9518             }
9519           if(nbOfCompMin==1)
9520             {
9521               ret=DataArrayInt::New();
9522               ret->alloc(nbOfTuple,nbOfCompMax);
9523               const int *aMinPtr=aMin->getConstPointer();
9524               const int *aMaxPtr=aMax->getConstPointer();
9525               int *res=ret->getPointer();
9526               for(int i=0;i<nbOfTuple;i++)
9527                 res=std::transform(aMaxPtr+i*nbOfCompMax,aMaxPtr+(i+1)*nbOfCompMax,res,std::bind2nd(std::plus<int>(),aMinPtr[i]));
9528               ret->copyStringInfoFrom(*aMax);
9529             }
9530           else
9531             throw INTERP_KERNEL::Exception("Nb of components mismatch for array Add !");
9532         }
9533     }
9534   else if((nbOfTuple==1 && nbOfTuple2>1) || (nbOfTuple>1 && nbOfTuple2==1))
9535     {
9536       if(nbOfComp==nbOfComp2)
9537         {
9538           int nbOfTupleMax=std::max(nbOfTuple,nbOfTuple2);
9539           const DataArrayInt *aMin=nbOfTuple>nbOfTuple2?a2:a1;
9540           const DataArrayInt *aMax=nbOfTuple>nbOfTuple2?a1:a2;
9541           const int *aMinPtr=aMin->getConstPointer(),*aMaxPtr=aMax->getConstPointer();
9542           ret=DataArrayInt::New();
9543           ret->alloc(nbOfTupleMax,nbOfComp);
9544           int *res=ret->getPointer();
9545           for(int i=0;i<nbOfTupleMax;i++)
9546             res=std::transform(aMaxPtr+i*nbOfComp,aMaxPtr+(i+1)*nbOfComp,aMinPtr,res,std::plus<int>());
9547           ret->copyStringInfoFrom(*aMax);
9548         }
9549       else
9550         throw INTERP_KERNEL::Exception("Nb of components mismatch for array Add !");
9551     }
9552   else
9553     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Add !");
9554   return ret.retn();
9555 }
9556
9557 /*!
9558  * Adds values of another DataArrayInt to values of \a this one. There are 3
9559  * valid cases.
9560  * 1.  The arrays have same number of tuples and components. Then each value of
9561  *   \a other array is added to the corresponding value of \a this array, i.e.:
9562  *   _a_ [ i, j ] += _other_ [ i, j ].
9563  * 2.  The arrays have same number of tuples and \a other array has one component. Then
9564  *   _a_ [ i, j ] += _other_ [ i, 0 ].
9565  * 3.  The arrays have same number of components and \a other array has one tuple. Then
9566  *   _a_ [ i, j ] += _a2_ [ 0, j ].
9567  *
9568  *  \param [in] other - an array to add to \a this one.
9569  *  \throw If \a other is NULL.
9570  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
9571  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
9572  *         \a other has number of both tuples and components not equal to 1.
9573  */
9574 void DataArrayInt::addEqual(const DataArrayInt *other) throw(INTERP_KERNEL::Exception)
9575 {
9576   if(!other)
9577     throw INTERP_KERNEL::Exception("DataArrayInt::addEqual : input DataArrayInt instance is NULL !");
9578   const char *msg="Nb of tuples mismatch for DataArrayInt::addEqual  !";
9579   checkAllocated(); other->checkAllocated();
9580   int nbOfTuple=getNumberOfTuples();
9581   int nbOfTuple2=other->getNumberOfTuples();
9582   int nbOfComp=getNumberOfComponents();
9583   int nbOfComp2=other->getNumberOfComponents();
9584   if(nbOfTuple==nbOfTuple2)
9585     {
9586       if(nbOfComp==nbOfComp2)
9587         {
9588           std::transform(begin(),end(),other->begin(),getPointer(),std::plus<int>());
9589         }
9590       else if(nbOfComp2==1)
9591         {
9592           int *ptr=getPointer();
9593           const int *ptrc=other->getConstPointer();
9594           for(int i=0;i<nbOfTuple;i++)
9595             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::plus<int>(),*ptrc++));
9596         }
9597       else
9598         throw INTERP_KERNEL::Exception(msg);
9599     }
9600   else if(nbOfTuple2==1)
9601     {
9602       if(nbOfComp2==nbOfComp)
9603         {
9604           int *ptr=getPointer();
9605           const int *ptrc=other->getConstPointer();
9606           for(int i=0;i<nbOfTuple;i++)
9607             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::plus<int>());
9608         }
9609       else
9610         throw INTERP_KERNEL::Exception(msg);
9611     }
9612   else
9613     throw INTERP_KERNEL::Exception(msg);
9614   declareAsNew();
9615 }
9616
9617 /*!
9618  * Returns a new DataArrayInt that is a subtraction of two given arrays. There are 3
9619  * valid cases.
9620  * 1.  The arrays have same number of tuples and components. Then each value of
9621  *   the result array (_a_) is a subtraction of the corresponding values of \a a1 and
9622  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ i, j ].
9623  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
9624  *   component. Then
9625  *   _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ i, 0 ].
9626  * 3.  The arrays have same number of components and one array, say _a2_, has one
9627  *   tuple. Then
9628  *   _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ 0, j ].
9629  *
9630  * Info on components is copied either from the first array (in the first case) or from
9631  * the array with maximal number of elements (getNbOfElems()).
9632  *  \param [in] a1 - an array to subtract from.
9633  *  \param [in] a2 - an array to subtract.
9634  *  \return DataArrayInt * - the new instance of DataArrayInt.
9635  *          The caller is to delete this result array using decrRef() as it is no more
9636  *          needed.
9637  *  \throw If either \a a1 or \a a2 is NULL.
9638  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
9639  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
9640  *         none of them has number of tuples or components equal to 1.
9641  */
9642 DataArrayInt *DataArrayInt::Substract(const DataArrayInt *a1, const DataArrayInt *a2) throw(INTERP_KERNEL::Exception)
9643 {
9644   if(!a1 || !a2)
9645     throw INTERP_KERNEL::Exception("DataArrayInt::Substract : input DataArrayInt instance is NULL !");
9646   int nbOfTuple1=a1->getNumberOfTuples();
9647   int nbOfTuple2=a2->getNumberOfTuples();
9648   int nbOfComp1=a1->getNumberOfComponents();
9649   int nbOfComp2=a2->getNumberOfComponents();
9650   if(nbOfTuple2==nbOfTuple1)
9651     {
9652       if(nbOfComp1==nbOfComp2)
9653         {
9654           MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
9655           ret->alloc(nbOfTuple2,nbOfComp1);
9656           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::minus<int>());
9657           ret->copyStringInfoFrom(*a1);
9658           return ret.retn();
9659         }
9660       else if(nbOfComp2==1)
9661         {
9662           MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
9663           ret->alloc(nbOfTuple1,nbOfComp1);
9664           const int *a2Ptr=a2->getConstPointer();
9665           const int *a1Ptr=a1->getConstPointer();
9666           int *res=ret->getPointer();
9667           for(int i=0;i<nbOfTuple1;i++)
9668             res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::minus<int>(),a2Ptr[i]));
9669           ret->copyStringInfoFrom(*a1);
9670           return ret.retn();
9671         }
9672       else
9673         {
9674           a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Substract !");
9675           return 0;
9676         }
9677     }
9678   else if(nbOfTuple2==1)
9679     {
9680       a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Substract !");
9681       MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
9682       ret->alloc(nbOfTuple1,nbOfComp1);
9683       const int *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
9684       int *pt=ret->getPointer();
9685       for(int i=0;i<nbOfTuple1;i++)
9686         pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::minus<int>());
9687       ret->copyStringInfoFrom(*a1);
9688       return ret.retn();
9689     }
9690   else
9691     {
9692       a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Substract !");//will always throw an exception
9693       return 0;
9694     }
9695 }
9696
9697 /*!
9698  * Subtract values of another DataArrayInt from values of \a this one. There are 3
9699  * valid cases.
9700  * 1.  The arrays have same number of tuples and components. Then each value of
9701  *   \a other array is subtracted from the corresponding value of \a this array, i.e.:
9702  *   _a_ [ i, j ] -= _other_ [ i, j ].
9703  * 2.  The arrays have same number of tuples and \a other array has one component. Then
9704  *   _a_ [ i, j ] -= _other_ [ i, 0 ].
9705  * 3.  The arrays have same number of components and \a other array has one tuple. Then
9706  *   _a_ [ i, j ] -= _a2_ [ 0, j ].
9707  *
9708  *  \param [in] other - an array to subtract from \a this one.
9709  *  \throw If \a other is NULL.
9710  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
9711  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
9712  *         \a other has number of both tuples and components not equal to 1.
9713  */
9714 void DataArrayInt::substractEqual(const DataArrayInt *other) throw(INTERP_KERNEL::Exception)
9715 {
9716   if(!other)
9717     throw INTERP_KERNEL::Exception("DataArrayInt::substractEqual : input DataArrayInt instance is NULL !");
9718   const char *msg="Nb of tuples mismatch for DataArrayInt::substractEqual  !";
9719   checkAllocated(); other->checkAllocated();
9720   int nbOfTuple=getNumberOfTuples();
9721   int nbOfTuple2=other->getNumberOfTuples();
9722   int nbOfComp=getNumberOfComponents();
9723   int nbOfComp2=other->getNumberOfComponents();
9724   if(nbOfTuple==nbOfTuple2)
9725     {
9726       if(nbOfComp==nbOfComp2)
9727         {
9728           std::transform(begin(),end(),other->begin(),getPointer(),std::minus<int>());
9729         }
9730       else if(nbOfComp2==1)
9731         {
9732           int *ptr=getPointer();
9733           const int *ptrc=other->getConstPointer();
9734           for(int i=0;i<nbOfTuple;i++)
9735             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::minus<int>(),*ptrc++));
9736         }
9737       else
9738         throw INTERP_KERNEL::Exception(msg);
9739     }
9740   else if(nbOfTuple2==1)
9741     {
9742       int *ptr=getPointer();
9743       const int *ptrc=other->getConstPointer();
9744       for(int i=0;i<nbOfTuple;i++)
9745         std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::minus<int>());
9746     }
9747   else
9748     throw INTERP_KERNEL::Exception(msg);
9749   declareAsNew();
9750 }
9751
9752 /*!
9753  * Returns a new DataArrayInt that is a product of two given arrays. There are 3
9754  * valid cases.
9755  * 1.  The arrays have same number of tuples and components. Then each value of
9756  *   the result array (_a_) is a product of the corresponding values of \a a1 and
9757  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ i, j ].
9758  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
9759  *   component. Then
9760  *   _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ i, 0 ].
9761  * 3.  The arrays have same number of components and one array, say _a2_, has one
9762  *   tuple. Then
9763  *   _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ 0, j ].
9764  *
9765  * Info on components is copied either from the first array (in the first case) or from
9766  * the array with maximal number of elements (getNbOfElems()).
9767  *  \param [in] a1 - a factor array.
9768  *  \param [in] a2 - another factor array.
9769  *  \return DataArrayInt * - the new instance of DataArrayInt.
9770  *          The caller is to delete this result array using decrRef() as it is no more
9771  *          needed.
9772  *  \throw If either \a a1 or \a a2 is NULL.
9773  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
9774  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
9775  *         none of them has number of tuples or components equal to 1.
9776  */
9777 DataArrayInt *DataArrayInt::Multiply(const DataArrayInt *a1, const DataArrayInt *a2) throw(INTERP_KERNEL::Exception)
9778 {
9779   if(!a1 || !a2)
9780     throw INTERP_KERNEL::Exception("DataArrayInt::Multiply : input DataArrayInt instance is NULL !");
9781   int nbOfTuple=a1->getNumberOfTuples();
9782   int nbOfTuple2=a2->getNumberOfTuples();
9783   int nbOfComp=a1->getNumberOfComponents();
9784   int nbOfComp2=a2->getNumberOfComponents();
9785   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=0;
9786   if(nbOfTuple==nbOfTuple2)
9787     {
9788       if(nbOfComp==nbOfComp2)
9789         {
9790           ret=DataArrayInt::New();
9791           ret->alloc(nbOfTuple,nbOfComp);
9792           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::multiplies<int>());
9793           ret->copyStringInfoFrom(*a1);
9794         }
9795       else
9796         {
9797           int nbOfCompMin,nbOfCompMax;
9798           const DataArrayInt *aMin, *aMax;
9799           if(nbOfComp>nbOfComp2)
9800             {
9801               nbOfCompMin=nbOfComp2; nbOfCompMax=nbOfComp;
9802               aMin=a2; aMax=a1;
9803             }
9804           else
9805             {
9806               nbOfCompMin=nbOfComp; nbOfCompMax=nbOfComp2;
9807               aMin=a1; aMax=a2;
9808             }
9809           if(nbOfCompMin==1)
9810             {
9811               ret=DataArrayInt::New();
9812               ret->alloc(nbOfTuple,nbOfCompMax);
9813               const int *aMinPtr=aMin->getConstPointer();
9814               const int *aMaxPtr=aMax->getConstPointer();
9815               int *res=ret->getPointer();
9816               for(int i=0;i<nbOfTuple;i++)
9817                 res=std::transform(aMaxPtr+i*nbOfCompMax,aMaxPtr+(i+1)*nbOfCompMax,res,std::bind2nd(std::multiplies<int>(),aMinPtr[i]));
9818               ret->copyStringInfoFrom(*aMax);
9819             }
9820           else
9821             throw INTERP_KERNEL::Exception("Nb of components mismatch for array Multiply !");
9822         }
9823     }
9824   else if((nbOfTuple==1 && nbOfTuple2>1) || (nbOfTuple>1 && nbOfTuple2==1))
9825     {
9826       if(nbOfComp==nbOfComp2)
9827         {
9828           int nbOfTupleMax=std::max(nbOfTuple,nbOfTuple2);
9829           const DataArrayInt *aMin=nbOfTuple>nbOfTuple2?a2:a1;
9830           const DataArrayInt *aMax=nbOfTuple>nbOfTuple2?a1:a2;
9831           const int *aMinPtr=aMin->getConstPointer(),*aMaxPtr=aMax->getConstPointer();
9832           ret=DataArrayInt::New();
9833           ret->alloc(nbOfTupleMax,nbOfComp);
9834           int *res=ret->getPointer();
9835           for(int i=0;i<nbOfTupleMax;i++)
9836             res=std::transform(aMaxPtr+i*nbOfComp,aMaxPtr+(i+1)*nbOfComp,aMinPtr,res,std::multiplies<int>());
9837           ret->copyStringInfoFrom(*aMax);
9838         }
9839       else
9840         throw INTERP_KERNEL::Exception("Nb of components mismatch for array Multiply !");
9841     }
9842   else
9843     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Multiply !");
9844   return ret.retn();
9845 }
9846
9847
9848 /*!
9849  * Multiply values of another DataArrayInt to values of \a this one. There are 3
9850  * valid cases.
9851  * 1.  The arrays have same number of tuples and components. Then each value of
9852  *   \a other array is multiplied to the corresponding value of \a this array, i.e.:
9853  *   _a_ [ i, j ] *= _other_ [ i, j ].
9854  * 2.  The arrays have same number of tuples and \a other array has one component. Then
9855  *   _a_ [ i, j ] *= _other_ [ i, 0 ].
9856  * 3.  The arrays have same number of components and \a other array has one tuple. Then
9857  *   _a_ [ i, j ] *= _a2_ [ 0, j ].
9858  *
9859  *  \param [in] other - an array to multiply to \a this one.
9860  *  \throw If \a other is NULL.
9861  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
9862  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
9863  *         \a other has number of both tuples and components not equal to 1.
9864  */
9865 void DataArrayInt::multiplyEqual(const DataArrayInt *other) throw(INTERP_KERNEL::Exception)
9866 {
9867   if(!other)
9868     throw INTERP_KERNEL::Exception("DataArrayInt::multiplyEqual : input DataArrayInt instance is NULL !");
9869   const char *msg="Nb of tuples mismatch for DataArrayInt::multiplyEqual !";
9870   checkAllocated(); other->checkAllocated();
9871   int nbOfTuple=getNumberOfTuples();
9872   int nbOfTuple2=other->getNumberOfTuples();
9873   int nbOfComp=getNumberOfComponents();
9874   int nbOfComp2=other->getNumberOfComponents();
9875   if(nbOfTuple==nbOfTuple2)
9876     {
9877       if(nbOfComp==nbOfComp2)
9878         {
9879           std::transform(begin(),end(),other->begin(),getPointer(),std::multiplies<int>());
9880         }
9881       else if(nbOfComp2==1)
9882         {
9883           int *ptr=getPointer();
9884           const int *ptrc=other->getConstPointer();
9885           for(int i=0;i<nbOfTuple;i++)
9886             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::multiplies<int>(),*ptrc++));    
9887         }
9888       else
9889         throw INTERP_KERNEL::Exception(msg);
9890     }
9891   else if(nbOfTuple2==1)
9892     {
9893       if(nbOfComp2==nbOfComp)
9894         {
9895           int *ptr=getPointer();
9896           const int *ptrc=other->getConstPointer();
9897           for(int i=0;i<nbOfTuple;i++)
9898             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::multiplies<int>());
9899         }
9900       else
9901         throw INTERP_KERNEL::Exception(msg);
9902     }
9903   else
9904     throw INTERP_KERNEL::Exception(msg);
9905   declareAsNew();
9906 }
9907
9908
9909 /*!
9910  * Returns a new DataArrayInt that is a division of two given arrays. There are 3
9911  * valid cases.
9912  * 1.  The arrays have same number of tuples and components. Then each value of
9913  *   the result array (_a_) is a division of the corresponding values of \a a1 and
9914  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ i, j ].
9915  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
9916  *   component. Then
9917  *   _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ i, 0 ].
9918  * 3.  The arrays have same number of components and one array, say _a2_, has one
9919  *   tuple. Then
9920  *   _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ 0, j ].
9921  *
9922  * Info on components is copied either from the first array (in the first case) or from
9923  * the array with maximal number of elements (getNbOfElems()).
9924  *  \warning No check of division by zero is performed!
9925  *  \param [in] a1 - a numerator array.
9926  *  \param [in] a2 - a denominator array.
9927  *  \return DataArrayInt * - the new instance of DataArrayInt.
9928  *          The caller is to delete this result array using decrRef() as it is no more
9929  *          needed.
9930  *  \throw If either \a a1 or \a a2 is NULL.
9931  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
9932  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
9933  *         none of them has number of tuples or components equal to 1.
9934  */
9935 DataArrayInt *DataArrayInt::Divide(const DataArrayInt *a1, const DataArrayInt *a2) throw(INTERP_KERNEL::Exception)
9936 {
9937   if(!a1 || !a2)
9938     throw INTERP_KERNEL::Exception("DataArrayInt::Divide : input DataArrayInt instance is NULL !");
9939   int nbOfTuple1=a1->getNumberOfTuples();
9940   int nbOfTuple2=a2->getNumberOfTuples();
9941   int nbOfComp1=a1->getNumberOfComponents();
9942   int nbOfComp2=a2->getNumberOfComponents();
9943   if(nbOfTuple2==nbOfTuple1)
9944     {
9945       if(nbOfComp1==nbOfComp2)
9946         {
9947           MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
9948           ret->alloc(nbOfTuple2,nbOfComp1);
9949           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::divides<int>());
9950           ret->copyStringInfoFrom(*a1);
9951           return ret.retn();
9952         }
9953       else if(nbOfComp2==1)
9954         {
9955           MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
9956           ret->alloc(nbOfTuple1,nbOfComp1);
9957           const int *a2Ptr=a2->getConstPointer();
9958           const int *a1Ptr=a1->getConstPointer();
9959           int *res=ret->getPointer();
9960           for(int i=0;i<nbOfTuple1;i++)
9961             res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::divides<int>(),a2Ptr[i]));
9962           ret->copyStringInfoFrom(*a1);
9963           return ret.retn();
9964         }
9965       else
9966         {
9967           a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Divide !");
9968           return 0;
9969         }
9970     }
9971   else if(nbOfTuple2==1)
9972     {
9973       a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Divide !");
9974       MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
9975       ret->alloc(nbOfTuple1,nbOfComp1);
9976       const int *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
9977       int *pt=ret->getPointer();
9978       for(int i=0;i<nbOfTuple1;i++)
9979         pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::divides<int>());
9980       ret->copyStringInfoFrom(*a1);
9981       return ret.retn();
9982     }
9983   else
9984     {
9985       a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Divide !");//will always throw an exception
9986       return 0;
9987     }
9988 }
9989
9990 /*!
9991  * Divide values of \a this array by values of another DataArrayInt. There are 3
9992  * valid cases.
9993  * 1.  The arrays have same number of tuples and components. Then each value of
9994  *    \a this array is divided by the corresponding value of \a other one, i.e.:
9995  *   _a_ [ i, j ] /= _other_ [ i, j ].
9996  * 2.  The arrays have same number of tuples and \a other array has one component. Then
9997  *   _a_ [ i, j ] /= _other_ [ i, 0 ].
9998  * 3.  The arrays have same number of components and \a other array has one tuple. Then
9999  *   _a_ [ i, j ] /= _a2_ [ 0, j ].
10000  *
10001  *  \warning No check of division by zero is performed!
10002  *  \param [in] other - an array to divide \a this one by.
10003  *  \throw If \a other is NULL.
10004  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
10005  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
10006  *         \a other has number of both tuples and components not equal to 1.
10007  */
10008 void DataArrayInt::divideEqual(const DataArrayInt *other) throw(INTERP_KERNEL::Exception)
10009 {
10010   if(!other)
10011     throw INTERP_KERNEL::Exception("DataArrayInt::divideEqual : input DataArrayInt instance is NULL !");
10012   const char *msg="Nb of tuples mismatch for DataArrayInt::divideEqual !";
10013   checkAllocated(); other->checkAllocated();
10014   int nbOfTuple=getNumberOfTuples();
10015   int nbOfTuple2=other->getNumberOfTuples();
10016   int nbOfComp=getNumberOfComponents();
10017   int nbOfComp2=other->getNumberOfComponents();
10018   if(nbOfTuple==nbOfTuple2)
10019     {
10020       if(nbOfComp==nbOfComp2)
10021         {
10022           std::transform(begin(),end(),other->begin(),getPointer(),std::divides<int>());
10023         }
10024       else if(nbOfComp2==1)
10025         {
10026           int *ptr=getPointer();
10027           const int *ptrc=other->getConstPointer();
10028           for(int i=0;i<nbOfTuple;i++)
10029             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::divides<int>(),*ptrc++));
10030         }
10031       else
10032         throw INTERP_KERNEL::Exception(msg);
10033     }
10034   else if(nbOfTuple2==1)
10035     {
10036       if(nbOfComp2==nbOfComp)
10037         {
10038           int *ptr=getPointer();
10039           const int *ptrc=other->getConstPointer();
10040           for(int i=0;i<nbOfTuple;i++)
10041             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::divides<int>());
10042         }
10043       else
10044         throw INTERP_KERNEL::Exception(msg);
10045     }
10046   else
10047     throw INTERP_KERNEL::Exception(msg);
10048   declareAsNew();
10049 }
10050
10051
10052 /*!
10053  * Returns a new DataArrayInt that is a modulus of two given arrays. There are 3
10054  * valid cases.
10055  * 1.  The arrays have same number of tuples and components. Then each value of
10056  *   the result array (_a_) is a division of the corresponding values of \a a1 and
10057  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] % _a2_ [ i, j ].
10058  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
10059  *   component. Then
10060  *   _a_ [ i, j ] = _a1_ [ i, j ] % _a2_ [ i, 0 ].
10061  * 3.  The arrays have same number of components and one array, say _a2_, has one
10062  *   tuple. Then
10063  *   _a_ [ i, j ] = _a1_ [ i, j ] % _a2_ [ 0, j ].
10064  *
10065  * Info on components is copied either from the first array (in the first case) or from
10066  * the array with maximal number of elements (getNbOfElems()).
10067  *  \warning No check of division by zero is performed!
10068  *  \param [in] a1 - a dividend array.
10069  *  \param [in] a2 - a divisor array.
10070  *  \return DataArrayInt * - the new instance of DataArrayInt.
10071  *          The caller is to delete this result array using decrRef() as it is no more
10072  *          needed.
10073  *  \throw If either \a a1 or \a a2 is NULL.
10074  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
10075  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
10076  *         none of them has number of tuples or components equal to 1.
10077  */
10078 DataArrayInt *DataArrayInt::Modulus(const DataArrayInt *a1, const DataArrayInt *a2) throw(INTERP_KERNEL::Exception)
10079 {
10080     if(!a1 || !a2)
10081     throw INTERP_KERNEL::Exception("DataArrayInt::Modulus : input DataArrayInt instance is NULL !");
10082   int nbOfTuple1=a1->getNumberOfTuples();
10083   int nbOfTuple2=a2->getNumberOfTuples();
10084   int nbOfComp1=a1->getNumberOfComponents();
10085   int nbOfComp2=a2->getNumberOfComponents();
10086   if(nbOfTuple2==nbOfTuple1)
10087     {
10088       if(nbOfComp1==nbOfComp2)
10089         {
10090           MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
10091           ret->alloc(nbOfTuple2,nbOfComp1);
10092           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::modulus<int>());
10093           ret->copyStringInfoFrom(*a1);
10094           return ret.retn();
10095         }
10096       else if(nbOfComp2==1)
10097         {
10098           MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
10099           ret->alloc(nbOfTuple1,nbOfComp1);
10100           const int *a2Ptr=a2->getConstPointer();
10101           const int *a1Ptr=a1->getConstPointer();
10102           int *res=ret->getPointer();
10103           for(int i=0;i<nbOfTuple1;i++)
10104             res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::modulus<int>(),a2Ptr[i]));
10105           ret->copyStringInfoFrom(*a1);
10106           return ret.retn();
10107         }
10108       else
10109         {
10110           a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Modulus !");
10111           return 0;
10112         }
10113     }
10114   else if(nbOfTuple2==1)
10115     {
10116       a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Modulus !");
10117       MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
10118       ret->alloc(nbOfTuple1,nbOfComp1);
10119       const int *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
10120       int *pt=ret->getPointer();
10121       for(int i=0;i<nbOfTuple1;i++)
10122         pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::modulus<int>());
10123       ret->copyStringInfoFrom(*a1);
10124       return ret.retn();
10125     }
10126   else
10127     {
10128       a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Modulus !");//will always throw an exception
10129       return 0;
10130     }
10131 }
10132
10133 /*!
10134  * Modify \a this array so that each value becomes a modulus of division of this value by
10135  * a value of another DataArrayInt. There are 3 valid cases.
10136  * 1.  The arrays have same number of tuples and components. Then each value of
10137  *    \a this array is divided by the corresponding value of \a other one, i.e.:
10138  *   _a_ [ i, j ] %= _other_ [ i, j ].
10139  * 2.  The arrays have same number of tuples and \a other array has one component. Then
10140  *   _a_ [ i, j ] %= _other_ [ i, 0 ].
10141  * 3.  The arrays have same number of components and \a other array has one tuple. Then
10142  *   _a_ [ i, j ] %= _a2_ [ 0, j ].
10143  *
10144  *  \warning No check of division by zero is performed!
10145  *  \param [in] other - a divisor array.
10146  *  \throw If \a other is NULL.
10147  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
10148  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
10149  *         \a other has number of both tuples and components not equal to 1.
10150  */
10151 void DataArrayInt::modulusEqual(const DataArrayInt *other) throw(INTERP_KERNEL::Exception)
10152 {
10153   if(!other)
10154     throw INTERP_KERNEL::Exception("DataArrayInt::modulusEqual : input DataArrayInt instance is NULL !");
10155   const char *msg="Nb of tuples mismatch for DataArrayInt::modulusEqual !";
10156   checkAllocated(); other->checkAllocated();
10157   int nbOfTuple=getNumberOfTuples();
10158   int nbOfTuple2=other->getNumberOfTuples();
10159   int nbOfComp=getNumberOfComponents();
10160   int nbOfComp2=other->getNumberOfComponents();
10161   if(nbOfTuple==nbOfTuple2)
10162     {
10163       if(nbOfComp==nbOfComp2)
10164         {
10165           std::transform(begin(),end(),other->begin(),getPointer(),std::modulus<int>());
10166         }
10167       else if(nbOfComp2==1)
10168         {
10169           if(nbOfComp2==nbOfComp)
10170             {
10171               int *ptr=getPointer();
10172               const int *ptrc=other->getConstPointer();
10173               for(int i=0;i<nbOfTuple;i++)
10174                 std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::modulus<int>(),*ptrc++));
10175             }
10176           else
10177             throw INTERP_KERNEL::Exception(msg);
10178         }
10179       else
10180         throw INTERP_KERNEL::Exception(msg);
10181     }
10182   else if(nbOfTuple2==1)
10183     {
10184       int *ptr=getPointer();
10185       const int *ptrc=other->getConstPointer();
10186       for(int i=0;i<nbOfTuple;i++)
10187         std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::modulus<int>());
10188     }
10189   else
10190     throw INTERP_KERNEL::Exception(msg);
10191   declareAsNew();
10192 }
10193
10194 /*!
10195  * Returns a new DataArrayInt that is the result of pow of two given arrays. There are 3
10196  * valid cases.
10197  *
10198  *  \param [in] a1 - an array to pow up.
10199  *  \param [in] a2 - another array to sum up.
10200  *  \return DataArrayInt * - the new instance of DataArrayInt.
10201  *          The caller is to delete this result array using decrRef() as it is no more
10202  *          needed.
10203  *  \throw If either \a a1 or \a a2 is NULL.
10204  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
10205  *  \throw If \a a1->getNumberOfComponents() != 1 or \a a2->getNumberOfComponents() != 1.
10206  *  \throw If there is a negative value in \a a2.
10207  */
10208 DataArrayInt *DataArrayInt::Pow(const DataArrayInt *a1, const DataArrayInt *a2) throw(INTERP_KERNEL::Exception)
10209 {
10210   if(!a1 || !a2)
10211     throw INTERP_KERNEL::Exception("DataArrayInt::Pow : at least one of input instances is null !");
10212   int nbOfTuple=a1->getNumberOfTuples();
10213   int nbOfTuple2=a2->getNumberOfTuples();
10214   int nbOfComp=a1->getNumberOfComponents();
10215   int nbOfComp2=a2->getNumberOfComponents();
10216   if(nbOfTuple!=nbOfTuple2)
10217     throw INTERP_KERNEL::Exception("DataArrayInt::Pow : number of tuples mismatches !");
10218   if(nbOfComp!=1 || nbOfComp2!=1)
10219     throw INTERP_KERNEL::Exception("DataArrayInt::Pow : number of components of both arrays must be equal to 1 !");
10220   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbOfTuple,1);
10221   const int *ptr1(a1->begin()),*ptr2(a2->begin());
10222   int *ptr=ret->getPointer();
10223   for(int i=0;i<nbOfTuple;i++,ptr1++,ptr2++,ptr++)
10224     {
10225       if(*ptr2>=0)
10226         {
10227           int tmp=1;
10228           for(int j=0;j<*ptr2;j++)
10229             tmp*=*ptr1;
10230           *ptr=tmp;
10231         }
10232       else
10233         {
10234           std::ostringstream oss; oss << "DataArrayInt::Pow : on tuple #" << i << " of a2 value is < 0 (" << *ptr2 << ") !";
10235           throw INTERP_KERNEL::Exception(oss.str().c_str());
10236         }
10237     }
10238   return ret.retn();
10239 }
10240
10241 /*!
10242  * Apply pow on values of another DataArrayInt to values of \a this one.
10243  *
10244  *  \param [in] other - an array to pow to \a this one.
10245  *  \throw If \a other is NULL.
10246  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples()
10247  *  \throw If \a this->getNumberOfComponents() != 1 or \a other->getNumberOfComponents() != 1
10248  *  \throw If there is a negative value in \a other.
10249  */
10250 void DataArrayInt::powEqual(const DataArrayInt *other) throw(INTERP_KERNEL::Exception)
10251 {
10252   if(!other)
10253     throw INTERP_KERNEL::Exception("DataArrayInt::powEqual : input instance is null !");
10254   int nbOfTuple=getNumberOfTuples();
10255   int nbOfTuple2=other->getNumberOfTuples();
10256   int nbOfComp=getNumberOfComponents();
10257   int nbOfComp2=other->getNumberOfComponents();
10258   if(nbOfTuple!=nbOfTuple2)
10259     throw INTERP_KERNEL::Exception("DataArrayInt::powEqual : number of tuples mismatches !");
10260   if(nbOfComp!=1 || nbOfComp2!=1)
10261     throw INTERP_KERNEL::Exception("DataArrayInt::powEqual : number of components of both arrays must be equal to 1 !");
10262   int *ptr=getPointer();
10263   const int *ptrc=other->begin();
10264   for(int i=0;i<nbOfTuple;i++,ptrc++,ptr++)
10265     {
10266       if(*ptrc>=0)
10267         {
10268           int tmp=1;
10269           for(int j=0;j<*ptrc;j++)
10270             tmp*=*ptr;
10271           *ptr=tmp;
10272         }
10273       else
10274         {
10275           std::ostringstream oss; oss << "DataArrayInt::powEqual : on tuple #" << i << " of other value is < 0 (" << *ptrc << ") !";
10276           throw INTERP_KERNEL::Exception(oss.str().c_str());
10277         }
10278     }
10279   declareAsNew();
10280 }
10281
10282 /*!
10283  * Returns a C array which is a renumbering map in "Old to New" mode for the input array.
10284  * This map, if applied to \a start array, would make it sorted. For example, if
10285  * \a start array contents are [9,10,0,6,4,11,3,7] then the contents of the result array is
10286  * [5,6,0,3,2,7,1,4].
10287  *  \param [in] start - pointer to the first element of the array for which the
10288  *         permutation map is computed.
10289  *  \param [in] end - pointer specifying the end of the array \a start, so that
10290  *         the last value of \a start is \a end[ -1 ].
10291  *  \return int * - the result permutation array that the caller is to delete as it is no
10292  *         more needed.
10293  *  \throw If there are equal values in the input array.
10294  */
10295 int *DataArrayInt::CheckAndPreparePermutation(const int *start, const int *end)
10296 {
10297   std::size_t sz=std::distance(start,end);
10298   int *ret=(int *)malloc(sz*sizeof(int));
10299   int *work=new int[sz];
10300   std::copy(start,end,work);
10301   std::sort(work,work+sz);
10302   if(std::unique(work,work+sz)!=work+sz)
10303     {
10304       delete [] work;
10305       free(ret);
10306       throw INTERP_KERNEL::Exception("Some elements are equals in the specified array !");
10307     }
10308   std::map<int,int> m;
10309   for(int *workPt=work;workPt!=work+sz;workPt++)
10310     m[*workPt]=(int)std::distance(work,workPt);
10311   int *iter2=ret;
10312   for(const int *iter=start;iter!=end;iter++,iter2++)
10313     *iter2=m[*iter];
10314   delete [] work;
10315   return ret;
10316 }
10317
10318 /*!
10319  * Returns a new DataArrayInt containing an arithmetic progression
10320  * that is equal to the sequence returned by Python \c range(\a begin,\a  end,\a  step )
10321  * function.
10322  *  \param [in] begin - the start value of the result sequence.
10323  *  \param [in] end - limiting value, so that every value of the result array is less than
10324  *              \a end.
10325  *  \param [in] step - specifies the increment or decrement.
10326  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
10327  *          array using decrRef() as it is no more needed.
10328  *  \throw If \a step == 0.
10329  *  \throw If \a end < \a begin && \a step > 0.
10330  *  \throw If \a end > \a begin && \a step < 0.
10331  */
10332 DataArrayInt *DataArrayInt::Range(int begin, int end, int step) throw(INTERP_KERNEL::Exception)
10333 {
10334   int nbOfTuples=GetNumberOfItemGivenBESRelative(begin,end,step,"DataArrayInt::Range");
10335   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
10336   ret->alloc(nbOfTuples,1);
10337   int *ptr=ret->getPointer();
10338   if(step>0)
10339     {
10340       for(int i=begin;i<end;i+=step,ptr++)
10341         *ptr=i;
10342     }
10343   else
10344     {
10345       for(int i=begin;i>end;i+=step,ptr++)
10346         *ptr=i;
10347     }
10348   return ret.retn();
10349 }
10350
10351 /*!
10352  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
10353  * Server side.
10354  */
10355 void DataArrayInt::getTinySerializationIntInformation(std::vector<int>& tinyInfo) const
10356 {
10357   tinyInfo.resize(2);
10358   if(isAllocated())
10359     {
10360       tinyInfo[0]=getNumberOfTuples();
10361       tinyInfo[1]=getNumberOfComponents();
10362     }
10363   else
10364     {
10365       tinyInfo[0]=-1;
10366       tinyInfo[1]=-1;
10367     }
10368 }
10369
10370 /*!
10371  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
10372  * Server side.
10373  */
10374 void DataArrayInt::getTinySerializationStrInformation(std::vector<std::string>& tinyInfo) const
10375 {
10376   if(isAllocated())
10377     {
10378       int nbOfCompo=getNumberOfComponents();
10379       tinyInfo.resize(nbOfCompo+1);
10380       tinyInfo[0]=getName();
10381       for(int i=0;i<nbOfCompo;i++)
10382         tinyInfo[i+1]=getInfoOnComponent(i);
10383     }
10384   else
10385     {
10386       tinyInfo.resize(1);
10387       tinyInfo[0]=getName();
10388     }
10389 }
10390
10391 /*!
10392  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
10393  * This method returns if a feeding is needed.
10394  */
10395 bool DataArrayInt::resizeForUnserialization(const std::vector<int>& tinyInfoI)
10396 {
10397   int nbOfTuple=tinyInfoI[0];
10398   int nbOfComp=tinyInfoI[1];
10399   if(nbOfTuple!=-1 || nbOfComp!=-1)
10400     {
10401       alloc(nbOfTuple,nbOfComp);
10402       return true;
10403     }
10404   return false;
10405 }
10406
10407 /*!
10408  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
10409  * This method returns if a feeding is needed.
10410  */
10411 void DataArrayInt::finishUnserialization(const std::vector<int>& tinyInfoI, const std::vector<std::string>& tinyInfoS)
10412 {
10413   setName(tinyInfoS[0].c_str());
10414   if(isAllocated())
10415     {
10416       int nbOfCompo=getNumberOfComponents();
10417       for(int i=0;i<nbOfCompo;i++)
10418         setInfoOnComponent(i,tinyInfoS[i+1].c_str());
10419     }
10420 }
10421
10422 DataArrayIntIterator::DataArrayIntIterator(DataArrayInt *da):_da(da),_pt(0),_tuple_id(0),_nb_comp(0),_nb_tuple(0)
10423 {
10424   if(_da)
10425     {
10426       _da->incrRef();
10427       if(_da->isAllocated())
10428         {
10429           _nb_comp=da->getNumberOfComponents();
10430           _nb_tuple=da->getNumberOfTuples();
10431           _pt=da->getPointer();
10432         }
10433     }
10434 }
10435
10436 DataArrayIntIterator::~DataArrayIntIterator()
10437 {
10438   if(_da)
10439     _da->decrRef();
10440 }
10441
10442 DataArrayIntTuple *DataArrayIntIterator::nextt() throw(INTERP_KERNEL::Exception)
10443 {
10444   if(_tuple_id<_nb_tuple)
10445     {
10446       _tuple_id++;
10447       DataArrayIntTuple *ret=new DataArrayIntTuple(_pt,_nb_comp);
10448       _pt+=_nb_comp;
10449       return ret;
10450     }
10451   else
10452     return 0;
10453 }
10454
10455 DataArrayIntTuple::DataArrayIntTuple(int *pt, int nbOfComp):_pt(pt),_nb_of_compo(nbOfComp)
10456 {
10457 }
10458
10459 std::string DataArrayIntTuple::repr() const throw(INTERP_KERNEL::Exception)
10460 {
10461   std::ostringstream oss; oss << "(";
10462   for(int i=0;i<_nb_of_compo-1;i++)
10463     oss << _pt[i] << ", ";
10464   oss << _pt[_nb_of_compo-1] << ")";
10465   return oss.str();
10466 }
10467
10468 int DataArrayIntTuple::intValue() const throw(INTERP_KERNEL::Exception)
10469 {
10470   if(_nb_of_compo==1)
10471     return *_pt;
10472   throw INTERP_KERNEL::Exception("DataArrayIntTuple::intValue : DataArrayIntTuple instance has not exactly 1 component -> Not possible to convert it into an integer !");
10473 }
10474
10475 /*!
10476  * This method returns a newly allocated instance the caller should dealed with by a ParaMEDMEM::DataArrayInt::decrRef.
10477  * This method performs \b no copy of data. The content is only referenced using ParaMEDMEM::DataArrayInt::useArray with ownership set to \b false.
10478  * 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
10479  * \b nbOfCompo=1 and \bnbOfTuples==this->_nb_of_elem.
10480  */
10481 DataArrayInt *DataArrayIntTuple::buildDAInt(int nbOfTuples, int nbOfCompo) const throw(INTERP_KERNEL::Exception)
10482 {
10483   if((_nb_of_compo==nbOfCompo && nbOfTuples==1) || (_nb_of_compo==nbOfTuples && nbOfCompo==1))
10484     {
10485       DataArrayInt *ret=DataArrayInt::New();
10486       ret->useExternalArrayWithRWAccess(_pt,nbOfTuples,nbOfCompo);
10487       return ret;
10488     }
10489   else
10490     {
10491       std::ostringstream oss; oss << "DataArrayIntTuple::buildDAInt : unable to build a requested DataArrayInt instance with nbofTuple=" << nbOfTuples << " and nbOfCompo=" << nbOfCompo;
10492       oss << ".\nBecause the number of elements in this is " << _nb_of_compo << " !";
10493       throw INTERP_KERNEL::Exception(oss.str().c_str());
10494     }
10495 }