Salome HOME
On the road of reimplementation of basic MEDLoader API with advanced one.
[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  * This method checks that all tuples in \a other are in \a this.
1791  * If true, the output param \a tupleIds contains the tuples ids of \a this that correspond to tupes in \a this.
1792  * For each i in [ 0 , other->getNumberOfTuples() ) tuple #i in \a other is equal ( regarding input precision \a prec ) to tuple tupleIds[i] in \a this.
1793  *
1794  * \param [in] other - the array having the same number of components than \a this.
1795  * \param [out] tupleIds - the tuple ids containing the same number of tuples than \a other has.
1796  * \sa DataArrayDouble::findCommonTuples
1797  */
1798 bool DataArrayDouble::areIncludedInMe(const DataArrayDouble *other, double prec, DataArrayInt *&tupleIds) const throw(INTERP_KERNEL::Exception)
1799 {
1800   if(!other)
1801     throw INTERP_KERNEL::Exception("DataArrayDouble::areIncludedInMe : input array is NULL !");
1802   checkAllocated(); other->checkAllocated();
1803   if(getNumberOfComponents()!=other->getNumberOfComponents())
1804     throw INTERP_KERNEL::Exception("DataArrayDouble::areIncludedInMe : the number of components does not match !");
1805   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> a=DataArrayDouble::Aggregate(this,other);
1806   DataArrayInt *c=0,*ci=0;
1807   a->findCommonTuples(prec,getNumberOfTuples(),c,ci);
1808   int newNbOfTuples=-1;
1809   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ids=DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2(a->getNumberOfTuples(),c->begin(),ci->begin(),ci->end(),newNbOfTuples);
1810   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret1=ids->selectByTupleId2(getNumberOfTuples(),a->getNumberOfTuples(),1);
1811   tupleIds=ret1.retn();
1812   return newNbOfTuples==getNumberOfTuples();
1813 }
1814
1815 /*!
1816  * Searches for tuples coincident within \a prec tolerance. Each tuple is considered
1817  * as coordinates of a point in getNumberOfComponents()-dimensional space. The
1818  * distance separating two points is computed with the infinite norm.
1819  *
1820  * Indices of coincident tuples are stored in output arrays.
1821  * A pair of arrays (\a comm, \a commIndex) is called "Surjective Format 2".
1822  *
1823  * This method is typically used by MEDCouplingPointSet::findCommonNodes() and
1824  * MEDCouplingUMesh::mergeNodes().
1825  *  \param [in] prec - minimal absolute distance between two tuples (infinite norm) at which they are
1826  *              considered not coincident.
1827  *  \param [in] limitTupleId - limit tuple id. If all tuples within a group of coincident
1828  *              tuples have id strictly lower than \a limitTupleId then they are not returned.
1829  *  \param [out] comm - the array holding ids (== indices) of coincident tuples. 
1830  *               \a comm->getNumberOfComponents() == 1. 
1831  *               \a comm->getNumberOfTuples() == \a commIndex->back().
1832  *  \param [out] commIndex - the array dividing all indices stored in \a comm into
1833  *               groups of (indices of) coincident tuples. Its every value is a tuple
1834  *               index where a next group of tuples begins. For example the second
1835  *               group of tuples in \a comm is described by following range of indices:
1836  *               [ \a commIndex[1], \a commIndex[2] ). \a commIndex->getNumberOfTuples()-1
1837  *               gives the number of groups of coincident tuples.
1838  *  \throw If \a this is not allocated.
1839  *  \throw If the number of components is not in [1,2,3].
1840  *
1841  *  \ref cpp_mcdataarraydouble_findcommontuples "Here is a C++ example".
1842  *
1843  *  \ref py_mcdataarraydouble_findcommontuples  "Here is a Python example".
1844  *  \sa DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2(), DataArrayDouble::areIncludedInMe
1845  */
1846 void DataArrayDouble::findCommonTuples(double prec, int limitTupleId, DataArrayInt *&comm, DataArrayInt *&commIndex) const throw(INTERP_KERNEL::Exception)
1847 {
1848   checkAllocated();
1849   int nbOfCompo=getNumberOfComponents();
1850   if ((nbOfCompo<1) || (nbOfCompo>3)) //test before work
1851     throw INTERP_KERNEL::Exception("DataArrayDouble::findCommonTuples : Unexpected spacedim of coords. Must be 1, 2 or 3.");
1852   
1853   int nbOfTuples=getNumberOfTuples();
1854   //
1855   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> c(DataArrayInt::New()),cI(DataArrayInt::New()); c->alloc(0,1); cI->pushBackSilent(0);
1856   switch(nbOfCompo)
1857     {
1858     case 3:
1859       findCommonTuplesAlg<3>(begin(),nbOfTuples,limitTupleId,prec,c,cI);
1860       break;
1861     case 2:
1862       findCommonTuplesAlg<2>(begin(),nbOfTuples,limitTupleId,prec,c,cI);
1863       break;
1864     case 1:
1865       findCommonTuplesAlg<1>(begin(),nbOfTuples,limitTupleId,prec,c,cI);
1866       break;
1867     default:
1868       throw INTERP_KERNEL::Exception("DataArrayDouble::findCommonTuples : nb of components managed are 1,2 and 3 ! not implemented for other number of components !");
1869     }
1870   comm=c.retn();
1871   commIndex=cI.retn();
1872 }
1873
1874 /*!
1875  * 
1876  * \param [in] nbTimes specifies the nb of times each tuples in \a this will be duplicated contiguouly in returned DataArrayDouble instance.
1877  *             \a nbTimes  should be at least equal to 1.
1878  * \return a newly allocated DataArrayDouble having one component and number of tuples equal to \a nbTimes * \c this->getNumberOfTuples.
1879  * \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.
1880  */
1881 DataArrayDouble *DataArrayDouble::duplicateEachTupleNTimes(int nbTimes) const throw(INTERP_KERNEL::Exception)
1882 {
1883   checkAllocated();
1884   if(getNumberOfComponents()!=1)
1885     throw INTERP_KERNEL::Exception("DataArrayDouble::duplicateEachTupleNTimes : this should have only one component !");
1886   if(nbTimes<1)
1887     throw INTERP_KERNEL::Exception("DataArrayDouble::duplicateEachTupleNTimes : nb times should be >= 1 !");
1888   int nbTuples=getNumberOfTuples();
1889   const double *inPtr=getConstPointer();
1890   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New(); ret->alloc(nbTimes*nbTuples,1);
1891   double *retPtr=ret->getPointer();
1892   for(int i=0;i<nbTuples;i++,inPtr++)
1893     {
1894       double val=*inPtr;
1895       for(int j=0;j<nbTimes;j++,retPtr++)
1896         *retPtr=val;
1897     }
1898   ret->copyStringInfoFrom(*this);
1899   return ret.retn();
1900 }
1901
1902 /*!
1903  * This methods returns the minimal distance between the two set of points \a this and \a other.
1904  * So \a this and \a other have to have the same number of components. If not an INTERP_KERNEL::Exception will be thrown.
1905  * This method works only if number of components of \a this (equal to those of \a other) is in 1, 2 or 3.
1906  *
1907  * \param [out] thisTupleId the tuple id in \a this corresponding to the returned minimal distance
1908  * \param [out] otherTupleId the tuple id in \a other corresponding to the returned minimal distance
1909  * \return the minimal distance between the two set of points \a this and \a other.
1910  * \sa DataArrayDouble::findClosestTupleId
1911  */
1912 double DataArrayDouble::minimalDistanceTo(const DataArrayDouble *other, int& thisTupleId, int& otherTupleId) const throw(INTERP_KERNEL::Exception)
1913 {
1914   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> part1=findClosestTupleId(other);
1915   int nbOfCompo(getNumberOfComponents());
1916   int otherNbTuples(other->getNumberOfTuples());
1917   const double *thisPt(begin()),*otherPt(other->begin());
1918   const int *part1Pt(part1->begin());
1919   double ret=std::numeric_limits<double>::max();
1920   for(int i=0;i<otherNbTuples;i++,part1Pt++,otherPt+=nbOfCompo)
1921     {
1922       double tmp(0.);
1923       for(int j=0;j<nbOfCompo;j++)
1924         tmp+=(otherPt[j]-thisPt[nbOfCompo*(*part1Pt)+j])*(otherPt[j]-thisPt[nbOfCompo*(*part1Pt)+j]);
1925       if(tmp<ret)
1926         { ret=tmp; thisTupleId=*part1Pt; otherTupleId=i; }
1927     }
1928   return sqrt(ret);
1929 }
1930
1931 /*!
1932  * This methods returns for each tuple in \a other which tuple in \a this is the closest.
1933  * So \a this and \a other have to have the same number of components. If not an INTERP_KERNEL::Exception will be thrown.
1934  * This method works only if number of components of \a this (equal to those of \a other) is in 1, 2 or 3.
1935  *
1936  * \return a newly allocated (new object to be dealt by the caller) DataArrayInt having \c other->getNumberOfTuples() tuples and one components.
1937  * \sa DataArrayDouble::minimalDistanceTo
1938  */
1939 DataArrayInt *DataArrayDouble::findClosestTupleId(const DataArrayDouble *other) const throw(INTERP_KERNEL::Exception)
1940 {
1941   if(!other)
1942     throw INTERP_KERNEL::Exception("DataArrayDouble::findClosestTupleId : other instance is NULL !");
1943   checkAllocated(); other->checkAllocated();
1944   int nbOfCompo=getNumberOfComponents();
1945   if(nbOfCompo!=other->getNumberOfComponents())
1946     {
1947       std::ostringstream oss; oss << "DataArrayDouble::findClosestTupleId : number of components in this is " << nbOfCompo;
1948       oss << ", whereas number of components in other is " << other->getNumberOfComponents() << "! Should be equal !";
1949       throw INTERP_KERNEL::Exception(oss.str().c_str());
1950     }
1951   int nbOfTuples=other->getNumberOfTuples();
1952   int thisNbOfTuples=getNumberOfTuples();
1953   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbOfTuples,1);
1954   double bounds[6];
1955   getMinMaxPerComponent(bounds);
1956   switch(nbOfCompo)
1957     {
1958     case 3:
1959       {
1960         double xDelta(fabs(bounds[1]-bounds[0])),yDelta(fabs(bounds[3]-bounds[2])),zDelta(fabs(bounds[5]-bounds[4]));
1961         double delta=std::max(xDelta,yDelta); delta=std::max(delta,zDelta);
1962         double characSize=pow((delta*delta*delta)/((double)thisNbOfTuples),1./3.);
1963         BBTreePts<3,int> myTree(begin(),0,0,getNumberOfTuples(),characSize*1e-12);
1964         FindClosestTupleIdAlg<3>(myTree,3.*characSize*characSize,other->begin(),nbOfTuples,begin(),thisNbOfTuples,ret->getPointer());
1965         break;
1966       }
1967     case 2:
1968       {
1969         double xDelta(fabs(bounds[1]-bounds[0])),yDelta(fabs(bounds[3]-bounds[2]));
1970         double delta=std::max(xDelta,yDelta);
1971         double characSize=sqrt(delta/(double)thisNbOfTuples);
1972         BBTreePts<2,int> myTree(begin(),0,0,getNumberOfTuples(),characSize*1e-12);
1973         FindClosestTupleIdAlg<2>(myTree,2.*characSize*characSize,other->begin(),nbOfTuples,begin(),thisNbOfTuples,ret->getPointer());
1974         break;
1975       }
1976     case 1:
1977       {
1978         double characSize=fabs(bounds[1]-bounds[0])/thisNbOfTuples;
1979         BBTreePts<1,int> myTree(begin(),0,0,getNumberOfTuples(),characSize*1e-12);
1980         FindClosestTupleIdAlg<1>(myTree,1.*characSize*characSize,other->begin(),nbOfTuples,begin(),thisNbOfTuples,ret->getPointer());
1981         break;
1982       }
1983     default:
1984       throw INTERP_KERNEL::Exception("Unexpected spacedim of coords for findClosestTupleId. Must be 1, 2 or 3.");
1985     }
1986   return ret.retn();
1987 }
1988
1989 /*!
1990  * Returns a copy of \a this array by excluding coincident tuples. Each tuple is
1991  * considered as coordinates of a point in getNumberOfComponents()-dimensional
1992  * space. The distance between tuples is computed using norm2. If several tuples are
1993  * not far each from other than \a prec, only one of them remains in the result
1994  * array. The order of tuples in the result array is same as in \a this one except
1995  * that coincident tuples are excluded.
1996  *  \param [in] prec - minimal absolute distance between two tuples at which they are
1997  *              considered not coincident.
1998  *  \param [in] limitTupleId - limit tuple id. If all tuples within a group of coincident
1999  *              tuples have id strictly lower than \a limitTupleId then they are not excluded.
2000  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
2001  *          is to delete using decrRef() as it is no more needed.
2002  *  \throw If \a this is not allocated.
2003  *  \throw If the number of components is not in [1,2,3].
2004  *
2005  *  \ref py_mcdataarraydouble_getdifferentvalues "Here is a Python example".
2006  */
2007 DataArrayDouble *DataArrayDouble::getDifferentValues(double prec, int limitTupleId) const throw(INTERP_KERNEL::Exception)
2008 {
2009   checkAllocated();
2010   DataArrayInt *c0=0,*cI0=0;
2011   findCommonTuples(prec,limitTupleId,c0,cI0);
2012   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> c(c0),cI(cI0);
2013   int newNbOfTuples=-1;
2014   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> o2n=DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2(getNumberOfTuples(),c0->begin(),cI0->begin(),cI0->end(),newNbOfTuples);
2015   return renumberAndReduce(o2n->getConstPointer(),newNbOfTuples);
2016 }
2017
2018 /*!
2019  * Copy all components in a specified order from another DataArrayDouble.
2020  * Both numerical and textual data is copied. The number of tuples in \a this and
2021  * the other array can be different.
2022  *  \param [in] a - the array to copy data from.
2023  *  \param [in] compoIds - sequence of zero based indices of components, data of which is
2024  *              to be copied.
2025  *  \throw If \a a is NULL.
2026  *  \throw If \a compoIds.size() != \a a->getNumberOfComponents().
2027  *  \throw If \a compoIds[i] < 0 or \a compoIds[i] > \a this->getNumberOfComponents().
2028  *
2029  *  \ref py_mcdataarraydouble_setselectedcomponents "Here is a Python example".
2030  */
2031 void DataArrayDouble::setSelectedComponents(const DataArrayDouble *a, const std::vector<int>& compoIds) throw(INTERP_KERNEL::Exception)
2032 {
2033   if(!a)
2034     throw INTERP_KERNEL::Exception("DataArrayDouble::setSelectedComponents : input DataArrayDouble is NULL !");
2035   checkAllocated();
2036   copyPartOfStringInfoFrom2(compoIds,*a);
2037   std::size_t partOfCompoSz=compoIds.size();
2038   int nbOfCompo=getNumberOfComponents();
2039   int nbOfTuples=std::min(getNumberOfTuples(),a->getNumberOfTuples());
2040   const double *ac=a->getConstPointer();
2041   double *nc=getPointer();
2042   for(int i=0;i<nbOfTuples;i++)
2043     for(std::size_t j=0;j<partOfCompoSz;j++,ac++)
2044       nc[nbOfCompo*i+compoIds[j]]=*ac;
2045 }
2046
2047 /*!
2048  * Copy all values from another DataArrayDouble into specified tuples and components
2049  * of \a this array. Textual data is not copied.
2050  * The tree parameters defining set of indices of tuples and components are similar to
2051  * the tree parameters of the Python function \c range(\c start,\c stop,\c step).
2052  *  \param [in] a - the array to copy values from.
2053  *  \param [in] bgTuples - index of the first tuple of \a this array to assign values to.
2054  *  \param [in] endTuples - index of the tuple before which the tuples to assign to
2055  *              are located.
2056  *  \param [in] stepTuples - index increment to get index of the next tuple to assign to.
2057  *  \param [in] bgComp - index of the first component of \a this array to assign values to.
2058  *  \param [in] endComp - index of the component before which the components to assign
2059  *              to are located.
2060  *  \param [in] stepComp - index increment to get index of the next component to assign to.
2061  *  \param [in] strictCompoCompare - if \a true (by default), then \a a->getNumberOfComponents() 
2062  *              must be equal to the number of columns to assign to, else an
2063  *              exception is thrown; if \a false, then it is only required that \a
2064  *              a->getNbOfElems() equals to number of values to assign to (this condition
2065  *              must be respected even if \a strictCompoCompare is \a true). The number of 
2066  *              values to assign to is given by following Python expression:
2067  *              \a nbTargetValues = 
2068  *              \c len(\c range(\a bgTuples,\a endTuples,\a stepTuples)) *
2069  *              \c len(\c range(\a bgComp,\a endComp,\a stepComp)).
2070  *  \throw If \a a is NULL.
2071  *  \throw If \a a is not allocated.
2072  *  \throw If \a this is not allocated.
2073  *  \throw If parameters specifying tuples and components to assign to do not give a
2074  *            non-empty range of increasing indices.
2075  *  \throw If \a a->getNbOfElems() != \a nbTargetValues.
2076  *  \throw If \a strictCompoCompare == \a true && \a a->getNumberOfComponents() !=
2077  *            \c len(\c range(\a bgComp,\a endComp,\a stepComp)).
2078  *
2079  *  \ref py_mcdataarraydouble_setpartofvalues1 "Here is a Python example".
2080  */
2081 void DataArrayDouble::setPartOfValues1(const DataArrayDouble *a, int bgTuples, int endTuples, int stepTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare) throw(INTERP_KERNEL::Exception)
2082 {
2083   if(!a)
2084     throw INTERP_KERNEL::Exception("DataArrayDouble::setPartOfValues1 : input DataArrayDouble is NULL !");
2085   const char msg[]="DataArrayDouble::setPartOfValues1";
2086   checkAllocated();
2087   a->checkAllocated();
2088   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
2089   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
2090   int nbComp=getNumberOfComponents();
2091   int nbOfTuples=getNumberOfTuples();
2092   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
2093   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
2094   bool assignTech=true;
2095   if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
2096     {
2097       if(strictCompoCompare)
2098         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
2099     }
2100   else
2101     {
2102       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
2103       assignTech=false;
2104     }
2105   const double *srcPt=a->getConstPointer();
2106   double *pt=getPointer()+bgTuples*nbComp+bgComp;
2107   if(assignTech)
2108     {
2109       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
2110         for(int j=0;j<newNbOfComp;j++,srcPt++)
2111           pt[j*stepComp]=*srcPt;
2112     }
2113   else
2114     {
2115       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
2116         {
2117           const double *srcPt2=srcPt;
2118           for(int j=0;j<newNbOfComp;j++,srcPt2++)
2119             pt[j*stepComp]=*srcPt2;
2120         }
2121     }
2122 }
2123
2124 /*!
2125  * Assign a given value to values at specified tuples and components of \a this array.
2126  * The tree parameters defining set of indices of tuples and components are similar to
2127  * the tree parameters of the Python function \c range(\c start,\c stop,\c step)..
2128  *  \param [in] a - the value to assign.
2129  *  \param [in] bgTuples - index of the first tuple of \a this array to assign to.
2130  *  \param [in] endTuples - index of the tuple before which the tuples to assign to
2131  *              are located.
2132  *  \param [in] stepTuples - index increment to get index of the next tuple to assign to.
2133  *  \param [in] bgComp - index of the first component of \a this array to assign to.
2134  *  \param [in] endComp - index of the component before which the components to assign
2135  *              to are located.
2136  *  \param [in] stepComp - index increment to get index of the next component to assign to.
2137  *  \throw If \a this is not allocated.
2138  *  \throw If parameters specifying tuples and components to assign to, do not give a
2139  *            non-empty range of increasing indices or indices are out of a valid range
2140  *            for \this array.
2141  *
2142  *  \ref py_mcdataarraydouble_setpartofvaluessimple1 "Here is a Python example".
2143  */
2144 void DataArrayDouble::setPartOfValuesSimple1(double a, int bgTuples, int endTuples, int stepTuples, int bgComp, int endComp, int stepComp) throw(INTERP_KERNEL::Exception)
2145 {
2146   const char msg[]="DataArrayDouble::setPartOfValuesSimple1";
2147   checkAllocated();
2148   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
2149   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
2150   int nbComp=getNumberOfComponents();
2151   int nbOfTuples=getNumberOfTuples();
2152   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
2153   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
2154   double *pt=getPointer()+bgTuples*nbComp+bgComp;
2155   for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
2156     for(int j=0;j<newNbOfComp;j++)
2157       pt[j*stepComp]=a;
2158 }
2159
2160 /*!
2161  * Copy all values from another DataArrayDouble (\a a) into specified tuples and 
2162  * components of \a this array. Textual data is not copied.
2163  * The tuples and components to assign to are defined by C arrays of indices.
2164  * There are two *modes of usage*:
2165  * - If \a a->getNbOfElems() equals to number of values to assign to, then every value
2166  *   of \a a is assigned to its own location within \a this array. 
2167  * - If \a a includes one tuple, then all values of \a a are assigned to the specified
2168  *   components of every specified tuple of \a this array. In this mode it is required
2169  *   that \a a->getNumberOfComponents() equals to the number of specified components.
2170  *
2171  *  \param [in] a - the array to copy values from.
2172  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
2173  *              assign values of \a a to.
2174  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
2175  *              pointer to a tuple index <em>(pi)</em> varies as this: 
2176  *              \a bgTuples <= \a pi < \a endTuples.
2177  *  \param [in] bgComp - pointer to an array of component indices of \a this array to
2178  *              assign values of \a a to.
2179  *  \param [in] endComp - specifies the end of the array \a bgTuples, so that
2180  *              pointer to a component index <em>(pi)</em> varies as this: 
2181  *              \a bgComp <= \a pi < \a endComp.
2182  *  \param [in] strictCompoCompare - this parameter is checked only if the
2183  *               *mode of usage* is the first; if it is \a true (default), 
2184  *               then \a a->getNumberOfComponents() must be equal 
2185  *               to the number of specified columns, else this is not required.
2186  *  \throw If \a a is NULL.
2187  *  \throw If \a a is not allocated.
2188  *  \throw If \a this is not allocated.
2189  *  \throw If any index of tuple/component given by <em>bgTuples / bgComp</em> is
2190  *         out of a valid range for \a this array.
2191  *  \throw In the first *mode of usage*, if <em>strictCompoCompare == true </em> and
2192  *         if <em> a->getNumberOfComponents() != (endComp - bgComp) </em>.
2193  *  \throw In the second *mode of usage*, if \a a->getNumberOfTuples() != 1 or
2194  *         <em> a->getNumberOfComponents() != (endComp - bgComp)</em>.
2195  *
2196  *  \ref py_mcdataarraydouble_setpartofvalues2 "Here is a Python example".
2197  */
2198 void DataArrayDouble::setPartOfValues2(const DataArrayDouble *a, const int *bgTuples, const int *endTuples, const int *bgComp, const int *endComp, bool strictCompoCompare) throw(INTERP_KERNEL::Exception)
2199 {
2200   if(!a)
2201     throw INTERP_KERNEL::Exception("DataArrayDouble::setPartOfValues2 : input DataArrayDouble is NULL !");
2202   const char msg[]="DataArrayDouble::setPartOfValues2";
2203   checkAllocated();
2204   a->checkAllocated();
2205   int nbComp=getNumberOfComponents();
2206   int nbOfTuples=getNumberOfTuples();
2207   for(const int *z=bgComp;z!=endComp;z++)
2208     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
2209   int newNbOfTuples=(int)std::distance(bgTuples,endTuples);
2210   int newNbOfComp=(int)std::distance(bgComp,endComp);
2211   bool assignTech=true;
2212   if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
2213     {
2214       if(strictCompoCompare)
2215         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
2216     }
2217   else
2218     {
2219       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
2220       assignTech=false;
2221     }
2222   double *pt=getPointer();
2223   const double *srcPt=a->getConstPointer();
2224   if(assignTech)
2225     {    
2226       for(const int *w=bgTuples;w!=endTuples;w++)
2227         {
2228           DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
2229           for(const int *z=bgComp;z!=endComp;z++,srcPt++)
2230             {    
2231               pt[(std::size_t)(*w)*nbComp+(*z)]=*srcPt;
2232             }
2233         }
2234     }
2235   else
2236     {
2237       for(const int *w=bgTuples;w!=endTuples;w++)
2238         {
2239           const double *srcPt2=srcPt;
2240           DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
2241           for(const int *z=bgComp;z!=endComp;z++,srcPt2++)
2242             {    
2243               pt[(std::size_t)(*w)*nbComp+(*z)]=*srcPt2;
2244             }
2245         }
2246     }
2247 }
2248
2249 /*!
2250  * Assign a given value to values at specified tuples and components of \a this array.
2251  * The tuples and components to assign to are defined by C arrays of indices.
2252  *  \param [in] a - the value to assign.
2253  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
2254  *              assign \a a to.
2255  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
2256  *              pointer to a tuple index (\a pi) varies as this: 
2257  *              \a bgTuples <= \a pi < \a endTuples.
2258  *  \param [in] bgComp - pointer to an array of component indices of \a this array to
2259  *              assign \a a to.
2260  *  \param [in] endComp - specifies the end of the array \a bgTuples, so that
2261  *              pointer to a component index (\a pi) varies as this: 
2262  *              \a bgComp <= \a pi < \a endComp.
2263  *  \throw If \a this is not allocated.
2264  *  \throw If any index of tuple/component given by <em>bgTuples / bgComp</em> is
2265  *         out of a valid range for \a this array.
2266  *
2267  *  \ref py_mcdataarraydouble_setpartofvaluessimple2 "Here is a Python example".
2268  */
2269 void DataArrayDouble::setPartOfValuesSimple2(double a, const int *bgTuples, const int *endTuples, const int *bgComp, const int *endComp) throw(INTERP_KERNEL::Exception)
2270 {
2271   checkAllocated();
2272   int nbComp=getNumberOfComponents();
2273   int nbOfTuples=getNumberOfTuples();
2274   for(const int *z=bgComp;z!=endComp;z++)
2275     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
2276   double *pt=getPointer();
2277   for(const int *w=bgTuples;w!=endTuples;w++)
2278     for(const int *z=bgComp;z!=endComp;z++)
2279       {
2280         DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
2281         pt[(std::size_t)(*w)*nbComp+(*z)]=a;
2282       }
2283 }
2284
2285 /*!
2286  * Copy all values from another DataArrayDouble (\a a) into specified tuples and 
2287  * components of \a this array. Textual data is not copied.
2288  * The tuples to assign to are defined by a C array of indices.
2289  * The components to assign to are defined by three values similar to parameters of
2290  * the Python function \c range(\c start,\c stop,\c step).
2291  * There are two *modes of usage*:
2292  * - If \a a->getNbOfElems() equals to number of values to assign to, then every value
2293  *   of \a a is assigned to its own location within \a this array. 
2294  * - If \a a includes one tuple, then all values of \a a are assigned to the specified
2295  *   components of every specified tuple of \a this array. In this mode it is required
2296  *   that \a a->getNumberOfComponents() equals to the number of specified components.
2297  *
2298  *  \param [in] a - the array to copy values from.
2299  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
2300  *              assign values of \a a to.
2301  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
2302  *              pointer to a tuple index <em>(pi)</em> varies as this: 
2303  *              \a bgTuples <= \a pi < \a endTuples.
2304  *  \param [in] bgComp - index of the first component of \a this array to assign to.
2305  *  \param [in] endComp - index of the component before which the components to assign
2306  *              to are located.
2307  *  \param [in] stepComp - index increment to get index of the next component to assign to.
2308  *  \param [in] strictCompoCompare - this parameter is checked only in the first
2309  *               *mode of usage*; if \a strictCompoCompare is \a true (default), 
2310  *               then \a a->getNumberOfComponents() must be equal 
2311  *               to the number of specified columns, else this is not required.
2312  *  \throw If \a a is NULL.
2313  *  \throw If \a a is not allocated.
2314  *  \throw If \a this is not allocated.
2315  *  \throw If any index of tuple given by \a bgTuples is out of a valid range for 
2316  *         \a this array.
2317  *  \throw In the first *mode of usage*, if <em>strictCompoCompare == true </em> and
2318  *         if <em> a->getNumberOfComponents()</em> is unequal to the number of components
2319  *         defined by <em>(bgComp,endComp,stepComp)</em>.
2320  *  \throw In the second *mode of usage*, if \a a->getNumberOfTuples() != 1 or
2321  *         <em> a->getNumberOfComponents()</em> is unequal to the number of components
2322  *         defined by <em>(bgComp,endComp,stepComp)</em>.
2323  *  \throw If parameters specifying components to assign to, do not give a
2324  *            non-empty range of increasing indices or indices are out of a valid range
2325  *            for \this array.
2326  *
2327  *  \ref py_mcdataarraydouble_setpartofvalues3 "Here is a Python example".
2328  */
2329 void DataArrayDouble::setPartOfValues3(const DataArrayDouble *a, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare) throw(INTERP_KERNEL::Exception)
2330 {
2331   if(!a)
2332     throw INTERP_KERNEL::Exception("DataArrayDouble::setPartOfValues3 : input DataArrayDouble is NULL !");
2333   const char msg[]="DataArrayDouble::setPartOfValues3";
2334   checkAllocated();
2335   a->checkAllocated();
2336   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
2337   int nbComp=getNumberOfComponents();
2338   int nbOfTuples=getNumberOfTuples();
2339   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
2340   int newNbOfTuples=(int)std::distance(bgTuples,endTuples);
2341   bool assignTech=true;
2342   if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
2343     {
2344       if(strictCompoCompare)
2345         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
2346     }
2347   else
2348     {
2349       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
2350       assignTech=false;
2351     }
2352   double *pt=getPointer()+bgComp;
2353   const double *srcPt=a->getConstPointer();
2354   if(assignTech)
2355     {
2356       for(const int *w=bgTuples;w!=endTuples;w++)
2357         for(int j=0;j<newNbOfComp;j++,srcPt++)
2358           {
2359             DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
2360             pt[(std::size_t)(*w)*nbComp+j*stepComp]=*srcPt;
2361           }
2362     }
2363   else
2364     {
2365       for(const int *w=bgTuples;w!=endTuples;w++)
2366         {
2367           const double *srcPt2=srcPt;
2368           for(int j=0;j<newNbOfComp;j++,srcPt2++)
2369             {
2370               DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
2371               pt[(std::size_t)(*w)*nbComp+j*stepComp]=*srcPt2;
2372             }
2373         }
2374     }
2375 }
2376
2377 /*!
2378  * Assign a given value to values at specified tuples and components of \a this array.
2379  * The tuples to assign to are defined by a C array of indices.
2380  * The components to assign to are defined by three values similar to parameters of
2381  * the Python function \c range(\c start,\c stop,\c step).
2382  *  \param [in] a - the value to assign.
2383  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
2384  *              assign \a a to.
2385  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
2386  *              pointer to a tuple index <em>(pi)</em> varies as this: 
2387  *              \a bgTuples <= \a pi < \a endTuples.
2388  *  \param [in] bgComp - index of the first component of \a this array to assign to.
2389  *  \param [in] endComp - index of the component before which the components to assign
2390  *              to are located.
2391  *  \param [in] stepComp - index increment to get index of the next component to assign to.
2392  *  \throw If \a this is not allocated.
2393  *  \throw If any index of tuple given by \a bgTuples is out of a valid range for 
2394  *         \a this array.
2395  *  \throw If parameters specifying components to assign to, do not give a
2396  *            non-empty range of increasing indices or indices are out of a valid range
2397  *            for \this array.
2398  *
2399  *  \ref py_mcdataarraydouble_setpartofvaluessimple3 "Here is a Python example".
2400  */
2401 void DataArrayDouble::setPartOfValuesSimple3(double a, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp) throw(INTERP_KERNEL::Exception)
2402 {
2403   const char msg[]="DataArrayDouble::setPartOfValuesSimple3";
2404   checkAllocated();
2405   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
2406   int nbComp=getNumberOfComponents();
2407   int nbOfTuples=getNumberOfTuples();
2408   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
2409   double *pt=getPointer()+bgComp;
2410   for(const int *w=bgTuples;w!=endTuples;w++)
2411     for(int j=0;j<newNbOfComp;j++)
2412       {
2413         DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
2414         pt[(std::size_t)(*w)*nbComp+j*stepComp]=a;
2415       }
2416 }
2417
2418 /*!
2419  * Copy all values from another DataArrayDouble into specified tuples and components
2420  * of \a this array. Textual data is not copied.
2421  * The tree parameters defining set of indices of tuples and components are similar to
2422  * the tree parameters of the Python function \c range(\c start,\c stop,\c step).
2423  *  \param [in] a - the array to copy values from.
2424  *  \param [in] bgTuples - index of the first tuple of \a this array to assign values to.
2425  *  \param [in] endTuples - index of the tuple before which the tuples to assign to
2426  *              are located.
2427  *  \param [in] stepTuples - index increment to get index of the next tuple to assign to.
2428  *  \param [in] bgComp - pointer to an array of component indices of \a this array to
2429  *              assign \a a to.
2430  *  \param [in] endComp - specifies the end of the array \a bgTuples, so that
2431  *              pointer to a component index (\a pi) varies as this: 
2432  *              \a bgComp <= \a pi < \a endComp.
2433  *  \param [in] strictCompoCompare - if \a true (by default), then \a a->getNumberOfComponents() 
2434  *              must be equal to the number of columns to assign to, else an
2435  *              exception is thrown; if \a false, then it is only required that \a
2436  *              a->getNbOfElems() equals to number of values to assign to (this condition
2437  *              must be respected even if \a strictCompoCompare is \a true). The number of 
2438  *              values to assign to is given by following Python expression:
2439  *              \a nbTargetValues = 
2440  *              \c len(\c range(\a bgTuples,\a endTuples,\a stepTuples)) *
2441  *              \c len(\c range(\a bgComp,\a endComp,\a stepComp)).
2442  *  \throw If \a a is NULL.
2443  *  \throw If \a a is not allocated.
2444  *  \throw If \a this is not allocated.
2445  *  \throw If parameters specifying tuples and components to assign to do not give a
2446  *            non-empty range of increasing indices.
2447  *  \throw If \a a->getNbOfElems() != \a nbTargetValues.
2448  *  \throw If \a strictCompoCompare == \a true && \a a->getNumberOfComponents() !=
2449  *            \c len(\c range(\a bgComp,\a endComp,\a stepComp)).
2450  *
2451  */
2452 void DataArrayDouble::setPartOfValues4(const DataArrayDouble *a, int bgTuples, int endTuples, int stepTuples, const int *bgComp, const int *endComp, bool strictCompoCompare) throw(INTERP_KERNEL::Exception)
2453 {
2454   if(!a)
2455     throw INTERP_KERNEL::Exception("DataArrayDouble::setPartOfValues4 : input DataArrayDouble is NULL !");
2456   const char msg[]="DataArrayDouble::setPartOfValues4";
2457   checkAllocated();
2458   a->checkAllocated();
2459   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
2460   int newNbOfComp=(int)std::distance(bgComp,endComp);
2461   int nbComp=getNumberOfComponents();
2462   for(const int *z=bgComp;z!=endComp;z++)
2463     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
2464   int nbOfTuples=getNumberOfTuples();
2465   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
2466   bool assignTech=true;
2467   if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
2468     {
2469       if(strictCompoCompare)
2470         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
2471     }
2472   else
2473     {
2474       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
2475       assignTech=false;
2476     }
2477   const double *srcPt=a->getConstPointer();
2478   double *pt=getPointer()+bgTuples*nbComp;
2479   if(assignTech)
2480     {
2481       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
2482         for(const int *z=bgComp;z!=endComp;z++,srcPt++)
2483           pt[*z]=*srcPt;
2484     }
2485   else
2486     {
2487       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
2488         {
2489           const double *srcPt2=srcPt;
2490           for(const int *z=bgComp;z!=endComp;z++,srcPt2++)
2491             pt[*z]=*srcPt2;
2492         }
2493     }
2494 }
2495
2496 void DataArrayDouble::setPartOfValuesSimple4(double a, int bgTuples, int endTuples, int stepTuples, const int *bgComp, const int *endComp) throw(INTERP_KERNEL::Exception)
2497 {
2498   const char msg[]="DataArrayDouble::setPartOfValuesSimple4";
2499   checkAllocated();
2500   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
2501   int nbComp=getNumberOfComponents();
2502   for(const int *z=bgComp;z!=endComp;z++)
2503     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
2504   int nbOfTuples=getNumberOfTuples();
2505   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
2506   double *pt=getPointer()+bgTuples*nbComp;
2507   for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
2508     for(const int *z=bgComp;z!=endComp;z++)
2509       pt[*z]=a;
2510 }
2511
2512 /*!
2513  * Copy some tuples from another DataArrayDouble into specified tuples
2514  * of \a this array. Textual data is not copied. Both arrays must have equal number of
2515  * components.
2516  * Both the tuples to assign and the tuples to assign to are defined by a DataArrayInt.
2517  * All components of selected tuples are copied.
2518  *  \param [in] a - the array to copy values from.
2519  *  \param [in] tuplesSelec - the array specifying both source tuples of \a a and
2520  *              target tuples of \a this. \a tuplesSelec has two components, and the
2521  *              first component specifies index of the source tuple and the second
2522  *              one specifies index of the target tuple.
2523  *  \throw If \a this is not allocated.
2524  *  \throw If \a a is NULL.
2525  *  \throw If \a a is not allocated.
2526  *  \throw If \a tuplesSelec is NULL.
2527  *  \throw If \a tuplesSelec is not allocated.
2528  *  \throw If <em>this->getNumberOfComponents() != a->getNumberOfComponents()</em>.
2529  *  \throw If \a tuplesSelec->getNumberOfComponents() != 2.
2530  *  \throw If any tuple index given by \a tuplesSelec is out of a valid range for 
2531  *         the corresponding (\a this or \a a) array.
2532  */
2533 void DataArrayDouble::setPartOfValuesAdv(const DataArrayDouble *a, const DataArrayInt *tuplesSelec) throw(INTERP_KERNEL::Exception)
2534 {
2535   if(!a || !tuplesSelec)
2536     throw INTERP_KERNEL::Exception("DataArrayDouble::setPartOfValuesAdv : input DataArrayDouble is NULL !");
2537   checkAllocated();
2538   a->checkAllocated();
2539   tuplesSelec->checkAllocated();
2540   int nbOfComp=getNumberOfComponents();
2541   if(nbOfComp!=a->getNumberOfComponents())
2542     throw INTERP_KERNEL::Exception("DataArrayDouble::setPartOfValuesAdv : This and a do not have the same number of components !");
2543   if(tuplesSelec->getNumberOfComponents()!=2)
2544     throw INTERP_KERNEL::Exception("DataArrayDouble::setPartOfValuesAdv : Expecting to have a tuple selector DataArrayInt instance with exactly 2 components !");
2545   int thisNt=getNumberOfTuples();
2546   int aNt=a->getNumberOfTuples();
2547   double *valsToSet=getPointer();
2548   const double *valsSrc=a->getConstPointer();
2549   for(const int *tuple=tuplesSelec->begin();tuple!=tuplesSelec->end();tuple+=2)
2550     {
2551       if(tuple[1]>=0 && tuple[1]<aNt)
2552         {
2553           if(tuple[0]>=0 && tuple[0]<thisNt)
2554             std::copy(valsSrc+nbOfComp*tuple[1],valsSrc+nbOfComp*(tuple[1]+1),valsToSet+nbOfComp*tuple[0]);
2555           else
2556             {
2557               std::ostringstream oss; oss << "DataArrayDouble::setPartOfValuesAdv : Tuple #" << std::distance(tuplesSelec->begin(),tuple)/2;
2558               oss << " of 'tuplesSelec' request of tuple id #" << tuple[0] << " in 'this' ! It should be in [0," << thisNt << ") !";
2559               throw INTERP_KERNEL::Exception(oss.str().c_str());
2560             }
2561         }
2562       else
2563         {
2564           std::ostringstream oss; oss << "DataArrayDouble::setPartOfValuesAdv : Tuple #" << std::distance(tuplesSelec->begin(),tuple)/2;
2565           oss << " of 'tuplesSelec' request of tuple id #" << tuple[1] << " in 'a' ! It should be in [0," << aNt << ") !";
2566           throw INTERP_KERNEL::Exception(oss.str().c_str());
2567         }
2568     }
2569 }
2570
2571 /*!
2572  * Copy some tuples from another DataArrayDouble (\a a) into contiguous tuples
2573  * of \a this array. Textual data is not copied. Both arrays must have equal number of
2574  * components.
2575  * The tuples to assign to are defined by index of the first tuple, and
2576  * their number is defined by \a tuplesSelec->getNumberOfTuples().
2577  * The tuples to copy are defined by values of a DataArrayInt.
2578  * All components of selected tuples are copied.
2579  *  \param [in] tupleIdStart - index of the first tuple of \a this array to assign
2580  *              values to.
2581  *  \param [in] a - the array to copy values from.
2582  *  \param [in] tuplesSelec - the array specifying tuples of \a a to copy.
2583  *  \throw If \a this is not allocated.
2584  *  \throw If \a a is NULL.
2585  *  \throw If \a a is not allocated.
2586  *  \throw If \a tuplesSelec is NULL.
2587  *  \throw If \a tuplesSelec is not allocated.
2588  *  \throw If <em>this->getNumberOfComponents() != a->getNumberOfComponents()</em>.
2589  *  \throw If \a tuplesSelec->getNumberOfComponents() != 1.
2590  *  \throw If <em>tupleIdStart + tuplesSelec->getNumberOfTuples() > this->getNumberOfTuples().</em>
2591  *  \throw If any tuple index given by \a tuplesSelec is out of a valid range for 
2592  *         \a a array.
2593  */
2594 void DataArrayDouble::setContigPartOfSelectedValues(int tupleIdStart, const DataArray *aBase, const DataArrayInt *tuplesSelec) throw(INTERP_KERNEL::Exception)
2595 {
2596   if(!aBase || !tuplesSelec)
2597     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues : input DataArray is NULL !");
2598   const DataArrayDouble *a=dynamic_cast<const DataArrayDouble *>(aBase);
2599   if(!a)
2600     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues : input DataArray aBase is not a DataArrayDouble !");
2601   checkAllocated();
2602   a->checkAllocated();
2603   tuplesSelec->checkAllocated();
2604   int nbOfComp=getNumberOfComponents();
2605   if(nbOfComp!=a->getNumberOfComponents())
2606     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues : This and a do not have the same number of components !");
2607   if(tuplesSelec->getNumberOfComponents()!=1)
2608     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues : Expecting to have a tuple selector DataArrayInt instance with exactly 1 component !");
2609   int thisNt=getNumberOfTuples();
2610   int aNt=a->getNumberOfTuples();
2611   int nbOfTupleToWrite=tuplesSelec->getNumberOfTuples();
2612   double *valsToSet=getPointer()+tupleIdStart*nbOfComp;
2613   if(tupleIdStart+nbOfTupleToWrite>thisNt)
2614     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues : invalid number range of values to write !");
2615   const double *valsSrc=a->getConstPointer();
2616   for(const int *tuple=tuplesSelec->begin();tuple!=tuplesSelec->end();tuple++,valsToSet+=nbOfComp)
2617     {
2618       if(*tuple>=0 && *tuple<aNt)
2619         {
2620           std::copy(valsSrc+nbOfComp*(*tuple),valsSrc+nbOfComp*(*tuple+1),valsToSet);
2621         }
2622       else
2623         {
2624           std::ostringstream oss; oss << "DataArrayDouble::setContigPartOfSelectedValues : Tuple #" << std::distance(tuplesSelec->begin(),tuple);
2625           oss << " of 'tuplesSelec' request of tuple id #" << *tuple << " in 'a' ! It should be in [0," << aNt << ") !";
2626           throw INTERP_KERNEL::Exception(oss.str().c_str());
2627         }
2628     }
2629 }
2630
2631 /*!
2632  * Copy some tuples from another DataArrayDouble (\a a) into contiguous tuples
2633  * of \a this array. Textual data is not copied. Both arrays must have equal number of
2634  * components.
2635  * The tuples to copy are defined by three values similar to parameters of
2636  * the Python function \c range(\c start,\c stop,\c step).
2637  * The tuples to assign to are defined by index of the first tuple, and
2638  * their number is defined by number of tuples to copy.
2639  * All components of selected tuples are copied.
2640  *  \param [in] tupleIdStart - index of the first tuple of \a this array to assign
2641  *              values to.
2642  *  \param [in] a - the array to copy values from.
2643  *  \param [in] bg - index of the first tuple to copy of the array \a a.
2644  *  \param [in] end2 - index of the tuple of \a a before which the tuples to copy
2645  *              are located.
2646  *  \param [in] step - index increment to get index of the next tuple to copy.
2647  *  \throw If \a this is not allocated.
2648  *  \throw If \a a is NULL.
2649  *  \throw If \a a is not allocated.
2650  *  \throw If <em>this->getNumberOfComponents() != a->getNumberOfComponents()</em>.
2651  *  \throw If <em>tupleIdStart + len(range(bg,end2,step)) > this->getNumberOfTuples().</em>
2652  *  \throw If parameters specifying tuples to copy, do not give a
2653  *            non-empty range of increasing indices or indices are out of a valid range
2654  *            for the array \a a.
2655  */
2656 void DataArrayDouble::setContigPartOfSelectedValues2(int tupleIdStart, const DataArray *aBase, int bg, int end2, int step) throw(INTERP_KERNEL::Exception)
2657 {
2658   if(!aBase)
2659     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues2 : input DataArray is NULL !");
2660   const DataArrayDouble *a=dynamic_cast<const DataArrayDouble *>(aBase);
2661   if(!a)
2662     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues2 : input DataArray aBase is not a DataArrayDouble !");
2663   checkAllocated();
2664   a->checkAllocated();
2665   int nbOfComp=getNumberOfComponents();
2666   const char msg[]="DataArrayDouble::setContigPartOfSelectedValues2";
2667   int nbOfTupleToWrite=DataArray::GetNumberOfItemGivenBES(bg,end2,step,msg);
2668   if(nbOfComp!=a->getNumberOfComponents())
2669     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues2 : This and a do not have the same number of components !");
2670   int thisNt=getNumberOfTuples();
2671   int aNt=a->getNumberOfTuples();
2672   double *valsToSet=getPointer()+tupleIdStart*nbOfComp;
2673   if(tupleIdStart+nbOfTupleToWrite>thisNt)
2674     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues2 : invalid number range of values to write !");
2675   if(end2>aNt)
2676     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues2 : invalid range of values to read !");
2677   const double *valsSrc=a->getConstPointer()+bg*nbOfComp;
2678   for(int i=0;i<nbOfTupleToWrite;i++,valsToSet+=nbOfComp,valsSrc+=step*nbOfComp)
2679     {
2680       std::copy(valsSrc,valsSrc+nbOfComp,valsToSet);
2681     }
2682 }
2683
2684 /*!
2685  * Returns a value located at specified tuple and component.
2686  * This method is equivalent to DataArrayDouble::getIJ() except that validity of
2687  * parameters is checked. So this method is safe but expensive if used to go through
2688  * all values of \a this.
2689  *  \param [in] tupleId - index of tuple of interest.
2690  *  \param [in] compoId - index of component of interest.
2691  *  \return double - value located by \a tupleId and \a compoId.
2692  *  \throw If \a this is not allocated.
2693  *  \throw If condition <em>( 0 <= tupleId < this->getNumberOfTuples() )</em> is violated.
2694  *  \throw If condition <em>( 0 <= compoId < this->getNumberOfComponents() )</em> is violated.
2695  */
2696 double DataArrayDouble::getIJSafe(int tupleId, int compoId) const throw(INTERP_KERNEL::Exception)
2697 {
2698   checkAllocated();
2699   if(tupleId<0 || tupleId>=getNumberOfTuples())
2700     {
2701       std::ostringstream oss; oss << "DataArrayDouble::getIJSafe : request for tupleId " << tupleId << " should be in [0," << getNumberOfTuples() << ") !";
2702       throw INTERP_KERNEL::Exception(oss.str().c_str());
2703     }
2704   if(compoId<0 || compoId>=getNumberOfComponents())
2705     {
2706       std::ostringstream oss; oss << "DataArrayDouble::getIJSafe : request for compoId " << compoId << " should be in [0," << getNumberOfComponents() << ") !";
2707       throw INTERP_KERNEL::Exception(oss.str().c_str());
2708     }
2709   return _mem[tupleId*_info_on_compo.size()+compoId];
2710 }
2711
2712 /*!
2713  * Returns the first value of \a this. 
2714  *  \return double - the last value of \a this array.
2715  *  \throw If \a this is not allocated.
2716  *  \throw If \a this->getNumberOfComponents() != 1.
2717  *  \throw If \a this->getNumberOfTuples() < 1.
2718  */
2719 double DataArrayDouble::front() const throw(INTERP_KERNEL::Exception)
2720 {
2721   checkAllocated();
2722   if(getNumberOfComponents()!=1)
2723     throw INTERP_KERNEL::Exception("DataArrayDouble::front : number of components not equal to one !");
2724   int nbOfTuples=getNumberOfTuples();
2725   if(nbOfTuples<1)
2726     throw INTERP_KERNEL::Exception("DataArrayDouble::front : number of tuples must be >= 1 !");
2727   return *(getConstPointer());
2728 }
2729
2730 /*!
2731  * Returns the last value of \a this. 
2732  *  \return double - the last value of \a this array.
2733  *  \throw If \a this is not allocated.
2734  *  \throw If \a this->getNumberOfComponents() != 1.
2735  *  \throw If \a this->getNumberOfTuples() < 1.
2736  */
2737 double DataArrayDouble::back() const throw(INTERP_KERNEL::Exception)
2738 {
2739   checkAllocated();
2740   if(getNumberOfComponents()!=1)
2741     throw INTERP_KERNEL::Exception("DataArrayDouble::back : number of components not equal to one !");
2742   int nbOfTuples=getNumberOfTuples();
2743   if(nbOfTuples<1)
2744     throw INTERP_KERNEL::Exception("DataArrayDouble::back : number of tuples must be >= 1 !");
2745   return *(getConstPointer()+nbOfTuples-1);
2746 }
2747
2748 void DataArrayDouble::SetArrayIn(DataArrayDouble *newArray, DataArrayDouble* &arrayToSet)
2749 {
2750   if(newArray!=arrayToSet)
2751     {
2752       if(arrayToSet)
2753         arrayToSet->decrRef();
2754       arrayToSet=newArray;
2755       if(arrayToSet)
2756         arrayToSet->incrRef();
2757     }
2758 }
2759
2760 /*!
2761  * Sets a C array to be used as raw data of \a this. The previously set info
2762  *  of components is retained and re-sized. 
2763  * For more info see \ref MEDCouplingArraySteps1.
2764  *  \param [in] array - the C array to be used as raw data of \a this.
2765  *  \param [in] ownership - if \a true, \a array will be deallocated at destruction of \a this.
2766  *  \param [in] type - specifies how to deallocate \a array. If \a type == ParaMEDMEM::CPP_DEALLOC,
2767  *                     \c delete [] \c array; will be called. If \a type == ParaMEDMEM::C_DEALLOC,
2768  *                     \c free(\c array ) will be called.
2769  *  \param [in] nbOfTuple - new number of tuples in \a this.
2770  *  \param [in] nbOfCompo - new number of components in \a this.
2771  */
2772 void DataArrayDouble::useArray(const double *array, bool ownership, DeallocType type, int nbOfTuple, int nbOfCompo) throw(INTERP_KERNEL::Exception)
2773 {
2774   _info_on_compo.resize(nbOfCompo);
2775   _mem.useArray(array,ownership,type,(std::size_t)nbOfTuple*nbOfCompo);
2776   declareAsNew();
2777 }
2778
2779 void DataArrayDouble::useExternalArrayWithRWAccess(const double *array, int nbOfTuple, int nbOfCompo) throw(INTERP_KERNEL::Exception)
2780 {
2781   _info_on_compo.resize(nbOfCompo);
2782   _mem.useExternalArrayWithRWAccess(array,(std::size_t)nbOfTuple*nbOfCompo);
2783   declareAsNew();
2784 }
2785
2786 /*!
2787  * Checks if 0.0 value is present in \a this array. If it is the case, an exception
2788  * is thrown.
2789  * \throw If zero is found in \a this array.
2790  */
2791 void DataArrayDouble::checkNoNullValues() const throw(INTERP_KERNEL::Exception)
2792 {
2793   const double *tmp=getConstPointer();
2794   std::size_t nbOfElems=getNbOfElems();
2795   const double *where=std::find(tmp,tmp+nbOfElems,0.);
2796   if(where!=tmp+nbOfElems)
2797     throw INTERP_KERNEL::Exception("A value 0.0 have been detected !");
2798 }
2799
2800 /*!
2801  * Computes minimal and maximal value in each component. An output array is filled
2802  * with \c 2 * \a this->getNumberOfComponents() values, so the caller is to allocate
2803  * enough memory before calling this method.
2804  *  \param [out] bounds - array of size at least 2 *\a this->getNumberOfComponents().
2805  *               It is filled as follows:<br>
2806  *               \a bounds[0] = \c min_of_component_0 <br>
2807  *               \a bounds[1] = \c max_of_component_0 <br>
2808  *               \a bounds[2] = \c min_of_component_1 <br>
2809  *               \a bounds[3] = \c max_of_component_1 <br>
2810  *               ...
2811  */
2812 void DataArrayDouble::getMinMaxPerComponent(double *bounds) const throw(INTERP_KERNEL::Exception)
2813 {
2814   checkAllocated();
2815   int dim=getNumberOfComponents();
2816   for (int idim=0; idim<dim; idim++)
2817     {
2818       bounds[idim*2]=std::numeric_limits<double>::max();
2819       bounds[idim*2+1]=-std::numeric_limits<double>::max();
2820     } 
2821   const double *ptr=getConstPointer();
2822   int nbOfTuples=getNumberOfTuples();
2823   for(int i=0;i<nbOfTuples;i++)
2824     {
2825       for(int idim=0;idim<dim;idim++)
2826         {
2827           if(bounds[idim*2]>ptr[i*dim+idim])
2828             {
2829               bounds[idim*2]=ptr[i*dim+idim];
2830             }
2831           if(bounds[idim*2+1]<ptr[i*dim+idim])
2832             {
2833               bounds[idim*2+1]=ptr[i*dim+idim];
2834             }
2835         }
2836     }
2837 }
2838
2839 /*!
2840  * This method retrieves a newly allocated DataArrayDouble instance having same number of tuples than \a this and twice number of components than \a this
2841  * to store both the min and max per component of each tuples. 
2842  * \param [in] epsilon the width of the bbox (identical in each direction) - 0.0 by default
2843  *
2844  * \return a newly created DataArrayDouble instance having \c this->getNumberOfTuples() tuples and 2 * \c this->getNumberOfComponent() components
2845  *
2846  * \throw If \a this is not allocated yet.
2847  */
2848 DataArrayDouble *DataArrayDouble::computeBBoxPerTuple(double epsilon)const throw(INTERP_KERNEL::Exception)
2849 {
2850   checkAllocated();
2851   const double *dataPtr=getConstPointer();
2852   int nbOfCompo=getNumberOfComponents();
2853   int nbTuples=getNumberOfTuples();
2854   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> bbox=DataArrayDouble::New();
2855   bbox->alloc(nbTuples,2*nbOfCompo);
2856   double *bboxPtr=bbox->getPointer();
2857   for(int i=0;i<nbTuples;i++)
2858     {
2859       for(int j=0;j<nbOfCompo;j++)
2860         {
2861           bboxPtr[2*nbOfCompo*i+2*j]=dataPtr[nbOfCompo*i+j]-epsilon;
2862           bboxPtr[2*nbOfCompo*i+2*j+1]=dataPtr[nbOfCompo*i+j]+epsilon;
2863         }
2864     }
2865   return bbox.retn();
2866 }
2867
2868 /*!
2869  * For each tuples **t** in \a other, this method retrieves tuples in \a this that are equal to **t**.
2870  * Two tuples are considered equal if the euclidian distance between the two tuples is lower than \a eps.
2871  * 
2872  * \param [in] other a DataArrayDouble having same number of components than \a this.
2873  * \param [in] eps absolute precision representing distance (using infinite norm) between 2 tuples behind which 2 tuples are considered equal.
2874  * \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.
2875  *             \a cI allows to extract information in \a c.
2876  * \param [out] cI is an indirection array that allows to extract the data contained in \a c.
2877  *
2878  * \throw In case of:
2879  *  - \a this is not allocated
2880  *  - \a other is not allocated or null
2881  *  - \a this and \a other do not have the same number of components
2882  *  - if number of components of \a this is not in [1,2,3]
2883  *
2884  * \sa MEDCouplingPointSet::getNodeIdsNearPoints, DataArrayDouble::getDifferentValues
2885  */
2886 void DataArrayDouble::computeTupleIdsNearTuples(const DataArrayDouble *other, double eps, DataArrayInt *& c, DataArrayInt *& cI) const throw(INTERP_KERNEL::Exception)
2887 {
2888   if(!other)
2889     throw INTERP_KERNEL::Exception("DataArrayDouble::computeTupleIdsNearTuples : input pointer other is null !");
2890   checkAllocated();
2891   other->checkAllocated();
2892   int nbOfCompo=getNumberOfComponents();
2893   int otherNbOfCompo=other->getNumberOfComponents();
2894   if(nbOfCompo!=otherNbOfCompo)
2895     throw INTERP_KERNEL::Exception("DataArrayDouble::computeTupleIdsNearTuples : number of components should be equal between this and other !");
2896   int nbOfTuplesOther=other->getNumberOfTuples();
2897   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cArr(DataArrayInt::New()),cIArr(DataArrayInt::New()); cArr->alloc(0,1); cIArr->pushBackSilent(0);
2898   switch(nbOfCompo)
2899     {
2900     case 3:
2901       {
2902         BBTreePts<3,int> myTree(begin(),0,0,getNumberOfTuples(),eps);
2903         FindTupleIdsNearTuplesAlg<3>(myTree,other->getConstPointer(),nbOfTuplesOther,eps,cArr,cIArr);
2904         break;
2905       }
2906     case 2:
2907       {
2908         BBTreePts<2,int> myTree(begin(),0,0,getNumberOfTuples(),eps);
2909         FindTupleIdsNearTuplesAlg<2>(myTree,other->getConstPointer(),nbOfTuplesOther,eps,cArr,cIArr);
2910         break;
2911       }
2912     case 1:
2913       {
2914         BBTreePts<1,int> myTree(begin(),0,0,getNumberOfTuples(),eps);
2915         FindTupleIdsNearTuplesAlg<1>(myTree,other->getConstPointer(),nbOfTuplesOther,eps,cArr,cIArr);
2916         break;
2917       }
2918     default:
2919       throw INTERP_KERNEL::Exception("Unexpected spacedim of coords for computeTupleIdsNearTuples. Must be 1, 2 or 3.");
2920     }
2921   c=cArr.retn(); cI=cIArr.retn();
2922 }
2923
2924 /*!
2925  * 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
2926  * around origin of 'radius' 1.
2927  * 
2928  * \param [in] eps absolute epsilon. under that value of delta between max and min no scale is performed.
2929  */
2930 void DataArrayDouble::recenterForMaxPrecision(double eps) throw(INTERP_KERNEL::Exception)
2931 {
2932   checkAllocated();
2933   int dim=getNumberOfComponents();
2934   std::vector<double> bounds(2*dim);
2935   getMinMaxPerComponent(&bounds[0]);
2936   for(int i=0;i<dim;i++)
2937     {
2938       double delta=bounds[2*i+1]-bounds[2*i];
2939       double offset=(bounds[2*i]+bounds[2*i+1])/2.;
2940       if(delta>eps)
2941         applyLin(1./delta,-offset/delta,i);
2942       else
2943         applyLin(1.,-offset,i);
2944     }
2945 }
2946
2947 /*!
2948  * Returns the maximal value and its location within \a this one-dimensional array.
2949  *  \param [out] tupleId - index of the tuple holding the maximal value.
2950  *  \return double - the maximal value among all values of \a this array.
2951  *  \throw If \a this->getNumberOfComponents() != 1
2952  *  \throw If \a this->getNumberOfTuples() < 1
2953  */
2954 double DataArrayDouble::getMaxValue(int& tupleId) const throw(INTERP_KERNEL::Exception)
2955 {
2956   checkAllocated();
2957   if(getNumberOfComponents()!=1)
2958     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 !");
2959   int nbOfTuples=getNumberOfTuples();
2960   if(nbOfTuples<=0)
2961     throw INTERP_KERNEL::Exception("DataArrayDouble::getMaxValue : array exists but number of tuples must be > 0 !");
2962   const double *vals=getConstPointer();
2963   const double *loc=std::max_element(vals,vals+nbOfTuples);
2964   tupleId=(int)std::distance(vals,loc);
2965   return *loc;
2966 }
2967
2968 /*!
2969  * Returns the maximal value within \a this array that is allowed to have more than
2970  *  one component.
2971  *  \return double - the maximal value among all values of \a this array.
2972  *  \throw If \a this is not allocated.
2973  */
2974 double DataArrayDouble::getMaxValueInArray() const throw(INTERP_KERNEL::Exception)
2975 {
2976   checkAllocated();
2977   const double *loc=std::max_element(begin(),end());
2978   return *loc;
2979 }
2980
2981 /*!
2982  * Returns the maximal value and all its locations within \a this one-dimensional array.
2983  *  \param [out] tupleIds - a new instance of DataArrayInt containg indices of
2984  *               tuples holding the maximal value. The caller is to delete it using
2985  *               decrRef() as it is no more needed.
2986  *  \return double - the maximal value among all values of \a this array.
2987  *  \throw If \a this->getNumberOfComponents() != 1
2988  *  \throw If \a this->getNumberOfTuples() < 1
2989  */
2990 double DataArrayDouble::getMaxValue2(DataArrayInt*& tupleIds) const throw(INTERP_KERNEL::Exception)
2991 {
2992   int tmp;
2993   tupleIds=0;
2994   double ret=getMaxValue(tmp);
2995   tupleIds=getIdsInRange(ret,ret);
2996   return ret;
2997 }
2998
2999 /*!
3000  * Returns the minimal value and its location within \a this one-dimensional array.
3001  *  \param [out] tupleId - index of the tuple holding the minimal value.
3002  *  \return double - the minimal value among all values of \a this array.
3003  *  \throw If \a this->getNumberOfComponents() != 1
3004  *  \throw If \a this->getNumberOfTuples() < 1
3005  */
3006 double DataArrayDouble::getMinValue(int& tupleId) const throw(INTERP_KERNEL::Exception)
3007 {
3008   checkAllocated();
3009   if(getNumberOfComponents()!=1)
3010     throw INTERP_KERNEL::Exception("DataArrayDouble::getMinValue : must be applied on DataArrayDouble with only one component, you can call 'rearrange' method before call 'getMinValueInArray' method !");
3011   int nbOfTuples=getNumberOfTuples();
3012   if(nbOfTuples<=0)
3013     throw INTERP_KERNEL::Exception("DataArrayDouble::getMinValue : array exists but number of tuples must be > 0 !");
3014   const double *vals=getConstPointer();
3015   const double *loc=std::min_element(vals,vals+nbOfTuples);
3016   tupleId=(int)std::distance(vals,loc);
3017   return *loc;
3018 }
3019
3020 /*!
3021  * Returns the minimal value within \a this array that is allowed to have more than
3022  *  one component.
3023  *  \return double - the minimal value among all values of \a this array.
3024  *  \throw If \a this is not allocated.
3025  */
3026 double DataArrayDouble::getMinValueInArray() const throw(INTERP_KERNEL::Exception)
3027 {
3028   checkAllocated();
3029   const double *loc=std::min_element(begin(),end());
3030   return *loc;
3031 }
3032
3033 /*!
3034  * Returns the minimal value and all its locations within \a this one-dimensional array.
3035  *  \param [out] tupleIds - a new instance of DataArrayInt containg indices of
3036  *               tuples holding the minimal value. The caller is to delete it using
3037  *               decrRef() as it is no more needed.
3038  *  \return double - the minimal value among all values of \a this array.
3039  *  \throw If \a this->getNumberOfComponents() != 1
3040  *  \throw If \a this->getNumberOfTuples() < 1
3041  */
3042 double DataArrayDouble::getMinValue2(DataArrayInt*& tupleIds) const throw(INTERP_KERNEL::Exception)
3043 {
3044   int tmp;
3045   tupleIds=0;
3046   double ret=getMinValue(tmp);
3047   tupleIds=getIdsInRange(ret,ret);
3048   return ret;
3049 }
3050
3051 /*!
3052  * 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.
3053  * This method only works for single component array.
3054  *
3055  * \return a value in [ 0, \c this->getNumberOfTuples() )
3056  *
3057  * \throw If \a this is not allocated
3058  *
3059  */
3060 int DataArrayDouble::count(double value, double eps) const throw(INTERP_KERNEL::Exception)
3061 {
3062   int ret=0;
3063   checkAllocated();
3064   if(getNumberOfComponents()!=1)
3065     throw INTERP_KERNEL::Exception("DataArrayDouble::count : must be applied on DataArrayDouble with only one component, you can call 'rearrange' method before !");
3066   const double *vals=begin();
3067   int nbOfTuples=getNumberOfTuples();
3068   for(int i=0;i<nbOfTuples;i++,vals++)
3069     if(fabs(*vals-value)<=eps)
3070       ret++;
3071   return ret;
3072 }
3073
3074 /*!
3075  * Returns the average value of \a this one-dimensional array.
3076  *  \return double - the average value over all values of \a this array.
3077  *  \throw If \a this->getNumberOfComponents() != 1
3078  *  \throw If \a this->getNumberOfTuples() < 1
3079  */
3080 double DataArrayDouble::getAverageValue() const throw(INTERP_KERNEL::Exception)
3081 {
3082   if(getNumberOfComponents()!=1)
3083     throw INTERP_KERNEL::Exception("DataArrayDouble::getAverageValue : must be applied on DataArrayDouble with only one component, you can call 'rearrange' method before !");
3084   int nbOfTuples=getNumberOfTuples();
3085   if(nbOfTuples<=0)
3086     throw INTERP_KERNEL::Exception("DataArrayDouble::getAverageValue : array exists but number of tuples must be > 0 !");
3087   const double *vals=getConstPointer();
3088   double ret=std::accumulate(vals,vals+nbOfTuples,0.);
3089   return ret/nbOfTuples;
3090 }
3091
3092 /*!
3093  * Returns the Euclidean norm of the vector defined by \a this array.
3094  *  \return double - the value of the Euclidean norm, i.e.
3095  *          the square root of the inner product of vector.
3096  *  \throw If \a this is not allocated.
3097  */
3098 double DataArrayDouble::norm2() const throw(INTERP_KERNEL::Exception)
3099 {
3100   checkAllocated();
3101   double ret=0.;
3102   std::size_t nbOfElems=getNbOfElems();
3103   const double *pt=getConstPointer();
3104   for(std::size_t i=0;i<nbOfElems;i++,pt++)
3105     ret+=(*pt)*(*pt);
3106   return sqrt(ret);
3107 }
3108
3109 /*!
3110  * Returns the maximum norm of the vector defined by \a this array.
3111  *  \return double - the value of the maximum norm, i.e.
3112  *          the maximal absolute value among values of \a this array.
3113  *  \throw If \a this is not allocated.
3114  */
3115 double DataArrayDouble::normMax() const throw(INTERP_KERNEL::Exception)
3116 {
3117   checkAllocated();
3118   double ret=-1.;
3119   std::size_t nbOfElems=getNbOfElems();
3120   const double *pt=getConstPointer();
3121   for(std::size_t i=0;i<nbOfElems;i++,pt++)
3122     {
3123       double val=std::abs(*pt);
3124       if(val>ret)
3125         ret=val;
3126     }
3127   return ret;
3128 }
3129
3130 /*!
3131  * Accumulates values of each component of \a this array.
3132  *  \param [out] res - an array of length \a this->getNumberOfComponents(), allocated 
3133  *         by the caller, that is filled by this method with sum value for each
3134  *         component.
3135  *  \throw If \a this is not allocated.
3136  */
3137 void DataArrayDouble::accumulate(double *res) const throw(INTERP_KERNEL::Exception)
3138 {
3139   checkAllocated();
3140   const double *ptr=getConstPointer();
3141   int nbTuple=getNumberOfTuples();
3142   int nbComps=getNumberOfComponents();
3143   std::fill(res,res+nbComps,0.);
3144   for(int i=0;i<nbTuple;i++)
3145     std::transform(ptr+i*nbComps,ptr+(i+1)*nbComps,res,res,std::plus<double>());
3146 }
3147
3148 /*!
3149  * This method returns the min distance from an external tuple defined by [ \a tupleBg , \a tupleEnd ) to \a this and
3150  * the first tuple in \a this that matches the returned distance. If there is no tuples in \a this an exception will be thrown.
3151  *
3152  *
3153  * \a this is expected to be allocated and expected to have a number of components equal to the distance from \a tupleBg to
3154  * \a tupleEnd. If not an exception will be thrown.
3155  *
3156  * \param [in] tupleBg start pointer (included) of input external tuple
3157  * \param [in] tupleEnd end pointer (not included) of input external tuple
3158  * \param [out] tupleId the tuple id in \a this that matches the min of distance between \a this and input external tuple
3159  * \return the min distance.
3160  * \sa MEDCouplingUMesh::distanceToPoint
3161  */
3162 double DataArrayDouble::distanceToTuple(const double *tupleBg, const double *tupleEnd, int& tupleId) const throw(INTERP_KERNEL::Exception)
3163 {
3164   checkAllocated();
3165   int nbTuple=getNumberOfTuples();
3166   int nbComps=getNumberOfComponents();
3167   if(nbComps!=(int)std::distance(tupleBg,tupleEnd))
3168     { 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()); }
3169   if(nbTuple==0)
3170     throw INTERP_KERNEL::Exception("DataArrayDouble::distanceToTuple : no tuple in this ! No distance to compute !");
3171   double ret0=std::numeric_limits<double>::max();
3172   tupleId=-1;
3173   const double *work=getConstPointer();
3174   for(int i=0;i<nbTuple;i++)
3175     {
3176       double val=0.;
3177       for(int j=0;j<nbComps;j++,work++) 
3178         val+=(*work-tupleBg[j])*((*work-tupleBg[j]));
3179       if(val>=ret0)
3180         continue;
3181       else
3182         { ret0=val; tupleId=i; }
3183     }
3184   return sqrt(ret0);
3185 }
3186
3187 /*!
3188  * Accumulate values of the given component of \a this array.
3189  *  \param [in] compId - the index of the component of interest.
3190  *  \return double - a sum value of \a compId-th component.
3191  *  \throw If \a this is not allocated.
3192  *  \throw If \a the condition ( 0 <= \a compId < \a this->getNumberOfComponents() ) is
3193  *         not respected.
3194  */
3195 double DataArrayDouble::accumulate(int compId) const throw(INTERP_KERNEL::Exception)
3196 {
3197   checkAllocated();
3198   const double *ptr=getConstPointer();
3199   int nbTuple=getNumberOfTuples();
3200   int nbComps=getNumberOfComponents();
3201   if(compId<0 || compId>=nbComps)
3202     throw INTERP_KERNEL::Exception("DataArrayDouble::accumulate : Invalid compId specified : No such nb of components !");
3203   double ret=0.;
3204   for(int i=0;i<nbTuple;i++)
3205     ret+=ptr[i*nbComps+compId];
3206   return ret;
3207 }
3208
3209 /*!
3210  * This method accumulate using addition tuples in \a this using input index array [ \a bgOfIndex, \a endOfIndex ).
3211  * The returned array will have same number of components than \a this and number of tuples equal to
3212  * \c std::distance(bgOfIndex,endOfIndex) \b minus \b one.
3213  *
3214  * The input index array is expected to be ascendingly sorted in which the all referenced ids should be in [0, \c this->getNumberOfTuples).
3215  * 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.
3216  *
3217  * \param [in] bgOfIndex - begin (included) of the input index array.
3218  * \param [in] endOfIndex - end (excluded) of the input index array.
3219  * \return DataArrayDouble * - the new instance having the same number of components than \a this.
3220  * 
3221  * \throw If bgOfIndex or end is NULL.
3222  * \throw If input index array is not ascendingly sorted.
3223  * \throw If there is an id in [ \a bgOfIndex, \a endOfIndex ) not in [0, \c this->getNumberOfTuples).
3224  * \throw If std::distance(bgOfIndex,endOfIndex)==0.
3225  */
3226 DataArrayDouble *DataArrayDouble::accumulatePerChunck(const int *bgOfIndex, const int *endOfIndex) const throw(INTERP_KERNEL::Exception)
3227 {
3228   if(!bgOfIndex || !endOfIndex)
3229     throw INTERP_KERNEL::Exception("DataArrayDouble::accumulatePerChunck : input pointer NULL !");
3230   checkAllocated();
3231   int nbCompo=getNumberOfComponents();
3232   int nbOfTuples=getNumberOfTuples();
3233   int sz=(int)std::distance(bgOfIndex,endOfIndex);
3234   if(sz<1)
3235     throw INTERP_KERNEL::Exception("DataArrayDouble::accumulatePerChunck : invalid size of input index array !");
3236   sz--;
3237   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New(); ret->alloc(sz,nbCompo);
3238   const int *w=bgOfIndex;
3239   if(*w<0 || *w>=nbOfTuples)
3240     throw INTERP_KERNEL::Exception("DataArrayDouble::accumulatePerChunck : The first element of the input index not in [0,nbOfTuples) !");
3241   const double *srcPt=begin()+(*w)*nbCompo;
3242   double *tmp=ret->getPointer();
3243   for(int i=0;i<sz;i++,tmp+=nbCompo,w++)
3244     {
3245       std::fill(tmp,tmp+nbCompo,0.);
3246       if(w[1]>=w[0])
3247         {
3248           for(int j=w[0];j<w[1];j++,srcPt+=nbCompo)
3249             {
3250               if(j>=0 && j<nbOfTuples)
3251                 std::transform(srcPt,srcPt+nbCompo,tmp,tmp,std::plus<double>());
3252               else
3253                 {
3254                   std::ostringstream oss; oss << "DataArrayDouble::accumulatePerChunck : At rank #" << i << " the input index array points to id " << j << " should be in [0," << nbOfTuples << ") !";
3255                   throw INTERP_KERNEL::Exception(oss.str().c_str());
3256                 }
3257             }
3258         }
3259       else
3260         {
3261           std::ostringstream oss; oss << "DataArrayDouble::accumulatePerChunck : At rank #" << i << " the input index array is not in ascendingly sorted.";
3262           throw INTERP_KERNEL::Exception(oss.str().c_str());
3263         }
3264     }
3265   ret->copyStringInfoFrom(*this);
3266   return ret.retn();
3267 }
3268
3269 /*!
3270  * Converts each 2D point defined by the tuple of \a this array from the Polar to the
3271  * Cartesian coordinate system. The two components of the tuple of \a this array are 
3272  * considered to contain (1) radius and (2) angle of the point in the Polar CS.
3273  *  \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
3274  *          contains X and Y coordinates of the point in the Cartesian CS. The caller
3275  *          is to delete this array using decrRef() as it is no more needed. The array
3276  *          does not contain any textual info on components.
3277  *  \throw If \a this->getNumberOfComponents() != 2.
3278  */
3279 DataArrayDouble *DataArrayDouble::fromPolarToCart() const throw(INTERP_KERNEL::Exception)
3280 {
3281   checkAllocated();
3282   int nbOfComp=getNumberOfComponents();
3283   if(nbOfComp!=2)
3284     throw INTERP_KERNEL::Exception("DataArrayDouble::fromPolarToCart : must be an array with exactly 2 components !");
3285   int nbOfTuple=getNumberOfTuples();
3286   DataArrayDouble *ret=DataArrayDouble::New();
3287   ret->alloc(nbOfTuple,2);
3288   double *w=ret->getPointer();
3289   const double *wIn=getConstPointer();
3290   for(int i=0;i<nbOfTuple;i++,w+=2,wIn+=2)
3291     {
3292       w[0]=wIn[0]*cos(wIn[1]);
3293       w[1]=wIn[0]*sin(wIn[1]);
3294     }
3295   return ret;
3296 }
3297
3298 /*!
3299  * Converts each 3D point defined by the tuple of \a this array from the Cylindrical to
3300  * the Cartesian coordinate system. The three components of the tuple of \a this array 
3301  * are considered to contain (1) radius, (2) azimuth and (3) altitude of the point in
3302  * the Cylindrical CS.
3303  *  \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
3304  *          contains X, Y and Z coordinates of the point in the Cartesian CS. The info
3305  *          on the third component is copied from \a this array. The caller
3306  *          is to delete this array using decrRef() as it is no more needed. 
3307  *  \throw If \a this->getNumberOfComponents() != 3.
3308  */
3309 DataArrayDouble *DataArrayDouble::fromCylToCart() const throw(INTERP_KERNEL::Exception)
3310 {
3311   checkAllocated();
3312   int nbOfComp=getNumberOfComponents();
3313   if(nbOfComp!=3)
3314     throw INTERP_KERNEL::Exception("DataArrayDouble::fromCylToCart : must be an array with exactly 3 components !");
3315   int nbOfTuple=getNumberOfTuples();
3316   DataArrayDouble *ret=DataArrayDouble::New();
3317   ret->alloc(getNumberOfTuples(),3);
3318   double *w=ret->getPointer();
3319   const double *wIn=getConstPointer();
3320   for(int i=0;i<nbOfTuple;i++,w+=3,wIn+=3)
3321     {
3322       w[0]=wIn[0]*cos(wIn[1]);
3323       w[1]=wIn[0]*sin(wIn[1]);
3324       w[2]=wIn[2];
3325     }
3326   ret->setInfoOnComponent(2,getInfoOnComponent(2).c_str());
3327   return ret;
3328 }
3329
3330 /*!
3331  * Converts each 3D point defined by the tuple of \a this array from the Spherical to
3332  * the Cartesian coordinate system. The three components of the tuple of \a this array 
3333  * are considered to contain (1) radius, (2) polar angle and (3) azimuthal angle of the
3334  * point in the Cylindrical CS.
3335  *  \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
3336  *          contains X, Y and Z coordinates of the point in the Cartesian CS. The info
3337  *          on the third component is copied from \a this array. The caller
3338  *          is to delete this array using decrRef() as it is no more needed.
3339  *  \throw If \a this->getNumberOfComponents() != 3.
3340  */
3341 DataArrayDouble *DataArrayDouble::fromSpherToCart() const throw(INTERP_KERNEL::Exception)
3342 {
3343   checkAllocated();
3344   int nbOfComp=getNumberOfComponents();
3345   if(nbOfComp!=3)
3346     throw INTERP_KERNEL::Exception("DataArrayDouble::fromSpherToCart : must be an array with exactly 3 components !");
3347   int nbOfTuple=getNumberOfTuples();
3348   DataArrayDouble *ret=DataArrayDouble::New();
3349   ret->alloc(getNumberOfTuples(),3);
3350   double *w=ret->getPointer();
3351   const double *wIn=getConstPointer();
3352   for(int i=0;i<nbOfTuple;i++,w+=3,wIn+=3)
3353     {
3354       w[0]=wIn[0]*cos(wIn[2])*sin(wIn[1]);
3355       w[1]=wIn[0]*sin(wIn[2])*sin(wIn[1]);
3356       w[2]=wIn[0]*cos(wIn[1]);
3357     }
3358   return ret;
3359 }
3360
3361 /*!
3362  * Computes the doubly contracted product of every tensor defined by the tuple of \a this
3363  * array contating 6 components.
3364  *  \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
3365  *          is calculated from the tuple <em>(t)</em> of \a this array as follows:
3366  *          \f$ t[0]^2+t[1]^2+t[2]^2+2*t[3]^2+2*t[4]^2+2*t[5]^2\f$.
3367  *         The caller is to delete this result array using decrRef() as it is no more needed. 
3368  *  \throw If \a this->getNumberOfComponents() != 6.
3369  */
3370 DataArrayDouble *DataArrayDouble::doublyContractedProduct() const throw(INTERP_KERNEL::Exception)
3371 {
3372   checkAllocated();
3373   int nbOfComp=getNumberOfComponents();
3374   if(nbOfComp!=6)
3375     throw INTERP_KERNEL::Exception("DataArrayDouble::doublyContractedProduct : must be an array with exactly 6 components !");
3376   DataArrayDouble *ret=DataArrayDouble::New();
3377   int nbOfTuple=getNumberOfTuples();
3378   ret->alloc(nbOfTuple,1);
3379   const double *src=getConstPointer();
3380   double *dest=ret->getPointer();
3381   for(int i=0;i<nbOfTuple;i++,dest++,src+=6)
3382     *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];
3383   return ret;
3384 }
3385
3386 /*!
3387  * Computes the determinant of every square matrix defined by the tuple of \a this
3388  * array, which contains either 4, 6 or 9 components. The case of 6 components
3389  * corresponds to that of the upper triangular matrix.
3390  *  \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
3391  *          is the determinant of matrix of the corresponding tuple of \a this array.
3392  *          The caller is to delete this result array using decrRef() as it is no more
3393  *          needed. 
3394  *  \throw If \a this->getNumberOfComponents() is not in [4,6,9].
3395  */
3396 DataArrayDouble *DataArrayDouble::determinant() const throw(INTERP_KERNEL::Exception)
3397 {
3398   checkAllocated();
3399   DataArrayDouble *ret=DataArrayDouble::New();
3400   int nbOfTuple=getNumberOfTuples();
3401   ret->alloc(nbOfTuple,1);
3402   const double *src=getConstPointer();
3403   double *dest=ret->getPointer();
3404   switch(getNumberOfComponents())
3405     {
3406     case 6:
3407       for(int i=0;i<nbOfTuple;i++,dest++,src+=6)
3408         *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];
3409       return ret;
3410     case 4:
3411       for(int i=0;i<nbOfTuple;i++,dest++,src+=4)
3412         *dest=src[0]*src[3]-src[1]*src[2];
3413       return ret;
3414     case 9:
3415       for(int i=0;i<nbOfTuple;i++,dest++,src+=9)
3416         *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];
3417       return ret;
3418     default:
3419       ret->decrRef();
3420       throw INTERP_KERNEL::Exception("DataArrayDouble::determinant : Invalid number of components ! must be in 4,6,9 !");
3421     }
3422 }
3423
3424 /*!
3425  * Computes 3 eigenvalues of every upper triangular matrix defined by the tuple of
3426  * \a this array, which contains 6 components.
3427  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing 3
3428  *          components, whose each tuple contains the eigenvalues of the matrix of
3429  *          corresponding tuple of \a this array. 
3430  *          The caller is to delete this result array using decrRef() as it is no more
3431  *          needed. 
3432  *  \throw If \a this->getNumberOfComponents() != 6.
3433  */
3434 DataArrayDouble *DataArrayDouble::eigenValues() const throw(INTERP_KERNEL::Exception)
3435 {
3436   checkAllocated();
3437   int nbOfComp=getNumberOfComponents();
3438   if(nbOfComp!=6)
3439     throw INTERP_KERNEL::Exception("DataArrayDouble::eigenValues : must be an array with exactly 6 components !");
3440   DataArrayDouble *ret=DataArrayDouble::New();
3441   int nbOfTuple=getNumberOfTuples();
3442   ret->alloc(nbOfTuple,3);
3443   const double *src=getConstPointer();
3444   double *dest=ret->getPointer();
3445   for(int i=0;i<nbOfTuple;i++,dest+=3,src+=6)
3446     INTERP_KERNEL::computeEigenValues6(src,dest);
3447   return ret;
3448 }
3449
3450 /*!
3451  * Computes 3 eigenvectors of every upper triangular matrix defined by the tuple of
3452  * \a this array, which contains 6 components.
3453  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing 9
3454  *          components, whose each tuple contains 3 eigenvectors of the matrix of
3455  *          corresponding tuple of \a this array.
3456  *          The caller is to delete this result array using decrRef() as it is no more
3457  *          needed.
3458  *  \throw If \a this->getNumberOfComponents() != 6.
3459  */
3460 DataArrayDouble *DataArrayDouble::eigenVectors() const throw(INTERP_KERNEL::Exception)
3461 {
3462   checkAllocated();
3463   int nbOfComp=getNumberOfComponents();
3464   if(nbOfComp!=6)
3465     throw INTERP_KERNEL::Exception("DataArrayDouble::eigenVectors : must be an array with exactly 6 components !");
3466   DataArrayDouble *ret=DataArrayDouble::New();
3467   int nbOfTuple=getNumberOfTuples();
3468   ret->alloc(nbOfTuple,9);
3469   const double *src=getConstPointer();
3470   double *dest=ret->getPointer();
3471   for(int i=0;i<nbOfTuple;i++,src+=6)
3472     {
3473       double tmp[3];
3474       INTERP_KERNEL::computeEigenValues6(src,tmp);
3475       for(int j=0;j<3;j++,dest+=3)
3476         INTERP_KERNEL::computeEigenVectorForEigenValue6(src,tmp[j],1e-12,dest);
3477     }
3478   return ret;
3479 }
3480
3481 /*!
3482  * Computes the inverse matrix of every matrix defined by the tuple of \a this
3483  * array, which contains either 4, 6 or 9 components. The case of 6 components
3484  * corresponds to that of the upper triangular matrix.
3485  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
3486  *          same number of components as \a this one, whose each tuple is the inverse
3487  *          matrix of the matrix of corresponding tuple of \a this array. 
3488  *          The caller is to delete this result array using decrRef() as it is no more
3489  *          needed. 
3490  *  \throw If \a this->getNumberOfComponents() is not in [4,6,9].
3491  */
3492 DataArrayDouble *DataArrayDouble::inverse() const throw(INTERP_KERNEL::Exception)
3493 {
3494   checkAllocated();
3495   int nbOfComp=getNumberOfComponents();
3496   if(nbOfComp!=6 && nbOfComp!=9 && nbOfComp!=4)
3497     throw INTERP_KERNEL::Exception("DataArrayDouble::inversion : must be an array with 4,6 or 9 components !");
3498   DataArrayDouble *ret=DataArrayDouble::New();
3499   int nbOfTuple=getNumberOfTuples();
3500   ret->alloc(nbOfTuple,nbOfComp);
3501   const double *src=getConstPointer();
3502   double *dest=ret->getPointer();
3503 if(nbOfComp==6)
3504     for(int i=0;i<nbOfTuple;i++,dest+=6,src+=6)
3505       {
3506         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];
3507         dest[0]=(src[1]*src[2]-src[4]*src[4])/det;
3508         dest[1]=(src[0]*src[2]-src[5]*src[5])/det;
3509         dest[2]=(src[0]*src[1]-src[3]*src[3])/det;
3510         dest[3]=(src[5]*src[4]-src[3]*src[2])/det;
3511         dest[4]=(src[5]*src[3]-src[0]*src[4])/det;
3512         dest[5]=(src[3]*src[4]-src[1]*src[5])/det;
3513       }
3514   else if(nbOfComp==4)
3515     for(int i=0;i<nbOfTuple;i++,dest+=4,src+=4)
3516       {
3517         double det=src[0]*src[3]-src[1]*src[2];
3518         dest[0]=src[3]/det;
3519         dest[1]=-src[1]/det;
3520         dest[2]=-src[2]/det;
3521         dest[3]=src[0]/det;
3522       }
3523   else
3524     for(int i=0;i<nbOfTuple;i++,dest+=9,src+=9)
3525       {
3526         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];
3527         dest[0]=(src[4]*src[8]-src[7]*src[5])/det;
3528         dest[1]=(src[7]*src[2]-src[1]*src[8])/det;
3529         dest[2]=(src[1]*src[5]-src[4]*src[2])/det;
3530         dest[3]=(src[6]*src[5]-src[3]*src[8])/det;
3531         dest[4]=(src[0]*src[8]-src[6]*src[2])/det;
3532         dest[5]=(src[2]*src[3]-src[0]*src[5])/det;
3533         dest[6]=(src[3]*src[7]-src[6]*src[4])/det;
3534         dest[7]=(src[6]*src[1]-src[0]*src[7])/det;
3535         dest[8]=(src[0]*src[4]-src[1]*src[3])/det;
3536       }
3537   return ret;
3538 }
3539
3540 /*!
3541  * Computes the trace of every matrix defined by the tuple of \a this
3542  * array, which contains either 4, 6 or 9 components. The case of 6 components
3543  * corresponds to that of the upper triangular matrix.
3544  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing 
3545  *          1 component, whose each tuple is the trace of
3546  *          the matrix of corresponding tuple of \a this array. 
3547  *          The caller is to delete this result array using decrRef() as it is no more
3548  *          needed. 
3549  *  \throw If \a this->getNumberOfComponents() is not in [4,6,9].
3550  */
3551 DataArrayDouble *DataArrayDouble::trace() const throw(INTERP_KERNEL::Exception)
3552 {
3553   checkAllocated();
3554   int nbOfComp=getNumberOfComponents();
3555   if(nbOfComp!=6 && nbOfComp!=9 && nbOfComp!=4)
3556     throw INTERP_KERNEL::Exception("DataArrayDouble::trace : must be an array with 4,6 or 9 components !");
3557   DataArrayDouble *ret=DataArrayDouble::New();
3558   int nbOfTuple=getNumberOfTuples();
3559   ret->alloc(nbOfTuple,1);
3560   const double *src=getConstPointer();
3561   double *dest=ret->getPointer();
3562   if(nbOfComp==6)
3563     for(int i=0;i<nbOfTuple;i++,dest++,src+=6)
3564       *dest=src[0]+src[1]+src[2];
3565   else if(nbOfComp==4)
3566     for(int i=0;i<nbOfTuple;i++,dest++,src+=4)
3567       *dest=src[0]+src[3];
3568   else
3569     for(int i=0;i<nbOfTuple;i++,dest++,src+=9)
3570       *dest=src[0]+src[4]+src[8];
3571   return ret;
3572 }
3573
3574 /*!
3575  * Computes the stress deviator tensor of every stress tensor defined by the tuple of
3576  * \a this array, which contains 6 components.
3577  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
3578  *          same number of components and tuples as \a this array.
3579  *          The caller is to delete this result array using decrRef() as it is no more
3580  *          needed.
3581  *  \throw If \a this->getNumberOfComponents() != 6.
3582  */
3583 DataArrayDouble *DataArrayDouble::deviator() const throw(INTERP_KERNEL::Exception)
3584 {
3585   checkAllocated();
3586   int nbOfComp=getNumberOfComponents();
3587   if(nbOfComp!=6)
3588     throw INTERP_KERNEL::Exception("DataArrayDouble::deviator : must be an array with exactly 6 components !");
3589   DataArrayDouble *ret=DataArrayDouble::New();
3590   int nbOfTuple=getNumberOfTuples();
3591   ret->alloc(nbOfTuple,6);
3592   const double *src=getConstPointer();
3593   double *dest=ret->getPointer();
3594   for(int i=0;i<nbOfTuple;i++,dest+=6,src+=6)
3595     {
3596       double tr=(src[0]+src[1]+src[2])/3.;
3597       dest[0]=src[0]-tr;
3598       dest[1]=src[1]-tr;
3599       dest[2]=src[2]-tr;
3600       dest[3]=src[3];
3601       dest[4]=src[4];
3602       dest[5]=src[5];
3603     }
3604   return ret;
3605 }
3606
3607 /*!
3608  * Computes the magnitude of every vector defined by the tuple of
3609  * \a this array.
3610  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
3611  *          same number of tuples as \a this array and one component.
3612  *          The caller is to delete this result array using decrRef() as it is no more
3613  *          needed.
3614  *  \throw If \a this is not allocated.
3615  */
3616 DataArrayDouble *DataArrayDouble::magnitude() const throw(INTERP_KERNEL::Exception)
3617 {
3618   checkAllocated();
3619   int nbOfComp=getNumberOfComponents();
3620   DataArrayDouble *ret=DataArrayDouble::New();
3621   int nbOfTuple=getNumberOfTuples();
3622   ret->alloc(nbOfTuple,1);
3623   const double *src=getConstPointer();
3624   double *dest=ret->getPointer();
3625   for(int i=0;i<nbOfTuple;i++,dest++)
3626     {
3627       double sum=0.;
3628       for(int j=0;j<nbOfComp;j++,src++)
3629         sum+=(*src)*(*src);
3630       *dest=sqrt(sum);
3631     }
3632   return ret;
3633 }
3634
3635 /*!
3636  * Computes the maximal value within every tuple of \a this array.
3637  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
3638  *          same number of tuples as \a this array and one component.
3639  *          The caller is to delete this result array using decrRef() as it is no more
3640  *          needed.
3641  *  \throw If \a this is not allocated.
3642  *  \sa DataArrayDouble::maxPerTupleWithCompoId
3643  */
3644 DataArrayDouble *DataArrayDouble::maxPerTuple() const throw(INTERP_KERNEL::Exception)
3645 {
3646   checkAllocated();
3647   int nbOfComp=getNumberOfComponents();
3648   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
3649   int nbOfTuple=getNumberOfTuples();
3650   ret->alloc(nbOfTuple,1);
3651   const double *src=getConstPointer();
3652   double *dest=ret->getPointer();
3653   for(int i=0;i<nbOfTuple;i++,dest++,src+=nbOfComp)
3654     *dest=*std::max_element(src,src+nbOfComp);
3655   return ret.retn();
3656 }
3657
3658 /*!
3659  * Computes the maximal value within every tuple of \a this array and it returns the first component
3660  * id for each tuple that corresponds to the maximal value within the tuple.
3661  * 
3662  *  \param [out] compoIdOfMaxPerTuple - the new new instance of DataArrayInt containing the
3663  *          same number of tuples and only one component.
3664  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
3665  *          same number of tuples as \a this array and one component.
3666  *          The caller is to delete this result array using decrRef() as it is no more
3667  *          needed.
3668  *  \throw If \a this is not allocated.
3669  *  \sa DataArrayDouble::maxPerTuple
3670  */
3671 DataArrayDouble *DataArrayDouble::maxPerTupleWithCompoId(DataArrayInt* &compoIdOfMaxPerTuple) const throw(INTERP_KERNEL::Exception)
3672 {
3673   checkAllocated();
3674   int nbOfComp=getNumberOfComponents();
3675   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret0=DataArrayDouble::New();
3676   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret1=DataArrayInt::New();
3677   int nbOfTuple=getNumberOfTuples();
3678   ret0->alloc(nbOfTuple,1); ret1->alloc(nbOfTuple,1);
3679   const double *src=getConstPointer();
3680   double *dest=ret0->getPointer(); int *dest1=ret1->getPointer();
3681   for(int i=0;i<nbOfTuple;i++,dest++,dest1++,src+=nbOfComp)
3682     {
3683       const double *loc=std::max_element(src,src+nbOfComp);
3684       *dest=*loc;
3685       *dest1=(int)std::distance(src,loc);
3686     }
3687   compoIdOfMaxPerTuple=ret1.retn();
3688   return ret0.retn();
3689 }
3690
3691 /*!
3692  * This method returns a newly allocated DataArrayDouble instance having one component and \c this->getNumberOfTuples() * \c this->getNumberOfTuples() tuples.
3693  * \n This returned array contains the euclidian distance for each tuple in \a this. 
3694  * \n So the returned array can be seen as a dense symmetrical matrix whose diagonal elements are equal to 0.
3695  * \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)
3696  *
3697  * \warning use this method with care because it can leads to big amount of consumed memory !
3698  * 
3699  * \return A newly allocated (huge) ParaMEDMEM::DataArrayDouble instance that the caller should deal with.
3700  *
3701  * \throw If \a this is not allocated.
3702  *
3703  * \sa DataArrayDouble::buildEuclidianDistanceDenseMatrixWith
3704  */
3705 DataArrayDouble *DataArrayDouble::buildEuclidianDistanceDenseMatrix() const throw(INTERP_KERNEL::Exception)
3706 {
3707   checkAllocated();
3708   int nbOfComp=getNumberOfComponents();
3709   int nbOfTuples=getNumberOfTuples();
3710   const double *inData=getConstPointer();
3711   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
3712   ret->alloc(nbOfTuples*nbOfTuples,1);
3713   double *outData=ret->getPointer();
3714   for(int i=0;i<nbOfTuples;i++)
3715     {
3716       outData[i*nbOfTuples+i]=0.;
3717       for(int j=i+1;j<nbOfTuples;j++)
3718         {
3719           double dist=0.;
3720           for(int k=0;k<nbOfComp;k++)
3721             { double delta=inData[i*nbOfComp+k]-inData[j*nbOfComp+k]; dist+=delta*delta; }
3722           dist=sqrt(dist);
3723           outData[i*nbOfTuples+j]=dist;
3724           outData[j*nbOfTuples+i]=dist;
3725         }
3726     }
3727   return ret.retn();
3728 }
3729
3730 /*!
3731  * This method returns a newly allocated DataArrayDouble instance having one component and \c this->getNumberOfTuples() * \c other->getNumberOfTuples() tuples.
3732  * \n This returned array contains the euclidian distance for each tuple in \a other with each tuple in \a this. 
3733  * \n So the returned array can be seen as a dense rectangular matrix with \c other->getNumberOfTuples() rows and \c this->getNumberOfTuples() columns.
3734  * \n Output rectangular matrix is sorted along rows.
3735  * \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)
3736  *
3737  * \warning use this method with care because it can leads to big amount of consumed memory !
3738  * 
3739  * \param [in] other DataArrayDouble instance having same number of components than \a this.
3740  * \return A newly allocated (huge) ParaMEDMEM::DataArrayDouble instance that the caller should deal with.
3741  *
3742  * \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.
3743  *
3744  * \sa DataArrayDouble::buildEuclidianDistanceDenseMatrix
3745  */
3746 DataArrayDouble *DataArrayDouble::buildEuclidianDistanceDenseMatrixWith(const DataArrayDouble *other) const throw(INTERP_KERNEL::Exception)
3747 {
3748   if(!other)
3749     throw INTERP_KERNEL::Exception("DataArrayDouble::buildEuclidianDistanceDenseMatrixWith : input parameter is null !");
3750   checkAllocated();
3751   other->checkAllocated();
3752   int nbOfComp=getNumberOfComponents();
3753   int otherNbOfComp=other->getNumberOfComponents();
3754   if(nbOfComp!=otherNbOfComp)
3755     {
3756       std::ostringstream oss; oss << "DataArrayDouble::buildEuclidianDistanceDenseMatrixWith : this nb of compo=" << nbOfComp << " and other nb of compo=" << otherNbOfComp << ". It should match !";
3757       throw INTERP_KERNEL::Exception(oss.str().c_str());
3758     }
3759   int nbOfTuples=getNumberOfTuples();
3760   int otherNbOfTuples=other->getNumberOfTuples();
3761   const double *inData=getConstPointer();
3762   const double *inDataOther=other->getConstPointer();
3763   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
3764   ret->alloc(otherNbOfTuples*nbOfTuples,1);
3765   double *outData=ret->getPointer();
3766   for(int i=0;i<otherNbOfTuples;i++,inDataOther+=nbOfComp)
3767     {
3768       for(int j=0;j<nbOfTuples;j++)
3769         {
3770           double dist=0.;
3771           for(int k=0;k<nbOfComp;k++)
3772             { double delta=inDataOther[k]-inData[j*nbOfComp+k]; dist+=delta*delta; }
3773           dist=sqrt(dist);
3774           outData[i*nbOfTuples+j]=dist;
3775         }
3776     }
3777   return ret.retn();
3778 }
3779
3780 /*!
3781  * Sorts value within every tuple of \a this array.
3782  *  \param [in] asc - if \a true, the values are sorted in ascending order, else,
3783  *              in descending order.
3784  *  \throw If \a this is not allocated.
3785  */
3786 void DataArrayDouble::sortPerTuple(bool asc) throw(INTERP_KERNEL::Exception)
3787 {
3788   checkAllocated();
3789   double *pt=getPointer();
3790   int nbOfTuple=getNumberOfTuples();
3791   int nbOfComp=getNumberOfComponents();
3792   if(asc)
3793     for(int i=0;i<nbOfTuple;i++,pt+=nbOfComp)
3794       std::sort(pt,pt+nbOfComp);
3795   else
3796     for(int i=0;i<nbOfTuple;i++,pt+=nbOfComp)
3797       std::sort(pt,pt+nbOfComp,std::greater<double>());
3798   declareAsNew();
3799 }
3800
3801 /*!
3802  * Converts every value of \a this array to its absolute value.
3803  *  \throw If \a this is not allocated.
3804  */
3805 void DataArrayDouble::abs() throw(INTERP_KERNEL::Exception)
3806 {
3807   checkAllocated();
3808   double *ptr=getPointer();
3809   std::size_t nbOfElems=getNbOfElems();
3810   std::transform(ptr,ptr+nbOfElems,ptr,std::ptr_fun<double,double>(fabs));
3811   declareAsNew();
3812 }
3813
3814 /*!
3815  * Apply a liner function to a given component of \a this array, so that
3816  * an array element <em>(x)</em> becomes \f$ a * x + b \f$.
3817  *  \param [in] a - the first coefficient of the function.
3818  *  \param [in] b - the second coefficient of the function.
3819  *  \param [in] compoId - the index of component to modify.
3820  *  \throw If \a this is not allocated.
3821  */
3822 void DataArrayDouble::applyLin(double a, double b, int compoId) throw(INTERP_KERNEL::Exception)
3823 {
3824   checkAllocated();
3825   double *ptr=getPointer()+compoId;
3826   int nbOfComp=getNumberOfComponents();
3827   int nbOfTuple=getNumberOfTuples();
3828   for(int i=0;i<nbOfTuple;i++,ptr+=nbOfComp)
3829     *ptr=a*(*ptr)+b;
3830   declareAsNew();
3831 }
3832
3833 /*!
3834  * Apply a liner function to all elements of \a this array, so that
3835  * an element _x_ becomes \f$ a * x + b \f$.
3836  *  \param [in] a - the first coefficient of the function.
3837  *  \param [in] b - the second coefficient of the function.
3838  *  \throw If \a this is not allocated.
3839  */
3840 void DataArrayDouble::applyLin(double a, double b) throw(INTERP_KERNEL::Exception)
3841 {
3842   checkAllocated();
3843   double *ptr=getPointer();
3844   std::size_t nbOfElems=getNbOfElems();
3845   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
3846     *ptr=a*(*ptr)+b;
3847   declareAsNew();
3848 }
3849
3850 /*!
3851  * Modify all elements of \a this array, so that
3852  * an element _x_ becomes \f$ numerator / x \f$.
3853  *  \warning If an exception is thrown because of presence of 0.0 element in \a this 
3854  *           array, all elements processed before detection of the zero element remain
3855  *           modified.
3856  *  \param [in] numerator - the numerator used to modify array elements.
3857  *  \throw If \a this is not allocated.
3858  *  \throw If there is an element equal to 0.0 in \a this array.
3859  */
3860 void DataArrayDouble::applyInv(double numerator) throw(INTERP_KERNEL::Exception)
3861 {
3862   checkAllocated();
3863   double *ptr=getPointer();
3864   std::size_t nbOfElems=getNbOfElems();
3865   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
3866     {
3867       if(std::abs(*ptr)>std::numeric_limits<double>::min())
3868         {
3869           *ptr=numerator/(*ptr);
3870         }
3871       else
3872         {
3873           std::ostringstream oss; oss << "DataArrayDouble::applyInv : presence of null value in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
3874           oss << " !";
3875           throw INTERP_KERNEL::Exception(oss.str().c_str());
3876         }
3877     }
3878   declareAsNew();
3879 }
3880
3881 /*!
3882  * Returns a full copy of \a this array except that sign of all elements is reversed.
3883  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
3884  *          same number of tuples and component as \a this array.
3885  *          The caller is to delete this result array using decrRef() as it is no more
3886  *          needed.
3887  *  \throw If \a this is not allocated.
3888  */
3889 DataArrayDouble *DataArrayDouble::negate() const throw(INTERP_KERNEL::Exception)
3890 {
3891   checkAllocated();
3892   DataArrayDouble *newArr=DataArrayDouble::New();
3893   int nbOfTuples=getNumberOfTuples();
3894   int nbOfComp=getNumberOfComponents();
3895   newArr->alloc(nbOfTuples,nbOfComp);
3896   const double *cptr=getConstPointer();
3897   std::transform(cptr,cptr+nbOfTuples*nbOfComp,newArr->getPointer(),std::negate<double>());
3898   newArr->copyStringInfoFrom(*this);
3899   return newArr;
3900 }
3901
3902 /*!
3903  * Modify all elements of \a this array, so that
3904  * an element _x_ becomes <em> val ^ x </em>. Contrary to DataArrayInt::applyPow
3905  * all values in \a this have to be >= 0 if val is \b not integer.
3906  *  \param [in] val - the value used to apply pow on all array elements.
3907  *  \throw If \a this is not allocated.
3908  *  \warning If an exception is thrown because of presence of 0 element in \a this 
3909  *           array and \a val is \b not integer, all elements processed before detection of the zero element remain
3910  *           modified.
3911  */
3912 void DataArrayDouble::applyPow(double val) throw(INTERP_KERNEL::Exception)
3913 {
3914   checkAllocated();
3915   double *ptr=getPointer();
3916   std::size_t nbOfElems=getNbOfElems();
3917   int val2=(int)val;
3918   bool isInt=((double)val2)==val;
3919   if(!isInt)
3920     {
3921       for(std::size_t i=0;i<nbOfElems;i++,ptr++)
3922         {
3923           if(*ptr>=0)
3924             *ptr=pow(*ptr,val);
3925           else
3926             {
3927               std::ostringstream oss; oss << "DataArrayDouble::applyPow (double) : At elem # " << i << " value is " << *ptr << " ! must be >=0. !";
3928               throw INTERP_KERNEL::Exception(oss.str().c_str());
3929             }
3930         }
3931     }
3932   else
3933     {
3934       for(std::size_t i=0;i<nbOfElems;i++,ptr++)
3935         *ptr=pow(*ptr,val2);
3936     }
3937   declareAsNew();
3938 }
3939
3940 /*!
3941  * Modify all elements of \a this array, so that
3942  * an element _x_ becomes \f$ val ^ x \f$.
3943  *  \param [in] val - the value used to apply pow on all array elements.
3944  *  \throw If \a this is not allocated.
3945  *  \throw If \a val < 0.
3946  *  \warning If an exception is thrown because of presence of 0 element in \a this 
3947  *           array, all elements processed before detection of the zero element remain
3948  *           modified.
3949  */
3950 void DataArrayDouble::applyRPow(double val) throw(INTERP_KERNEL::Exception)
3951 {
3952   checkAllocated();
3953   if(val<0.)
3954     throw INTERP_KERNEL::Exception("DataArrayDouble::applyRPow : the input value has to be >= 0 !");
3955   double *ptr=getPointer();
3956   std::size_t nbOfElems=getNbOfElems();
3957   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
3958     *ptr=pow(val,*ptr);
3959   declareAsNew();
3960 }
3961
3962 /*!
3963  * Returns a new DataArrayDouble created from \a this one by applying \a
3964  * FunctionToEvaluate to every tuple of \a this array. Textual data is not copied.
3965  * For more info see \ref MEDCouplingArrayApplyFunc
3966  *  \param [in] nbOfComp - number of components in the result array.
3967  *  \param [in] func - the \a FunctionToEvaluate declared as 
3968  *              \c bool (*\a func)(\c const \c double *\a pos, \c double *\a res), 
3969  *              where \a pos points to the first component of a tuple of \a this array
3970  *              and \a res points to the first component of a tuple of the result array.
3971  *              Note that length (number of components) of \a pos can differ from
3972  *              that of \a res.
3973  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
3974  *          same number of tuples as \a this array.
3975  *          The caller is to delete this result array using decrRef() as it is no more
3976  *          needed.
3977  *  \throw If \a this is not allocated.
3978  *  \throw If \a func returns \a false.
3979  */
3980 DataArrayDouble *DataArrayDouble::applyFunc(int nbOfComp, FunctionToEvaluate func) const throw(INTERP_KERNEL::Exception)
3981 {
3982   checkAllocated();
3983   DataArrayDouble *newArr=DataArrayDouble::New();
3984   int nbOfTuples=getNumberOfTuples();
3985   int oldNbOfComp=getNumberOfComponents();
3986   newArr->alloc(nbOfTuples,nbOfComp);
3987   const double *ptr=getConstPointer();
3988   double *ptrToFill=newArr->getPointer();
3989   for(int i=0;i<nbOfTuples;i++)
3990     {
3991       if(!func(ptr+i*oldNbOfComp,ptrToFill+i*nbOfComp))
3992         {
3993           std::ostringstream oss; oss << "For tuple # " << i << " with value (";
3994           std::copy(ptr+oldNbOfComp*i,ptr+oldNbOfComp*(i+1),std::ostream_iterator<double>(oss,", "));
3995           oss << ") : Evaluation of function failed !";
3996           newArr->decrRef();
3997           throw INTERP_KERNEL::Exception(oss.str().c_str());
3998         }
3999     }
4000   return newArr;
4001 }
4002
4003 /*!
4004  * Returns a new DataArrayDouble created from \a this one by applying a function to every
4005  * tuple of \a this array. Textual data is not copied.
4006  * For more info see \ref MEDCouplingArrayApplyFunc1.
4007  *  \param [in] nbOfComp - number of components in the result array.
4008  *  \param [in] func - the expression defining how to transform a tuple of \a this array.
4009  *              Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
4010  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
4011  *          same number of tuples as \a this array and \a nbOfComp components.
4012  *          The caller is to delete this result array using decrRef() as it is no more
4013  *          needed.
4014  *  \throw If \a this is not allocated.
4015  *  \throw If computing \a func fails.
4016  */
4017 DataArrayDouble *DataArrayDouble::applyFunc(int nbOfComp, const char *func) const throw(INTERP_KERNEL::Exception)
4018 {
4019   checkAllocated();
4020   INTERP_KERNEL::ExprParser expr(func);
4021   expr.parse();
4022   std::set<std::string> vars;
4023   expr.getTrueSetOfVars(vars);
4024   int oldNbOfComp=getNumberOfComponents();
4025   if((int)vars.size()>oldNbOfComp)
4026     {
4027       std::ostringstream oss; oss << "The field has " << oldNbOfComp << " components and there are ";
4028       oss << vars.size() << " variables : ";
4029       std::copy(vars.begin(),vars.end(),std::ostream_iterator<std::string>(oss," "));
4030       throw INTERP_KERNEL::Exception(oss.str().c_str());
4031     }
4032   std::vector<std::string> varsV(vars.begin(),vars.end());
4033   expr.prepareExprEvaluation(varsV,oldNbOfComp,nbOfComp);
4034   //
4035   DataArrayDouble *newArr=DataArrayDouble::New();
4036   int nbOfTuples=getNumberOfTuples();
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*oldNbOfComp,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+oldNbOfComp*i,ptr+oldNbOfComp*(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 MEDCouplingArrayApplyFunc0.
4062  *  \param [in] func - the expression defining how to transform a tuple of \a this array.
4063  *              Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
4064  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
4065  *          same number of tuples and components as \a this array.
4066  *          The caller is to delete this result array using decrRef() as it is no more
4067  *          needed.
4068  *  \throw If \a this is not allocated.
4069  *  \throw If computing \a func fails.
4070  */
4071 DataArrayDouble *DataArrayDouble::applyFunc(const char *func) const throw(INTERP_KERNEL::Exception)
4072 {
4073   checkAllocated();
4074   INTERP_KERNEL::ExprParser expr(func);
4075   expr.parse();
4076   expr.prepareExprEvaluationVec();
4077   //
4078   DataArrayDouble *newArr=DataArrayDouble::New();
4079   int nbOfTuples=getNumberOfTuples();
4080   int nbOfComp=getNumberOfComponents();
4081   newArr->alloc(nbOfTuples,nbOfComp);
4082   const double *ptr=getConstPointer();
4083   double *ptrToFill=newArr->getPointer();
4084   for(int i=0;i<nbOfTuples;i++)
4085     {
4086       try
4087         {
4088           expr.evaluateExpr(nbOfComp,ptr+i*nbOfComp,ptrToFill+i*nbOfComp);
4089         }
4090       catch(INTERP_KERNEL::Exception& e)
4091         {
4092           std::ostringstream oss; oss << "For tuple # " << i << " with value (";
4093           std::copy(ptr+nbOfComp*i,ptr+nbOfComp*(i+1),std::ostream_iterator<double>(oss,", "));
4094           oss << ") : Evaluation of function failed ! " << e.what();
4095           newArr->decrRef();
4096           throw INTERP_KERNEL::Exception(oss.str().c_str());
4097         }
4098     }
4099   return newArr;
4100 }
4101
4102 /*!
4103  * Returns a new DataArrayDouble created from \a this one by applying a function to every
4104  * tuple of \a this array. Textual data is not copied.
4105  * For more info see \ref MEDCouplingArrayApplyFunc2.
4106  *  \param [in] nbOfComp - number of components in the result array.
4107  *  \param [in] func - the expression defining how to transform a tuple of \a this array.
4108  *              Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
4109  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
4110  *          same number of tuples as \a this array.
4111  *          The caller is to delete this result array using decrRef() as it is no more
4112  *          needed.
4113  *  \throw If \a this is not allocated.
4114  *  \throw If \a func contains vars that are not in \a this->getInfoOnComponent().
4115  *  \throw If computing \a func fails.
4116  */
4117 DataArrayDouble *DataArrayDouble::applyFunc2(int nbOfComp, const char *func) const throw(INTERP_KERNEL::Exception)
4118 {
4119   checkAllocated();
4120   INTERP_KERNEL::ExprParser expr(func);
4121   expr.parse();
4122   std::set<std::string> vars;
4123   expr.getTrueSetOfVars(vars);
4124   int oldNbOfComp=getNumberOfComponents();
4125   if((int)vars.size()>oldNbOfComp)
4126     {
4127       std::ostringstream oss; oss << "The field has " << oldNbOfComp << " components and there are ";
4128       oss << vars.size() << " variables : ";
4129       std::copy(vars.begin(),vars.end(),std::ostream_iterator<std::string>(oss," "));
4130       throw INTERP_KERNEL::Exception(oss.str().c_str());
4131     }
4132   expr.prepareExprEvaluation(getVarsOnComponent(),oldNbOfComp,nbOfComp);
4133   //
4134   DataArrayDouble *newArr=DataArrayDouble::New();
4135   int nbOfTuples=getNumberOfTuples();
4136   newArr->alloc(nbOfTuples,nbOfComp);
4137   const double *ptr=getConstPointer();
4138   double *ptrToFill=newArr->getPointer();
4139   for(int i=0;i<nbOfTuples;i++)
4140     {
4141       try
4142         {
4143           expr.evaluateExpr(nbOfComp,ptr+i*oldNbOfComp,ptrToFill+i*nbOfComp);
4144         }
4145       catch(INTERP_KERNEL::Exception& e)
4146         {
4147           std::ostringstream oss; oss << "For tuple # " << i << " with value (";
4148           std::copy(ptr+oldNbOfComp*i,ptr+oldNbOfComp*(i+1),std::ostream_iterator<double>(oss,", "));
4149           oss << ") : Evaluation of function failed !" << e.what();
4150           newArr->decrRef();
4151           throw INTERP_KERNEL::Exception(oss.str().c_str());
4152         }
4153     }
4154   return newArr;
4155 }
4156
4157 /*!
4158  * Returns a new DataArrayDouble created from \a this one by applying a function to every
4159  * tuple of \a this array. Textual data is not copied.
4160  * For more info see \ref MEDCouplingArrayApplyFunc3.
4161  *  \param [in] nbOfComp - number of components in the result array.
4162  *  \param [in] varsOrder - sequence of vars defining their order.
4163  *  \param [in] func - the expression defining how to transform a tuple of \a this array.
4164  *              Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
4165  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
4166  *          same number of tuples as \a this array.
4167  *          The caller is to delete this result array using decrRef() as it is no more
4168  *          needed.
4169  *  \throw If \a this is not allocated.
4170  *  \throw If \a func contains vars not in \a varsOrder.
4171  *  \throw If computing \a func fails.
4172  */
4173 DataArrayDouble *DataArrayDouble::applyFunc3(int nbOfComp, const std::vector<std::string>& varsOrder, const char *func) const throw(INTERP_KERNEL::Exception)
4174 {
4175   checkAllocated();
4176   INTERP_KERNEL::ExprParser expr(func);
4177   expr.parse();
4178   std::set<std::string> vars;
4179   expr.getTrueSetOfVars(vars);
4180   int oldNbOfComp=getNumberOfComponents();
4181   if((int)vars.size()>oldNbOfComp)
4182     {
4183       std::ostringstream oss; oss << "The field has " << oldNbOfComp << " components and there are ";
4184       oss << vars.size() << " variables : ";
4185       std::copy(vars.begin(),vars.end(),std::ostream_iterator<std::string>(oss," "));
4186       throw INTERP_KERNEL::Exception(oss.str().c_str());
4187     }
4188   expr.prepareExprEvaluation(varsOrder,oldNbOfComp,nbOfComp);
4189   //
4190   DataArrayDouble *newArr=DataArrayDouble::New();
4191   int nbOfTuples=getNumberOfTuples();
4192   newArr->alloc(nbOfTuples,nbOfComp);
4193   const double *ptr=getConstPointer();
4194   double *ptrToFill=newArr->getPointer();
4195   for(int i=0;i<nbOfTuples;i++)
4196     {
4197       try
4198         {
4199           expr.evaluateExpr(nbOfComp,ptr+i*oldNbOfComp,ptrToFill+i*nbOfComp);
4200         }
4201       catch(INTERP_KERNEL::Exception& e)
4202         {
4203           std::ostringstream oss; oss << "For tuple # " << i << " with value (";
4204           std::copy(ptr+oldNbOfComp*i,ptr+oldNbOfComp*(i+1),std::ostream_iterator<double>(oss,", "));
4205           oss << ") : Evaluation of function failed !" << e.what();
4206           newArr->decrRef();
4207           throw INTERP_KERNEL::Exception(oss.str().c_str());
4208         }
4209     }
4210   return newArr;
4211 }
4212
4213 void DataArrayDouble::applyFuncFast32(const char *func) throw(INTERP_KERNEL::Exception)
4214 {
4215   checkAllocated();
4216   INTERP_KERNEL::ExprParser expr(func);
4217   expr.parse();
4218   char *funcStr=expr.compileX86();
4219   MYFUNCPTR funcPtr;
4220   *((void **)&funcPtr)=funcStr;//he he...
4221   //
4222   double *ptr=getPointer();
4223   int nbOfComp=getNumberOfComponents();
4224   int nbOfTuples=getNumberOfTuples();
4225   int nbOfElems=nbOfTuples*nbOfComp;
4226   for(int i=0;i<nbOfElems;i++,ptr++)
4227     *ptr=funcPtr(*ptr);
4228   declareAsNew();
4229 }
4230
4231 void DataArrayDouble::applyFuncFast64(const char *func) throw(INTERP_KERNEL::Exception)
4232 {
4233   checkAllocated();
4234   INTERP_KERNEL::ExprParser expr(func);
4235   expr.parse();
4236   char *funcStr=expr.compileX86_64();
4237   MYFUNCPTR funcPtr;
4238   *((void **)&funcPtr)=funcStr;//he he...
4239   //
4240   double *ptr=getPointer();
4241   int nbOfComp=getNumberOfComponents();
4242   int nbOfTuples=getNumberOfTuples();
4243   int nbOfElems=nbOfTuples*nbOfComp;
4244   for(int i=0;i<nbOfElems;i++,ptr++)
4245     *ptr=funcPtr(*ptr);
4246   declareAsNew();
4247 }
4248
4249 DataArrayDoubleIterator *DataArrayDouble::iterator() throw(INTERP_KERNEL::Exception)
4250 {
4251   return new DataArrayDoubleIterator(this);
4252 }
4253
4254 /*!
4255  * Returns a new DataArrayInt contating indices of tuples of \a this one-dimensional
4256  * array whose values are within a given range. Textual data is not copied.
4257  *  \param [in] vmin - a lowest acceptable value (included).
4258  *  \param [in] vmax - a greatest acceptable value (included).
4259  *  \return DataArrayInt * - the new instance of DataArrayInt.
4260  *          The caller is to delete this result array using decrRef() as it is no more
4261  *          needed.
4262  *  \throw If \a this->getNumberOfComponents() != 1.
4263  *
4264  *  \ref cpp_mcdataarraydouble_getidsinrange "Here is a C++ example".<br>
4265  *  \ref py_mcdataarraydouble_getidsinrange "Here is a Python example".
4266  */
4267 DataArrayInt *DataArrayDouble::getIdsInRange(double vmin, double vmax) const throw(INTERP_KERNEL::Exception)
4268 {
4269   checkAllocated();
4270   if(getNumberOfComponents()!=1)
4271     throw INTERP_KERNEL::Exception("DataArrayDouble::getIdsInRange : this must have exactly one component !");
4272   const double *cptr=getConstPointer();
4273   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(0,1);
4274   int nbOfTuples=getNumberOfTuples();
4275   for(int i=0;i<nbOfTuples;i++,cptr++)
4276     if(*cptr>=vmin && *cptr<=vmax)
4277       ret->pushBackSilent(i);
4278   return ret.retn();
4279 }
4280
4281 /*!
4282  * Returns a new DataArrayDouble by concatenating two given arrays, so that (1) the number
4283  * of tuples in the result array is a sum of the number of tuples of given arrays and (2)
4284  * the number of component in the result array is same as that of each of given arrays.
4285  * Info on components is copied from the first of the given arrays. Number of components
4286  * in the given arrays must be  the same.
4287  *  \param [in] a1 - an array to include in the result array.
4288  *  \param [in] a2 - another array to include in the result array.
4289  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4290  *          The caller is to delete this result array using decrRef() as it is no more
4291  *          needed.
4292  *  \throw If both \a a1 and \a a2 are NULL.
4293  *  \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents().
4294  */
4295 DataArrayDouble *DataArrayDouble::Aggregate(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception)
4296 {
4297   std::vector<const DataArrayDouble *> tmp(2);
4298   tmp[0]=a1; tmp[1]=a2;
4299   return Aggregate(tmp);
4300 }
4301
4302 /*!
4303  * Returns a new DataArrayDouble by concatenating all given arrays, so that (1) the number
4304  * of tuples in the result array is a sum of the number of tuples of given arrays and (2)
4305  * the number of component in the result array is same as that of each of given arrays.
4306  * Info on components is copied from the first of the given arrays. Number of components
4307  * in the given arrays must be  the same.
4308  *  \param [in] arr - a sequence of arrays to include in the result array.
4309  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4310  *          The caller is to delete this result array using decrRef() as it is no more
4311  *          needed.
4312  *  \throw If all arrays within \a arr are NULL.
4313  *  \throw If getNumberOfComponents() of arrays within \a arr.
4314  */
4315 DataArrayDouble *DataArrayDouble::Aggregate(const std::vector<const DataArrayDouble *>& arr) throw(INTERP_KERNEL::Exception)
4316 {
4317   std::vector<const DataArrayDouble *> a;
4318   for(std::vector<const DataArrayDouble *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
4319     if(*it4)
4320       a.push_back(*it4);
4321   if(a.empty())
4322     throw INTERP_KERNEL::Exception("DataArrayDouble::Aggregate : input list must contain at least one NON EMPTY DataArrayDouble !");
4323   std::vector<const DataArrayDouble *>::const_iterator it=a.begin();
4324   int nbOfComp=(*it)->getNumberOfComponents();
4325   int nbt=(*it++)->getNumberOfTuples();
4326   for(int i=1;it!=a.end();it++,i++)
4327     {
4328       if((*it)->getNumberOfComponents()!=nbOfComp)
4329         throw INTERP_KERNEL::Exception("DataArrayDouble::Aggregate : Nb of components mismatch for array aggregation !");
4330       nbt+=(*it)->getNumberOfTuples();
4331     }
4332   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
4333   ret->alloc(nbt,nbOfComp);
4334   double *pt=ret->getPointer();
4335   for(it=a.begin();it!=a.end();it++)
4336     pt=std::copy((*it)->getConstPointer(),(*it)->getConstPointer()+(*it)->getNbOfElems(),pt);
4337   ret->copyStringInfoFrom(*(a[0]));
4338   return ret.retn();
4339 }
4340
4341 /*!
4342  * Returns a new DataArrayDouble by aggregating two given arrays, so that (1) the number
4343  * of components in the result array is a sum of the number of components of given arrays
4344  * and (2) the number of tuples in the result array is same as that of each of given
4345  * arrays. In other words the i-th tuple of result array includes all components of
4346  * i-th tuples of all given arrays.
4347  * Number of tuples in the given arrays must be  the same.
4348  *  \param [in] a1 - an array to include in the result array.
4349  *  \param [in] a2 - another array to include in the result array.
4350  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4351  *          The caller is to delete this result array using decrRef() as it is no more
4352  *          needed.
4353  *  \throw If both \a a1 and \a a2 are NULL.
4354  *  \throw If any given array is not allocated.
4355  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
4356  */
4357 DataArrayDouble *DataArrayDouble::Meld(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception)
4358 {
4359   std::vector<const DataArrayDouble *> arr(2);
4360   arr[0]=a1; arr[1]=a2;
4361   return Meld(arr);
4362 }
4363
4364 /*!
4365  * Returns a new DataArrayDouble by aggregating all given arrays, so that (1) the number
4366  * of components in the result array is a sum of the number of components of given arrays
4367  * and (2) the number of tuples in the result array is same as that of each of given
4368  * arrays. In other words the i-th tuple of result array includes all components of
4369  * i-th tuples of all given arrays.
4370  * Number of tuples in the given arrays must be  the same.
4371  *  \param [in] arr - a sequence of arrays to include in the result array.
4372  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4373  *          The caller is to delete this result array using decrRef() as it is no more
4374  *          needed.
4375  *  \throw If all arrays within \a arr are NULL.
4376  *  \throw If any given array is not allocated.
4377  *  \throw If getNumberOfTuples() of arrays within \a arr is different.
4378  */
4379 DataArrayDouble *DataArrayDouble::Meld(const std::vector<const DataArrayDouble *>& arr) throw(INTERP_KERNEL::Exception)
4380 {
4381   std::vector<const DataArrayDouble *> a;
4382   for(std::vector<const DataArrayDouble *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
4383     if(*it4)
4384       a.push_back(*it4);
4385   if(a.empty())
4386     throw INTERP_KERNEL::Exception("DataArrayDouble::Meld : input list must contain at least one NON EMPTY DataArrayDouble !");
4387   std::vector<const DataArrayDouble *>::const_iterator it;
4388   for(it=a.begin();it!=a.end();it++)
4389     (*it)->checkAllocated();
4390   it=a.begin();
4391   int nbOfTuples=(*it)->getNumberOfTuples();
4392   std::vector<int> nbc(a.size());
4393   std::vector<const double *> pts(a.size());
4394   nbc[0]=(*it)->getNumberOfComponents();
4395   pts[0]=(*it++)->getConstPointer();
4396   for(int i=1;it!=a.end();it++,i++)
4397     {
4398       if(nbOfTuples!=(*it)->getNumberOfTuples())
4399         throw INTERP_KERNEL::Exception("DataArrayDouble::Meld : mismatch of number of tuples !");
4400       nbc[i]=(*it)->getNumberOfComponents();
4401       pts[i]=(*it)->getConstPointer();
4402     }
4403   int totalNbOfComp=std::accumulate(nbc.begin(),nbc.end(),0);
4404   DataArrayDouble *ret=DataArrayDouble::New();
4405   ret->alloc(nbOfTuples,totalNbOfComp);
4406   double *retPtr=ret->getPointer();
4407   for(int i=0;i<nbOfTuples;i++)
4408     for(int j=0;j<(int)a.size();j++)
4409       {
4410         retPtr=std::copy(pts[j],pts[j]+nbc[j],retPtr);
4411         pts[j]+=nbc[j];
4412       }
4413   int k=0;
4414   for(int i=0;i<(int)a.size();i++)
4415     for(int j=0;j<nbc[i];j++,k++)
4416       ret->setInfoOnComponent(k,a[i]->getInfoOnComponent(j).c_str());
4417   return ret;
4418 }
4419
4420 /*!
4421  * Returns a new DataArrayDouble containing a dot product of two given arrays, so that
4422  * the i-th tuple of the result array is a sum of products of j-th components of i-th
4423  * tuples of given arrays (\f$ a_i = \sum_{j=1}^n a1_j * a2_j \f$).
4424  * Info on components and name is copied from the first of the given arrays.
4425  * Number of tuples and components in the given arrays must be the same.
4426  *  \param [in] a1 - a given array.
4427  *  \param [in] a2 - another given array.
4428  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4429  *          The caller is to delete this result array using decrRef() as it is no more
4430  *          needed.
4431  *  \throw If either \a a1 or \a a2 is NULL.
4432  *  \throw If any given array is not allocated.
4433  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
4434  *  \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents()
4435  */
4436 DataArrayDouble *DataArrayDouble::Dot(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception)
4437 {
4438   if(!a1 || !a2)
4439     throw INTERP_KERNEL::Exception("DataArrayDouble::Dot : input DataArrayDouble instance is NULL !");
4440   a1->checkAllocated();
4441   a2->checkAllocated();
4442   int nbOfComp=a1->getNumberOfComponents();
4443   if(nbOfComp!=a2->getNumberOfComponents())
4444     throw INTERP_KERNEL::Exception("Nb of components mismatch for array Dot !");
4445   int nbOfTuple=a1->getNumberOfTuples();
4446   if(nbOfTuple!=a2->getNumberOfTuples())
4447     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Dot !");
4448   DataArrayDouble *ret=DataArrayDouble::New();
4449   ret->alloc(nbOfTuple,1);
4450   double *retPtr=ret->getPointer();
4451   const double *a1Ptr=a1->getConstPointer();
4452   const double *a2Ptr=a2->getConstPointer();
4453   for(int i=0;i<nbOfTuple;i++)
4454     {
4455       double sum=0.;
4456       for(int j=0;j<nbOfComp;j++)
4457         sum+=a1Ptr[i*nbOfComp+j]*a2Ptr[i*nbOfComp+j];
4458       retPtr[i]=sum;
4459     }
4460   ret->setInfoOnComponent(0,a1->getInfoOnComponent(0).c_str());
4461   ret->setName(a1->getName().c_str());
4462   return ret;
4463 }
4464
4465 /*!
4466  * Returns a new DataArrayDouble containing a cross product of two given arrays, so that
4467  * the i-th tuple of the result array contains 3 components of a vector which is a cross
4468  * product of two vectors defined by the i-th tuples of given arrays.
4469  * Info on components is copied from the first of the given arrays.
4470  * Number of tuples in the given arrays must be the same.
4471  * Number of components in the given arrays must be 3.
4472  *  \param [in] a1 - a given array.
4473  *  \param [in] a2 - another given array.
4474  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4475  *          The caller is to delete this result array using decrRef() as it is no more
4476  *          needed.
4477  *  \throw If either \a a1 or \a a2 is NULL.
4478  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
4479  *  \throw If \a a1->getNumberOfComponents() != 3
4480  *  \throw If \a a2->getNumberOfComponents() != 3
4481  */
4482 DataArrayDouble *DataArrayDouble::CrossProduct(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception)
4483 {
4484   if(!a1 || !a2)
4485     throw INTERP_KERNEL::Exception("DataArrayDouble::CrossProduct : input DataArrayDouble instance is NULL !");
4486   int nbOfComp=a1->getNumberOfComponents();
4487   if(nbOfComp!=a2->getNumberOfComponents())
4488     throw INTERP_KERNEL::Exception("Nb of components mismatch for array crossProduct !");
4489   if(nbOfComp!=3)
4490     throw INTERP_KERNEL::Exception("Nb of components must be equal to 3 for array crossProduct !");
4491   int nbOfTuple=a1->getNumberOfTuples();
4492   if(nbOfTuple!=a2->getNumberOfTuples())
4493     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array crossProduct !");
4494   DataArrayDouble *ret=DataArrayDouble::New();
4495   ret->alloc(nbOfTuple,3);
4496   double *retPtr=ret->getPointer();
4497   const double *a1Ptr=a1->getConstPointer();
4498   const double *a2Ptr=a2->getConstPointer();
4499   for(int i=0;i<nbOfTuple;i++)
4500     {
4501       retPtr[3*i]=a1Ptr[3*i+1]*a2Ptr[3*i+2]-a1Ptr[3*i+2]*a2Ptr[3*i+1];
4502       retPtr[3*i+1]=a1Ptr[3*i+2]*a2Ptr[3*i]-a1Ptr[3*i]*a2Ptr[3*i+2];
4503       retPtr[3*i+2]=a1Ptr[3*i]*a2Ptr[3*i+1]-a1Ptr[3*i+1]*a2Ptr[3*i];
4504     }
4505   ret->copyStringInfoFrom(*a1);
4506   return ret;
4507 }
4508
4509 /*!
4510  * Returns a new DataArrayDouble containing maximal values of two given arrays.
4511  * Info on components is copied from the first of the given arrays.
4512  * Number of tuples and components in the given arrays must be the same.
4513  *  \param [in] a1 - an array to compare values with another one.
4514  *  \param [in] a2 - another array to compare values with the first one.
4515  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4516  *          The caller is to delete this result array using decrRef() as it is no more
4517  *          needed.
4518  *  \throw If either \a a1 or \a a2 is NULL.
4519  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
4520  *  \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents()
4521  */
4522 DataArrayDouble *DataArrayDouble::Max(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception)
4523 {
4524   if(!a1 || !a2)
4525     throw INTERP_KERNEL::Exception("DataArrayDouble::Max : input DataArrayDouble instance is NULL !");
4526   int nbOfComp=a1->getNumberOfComponents();
4527   if(nbOfComp!=a2->getNumberOfComponents())
4528     throw INTERP_KERNEL::Exception("Nb of components mismatch for array Max !");
4529   int nbOfTuple=a1->getNumberOfTuples();
4530   if(nbOfTuple!=a2->getNumberOfTuples())
4531     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Max !");
4532   DataArrayDouble *ret=DataArrayDouble::New();
4533   ret->alloc(nbOfTuple,nbOfComp);
4534   double *retPtr=ret->getPointer();
4535   const double *a1Ptr=a1->getConstPointer();
4536   const double *a2Ptr=a2->getConstPointer();
4537   int nbElem=nbOfTuple*nbOfComp;
4538   for(int i=0;i<nbElem;i++)
4539     retPtr[i]=std::max(a1Ptr[i],a2Ptr[i]);
4540   ret->copyStringInfoFrom(*a1);
4541   return ret;
4542 }
4543
4544 /*!
4545  * Returns a new DataArrayDouble containing minimal values of two given arrays.
4546  * Info on components is copied from the first of the given arrays.
4547  * Number of tuples and components in the given arrays must be the same.
4548  *  \param [in] a1 - an array to compare values with another one.
4549  *  \param [in] a2 - another array to compare values with the first one.
4550  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4551  *          The caller is to delete this result array using decrRef() as it is no more
4552  *          needed.
4553  *  \throw If either \a a1 or \a a2 is NULL.
4554  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
4555  *  \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents()
4556  */
4557 DataArrayDouble *DataArrayDouble::Min(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception)
4558 {
4559   if(!a1 || !a2)
4560     throw INTERP_KERNEL::Exception("DataArrayDouble::Min : input DataArrayDouble instance is NULL !");
4561   int nbOfComp=a1->getNumberOfComponents();
4562   if(nbOfComp!=a2->getNumberOfComponents())
4563     throw INTERP_KERNEL::Exception("Nb of components mismatch for array min !");
4564   int nbOfTuple=a1->getNumberOfTuples();
4565   if(nbOfTuple!=a2->getNumberOfTuples())
4566     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array min !");
4567   DataArrayDouble *ret=DataArrayDouble::New();
4568   ret->alloc(nbOfTuple,nbOfComp);
4569   double *retPtr=ret->getPointer();
4570   const double *a1Ptr=a1->getConstPointer();
4571   const double *a2Ptr=a2->getConstPointer();
4572   int nbElem=nbOfTuple*nbOfComp;
4573   for(int i=0;i<nbElem;i++)
4574     retPtr[i]=std::min(a1Ptr[i],a2Ptr[i]);
4575   ret->copyStringInfoFrom(*a1);
4576   return ret;
4577 }
4578
4579 /*!
4580  * Returns a new DataArrayDouble that is a sum of two given arrays. There are 3
4581  * valid cases.
4582  * 1.  The arrays have same number of tuples and components. Then each value of
4583  *   the result array (_a_) is a sum of the corresponding values of \a a1 and \a a2,
4584  *   i.e.: _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ i, j ].
4585  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
4586  *   component. Then
4587  *   _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ i, 0 ].
4588  * 3.  The arrays have same number of components and one array, say _a2_, has one
4589  *   tuple. Then
4590  *   _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ 0, j ].
4591  *
4592  * Info on components is copied either from the first array (in the first case) or from
4593  * the array with maximal number of elements (getNbOfElems()).
4594  *  \param [in] a1 - an array to sum up.
4595  *  \param [in] a2 - another array to sum up.
4596  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4597  *          The caller is to delete this result array using decrRef() as it is no more
4598  *          needed.
4599  *  \throw If either \a a1 or \a a2 is NULL.
4600  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
4601  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
4602  *         none of them has number of tuples or components equal to 1.
4603  */
4604 DataArrayDouble *DataArrayDouble::Add(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception)
4605 {
4606   if(!a1 || !a2)
4607     throw INTERP_KERNEL::Exception("DataArrayDouble::Add : input DataArrayDouble instance is NULL !");
4608   int nbOfTuple=a1->getNumberOfTuples();
4609   int nbOfTuple2=a2->getNumberOfTuples();
4610   int nbOfComp=a1->getNumberOfComponents();
4611   int nbOfComp2=a2->getNumberOfComponents();
4612   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=0;
4613   if(nbOfTuple==nbOfTuple2)
4614     {
4615       if(nbOfComp==nbOfComp2)
4616         {
4617           ret=DataArrayDouble::New();
4618           ret->alloc(nbOfTuple,nbOfComp);
4619           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::plus<double>());
4620           ret->copyStringInfoFrom(*a1);
4621         }
4622       else
4623         {
4624           int nbOfCompMin,nbOfCompMax;
4625           const DataArrayDouble *aMin, *aMax;
4626           if(nbOfComp>nbOfComp2)
4627             {
4628               nbOfCompMin=nbOfComp2; nbOfCompMax=nbOfComp;
4629               aMin=a2; aMax=a1;
4630             }
4631           else
4632             {
4633               nbOfCompMin=nbOfComp; nbOfCompMax=nbOfComp2;
4634               aMin=a1; aMax=a2;
4635             }
4636           if(nbOfCompMin==1)
4637             {
4638               ret=DataArrayDouble::New();
4639               ret->alloc(nbOfTuple,nbOfCompMax);
4640               const double *aMinPtr=aMin->getConstPointer();
4641               const double *aMaxPtr=aMax->getConstPointer();
4642               double *res=ret->getPointer();
4643               for(int i=0;i<nbOfTuple;i++)
4644                 res=std::transform(aMaxPtr+i*nbOfCompMax,aMaxPtr+(i+1)*nbOfCompMax,res,std::bind2nd(std::plus<double>(),aMinPtr[i]));
4645               ret->copyStringInfoFrom(*aMax);
4646             }
4647           else
4648             throw INTERP_KERNEL::Exception("Nb of components mismatch for array Add !");
4649         }
4650     }
4651   else if((nbOfTuple==1 && nbOfTuple2>1) || (nbOfTuple>1 && nbOfTuple2==1))
4652     {
4653       if(nbOfComp==nbOfComp2)
4654         {
4655           int nbOfTupleMax=std::max(nbOfTuple,nbOfTuple2);
4656           const DataArrayDouble *aMin=nbOfTuple>nbOfTuple2?a2:a1;
4657           const DataArrayDouble *aMax=nbOfTuple>nbOfTuple2?a1:a2;
4658           const double *aMinPtr=aMin->getConstPointer(),*aMaxPtr=aMax->getConstPointer();
4659           ret=DataArrayDouble::New();
4660           ret->alloc(nbOfTupleMax,nbOfComp);
4661           double *res=ret->getPointer();
4662           for(int i=0;i<nbOfTupleMax;i++)
4663             res=std::transform(aMaxPtr+i*nbOfComp,aMaxPtr+(i+1)*nbOfComp,aMinPtr,res,std::plus<double>());
4664           ret->copyStringInfoFrom(*aMax);
4665         }
4666       else
4667         throw INTERP_KERNEL::Exception("Nb of components mismatch for array Add !");
4668     }
4669   else
4670     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Add !");
4671   return ret.retn();
4672 }
4673
4674 /*!
4675  * Adds values of another DataArrayDouble to values of \a this one. There are 3
4676  * valid cases.
4677  * 1.  The arrays have same number of tuples and components. Then each value of
4678  *   \a other array is added to the corresponding value of \a this array, i.e.:
4679  *   _a_ [ i, j ] += _other_ [ i, j ].
4680  * 2.  The arrays have same number of tuples and \a other array has one component. Then
4681  *   _a_ [ i, j ] += _other_ [ i, 0 ].
4682  * 3.  The arrays have same number of components and \a other array has one tuple. Then
4683  *   _a_ [ i, j ] += _a2_ [ 0, j ].
4684  *
4685  *  \param [in] other - an array to add to \a this one.
4686  *  \throw If \a other is NULL.
4687  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
4688  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
4689  *         \a other has number of both tuples and components not equal to 1.
4690  */
4691 void DataArrayDouble::addEqual(const DataArrayDouble *other) throw(INTERP_KERNEL::Exception)
4692 {
4693   if(!other)
4694     throw INTERP_KERNEL::Exception("DataArrayDouble::addEqual : input DataArrayDouble instance is NULL !");
4695   const char *msg="Nb of tuples mismatch for DataArrayDouble::addEqual  !";
4696   checkAllocated();
4697   other->checkAllocated();
4698   int nbOfTuple=getNumberOfTuples();
4699   int nbOfTuple2=other->getNumberOfTuples();
4700   int nbOfComp=getNumberOfComponents();
4701   int nbOfComp2=other->getNumberOfComponents();
4702   if(nbOfTuple==nbOfTuple2)
4703     {
4704       if(nbOfComp==nbOfComp2)
4705         {
4706           std::transform(begin(),end(),other->begin(),getPointer(),std::plus<double>());
4707         }
4708       else if(nbOfComp2==1)
4709         {
4710           double *ptr=getPointer();
4711           const double *ptrc=other->getConstPointer();
4712           for(int i=0;i<nbOfTuple;i++)
4713             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::plus<double>(),*ptrc++));
4714         }
4715       else
4716         throw INTERP_KERNEL::Exception(msg);
4717     }
4718   else if(nbOfTuple2==1)
4719     {
4720       if(nbOfComp2==nbOfComp)
4721         {
4722           double *ptr=getPointer();
4723           const double *ptrc=other->getConstPointer();
4724           for(int i=0;i<nbOfTuple;i++)
4725             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::plus<double>());
4726         }
4727       else
4728         throw INTERP_KERNEL::Exception(msg);
4729     }
4730   else
4731     throw INTERP_KERNEL::Exception(msg);
4732   declareAsNew();
4733 }
4734
4735 /*!
4736  * Returns a new DataArrayDouble that is a subtraction of two given arrays. There are 3
4737  * valid cases.
4738  * 1.  The arrays have same number of tuples and components. Then each value of
4739  *   the result array (_a_) is a subtraction of the corresponding values of \a a1 and
4740  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ i, j ].
4741  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
4742  *   component. Then
4743  *   _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ i, 0 ].
4744  * 3.  The arrays have same number of components and one array, say _a2_, has one
4745  *   tuple. Then
4746  *   _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ 0, j ].
4747  *
4748  * Info on components is copied either from the first array (in the first case) or from
4749  * the array with maximal number of elements (getNbOfElems()).
4750  *  \param [in] a1 - an array to subtract from.
4751  *  \param [in] a2 - an array to subtract.
4752  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4753  *          The caller is to delete this result array using decrRef() as it is no more
4754  *          needed.
4755  *  \throw If either \a a1 or \a a2 is NULL.
4756  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
4757  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
4758  *         none of them has number of tuples or components equal to 1.
4759  */
4760 DataArrayDouble *DataArrayDouble::Substract(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception)
4761 {
4762   if(!a1 || !a2)
4763     throw INTERP_KERNEL::Exception("DataArrayDouble::Substract : input DataArrayDouble instance is NULL !");
4764   int nbOfTuple1=a1->getNumberOfTuples();
4765   int nbOfTuple2=a2->getNumberOfTuples();
4766   int nbOfComp1=a1->getNumberOfComponents();
4767   int nbOfComp2=a2->getNumberOfComponents();
4768   if(nbOfTuple2==nbOfTuple1)
4769     {
4770       if(nbOfComp1==nbOfComp2)
4771         {
4772           MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
4773           ret->alloc(nbOfTuple2,nbOfComp1);
4774           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::minus<double>());
4775           ret->copyStringInfoFrom(*a1);
4776           return ret.retn();
4777         }
4778       else if(nbOfComp2==1)
4779         {
4780           MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
4781           ret->alloc(nbOfTuple1,nbOfComp1);
4782           const double *a2Ptr=a2->getConstPointer();
4783           const double *a1Ptr=a1->getConstPointer();
4784           double *res=ret->getPointer();
4785           for(int i=0;i<nbOfTuple1;i++)
4786             res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::minus<double>(),a2Ptr[i]));
4787           ret->copyStringInfoFrom(*a1);
4788           return ret.retn();
4789         }
4790       else
4791         {
4792           a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Substract !");
4793           return 0;
4794         }
4795     }
4796   else if(nbOfTuple2==1)
4797     {
4798       a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Substract !");
4799       MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
4800       ret->alloc(nbOfTuple1,nbOfComp1);
4801       const double *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
4802       double *pt=ret->getPointer();
4803       for(int i=0;i<nbOfTuple1;i++)
4804         pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::minus<double>());
4805       ret->copyStringInfoFrom(*a1);
4806       return ret.retn();
4807     }
4808   else
4809     {
4810       a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Substract !");//will always throw an exception
4811       return 0;
4812     }
4813 }
4814
4815 /*!
4816  * Subtract values of another DataArrayDouble from values of \a this one. There are 3
4817  * valid cases.
4818  * 1.  The arrays have same number of tuples and components. Then each value of
4819  *   \a other array is subtracted from the corresponding value of \a this array, i.e.:
4820  *   _a_ [ i, j ] -= _other_ [ i, j ].
4821  * 2.  The arrays have same number of tuples and \a other array has one component. Then
4822  *   _a_ [ i, j ] -= _other_ [ i, 0 ].
4823  * 3.  The arrays have same number of components and \a other array has one tuple. Then
4824  *   _a_ [ i, j ] -= _a2_ [ 0, j ].
4825  *
4826  *  \param [in] other - an array to subtract from \a this one.
4827  *  \throw If \a other is NULL.
4828  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
4829  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
4830  *         \a other has number of both tuples and components not equal to 1.
4831  */
4832 void DataArrayDouble::substractEqual(const DataArrayDouble *other) throw(INTERP_KERNEL::Exception)
4833 {
4834   if(!other)
4835     throw INTERP_KERNEL::Exception("DataArrayDouble::substractEqual : input DataArrayDouble instance is NULL !");
4836   const char *msg="Nb of tuples mismatch for DataArrayDouble::substractEqual  !";
4837   checkAllocated();
4838   other->checkAllocated();
4839   int nbOfTuple=getNumberOfTuples();
4840   int nbOfTuple2=other->getNumberOfTuples();
4841   int nbOfComp=getNumberOfComponents();
4842   int nbOfComp2=other->getNumberOfComponents();
4843   if(nbOfTuple==nbOfTuple2)
4844     {
4845       if(nbOfComp==nbOfComp2)
4846         {
4847           std::transform(begin(),end(),other->begin(),getPointer(),std::minus<double>());
4848         }
4849       else if(nbOfComp2==1)
4850         {
4851           double *ptr=getPointer();
4852           const double *ptrc=other->getConstPointer();
4853           for(int i=0;i<nbOfTuple;i++)
4854             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::minus<double>(),*ptrc++)); 
4855         }
4856       else
4857         throw INTERP_KERNEL::Exception(msg);
4858     }
4859   else if(nbOfTuple2==1)
4860     {
4861       if(nbOfComp2==nbOfComp)
4862         {
4863           double *ptr=getPointer();
4864           const double *ptrc=other->getConstPointer();
4865           for(int i=0;i<nbOfTuple;i++)
4866             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::minus<double>());
4867         }
4868       else
4869         throw INTERP_KERNEL::Exception(msg);
4870     }
4871   else
4872     throw INTERP_KERNEL::Exception(msg);
4873   declareAsNew();
4874 }
4875
4876 /*!
4877  * Returns a new DataArrayDouble that is a product of two given arrays. There are 3
4878  * valid cases.
4879  * 1.  The arrays have same number of tuples and components. Then each value of
4880  *   the result array (_a_) is a product of the corresponding values of \a a1 and
4881  *   \a a2, i.e. _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ i, j ].
4882  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
4883  *   component. Then
4884  *   _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ i, 0 ].
4885  * 3.  The arrays have same number of components and one array, say _a2_, has one
4886  *   tuple. Then
4887  *   _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ 0, j ].
4888  *
4889  * Info on components is copied either from the first array (in the first case) or from
4890  * the array with maximal number of elements (getNbOfElems()).
4891  *  \param [in] a1 - a factor array.
4892  *  \param [in] a2 - another factor array.
4893  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4894  *          The caller is to delete this result array using decrRef() as it is no more
4895  *          needed.
4896  *  \throw If either \a a1 or \a a2 is NULL.
4897  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
4898  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
4899  *         none of them has number of tuples or components equal to 1.
4900  */
4901 DataArrayDouble *DataArrayDouble::Multiply(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception)
4902 {
4903   if(!a1 || !a2)
4904     throw INTERP_KERNEL::Exception("DataArrayDouble::Multiply : input DataArrayDouble instance is NULL !");
4905   int nbOfTuple=a1->getNumberOfTuples();
4906   int nbOfTuple2=a2->getNumberOfTuples();
4907   int nbOfComp=a1->getNumberOfComponents();
4908   int nbOfComp2=a2->getNumberOfComponents();
4909   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=0;
4910   if(nbOfTuple==nbOfTuple2)
4911     {
4912       if(nbOfComp==nbOfComp2)
4913         {
4914           ret=DataArrayDouble::New();
4915           ret->alloc(nbOfTuple,nbOfComp);
4916           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::multiplies<double>());
4917           ret->copyStringInfoFrom(*a1);
4918         }
4919       else
4920         {
4921           int nbOfCompMin,nbOfCompMax;
4922           const DataArrayDouble *aMin, *aMax;
4923           if(nbOfComp>nbOfComp2)
4924             {
4925               nbOfCompMin=nbOfComp2; nbOfCompMax=nbOfComp;
4926               aMin=a2; aMax=a1;
4927             }
4928           else
4929             {
4930               nbOfCompMin=nbOfComp; nbOfCompMax=nbOfComp2;
4931               aMin=a1; aMax=a2;
4932             }
4933           if(nbOfCompMin==1)
4934             {
4935               ret=DataArrayDouble::New();
4936               ret->alloc(nbOfTuple,nbOfCompMax);
4937               const double *aMinPtr=aMin->getConstPointer();
4938               const double *aMaxPtr=aMax->getConstPointer();
4939               double *res=ret->getPointer();
4940               for(int i=0;i<nbOfTuple;i++)
4941                 res=std::transform(aMaxPtr+i*nbOfCompMax,aMaxPtr+(i+1)*nbOfCompMax,res,std::bind2nd(std::multiplies<double>(),aMinPtr[i]));
4942               ret->copyStringInfoFrom(*aMax);
4943             }
4944           else
4945             throw INTERP_KERNEL::Exception("Nb of components mismatch for array Multiply !");
4946         }
4947     }
4948   else if((nbOfTuple==1 && nbOfTuple2>1) || (nbOfTuple>1 && nbOfTuple2==1))
4949     {
4950       if(nbOfComp==nbOfComp2)
4951         {
4952           int nbOfTupleMax=std::max(nbOfTuple,nbOfTuple2);
4953           const DataArrayDouble *aMin=nbOfTuple>nbOfTuple2?a2:a1;
4954           const DataArrayDouble *aMax=nbOfTuple>nbOfTuple2?a1:a2;
4955           const double *aMinPtr=aMin->getConstPointer(),*aMaxPtr=aMax->getConstPointer();
4956           ret=DataArrayDouble::New();
4957           ret->alloc(nbOfTupleMax,nbOfComp);
4958           double *res=ret->getPointer();
4959           for(int i=0;i<nbOfTupleMax;i++)
4960             res=std::transform(aMaxPtr+i*nbOfComp,aMaxPtr+(i+1)*nbOfComp,aMinPtr,res,std::multiplies<double>());
4961           ret->copyStringInfoFrom(*aMax);
4962         }
4963       else
4964         throw INTERP_KERNEL::Exception("Nb of components mismatch for array Multiply !");
4965     }
4966   else
4967     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Multiply !");
4968   return ret.retn();
4969 }
4970
4971 /*!
4972  * Multiply values of another DataArrayDouble to values of \a this one. There are 3
4973  * valid cases.
4974  * 1.  The arrays have same number of tuples and components. Then each value of
4975  *   \a other array is multiplied to the corresponding value of \a this array, i.e.
4976  *   _this_ [ i, j ] *= _other_ [ i, j ].
4977  * 2.  The arrays have same number of tuples and \a other array has one component. Then
4978  *   _this_ [ i, j ] *= _other_ [ i, 0 ].
4979  * 3.  The arrays have same number of components and \a other array has one tuple. Then
4980  *   _this_ [ i, j ] *= _a2_ [ 0, j ].
4981  *
4982  *  \param [in] other - an array to multiply to \a this one.
4983  *  \throw If \a other is NULL.
4984  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
4985  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
4986  *         \a other has number of both tuples and components not equal to 1.
4987  */
4988 void DataArrayDouble::multiplyEqual(const DataArrayDouble *other) throw(INTERP_KERNEL::Exception)
4989 {
4990   if(!other)
4991     throw INTERP_KERNEL::Exception("DataArrayDouble::multiplyEqual : input DataArrayDouble instance is NULL !");
4992   const char *msg="Nb of tuples mismatch for DataArrayDouble::multiplyEqual !";
4993   checkAllocated();
4994   other->checkAllocated();
4995   int nbOfTuple=getNumberOfTuples();
4996   int nbOfTuple2=other->getNumberOfTuples();
4997   int nbOfComp=getNumberOfComponents();
4998   int nbOfComp2=other->getNumberOfComponents();
4999   if(nbOfTuple==nbOfTuple2)
5000     {
5001       if(nbOfComp==nbOfComp2)
5002         {
5003           std::transform(begin(),end(),other->begin(),getPointer(),std::multiplies<double>());
5004         }
5005       else if(nbOfComp2==1)
5006         {
5007           double *ptr=getPointer();
5008           const double *ptrc=other->getConstPointer();
5009           for(int i=0;i<nbOfTuple;i++)
5010             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::multiplies<double>(),*ptrc++));
5011         }
5012       else
5013         throw INTERP_KERNEL::Exception(msg);
5014     }
5015   else if(nbOfTuple2==1)
5016     {
5017       if(nbOfComp2==nbOfComp)
5018         {
5019           double *ptr=getPointer();
5020           const double *ptrc=other->getConstPointer();
5021           for(int i=0;i<nbOfTuple;i++)
5022             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::multiplies<double>());
5023         }
5024       else
5025         throw INTERP_KERNEL::Exception(msg);
5026     }
5027   else
5028     throw INTERP_KERNEL::Exception(msg);
5029   declareAsNew();
5030 }
5031
5032 /*!
5033  * Returns a new DataArrayDouble that is a division of two given arrays. There are 3
5034  * valid cases.
5035  * 1.  The arrays have same number of tuples and components. Then each value of
5036  *   the result array (_a_) is a division of the corresponding values of \a a1 and
5037  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ i, j ].
5038  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
5039  *   component. Then
5040  *   _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ i, 0 ].
5041  * 3.  The arrays have same number of components and one array, say _a2_, has one
5042  *   tuple. Then
5043  *   _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ 0, j ].
5044  *
5045  * Info on components is copied either from the first array (in the first case) or from
5046  * the array with maximal number of elements (getNbOfElems()).
5047  *  \warning No check of division by zero is performed!
5048  *  \param [in] a1 - a numerator array.
5049  *  \param [in] a2 - a denominator array.
5050  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
5051  *          The caller is to delete this result array using decrRef() as it is no more
5052  *          needed.
5053  *  \throw If either \a a1 or \a a2 is NULL.
5054  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
5055  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
5056  *         none of them has number of tuples or components equal to 1.
5057  */
5058 DataArrayDouble *DataArrayDouble::Divide(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception)
5059 {
5060   if(!a1 || !a2)
5061     throw INTERP_KERNEL::Exception("DataArrayDouble::Divide : input DataArrayDouble instance is NULL !");
5062   int nbOfTuple1=a1->getNumberOfTuples();
5063   int nbOfTuple2=a2->getNumberOfTuples();
5064   int nbOfComp1=a1->getNumberOfComponents();
5065   int nbOfComp2=a2->getNumberOfComponents();
5066   if(nbOfTuple2==nbOfTuple1)
5067     {
5068       if(nbOfComp1==nbOfComp2)
5069         {
5070           MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
5071           ret->alloc(nbOfTuple2,nbOfComp1);
5072           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::divides<double>());
5073           ret->copyStringInfoFrom(*a1);
5074           return ret.retn();
5075         }
5076       else if(nbOfComp2==1)
5077         {
5078           MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
5079           ret->alloc(nbOfTuple1,nbOfComp1);
5080           const double *a2Ptr=a2->getConstPointer();
5081           const double *a1Ptr=a1->getConstPointer();
5082           double *res=ret->getPointer();
5083           for(int i=0;i<nbOfTuple1;i++)
5084             res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::divides<double>(),a2Ptr[i]));
5085           ret->copyStringInfoFrom(*a1);
5086           return ret.retn();
5087         }
5088       else
5089         {
5090           a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Divide !");
5091           return 0;
5092         }
5093     }
5094   else if(nbOfTuple2==1)
5095     {
5096       a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Divide !");
5097       MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
5098       ret->alloc(nbOfTuple1,nbOfComp1);
5099       const double *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
5100       double *pt=ret->getPointer();
5101       for(int i=0;i<nbOfTuple1;i++)
5102         pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::divides<double>());
5103       ret->copyStringInfoFrom(*a1);
5104       return ret.retn();
5105     }
5106   else
5107     {
5108       a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Divide !");//will always throw an exception
5109       return 0;
5110     }
5111 }
5112
5113 /*!
5114  * Divide values of \a this array by values of another DataArrayDouble. There are 3
5115  * valid cases.
5116  * 1.  The arrays have same number of tuples and components. Then each value of
5117  *    \a this array is divided by the corresponding value of \a other one, i.e.:
5118  *   _a_ [ i, j ] /= _other_ [ i, j ].
5119  * 2.  The arrays have same number of tuples and \a other array has one component. Then
5120  *   _a_ [ i, j ] /= _other_ [ i, 0 ].
5121  * 3.  The arrays have same number of components and \a other array has one tuple. Then
5122  *   _a_ [ i, j ] /= _a2_ [ 0, j ].
5123  *
5124  *  \warning No check of division by zero is performed!
5125  *  \param [in] other - an array to divide \a this one by.
5126  *  \throw If \a other is NULL.
5127  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
5128  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
5129  *         \a other has number of both tuples and components not equal to 1.
5130  */
5131 void DataArrayDouble::divideEqual(const DataArrayDouble *other) throw(INTERP_KERNEL::Exception)
5132 {
5133   if(!other)
5134     throw INTERP_KERNEL::Exception("DataArrayDouble::divideEqual : input DataArrayDouble instance is NULL !");
5135   const char *msg="Nb of tuples mismatch for DataArrayDouble::divideEqual !";
5136   checkAllocated();
5137   other->checkAllocated();
5138   int nbOfTuple=getNumberOfTuples();
5139   int nbOfTuple2=other->getNumberOfTuples();
5140   int nbOfComp=getNumberOfComponents();
5141   int nbOfComp2=other->getNumberOfComponents();
5142   if(nbOfTuple==nbOfTuple2)
5143     {
5144       if(nbOfComp==nbOfComp2)
5145         {
5146           std::transform(begin(),end(),other->begin(),getPointer(),std::divides<double>());
5147         }
5148       else if(nbOfComp2==1)
5149         {
5150           double *ptr=getPointer();
5151           const double *ptrc=other->getConstPointer();
5152           for(int i=0;i<nbOfTuple;i++)
5153             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::divides<double>(),*ptrc++));
5154         }
5155       else
5156         throw INTERP_KERNEL::Exception(msg);
5157     }
5158   else if(nbOfTuple2==1)
5159     {
5160       if(nbOfComp2==nbOfComp)
5161         {
5162           double *ptr=getPointer();
5163           const double *ptrc=other->getConstPointer();
5164           for(int i=0;i<nbOfTuple;i++)
5165             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::divides<double>());
5166         }
5167       else
5168         throw INTERP_KERNEL::Exception(msg);
5169     }
5170   else
5171     throw INTERP_KERNEL::Exception(msg);
5172   declareAsNew();
5173 }
5174
5175 /*!
5176  * Returns a new DataArrayDouble that is the result of pow of two given arrays. There are 3
5177  * valid cases.
5178  *
5179  *  \param [in] a1 - an array to pow up.
5180  *  \param [in] a2 - another array to sum up.
5181  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
5182  *          The caller is to delete this result array using decrRef() as it is no more
5183  *          needed.
5184  *  \throw If either \a a1 or \a a2 is NULL.
5185  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
5186  *  \throw If \a a1->getNumberOfComponents() != 1 or \a a2->getNumberOfComponents() != 1.
5187  *  \throw If there is a negative value in \a a1.
5188  */
5189 DataArrayDouble *DataArrayDouble::Pow(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception)
5190 {
5191   if(!a1 || !a2)
5192     throw INTERP_KERNEL::Exception("DataArrayDouble::Pow : at least one of input instances is null !");
5193   int nbOfTuple=a1->getNumberOfTuples();
5194   int nbOfTuple2=a2->getNumberOfTuples();
5195   int nbOfComp=a1->getNumberOfComponents();
5196   int nbOfComp2=a2->getNumberOfComponents();
5197   if(nbOfTuple!=nbOfTuple2)
5198     throw INTERP_KERNEL::Exception("DataArrayDouble::Pow : number of tuples mismatches !");
5199   if(nbOfComp!=1 || nbOfComp2!=1)
5200     throw INTERP_KERNEL::Exception("DataArrayDouble::Pow : number of components of both arrays must be equal to 1 !");
5201   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New(); ret->alloc(nbOfTuple,1);
5202   const double *ptr1(a1->begin()),*ptr2(a2->begin());
5203   double *ptr=ret->getPointer();
5204   for(int i=0;i<nbOfTuple;i++,ptr1++,ptr2++,ptr++)
5205     {
5206       if(*ptr1>=0)
5207         {
5208           *ptr=pow(*ptr1,*ptr2);
5209         }
5210       else
5211         {
5212           std::ostringstream oss; oss << "DataArrayDouble::Pow : on tuple #" << i << " of a1 value is < 0 (" << *ptr1 << ") !";
5213           throw INTERP_KERNEL::Exception(oss.str().c_str());
5214         }
5215     }
5216   return ret.retn();
5217 }
5218
5219 /*!
5220  * Apply pow on values of another DataArrayDouble to values of \a this one.
5221  *
5222  *  \param [in] other - an array to pow to \a this one.
5223  *  \throw If \a other is NULL.
5224  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples()
5225  *  \throw If \a this->getNumberOfComponents() != 1 or \a other->getNumberOfComponents() != 1
5226  *  \throw If there is a negative value in \a this.
5227  */
5228 void DataArrayDouble::powEqual(const DataArrayDouble *other) throw(INTERP_KERNEL::Exception)
5229 {
5230   if(!other)
5231     throw INTERP_KERNEL::Exception("DataArrayDouble::powEqual : input instance is null !");
5232   int nbOfTuple=getNumberOfTuples();
5233   int nbOfTuple2=other->getNumberOfTuples();
5234   int nbOfComp=getNumberOfComponents();
5235   int nbOfComp2=other->getNumberOfComponents();
5236   if(nbOfTuple!=nbOfTuple2)
5237     throw INTERP_KERNEL::Exception("DataArrayDouble::powEqual : number of tuples mismatches !");
5238   if(nbOfComp!=1 || nbOfComp2!=1)
5239     throw INTERP_KERNEL::Exception("DataArrayDouble::powEqual : number of components of both arrays must be equal to 1 !");
5240   double *ptr=getPointer();
5241   const double *ptrc=other->begin();
5242   for(int i=0;i<nbOfTuple;i++,ptrc++,ptr++)
5243     {
5244       if(*ptr>=0)
5245         *ptr=pow(*ptr,*ptrc);
5246       else
5247         {
5248           std::ostringstream oss; oss << "DataArrayDouble::powEqual : on tuple #" << i << " of this value is < 0 (" << *ptr << ") !";
5249           throw INTERP_KERNEL::Exception(oss.str().c_str());
5250         }
5251     }
5252   declareAsNew();
5253 }
5254
5255 /*!
5256  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
5257  * Server side.
5258  */
5259 void DataArrayDouble::getTinySerializationIntInformation(std::vector<int>& tinyInfo) const
5260 {
5261   tinyInfo.resize(2);
5262   if(isAllocated())
5263     {
5264       tinyInfo[0]=getNumberOfTuples();
5265       tinyInfo[1]=getNumberOfComponents();
5266     }
5267   else
5268     {
5269       tinyInfo[0]=-1;
5270       tinyInfo[1]=-1;
5271     }
5272 }
5273
5274 /*!
5275  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
5276  * Server side.
5277  */
5278 void DataArrayDouble::getTinySerializationStrInformation(std::vector<std::string>& tinyInfo) const
5279 {
5280   if(isAllocated())
5281     {
5282       int nbOfCompo=getNumberOfComponents();
5283       tinyInfo.resize(nbOfCompo+1);
5284       tinyInfo[0]=getName();
5285       for(int i=0;i<nbOfCompo;i++)
5286         tinyInfo[i+1]=getInfoOnComponent(i);
5287     }
5288   else
5289     {
5290       tinyInfo.resize(1);
5291       tinyInfo[0]=getName();
5292     }
5293 }
5294
5295 /*!
5296  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
5297  * This method returns if a feeding is needed.
5298  */
5299 bool DataArrayDouble::resizeForUnserialization(const std::vector<int>& tinyInfoI)
5300 {
5301   int nbOfTuple=tinyInfoI[0];
5302   int nbOfComp=tinyInfoI[1];
5303   if(nbOfTuple!=-1 || nbOfComp!=-1)
5304     {
5305       alloc(nbOfTuple,nbOfComp);
5306       return true;
5307     }
5308   return false;
5309 }
5310
5311 /*!
5312  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
5313  */
5314 void DataArrayDouble::finishUnserialization(const std::vector<int>& tinyInfoI, const std::vector<std::string>& tinyInfoS)
5315 {
5316   setName(tinyInfoS[0].c_str());
5317   if(isAllocated())
5318     {
5319       int nbOfCompo=getNumberOfComponents();
5320       for(int i=0;i<nbOfCompo;i++)
5321         setInfoOnComponent(i,tinyInfoS[i+1].c_str());
5322     }
5323 }
5324
5325 DataArrayDoubleIterator::DataArrayDoubleIterator(DataArrayDouble *da):_da(da),_tuple_id(0),_nb_comp(0),_nb_tuple(0)
5326 {
5327   if(_da)
5328     {
5329       _da->incrRef();
5330       if(_da->isAllocated())
5331         {
5332           _nb_comp=da->getNumberOfComponents();
5333           _nb_tuple=da->getNumberOfTuples();
5334           _pt=da->getPointer();
5335         }
5336     }
5337 }
5338
5339 DataArrayDoubleIterator::~DataArrayDoubleIterator()
5340 {
5341   if(_da)
5342     _da->decrRef();
5343 }
5344
5345 DataArrayDoubleTuple *DataArrayDoubleIterator::nextt() throw(INTERP_KERNEL::Exception)
5346 {
5347   if(_tuple_id<_nb_tuple)
5348     {
5349       _tuple_id++;
5350       DataArrayDoubleTuple *ret=new DataArrayDoubleTuple(_pt,_nb_comp);
5351       _pt+=_nb_comp;
5352       return ret;
5353     }
5354   else
5355     return 0;
5356 }
5357
5358 DataArrayDoubleTuple::DataArrayDoubleTuple(double *pt, int nbOfComp):_pt(pt),_nb_of_compo(nbOfComp)
5359 {
5360 }
5361
5362
5363 std::string DataArrayDoubleTuple::repr() const throw(INTERP_KERNEL::Exception)
5364 {
5365   std::ostringstream oss; oss.precision(17); oss << "(";
5366   for(int i=0;i<_nb_of_compo-1;i++)
5367     oss << _pt[i] << ", ";
5368   oss << _pt[_nb_of_compo-1] << ")";
5369   return oss.str();
5370 }
5371
5372 double DataArrayDoubleTuple::doubleValue() const throw(INTERP_KERNEL::Exception)
5373 {
5374   if(_nb_of_compo==1)
5375     return *_pt;
5376   throw INTERP_KERNEL::Exception("DataArrayDoubleTuple::doubleValue : DataArrayDoubleTuple instance has not exactly 1 component -> Not possible to convert it into a double precision float !");
5377 }
5378
5379 /*!
5380  * This method returns a newly allocated instance the caller should dealed with by a ParaMEDMEM::DataArrayDouble::decrRef.
5381  * This method performs \b no copy of data. The content is only referenced using ParaMEDMEM::DataArrayDouble::useArray with ownership set to \b false.
5382  * 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
5383  * \b nbOfCompo=1 and \bnbOfTuples==this->_nb_of_elem.
5384  */
5385 DataArrayDouble *DataArrayDoubleTuple::buildDADouble(int nbOfTuples, int nbOfCompo) const throw(INTERP_KERNEL::Exception)
5386 {
5387   if((_nb_of_compo==nbOfCompo && nbOfTuples==1) || (_nb_of_compo==nbOfTuples && nbOfCompo==1))
5388     {
5389       DataArrayDouble *ret=DataArrayDouble::New();
5390       ret->useExternalArrayWithRWAccess(_pt,nbOfTuples,nbOfCompo);
5391       return ret;
5392     }
5393   else
5394     {
5395       std::ostringstream oss; oss << "DataArrayDoubleTuple::buildDADouble : unable to build a requested DataArrayDouble instance with nbofTuple=" << nbOfTuples << " and nbOfCompo=" << nbOfCompo;
5396       oss << ".\nBecause the number of elements in this is " << _nb_of_compo << " !";
5397       throw INTERP_KERNEL::Exception(oss.str().c_str());
5398     }
5399 }
5400
5401 /*!
5402  * Returns a new instance of DataArrayInt. The caller is to delete this array
5403  * using decrRef() as it is no more needed. 
5404  */
5405 DataArrayInt *DataArrayInt::New()
5406 {
5407   return new DataArrayInt;
5408 }
5409
5410 /*!
5411  * Checks if raw data is allocated. Read more on the raw data
5412  * in \ref MEDCouplingArrayBasicsTuplesAndCompo "DataArrays infos" for more information.
5413  *  \return bool - \a true if the raw data is allocated, \a false else.
5414  */
5415 bool DataArrayInt::isAllocated() const throw(INTERP_KERNEL::Exception)
5416 {
5417   return getConstPointer()!=0;
5418 }
5419
5420 /*!
5421  * Checks if raw data is allocated and throws an exception if it is not the case.
5422  *  \throw If the raw data is not allocated.
5423  */
5424 void DataArrayInt::checkAllocated() const throw(INTERP_KERNEL::Exception)
5425 {
5426   if(!isAllocated())
5427     throw INTERP_KERNEL::Exception("DataArrayInt::checkAllocated : Array is defined but not allocated ! Call alloc or setValues method first !");
5428 }
5429
5430 std::size_t DataArrayInt::getHeapMemorySize() const
5431 {
5432   std::size_t sz=_mem.getNbOfElemAllocated();
5433   sz*=sizeof(int);
5434   return DataArray::getHeapMemorySize()+sz;
5435 }
5436
5437 /*!
5438  * Returns the only one value in \a this, if and only if number of elements
5439  * (nb of tuples * nb of components) is equal to 1, and that \a this is allocated.
5440  *  \return double - the sole value stored in \a this array.
5441  *  \throw If at least one of conditions stated above is not fulfilled.
5442  */
5443 int DataArrayInt::intValue() const throw(INTERP_KERNEL::Exception)
5444 {
5445   if(isAllocated())
5446     {
5447       if(getNbOfElems()==1)
5448         {
5449           return *getConstPointer();
5450         }
5451       else
5452         throw INTERP_KERNEL::Exception("DataArrayInt::intValue : DataArrayInt instance is allocated but number of elements is not equal to 1 !");
5453     }
5454   else
5455     throw INTERP_KERNEL::Exception("DataArrayInt::intValue : DataArrayInt instance is not allocated !");
5456 }
5457
5458 /*!
5459  * Returns an integer value characterizing \a this array, which is useful for a quick
5460  * comparison of many instances of DataArrayInt.
5461  *  \return int - the hash value.
5462  *  \throw If \a this is not allocated.
5463  */
5464 int DataArrayInt::getHashCode() const throw(INTERP_KERNEL::Exception)
5465 {
5466   checkAllocated();
5467   std::size_t nbOfElems=getNbOfElems();
5468   int ret=nbOfElems*65536;
5469   int delta=3;
5470   if(nbOfElems>48)
5471     delta=nbOfElems/8;
5472   int ret0=0;
5473   const int *pt=begin();
5474   for(std::size_t i=0;i<nbOfElems;i+=delta)
5475     ret0+=pt[i] & 0x1FFF;
5476   return ret+ret0;
5477 }
5478
5479 /*!
5480  * Checks the number of tuples.
5481  *  \return bool - \a true if getNumberOfTuples() == 0, \a false else.
5482  *  \throw If \a this is not allocated.
5483  */
5484 bool DataArrayInt::empty() const throw(INTERP_KERNEL::Exception)
5485 {
5486   checkAllocated();
5487   return getNumberOfTuples()==0;
5488 }
5489
5490 /*!
5491  * Returns a full copy of \a this. For more info on copying data arrays see
5492  * \ref MEDCouplingArrayBasicsCopyDeep.
5493  *  \return DataArrayInt * - a new instance of DataArrayInt.
5494  */
5495 DataArrayInt *DataArrayInt::deepCpy() const throw(INTERP_KERNEL::Exception)
5496 {
5497   return new DataArrayInt(*this);
5498 }
5499
5500 /*!
5501  * Returns either a \a deep or \a shallow copy of this array. For more info see
5502  * \ref MEDCouplingArrayBasicsCopyDeep and \ref MEDCouplingArrayBasicsCopyShallow.
5503  *  \param [in] dCpy - if \a true, a deep copy is returned, else, a shallow one.
5504  *  \return DataArrayInt * - either a new instance of DataArrayInt (if \a dCpy
5505  *          == \a true) or \a this instance (if \a dCpy == \a false).
5506  */
5507 DataArrayInt *DataArrayInt::performCpy(bool dCpy) const throw(INTERP_KERNEL::Exception)
5508 {
5509   if(dCpy)
5510     return deepCpy();
5511   else
5512     {
5513       incrRef();
5514       return const_cast<DataArrayInt *>(this);
5515     }
5516 }
5517
5518 /*!
5519  * Copies all the data from another DataArrayInt. For more info see
5520  * \ref MEDCouplingArrayBasicsCopyDeepAssign.
5521  *  \param [in] other - another instance of DataArrayInt to copy data from.
5522  *  \throw If the \a other is not allocated.
5523  */
5524 void DataArrayInt::cpyFrom(const DataArrayInt& other) throw(INTERP_KERNEL::Exception)
5525 {
5526   other.checkAllocated();
5527   int nbOfTuples=other.getNumberOfTuples();
5528   int nbOfComp=other.getNumberOfComponents();
5529   allocIfNecessary(nbOfTuples,nbOfComp);
5530   std::size_t nbOfElems=(std::size_t)nbOfTuples*nbOfComp;
5531   int *pt=getPointer();
5532   const int *ptI=other.getConstPointer();
5533   for(std::size_t i=0;i<nbOfElems;i++)
5534     pt[i]=ptI[i];
5535   copyStringInfoFrom(other);
5536 }
5537
5538 /*!
5539  * This method reserve nbOfElems elements in memory ( nbOfElems*4 bytes ) \b without impacting the number of tuples in \a this.
5540  * 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.
5541  * If \a this has not already been allocated, number of components is set to one.
5542  * This method allows to reduce number of reallocations on invokation of DataArrayInt::pushBackSilent and DataArrayInt::pushBackValsSilent on \a this.
5543  * 
5544  * \sa DataArrayInt::pack, DataArrayInt::pushBackSilent, DataArrayInt::pushBackValsSilent
5545  */
5546 void DataArrayInt::reserve(std::size_t nbOfElems) throw(INTERP_KERNEL::Exception)
5547 {
5548   int nbCompo=getNumberOfComponents();
5549   if(nbCompo==1)
5550     {
5551       _mem.reserve(nbOfElems);
5552     }
5553   else if(nbCompo==0)
5554     {
5555       _mem.reserve(nbOfElems);
5556       _info_on_compo.resize(1);
5557     }
5558   else
5559     throw INTERP_KERNEL::Exception("DataArrayInt::reserve : not available for DataArrayInt with number of components different than 1 !");
5560 }
5561
5562 /*!
5563  * 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
5564  * of counter. So the caller is expected to call TimeLabel::declareAsNew on \a this at the end of the push session.
5565  *
5566  * \param [in] val the value to be added in \a this
5567  * \throw If \a this has already been allocated with number of components different from one.
5568  * \sa DataArrayInt::pushBackValsSilent
5569  */
5570 void DataArrayInt::pushBackSilent(int val) throw(INTERP_KERNEL::Exception)
5571 {
5572   int nbCompo=getNumberOfComponents();
5573   if(nbCompo==1)
5574     _mem.pushBack(val);
5575   else if(nbCompo==0)
5576     {
5577       _info_on_compo.resize(1);
5578       _mem.pushBack(val);
5579     }
5580   else
5581     throw INTERP_KERNEL::Exception("DataArrayInt::pushBackSilent : not available for DataArrayInt with number of components different than 1 !");
5582 }
5583
5584 /*!
5585  * 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
5586  * of counter. So the caller is expected to call TimeLabel::declareAsNew on \a this at the end of the push session.
5587  *
5588  *  \param [in] valsBg - an array of values to push at the end of \this.
5589  *  \param [in] valsEnd - specifies the end of the array \a valsBg, so that
5590  *              the last value of \a valsBg is \a valsEnd[ -1 ].
5591  * \throw If \a this has already been allocated with number of components different from one.
5592  * \sa DataArrayInt::pushBackSilent
5593  */
5594 void DataArrayInt::pushBackValsSilent(const int *valsBg, const int *valsEnd) throw(INTERP_KERNEL::Exception)
5595 {
5596   int nbCompo=getNumberOfComponents();
5597   if(nbCompo==1)
5598     _mem.insertAtTheEnd(valsBg,valsEnd);
5599   else if(nbCompo==0)
5600     {
5601       _info_on_compo.resize(1);
5602       _mem.insertAtTheEnd(valsBg,valsEnd);
5603     }
5604   else
5605     throw INTERP_KERNEL::Exception("DataArrayInt::pushBackValsSilent : not available for DataArrayInt with number of components different than 1 !");
5606 }
5607
5608 /*!
5609  * This method returns silently ( without updating time label in \a this ) the last value, if any and suppress it.
5610  * \throw If \a this is already empty.
5611  * \throw If \a this has number of components different from one.
5612  */
5613 int DataArrayInt::popBackSilent() throw(INTERP_KERNEL::Exception)
5614 {
5615   if(getNumberOfComponents()==1)
5616     return _mem.popBack();
5617   else
5618     throw INTERP_KERNEL::Exception("DataArrayInt::popBackSilent : not available for DataArrayInt with number of components different than 1 !");
5619 }
5620
5621 /*!
5622  * 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.
5623  *
5624  * \sa DataArrayInt::getHeapMemorySize, DataArrayInt::reserve
5625  */
5626 void DataArrayInt::pack() const throw(INTERP_KERNEL::Exception)
5627 {
5628   _mem.pack();
5629 }
5630
5631 /*!
5632  * Allocates the raw data in memory. If exactly as same memory as needed already
5633  * allocated, it is not re-allocated.
5634  *  \param [in] nbOfTuple - number of tuples of data to allocate.
5635  *  \param [in] nbOfCompo - number of components of data to allocate.
5636  *  \throw If \a nbOfTuple < 0 or \a nbOfCompo < 0.
5637  */
5638 void DataArrayInt::allocIfNecessary(int nbOfTuple, int nbOfCompo) throw(INTERP_KERNEL::Exception)
5639 {
5640   if(isAllocated())
5641     {
5642       if(nbOfTuple!=getNumberOfTuples() || nbOfCompo!=getNumberOfComponents())
5643         alloc(nbOfTuple,nbOfCompo);
5644     }
5645   else
5646     alloc(nbOfTuple,nbOfCompo);
5647 }
5648
5649 /*!
5650  * Allocates the raw data in memory. If the memory was already allocated, then it is
5651  * freed and re-allocated. See an example of this method use
5652  * \ref MEDCouplingArraySteps1WC "here".
5653  *  \param [in] nbOfTuple - number of tuples of data to allocate.
5654  *  \param [in] nbOfCompo - number of components of data to allocate.
5655  *  \throw If \a nbOfTuple < 0 or \a nbOfCompo < 0.
5656  */
5657 void DataArrayInt::alloc(int nbOfTuple, int nbOfCompo) throw(INTERP_KERNEL::Exception)
5658 {
5659   if(nbOfTuple<0 || nbOfCompo<0)
5660     throw INTERP_KERNEL::Exception("DataArrayInt::alloc : request for negative length of data !");
5661   _info_on_compo.resize(nbOfCompo);
5662   _mem.alloc(nbOfCompo*(std::size_t)nbOfTuple);
5663   declareAsNew();
5664 }
5665
5666 /*!
5667  * Assign zero to all values in \a this array. To know more on filling arrays see
5668  * \ref MEDCouplingArrayFill.
5669  * \throw If \a this is not allocated.
5670  */
5671 void DataArrayInt::fillWithZero() throw(INTERP_KERNEL::Exception)
5672 {
5673   checkAllocated();
5674   _mem.fillWithValue(0);
5675   declareAsNew();
5676 }
5677
5678 /*!
5679  * Assign \a val to all values in \a this array. To know more on filling arrays see
5680  * \ref MEDCouplingArrayFill.
5681  *  \param [in] val - the value to fill with.
5682  *  \throw If \a this is not allocated.
5683  */
5684 void DataArrayInt::fillWithValue(int val) throw(INTERP_KERNEL::Exception)
5685 {
5686   checkAllocated();
5687   _mem.fillWithValue(val);
5688   declareAsNew();
5689 }
5690
5691 /*!
5692  * Set all values in \a this array so that the i-th element equals to \a init + i
5693  * (i starts from zero). To know more on filling arrays see \ref MEDCouplingArrayFill.
5694  *  \param [in] init - value to assign to the first element of array.
5695  *  \throw If \a this->getNumberOfComponents() != 1
5696  *  \throw If \a this is not allocated.
5697  */
5698 void DataArrayInt::iota(int init) throw(INTERP_KERNEL::Exception)
5699 {
5700   checkAllocated();
5701   if(getNumberOfComponents()!=1)
5702     throw INTERP_KERNEL::Exception("DataArrayInt::iota : works only for arrays with only one component, you can call 'rearrange' method before !");
5703   int *ptr=getPointer();
5704   int ntuples=getNumberOfTuples();
5705   for(int i=0;i<ntuples;i++)
5706     ptr[i]=init+i;
5707   declareAsNew();
5708 }
5709
5710 /*!
5711  * Returns a textual and human readable representation of \a this instance of
5712  * DataArrayInt. This text is shown when a DataArrayInt is printed in Python.
5713  *  \return std::string - text describing \a this DataArrayInt.
5714  */
5715 std::string DataArrayInt::repr() const throw(INTERP_KERNEL::Exception)
5716 {
5717   std::ostringstream ret;
5718   reprStream(ret);
5719   return ret.str();
5720 }
5721
5722 std::string DataArrayInt::reprZip() const throw(INTERP_KERNEL::Exception)
5723 {
5724   std::ostringstream ret;
5725   reprZipStream(ret);
5726   return ret.str();
5727 }
5728
5729 void DataArrayInt::writeVTK(std::ostream& ofs, int indent, const char *type, const char *nameInFile) const throw(INTERP_KERNEL::Exception)
5730 {
5731   checkAllocated();
5732   std::string idt(indent,' ');
5733   ofs << idt << "<DataArray type=\"" << type << "\" Name=\"" << nameInFile << "\" NumberOfComponents=\"" << getNumberOfComponents() << "\"";
5734   ofs << " format=\"ascii\" RangeMin=\"" << getMinValueInArray() << "\" RangeMax=\"" << getMaxValueInArray() << "\">\n" << idt;
5735   std::copy(begin(),end(),std::ostream_iterator<int>(ofs," "));
5736   ofs << std::endl << idt << "</DataArray>\n";
5737 }
5738
5739 void DataArrayInt::reprStream(std::ostream& stream) const throw(INTERP_KERNEL::Exception)
5740 {
5741   stream << "Name of int array : \"" << _name << "\"\n";
5742   reprWithoutNameStream(stream);
5743 }
5744
5745 void DataArrayInt::reprZipStream(std::ostream& stream) const throw(INTERP_KERNEL::Exception)
5746 {
5747   stream << "Name of int array : \"" << _name << "\"\n";
5748   reprZipWithoutNameStream(stream);
5749 }
5750
5751 void DataArrayInt::reprWithoutNameStream(std::ostream& stream) const throw(INTERP_KERNEL::Exception)
5752 {
5753   DataArray::reprWithoutNameStream(stream);
5754   _mem.repr(getNumberOfComponents(),stream);
5755 }
5756
5757 void DataArrayInt::reprZipWithoutNameStream(std::ostream& stream) const throw(INTERP_KERNEL::Exception)
5758 {
5759   DataArray::reprWithoutNameStream(stream);
5760   _mem.reprZip(getNumberOfComponents(),stream);
5761 }
5762
5763 void DataArrayInt::reprCppStream(const char *varName, std::ostream& stream) const throw(INTERP_KERNEL::Exception)
5764 {
5765   int nbTuples=getNumberOfTuples(),nbComp=getNumberOfComponents();
5766   const int *data=getConstPointer();
5767   stream << "DataArrayInt *" << varName << "=DataArrayInt::New();" << std::endl;
5768   if(nbTuples*nbComp>=1)
5769     {
5770       stream << "const int " << varName << "Data[" << nbTuples*nbComp << "]={";
5771       std::copy(data,data+nbTuples*nbComp-1,std::ostream_iterator<int>(stream,","));
5772       stream << data[nbTuples*nbComp-1] << "};" << std::endl;
5773       stream << varName << "->useArray(" << varName << "Data,false,CPP_DEALLOC," << nbTuples << "," << nbComp << ");" << std::endl;
5774     }
5775   else
5776     stream << varName << "->alloc(" << nbTuples << "," << nbComp << ");" << std::endl;
5777   stream << varName << "->setName(\"" << getName() << "\");" << std::endl;
5778 }
5779
5780 /*!
5781  * Method that gives a quick overvien of \a this for python.
5782  */
5783 void DataArrayInt::reprQuickOverview(std::ostream& stream) const throw(INTERP_KERNEL::Exception)
5784 {
5785   static const std::size_t MAX_NB_OF_BYTE_IN_REPR=300;
5786   stream << "DataArrayInt C++ instance at " << this << ". ";
5787   if(isAllocated())
5788     {
5789       int nbOfCompo=(int)_info_on_compo.size();
5790       if(nbOfCompo>=1)
5791         {
5792           int nbOfTuples=getNumberOfTuples();
5793           stream << "Number of tuples : " << nbOfTuples << ". Number of components : " << nbOfCompo << "." << std::endl;
5794           reprQuickOverviewData(stream,MAX_NB_OF_BYTE_IN_REPR);
5795         }
5796       else
5797         stream << "Number of components : 0.";
5798     }
5799   else
5800     stream << "*** No data allocated ****";
5801 }
5802
5803 void DataArrayInt::reprQuickOverviewData(std::ostream& stream, std::size_t maxNbOfByteInRepr) const throw(INTERP_KERNEL::Exception)
5804 {
5805   const int *data=begin();
5806   int nbOfTuples=getNumberOfTuples();
5807   int nbOfCompo=(int)_info_on_compo.size();
5808   std::ostringstream oss2; oss2 << "[";
5809   std::string oss2Str(oss2.str());
5810   bool isFinished=true;
5811   for(int i=0;i<nbOfTuples && isFinished;i++)
5812     {
5813       if(nbOfCompo>1)
5814         {
5815           oss2 << "(";
5816           for(int j=0;j<nbOfCompo;j++,data++)
5817             {
5818               oss2 << *data;
5819               if(j!=nbOfCompo-1) oss2 << ", ";
5820             }
5821           oss2 << ")";
5822         }
5823       else
5824         oss2 << *data++;
5825       if(i!=nbOfTuples-1) oss2 << ", ";
5826       std::string oss3Str(oss2.str());
5827       if(oss3Str.length()<maxNbOfByteInRepr)
5828         oss2Str=oss3Str;
5829       else
5830         isFinished=false;
5831     }
5832   stream << oss2Str;
5833   if(!isFinished)
5834     stream << "... ";
5835   stream << "]";
5836 }
5837
5838 /*!
5839  * Modifies \a this one-dimensional array so that each value \a v = \a indArrBg[ \a v ],
5840  * i.e. a current value is used as in index to get a new value from \a indArrBg.
5841  *  \param [in] indArrBg - pointer to the first element of array of new values to assign
5842  *         to \a this array.
5843  *  \param [in] indArrEnd - specifies the end of the array \a indArrBg, so that
5844  *              the last value of \a indArrBg is \a indArrEnd[ -1 ].
5845  *  \throw If \a this->getNumberOfComponents() != 1
5846  *  \throw If any value of \a this can't be used as a valid index for 
5847  *         [\a indArrBg, \a indArrEnd).
5848  */
5849 void DataArrayInt::transformWithIndArr(const int *indArrBg, const int *indArrEnd) throw(INTERP_KERNEL::Exception)
5850 {
5851   checkAllocated();
5852   if(getNumberOfComponents()!=1)
5853     throw INTERP_KERNEL::Exception("Call transformWithIndArr method on DataArrayInt with only one component, you can call 'rearrange' method before !");
5854   int nbElemsIn=(int)std::distance(indArrBg,indArrEnd);
5855   int nbOfTuples=getNumberOfTuples();
5856   int *pt=getPointer();
5857   for(int i=0;i<nbOfTuples;i++,pt++)
5858     {
5859       if(*pt>=0 && *pt<nbElemsIn)
5860         *pt=indArrBg[*pt];
5861       else
5862         {
5863           std::ostringstream oss; oss << "DataArrayInt::transformWithIndArr : error on tuple #" << i << " of this value is " << *pt << ", should be in [0," << nbElemsIn << ") !";
5864           throw INTERP_KERNEL::Exception(oss.str().c_str());
5865         }
5866     }
5867   declareAsNew();
5868 }
5869
5870 /*!
5871  * Computes distribution of values of \a this one-dimensional array between given value
5872  * ranges (casts). This method is typically useful for entity number spliting by types,
5873  * for example. 
5874  *  \warning The values contained in \a arrBg should be sorted ascendently. No
5875  *           check of this is be done. If not, the result is not warranted. 
5876  *  \param [in] arrBg - the array of ascending values defining the value ranges. The i-th
5877  *         value of \a arrBg (\a arrBg[ i ]) gives the lowest value of the i-th range,
5878  *         and the greatest value of the i-th range equals to \a arrBg[ i+1 ] - 1. \a
5879  *         arrBg containing \a n values defines \a n-1 ranges. The last value of \a arrBg
5880  *         should be more than every value in \a this array.
5881  *  \param [in] arrEnd - specifies the end of the array \a arrBg, so that
5882  *              the last value of \a arrBg is \a arrEnd[ -1 ].
5883  *  \param [out] castArr - a new instance of DataArrayInt, of same size as \a this array
5884  *         (same number of tuples and components), the caller is to delete 
5885  *         using decrRef() as it is no more needed.
5886  *         This array contains indices of ranges for every value of \a this array. I.e.
5887  *         the i-th value of \a castArr gives the index of range the i-th value of \a this
5888  *         belongs to. Or, in other words, this parameter contains for each tuple in \a
5889  *         this in which cast it holds.
5890  *  \param [out] rankInsideCast - a new instance of DataArrayInt, of same size as \a this
5891  *         array, the caller is to delete using decrRef() as it is no more needed.
5892  *         This array contains ranks of values of \a this array within ranges
5893  *         they belongs to. I.e. the i-th value of \a rankInsideCast gives the rank of
5894  *         the i-th value of \a this array within the \a castArr[ i ]-th range, to which
5895  *         the i-th value of \a this belongs to. Or, in other words, this param contains 
5896  *         for each tuple its rank inside its cast. The rank is computed as difference
5897  *         between the value and the lowest value of range.
5898  *  \param [out] castsPresent - a new instance of DataArrayInt, containing indices of
5899  *         ranges (casts) to which at least one value of \a this array belongs.
5900  *         Or, in other words, this param contains the casts that \a this contains.
5901  *         The caller is to delete this array using decrRef() as it is no more needed.
5902  *
5903  * \b Example: If \a this contains [6,5,0,3,2,7,8,1,4] and \a arrBg contains [0,4,9] then
5904  *            the output of this method will be : 
5905  * - \a castArr       : [1,1,0,0,0,1,1,0,1]
5906  * - \a rankInsideCast: [2,1,0,3,2,3,4,1,0]
5907  * - \a castsPresent  : [0,1]
5908  *
5909  * I.e. values of \a this array belong to 2 ranges: #0 and #1. Value 6 belongs to the
5910  * range #1 and its rank within this range is 2; etc.
5911  *
5912  *  \throw If \a this->getNumberOfComponents() != 1.
5913  *  \throw If \a arrEnd - arrBg < 2.
5914  *  \throw If any value of \a this is not less than \a arrEnd[-1].
5915  */
5916 void DataArrayInt::splitByValueRange(const int *arrBg, const int *arrEnd,
5917                                      DataArrayInt *& castArr, DataArrayInt *& rankInsideCast, DataArrayInt *& castsPresent) const throw(INTERP_KERNEL::Exception)
5918 {
5919   checkAllocated();
5920   if(getNumberOfComponents()!=1)
5921     throw INTERP_KERNEL::Exception("Call splitByValueRange  method on DataArrayInt with only one component, you can call 'rearrange' method before !");
5922   int nbOfTuples=getNumberOfTuples();
5923   std::size_t nbOfCast=std::distance(arrBg,arrEnd);
5924   if(nbOfCast<2)
5925     throw INTERP_KERNEL::Exception("DataArrayInt::splitByValueRange : The input array giving the cast range values should be of size >=2 !");
5926   nbOfCast--;
5927   const int *work=getConstPointer();
5928   typedef std::reverse_iterator<const int *> rintstart;
5929   rintstart bg(arrEnd);//OK no problem because size of 'arr' is greater or equal 2
5930   rintstart end2(arrBg);
5931   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret1=DataArrayInt::New();
5932   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret2=DataArrayInt::New();
5933   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret3=DataArrayInt::New();
5934   ret1->alloc(nbOfTuples,1);
5935   ret2->alloc(nbOfTuples,1);
5936   int *ret1Ptr=ret1->getPointer();
5937   int *ret2Ptr=ret2->getPointer();
5938   std::set<std::size_t> castsDetected;
5939   for(int i=0;i<nbOfTuples;i++)
5940     {
5941       rintstart res=std::find_if(bg,end2,std::bind2nd(std::less_equal<int>(), work[i]));
5942       std::size_t pos=std::distance(bg,res);
5943       std::size_t pos2=nbOfCast-pos;
5944       if(pos2<nbOfCast)
5945         {
5946           ret1Ptr[i]=(int)pos2;
5947           ret2Ptr[i]=work[i]-arrBg[pos2];
5948           castsDetected.insert(pos2);
5949         }
5950       else
5951         {
5952           std::ostringstream oss; oss << "DataArrayInt::splitByValueRange : At rank #" << i << " the value is " << work[i] << " should be in [0," << *bg << ") !";
5953           throw INTERP_KERNEL::Exception(oss.str().c_str());
5954         }
5955     }
5956   ret3->alloc((int)castsDetected.size(),1);
5957   std::copy(castsDetected.begin(),castsDetected.end(),ret3->getPointer());
5958   castArr=ret1.retn();
5959   rankInsideCast=ret2.retn();
5960   castsPresent=ret3.retn();
5961 }
5962
5963 /*!
5964  * Creates a one-dimensional DataArrayInt (\a res) whose contents are computed from 
5965  * values of \a this (\a a) and the given (\a indArr) arrays as follows:
5966  * \a res[ \a indArr[ \a a[ i ]]] = i. I.e. for each value in place i \a v = \a a[ i ],
5967  * new value in place \a indArr[ \a v ] is i.
5968  *  \param [in] indArrBg - the array holding indices within the result array to assign
5969  *         indices of values of \a this array pointing to values of \a indArrBg.
5970  *  \param [in] indArrEnd - specifies the end of the array \a indArrBg, so that
5971  *              the last value of \a indArrBg is \a indArrEnd[ -1 ].
5972  *  \return DataArrayInt * - the new instance of DataArrayInt.
5973  *          The caller is to delete this result array using decrRef() as it is no more
5974  *          needed.
5975  *  \throw If \a this->getNumberOfComponents() != 1.
5976  *  \throw If any value of \a this array is not a valid index for \a indArrBg array.
5977  *  \throw If any value of \a indArrBg is not a valid index for \a this array.
5978  */
5979 DataArrayInt *DataArrayInt::transformWithIndArrR(const int *indArrBg, const int *indArrEnd) const throw(INTERP_KERNEL::Exception)
5980 {
5981   checkAllocated();
5982   if(getNumberOfComponents()!=1)
5983     throw INTERP_KERNEL::Exception("Call transformWithIndArrR method on DataArrayInt with only one component, you can call 'rearrange' method before !");
5984   int nbElemsIn=(int)std::distance(indArrBg,indArrEnd);
5985   int nbOfTuples=getNumberOfTuples();
5986   const int *pt=getConstPointer();
5987   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
5988   ret->alloc(nbOfTuples,1);
5989   ret->fillWithValue(-1);
5990   int *tmp=ret->getPointer();
5991   for(int i=0;i<nbOfTuples;i++,pt++)
5992     {
5993       if(*pt>=0 && *pt<nbElemsIn)
5994         {
5995           int pos=indArrBg[*pt];
5996           if(pos>=0 && pos<nbOfTuples)
5997             tmp[pos]=i;
5998           else
5999             {
6000               std::ostringstream oss; oss << "DataArrayInt::transformWithIndArrR : error on tuple #" << i << " value of new pos is " << pos << " ( indArrBg[" << *pt << "]) ! Should be in [0," << nbOfTuples << ") !";
6001               throw INTERP_KERNEL::Exception(oss.str().c_str());
6002             }
6003         }
6004       else
6005         {
6006           std::ostringstream oss; oss << "DataArrayInt::transformWithIndArrR : error on tuple #" << i << " value is " << *pt << " and indirectionnal array as a size equal to " << nbElemsIn << " !";
6007           throw INTERP_KERNEL::Exception(oss.str().c_str());
6008         }
6009     }
6010   return ret.retn();
6011 }
6012
6013 /*!
6014  * Creates a one-dimensional DataArrayInt of given length, whose contents are computed
6015  * from values of \a this array, which is supposed to contain a renumbering map in 
6016  * "Old to New" mode. The result array contains a renumbering map in "New to Old" mode.
6017  * To know how to use the renumbering maps see \ref MEDCouplingArrayRenumbering.
6018  *  \param [in] newNbOfElem - the number of tuples in the result array.
6019  *  \return DataArrayInt * - the new instance of DataArrayInt.
6020  *          The caller is to delete this result array using decrRef() as it is no more
6021  *          needed.
6022  * 
6023  *  \ref cpp_mcdataarrayint_invertarrayo2n2n2o "Here is a C++ example".<br>
6024  *  \ref py_mcdataarrayint_invertarrayo2n2n2o  "Here is a Python example".
6025  */
6026 DataArrayInt *DataArrayInt::invertArrayO2N2N2O(int newNbOfElem) const
6027 {
6028   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6029   ret->alloc(newNbOfElem,1);
6030   int nbOfOldNodes=getNumberOfTuples();
6031   const int *old2New=getConstPointer();
6032   int *pt=ret->getPointer();
6033   for(int i=0;i!=nbOfOldNodes;i++)
6034     if(old2New[i]!=-1)
6035       pt[old2New[i]]=i;
6036   return ret.retn();
6037 }
6038
6039 /*!
6040  * This method is similar to DataArrayInt::invertArrayO2N2N2O except that 
6041  * 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]
6042  */
6043 DataArrayInt *DataArrayInt::invertArrayO2N2N2OBis(int newNbOfElem) const throw(INTERP_KERNEL::Exception)
6044 {
6045   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6046   ret->alloc(newNbOfElem,1);
6047   int nbOfOldNodes=getNumberOfTuples();
6048   const int *old2New=getConstPointer();
6049   int *pt=ret->getPointer();
6050   for(int i=nbOfOldNodes-1;i>=0;i--)
6051     if(old2New[i]!=-1)
6052       pt[old2New[i]]=i;
6053   return ret.retn();
6054 }
6055
6056 /*!
6057  * Creates a one-dimensional DataArrayInt of given length, whose contents are computed
6058  * from values of \a this array, which is supposed to contain a renumbering map in 
6059  * "New to Old" mode. The result array contains a renumbering map in "Old to New" mode.
6060  * To know how to use the renumbering maps see \ref MEDCouplingArrayRenumbering.
6061  *  \param [in] newNbOfElem - the number of tuples in the result array.
6062  *  \return DataArrayInt * - the new instance of DataArrayInt.
6063  *          The caller is to delete this result array using decrRef() as it is no more
6064  *          needed.
6065  * 
6066  *  \ref cpp_mcdataarrayint_invertarrayn2o2o2n "Here is a C++ example".
6067  *
6068  *  \ref py_mcdataarrayint_invertarrayn2o2o2n "Here is a Python example".
6069  */
6070 DataArrayInt *DataArrayInt::invertArrayN2O2O2N(int oldNbOfElem) const
6071 {
6072   checkAllocated();
6073   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6074   ret->alloc(oldNbOfElem,1);
6075   const int *new2Old=getConstPointer();
6076   int *pt=ret->getPointer();
6077   std::fill(pt,pt+oldNbOfElem,-1);
6078   int nbOfNewElems=getNumberOfTuples();
6079   for(int i=0;i<nbOfNewElems;i++)
6080     pt[new2Old[i]]=i;
6081   return ret.retn();
6082 }
6083
6084 /*!
6085  * Equivalent to DataArrayInt::isEqual except that if false the reason of
6086  * mismatch is given.
6087  * 
6088  * \param [in] other the instance to be compared with \a this
6089  * \param [out] reason In case of inequality returns the reason.
6090  * \sa DataArrayInt::isEqual
6091  */
6092 bool DataArrayInt::isEqualIfNotWhy(const DataArrayInt& other, std::string& reason) const throw(INTERP_KERNEL::Exception)
6093 {
6094   if(!areInfoEqualsIfNotWhy(other,reason))
6095     return false;
6096   return _mem.isEqual(other._mem,0,reason);
6097 }
6098
6099 /*!
6100  * Checks if \a this and another DataArrayInt are fully equal. For more info see
6101  * \ref MEDCouplingArrayBasicsCompare.
6102  *  \param [in] other - an instance of DataArrayInt to compare with \a this one.
6103  *  \return bool - \a true if the two arrays are equal, \a false else.
6104  */
6105 bool DataArrayInt::isEqual(const DataArrayInt& other) const throw(INTERP_KERNEL::Exception)
6106 {
6107   std::string tmp;
6108   return isEqualIfNotWhy(other,tmp);
6109 }
6110
6111 /*!
6112  * Checks if values of \a this and another DataArrayInt are equal. For more info see
6113  * \ref MEDCouplingArrayBasicsCompare.
6114  *  \param [in] other - an instance of DataArrayInt to compare with \a this one.
6115  *  \return bool - \a true if the values of two arrays are equal, \a false else.
6116  */
6117 bool DataArrayInt::isEqualWithoutConsideringStr(const DataArrayInt& other) const throw(INTERP_KERNEL::Exception)
6118 {
6119   std::string tmp;
6120   return _mem.isEqual(other._mem,0,tmp);
6121 }
6122
6123 /*!
6124  * Checks if values of \a this and another DataArrayInt are equal. Comparison is
6125  * performed on sorted value sequences.
6126  * For more info see\ref MEDCouplingArrayBasicsCompare.
6127  *  \param [in] other - an instance of DataArrayInt to compare with \a this one.
6128  *  \return bool - \a true if the sorted values of two arrays are equal, \a false else.
6129  */
6130 bool DataArrayInt::isEqualWithoutConsideringStrAndOrder(const DataArrayInt& other) const throw(INTERP_KERNEL::Exception)
6131 {
6132   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> a=deepCpy();
6133   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> b=other.deepCpy();
6134   a->sort();
6135   b->sort();
6136   return a->isEqualWithoutConsideringStr(*b);
6137 }
6138
6139 /*!
6140  * Sorts values of the array.
6141  *  \param [in] asc - \a true means ascending order, \a false, descending.
6142  *  \throw If \a this is not allocated.
6143  *  \throw If \a this->getNumberOfComponents() != 1.
6144  */
6145 void DataArrayInt::sort(bool asc) throw(INTERP_KERNEL::Exception)
6146 {
6147   checkAllocated();
6148   if(getNumberOfComponents()!=1)
6149     throw INTERP_KERNEL::Exception("DataArrayInt::sort : only supported with 'this' array with ONE component !");
6150   _mem.sort(asc);
6151   declareAsNew();
6152 }
6153
6154 /*!
6155  * Reverse the array values.
6156  *  \throw If \a this->getNumberOfComponents() < 1.
6157  *  \throw If \a this is not allocated.
6158  */
6159 void DataArrayInt::reverse() throw(INTERP_KERNEL::Exception)
6160 {
6161   checkAllocated();
6162   _mem.reverse(getNumberOfComponents());
6163   declareAsNew();
6164 }
6165
6166 /*!
6167  * Checks that \a this array is consistently **increasing** or **decreasing** in value.
6168  * If not an exception is thrown.
6169  *  \param [in] increasing - if \a true, the array values should be increasing.
6170  *  \throw If sequence of values is not strictly monotonic in agreement with \a
6171  *         increasing arg.
6172  *  \throw If \a this->getNumberOfComponents() != 1.
6173  *  \throw If \a this is not allocated.
6174  */
6175 void DataArrayInt::checkMonotonic(bool increasing) const throw(INTERP_KERNEL::Exception)
6176 {
6177   if(!isMonotonic(increasing))
6178     {
6179       if (increasing)
6180         throw INTERP_KERNEL::Exception("DataArrayInt::checkMonotonic : 'this' is not INCREASING monotonic !");
6181       else
6182         throw INTERP_KERNEL::Exception("DataArrayInt::checkMonotonic : 'this' is not DECREASING monotonic !");
6183     }
6184 }
6185
6186 /*!
6187  * Checks that \a this array is consistently **increasing** or **decreasing** in value.
6188  *  \param [in] increasing - if \a true, array values should be increasing.
6189  *  \return bool - \a true if values change in accordance with \a increasing arg.
6190  *  \throw If \a this->getNumberOfComponents() != 1.
6191  *  \throw If \a this is not allocated.
6192  */
6193 bool DataArrayInt::isMonotonic(bool increasing) const throw(INTERP_KERNEL::Exception)
6194 {
6195   checkAllocated();
6196   if(getNumberOfComponents()!=1)
6197     throw INTERP_KERNEL::Exception("DataArrayInt::isMonotonic : only supported with 'this' array with ONE component !");
6198   int nbOfElements=getNumberOfTuples();
6199   const int *ptr=getConstPointer();
6200   if(nbOfElements==0)
6201     return true;
6202   int ref=ptr[0];
6203   if(increasing)
6204     {
6205       for(int i=1;i<nbOfElements;i++)
6206         {
6207           if(ptr[i]>=ref)
6208             ref=ptr[i];
6209           else
6210             return false;
6211         }
6212     }
6213   else
6214     {
6215       for(int i=1;i<nbOfElements;i++)
6216         {
6217           if(ptr[i]<=ref)
6218             ref=ptr[i];
6219           else
6220             return false;
6221         }
6222     }
6223   return true;
6224 }
6225
6226 /*!
6227  * This method check that array consistently INCREASING or DECREASING in value.
6228  */
6229 bool DataArrayInt::isStrictlyMonotonic(bool increasing) const throw(INTERP_KERNEL::Exception)
6230 {
6231   checkAllocated();
6232   if(getNumberOfComponents()!=1)
6233     throw INTERP_KERNEL::Exception("DataArrayInt::isStrictlyMonotonic : only supported with 'this' array with ONE component !");
6234   int nbOfElements=getNumberOfTuples();
6235   const int *ptr=getConstPointer();
6236   if(nbOfElements==0)
6237     return true;
6238   int ref=ptr[0];
6239   if(increasing)
6240     {
6241       for(int i=1;i<nbOfElements;i++)
6242         {
6243           if(ptr[i]>ref)
6244             ref=ptr[i];
6245           else
6246             return false;
6247         }
6248     }
6249   else
6250     {
6251       for(int i=1;i<nbOfElements;i++)
6252         {
6253           if(ptr[i]<ref)
6254             ref=ptr[i];
6255           else
6256             return false;
6257         }
6258     }
6259   return true;
6260 }
6261
6262 /*!
6263  * This method check that array consistently INCREASING or DECREASING in value.
6264  */
6265 void DataArrayInt::checkStrictlyMonotonic(bool increasing) const throw(INTERP_KERNEL::Exception)
6266 {
6267   if(!isStrictlyMonotonic(increasing))
6268     {
6269       if (increasing)
6270         throw INTERP_KERNEL::Exception("DataArrayInt::checkStrictlyMonotonic : 'this' is not strictly INCREASING monotonic !");
6271       else
6272         throw INTERP_KERNEL::Exception("DataArrayInt::checkStrictlyMonotonic : 'this' is not strictly DECREASING monotonic !");
6273     }
6274 }
6275
6276 /*!
6277  * Creates a new one-dimensional DataArrayInt of the same size as \a this and a given
6278  * one-dimensional arrays that must be of the same length. The result array describes
6279  * correspondence between \a this and \a other arrays, so that 
6280  * <em> other.getIJ(i,0) == this->getIJ(ret->getIJ(i),0)</em>. If such a permutation is
6281  * not possible because some element in \a other is not in \a this, an exception is thrown.
6282  *  \param [in] other - an array to compute permutation to.
6283  *  \return DataArrayInt * - a new instance of DataArrayInt, which is a permutation array
6284  * from \a this to \a other. The caller is to delete this array using decrRef() as it is
6285  * no more needed.
6286  *  \throw If \a this->getNumberOfComponents() != 1.
6287  *  \throw If \a other->getNumberOfComponents() != 1.
6288  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples().
6289  *  \throw If \a other includes a value which is not in \a this array.
6290  * 
6291  *  \ref cpp_mcdataarrayint_buildpermutationarr "Here is a C++ example".
6292  *
6293  *  \ref py_mcdataarrayint_buildpermutationarr "Here is a Python example".
6294  */
6295 DataArrayInt *DataArrayInt::buildPermutationArr(const DataArrayInt& other) const throw(INTERP_KERNEL::Exception)
6296 {
6297   checkAllocated();
6298   if(getNumberOfComponents()!=1 || other.getNumberOfComponents()!=1)
6299     throw INTERP_KERNEL::Exception("DataArrayInt::buildPermutationArr : 'this' and 'other' have to have exactly ONE component !");
6300   int nbTuple=getNumberOfTuples();
6301   other.checkAllocated();
6302   if(nbTuple!=other.getNumberOfTuples())
6303     throw INTERP_KERNEL::Exception("DataArrayInt::buildPermutationArr : 'this' and 'other' must have the same number of tuple !");
6304   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6305   ret->alloc(nbTuple,1);
6306   ret->fillWithValue(-1);
6307   const int *pt=getConstPointer();
6308   std::map<int,int> mm;
6309   for(int i=0;i<nbTuple;i++)
6310     mm[pt[i]]=i;
6311   pt=other.getConstPointer();
6312   int *retToFill=ret->getPointer();
6313   for(int i=0;i<nbTuple;i++)
6314     {
6315       std::map<int,int>::const_iterator it=mm.find(pt[i]);
6316       if(it==mm.end())
6317         {
6318           std::ostringstream oss; oss << "DataArrayInt::buildPermutationArr : Arrays mismatch : element (" << pt[i] << ") in 'other' not findable in 'this' !";
6319           throw INTERP_KERNEL::Exception(oss.str().c_str());
6320         }
6321       retToFill[i]=(*it).second;
6322     }
6323   return ret.retn();
6324 }
6325
6326 /*!
6327  * Sets a C array to be used as raw data of \a this. The previously set info
6328  *  of components is retained and re-sized. 
6329  * For more info see \ref MEDCouplingArraySteps1.
6330  *  \param [in] array - the C array to be used as raw data of \a this.
6331  *  \param [in] ownership - if \a true, \a array will be deallocated at destruction of \a this.
6332  *  \param [in] type - specifies how to deallocate \a array. If \a type == ParaMEDMEM::CPP_DEALLOC,
6333  *                     \c delete [] \c array; will be called. If \a type == ParaMEDMEM::C_DEALLOC,
6334  *                     \c free(\c array ) will be called.
6335  *  \param [in] nbOfTuple - new number of tuples in \a this.
6336  *  \param [in] nbOfCompo - new number of components in \a this.
6337  */
6338 void DataArrayInt::useArray(const int *array, bool ownership,  DeallocType type, int nbOfTuple, int nbOfCompo) throw(INTERP_KERNEL::Exception)
6339 {
6340   _info_on_compo.resize(nbOfCompo);
6341   _mem.useArray(array,ownership,type,nbOfTuple*nbOfCompo);
6342   declareAsNew();
6343 }
6344
6345 void DataArrayInt::useExternalArrayWithRWAccess(const int *array, int nbOfTuple, int nbOfCompo) throw(INTERP_KERNEL::Exception)
6346 {
6347   _info_on_compo.resize(nbOfCompo);
6348   _mem.useExternalArrayWithRWAccess(array,nbOfTuple*nbOfCompo);
6349   declareAsNew();
6350 }
6351
6352 /*!
6353  * Returns a new DataArrayInt holding the same values as \a this array but differently
6354  * arranged in memory. If \a this array holds 2 components of 3 values:
6355  * \f$ x_0,x_1,x_2,y_0,y_1,y_2 \f$, then the result array holds these values arranged
6356  * as follows: \f$ x_0,y_0,x_1,y_1,x_2,y_2 \f$.
6357  *  \warning Do not confuse this method with transpose()!
6358  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
6359  *          is to delete using decrRef() as it is no more needed.
6360  *  \throw If \a this is not allocated.
6361  */
6362 DataArrayInt *DataArrayInt::fromNoInterlace() const throw(INTERP_KERNEL::Exception)
6363 {
6364   checkAllocated();
6365   if(_mem.isNull())
6366     throw INTERP_KERNEL::Exception("DataArrayInt::fromNoInterlace : Not defined array !");
6367   int *tab=_mem.fromNoInterlace(getNumberOfComponents());
6368   DataArrayInt *ret=DataArrayInt::New();
6369   ret->useArray(tab,true,C_DEALLOC,getNumberOfTuples(),getNumberOfComponents());
6370   return ret;
6371 }
6372
6373 /*!
6374  * Returns a new DataArrayInt holding the same values as \a this array but differently
6375  * arranged in memory. If \a this array holds 2 components of 3 values:
6376  * \f$ x_0,y_0,x_1,y_1,x_2,y_2 \f$, then the result array holds these values arranged
6377  * as follows: \f$ x_0,x_1,x_2,y_0,y_1,y_2 \f$.
6378  *  \warning Do not confuse this method with transpose()!
6379  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
6380  *          is to delete using decrRef() as it is no more needed.
6381  *  \throw If \a this is not allocated.
6382  */
6383 DataArrayInt *DataArrayInt::toNoInterlace() const throw(INTERP_KERNEL::Exception)
6384 {
6385   checkAllocated();
6386   if(_mem.isNull())
6387     throw INTERP_KERNEL::Exception("DataArrayInt::toNoInterlace : Not defined array !");
6388   int *tab=_mem.toNoInterlace(getNumberOfComponents());
6389   DataArrayInt *ret=DataArrayInt::New();
6390   ret->useArray(tab,true,C_DEALLOC,getNumberOfTuples(),getNumberOfComponents());
6391   return ret;
6392 }
6393
6394 /*!
6395  * Permutes values of \a this array as required by \a old2New array. The values are
6396  * permuted so that \c new[ \a old2New[ i ]] = \c old[ i ]. Number of tuples remains
6397  * the same as in \this one.
6398  * If a permutation reduction is needed, substr() or selectByTupleId() should be used.
6399  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
6400  *  \param [in] old2New - C array of length equal to \a this->getNumberOfTuples()
6401  *     giving a new position for i-th old value.
6402  */
6403 void DataArrayInt::renumberInPlace(const int *old2New) throw(INTERP_KERNEL::Exception)
6404 {
6405   checkAllocated();
6406   int nbTuples=getNumberOfTuples();
6407   int nbOfCompo=getNumberOfComponents();
6408   int *tmp=new int[nbTuples*nbOfCompo];
6409   const int *iptr=getConstPointer();
6410   for(int i=0;i<nbTuples;i++)
6411     {
6412       int v=old2New[i];
6413       if(v>=0 && v<nbTuples)
6414         std::copy(iptr+nbOfCompo*i,iptr+nbOfCompo*(i+1),tmp+nbOfCompo*v);
6415       else
6416         {
6417           std::ostringstream oss; oss << "DataArrayInt::renumberInPlace : At place #" << i << " value is " << v << " ! Should be in [0," << nbTuples << ") !";
6418           throw INTERP_KERNEL::Exception(oss.str().c_str());
6419         }
6420     }
6421   std::copy(tmp,tmp+nbTuples*nbOfCompo,getPointer());
6422   delete [] tmp;
6423   declareAsNew();
6424 }
6425
6426 /*!
6427  * Permutes values of \a this array as required by \a new2Old array. The values are
6428  * permuted so that \c new[ i ] = \c old[ \a new2Old[ i ]]. Number of tuples remains
6429  * the same as in \this one.
6430  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
6431  *  \param [in] new2Old - C array of length equal to \a this->getNumberOfTuples()
6432  *     giving a previous position of i-th new value.
6433  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
6434  *          is to delete using decrRef() as it is no more needed.
6435  */
6436 void DataArrayInt::renumberInPlaceR(const int *new2Old) throw(INTERP_KERNEL::Exception)
6437 {
6438   checkAllocated();
6439   int nbTuples=getNumberOfTuples();
6440   int nbOfCompo=getNumberOfComponents();
6441   int *tmp=new int[nbTuples*nbOfCompo];
6442   const int *iptr=getConstPointer();
6443   for(int i=0;i<nbTuples;i++)
6444     {
6445       int v=new2Old[i];
6446       if(v>=0 && v<nbTuples)
6447         std::copy(iptr+nbOfCompo*v,iptr+nbOfCompo*(v+1),tmp+nbOfCompo*i);
6448       else
6449         {
6450           std::ostringstream oss; oss << "DataArrayInt::renumberInPlaceR : At place #" << i << " value is " << v << " ! Should be in [0," << nbTuples << ") !";
6451           throw INTERP_KERNEL::Exception(oss.str().c_str());
6452         }
6453     }
6454   std::copy(tmp,tmp+nbTuples*nbOfCompo,getPointer());
6455   delete [] tmp;
6456   declareAsNew();
6457 }
6458
6459 /*!
6460  * Returns a copy of \a this array with values permuted as required by \a old2New array.
6461  * The values are permuted so that  \c new[ \a old2New[ i ]] = \c old[ i ].
6462  * Number of tuples in the result array remains the same as in \this one.
6463  * If a permutation reduction is needed, renumberAndReduce() should be used.
6464  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
6465  *  \param [in] old2New - C array of length equal to \a this->getNumberOfTuples()
6466  *          giving a new position for i-th old value.
6467  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
6468  *          is to delete using decrRef() as it is no more needed.
6469  *  \throw If \a this is not allocated.
6470  */
6471 DataArrayInt *DataArrayInt::renumber(const int *old2New) const throw(INTERP_KERNEL::Exception)
6472 {
6473   checkAllocated();
6474   int nbTuples=getNumberOfTuples();
6475   int nbOfCompo=getNumberOfComponents();
6476   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6477   ret->alloc(nbTuples,nbOfCompo);
6478   ret->copyStringInfoFrom(*this);
6479   const int *iptr=getConstPointer();
6480   int *optr=ret->getPointer();
6481   for(int i=0;i<nbTuples;i++)
6482     std::copy(iptr+nbOfCompo*i,iptr+nbOfCompo*(i+1),optr+nbOfCompo*old2New[i]);
6483   ret->copyStringInfoFrom(*this);
6484   return ret.retn();
6485 }
6486
6487 /*!
6488  * Returns a copy of \a this array with values permuted as required by \a new2Old array.
6489  * The values are permuted so that  \c new[ i ] = \c old[ \a new2Old[ i ]]. Number of
6490  * tuples in the result array remains the same as in \this one.
6491  * If a permutation reduction is needed, substr() or selectByTupleId() should be used.
6492  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
6493  *  \param [in] new2Old - C array of length equal to \a this->getNumberOfTuples()
6494  *     giving a previous position of i-th new value.
6495  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
6496  *          is to delete using decrRef() as it is no more needed.
6497  */
6498 DataArrayInt *DataArrayInt::renumberR(const int *new2Old) const throw(INTERP_KERNEL::Exception)
6499 {
6500   checkAllocated();
6501   int nbTuples=getNumberOfTuples();
6502   int nbOfCompo=getNumberOfComponents();
6503   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6504   ret->alloc(nbTuples,nbOfCompo);
6505   ret->copyStringInfoFrom(*this);
6506   const int *iptr=getConstPointer();
6507   int *optr=ret->getPointer();
6508   for(int i=0;i<nbTuples;i++)
6509     std::copy(iptr+nbOfCompo*new2Old[i],iptr+nbOfCompo*(new2Old[i]+1),optr+nbOfCompo*i);
6510   ret->copyStringInfoFrom(*this);
6511   return ret.retn();
6512 }
6513
6514 /*!
6515  * Returns a shorten and permuted copy of \a this array. The new DataArrayInt is
6516  * of size \a newNbOfTuple and it's values are permuted as required by \a old2New array.
6517  * The values are permuted so that  \c new[ \a old2New[ i ]] = \c old[ i ] for all
6518  * \a old2New[ i ] >= 0. In other words every i-th tuple in \a this array, for which 
6519  * \a old2New[ i ] is negative, is missing from the result array.
6520  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
6521  *  \param [in] old2New - C array of length equal to \a this->getNumberOfTuples()
6522  *     giving a new position for i-th old tuple and giving negative position for
6523  *     for i-th old tuple that should be omitted.
6524  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
6525  *          is to delete using decrRef() as it is no more needed.
6526  */
6527 DataArrayInt *DataArrayInt::renumberAndReduce(const int *old2New, int newNbOfTuple) const throw(INTERP_KERNEL::Exception)
6528 {
6529   checkAllocated();
6530   int nbTuples=getNumberOfTuples();
6531   int nbOfCompo=getNumberOfComponents();
6532   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6533   ret->alloc(newNbOfTuple,nbOfCompo);
6534   const int *iptr=getConstPointer();
6535   int *optr=ret->getPointer();
6536   for(int i=0;i<nbTuples;i++)
6537     {
6538       int w=old2New[i];
6539       if(w>=0)
6540         std::copy(iptr+i*nbOfCompo,iptr+(i+1)*nbOfCompo,optr+w*nbOfCompo);
6541     }
6542   ret->copyStringInfoFrom(*this);
6543   return ret.retn();
6544 }
6545
6546 /*!
6547  * Returns a shorten and permuted copy of \a this array. The new DataArrayInt is
6548  * of size \a new2OldEnd - \a new2OldBg and it's values are permuted as required by
6549  * \a new2OldBg array.
6550  * The values are permuted so that  \c new[ i ] = \c old[ \a new2OldBg[ i ]].
6551  * This method is equivalent to renumberAndReduce() except that convention in input is
6552  * \c new2old and \b not \c old2new.
6553  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
6554  *  \param [in] new2OldBg - pointer to the beginning of a permutation array that gives a
6555  *              tuple index in \a this array to fill the i-th tuple in the new array.
6556  *  \param [in] new2OldEnd - specifies the end of the permutation array that starts at
6557  *              \a new2OldBg, so that pointer to a tuple index (\a pi) varies as this:
6558  *              \a new2OldBg <= \a pi < \a new2OldEnd.
6559  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
6560  *          is to delete using decrRef() as it is no more needed.
6561  */
6562 DataArrayInt *DataArrayInt::selectByTupleId(const int *new2OldBg, const int *new2OldEnd) const
6563 {
6564   checkAllocated();
6565   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6566   int nbComp=getNumberOfComponents();
6567   ret->alloc((int)std::distance(new2OldBg,new2OldEnd),nbComp);
6568   ret->copyStringInfoFrom(*this);
6569   int *pt=ret->getPointer();
6570   const int *srcPt=getConstPointer();
6571   int i=0;
6572   for(const int *w=new2OldBg;w!=new2OldEnd;w++,i++)
6573     std::copy(srcPt+(*w)*nbComp,srcPt+((*w)+1)*nbComp,pt+i*nbComp);
6574   ret->copyStringInfoFrom(*this);
6575   return ret.retn();
6576 }
6577
6578 /*!
6579  * Returns a shorten and permuted copy of \a this array. The new DataArrayInt is
6580  * of size \a new2OldEnd - \a new2OldBg and it's values are permuted as required by
6581  * \a new2OldBg array.
6582  * The values are permuted so that  \c new[ i ] = \c old[ \a new2OldBg[ i ]].
6583  * This method is equivalent to renumberAndReduce() except that convention in input is
6584  * \c new2old and \b not \c old2new.
6585  * This method is equivalent to selectByTupleId() except that it prevents coping data
6586  * from behind the end of \a this array.
6587  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
6588  *  \param [in] new2OldBg - pointer to the beginning of a permutation array that gives a
6589  *              tuple index in \a this array to fill the i-th tuple in the new array.
6590  *  \param [in] new2OldEnd - specifies the end of the permutation array that starts at
6591  *              \a new2OldBg, so that pointer to a tuple index (\a pi) varies as this:
6592  *              \a new2OldBg <= \a pi < \a new2OldEnd.
6593  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
6594  *          is to delete using decrRef() as it is no more needed.
6595  *  \throw If \a new2OldEnd - \a new2OldBg > \a this->getNumberOfTuples().
6596  */
6597 DataArrayInt *DataArrayInt::selectByTupleIdSafe(const int *new2OldBg, const int *new2OldEnd) const throw(INTERP_KERNEL::Exception)
6598 {
6599   checkAllocated();
6600   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6601   int nbComp=getNumberOfComponents();
6602   int oldNbOfTuples=getNumberOfTuples();
6603   ret->alloc((int)std::distance(new2OldBg,new2OldEnd),nbComp);
6604   ret->copyStringInfoFrom(*this);
6605   int *pt=ret->getPointer();
6606   const int *srcPt=getConstPointer();
6607   int i=0;
6608   for(const int *w=new2OldBg;w!=new2OldEnd;w++,i++)
6609     if(*w>=0 && *w<oldNbOfTuples)
6610       std::copy(srcPt+(*w)*nbComp,srcPt+((*w)+1)*nbComp,pt+i*nbComp);
6611     else
6612       throw INTERP_KERNEL::Exception("DataArrayInt::selectByTupleIdSafe : some ids has been detected to be out of [0,this->getNumberOfTuples) !");
6613   ret->copyStringInfoFrom(*this);
6614   return ret.retn();
6615 }
6616
6617 /*!
6618  * Returns a shorten copy of \a this array. The new DataArrayInt contains every
6619  * (\a bg + \c i * \a step)-th tuple of \a this array located before the \a end2-th
6620  * tuple. Indices of the selected tuples are the same as ones returned by the Python
6621  * command \c range( \a bg, \a end2, \a step ).
6622  * This method is equivalent to selectByTupleIdSafe() except that the input array is
6623  * not constructed explicitly.
6624  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
6625  *  \param [in] bg - index of the first tuple to copy from \a this array.
6626  *  \param [in] end2 - index of the tuple before which the tuples to copy are located.
6627  *  \param [in] step - index increment to get index of the next tuple to copy.
6628  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
6629  *          is to delete using decrRef() as it is no more needed.
6630  *  \sa DataArrayInt::substr.
6631  */
6632 DataArrayInt *DataArrayInt::selectByTupleId2(int bg, int end2, int step) const throw(INTERP_KERNEL::Exception)
6633 {
6634   checkAllocated();
6635   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6636   int nbComp=getNumberOfComponents();
6637   int newNbOfTuples=GetNumberOfItemGivenBESRelative(bg,end2,step,"DataArrayInt::selectByTupleId2 : ");
6638   ret->alloc(newNbOfTuples,nbComp);
6639   int *pt=ret->getPointer();
6640   const int *srcPt=getConstPointer()+bg*nbComp;
6641   for(int i=0;i<newNbOfTuples;i++,srcPt+=step*nbComp)
6642     std::copy(srcPt,srcPt+nbComp,pt+i*nbComp);
6643   ret->copyStringInfoFrom(*this);
6644   return ret.retn();
6645 }
6646
6647 /*!
6648  * Returns a shorten copy of \a this array. The new DataArrayInt contains ranges
6649  * of tuples specified by \a ranges parameter.
6650  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
6651  *  \param [in] ranges - std::vector of std::pair's each of which defines a range
6652  *              of tuples in [\c begin,\c end) format.
6653  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
6654  *          is to delete using decrRef() as it is no more needed.
6655  *  \throw If \a end < \a begin.
6656  *  \throw If \a end > \a this->getNumberOfTuples().
6657  *  \throw If \a this is not allocated.
6658  */
6659 DataArray *DataArrayInt::selectByTupleRanges(const std::vector<std::pair<int,int> >& ranges) const throw(INTERP_KERNEL::Exception)
6660 {
6661   checkAllocated();
6662   int nbOfComp=getNumberOfComponents();
6663   int nbOfTuplesThis=getNumberOfTuples();
6664   if(ranges.empty())
6665     {
6666       MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6667       ret->alloc(0,nbOfComp);
6668       ret->copyStringInfoFrom(*this);
6669       return ret.retn();
6670     }
6671   int ref=ranges.front().first;
6672   int nbOfTuples=0;
6673   bool isIncreasing=true;
6674   for(std::vector<std::pair<int,int> >::const_iterator it=ranges.begin();it!=ranges.end();it++)
6675     {
6676       if((*it).first<=(*it).second)
6677         {
6678           if((*it).first>=0 && (*it).second<=nbOfTuplesThis)
6679             {
6680               nbOfTuples+=(*it).second-(*it).first;
6681               if(isIncreasing)
6682                 isIncreasing=ref<=(*it).first;
6683               ref=(*it).second;
6684             }
6685           else
6686             {
6687               std::ostringstream oss; oss << "DataArrayInt::selectByTupleRanges : on range #" << std::distance(ranges.begin(),it);
6688               oss << " (" << (*it).first << "," << (*it).second << ") is greater than number of tuples of this :" << nbOfTuples << " !";
6689               throw INTERP_KERNEL::Exception(oss.str().c_str());
6690             }
6691         }
6692       else
6693         {
6694           std::ostringstream oss; oss << "DataArrayInt::selectByTupleRanges : on range #" << std::distance(ranges.begin(),it);
6695           oss << " (" << (*it).first << "," << (*it).second << ") end is before begin !";
6696           throw INTERP_KERNEL::Exception(oss.str().c_str());
6697         }
6698     }
6699   if(isIncreasing && nbOfTuplesThis==nbOfTuples)
6700     return deepCpy();
6701   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6702   ret->alloc(nbOfTuples,nbOfComp);
6703   ret->copyStringInfoFrom(*this);
6704   const int *src=getConstPointer();
6705   int *work=ret->getPointer();
6706   for(std::vector<std::pair<int,int> >::const_iterator it=ranges.begin();it!=ranges.end();it++)
6707     work=std::copy(src+(*it).first*nbOfComp,src+(*it).second*nbOfComp,work);
6708   return ret.retn();
6709 }
6710
6711 /*!
6712  * Returns a new DataArrayInt containing a renumbering map in "Old to New" mode.
6713  * This map, if applied to \a this array, would make it sorted. For example, if
6714  * \a this array contents are [9,10,0,6,4,11,3,7] then the contents of the result array
6715  * are [5,6,0,3,2,7,1,4]; if this result array (\a res) is used as an argument in call
6716  * \a this->renumber(\a res) then the returned array contains [0,3,4,6,7,9,10,11].
6717  * This method is useful for renumbering (in MED file for example). For more info
6718  * on renumbering see \ref MEDCouplingArrayRenumbering.
6719  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
6720  *          array using decrRef() as it is no more needed.
6721  *  \throw If \a this is not allocated.
6722  *  \throw If \a this->getNumberOfComponents() != 1.
6723  *  \throw If there are equal values in \a this array.
6724  */
6725 DataArrayInt *DataArrayInt::checkAndPreparePermutation() const throw(INTERP_KERNEL::Exception)
6726 {
6727   checkAllocated();
6728   if(getNumberOfComponents()!=1)
6729     throw INTERP_KERNEL::Exception("DataArrayInt::checkAndPreparePermutation : number of components must == 1 !");
6730   int nbTuples=getNumberOfTuples();
6731   const int *pt=getConstPointer();
6732   int *pt2=CheckAndPreparePermutation(pt,pt+nbTuples);
6733   DataArrayInt *ret=DataArrayInt::New();
6734   ret->useArray(pt2,true,C_DEALLOC,nbTuples,1);
6735   return ret;
6736 }
6737
6738 /*!
6739  * Returns two arrays describing a surjective mapping from \a this set of values (\a A)
6740  * onto a set of values of size \a targetNb (\a B). The surjective function is 
6741  * \a B[ \a A[ i ]] = i. That is to say that for each \a id in [0,\a targetNb), where \a
6742  * targetNb < \a this->getNumberOfTuples(), there exists at least one tupleId (\a tid) so
6743  * that <em> this->getIJ( tid, 0 ) == id</em>. <br>
6744  * The first of out arrays returns indices of elements of \a this array, grouped by their
6745  * place in the set \a B. The second out array is the index of the first one; it shows how
6746  * many elements of \a A are mapped into each element of \a B. <br>
6747  * For more info on
6748  * mapping and its usage in renumbering see \ref MEDCouplingArrayRenumbering. <br>
6749  * \b Example:
6750  * - \a this: [0,3,2,3,2,2,1,2]
6751  * - \a targetNb: 4
6752  * - \a arr:  [0,  6,  2,4,5,7,  1,3]
6753  * - \a arrI: [0,1,2,6,8]
6754  *
6755  * This result means: <br>
6756  * the element of \a B 0 encounters within \a A once (\a arrI[ 0+1 ] - \a arrI[ 0 ]) and
6757  * its index within \a A is 0 ( \a arr[ 0:1 ] == \a arr[ \a arrI[ 0 ] : \a arrI[ 0+1 ]]);<br>
6758  * the element of \a B 2 encounters within \a A 4 times (\a arrI[ 2+1 ] - \a arrI[ 2 ]) and
6759  * its indices within \a A are [2,4,5,7] ( \a arr[ 2:6 ] == \a arr[ \a arrI[ 2 ] : 
6760  * \a arrI[ 2+1 ]]); <br> etc.
6761  *  \param [in] targetNb - the size of the set \a B. \a targetNb must be equal or more
6762  *         than the maximal value of \a A.
6763  *  \param [out] arr - a new instance of DataArrayInt returning indices of
6764  *         elements of \a this, grouped by their place in the set \a B. The caller is to delete
6765  *         this array using decrRef() as it is no more needed.
6766  *  \param [out] arrI - a new instance of DataArrayInt returning size of groups of equal
6767  *         elements of \a this. The caller is to delete this array using decrRef() as it
6768  *         is no more needed.
6769  *  \throw If \a this is not allocated.
6770  *  \throw If \a this->getNumberOfComponents() != 1.
6771  *  \throw If any value in \a this is more or equal to \a targetNb.
6772  */
6773 void DataArrayInt::changeSurjectiveFormat(int targetNb, DataArrayInt *&arr, DataArrayInt *&arrI) const throw(INTERP_KERNEL::Exception)
6774 {
6775   checkAllocated();
6776   if(getNumberOfComponents()!=1)
6777     throw INTERP_KERNEL::Exception("DataArrayInt::changeSurjectiveFormat : number of components must == 1 !");
6778   int nbOfTuples=getNumberOfTuples();
6779   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New());
6780   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> retI(DataArrayInt::New());
6781   retI->alloc(targetNb+1,1);
6782   const int *input=getConstPointer();
6783   std::vector< std::vector<int> > tmp(targetNb);
6784   for(int i=0;i<nbOfTuples;i++)
6785     {
6786       int tmp2=input[i];
6787       if(tmp2>=0 && tmp2<targetNb)
6788         tmp[tmp2].push_back(i);
6789       else
6790         {
6791           std::ostringstream oss; oss << "DataArrayInt::changeSurjectiveFormat : At pos " << i << " presence of element " << tmp2 << " ! should be in [0," << targetNb << ") !";
6792           throw INTERP_KERNEL::Exception(oss.str().c_str());
6793         }
6794     }
6795   int *retIPtr=retI->getPointer();
6796   *retIPtr=0;
6797   for(std::vector< std::vector<int> >::const_iterator it1=tmp.begin();it1!=tmp.end();it1++,retIPtr++)
6798     retIPtr[1]=retIPtr[0]+(int)((*it1).size());
6799   if(nbOfTuples!=retI->getIJ(targetNb,0))
6800     throw INTERP_KERNEL::Exception("DataArrayInt::changeSurjectiveFormat : big problem should never happen !");
6801   ret->alloc(nbOfTuples,1);
6802   int *retPtr=ret->getPointer();
6803   for(std::vector< std::vector<int> >::const_iterator it1=tmp.begin();it1!=tmp.end();it1++)
6804     retPtr=std::copy((*it1).begin(),(*it1).end(),retPtr);
6805   arr=ret.retn();
6806   arrI=retI.retn();
6807 }
6808
6809
6810 /*!
6811  * Returns a new DataArrayInt containing a renumbering map in "Old to New" mode computed
6812  * from a zip representation of a surjective format (returned e.g. by
6813  * \ref ParaMEDMEM::DataArrayDouble::findCommonTuples() "DataArrayDouble::findCommonTuples()"
6814  * for example). The result array minimizes the permutation. <br>
6815  * For more info on renumbering see \ref MEDCouplingArrayRenumbering. <br>
6816  * \b Example: <br>
6817  * - \a nbOfOldTuples: 10 
6818  * - \a arr          : [0,3, 5,7,9]
6819  * - \a arrIBg       : [0,2,5]
6820  * - \a newNbOfTuples: 7
6821  * - result array    : [0,1,2,0,3,4,5,4,6,4]
6822  *
6823  *  \param [in] nbOfOldTuples - number of tuples in the initial array \a arr.
6824  *  \param [in] arr - the array of tuple indices grouped by \a arrIBg array.
6825  *  \param [in] arrIBg - the array dividing all indices stored in \a arr into groups of
6826  *         (indices of) equal values. Its every element (except the last one) points to
6827  *         the first element of a group of equal values.
6828  *  \param [in] arrIEnd - specifies the end of \a arrIBg, so that the last element of \a
6829  *          arrIBg is \a arrIEnd[ -1 ].
6830  *  \param [out] newNbOfTuples - number of tuples after surjection application.
6831  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
6832  *          array using decrRef() as it is no more needed.
6833  *  \throw If any value of \a arr breaks condition ( 0 <= \a arr[ i ] < \a nbOfOldTuples ).
6834  */
6835 DataArrayInt *DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2(int nbOfOldTuples, const int *arr, const int *arrIBg, const int *arrIEnd, int &newNbOfTuples) throw(INTERP_KERNEL::Exception)
6836 {
6837   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6838   ret->alloc(nbOfOldTuples,1);
6839   int *pt=ret->getPointer();
6840   std::fill(pt,pt+nbOfOldTuples,-1);
6841   int nbOfGrps=((int)std::distance(arrIBg,arrIEnd))-1;
6842   const int *cIPtr=arrIBg;
6843   for(int i=0;i<nbOfGrps;i++)
6844     pt[arr[cIPtr[i]]]=-(i+2);
6845   int newNb=0;
6846   for(int iNode=0;iNode<nbOfOldTuples;iNode++)
6847     {
6848       if(pt[iNode]<0)
6849         {
6850           if(pt[iNode]==-1)
6851             pt[iNode]=newNb++;
6852           else
6853             {
6854               int grpId=-(pt[iNode]+2);
6855               for(int j=cIPtr[grpId];j<cIPtr[grpId+1];j++)
6856                 {
6857                   if(arr[j]>=0 && arr[j]<nbOfOldTuples)
6858                     pt[arr[j]]=newNb;
6859                   else
6860                     {
6861                       std::ostringstream oss; oss << "DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2 : With element #" << j << " value is " << arr[j] << " should be in [0," << nbOfOldTuples << ") !";
6862                       throw INTERP_KERNEL::Exception(oss.str().c_str());
6863                     }
6864                 }
6865               newNb++;
6866             }
6867         }
6868     }
6869   newNbOfTuples=newNb;
6870   return ret.retn();
6871 }
6872
6873 /*!
6874  * Returns a new DataArrayInt containing a renumbering map in "New to Old" mode,
6875  * which if applied to \a this array would make it sorted ascendingly.
6876  * For more info on renumbering see \ref MEDCouplingArrayRenumbering. <br>
6877  * \b Example: <br>
6878  * - \a this: [2,0,1,1,0,1,2,0,1,1,0,0]
6879  * - result: [10,0,5,6,1,7,11,2,8,9,3,4]
6880  * - after applying result to \a this: [0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2] 
6881  *
6882  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
6883  *          array using decrRef() as it is no more needed.
6884  *  \throw If \a this is not allocated.
6885  *  \throw If \a this->getNumberOfComponents() != 1.
6886  */
6887 DataArrayInt *DataArrayInt::buildPermArrPerLevel() const throw(INTERP_KERNEL::Exception)
6888 {
6889   checkAllocated();
6890   if(getNumberOfComponents()!=1)
6891     throw INTERP_KERNEL::Exception("DataArrayInt::buildPermArrPerLevel : number of components must == 1 !");
6892   int nbOfTuples=getNumberOfTuples();
6893   const int *pt=getConstPointer();
6894   std::map<int,int> m;
6895   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6896   ret->alloc(nbOfTuples,1);
6897   int *opt=ret->getPointer();
6898   for(int i=0;i<nbOfTuples;i++,pt++,opt++)
6899     {
6900       int val=*pt;
6901       std::map<int,int>::iterator it=m.find(val);
6902       if(it!=m.end())
6903         {
6904           *opt=(*it).second;
6905           (*it).second++;
6906         }
6907       else
6908         {
6909           *opt=0;
6910           m.insert(std::pair<int,int>(val,1));
6911         }
6912     }
6913   int sum=0;
6914   for(std::map<int,int>::iterator it=m.begin();it!=m.end();it++)
6915     {
6916       int vt=(*it).second;
6917       (*it).second=sum;
6918       sum+=vt;
6919     }
6920   pt=getConstPointer();
6921   opt=ret->getPointer();
6922   for(int i=0;i<nbOfTuples;i++,pt++,opt++)
6923     *opt+=m[*pt];
6924   //
6925   return ret.retn();
6926 }
6927
6928 /*!
6929  * Checks if contents of \a this array are equal to that of an array filled with
6930  * iota(). This method is particularly useful for DataArrayInt instances that represent
6931  * a renumbering array to check the real need in renumbering. 
6932  *  \return bool - \a true if \a this array contents == \a range( \a this->getNumberOfTuples())
6933  *  \throw If \a this is not allocated.
6934  *  \throw If \a this->getNumberOfComponents() != 1.
6935  */
6936 bool DataArrayInt::isIdentity() const throw(INTERP_KERNEL::Exception)
6937 {
6938   checkAllocated();
6939   if(getNumberOfComponents()!=1)
6940     return false;
6941   int nbOfTuples=getNumberOfTuples();
6942   const int *pt=getConstPointer();
6943   for(int i=0;i<nbOfTuples;i++,pt++)
6944     if(*pt!=i)
6945       return false;
6946   return true;
6947 }
6948
6949 /*!
6950  * Checks if all values in \a this array are equal to \a val.
6951  *  \param [in] val - value to check equality of array values to.
6952  *  \return bool - \a true if all values are \a val.
6953  *  \throw If \a this is not allocated.
6954  *  \throw If \a this->getNumberOfComponents() != 1
6955  */
6956 bool DataArrayInt::isUniform(int val) const throw(INTERP_KERNEL::Exception)
6957 {
6958   checkAllocated();
6959   if(getNumberOfComponents()!=1)
6960     throw INTERP_KERNEL::Exception("DataArrayInt::isUniform : must be applied on DataArrayInt with only one component, you can call 'rearrange' method before !");
6961   int nbOfTuples=getNumberOfTuples();
6962   const int *w=getConstPointer();
6963   const int *end2=w+nbOfTuples;
6964   for(;w!=end2;w++)
6965     if(*w!=val)
6966       return false;
6967   return true;
6968 }
6969
6970 /*!
6971  * Creates a new DataArrayDouble and assigns all (textual and numerical) data of \a this
6972  * array to the new one.
6973  *  \return DataArrayDouble * - the new instance of DataArrayInt.
6974  */
6975 DataArrayDouble *DataArrayInt::convertToDblArr() const
6976 {
6977   checkAllocated();
6978   DataArrayDouble *ret=DataArrayDouble::New();
6979   ret->alloc(getNumberOfTuples(),getNumberOfComponents());
6980   std::size_t nbOfVals=getNbOfElems();
6981   const int *src=getConstPointer();
6982   double *dest=ret->getPointer();
6983   std::copy(src,src+nbOfVals,dest);
6984   ret->copyStringInfoFrom(*this);
6985   return ret;
6986 }
6987
6988 /*!
6989  * Returns a shorten copy of \a this array. The new DataArrayInt contains all
6990  * tuples starting from the \a tupleIdBg-th tuple and including all tuples located before
6991  * the \a tupleIdEnd-th one. This methods has a similar behavior as std::string::substr().
6992  * This method is a specialization of selectByTupleId2().
6993  *  \param [in] tupleIdBg - index of the first tuple to copy from \a this array.
6994  *  \param [in] tupleIdEnd - index of the tuple before which the tuples to copy are located.
6995  *          If \a tupleIdEnd == -1, all the tuples till the end of \a this array are copied.
6996  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
6997  *          is to delete using decrRef() as it is no more needed.
6998  *  \throw If \a tupleIdBg < 0.
6999  *  \throw If \a tupleIdBg > \a this->getNumberOfTuples().
7000     \throw If \a tupleIdEnd != -1 && \a tupleIdEnd < \a this->getNumberOfTuples().
7001  *  \sa DataArrayInt::selectByTupleId2
7002  */
7003 DataArrayInt *DataArrayInt::substr(int tupleIdBg, int tupleIdEnd) const throw(INTERP_KERNEL::Exception)
7004 {
7005   checkAllocated();
7006   int nbt=getNumberOfTuples();
7007   if(tupleIdBg<0)
7008     throw INTERP_KERNEL::Exception("DataArrayInt::substr : The tupleIdBg parameter must be greater than 0 !");
7009   if(tupleIdBg>nbt)
7010     throw INTERP_KERNEL::Exception("DataArrayInt::substr : The tupleIdBg parameter is greater than number of tuples !");
7011   int trueEnd=tupleIdEnd;
7012   if(tupleIdEnd!=-1)
7013     {
7014       if(tupleIdEnd>nbt)
7015         throw INTERP_KERNEL::Exception("DataArrayInt::substr : The tupleIdBg parameter is greater or equal than number of tuples !");
7016     }
7017   else
7018     trueEnd=nbt;
7019   int nbComp=getNumberOfComponents();
7020   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
7021   ret->alloc(trueEnd-tupleIdBg,nbComp);
7022   ret->copyStringInfoFrom(*this);
7023   std::copy(getConstPointer()+tupleIdBg*nbComp,getConstPointer()+trueEnd*nbComp,ret->getPointer());
7024   return ret.retn();
7025 }
7026
7027 /*!
7028  * Changes the number of components within \a this array so that its raw data **does
7029  * not** change, instead splitting this data into tuples changes.
7030  *  \warning This method erases all (name and unit) component info set before!
7031  *  \param [in] newNbOfComp - number of components for \a this array to have.
7032  *  \throw If \a this is not allocated
7033  *  \throw If getNbOfElems() % \a newNbOfCompo != 0.
7034  *  \throw If \a newNbOfCompo is lower than 1.
7035  *  \throw If the rearrange method would lead to a number of tuples higher than 2147483647 (maximal capacity of int32 !).
7036  *  \warning This method erases all (name and unit) component info set before!
7037  */
7038 void DataArrayInt::rearrange(int newNbOfCompo) throw(INTERP_KERNEL::Exception)
7039 {
7040   checkAllocated();
7041   if(newNbOfCompo<1)
7042     throw INTERP_KERNEL::Exception("DataArrayInt::rearrange : input newNbOfCompo must be > 0 !");
7043   std::size_t nbOfElems=getNbOfElems();
7044   if(nbOfElems%newNbOfCompo!=0)
7045     throw INTERP_KERNEL::Exception("DataArrayInt::rearrange : nbOfElems%newNbOfCompo!=0 !");
7046   if(nbOfElems/newNbOfCompo>(std::size_t)std::numeric_limits<int>::max())
7047     throw INTERP_KERNEL::Exception("DataArrayInt::rearrange : the rearrangement leads to too high number of tuples (> 2147483647) !");
7048   _info_on_compo.clear();
7049   _info_on_compo.resize(newNbOfCompo);
7050   declareAsNew();
7051 }
7052
7053 /*!
7054  * Changes the number of components within \a this array to be equal to its number
7055  * of tuples, and inversely its number of tuples to become equal to its number of 
7056  * components. So that its raw data **does not** change, instead splitting this
7057  * data into tuples changes.
7058  *  \warning This method erases all (name and unit) component info set before!
7059  *  \warning Do not confuse this method with fromNoInterlace() and toNoInterlace()!
7060  *  \throw If \a this is not allocated.
7061  *  \sa rearrange()
7062  */
7063 void DataArrayInt::transpose() throw(INTERP_KERNEL::Exception)
7064 {
7065   checkAllocated();
7066   int nbOfTuples=getNumberOfTuples();
7067   rearrange(nbOfTuples);
7068 }
7069
7070 /*!
7071  * Returns a shorten or extended copy of \a this array. If \a newNbOfComp is less
7072  * than \a this->getNumberOfComponents() then the result array is shorten as each tuple
7073  * is truncated to have \a newNbOfComp components, keeping first components. If \a
7074  * newNbOfComp is more than \a this->getNumberOfComponents() then the result array is
7075  * expanded as each tuple is populated with \a dftValue to have \a newNbOfComp
7076  * components.  
7077  *  \param [in] newNbOfComp - number of components for the new array to have.
7078  *  \param [in] dftValue - value assigned to new values added to the new array.
7079  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
7080  *          is to delete using decrRef() as it is no more needed.
7081  *  \throw If \a this is not allocated.
7082  */
7083 DataArrayInt *DataArrayInt::changeNbOfComponents(int newNbOfComp, int dftValue) const throw(INTERP_KERNEL::Exception)
7084 {
7085   checkAllocated();
7086   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
7087   ret->alloc(getNumberOfTuples(),newNbOfComp);
7088   const int *oldc=getConstPointer();
7089   int *nc=ret->getPointer();
7090   int nbOfTuples=getNumberOfTuples();
7091   int oldNbOfComp=getNumberOfComponents();
7092   int dim=std::min(oldNbOfComp,newNbOfComp);
7093   for(int i=0;i<nbOfTuples;i++)
7094     {
7095       int j=0;
7096       for(;j<dim;j++)
7097         nc[newNbOfComp*i+j]=oldc[i*oldNbOfComp+j];
7098       for(;j<newNbOfComp;j++)
7099         nc[newNbOfComp*i+j]=dftValue;
7100     }
7101   ret->setName(getName().c_str());
7102   for(int i=0;i<dim;i++)
7103     ret->setInfoOnComponent(i,getInfoOnComponent(i).c_str());
7104   ret->setName(getName().c_str());
7105   return ret.retn();
7106 }
7107
7108 /*!
7109  * Changes number of tuples in the array. If the new number of tuples is smaller
7110  * than the current number the array is truncated, otherwise the array is extended.
7111  *  \param [in] nbOfTuples - new number of tuples. 
7112  *  \throw If \a this is not allocated.
7113  */
7114 void DataArrayInt::reAlloc(int nbOfTuples) throw(INTERP_KERNEL::Exception)
7115 {
7116   checkAllocated();
7117   _mem.reAlloc(getNumberOfComponents()*(std::size_t)nbOfTuples);
7118   declareAsNew();
7119 }
7120
7121
7122 /*!
7123  * Returns a copy of \a this array composed of selected components.
7124  * The new DataArrayInt has the same number of tuples but includes components
7125  * specified by \a compoIds parameter. So that getNbOfElems() of the result array
7126  * can be either less, same or more than \a this->getNbOfElems().
7127  *  \param [in] compoIds - sequence of zero based indices of components to include
7128  *              into the new array.
7129  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
7130  *          is to delete using decrRef() as it is no more needed.
7131  *  \throw If \a this is not allocated.
7132  *  \throw If a component index (\a i) is not valid: 
7133  *         \a i < 0 || \a i >= \a this->getNumberOfComponents().
7134  *
7135  *  \ref py_mcdataarrayint_keepselectedcomponents "Here is a Python example".
7136  */
7137 DataArray *DataArrayInt::keepSelectedComponents(const std::vector<int>& compoIds) const throw(INTERP_KERNEL::Exception)
7138 {
7139   checkAllocated();
7140   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New());
7141   int newNbOfCompo=(int)compoIds.size();
7142   int oldNbOfCompo=getNumberOfComponents();
7143   for(std::vector<int>::const_iterator it=compoIds.begin();it!=compoIds.end();it++)
7144     DataArray::CheckValueInRange(oldNbOfCompo,(*it),"keepSelectedComponents invalid requested component");
7145   int nbOfTuples=getNumberOfTuples();
7146   ret->alloc(nbOfTuples,newNbOfCompo);
7147   ret->copyPartOfStringInfoFrom(*this,compoIds);
7148   const int *oldc=getConstPointer();
7149   int *nc=ret->getPointer();
7150   for(int i=0;i<nbOfTuples;i++)
7151     for(int j=0;j<newNbOfCompo;j++,nc++)
7152       *nc=oldc[i*oldNbOfCompo+compoIds[j]];
7153   return ret.retn();
7154 }
7155
7156 /*!
7157  * Appends components of another array to components of \a this one, tuple by tuple.
7158  * So that the number of tuples of \a this array remains the same and the number of 
7159  * components increases.
7160  *  \param [in] other - the DataArrayInt to append to \a this one.
7161  *  \throw If \a this is not allocated.
7162  *  \throw If \a this and \a other arrays have different number of tuples.
7163  *
7164  *  \ref cpp_mcdataarrayint_meldwith "Here is a C++ example".
7165  *
7166  *  \ref py_mcdataarrayint_meldwith "Here is a Python example".
7167  */
7168 void DataArrayInt::meldWith(const DataArrayInt *other) throw(INTERP_KERNEL::Exception)
7169 {
7170   if(!other)
7171     throw INTERP_KERNEL::Exception("DataArrayInt::meldWith : DataArrayInt pointer in input is NULL !");
7172   checkAllocated();
7173   other->checkAllocated();
7174   int nbOfTuples=getNumberOfTuples();
7175   if(nbOfTuples!=other->getNumberOfTuples())
7176     throw INTERP_KERNEL::Exception("DataArrayInt::meldWith : mismatch of number of tuples !");
7177   int nbOfComp1=getNumberOfComponents();
7178   int nbOfComp2=other->getNumberOfComponents();
7179   int *newArr=(int *)malloc(nbOfTuples*(nbOfComp1+nbOfComp2)*sizeof(int));
7180   int *w=newArr;
7181   const int *inp1=getConstPointer();
7182   const int *inp2=other->getConstPointer();
7183   for(int i=0;i<nbOfTuples;i++,inp1+=nbOfComp1,inp2+=nbOfComp2)
7184     {
7185       w=std::copy(inp1,inp1+nbOfComp1,w);
7186       w=std::copy(inp2,inp2+nbOfComp2,w);
7187     }
7188   useArray(newArr,true,C_DEALLOC,nbOfTuples,nbOfComp1+nbOfComp2);
7189   std::vector<int> compIds(nbOfComp2);
7190   for(int i=0;i<nbOfComp2;i++)
7191     compIds[i]=nbOfComp1+i;
7192   copyPartOfStringInfoFrom2(compIds,*other);
7193 }
7194
7195 /*!
7196  * Copy all components in a specified order from another DataArrayInt.
7197  * The specified components become the first ones in \a this array.
7198  * Both numerical and textual data is copied. The number of tuples in \a this and
7199  * the other array can be different.
7200  *  \param [in] a - the array to copy data from.
7201  *  \param [in] compoIds - sequence of zero based indices of components, data of which is
7202  *              to be copied.
7203  *  \throw If \a a is NULL.
7204  *  \throw If \a compoIds.size() != \a a->getNumberOfComponents().
7205  *  \throw If \a compoIds[i] < 0 or \a compoIds[i] > \a this->getNumberOfComponents().
7206  *
7207  *  \ref py_mcdataarrayint_setselectedcomponents "Here is a Python example".
7208  */
7209 void DataArrayInt::setSelectedComponents(const DataArrayInt *a, const std::vector<int>& compoIds) throw(INTERP_KERNEL::Exception)
7210 {
7211   if(!a)
7212     throw INTERP_KERNEL::Exception("DataArrayInt::setSelectedComponents : input DataArrayInt is NULL !");
7213   checkAllocated();
7214   a->checkAllocated();
7215   copyPartOfStringInfoFrom2(compoIds,*a);
7216   std::size_t partOfCompoSz=compoIds.size();
7217   int nbOfCompo=getNumberOfComponents();
7218   int nbOfTuples=std::min(getNumberOfTuples(),a->getNumberOfTuples());
7219   const int *ac=a->getConstPointer();
7220   int *nc=getPointer();
7221   for(int i=0;i<nbOfTuples;i++)
7222     for(std::size_t j=0;j<partOfCompoSz;j++,ac++)
7223       nc[nbOfCompo*i+compoIds[j]]=*ac;
7224 }
7225
7226 /*!
7227  * Copy all values from another DataArrayInt into specified tuples and components
7228  * of \a this array. Textual data is not copied.
7229  * The tree parameters defining set of indices of tuples and components are similar to
7230  * the tree parameters of the Python function \c range(\c start,\c stop,\c step).
7231  *  \param [in] a - the array to copy values from.
7232  *  \param [in] bgTuples - index of the first tuple of \a this array to assign values to.
7233  *  \param [in] endTuples - index of the tuple before which the tuples to assign to
7234  *              are located.
7235  *  \param [in] stepTuples - index increment to get index of the next tuple to assign to.
7236  *  \param [in] bgComp - index of the first component of \a this array to assign values to.
7237  *  \param [in] endComp - index of the component before which the components to assign
7238  *              to are located.
7239  *  \param [in] stepComp - index increment to get index of the next component to assign to.
7240  *  \param [in] strictCompoCompare - if \a true (by default), then \a a->getNumberOfComponents() 
7241  *              must be equal to the number of columns to assign to, else an
7242  *              exception is thrown; if \a false, then it is only required that \a
7243  *              a->getNbOfElems() equals to number of values to assign to (this condition
7244  *              must be respected even if \a strictCompoCompare is \a true). The number of 
7245  *              values to assign to is given by following Python expression:
7246  *              \a nbTargetValues = 
7247  *              \c len(\c range(\a bgTuples,\a endTuples,\a stepTuples)) *
7248  *              \c len(\c range(\a bgComp,\a endComp,\a stepComp)).
7249  *  \throw If \a a is NULL.
7250  *  \throw If \a a is not allocated.
7251  *  \throw If \a this is not allocated.
7252  *  \throw If parameters specifying tuples and components to assign to do not give a
7253  *            non-empty range of increasing indices.
7254  *  \throw If \a a->getNbOfElems() != \a nbTargetValues.
7255  *  \throw If \a strictCompoCompare == \a true && \a a->getNumberOfComponents() !=
7256  *            \c len(\c range(\a bgComp,\a endComp,\a stepComp)).
7257  *
7258  *  \ref py_mcdataarrayint_setpartofvalues1 "Here is a Python example".
7259  */
7260 void DataArrayInt::setPartOfValues1(const DataArrayInt *a, int bgTuples, int endTuples, int stepTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare) throw(INTERP_KERNEL::Exception)
7261 {
7262   if(!a)
7263     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValues1 : DataArrayInt pointer in input is NULL !");
7264   const char msg[]="DataArrayInt::setPartOfValues1";
7265   checkAllocated();
7266   a->checkAllocated();
7267   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
7268   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
7269   int nbComp=getNumberOfComponents();
7270   int nbOfTuples=getNumberOfTuples();
7271   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
7272   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
7273   bool assignTech=true;
7274   if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
7275     {
7276       if(strictCompoCompare)
7277         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
7278     }
7279   else
7280     {
7281       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
7282       assignTech=false;
7283     }
7284   int *pt=getPointer()+bgTuples*nbComp+bgComp;
7285   const int *srcPt=a->getConstPointer();
7286   if(assignTech)
7287     {
7288       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
7289         for(int j=0;j<newNbOfComp;j++,srcPt++)
7290           pt[j*stepComp]=*srcPt;
7291     }
7292   else
7293     {
7294       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
7295         {
7296           const int *srcPt2=srcPt;
7297           for(int j=0;j<newNbOfComp;j++,srcPt2++)
7298             pt[j*stepComp]=*srcPt2;
7299         }
7300     }
7301 }
7302
7303 /*!
7304  * Assign a given value to values at specified tuples and components of \a this array.
7305  * The tree parameters defining set of indices of tuples and components are similar to
7306  * the tree parameters of the Python function \c range(\c start,\c stop,\c step)..
7307  *  \param [in] a - the value to assign.
7308  *  \param [in] bgTuples - index of the first tuple of \a this array to assign to.
7309  *  \param [in] endTuples - index of the tuple before which the tuples to assign to
7310  *              are located.
7311  *  \param [in] stepTuples - index increment to get index of the next tuple to assign to.
7312  *  \param [in] bgComp - index of the first component of \a this array to assign to.
7313  *  \param [in] endComp - index of the component before which the components to assign
7314  *              to are located.
7315  *  \param [in] stepComp - index increment to get index of the next component to assign to.
7316  *  \throw If \a this is not allocated.
7317  *  \throw If parameters specifying tuples and components to assign to, do not give a
7318  *            non-empty range of increasing indices or indices are out of a valid range
7319  *            for \this array.
7320  *
7321  *  \ref py_mcdataarrayint_setpartofvaluessimple1 "Here is a Python example".
7322  */
7323 void DataArrayInt::setPartOfValuesSimple1(int a, int bgTuples, int endTuples, int stepTuples, int bgComp, int endComp, int stepComp) throw(INTERP_KERNEL::Exception)
7324 {
7325   const char msg[]="DataArrayInt::setPartOfValuesSimple1";
7326   checkAllocated();
7327   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
7328   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
7329   int nbComp=getNumberOfComponents();
7330   int nbOfTuples=getNumberOfTuples();
7331   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
7332   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
7333   int *pt=getPointer()+bgTuples*nbComp+bgComp;
7334   for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
7335     for(int j=0;j<newNbOfComp;j++)
7336       pt[j*stepComp]=a;
7337 }
7338
7339
7340 /*!
7341  * Copy all values from another DataArrayInt (\a a) into specified tuples and 
7342  * components of \a this array. Textual data is not copied.
7343  * The tuples and components to assign to are defined by C arrays of indices.
7344  * There are two *modes of usage*:
7345  * - If \a a->getNbOfElems() equals to number of values to assign to, then every value
7346  *   of \a a is assigned to its own location within \a this array. 
7347  * - If \a a includes one tuple, then all values of \a a are assigned to the specified
7348  *   components of every specified tuple of \a this array. In this mode it is required
7349  *   that \a a->getNumberOfComponents() equals to the number of specified components.
7350  * 
7351  *  \param [in] a - the array to copy values from.
7352  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
7353  *              assign values of \a a to.
7354  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
7355  *              pointer to a tuple index <em>(pi)</em> varies as this: 
7356  *              \a bgTuples <= \a pi < \a endTuples.
7357  *  \param [in] bgComp - pointer to an array of component indices of \a this array to
7358  *              assign values of \a a to.
7359  *  \param [in] endComp - specifies the end of the array \a bgTuples, so that
7360  *              pointer to a component index <em>(pi)</em> varies as this: 
7361  *              \a bgComp <= \a pi < \a endComp.
7362  *  \param [in] strictCompoCompare - this parameter is checked only if the
7363  *               *mode of usage* is the first; if it is \a true (default), 
7364  *               then \a a->getNumberOfComponents() must be equal 
7365  *               to the number of specified columns, else this is not required.
7366  *  \throw If \a a is NULL.
7367  *  \throw If \a a is not allocated.
7368  *  \throw If \a this is not allocated.
7369  *  \throw If any index of tuple/component given by <em>bgTuples / bgComp</em> is
7370  *         out of a valid range for \a this array.
7371  *  \throw In the first *mode of usage*, if <em>strictCompoCompare == true </em> and
7372  *         if <em> a->getNumberOfComponents() != (endComp - bgComp) </em>.
7373  *  \throw In the second *mode of usage*, if \a a->getNumberOfTuples() != 1 or
7374  *         <em> a->getNumberOfComponents() != (endComp - bgComp)</em>.
7375  *
7376  *  \ref py_mcdataarrayint_setpartofvalues2 "Here is a Python example".
7377  */
7378 void DataArrayInt::setPartOfValues2(const DataArrayInt *a, const int *bgTuples, const int *endTuples, const int *bgComp, const int *endComp, bool strictCompoCompare) throw(INTERP_KERNEL::Exception)
7379 {
7380   if(!a)
7381     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValues2 : DataArrayInt pointer in input is NULL !");
7382   const char msg[]="DataArrayInt::setPartOfValues2";
7383   checkAllocated();
7384   a->checkAllocated();
7385   int nbComp=getNumberOfComponents();
7386   int nbOfTuples=getNumberOfTuples();
7387   for(const int *z=bgComp;z!=endComp;z++)
7388     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
7389   int newNbOfTuples=(int)std::distance(bgTuples,endTuples);
7390   int newNbOfComp=(int)std::distance(bgComp,endComp);
7391   bool assignTech=true;
7392   if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
7393     {
7394       if(strictCompoCompare)
7395         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
7396     }
7397   else
7398     {
7399       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
7400       assignTech=false;
7401     }
7402   int *pt=getPointer();
7403   const int *srcPt=a->getConstPointer();
7404   if(assignTech)
7405     {    
7406       for(const int *w=bgTuples;w!=endTuples;w++)
7407         {
7408           DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
7409           for(const int *z=bgComp;z!=endComp;z++,srcPt++)
7410             {    
7411               pt[(std::size_t)(*w)*nbComp+(*z)]=*srcPt;
7412             }
7413         }
7414     }
7415   else
7416     {
7417       for(const int *w=bgTuples;w!=endTuples;w++)
7418         {
7419           const int *srcPt2=srcPt;
7420           DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
7421           for(const int *z=bgComp;z!=endComp;z++,srcPt2++)
7422             {    
7423               pt[(std::size_t)(*w)*nbComp+(*z)]=*srcPt2;
7424             }
7425         }
7426     }
7427 }
7428
7429 /*!
7430  * Assign a given value to values at specified tuples and components of \a this array.
7431  * The tuples and components to assign to are defined by C arrays of indices.
7432  *  \param [in] a - the value to assign.
7433  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
7434  *              assign \a a to.
7435  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
7436  *              pointer to a tuple index (\a pi) varies as this: 
7437  *              \a bgTuples <= \a pi < \a endTuples.
7438  *  \param [in] bgComp - pointer to an array of component indices of \a this array to
7439  *              assign \a a to.
7440  *  \param [in] endComp - specifies the end of the array \a bgTuples, so that
7441  *              pointer to a component index (\a pi) varies as this: 
7442  *              \a bgComp <= \a pi < \a endComp.
7443  *  \throw If \a this is not allocated.
7444  *  \throw If any index of tuple/component given by <em>bgTuples / bgComp</em> is
7445  *         out of a valid range for \a this array.
7446  *
7447  *  \ref py_mcdataarrayint_setpartofvaluessimple2 "Here is a Python example".
7448  */
7449 void DataArrayInt::setPartOfValuesSimple2(int a, const int *bgTuples, const int *endTuples, const int *bgComp, const int *endComp) throw(INTERP_KERNEL::Exception)
7450 {
7451   checkAllocated();
7452   int nbComp=getNumberOfComponents();
7453   int nbOfTuples=getNumberOfTuples();
7454   for(const int *z=bgComp;z!=endComp;z++)
7455     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
7456   int *pt=getPointer();
7457   for(const int *w=bgTuples;w!=endTuples;w++)
7458     for(const int *z=bgComp;z!=endComp;z++)
7459       {
7460         DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
7461         pt[(std::size_t)(*w)*nbComp+(*z)]=a;
7462       }
7463 }
7464
7465 /*!
7466  * Copy all values from another DataArrayInt (\a a) into specified tuples and 
7467  * components of \a this array. Textual data is not copied.
7468  * The tuples to assign to are defined by a C array of indices.
7469  * The components to assign to are defined by three values similar to parameters of
7470  * the Python function \c range(\c start,\c stop,\c step).
7471  * There are two *modes of usage*:
7472  * - If \a a->getNbOfElems() equals to number of values to assign to, then every value
7473  *   of \a a is assigned to its own location within \a this array. 
7474  * - If \a a includes one tuple, then all values of \a a are assigned to the specified
7475  *   components of every specified tuple of \a this array. In this mode it is required
7476  *   that \a a->getNumberOfComponents() equals to the number of specified components.
7477  *
7478  *  \param [in] a - the array to copy values from.
7479  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
7480  *              assign values of \a a to.
7481  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
7482  *              pointer to a tuple index <em>(pi)</em> varies as this: 
7483  *              \a bgTuples <= \a pi < \a endTuples.
7484  *  \param [in] bgComp - index of the first component of \a this array to assign to.
7485  *  \param [in] endComp - index of the component before which the components to assign
7486  *              to are located.
7487  *  \param [in] stepComp - index increment to get index of the next component to assign to.
7488  *  \param [in] strictCompoCompare - this parameter is checked only in the first
7489  *               *mode of usage*; if \a strictCompoCompare is \a true (default), 
7490  *               then \a a->getNumberOfComponents() must be equal 
7491  *               to the number of specified columns, else this is not required.
7492  *  \throw If \a a is NULL.
7493  *  \throw If \a a is not allocated.
7494  *  \throw If \a this is not allocated.
7495  *  \throw If any index of tuple given by \a bgTuples is out of a valid range for 
7496  *         \a this array.
7497  *  \throw In the first *mode of usage*, if <em>strictCompoCompare == true </em> and
7498  *         if <em> a->getNumberOfComponents()</em> is unequal to the number of components
7499  *         defined by <em>(bgComp,endComp,stepComp)</em>.
7500  *  \throw In the second *mode of usage*, if \a a->getNumberOfTuples() != 1 or
7501  *         <em> a->getNumberOfComponents()</em> is unequal to the number of components
7502  *         defined by <em>(bgComp,endComp,stepComp)</em>.
7503  *  \throw If parameters specifying components to assign to, do not give a
7504  *            non-empty range of increasing indices or indices are out of a valid range
7505  *            for \this array.
7506  *
7507  *  \ref py_mcdataarrayint_setpartofvalues3 "Here is a Python example".
7508  */
7509 void DataArrayInt::setPartOfValues3(const DataArrayInt *a, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare) throw(INTERP_KERNEL::Exception)
7510 {
7511   if(!a)
7512     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValues3 : DataArrayInt pointer in input is NULL !");
7513   const char msg[]="DataArrayInt::setPartOfValues3";
7514   checkAllocated();
7515   a->checkAllocated();
7516   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
7517   int nbComp=getNumberOfComponents();
7518   int nbOfTuples=getNumberOfTuples();
7519   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
7520   int newNbOfTuples=(int)std::distance(bgTuples,endTuples);
7521   bool assignTech=true;
7522   if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
7523     {
7524       if(strictCompoCompare)
7525         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
7526     }
7527   else
7528     {
7529       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
7530       assignTech=false;
7531     }
7532   int *pt=getPointer()+bgComp;
7533   const int *srcPt=a->getConstPointer();
7534   if(assignTech)
7535     {
7536       for(const int *w=bgTuples;w!=endTuples;w++)
7537         for(int j=0;j<newNbOfComp;j++,srcPt++)
7538           {
7539             DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
7540             pt[(std::size_t)(*w)*nbComp+j*stepComp]=*srcPt;
7541           }
7542     }
7543   else
7544     {
7545       for(const int *w=bgTuples;w!=endTuples;w++)
7546         {
7547           const int *srcPt2=srcPt;
7548           for(int j=0;j<newNbOfComp;j++,srcPt2++)
7549             {
7550               DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
7551               pt[(std::size_t)(*w)*nbComp+j*stepComp]=*srcPt2;
7552             }
7553         }
7554     }
7555 }
7556
7557 /*!
7558  * Assign a given value to values at specified tuples and components of \a this array.
7559  * The tuples to assign to are defined by a C array of indices.
7560  * The components to assign to are defined by three values similar to parameters of
7561  * the Python function \c range(\c start,\c stop,\c step).
7562  *  \param [in] a - the value to assign.
7563  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
7564  *              assign \a a to.
7565  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
7566  *              pointer to a tuple index <em>(pi)</em> varies as this: 
7567  *              \a bgTuples <= \a pi < \a endTuples.
7568  *  \param [in] bgComp - index of the first component of \a this array to assign to.
7569  *  \param [in] endComp - index of the component before which the components to assign
7570  *              to are located.
7571  *  \param [in] stepComp - index increment to get index of the next component to assign to.
7572  *  \throw If \a this is not allocated.
7573  *  \throw If any index of tuple given by \a bgTuples is out of a valid range for 
7574  *         \a this array.
7575  *  \throw If parameters specifying components to assign to, do not give a
7576  *            non-empty range of increasing indices or indices are out of a valid range
7577  *            for \this array.
7578  *
7579  *  \ref py_mcdataarrayint_setpartofvaluessimple3 "Here is a Python example".
7580  */
7581 void DataArrayInt::setPartOfValuesSimple3(int a, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp) throw(INTERP_KERNEL::Exception)
7582 {
7583   const char msg[]="DataArrayInt::setPartOfValuesSimple3";
7584   checkAllocated();
7585   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
7586   int nbComp=getNumberOfComponents();
7587   int nbOfTuples=getNumberOfTuples();
7588   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
7589   int *pt=getPointer()+bgComp;
7590   for(const int *w=bgTuples;w!=endTuples;w++)
7591     for(int j=0;j<newNbOfComp;j++)
7592       {
7593         DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
7594         pt[(std::size_t)(*w)*nbComp+j*stepComp]=a;
7595       }
7596 }
7597
7598 void DataArrayInt::setPartOfValues4(const DataArrayInt *a, int bgTuples, int endTuples, int stepTuples, const int *bgComp, const int *endComp, bool strictCompoCompare) throw(INTERP_KERNEL::Exception)
7599 {
7600   if(!a)
7601     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValues4 : input DataArrayInt is NULL !");
7602   const char msg[]="DataArrayInt::setPartOfValues4";
7603   checkAllocated();
7604   a->checkAllocated();
7605   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
7606   int newNbOfComp=(int)std::distance(bgComp,endComp);
7607   int nbComp=getNumberOfComponents();
7608   for(const int *z=bgComp;z!=endComp;z++)
7609     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
7610   int nbOfTuples=getNumberOfTuples();
7611   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
7612   bool assignTech=true;
7613   if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
7614     {
7615       if(strictCompoCompare)
7616         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
7617     }
7618   else
7619     {
7620       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
7621       assignTech=false;
7622     }
7623   const int *srcPt=a->getConstPointer();
7624   int *pt=getPointer()+bgTuples*nbComp;
7625   if(assignTech)
7626     {
7627       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
7628         for(const int *z=bgComp;z!=endComp;z++,srcPt++)
7629           pt[*z]=*srcPt;
7630     }
7631   else
7632     {
7633       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
7634         {
7635           const int *srcPt2=srcPt;
7636           for(const int *z=bgComp;z!=endComp;z++,srcPt2++)
7637             pt[*z]=*srcPt2;
7638         }
7639     }
7640 }
7641
7642 void DataArrayInt::setPartOfValuesSimple4(int a, int bgTuples, int endTuples, int stepTuples, const int *bgComp, const int *endComp) throw(INTERP_KERNEL::Exception)
7643 {
7644   const char msg[]="DataArrayInt::setPartOfValuesSimple4";
7645   checkAllocated();
7646   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
7647   int nbComp=getNumberOfComponents();
7648   for(const int *z=bgComp;z!=endComp;z++)
7649     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
7650   int nbOfTuples=getNumberOfTuples();
7651   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
7652   int *pt=getPointer()+bgTuples*nbComp;
7653   for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
7654     for(const int *z=bgComp;z!=endComp;z++)
7655       pt[*z]=a;
7656 }
7657
7658 /*!
7659  * Copy some tuples from another DataArrayInt into specified tuples
7660  * of \a this array. Textual data is not copied. Both arrays must have equal number of
7661  * components.
7662  * Both the tuples to assign and the tuples to assign to are defined by a DataArrayInt.
7663  * All components of selected tuples are copied.
7664  *  \param [in] a - the array to copy values from.
7665  *  \param [in] tuplesSelec - the array specifying both source tuples of \a a and
7666  *              target tuples of \a this. \a tuplesSelec has two components, and the
7667  *              first component specifies index of the source tuple and the second
7668  *              one specifies index of the target tuple.
7669  *  \throw If \a this is not allocated.
7670  *  \throw If \a a is NULL.
7671  *  \throw If \a a is not allocated.
7672  *  \throw If \a tuplesSelec is NULL.
7673  *  \throw If \a tuplesSelec is not allocated.
7674  *  \throw If <em>this->getNumberOfComponents() != a->getNumberOfComponents()</em>.
7675  *  \throw If \a tuplesSelec->getNumberOfComponents() != 2.
7676  *  \throw If any tuple index given by \a tuplesSelec is out of a valid range for 
7677  *         the corresponding (\a this or \a a) array.
7678  */
7679 void DataArrayInt::setPartOfValuesAdv(const DataArrayInt *a, const DataArrayInt *tuplesSelec) throw(INTERP_KERNEL::Exception)
7680 {
7681   if(!a || !tuplesSelec)
7682     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValuesAdv : DataArrayInt pointer in input is NULL !");
7683   checkAllocated();
7684   a->checkAllocated();
7685   tuplesSelec->checkAllocated();
7686   int nbOfComp=getNumberOfComponents();
7687   if(nbOfComp!=a->getNumberOfComponents())
7688     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValuesAdv : This and a do not have the same number of components !");
7689   if(tuplesSelec->getNumberOfComponents()!=2)
7690     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValuesAdv : Expecting to have a tuple selector DataArrayInt instance with exactly 2 components !");
7691   int thisNt=getNumberOfTuples();
7692   int aNt=a->getNumberOfTuples();
7693   int *valsToSet=getPointer();
7694   const int *valsSrc=a->getConstPointer();
7695   for(const int *tuple=tuplesSelec->begin();tuple!=tuplesSelec->end();tuple+=2)
7696     {
7697       if(tuple[1]>=0 && tuple[1]<aNt)
7698         {
7699           if(tuple[0]>=0 && tuple[0]<thisNt)
7700             std::copy(valsSrc+nbOfComp*tuple[1],valsSrc+nbOfComp*(tuple[1]+1),valsToSet+nbOfComp*tuple[0]);
7701           else
7702             {
7703               std::ostringstream oss; oss << "DataArrayInt::setPartOfValuesAdv : Tuple #" << std::distance(tuplesSelec->begin(),tuple)/2;
7704               oss << " of 'tuplesSelec' request of tuple id #" << tuple[0] << " in 'this' ! It should be in [0," << thisNt << ") !";
7705               throw INTERP_KERNEL::Exception(oss.str().c_str());
7706             }
7707         }
7708       else
7709         {
7710           std::ostringstream oss; oss << "DataArrayInt::setPartOfValuesAdv : Tuple #" << std::distance(tuplesSelec->begin(),tuple)/2;
7711           oss << " of 'tuplesSelec' request of tuple id #" << tuple[1] << " in 'a' ! It should be in [0," << aNt << ") !";
7712           throw INTERP_KERNEL::Exception(oss.str().c_str());
7713         }
7714     }
7715 }
7716
7717 /*!
7718  * Copy some tuples from another DataArrayInt (\a a) into contiguous tuples
7719  * of \a this array. Textual data is not copied. Both arrays must have equal number of
7720  * components.
7721  * The tuples to assign to are defined by index of the first tuple, and
7722  * their number is defined by \a tuplesSelec->getNumberOfTuples().
7723  * The tuples to copy are defined by values of a DataArrayInt.
7724  * All components of selected tuples are copied.
7725  *  \param [in] tupleIdStart - index of the first tuple of \a this array to assign
7726  *              values to.
7727  *  \param [in] a - the array to copy values from.
7728  *  \param [in] tuplesSelec - the array specifying tuples of \a a to copy.
7729  *  \throw If \a this is not allocated.
7730  *  \throw If \a a is NULL.
7731  *  \throw If \a a is not allocated.
7732  *  \throw If \a tuplesSelec is NULL.
7733  *  \throw If \a tuplesSelec is not allocated.
7734  *  \throw If <em>this->getNumberOfComponents() != a->getNumberOfComponents()</em>.
7735  *  \throw If \a tuplesSelec->getNumberOfComponents() != 1.
7736  *  \throw If <em>tupleIdStart + tuplesSelec->getNumberOfTuples() > this->getNumberOfTuples().</em>
7737  *  \throw If any tuple index given by \a tuplesSelec is out of a valid range for 
7738  *         \a a array.
7739  */
7740 void DataArrayInt::setContigPartOfSelectedValues(int tupleIdStart, const DataArray *aBase, const DataArrayInt *tuplesSelec) throw(INTERP_KERNEL::Exception)
7741 {
7742   if(!aBase || !tuplesSelec)
7743     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues : input DataArray is NULL !");
7744   const DataArrayInt *a=dynamic_cast<const DataArrayInt *>(aBase);
7745   if(!a)
7746     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues : input DataArray aBase is not a DataArrayInt !");
7747   checkAllocated();
7748   a->checkAllocated();
7749   tuplesSelec->checkAllocated();
7750   int nbOfComp=getNumberOfComponents();
7751   if(nbOfComp!=a->getNumberOfComponents())
7752     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues : This and a do not have the same number of components !");
7753   if(tuplesSelec->getNumberOfComponents()!=1)
7754     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues : Expecting to have a tuple selector DataArrayInt instance with exactly 1 component !");
7755   int thisNt=getNumberOfTuples();
7756   int aNt=a->getNumberOfTuples();
7757   int nbOfTupleToWrite=tuplesSelec->getNumberOfTuples();
7758   int *valsToSet=getPointer()+tupleIdStart*nbOfComp;
7759   if(tupleIdStart+nbOfTupleToWrite>thisNt)
7760     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues : invalid number range of values to write !");
7761   const int *valsSrc=a->getConstPointer();
7762   for(const int *tuple=tuplesSelec->begin();tuple!=tuplesSelec->end();tuple++,valsToSet+=nbOfComp)
7763     {
7764       if(*tuple>=0 && *tuple<aNt)
7765         {
7766           std::copy(valsSrc+nbOfComp*(*tuple),valsSrc+nbOfComp*(*tuple+1),valsToSet);
7767         }
7768       else
7769         {
7770           std::ostringstream oss; oss << "DataArrayInt::setContigPartOfSelectedValues : Tuple #" << std::distance(tuplesSelec->begin(),tuple);
7771           oss << " of 'tuplesSelec' request of tuple id #" << *tuple << " in 'a' ! It should be in [0," << aNt << ") !";
7772           throw INTERP_KERNEL::Exception(oss.str().c_str());
7773         }
7774     }
7775 }
7776
7777 /*!
7778  * Copy some tuples from another DataArrayInt (\a a) into contiguous tuples
7779  * of \a this array. Textual data is not copied. Both arrays must have equal number of
7780  * components.
7781  * The tuples to copy are defined by three values similar to parameters of
7782  * the Python function \c range(\c start,\c stop,\c step).
7783  * The tuples to assign to are defined by index of the first tuple, and
7784  * their number is defined by number of tuples to copy.
7785  * All components of selected tuples are copied.
7786  *  \param [in] tupleIdStart - index of the first tuple of \a this array to assign
7787  *              values to.
7788  *  \param [in] a - the array to copy values from.
7789  *  \param [in] bg - index of the first tuple to copy of the array \a a.
7790  *  \param [in] end2 - index of the tuple of \a a before which the tuples to copy
7791  *              are located.
7792  *  \param [in] step - index increment to get index of the next tuple to copy.
7793  *  \throw If \a this is not allocated.
7794  *  \throw If \a a is NULL.
7795  *  \throw If \a a is not allocated.
7796  *  \throw If <em>this->getNumberOfComponents() != a->getNumberOfComponents()</em>.
7797  *  \throw If <em>tupleIdStart + len(range(bg,end2,step)) > this->getNumberOfTuples().</em>
7798  *  \throw If parameters specifying tuples to copy, do not give a
7799  *            non-empty range of increasing indices or indices are out of a valid range
7800  *            for the array \a a.
7801  */
7802 void DataArrayInt::setContigPartOfSelectedValues2(int tupleIdStart, const DataArray *aBase, int bg, int end2, int step) throw(INTERP_KERNEL::Exception)
7803 {
7804   if(!aBase)
7805     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues2 : input DataArray is NULL !");
7806   const DataArrayInt *a=dynamic_cast<const DataArrayInt *>(aBase);
7807   if(!a)
7808     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues2 : input DataArray aBase is not a DataArrayInt !");
7809   checkAllocated();
7810   a->checkAllocated();
7811   int nbOfComp=getNumberOfComponents();
7812   const char msg[]="DataArrayInt::setContigPartOfSelectedValues2";
7813   int nbOfTupleToWrite=DataArray::GetNumberOfItemGivenBES(bg,end2,step,msg);
7814   if(nbOfComp!=a->getNumberOfComponents())
7815     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues2 : This and a do not have the same number of components !");
7816   int thisNt=getNumberOfTuples();
7817   int aNt=a->getNumberOfTuples();
7818   int *valsToSet=getPointer()+tupleIdStart*nbOfComp;
7819   if(tupleIdStart+nbOfTupleToWrite>thisNt)
7820     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues2 : invalid number range of values to write !");
7821   if(end2>aNt)
7822     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues2 : invalid range of values to read !");
7823   const int *valsSrc=a->getConstPointer()+bg*nbOfComp;
7824   for(int i=0;i<nbOfTupleToWrite;i++,valsToSet+=nbOfComp,valsSrc+=step*nbOfComp)
7825     {
7826       std::copy(valsSrc,valsSrc+nbOfComp,valsToSet);
7827     }
7828 }
7829
7830 /*!
7831  * Returns a value located at specified tuple and component.
7832  * This method is equivalent to DataArrayInt::getIJ() except that validity of
7833  * parameters is checked. So this method is safe but expensive if used to go through
7834  * all values of \a this.
7835  *  \param [in] tupleId - index of tuple of interest.
7836  *  \param [in] compoId - index of component of interest.
7837  *  \return double - value located by \a tupleId and \a compoId.
7838  *  \throw If \a this is not allocated.
7839  *  \throw If condition <em>( 0 <= tupleId < this->getNumberOfTuples() )</em> is violated.
7840  *  \throw If condition <em>( 0 <= compoId < this->getNumberOfComponents() )</em> is violated.
7841  */
7842 int DataArrayInt::getIJSafe(int tupleId, int compoId) const throw(INTERP_KERNEL::Exception)
7843 {
7844   checkAllocated();
7845   if(tupleId<0 || tupleId>=getNumberOfTuples())
7846     {
7847       std::ostringstream oss; oss << "DataArrayInt::getIJSafe : request for tupleId " << tupleId << " should be in [0," << getNumberOfTuples() << ") !";
7848       throw INTERP_KERNEL::Exception(oss.str().c_str());
7849     }
7850   if(compoId<0 || compoId>=getNumberOfComponents())
7851     {
7852       std::ostringstream oss; oss << "DataArrayInt::getIJSafe : request for compoId " << compoId << " should be in [0," << getNumberOfComponents() << ") !";
7853       throw INTERP_KERNEL::Exception(oss.str().c_str());
7854     }
7855   return _mem[tupleId*_info_on_compo.size()+compoId];
7856 }
7857
7858 /*!
7859  * Returns the first value of \a this. 
7860  *  \return int - the last value of \a this array.
7861  *  \throw If \a this is not allocated.
7862  *  \throw If \a this->getNumberOfComponents() != 1.
7863  *  \throw If \a this->getNumberOfTuples() < 1.
7864  */
7865 int DataArrayInt::front() const throw(INTERP_KERNEL::Exception)
7866 {
7867   checkAllocated();
7868   if(getNumberOfComponents()!=1)
7869     throw INTERP_KERNEL::Exception("DataArrayInt::front : number of components not equal to one !");
7870   int nbOfTuples=getNumberOfTuples();
7871   if(nbOfTuples<1)
7872     throw INTERP_KERNEL::Exception("DataArrayInt::front : number of tuples must be >= 1 !");
7873   return *(getConstPointer());
7874 }
7875
7876 /*!
7877  * Returns the last value of \a this. 
7878  *  \return int - the last value of \a this array.
7879  *  \throw If \a this is not allocated.
7880  *  \throw If \a this->getNumberOfComponents() != 1.
7881  *  \throw If \a this->getNumberOfTuples() < 1.
7882  */
7883 int DataArrayInt::back() const throw(INTERP_KERNEL::Exception)
7884 {
7885   checkAllocated();
7886   if(getNumberOfComponents()!=1)
7887     throw INTERP_KERNEL::Exception("DataArrayInt::back : number of components not equal to one !");
7888   int nbOfTuples=getNumberOfTuples();
7889   if(nbOfTuples<1)
7890     throw INTERP_KERNEL::Exception("DataArrayInt::back : number of tuples must be >= 1 !");
7891   return *(getConstPointer()+nbOfTuples-1);
7892 }
7893
7894 /*!
7895  * Assign pointer to one array to a pointer to another appay. Reference counter of
7896  * \a arrayToSet is incremented / decremented.
7897  *  \param [in] newArray - the pointer to array to assign to \a arrayToSet.
7898  *  \param [in,out] arrayToSet - the pointer to array to assign to.
7899  */
7900 void DataArrayInt::SetArrayIn(DataArrayInt *newArray, DataArrayInt* &arrayToSet)
7901 {
7902   if(newArray!=arrayToSet)
7903     {
7904       if(arrayToSet)
7905         arrayToSet->decrRef();
7906       arrayToSet=newArray;
7907       if(arrayToSet)
7908         arrayToSet->incrRef();
7909     }
7910 }
7911
7912 DataArrayIntIterator *DataArrayInt::iterator() throw(INTERP_KERNEL::Exception)
7913 {
7914   return new DataArrayIntIterator(this);
7915 }
7916
7917 /*!
7918  * Creates a new DataArrayInt containing IDs (indices) of tuples holding value equal to a
7919  * given one.
7920  *  \param [in] val - the value to find within \a this.
7921  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
7922  *          array using decrRef() as it is no more needed.
7923  *  \throw If \a this is not allocated.
7924  *  \throw If \a this->getNumberOfComponents() != 1.
7925  */
7926 DataArrayInt *DataArrayInt::getIdsEqual(int val) const throw(INTERP_KERNEL::Exception)
7927 {
7928   checkAllocated();
7929   if(getNumberOfComponents()!=1)
7930     throw INTERP_KERNEL::Exception("DataArrayInt::getIdsEqual : the array must have only one component, you can call 'rearrange' method before !");
7931   const int *cptr=getConstPointer();
7932   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
7933   int nbOfTuples=getNumberOfTuples();
7934   for(int i=0;i<nbOfTuples;i++,cptr++)
7935     if(*cptr==val)
7936       ret->pushBackSilent(i);
7937   return ret.retn();
7938 }
7939
7940 /*!
7941  * Creates a new DataArrayInt containing IDs (indices) of tuples holding value \b not
7942  * equal to a given one. 
7943  *  \param [in] val - the value to ignore within \a this.
7944  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
7945  *          array using decrRef() as it is no more needed.
7946  *  \throw If \a this is not allocated.
7947  *  \throw If \a this->getNumberOfComponents() != 1.
7948  */
7949 DataArrayInt *DataArrayInt::getIdsNotEqual(int val) const throw(INTERP_KERNEL::Exception)
7950 {
7951   checkAllocated();
7952   if(getNumberOfComponents()!=1)
7953     throw INTERP_KERNEL::Exception("DataArrayInt::getIdsNotEqual : the array must have only one component, you can call 'rearrange' method before !");
7954   const int *cptr=getConstPointer();
7955   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
7956   int nbOfTuples=getNumberOfTuples();
7957   for(int i=0;i<nbOfTuples;i++,cptr++)
7958     if(*cptr!=val)
7959       ret->pushBackSilent(i);
7960   return ret.retn();
7961 }
7962
7963
7964 /*!
7965  * Assigns \a newValue to all elements holding \a oldValue within \a this
7966  * one-dimensional array.
7967  *  \param [in] oldValue - the value to replace.
7968  *  \param [in] newValue - the value to assign.
7969  *  \return int - number of replacements performed.
7970  *  \throw If \a this is not allocated.
7971  *  \throw If \a this->getNumberOfComponents() != 1.
7972  */
7973 int DataArrayInt::changeValue(int oldValue, int newValue) throw(INTERP_KERNEL::Exception)
7974 {
7975   checkAllocated();
7976   if(getNumberOfComponents()!=1)
7977     throw INTERP_KERNEL::Exception("DataArrayInt::changeValue : the array must have only one component, you can call 'rearrange' method before !");
7978   int *start=getPointer();
7979   int *end2=start+getNbOfElems();
7980   int ret=0;
7981   for(int *val=start;val!=end2;val++)
7982     {
7983       if(*val==oldValue)
7984         {
7985           *val=newValue;
7986           ret++;
7987         }
7988     }
7989   return ret;
7990 }
7991
7992 /*!
7993  * Creates a new DataArrayInt containing IDs (indices) of tuples holding value equal to
7994  * one of given values.
7995  *  \param [in] valsBg - an array of values to find within \a this array.
7996  *  \param [in] valsEnd - specifies the end of the array \a valsBg, so that
7997  *              the last value of \a valsBg is \a valsEnd[ -1 ].
7998  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
7999  *          array using decrRef() as it is no more needed.
8000  *  \throw If \a this->getNumberOfComponents() != 1.
8001  */
8002 DataArrayInt *DataArrayInt::getIdsEqualList(const int *valsBg, const int *valsEnd) const throw(INTERP_KERNEL::Exception)
8003 {
8004   if(getNumberOfComponents()!=1)
8005     throw INTERP_KERNEL::Exception("DataArrayInt::getIdsEqualList : the array must have only one component, you can call 'rearrange' method before !");
8006   std::set<int> vals2(valsBg,valsEnd);
8007   const int *cptr=getConstPointer();
8008   std::vector<int> res;
8009   int nbOfTuples=getNumberOfTuples();
8010   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
8011   for(int i=0;i<nbOfTuples;i++,cptr++)
8012     if(vals2.find(*cptr)!=vals2.end())
8013       ret->pushBackSilent(i);
8014   return ret.retn();
8015 }
8016
8017 /*!
8018  * Creates a new DataArrayInt containing IDs (indices) of tuples holding values \b not
8019  * equal to any of given values.
8020  *  \param [in] valsBg - an array of values to ignore within \a this array.
8021  *  \param [in] valsEnd - specifies the end of the array \a valsBg, so that
8022  *              the last value of \a valsBg is \a valsEnd[ -1 ].
8023  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
8024  *          array using decrRef() as it is no more needed.
8025  *  \throw If \a this->getNumberOfComponents() != 1.
8026  */
8027 DataArrayInt *DataArrayInt::getIdsNotEqualList(const int *valsBg, const int *valsEnd) const throw(INTERP_KERNEL::Exception)
8028 {
8029   if(getNumberOfComponents()!=1)
8030     throw INTERP_KERNEL::Exception("DataArrayInt::getIdsNotEqualList : the array must have only one component, you can call 'rearrange' method before !");
8031   std::set<int> vals2(valsBg,valsEnd);
8032   const int *cptr=getConstPointer();
8033   std::vector<int> res;
8034   int nbOfTuples=getNumberOfTuples();
8035   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
8036   for(int i=0;i<nbOfTuples;i++,cptr++)
8037     if(vals2.find(*cptr)==vals2.end())
8038       ret->pushBackSilent(i);
8039   return ret.retn();
8040 }
8041
8042 /*!
8043  * This method is an extension of DataArrayInt::locateValue method because this method works for DataArrayInt with
8044  * any number of components excepted 0 (an INTERP_KERNEL::Exception is thrown in this case).
8045  * This method searches in \b this is there is a tuple that matched the input parameter \b tupl.
8046  * If any the tuple id is returned. If not -1 is returned.
8047  * 
8048  * This method throws an INTERP_KERNEL::Exception if the number of components in \b this mismatches with the size of
8049  * the input vector. An INTERP_KERNEL::Exception is thrown too if \b this is not allocated.
8050  *
8051  * \return tuple id where \b tupl is. -1 if no such tuple exists in \b this.
8052  * \sa DataArrayInt::search, DataArrayInt::presenceOfTuple.
8053  */
8054 int DataArrayInt::locateTuple(const std::vector<int>& tupl) const throw(INTERP_KERNEL::Exception)
8055 {
8056   checkAllocated();
8057   int nbOfCompo=getNumberOfComponents();
8058   if(nbOfCompo==0)
8059     throw INTERP_KERNEL::Exception("DataArrayInt::locateTuple : 0 components in 'this' !");
8060   if(nbOfCompo!=(int)tupl.size())
8061     {
8062       std::ostringstream oss; oss << "DataArrayInt::locateTuple : 'this' contains " << nbOfCompo << " components and searching for a tuple of length " << tupl.size() << " !";
8063       throw INTERP_KERNEL::Exception(oss.str().c_str());
8064     }
8065   const int *cptr=getConstPointer();
8066   std::size_t nbOfVals=getNbOfElems();
8067   for(const int *work=cptr;work!=cptr+nbOfVals;)
8068     {
8069       work=std::search(work,cptr+nbOfVals,tupl.begin(),tupl.end());
8070       if(work!=cptr+nbOfVals)
8071         {
8072           if(std::distance(cptr,work)%nbOfCompo!=0)
8073             work++;
8074           else
8075             return std::distance(cptr,work)/nbOfCompo;
8076         }
8077     }
8078   return -1;
8079 }
8080
8081 /*!
8082  * This method searches the sequence specified in input parameter \b vals in \b this.
8083  * This works only for DataArrayInt having number of components equal to one (if not an INTERP_KERNEL::Exception will be thrown).
8084  * This method differs from DataArrayInt::locateTuple in that the position is internal raw data is not considered here contrary to DataArrayInt::locateTuple.
8085  * \sa DataArrayInt::locateTuple
8086  */
8087 int DataArrayInt::search(const std::vector<int>& vals) const throw(INTERP_KERNEL::Exception)
8088 {
8089   checkAllocated();
8090   int nbOfCompo=getNumberOfComponents();
8091   if(nbOfCompo!=1)
8092     throw INTERP_KERNEL::Exception("DataArrayInt::search : works only for DataArrayInt instance with one component !");
8093   const int *cptr=getConstPointer();
8094   std::size_t nbOfVals=getNbOfElems();
8095   const int *loc=std::search(cptr,cptr+nbOfVals,vals.begin(),vals.end());
8096   if(loc!=cptr+nbOfVals)
8097     return std::distance(cptr,loc);
8098   return -1;
8099 }
8100
8101 /*!
8102  * This method expects to be called when number of components of this is equal to one.
8103  * This method returns the tuple id, if it exists, of the first tuple equal to \b value.
8104  * If not any tuple contains \b value -1 is returned.
8105  * \sa DataArrayInt::presenceOfValue
8106  */
8107 int DataArrayInt::locateValue(int value) const throw(INTERP_KERNEL::Exception)
8108 {
8109   checkAllocated();
8110   if(getNumberOfComponents()!=1)
8111     throw INTERP_KERNEL::Exception("DataArrayInt::presenceOfValue : the array must have only one component, you can call 'rearrange' method before !");
8112   const int *cptr=getConstPointer();
8113   int nbOfTuples=getNumberOfTuples();
8114   const int *ret=std::find(cptr,cptr+nbOfTuples,value);
8115   if(ret!=cptr+nbOfTuples)
8116     return std::distance(cptr,ret);
8117   return -1;
8118 }
8119
8120 /*!
8121  * This method expects to be called when number of components of this is equal to one.
8122  * This method returns the tuple id, if it exists, of the first tuple so that the value is contained in \b vals.
8123  * If not any tuple contains one of the values contained in 'vals' false is returned.
8124  * \sa DataArrayInt::presenceOfValue
8125  */
8126 int DataArrayInt::locateValue(const std::vector<int>& vals) const throw(INTERP_KERNEL::Exception)
8127 {
8128   checkAllocated();
8129   if(getNumberOfComponents()!=1)
8130     throw INTERP_KERNEL::Exception("DataArrayInt::presenceOfValue : the array must have only one component, you can call 'rearrange' method before !");
8131   std::set<int> vals2(vals.begin(),vals.end());
8132   const int *cptr=getConstPointer();
8133   int nbOfTuples=getNumberOfTuples();
8134   for(const int *w=cptr;w!=cptr+nbOfTuples;w++)
8135     if(vals2.find(*w)!=vals2.end())
8136       return std::distance(cptr,w);
8137   return -1;
8138 }
8139
8140 /*!
8141  * This method returns the number of values in \a this that are equals to input parameter \a value.
8142  * This method only works for single component array.
8143  *
8144  * \return a value in [ 0, \c this->getNumberOfTuples() )
8145  *
8146  * \throw If \a this is not allocated
8147  *
8148  */
8149 int DataArrayInt::count(int value) const throw(INTERP_KERNEL::Exception)
8150 {
8151   int ret=0;
8152   checkAllocated();
8153   if(getNumberOfComponents()!=1)
8154     throw INTERP_KERNEL::Exception("DataArrayInt::count : must be applied on DataArrayInt with only one component, you can call 'rearrange' method before !");
8155   const int *vals=begin();
8156   int nbOfTuples=getNumberOfTuples();
8157   for(int i=0;i<nbOfTuples;i++,vals++)
8158     if(*vals==value)
8159       ret++;
8160   return ret;
8161 }
8162
8163 /*!
8164  * This method is an extension of DataArrayInt::presenceOfValue method because this method works for DataArrayInt with
8165  * any number of components excepted 0 (an INTERP_KERNEL::Exception is thrown in this case).
8166  * This method searches in \b this is there is a tuple that matched the input parameter \b tupl.
8167  * This method throws an INTERP_KERNEL::Exception if the number of components in \b this mismatches with the size of
8168  * the input vector. An INTERP_KERNEL::Exception is thrown too if \b this is not allocated.
8169  * \sa DataArrayInt::locateTuple
8170  */
8171 bool DataArrayInt::presenceOfTuple(const std::vector<int>& tupl) const throw(INTERP_KERNEL::Exception)
8172 {
8173   return locateTuple(tupl)!=-1;
8174 }
8175
8176
8177 /*!
8178  * Returns \a true if a given value is present within \a this one-dimensional array.
8179  *  \param [in] value - the value to find within \a this array.
8180  *  \return bool - \a true in case if \a value is present within \a this array.
8181  *  \throw If \a this is not allocated.
8182  *  \throw If \a this->getNumberOfComponents() != 1.
8183  *  \sa locateValue()
8184  */
8185 bool DataArrayInt::presenceOfValue(int value) const throw(INTERP_KERNEL::Exception)
8186 {
8187   return locateValue(value)!=-1;
8188 }
8189
8190 /*!
8191  * This method expects to be called when number of components of this is equal to one.
8192  * This method returns true if it exists a tuple so that the value is contained in \b vals.
8193  * If not any tuple contains one of the values contained in 'vals' false is returned.
8194  * \sa DataArrayInt::locateValue
8195  */
8196 bool DataArrayInt::presenceOfValue(const std::vector<int>& vals) const throw(INTERP_KERNEL::Exception)
8197 {
8198   return locateValue(vals)!=-1;
8199 }
8200
8201 /*!
8202  * Accumulates values of each component of \a this array.
8203  *  \param [out] res - an array of length \a this->getNumberOfComponents(), allocated 
8204  *         by the caller, that is filled by this method with sum value for each
8205  *         component.
8206  *  \throw If \a this is not allocated.
8207  */
8208 void DataArrayInt::accumulate(int *res) const throw(INTERP_KERNEL::Exception)
8209 {
8210   checkAllocated();
8211   const int *ptr=getConstPointer();
8212   int nbTuple=getNumberOfTuples();
8213   int nbComps=getNumberOfComponents();
8214   std::fill(res,res+nbComps,0);
8215   for(int i=0;i<nbTuple;i++)
8216     std::transform(ptr+i*nbComps,ptr+(i+1)*nbComps,res,res,std::plus<int>());
8217 }
8218
8219 int DataArrayInt::accumulate(int compId) const throw(INTERP_KERNEL::Exception)
8220 {
8221   checkAllocated();
8222   const int *ptr=getConstPointer();
8223   int nbTuple=getNumberOfTuples();
8224   int nbComps=getNumberOfComponents();
8225   if(compId<0 || compId>=nbComps)
8226     throw INTERP_KERNEL::Exception("DataArrayInt::accumulate : Invalid compId specified : No such nb of components !");
8227   int ret=0;
8228   for(int i=0;i<nbTuple;i++)
8229     ret+=ptr[i*nbComps+compId];
8230   return ret;
8231 }
8232
8233 /*!
8234  * This method accumulate using addition tuples in \a this using input index array [ \a bgOfIndex, \a endOfIndex ).
8235  * The returned array will have same number of components than \a this and number of tuples equal to
8236  * \c std::distance(bgOfIndex,endOfIndex) \b minus \b one.
8237  *
8238  * The input index array is expected to be ascendingly sorted in which the all referenced ids should be in [0, \c this->getNumberOfTuples).
8239  *
8240  * \param [in] bgOfIndex - begin (included) of the input index array.
8241  * \param [in] endOfIndex - end (excluded) of the input index array.
8242  * \return DataArrayInt * - the new instance having the same number of components than \a this.
8243  * 
8244  * \throw If bgOfIndex or end is NULL.
8245  * \throw If input index array is not ascendingly sorted.
8246  * \throw If there is an id in [ \a bgOfIndex, \a endOfIndex ) not in [0, \c this->getNumberOfTuples).
8247  * \throw If std::distance(bgOfIndex,endOfIndex)==0.
8248  */
8249 DataArrayInt *DataArrayInt::accumulatePerChunck(const int *bgOfIndex, const int *endOfIndex) const throw(INTERP_KERNEL::Exception)
8250 {
8251   if(!bgOfIndex || !endOfIndex)
8252     throw INTERP_KERNEL::Exception("DataArrayInt::accumulatePerChunck : input pointer NULL !");
8253   checkAllocated();
8254   int nbCompo=getNumberOfComponents();
8255   int nbOfTuples=getNumberOfTuples();
8256   int sz=(int)std::distance(bgOfIndex,endOfIndex);
8257   if(sz<1)
8258     throw INTERP_KERNEL::Exception("DataArrayInt::accumulatePerChunck : invalid size of input index array !");
8259   sz--;
8260   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(sz,nbCompo);
8261   const int *w=bgOfIndex;
8262   if(*w<0 || *w>=nbOfTuples)
8263     throw INTERP_KERNEL::Exception("DataArrayInt::accumulatePerChunck : The first element of the input index not in [0,nbOfTuples) !");
8264   const int *srcPt=begin()+(*w)*nbCompo;
8265   int *tmp=ret->getPointer();
8266   for(int i=0;i<sz;i++,tmp+=nbCompo,w++)
8267     {
8268       std::fill(tmp,tmp+nbCompo,0.);
8269       if(w[1]>=w[0])
8270         {
8271           for(int j=w[0];j<w[1];j++,srcPt+=nbCompo)
8272             {
8273               if(j>=0 && j<nbOfTuples)
8274                 std::transform(srcPt,srcPt+nbCompo,tmp,tmp,std::plus<int>());
8275               else
8276                 {
8277                   std::ostringstream oss; oss << "DataArrayInt::accumulatePerChunck : At rank #" << i << " the input index array points to id " << j << " should be in [0," << nbOfTuples << ") !";
8278                   throw INTERP_KERNEL::Exception(oss.str().c_str());
8279                 }
8280             }
8281         }
8282       else
8283         {
8284           std::ostringstream oss; oss << "DataArrayInt::accumulatePerChunck : At rank #" << i << " the input index array is not in ascendingly sorted.";
8285           throw INTERP_KERNEL::Exception(oss.str().c_str());
8286         }
8287     }
8288   ret->copyStringInfoFrom(*this);
8289   return ret.retn();
8290 }
8291
8292 /*!
8293  * Returns a new DataArrayInt by concatenating two given arrays, so that (1) the number
8294  * of tuples in the result array is <em> a1->getNumberOfTuples() + a2->getNumberOfTuples() -
8295  * offsetA2</em> and (2)
8296  * the number of component in the result array is same as that of each of given arrays.
8297  * First \a offsetA2 tuples of \a a2 are skipped and thus are missing from the result array.
8298  * Info on components is copied from the first of the given arrays. Number of components
8299  * in the given arrays must be the same.
8300  *  \param [in] a1 - an array to include in the result array.
8301  *  \param [in] a2 - another array to include in the result array.
8302  *  \param [in] offsetA2 - number of tuples of \a a2 to skip.
8303  *  \return DataArrayInt * - the new instance of DataArrayInt.
8304  *          The caller is to delete this result array using decrRef() as it is no more
8305  *          needed.
8306  *  \throw If either \a a1 or \a a2 is NULL.
8307  *  \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents().
8308  */
8309 DataArrayInt *DataArrayInt::Aggregate(const DataArrayInt *a1, const DataArrayInt *a2, int offsetA2)
8310 {
8311   if(!a1 || !a2)
8312     throw INTERP_KERNEL::Exception("DataArrayInt::Aggregate : input DataArrayInt instance is NULL !");
8313   int nbOfComp=a1->getNumberOfComponents();
8314   if(nbOfComp!=a2->getNumberOfComponents())
8315     throw INTERP_KERNEL::Exception("Nb of components mismatch for array Aggregation !");
8316   int nbOfTuple1=a1->getNumberOfTuples();
8317   int nbOfTuple2=a2->getNumberOfTuples();
8318   DataArrayInt *ret=DataArrayInt::New();
8319   ret->alloc(nbOfTuple1+nbOfTuple2-offsetA2,nbOfComp);
8320   int *pt=std::copy(a1->getConstPointer(),a1->getConstPointer()+nbOfTuple1*nbOfComp,ret->getPointer());
8321   std::copy(a2->getConstPointer()+offsetA2*nbOfComp,a2->getConstPointer()+nbOfTuple2*nbOfComp,pt);
8322   ret->copyStringInfoFrom(*a1);
8323   return ret;
8324 }
8325
8326 /*!
8327  * Returns a new DataArrayInt by concatenating all given arrays, so that (1) the number
8328  * of tuples in the result array is a sum of the number of tuples of given arrays and (2)
8329  * the number of component in the result array is same as that of each of given arrays.
8330  * Info on components is copied from the first of the given arrays. Number of components
8331  * in the given arrays must be  the same.
8332  *  \param [in] arr - a sequence of arrays to include in the result array.
8333  *  \return DataArrayInt * - the new instance of DataArrayInt.
8334  *          The caller is to delete this result array using decrRef() as it is no more
8335  *          needed.
8336  *  \throw If all arrays within \a arr are NULL.
8337  *  \throw If getNumberOfComponents() of arrays within \a arr.
8338  */
8339 DataArrayInt *DataArrayInt::Aggregate(const std::vector<const DataArrayInt *>& arr) throw(INTERP_KERNEL::Exception)
8340 {
8341   std::vector<const DataArrayInt *> a;
8342   for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
8343     if(*it4)
8344       a.push_back(*it4);
8345   if(a.empty())
8346     throw INTERP_KERNEL::Exception("DataArrayInt::Aggregate : input list must be NON EMPTY !");
8347   std::vector<const DataArrayInt *>::const_iterator it=a.begin();
8348   int nbOfComp=(*it)->getNumberOfComponents();
8349   int nbt=(*it++)->getNumberOfTuples();
8350   for(int i=1;it!=a.end();it++,i++)
8351     {
8352       if((*it)->getNumberOfComponents()!=nbOfComp)
8353         throw INTERP_KERNEL::Exception("DataArrayInt::Aggregate : Nb of components mismatch for array aggregation !");
8354       nbt+=(*it)->getNumberOfTuples();
8355     }
8356   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
8357   ret->alloc(nbt,nbOfComp);
8358   int *pt=ret->getPointer();
8359   for(it=a.begin();it!=a.end();it++)
8360     pt=std::copy((*it)->getConstPointer(),(*it)->getConstPointer()+(*it)->getNbOfElems(),pt);
8361   ret->copyStringInfoFrom(*(a[0]));
8362   return ret.retn();
8363 }
8364
8365 /*!
8366  * This method takes as input a list of DataArrayInt instances \a arrs that represent each a packed index arrays.
8367  * A packed index array is an allocated array with one component, and at least one tuple. The first element
8368  * of each array in \a arrs must be 0. Each array in \a arrs is expected to be increasingly monotonic.
8369  * This method is useful for users that want to aggregate a pair of DataArrayInt representing an indexed data (typically nodal connectivity index in unstructured meshes.
8370  * 
8371  * \return DataArrayInt * - a new object to be managed by the caller.
8372  */
8373 DataArrayInt *DataArrayInt::AggregateIndexes(const std::vector<const DataArrayInt *>& arrs) throw(INTERP_KERNEL::Exception)
8374 {
8375   int retSz=1;
8376   for(std::vector<const DataArrayInt *>::const_iterator it4=arrs.begin();it4!=arrs.end();it4++)
8377     {
8378       if(*it4)
8379         {
8380           (*it4)->checkAllocated();
8381           if((*it4)->getNumberOfComponents()!=1)
8382             {
8383               std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a DataArrayInt instance with nb of compo != 1 at pos " << std::distance(arrs.begin(),it4) << " !";
8384               throw INTERP_KERNEL::Exception(oss.str().c_str());
8385             }
8386           int nbTupl=(*it4)->getNumberOfTuples();
8387           if(nbTupl<1)
8388             {
8389               std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a DataArrayInt instance with nb of tuples < 1 at pos " << std::distance(arrs.begin(),it4) << " !";
8390               throw INTERP_KERNEL::Exception(oss.str().c_str());
8391             }
8392           if((*it4)->front()!=0)
8393             {
8394               std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a DataArrayInt instance with front value != 0 at pos " << std::distance(arrs.begin(),it4) << " !";
8395               throw INTERP_KERNEL::Exception(oss.str().c_str());
8396             }
8397           retSz+=nbTupl-1;
8398         }
8399       else
8400         {
8401           std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a null instance at pos " << std::distance(arrs.begin(),it4) << " !";
8402           throw INTERP_KERNEL::Exception(oss.str().c_str());
8403         }
8404     }
8405   if(arrs.empty())
8406     throw INTERP_KERNEL::Exception("DataArrayInt::AggregateIndexes : input list must be NON EMPTY !");
8407   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
8408   ret->alloc(retSz,1);
8409   int *pt=ret->getPointer(); *pt++=0;
8410   for(std::vector<const DataArrayInt *>::const_iterator it=arrs.begin();it!=arrs.end();it++)
8411     pt=std::transform((*it)->begin()+1,(*it)->end(),pt,std::bind2nd(std::plus<int>(),pt[-1]));
8412   ret->copyStringInfoFrom(*(arrs[0]));
8413   return ret.retn();
8414 }
8415
8416 /*!
8417  * Returns the maximal value and its location within \a this one-dimensional array.
8418  *  \param [out] tupleId - index of the tuple holding the maximal value.
8419  *  \return int - the maximal value among all values of \a this array.
8420  *  \throw If \a this->getNumberOfComponents() != 1
8421  *  \throw If \a this->getNumberOfTuples() < 1
8422  */
8423 int DataArrayInt::getMaxValue(int& tupleId) const throw(INTERP_KERNEL::Exception)
8424 {
8425   checkAllocated();
8426   if(getNumberOfComponents()!=1)
8427     throw INTERP_KERNEL::Exception("DataArrayInt::getMaxValue : must be applied on DataArrayInt with only one component !");
8428   int nbOfTuples=getNumberOfTuples();
8429   if(nbOfTuples<=0)
8430     throw INTERP_KERNEL::Exception("DataArrayInt::getMaxValue : array exists but number of tuples must be > 0 !");
8431   const int *vals=getConstPointer();
8432   const int *loc=std::max_element(vals,vals+nbOfTuples);
8433   tupleId=(int)std::distance(vals,loc);
8434   return *loc;
8435 }
8436
8437 /*!
8438  * Returns the maximal value within \a this array that is allowed to have more than
8439  *  one component.
8440  *  \return int - the maximal value among all values of \a this array.
8441  *  \throw If \a this is not allocated.
8442  */
8443 int DataArrayInt::getMaxValueInArray() const throw(INTERP_KERNEL::Exception)
8444 {
8445   checkAllocated();
8446   const int *loc=std::max_element(begin(),end());
8447   return *loc;
8448 }
8449
8450 /*!
8451  * Returns the minimal value and its location within \a this one-dimensional array.
8452  *  \param [out] tupleId - index of the tuple holding the minimal value.
8453  *  \return int - the minimal value among all values of \a this array.
8454  *  \throw If \a this->getNumberOfComponents() != 1
8455  *  \throw If \a this->getNumberOfTuples() < 1
8456  */
8457 int DataArrayInt::getMinValue(int& tupleId) const throw(INTERP_KERNEL::Exception)
8458 {
8459   checkAllocated();
8460   if(getNumberOfComponents()!=1)
8461     throw INTERP_KERNEL::Exception("DataArrayInt::getMaxValue : must be applied on DataArrayInt with only one component !");
8462   int nbOfTuples=getNumberOfTuples();
8463   if(nbOfTuples<=0)
8464     throw INTERP_KERNEL::Exception("DataArrayInt::getMaxValue : array exists but number of tuples must be > 0 !");
8465   const int *vals=getConstPointer();
8466   const int *loc=std::min_element(vals,vals+nbOfTuples);
8467   tupleId=(int)std::distance(vals,loc);
8468   return *loc;
8469 }
8470
8471 /*!
8472  * Returns the minimal value within \a this array that is allowed to have more than
8473  *  one component.
8474  *  \return int - the minimal value among all values of \a this array.
8475  *  \throw If \a this is not allocated.
8476  */
8477 int DataArrayInt::getMinValueInArray() const throw(INTERP_KERNEL::Exception)
8478 {
8479   checkAllocated();
8480   const int *loc=std::min_element(begin(),end());
8481   return *loc;
8482 }
8483
8484 /*!
8485  * Converts every value of \a this array to its absolute value.
8486  *  \throw If \a this is not allocated.
8487  */
8488 void DataArrayInt::abs() throw(INTERP_KERNEL::Exception)
8489 {
8490   checkAllocated();
8491   int *ptr=getPointer();
8492   std::size_t nbOfElems=getNbOfElems();
8493   std::transform(ptr,ptr+nbOfElems,ptr,std::ptr_fun<int,int>(std::abs));
8494   declareAsNew();
8495 }
8496
8497 /*!
8498  * Apply a liner function to a given component of \a this array, so that
8499  * an array element <em>(x)</em> becomes \f$ a * x + b \f$.
8500  *  \param [in] a - the first coefficient of the function.
8501  *  \param [in] b - the second coefficient of the function.
8502  *  \param [in] compoId - the index of component to modify.
8503  *  \throw If \a this is not allocated.
8504  */
8505 void DataArrayInt::applyLin(int a, int b, int compoId) throw(INTERP_KERNEL::Exception)
8506 {
8507   checkAllocated();
8508   int *ptr=getPointer()+compoId;
8509   int nbOfComp=getNumberOfComponents();
8510   int nbOfTuple=getNumberOfTuples();
8511   for(int i=0;i<nbOfTuple;i++,ptr+=nbOfComp)
8512     *ptr=a*(*ptr)+b;
8513   declareAsNew();
8514 }
8515
8516 /*!
8517  * Apply a liner function to all elements of \a this array, so that
8518  * an element _x_ becomes \f$ a * x + b \f$.
8519  *  \param [in] a - the first coefficient of the function.
8520  *  \param [in] b - the second coefficient of the function.
8521  *  \throw If \a this is not allocated.
8522  */
8523 void DataArrayInt::applyLin(int a, int b) throw(INTERP_KERNEL::Exception)
8524 {
8525   checkAllocated();
8526   int *ptr=getPointer();
8527   std::size_t nbOfElems=getNbOfElems();
8528   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
8529     *ptr=a*(*ptr)+b;
8530   declareAsNew();
8531 }
8532
8533 /*!
8534  * Returns a full copy of \a this array except that sign of all elements is reversed.
8535  *  \return DataArrayInt * - the new instance of DataArrayInt containing the
8536  *          same number of tuples and component as \a this array.
8537  *          The caller is to delete this result array using decrRef() as it is no more
8538  *          needed.
8539  *  \throw If \a this is not allocated.
8540  */
8541 DataArrayInt *DataArrayInt::negate() const throw(INTERP_KERNEL::Exception)
8542 {
8543   checkAllocated();
8544   DataArrayInt *newArr=DataArrayInt::New();
8545   int nbOfTuples=getNumberOfTuples();
8546   int nbOfComp=getNumberOfComponents();
8547   newArr->alloc(nbOfTuples,nbOfComp);
8548   const int *cptr=getConstPointer();
8549   std::transform(cptr,cptr+nbOfTuples*nbOfComp,newArr->getPointer(),std::negate<int>());
8550   newArr->copyStringInfoFrom(*this);
8551   return newArr;
8552 }
8553
8554 /*!
8555  * Modify all elements of \a this array, so that
8556  * an element _x_ becomes \f$ numerator / x \f$.
8557  *  \warning If an exception is thrown because of presence of 0 element in \a this 
8558  *           array, all elements processed before detection of the zero element remain
8559  *           modified.
8560  *  \param [in] numerator - the numerator used to modify array elements.
8561  *  \throw If \a this is not allocated.
8562  *  \throw If there is an element equal to 0 in \a this array.
8563  */
8564 void DataArrayInt::applyInv(int numerator) throw(INTERP_KERNEL::Exception)
8565 {
8566   checkAllocated();
8567   int *ptr=getPointer();
8568   std::size_t nbOfElems=getNbOfElems();
8569   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
8570     {
8571       if(*ptr!=0)
8572         {
8573           *ptr=numerator/(*ptr);
8574         }
8575       else
8576         {
8577           std::ostringstream oss; oss << "DataArrayInt::applyInv : presence of null value in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
8578           oss << " !";
8579           throw INTERP_KERNEL::Exception(oss.str().c_str());
8580         }
8581     }
8582   declareAsNew();
8583 }
8584
8585 /*!
8586  * Modify all elements of \a this array, so that
8587  * an element _x_ becomes \f$ x / val \f$.
8588  *  \param [in] val - the denominator used to modify array elements.
8589  *  \throw If \a this is not allocated.
8590  *  \throw If \a val == 0.
8591  */
8592 void DataArrayInt::applyDivideBy(int val) throw(INTERP_KERNEL::Exception)
8593 {
8594   if(val==0)
8595     throw INTERP_KERNEL::Exception("DataArrayInt::applyDivideBy : Trying to divide by 0 !");
8596   checkAllocated();
8597   int *ptr=getPointer();
8598   std::size_t nbOfElems=getNbOfElems();
8599   std::transform(ptr,ptr+nbOfElems,ptr,std::bind2nd(std::divides<int>(),val));
8600   declareAsNew();
8601 }
8602
8603 /*!
8604  * Modify all elements of \a this array, so that
8605  * an element _x_ becomes  <em> x % val </em>.
8606  *  \param [in] val - the divisor used to modify array elements.
8607  *  \throw If \a this is not allocated.
8608  *  \throw If \a val <= 0.
8609  */
8610 void DataArrayInt::applyModulus(int val) throw(INTERP_KERNEL::Exception)
8611 {
8612   if(val<=0)
8613     throw INTERP_KERNEL::Exception("DataArrayInt::applyDivideBy : Trying to operate modulus on value <= 0 !");
8614   checkAllocated();
8615   int *ptr=getPointer();
8616   std::size_t nbOfElems=getNbOfElems();
8617   std::transform(ptr,ptr+nbOfElems,ptr,std::bind2nd(std::modulus<int>(),val));
8618   declareAsNew();
8619 }
8620
8621 /*!
8622  * This method works only on data array with one component.
8623  * This method returns a newly allocated array storing stored ascendantly tuple ids in \b this so that
8624  * this[*id] in [\b vmin,\b vmax)
8625  * 
8626  * \param [in] vmin begin of range. This value is included in range (included).
8627  * \param [in] vmax end of range. This value is \b not included in range (excluded).
8628  * \return a newly allocated data array that the caller should deal with.
8629  */
8630 DataArrayInt *DataArrayInt::getIdsInRange(int vmin, int vmax) const throw(INTERP_KERNEL::Exception)
8631 {
8632   checkAllocated();
8633   if(getNumberOfComponents()!=1)
8634     throw INTERP_KERNEL::Exception("DataArrayInt::getIdsInRange : this must have exactly one component !");
8635   const int *cptr=getConstPointer();
8636   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(0,1);
8637   int nbOfTuples=getNumberOfTuples();
8638   for(int i=0;i<nbOfTuples;i++,cptr++)
8639     if(*cptr>=vmin && *cptr<vmax)
8640       ret->pushBackSilent(i);
8641   return ret.retn();
8642 }
8643
8644 /*!
8645  * This method works only on data array with one component.
8646  * 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.
8647  * 
8648  * \param [in] vmin begin of range. This value is included in range (included).
8649  * \param [in] vmax end of range. This value is \b not included in range (excluded).
8650  * \return if all ids in \a this are so that (*this)[i]==i for all i in [ 0, \c this->getNumberOfTuples() ).
8651  */
8652 bool DataArrayInt::checkAllIdsInRange(int vmin, int vmax) const throw(INTERP_KERNEL::Exception)
8653 {
8654   checkAllocated();
8655   if(getNumberOfComponents()!=1)
8656     throw INTERP_KERNEL::Exception("DataArrayInt::checkAllIdsInRange : this must have exactly one component !");
8657   int nbOfTuples=getNumberOfTuples();
8658   bool ret=true;
8659   const int *cptr=getConstPointer();
8660   for(int i=0;i<nbOfTuples;i++,cptr++)
8661     {
8662       if(*cptr>=vmin && *cptr<vmax)
8663         { ret=ret && *cptr==i; }
8664       else
8665         {
8666           std::ostringstream oss; oss << "DataArrayInt::checkAllIdsInRange : tuple #" << i << " has value " << *cptr << " should be in [" << vmin << "," << vmax << ") !";
8667           throw INTERP_KERNEL::Exception(oss.str().c_str());
8668         }
8669     }
8670   return ret;
8671 }
8672
8673 /*!
8674  * Modify all elements of \a this array, so that
8675  * an element _x_ becomes <em> val % x </em>.
8676  *  \warning If an exception is thrown because of presence of an element <= 0 in \a this 
8677  *           array, all elements processed before detection of the zero element remain
8678  *           modified.
8679  *  \param [in] val - the divident used to modify array elements.
8680  *  \throw If \a this is not allocated.
8681  *  \throw If there is an element equal to or less than 0 in \a this array.
8682  */
8683 void DataArrayInt::applyRModulus(int val) throw(INTERP_KERNEL::Exception)
8684 {
8685   checkAllocated();
8686   int *ptr=getPointer();
8687   std::size_t nbOfElems=getNbOfElems();
8688   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
8689     {
8690       if(*ptr>0)
8691         {
8692           *ptr=val%(*ptr);
8693         }
8694       else
8695         {
8696           std::ostringstream oss; oss << "DataArrayInt::applyRModulus : presence of value <=0 in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
8697           oss << " !";
8698           throw INTERP_KERNEL::Exception(oss.str().c_str());
8699         }
8700     }
8701   declareAsNew();
8702 }
8703
8704 /*!
8705  * Modify all elements of \a this array, so that
8706  * an element _x_ becomes <em> val ^ x </em>.
8707  *  \param [in] val - the value used to apply pow on all array elements.
8708  *  \throw If \a this is not allocated.
8709  *  \throw If \a val < 0.
8710  */
8711 void DataArrayInt::applyPow(int val) throw(INTERP_KERNEL::Exception)
8712 {
8713   checkAllocated();
8714   if(val<0)
8715     throw INTERP_KERNEL::Exception("DataArrayInt::applyPow : input pow in < 0 !");
8716   int *ptr=getPointer();
8717   std::size_t nbOfElems=getNbOfElems();
8718   if(val==0)
8719     {
8720       std::fill(ptr,ptr+nbOfElems,1.);
8721       return ;
8722     }
8723   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
8724     {
8725       int tmp=1;
8726       for(int j=0;j<val;j++)
8727         tmp*=*ptr;
8728       *ptr=tmp;
8729     }
8730   declareAsNew();
8731 }
8732
8733 /*!
8734  * Modify all elements of \a this array, so that
8735  * an element _x_ becomes \f$ val ^ x \f$.
8736  *  \param [in] val - the value used to apply pow on all array elements.
8737  *  \throw If \a this is not allocated.
8738  *  \throw If there is an element < 0 in \a this array.
8739  *  \warning If an exception is thrown because of presence of 0 element in \a this 
8740  *           array, all elements processed before detection of the zero element remain
8741  *           modified.
8742  */
8743 void DataArrayInt::applyRPow(int val) throw(INTERP_KERNEL::Exception)
8744 {
8745   checkAllocated();
8746   int *ptr=getPointer();
8747   std::size_t nbOfElems=getNbOfElems();
8748   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
8749     {
8750       if(*ptr>=0)
8751         {
8752           int tmp=1;
8753           for(int j=0;j<*ptr;j++)
8754             tmp*=val;
8755           *ptr=tmp;
8756         }
8757       else
8758         {
8759           std::ostringstream oss; oss << "DataArrayInt::applyRPow : presence of negative value in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
8760           oss << " !";
8761           throw INTERP_KERNEL::Exception(oss.str().c_str());
8762         }
8763     }
8764   declareAsNew();
8765 }
8766
8767 /*!
8768  * Returns a new DataArrayInt by aggregating two given arrays, so that (1) the number
8769  * of components in the result array is a sum of the number of components of given arrays
8770  * and (2) the number of tuples in the result array is same as that of each of given
8771  * arrays. In other words the i-th tuple of result array includes all components of
8772  * i-th tuples of all given arrays.
8773  * Number of tuples in the given arrays must be the same.
8774  *  \param [in] a1 - an array to include in the result array.
8775  *  \param [in] a2 - another array to include in the result array.
8776  *  \return DataArrayInt * - the new instance of DataArrayInt.
8777  *          The caller is to delete this result array using decrRef() as it is no more
8778  *          needed.
8779  *  \throw If both \a a1 and \a a2 are NULL.
8780  *  \throw If any given array is not allocated.
8781  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
8782  */
8783 DataArrayInt *DataArrayInt::Meld(const DataArrayInt *a1, const DataArrayInt *a2) throw(INTERP_KERNEL::Exception)
8784 {
8785   std::vector<const DataArrayInt *> arr(2);
8786   arr[0]=a1; arr[1]=a2;
8787   return Meld(arr);
8788 }
8789
8790 /*!
8791  * Returns a new DataArrayInt by aggregating all given arrays, so that (1) the number
8792  * of components in the result array is a sum of the number of components of given arrays
8793  * and (2) the number of tuples in the result array is same as that of each of given
8794  * arrays. In other words the i-th tuple of result array includes all components of
8795  * i-th tuples of all given arrays.
8796  * Number of tuples in the given arrays must be  the same.
8797  *  \param [in] arr - a sequence of arrays to include in the result array.
8798  *  \return DataArrayInt * - the new instance of DataArrayInt.
8799  *          The caller is to delete this result array using decrRef() as it is no more
8800  *          needed.
8801  *  \throw If all arrays within \a arr are NULL.
8802  *  \throw If any given array is not allocated.
8803  *  \throw If getNumberOfTuples() of arrays within \a arr is different.
8804  */
8805 DataArrayInt *DataArrayInt::Meld(const std::vector<const DataArrayInt *>& arr) throw(INTERP_KERNEL::Exception)
8806 {
8807   std::vector<const DataArrayInt *> a;
8808   for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
8809     if(*it4)
8810       a.push_back(*it4);
8811   if(a.empty())
8812     throw INTERP_KERNEL::Exception("DataArrayInt::Meld : array must be NON empty !");
8813   std::vector<const DataArrayInt *>::const_iterator it;
8814   for(it=a.begin();it!=a.end();it++)
8815     (*it)->checkAllocated();
8816   it=a.begin();
8817   int nbOfTuples=(*it)->getNumberOfTuples();
8818   std::vector<int> nbc(a.size());
8819   std::vector<const int *> pts(a.size());
8820   nbc[0]=(*it)->getNumberOfComponents();
8821   pts[0]=(*it++)->getConstPointer();
8822   for(int i=1;it!=a.end();it++,i++)
8823     {
8824       if(nbOfTuples!=(*it)->getNumberOfTuples())
8825         throw INTERP_KERNEL::Exception("DataArrayInt::meld : mismatch of number of tuples !");
8826       nbc[i]=(*it)->getNumberOfComponents();
8827       pts[i]=(*it)->getConstPointer();
8828     }
8829   int totalNbOfComp=std::accumulate(nbc.begin(),nbc.end(),0);
8830   DataArrayInt *ret=DataArrayInt::New();
8831   ret->alloc(nbOfTuples,totalNbOfComp);
8832   int *retPtr=ret->getPointer();
8833   for(int i=0;i<nbOfTuples;i++)
8834     for(int j=0;j<(int)a.size();j++)
8835       {
8836         retPtr=std::copy(pts[j],pts[j]+nbc[j],retPtr);
8837         pts[j]+=nbc[j];
8838       }
8839   int k=0;
8840   for(int i=0;i<(int)a.size();i++)
8841     for(int j=0;j<nbc[i];j++,k++)
8842       ret->setInfoOnComponent(k,a[i]->getInfoOnComponent(j).c_str());
8843   return ret;
8844 }
8845
8846 /*!
8847  * Returns a new DataArrayInt which is a minimal partition of elements of \a groups.
8848  * The i-th item of the result array is an ID of a set of elements belonging to a
8849  * unique set of groups, which the i-th element is a part of. This set of elements
8850  * belonging to a unique set of groups is called \a family, so the result array contains
8851  * IDs of families each element belongs to.
8852  *
8853  * \b Example: if we have two groups of elements: \a group1 [0,4] and \a group2 [ 0,1,2 ],
8854  * then there are 3 families:
8855  * - \a family1 (with ID 1) contains element [0] belonging to ( \a group1 + \a group2 ),
8856  * - \a family2 (with ID 2) contains elements [4] belonging to ( \a group1 ),
8857  * - \a family3 (with ID 3) contains element [1,2] belonging to ( \a group2 ), <br>
8858  * and the result array contains IDs of families [ 1,3,3,0,2 ]. <br> Note a family ID 0 which
8859  * stands for the element #3 which is in none of groups.
8860  *
8861  *  \param [in] groups - sequence of groups of element IDs.
8862  *  \param [in] newNb - total number of elements; it must be more than max ID of element
8863  *         in \a groups.
8864  *  \param [out] fidsOfGroups - IDs of families the elements of each group belong to.
8865  *  \return DataArrayInt * - a new instance of DataArrayInt containing IDs of families
8866  *         each element with ID from range [0, \a newNb ) belongs to. The caller is to
8867  *         delete this array using decrRef() as it is no more needed.
8868  *  \throw If any element ID in \a groups violates condition ( 0 <= ID < \a newNb ).
8869  */
8870 DataArrayInt *DataArrayInt::MakePartition(const std::vector<const DataArrayInt *>& groups, int newNb, std::vector< std::vector<int> >& fidsOfGroups) throw(INTERP_KERNEL::Exception)
8871 {
8872   std::vector<const DataArrayInt *> groups2;
8873   for(std::vector<const DataArrayInt *>::const_iterator it4=groups.begin();it4!=groups.end();it4++)
8874     if(*it4)
8875       groups2.push_back(*it4);
8876   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
8877   ret->alloc(newNb,1);
8878   int *retPtr=ret->getPointer();
8879   std::fill(retPtr,retPtr+newNb,0);
8880   int fid=1;
8881   for(std::vector<const DataArrayInt *>::const_iterator iter=groups2.begin();iter!=groups2.end();iter++)
8882     {
8883       const int *ptr=(*iter)->getConstPointer();
8884       std::size_t nbOfElem=(*iter)->getNbOfElems();
8885       int sfid=fid;
8886       for(int j=0;j<sfid;j++)
8887         {
8888           bool found=false;
8889           for(std::size_t i=0;i<nbOfElem;i++)
8890             {
8891               if(ptr[i]>=0 && ptr[i]<newNb)
8892                 {
8893                   if(retPtr[ptr[i]]==j)
8894                     {
8895                       retPtr[ptr[i]]=fid;
8896                       found=true;
8897                     }
8898                 }
8899               else
8900                 {
8901                   std::ostringstream oss; oss << "DataArrayInt::MakePartition : In group \"" << (*iter)->getName() << "\" in tuple #" << i << " value = " << ptr[i] << " ! Should be in [0," << newNb;
8902                   oss << ") !";
8903                   throw INTERP_KERNEL::Exception(oss.str().c_str());
8904                 }
8905             }
8906           if(found)
8907             fid++;
8908         }
8909     }
8910   fidsOfGroups.clear();
8911   fidsOfGroups.resize(groups2.size());
8912   int grId=0;
8913   for(std::vector<const DataArrayInt *>::const_iterator iter=groups2.begin();iter!=groups2.end();iter++,grId++)
8914     {
8915       std::set<int> tmp;
8916       const int *ptr=(*iter)->getConstPointer();
8917       std::size_t nbOfElem=(*iter)->getNbOfElems();
8918       for(const int *p=ptr;p!=ptr+nbOfElem;p++)
8919         tmp.insert(retPtr[*p]);
8920       fidsOfGroups[grId].insert(fidsOfGroups[grId].end(),tmp.begin(),tmp.end());
8921     }
8922   return ret.retn();
8923 }
8924
8925 /*!
8926  * Returns a new DataArrayInt which contains all elements of given one-dimensional
8927  * arrays. The result array does not contain any duplicates and its values
8928  * are sorted in ascending order.
8929  *  \param [in] arr - sequence of DataArrayInt's to unite.
8930  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
8931  *         array using decrRef() as it is no more needed.
8932  *  \throw If any \a arr[i] is not allocated.
8933  *  \throw If \a arr[i]->getNumberOfComponents() != 1.
8934  */
8935 DataArrayInt *DataArrayInt::BuildUnion(const std::vector<const DataArrayInt *>& arr) throw(INTERP_KERNEL::Exception)
8936 {
8937   std::vector<const DataArrayInt *> a;
8938   for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
8939     if(*it4)
8940       a.push_back(*it4);
8941   for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
8942     {
8943       (*it)->checkAllocated();
8944       if((*it)->getNumberOfComponents()!=1)
8945         throw INTERP_KERNEL::Exception("DataArrayInt::BuildUnion : only single component allowed !");
8946     }
8947   //
8948   std::set<int> r;
8949   for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
8950     {
8951       const int *pt=(*it)->getConstPointer();
8952       int nbOfTuples=(*it)->getNumberOfTuples();
8953       r.insert(pt,pt+nbOfTuples);
8954     }
8955   DataArrayInt *ret=DataArrayInt::New();
8956   ret->alloc((int)r.size(),1);
8957   std::copy(r.begin(),r.end(),ret->getPointer());
8958   return ret;
8959 }
8960
8961 /*!
8962  * Returns a new DataArrayInt which contains elements present in each of given one-dimensional
8963  * arrays. The result array does not contain any duplicates and its values
8964  * are sorted in ascending order.
8965  *  \param [in] arr - sequence of DataArrayInt's to intersect.
8966  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
8967  *         array using decrRef() as it is no more needed.
8968  *  \throw If any \a arr[i] is not allocated.
8969  *  \throw If \a arr[i]->getNumberOfComponents() != 1.
8970  */
8971 DataArrayInt *DataArrayInt::BuildIntersection(const std::vector<const DataArrayInt *>& arr) throw(INTERP_KERNEL::Exception)
8972 {
8973   std::vector<const DataArrayInt *> a;
8974   for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
8975     if(*it4)
8976       a.push_back(*it4);
8977   for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
8978     {
8979       (*it)->checkAllocated();
8980       if((*it)->getNumberOfComponents()!=1)
8981         throw INTERP_KERNEL::Exception("DataArrayInt::BuildIntersection : only single component allowed !");
8982     }
8983   //
8984   std::set<int> r;
8985   for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
8986     {
8987       const int *pt=(*it)->getConstPointer();
8988       int nbOfTuples=(*it)->getNumberOfTuples();
8989       std::set<int> s1(pt,pt+nbOfTuples);
8990       if(it!=a.begin())
8991         {
8992           std::set<int> r2;
8993           std::set_intersection(r.begin(),r.end(),s1.begin(),s1.end(),inserter(r2,r2.end()));
8994           r=r2;
8995         }
8996       else
8997         r=s1;
8998     }
8999   DataArrayInt *ret=DataArrayInt::New();
9000   ret->alloc((int)r.size(),1);
9001   std::copy(r.begin(),r.end(),ret->getPointer());
9002   return ret;
9003 }
9004
9005 /*!
9006  * Returns a new DataArrayInt which contains a complement of elements of \a this
9007  * one-dimensional array. I.e. the result array contains all elements from the range [0,
9008  * \a nbOfElement) not present in \a this array.
9009  *  \param [in] nbOfElement - maximal size of the result array.
9010  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
9011  *         array using decrRef() as it is no more needed.
9012  *  \throw If \a this is not allocated.
9013  *  \throw If \a this->getNumberOfComponents() != 1.
9014  *  \throw If any element \a x of \a this array violates condition ( 0 <= \a x < \a
9015  *         nbOfElement ).
9016  */
9017 DataArrayInt *DataArrayInt::buildComplement(int nbOfElement) const throw(INTERP_KERNEL::Exception)
9018 {
9019    checkAllocated();
9020    if(getNumberOfComponents()!=1)
9021      throw INTERP_KERNEL::Exception("DataArrayInt::buildComplement : only single component allowed !");
9022    std::vector<bool> tmp(nbOfElement);
9023    const int *pt=getConstPointer();
9024    int nbOfTuples=getNumberOfTuples();
9025    for(const int *w=pt;w!=pt+nbOfTuples;w++)
9026      if(*w>=0 && *w<nbOfElement)
9027        tmp[*w]=true;
9028      else
9029        throw INTERP_KERNEL::Exception("DataArrayInt::buildComplement : an element is not in valid range : [0,nbOfElement) !");
9030    int nbOfRetVal=(int)std::count(tmp.begin(),tmp.end(),false);
9031    DataArrayInt *ret=DataArrayInt::New();
9032    ret->alloc(nbOfRetVal,1);
9033    int j=0;
9034    int *retPtr=ret->getPointer();
9035    for(int i=0;i<nbOfElement;i++)
9036      if(!tmp[i])
9037        retPtr[j++]=i;
9038    return ret;
9039 }
9040
9041 /*!
9042  * Returns a new DataArrayInt containing elements of \a this one-dimensional missing
9043  * from an \a other one-dimensional array.
9044  *  \param [in] other - a DataArrayInt containing elements not to include in the result array.
9045  *  \return DataArrayInt * - a new instance of DataArrayInt with one component. The
9046  *         caller is to delete this array using decrRef() as it is no more needed.
9047  *  \throw If \a other is NULL.
9048  *  \throw If \a other is not allocated.
9049  *  \throw If \a other->getNumberOfComponents() != 1.
9050  *  \throw If \a this is not allocated.
9051  *  \throw If \a this->getNumberOfComponents() != 1.
9052  *  \sa DataArrayInt::buildSubstractionOptimized()
9053  */
9054 DataArrayInt *DataArrayInt::buildSubstraction(const DataArrayInt *other) const throw(INTERP_KERNEL::Exception)
9055 {
9056   if(!other)
9057     throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstraction : DataArrayInt pointer in input is NULL !");
9058   checkAllocated();
9059   other->checkAllocated();
9060   if(getNumberOfComponents()!=1)
9061      throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstraction : only single component allowed !");
9062   if(other->getNumberOfComponents()!=1)
9063      throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstraction : only single component allowed for other type !");
9064   const int *pt=getConstPointer();
9065   int nbOfTuples=getNumberOfTuples();
9066   std::set<int> s1(pt,pt+nbOfTuples);
9067   pt=other->getConstPointer();
9068   nbOfTuples=other->getNumberOfTuples();
9069   std::set<int> s2(pt,pt+nbOfTuples);
9070   std::vector<int> r;
9071   std::set_difference(s1.begin(),s1.end(),s2.begin(),s2.end(),std::back_insert_iterator< std::vector<int> >(r));
9072   DataArrayInt *ret=DataArrayInt::New();
9073   ret->alloc((int)r.size(),1);
9074   std::copy(r.begin(),r.end(),ret->getPointer());
9075   return ret;
9076 }
9077
9078 /*!
9079  * \a this is expected to have one component and to be sorted ascendingly (as for \a other).
9080  * \a other is expected to be a part of \a this. If not DataArrayInt::buildSubstraction should be called instead.
9081  * 
9082  * \param [in] other an array with one component and expected to be sorted ascendingly.
9083  * \ret list of ids in \a this but not in \a other.
9084  * \sa DataArrayInt::buildSubstraction
9085  */
9086 DataArrayInt *DataArrayInt::buildSubstractionOptimized(const DataArrayInt *other) const throw(INTERP_KERNEL::Exception)
9087 {
9088   static const char *MSG="DataArrayInt::buildSubstractionOptimized : only single component allowed !";
9089   if(!other) throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstractionOptimized : NULL input array !");
9090   checkAllocated(); other->checkAllocated();
9091   if(getNumberOfComponents()!=1) throw INTERP_KERNEL::Exception(MSG);
9092   if(other->getNumberOfComponents()!=1) throw INTERP_KERNEL::Exception(MSG);
9093   const int *pt1Bg(begin()),*pt1End(end()),*pt2Bg(other->begin()),*pt2End(other->end()),*work1(pt1Bg),*work2(pt2Bg);
9094   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
9095   for(;work1!=pt1End;work1++)
9096     {
9097       if(work2!=pt2End && *work1==*work2)
9098         work2++;
9099       else
9100         ret->pushBackSilent(*work1);
9101     }
9102   return ret.retn();
9103 }
9104
9105
9106 /*!
9107  * Returns a new DataArrayInt which contains all elements of \a this and a given
9108  * one-dimensional arrays. The result array does not contain any duplicates
9109  * and its values are sorted in ascending order.
9110  *  \param [in] other - an array to unite with \a this one.
9111  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
9112  *         array using decrRef() as it is no more needed.
9113  *  \throw If \a this or \a other is not allocated.
9114  *  \throw If \a this->getNumberOfComponents() != 1.
9115  *  \throw If \a other->getNumberOfComponents() != 1.
9116  */
9117 DataArrayInt *DataArrayInt::buildUnion(const DataArrayInt *other) const throw(INTERP_KERNEL::Exception)
9118 {
9119   std::vector<const DataArrayInt *>arrs(2);
9120   arrs[0]=this; arrs[1]=other;
9121   return BuildUnion(arrs);
9122 }
9123
9124
9125 /*!
9126  * Returns a new DataArrayInt which contains elements present in both \a this and a given
9127  * one-dimensional arrays. The result array does not contain any duplicates
9128  * and its values are sorted in ascending order.
9129  *  \param [in] other - an array to intersect with \a this one.
9130  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
9131  *         array using decrRef() as it is no more needed.
9132  *  \throw If \a this or \a other is not allocated.
9133  *  \throw If \a this->getNumberOfComponents() != 1.
9134  *  \throw If \a other->getNumberOfComponents() != 1.
9135  */
9136 DataArrayInt *DataArrayInt::buildIntersection(const DataArrayInt *other) const throw(INTERP_KERNEL::Exception)
9137 {
9138   std::vector<const DataArrayInt *>arrs(2);
9139   arrs[0]=this; arrs[1]=other;
9140   return BuildIntersection(arrs);
9141 }
9142
9143 /*!
9144  * This method can be applied on allocated with one component DataArrayInt instance.
9145  * This method is typically relevant for sorted arrays. All consecutive duplicated items in \a this will appear only once in returned DataArrayInt instance.
9146  * 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]
9147  * 
9148  * \return a newly allocated array that contain the result of the unique operation applied on \a this.
9149  * \throw if \a this is not allocated or if \a this has not exactly one component.
9150  */
9151 DataArrayInt *DataArrayInt::buildUnique() const throw(INTERP_KERNEL::Exception)
9152 {
9153   checkAllocated();
9154   if(getNumberOfComponents()!=1)
9155      throw INTERP_KERNEL::Exception("DataArrayInt::buildUnique : only single component allowed !");
9156   int nbOfTuples=getNumberOfTuples();
9157   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp=deepCpy();
9158   int *data=tmp->getPointer();
9159   int *last=std::unique(data,data+nbOfTuples);
9160   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
9161   ret->alloc(std::distance(data,last),1);
9162   std::copy(data,last,ret->getPointer());
9163   return ret.retn();
9164 }
9165
9166 /*!
9167  * Returns a new DataArrayInt which contains size of every of groups described by \a this
9168  * "index" array. Such "index" array is returned for example by 
9169  * \ref ParaMEDMEM::MEDCouplingUMesh::buildDescendingConnectivity
9170  * "MEDCouplingUMesh::buildDescendingConnectivity" and
9171  * \ref ParaMEDMEM::MEDCouplingUMesh::getNodalConnectivityIndex
9172  * "MEDCouplingUMesh::getNodalConnectivityIndex" etc.
9173  * This method preforms the reverse operation of DataArrayInt::computeOffsets2.
9174  *  \return DataArrayInt * - a new instance of DataArrayInt, whose number of tuples
9175  *          equals to \a this->getNumberOfComponents() - 1, and number of components is 1.
9176  *          The caller is to delete this array using decrRef() as it is no more needed. 
9177  *  \throw If \a this is not allocated.
9178  *  \throw If \a this->getNumberOfComponents() != 1.
9179  *  \throw If \a this->getNumberOfTuples() < 2.
9180  *
9181  *  \b Example: <br> 
9182  *         - this contains [1,3,6,7,7,9,15]
9183  *         - result array contains [2,3,1,0,2,6],
9184  *          where 2 = 3 - 1, 3 = 6 - 3, 1 = 7 - 6 etc.
9185  *
9186  * \sa DataArrayInt::computeOffsets2
9187  */
9188 DataArrayInt *DataArrayInt::deltaShiftIndex() const throw(INTERP_KERNEL::Exception)
9189 {
9190   checkAllocated();
9191   if(getNumberOfComponents()!=1)
9192      throw INTERP_KERNEL::Exception("DataArrayInt::deltaShiftIndex : only single component allowed !");
9193   int nbOfTuples=getNumberOfTuples();
9194   if(nbOfTuples<2)
9195     throw INTERP_KERNEL::Exception("DataArrayInt::deltaShiftIndex : 1 tuple at least must be present in 'this' !");
9196   const int *ptr=getConstPointer();
9197   DataArrayInt *ret=DataArrayInt::New();
9198   ret->alloc(nbOfTuples-1,1);
9199   int *out=ret->getPointer();
9200   std::transform(ptr+1,ptr+nbOfTuples,ptr,out,std::minus<int>());
9201   return ret;
9202 }
9203
9204 /*!
9205  * Modifies \a this one-dimensional array so that value of each element \a x
9206  * of \a this array (\a a) is computed as \f$ x_i = \sum_{j=0}^{i-1} a[ j ] \f$.
9207  * Or: for each i>0 new[i]=new[i-1]+old[i-1] for i==0 new[i]=0. Number of tuples
9208  * and components remains the same.<br>
9209  * This method is useful for allToAllV in MPI with contiguous policy. This method
9210  * differs from computeOffsets2() in that the number of tuples is \b not changed by
9211  * this one.
9212  *  \throw If \a this is not allocated.
9213  *  \throw If \a this->getNumberOfComponents() != 1.
9214  *
9215  *  \b Example: <br>
9216  *          - Before \a this contains [3,5,1,2,0,8]
9217  *          - After \a this contains  [0,3,8,9,11,11]<br>
9218  *          Note that the last element 19 = 11 + 8 is missing because size of \a this
9219  *          array is retained and thus there is no space to store the last element.
9220  */
9221 void DataArrayInt::computeOffsets() throw(INTERP_KERNEL::Exception)
9222 {
9223   checkAllocated();
9224   if(getNumberOfComponents()!=1)
9225      throw INTERP_KERNEL::Exception("DataArrayInt::computeOffsets : only single component allowed !");
9226   int nbOfTuples=getNumberOfTuples();
9227   if(nbOfTuples==0)
9228     return ;
9229   int *work=getPointer();
9230   int tmp=work[0];
9231   work[0]=0;
9232   for(int i=1;i<nbOfTuples;i++)
9233     {
9234       int tmp2=work[i];
9235       work[i]=work[i-1]+tmp;
9236       tmp=tmp2;
9237     }
9238   declareAsNew();
9239 }
9240
9241
9242 /*!
9243  * Modifies \a this one-dimensional array so that value of each element \a x
9244  * of \a this array (\a a) is computed as \f$ x_i = \sum_{j=0}^{i-1} a[ j ] \f$.
9245  * Or: for each i>0 new[i]=new[i-1]+old[i-1] for i==0 new[i]=0. Number
9246  * components remains the same and number of tuples is inceamented by one.<br>
9247  * This method is useful for allToAllV in MPI with contiguous policy. This method
9248  * differs from computeOffsets() in that the number of tuples is changed by this one.
9249  * This method preforms the reverse operation of DataArrayInt::deltaShiftIndex.
9250  *  \throw If \a this is not allocated.
9251  *  \throw If \a this->getNumberOfComponents() != 1.
9252  *
9253  *  \b Example: <br>
9254  *          - Before \a this contains [3,5,1,2,0,8]
9255  *          - After \a this contains  [0,3,8,9,11,11,19]<br>
9256  * \sa DataArrayInt::deltaShiftIndex
9257  */
9258 void DataArrayInt::computeOffsets2() throw(INTERP_KERNEL::Exception)
9259 {
9260   checkAllocated();
9261   if(getNumberOfComponents()!=1)
9262     throw INTERP_KERNEL::Exception("DataArrayInt::computeOffsets2 : only single component allowed !");
9263   int nbOfTuples=getNumberOfTuples();
9264   int *ret=(int *)malloc((nbOfTuples+1)*sizeof(int));
9265   if(nbOfTuples==0)
9266     return ;
9267   const int *work=getConstPointer();
9268   ret[0]=0;
9269   for(int i=0;i<nbOfTuples;i++)
9270     ret[i+1]=work[i]+ret[i];
9271   useArray(ret,true,C_DEALLOC,nbOfTuples+1,1);
9272   declareAsNew();
9273 }
9274
9275 /*!
9276  * Returns two new DataArrayInt instances whose contents is computed from that of \a this and \a listOfIds arrays as follows.
9277  * \a this is expected to be an offset format ( as returned by DataArrayInt::computeOffsets2 ) that is to say with one component
9278  * and ** sorted strictly increasingly **. \a listOfIds is expected to be sorted ascendingly (not strictly needed for \a listOfIds).
9279  * This methods searches in \a this, considered as a set of contiguous \c this->getNumberOfComponents() ranges, all ids in \a listOfIds
9280  * filling completely one of the ranges in \a this.
9281  *
9282  * \param [in] listOfIds a list of ids that has to be sorted ascendingly.
9283  * \param [out] rangeIdsFetched the range ids fetched
9284  * \param [out] idsInInputListThatFetch contains the list of ids in \a listOfIds that are \b fully included in a range in \a this. So
9285  *              \a idsInInputListThatFetch is a part of input \a listOfIds.
9286  *
9287  * \sa DataArrayInt::computeOffsets2
9288  *
9289  *  \b Example: <br>
9290  *          - \a this : [0,3,7,9,15,18]
9291  *          - \a listOfIds contains  [0,1,2,3,7,8,15,16,17]
9292  *          - \a rangeIdsFetched result array: [0,2,4]
9293  *          - \a idsInInputListThatFetch result array: [0,1,2,7,8,15,16,17]
9294  * In this example id 3 in input \a listOfIds is alone so it do not appear in output \a idsInInputListThatFetch.
9295  * <br>
9296  */
9297 void DataArrayInt::searchRangesInListOfIds(const DataArrayInt *listOfIds, DataArrayInt *& rangeIdsFetched, DataArrayInt *& idsInInputListThatFetch) const throw(INTERP_KERNEL::Exception)
9298 {
9299   if(!listOfIds)
9300     throw INTERP_KERNEL::Exception("DataArrayInt::searchRangesInListOfIds : input list of ids is null !");
9301   listOfIds->checkAllocated(); checkAllocated();
9302   if(listOfIds->getNumberOfComponents()!=1)
9303     throw INTERP_KERNEL::Exception("DataArrayInt::searchRangesInListOfIds : input list of ids must have exactly one component !");
9304   if(getNumberOfComponents()!=1)
9305     throw INTERP_KERNEL::Exception("DataArrayInt::searchRangesInListOfIds : this must have exactly one component !");
9306   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret0=DataArrayInt::New(); ret0->alloc(0,1);
9307   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret1=DataArrayInt::New(); ret1->alloc(0,1);
9308   const int *tupEnd(listOfIds->end()),*offBg(begin()),*offEnd(end()-1);
9309   const int *tupPtr(listOfIds->begin()),*offPtr(offBg);
9310   while(tupPtr!=tupEnd && offPtr!=offEnd)
9311     {
9312       if(*tupPtr==*offPtr)
9313         {
9314           int i=offPtr[0];
9315           while(i<offPtr[1] && *tupPtr==i && tupPtr!=tupEnd) { i++; tupPtr++; }
9316           if(i==offPtr[1])
9317             {
9318               ret0->pushBackSilent((int)std::distance(offBg,offPtr));
9319               ret1->pushBackValsSilent(tupPtr-(offPtr[1]-offPtr[0]),tupPtr);
9320               offPtr++;
9321             }
9322         }
9323       else
9324         { if(*tupPtr<*offPtr) tupPtr++; else offPtr++; }
9325     }
9326   rangeIdsFetched=ret0.retn();
9327   idsInInputListThatFetch=ret1.retn();
9328 }
9329
9330 /*!
9331  * Returns a new DataArrayInt whose contents is computed from that of \a this and \a
9332  * offsets arrays as follows. \a offsets is a one-dimensional array considered as an
9333  * "index" array of a "iota" array, thus, whose each element gives an index of a group
9334  * beginning within the "iota" array. And \a this is a one-dimensional array
9335  * considered as a selector of groups described by \a offsets to include into the result array.
9336  *  \throw If \a offsets is NULL.
9337  *  \throw If \a offsets is not allocated.
9338  *  \throw If \a offsets->getNumberOfComponents() != 1.
9339  *  \throw If \a offsets is not monotonically increasing.
9340  *  \throw If \a this is not allocated.
9341  *  \throw If \a this->getNumberOfComponents() != 1.
9342  *  \throw If any element of \a this is not a valid index for \a offsets array.
9343  *
9344  *  \b Example: <br>
9345  *          - \a this: [0,2,3]
9346  *          - \a offsets: [0,3,6,10,14,20]
9347  *          - result array: [0,1,2,6,7,8,9,10,11,12,13] == <br>
9348  *            \c range(0,3) + \c range(6,10) + \c range(10,14) ==<br>
9349  *            \c range( \a offsets[ \a this[0] ], offsets[ \a this[0]+1 ]) + 
9350  *            \c range( \a offsets[ \a this[1] ], offsets[ \a this[1]+1 ]) + 
9351  *            \c range( \a offsets[ \a this[2] ], offsets[ \a this[2]+1 ])
9352  */
9353 DataArrayInt *DataArrayInt::buildExplicitArrByRanges(const DataArrayInt *offsets) const throw(INTERP_KERNEL::Exception)
9354 {
9355   if(!offsets)
9356     throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrByRanges : DataArrayInt pointer in input is NULL !");
9357   checkAllocated();
9358   if(getNumberOfComponents()!=1)
9359      throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrByRanges : only single component allowed !");
9360   offsets->checkAllocated();
9361   if(offsets->getNumberOfComponents()!=1)
9362      throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrByRanges : input array should have only single component !");
9363   int othNbTuples=offsets->getNumberOfTuples()-1;
9364   int nbOfTuples=getNumberOfTuples();
9365   int retNbOftuples=0;
9366   const int *work=getConstPointer();
9367   const int *offPtr=offsets->getConstPointer();
9368   for(int i=0;i<nbOfTuples;i++)
9369     {
9370       int val=work[i];
9371       if(val>=0 && val<othNbTuples)
9372         {
9373           int delta=offPtr[val+1]-offPtr[val];
9374           if(delta>=0)
9375             retNbOftuples+=delta;
9376           else
9377             {
9378               std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrByRanges : Tuple #" << val << " of offset array has a delta < 0 !";
9379               throw INTERP_KERNEL::Exception(oss.str().c_str());
9380             }
9381         }
9382       else
9383         {
9384           std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrByRanges : Tuple #" << i << " in this contains " << val;
9385           oss << " whereas offsets array is of size " << othNbTuples+1 << " !";
9386           throw INTERP_KERNEL::Exception(oss.str().c_str());
9387         }
9388     }
9389   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
9390   ret->alloc(retNbOftuples,1);
9391   int *retPtr=ret->getPointer();
9392   for(int i=0;i<nbOfTuples;i++)
9393     {
9394       int val=work[i];
9395       int start=offPtr[val];
9396       int off=offPtr[val+1]-start;
9397       for(int j=0;j<off;j++,retPtr++)
9398         *retPtr=start+j;
9399     }
9400   return ret.retn();
9401 }
9402
9403 /*!
9404  * 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.
9405  * 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
9406  * in tuple **i** of returned DataArrayInt.
9407  * If ranges overlapped (in theory it should not) this method do not detect it and always returns the first range.
9408  *
9409  * 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)]
9410  * The return DataArrayInt will contain : **[0,4,1,2,2,3]**
9411  * 
9412  * \param [in] ranges typically come from output of MEDCouplingUMesh::ComputeRangesFromTypeDistribution. Each range is specified like this : 1st component is
9413  *             for lower value included and 2nd component is the upper value of corresponding range **excluded**.
9414  * \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
9415  *        is thrown if no ranges in \a ranges contains value in \a this.
9416  * 
9417  * \sa DataArrayInt::findIdInRangeForEachTuple
9418  */
9419 DataArrayInt *DataArrayInt::findRangeIdForEachTuple(const DataArrayInt *ranges) const throw(INTERP_KERNEL::Exception)
9420 {
9421   if(!ranges)
9422     throw INTERP_KERNEL::Exception("DataArrayInt::findRangeIdForEachTuple : null input pointer !");
9423   if(ranges->getNumberOfComponents()!=2)
9424     throw INTERP_KERNEL::Exception("DataArrayInt::findRangeIdForEachTuple : input DataArrayInt instance should have 2 components !");
9425   checkAllocated();
9426   if(getNumberOfComponents()!=1)
9427     throw INTERP_KERNEL::Exception("DataArrayInt::findRangeIdForEachTuple : this should have only one component !");
9428   int nbTuples=getNumberOfTuples();
9429   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbTuples,1);
9430   int nbOfRanges=ranges->getNumberOfTuples();
9431   const int *rangesPtr=ranges->getConstPointer();
9432   int *retPtr=ret->getPointer();
9433   const int *inPtr=getConstPointer();
9434   for(int i=0;i<nbTuples;i++,retPtr++)
9435     {
9436       int val=inPtr[i];
9437       bool found=false;
9438       for(int j=0;j<nbOfRanges && !found;j++)
9439         if(val>=rangesPtr[2*j] && val<rangesPtr[2*j+1])
9440           { *retPtr=j; found=true; }
9441       if(found)
9442         continue;
9443       else
9444         {
9445           std::ostringstream oss; oss << "DataArrayInt::findRangeIdForEachTuple : tuple #" << i << " not found by any ranges !";
9446           throw INTERP_KERNEL::Exception(oss.str().c_str());
9447         }
9448     }
9449   return ret.retn();
9450 }
9451
9452 /*!
9453  * 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.
9454  * 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
9455  * in tuple **i** of returned DataArrayInt.
9456  * If ranges overlapped (in theory it should not) this method do not detect it and always returns the sub position of the first range.
9457  *
9458  * 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)]
9459  * The return DataArrayInt will contain : **[1,2,4,0,2,2]**
9460  * This method is often called in pair with DataArrayInt::findRangeIdForEachTuple method.
9461  * 
9462  * \param [in] ranges typically come from output of MEDCouplingUMesh::ComputeRangesFromTypeDistribution. Each range is specified like this : 1st component is
9463  *             for lower value included and 2nd component is the upper value of corresponding range **excluded**.
9464  * \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
9465  *        is thrown if no ranges in \a ranges contains value in \a this.
9466  * \sa DataArrayInt::findRangeIdForEachTuple
9467  */
9468 DataArrayInt *DataArrayInt::findIdInRangeForEachTuple(const DataArrayInt *ranges) const throw(INTERP_KERNEL::Exception)
9469 {
9470   if(!ranges)
9471     throw INTERP_KERNEL::Exception("DataArrayInt::findIdInRangeForEachTuple : null input pointer !");
9472   if(ranges->getNumberOfComponents()!=2)
9473     throw INTERP_KERNEL::Exception("DataArrayInt::findIdInRangeForEachTuple : input DataArrayInt instance should have 2 components !");
9474   checkAllocated();
9475   if(getNumberOfComponents()!=1)
9476     throw INTERP_KERNEL::Exception("DataArrayInt::findIdInRangeForEachTuple : this should have only one component !");
9477   int nbTuples=getNumberOfTuples();
9478   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbTuples,1);
9479   int nbOfRanges=ranges->getNumberOfTuples();
9480   const int *rangesPtr=ranges->getConstPointer();
9481   int *retPtr=ret->getPointer();
9482   const int *inPtr=getConstPointer();
9483   for(int i=0;i<nbTuples;i++,retPtr++)
9484     {
9485       int val=inPtr[i];
9486       bool found=false;
9487       for(int j=0;j<nbOfRanges && !found;j++)
9488         if(val>=rangesPtr[2*j] && val<rangesPtr[2*j+1])
9489           { *retPtr=val-rangesPtr[2*j]; found=true; }
9490       if(found)
9491         continue;
9492       else
9493         {
9494           std::ostringstream oss; oss << "DataArrayInt::findIdInRangeForEachTuple : tuple #" << i << " not found by any ranges !";
9495           throw INTERP_KERNEL::Exception(oss.str().c_str());
9496         }
9497     }
9498   return ret.retn();
9499 }
9500
9501 /*!
9502  * 
9503  * \param [in] nbTimes specifies the nb of times each tuples in \a this will be duplicated contiguouly in returned DataArrayInt instance.
9504  *             \a nbTimes  should be at least equal to 1.
9505  * \return a newly allocated DataArrayInt having one component and number of tuples equal to \a nbTimes * \c this->getNumberOfTuples.
9506  * \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.
9507  */
9508 DataArrayInt *DataArrayInt::duplicateEachTupleNTimes(int nbTimes) const throw(INTERP_KERNEL::Exception)
9509 {
9510   checkAllocated();
9511   if(getNumberOfComponents()!=1)
9512     throw INTERP_KERNEL::Exception("DataArrayInt::duplicateEachTupleNTimes : this should have only one component !");
9513   if(nbTimes<1)
9514     throw INTERP_KERNEL::Exception("DataArrayInt::duplicateEachTupleNTimes : nb times should be >= 1 !");
9515   int nbTuples=getNumberOfTuples();
9516   const int *inPtr=getConstPointer();
9517   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbTimes*nbTuples,1);
9518   int *retPtr=ret->getPointer();
9519   for(int i=0;i<nbTuples;i++,inPtr++)
9520     {
9521       int val=*inPtr;
9522       for(int j=0;j<nbTimes;j++,retPtr++)
9523         *retPtr=val;
9524     }
9525   ret->copyStringInfoFrom(*this);
9526   return ret.retn();
9527 }
9528
9529 /*!
9530  * This method returns all different values found in \a this. This method throws if \a this has not been allocated.
9531  * But the number of components can be different from one.
9532  * \return a newly allocated array (that should be dealt by the caller) containing different values in \a this.
9533  */
9534 DataArrayInt *DataArrayInt::getDifferentValues() const throw(INTERP_KERNEL::Exception)
9535 {
9536   checkAllocated();
9537   std::set<int> ret;
9538   ret.insert(begin(),end());
9539   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret2=DataArrayInt::New(); ret2->alloc((int)ret.size(),1);
9540   std::copy(ret.begin(),ret.end(),ret2->getPointer());
9541   return ret2.retn();
9542 }
9543
9544 /*!
9545  * This method is a refinement of DataArrayInt::getDifferentValues because it returns not only different values in \a this but also, for each of
9546  * them it tells which tuple id have this id.
9547  * This method works only on arrays with one component (if it is not the case call DataArrayInt::rearrange(1) ).
9548  * This method returns two arrays having same size.
9549  * 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.
9550  * 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]]
9551  */
9552 std::vector<DataArrayInt *> DataArrayInt::partitionByDifferentValues(std::vector<int>& differentIds) const throw(INTERP_KERNEL::Exception)
9553 {
9554   checkAllocated();
9555   if(getNumberOfComponents()!=1)
9556     throw INTERP_KERNEL::Exception("DataArrayInt::partitionByDifferentValues : this should have only one component !");
9557   int id=0;
9558   std::map<int,int> m,m2,m3;
9559   for(const int *w=begin();w!=end();w++)
9560     m[*w]++;
9561   differentIds.resize(m.size());
9562   std::vector<DataArrayInt *> ret(m.size());
9563   std::vector<int *> retPtr(m.size());
9564   for(std::map<int,int>::const_iterator it=m.begin();it!=m.end();it++,id++)
9565     {
9566       m2[(*it).first]=id;
9567       ret[id]=DataArrayInt::New();
9568       ret[id]->alloc((*it).second,1);
9569       retPtr[id]=ret[id]->getPointer();
9570       differentIds[id]=(*it).first;
9571     }
9572   id=0;
9573   for(const int *w=begin();w!=end();w++,id++)
9574     {
9575       retPtr[m2[*w]][m3[*w]++]=id;
9576     }
9577   return ret;
9578 }
9579
9580 /*!
9581  * Returns a new DataArrayInt that is a sum of two given arrays. There are 3
9582  * valid cases.
9583  * 1.  The arrays have same number of tuples and components. Then each value of
9584  *   the result array (_a_) is a sum of the corresponding values of \a a1 and \a a2,
9585  *   i.e.: _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ i, j ].
9586  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
9587  *   component. Then
9588  *   _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ i, 0 ].
9589  * 3.  The arrays have same number of components and one array, say _a2_, has one
9590  *   tuple. Then
9591  *   _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ 0, j ].
9592  *
9593  * Info on components is copied either from the first array (in the first case) or from
9594  * the array with maximal number of elements (getNbOfElems()).
9595  *  \param [in] a1 - an array to sum up.
9596  *  \param [in] a2 - another array to sum up.
9597  *  \return DataArrayInt * - the new instance of DataArrayInt.
9598  *          The caller is to delete this result array using decrRef() as it is no more
9599  *          needed.
9600  *  \throw If either \a a1 or \a a2 is NULL.
9601  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
9602  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
9603  *         none of them has number of tuples or components equal to 1.
9604  */
9605 DataArrayInt *DataArrayInt::Add(const DataArrayInt *a1, const DataArrayInt *a2) throw(INTERP_KERNEL::Exception)
9606 {
9607   if(!a1 || !a2)
9608     throw INTERP_KERNEL::Exception("DataArrayInt::Add : input DataArrayInt instance is NULL !");
9609   int nbOfTuple=a1->getNumberOfTuples();
9610   int nbOfTuple2=a2->getNumberOfTuples();
9611   int nbOfComp=a1->getNumberOfComponents();
9612   int nbOfComp2=a2->getNumberOfComponents();
9613   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=0;
9614   if(nbOfTuple==nbOfTuple2)
9615     {
9616       if(nbOfComp==nbOfComp2)
9617         {
9618           ret=DataArrayInt::New();
9619           ret->alloc(nbOfTuple,nbOfComp);
9620           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::plus<int>());
9621           ret->copyStringInfoFrom(*a1);
9622         }
9623       else
9624         {
9625           int nbOfCompMin,nbOfCompMax;
9626           const DataArrayInt *aMin, *aMax;
9627           if(nbOfComp>nbOfComp2)
9628             {
9629               nbOfCompMin=nbOfComp2; nbOfCompMax=nbOfComp;
9630               aMin=a2; aMax=a1;
9631             }
9632           else
9633             {
9634               nbOfCompMin=nbOfComp; nbOfCompMax=nbOfComp2;
9635               aMin=a1; aMax=a2;
9636             }
9637           if(nbOfCompMin==1)
9638             {
9639               ret=DataArrayInt::New();
9640               ret->alloc(nbOfTuple,nbOfCompMax);
9641               const int *aMinPtr=aMin->getConstPointer();
9642               const int *aMaxPtr=aMax->getConstPointer();
9643               int *res=ret->getPointer();
9644               for(int i=0;i<nbOfTuple;i++)
9645                 res=std::transform(aMaxPtr+i*nbOfCompMax,aMaxPtr+(i+1)*nbOfCompMax,res,std::bind2nd(std::plus<int>(),aMinPtr[i]));
9646               ret->copyStringInfoFrom(*aMax);
9647             }
9648           else
9649             throw INTERP_KERNEL::Exception("Nb of components mismatch for array Add !");
9650         }
9651     }
9652   else if((nbOfTuple==1 && nbOfTuple2>1) || (nbOfTuple>1 && nbOfTuple2==1))
9653     {
9654       if(nbOfComp==nbOfComp2)
9655         {
9656           int nbOfTupleMax=std::max(nbOfTuple,nbOfTuple2);
9657           const DataArrayInt *aMin=nbOfTuple>nbOfTuple2?a2:a1;
9658           const DataArrayInt *aMax=nbOfTuple>nbOfTuple2?a1:a2;
9659           const int *aMinPtr=aMin->getConstPointer(),*aMaxPtr=aMax->getConstPointer();
9660           ret=DataArrayInt::New();
9661           ret->alloc(nbOfTupleMax,nbOfComp);
9662           int *res=ret->getPointer();
9663           for(int i=0;i<nbOfTupleMax;i++)
9664             res=std::transform(aMaxPtr+i*nbOfComp,aMaxPtr+(i+1)*nbOfComp,aMinPtr,res,std::plus<int>());
9665           ret->copyStringInfoFrom(*aMax);
9666         }
9667       else
9668         throw INTERP_KERNEL::Exception("Nb of components mismatch for array Add !");
9669     }
9670   else
9671     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Add !");
9672   return ret.retn();
9673 }
9674
9675 /*!
9676  * Adds values of another DataArrayInt to values of \a this one. There are 3
9677  * valid cases.
9678  * 1.  The arrays have same number of tuples and components. Then each value of
9679  *   \a other array is added to the corresponding value of \a this array, i.e.:
9680  *   _a_ [ i, j ] += _other_ [ i, j ].
9681  * 2.  The arrays have same number of tuples and \a other array has one component. Then
9682  *   _a_ [ i, j ] += _other_ [ i, 0 ].
9683  * 3.  The arrays have same number of components and \a other array has one tuple. Then
9684  *   _a_ [ i, j ] += _a2_ [ 0, j ].
9685  *
9686  *  \param [in] other - an array to add to \a this one.
9687  *  \throw If \a other is NULL.
9688  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
9689  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
9690  *         \a other has number of both tuples and components not equal to 1.
9691  */
9692 void DataArrayInt::addEqual(const DataArrayInt *other) throw(INTERP_KERNEL::Exception)
9693 {
9694   if(!other)
9695     throw INTERP_KERNEL::Exception("DataArrayInt::addEqual : input DataArrayInt instance is NULL !");
9696   const char *msg="Nb of tuples mismatch for DataArrayInt::addEqual  !";
9697   checkAllocated(); other->checkAllocated();
9698   int nbOfTuple=getNumberOfTuples();
9699   int nbOfTuple2=other->getNumberOfTuples();
9700   int nbOfComp=getNumberOfComponents();
9701   int nbOfComp2=other->getNumberOfComponents();
9702   if(nbOfTuple==nbOfTuple2)
9703     {
9704       if(nbOfComp==nbOfComp2)
9705         {
9706           std::transform(begin(),end(),other->begin(),getPointer(),std::plus<int>());
9707         }
9708       else if(nbOfComp2==1)
9709         {
9710           int *ptr=getPointer();
9711           const int *ptrc=other->getConstPointer();
9712           for(int i=0;i<nbOfTuple;i++)
9713             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::plus<int>(),*ptrc++));
9714         }
9715       else
9716         throw INTERP_KERNEL::Exception(msg);
9717     }
9718   else if(nbOfTuple2==1)
9719     {
9720       if(nbOfComp2==nbOfComp)
9721         {
9722           int *ptr=getPointer();
9723           const int *ptrc=other->getConstPointer();
9724           for(int i=0;i<nbOfTuple;i++)
9725             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::plus<int>());
9726         }
9727       else
9728         throw INTERP_KERNEL::Exception(msg);
9729     }
9730   else
9731     throw INTERP_KERNEL::Exception(msg);
9732   declareAsNew();
9733 }
9734
9735 /*!
9736  * Returns a new DataArrayInt that is a subtraction of two given arrays. There are 3
9737  * valid cases.
9738  * 1.  The arrays have same number of tuples and components. Then each value of
9739  *   the result array (_a_) is a subtraction of the corresponding values of \a a1 and
9740  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ i, j ].
9741  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
9742  *   component. Then
9743  *   _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ i, 0 ].
9744  * 3.  The arrays have same number of components and one array, say _a2_, has one
9745  *   tuple. Then
9746  *   _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ 0, j ].
9747  *
9748  * Info on components is copied either from the first array (in the first case) or from
9749  * the array with maximal number of elements (getNbOfElems()).
9750  *  \param [in] a1 - an array to subtract from.
9751  *  \param [in] a2 - an array to subtract.
9752  *  \return DataArrayInt * - the new instance of DataArrayInt.
9753  *          The caller is to delete this result array using decrRef() as it is no more
9754  *          needed.
9755  *  \throw If either \a a1 or \a a2 is NULL.
9756  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
9757  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
9758  *         none of them has number of tuples or components equal to 1.
9759  */
9760 DataArrayInt *DataArrayInt::Substract(const DataArrayInt *a1, const DataArrayInt *a2) throw(INTERP_KERNEL::Exception)
9761 {
9762   if(!a1 || !a2)
9763     throw INTERP_KERNEL::Exception("DataArrayInt::Substract : input DataArrayInt instance is NULL !");
9764   int nbOfTuple1=a1->getNumberOfTuples();
9765   int nbOfTuple2=a2->getNumberOfTuples();
9766   int nbOfComp1=a1->getNumberOfComponents();
9767   int nbOfComp2=a2->getNumberOfComponents();
9768   if(nbOfTuple2==nbOfTuple1)
9769     {
9770       if(nbOfComp1==nbOfComp2)
9771         {
9772           MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
9773           ret->alloc(nbOfTuple2,nbOfComp1);
9774           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::minus<int>());
9775           ret->copyStringInfoFrom(*a1);
9776           return ret.retn();
9777         }
9778       else if(nbOfComp2==1)
9779         {
9780           MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
9781           ret->alloc(nbOfTuple1,nbOfComp1);
9782           const int *a2Ptr=a2->getConstPointer();
9783           const int *a1Ptr=a1->getConstPointer();
9784           int *res=ret->getPointer();
9785           for(int i=0;i<nbOfTuple1;i++)
9786             res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::minus<int>(),a2Ptr[i]));
9787           ret->copyStringInfoFrom(*a1);
9788           return ret.retn();
9789         }
9790       else
9791         {
9792           a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Substract !");
9793           return 0;
9794         }
9795     }
9796   else if(nbOfTuple2==1)
9797     {
9798       a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Substract !");
9799       MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
9800       ret->alloc(nbOfTuple1,nbOfComp1);
9801       const int *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
9802       int *pt=ret->getPointer();
9803       for(int i=0;i<nbOfTuple1;i++)
9804         pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::minus<int>());
9805       ret->copyStringInfoFrom(*a1);
9806       return ret.retn();
9807     }
9808   else
9809     {
9810       a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Substract !");//will always throw an exception
9811       return 0;
9812     }
9813 }
9814
9815 /*!
9816  * Subtract values of another DataArrayInt from values of \a this one. There are 3
9817  * valid cases.
9818  * 1.  The arrays have same number of tuples and components. Then each value of
9819  *   \a other array is subtracted from the corresponding value of \a this array, i.e.:
9820  *   _a_ [ i, j ] -= _other_ [ i, j ].
9821  * 2.  The arrays have same number of tuples and \a other array has one component. Then
9822  *   _a_ [ i, j ] -= _other_ [ i, 0 ].
9823  * 3.  The arrays have same number of components and \a other array has one tuple. Then
9824  *   _a_ [ i, j ] -= _a2_ [ 0, j ].
9825  *
9826  *  \param [in] other - an array to subtract from \a this one.
9827  *  \throw If \a other is NULL.
9828  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
9829  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
9830  *         \a other has number of both tuples and components not equal to 1.
9831  */
9832 void DataArrayInt::substractEqual(const DataArrayInt *other) throw(INTERP_KERNEL::Exception)
9833 {
9834   if(!other)
9835     throw INTERP_KERNEL::Exception("DataArrayInt::substractEqual : input DataArrayInt instance is NULL !");
9836   const char *msg="Nb of tuples mismatch for DataArrayInt::substractEqual  !";
9837   checkAllocated(); other->checkAllocated();
9838   int nbOfTuple=getNumberOfTuples();
9839   int nbOfTuple2=other->getNumberOfTuples();
9840   int nbOfComp=getNumberOfComponents();
9841   int nbOfComp2=other->getNumberOfComponents();
9842   if(nbOfTuple==nbOfTuple2)
9843     {
9844       if(nbOfComp==nbOfComp2)
9845         {
9846           std::transform(begin(),end(),other->begin(),getPointer(),std::minus<int>());
9847         }
9848       else if(nbOfComp2==1)
9849         {
9850           int *ptr=getPointer();
9851           const int *ptrc=other->getConstPointer();
9852           for(int i=0;i<nbOfTuple;i++)
9853             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::minus<int>(),*ptrc++));
9854         }
9855       else
9856         throw INTERP_KERNEL::Exception(msg);
9857     }
9858   else if(nbOfTuple2==1)
9859     {
9860       int *ptr=getPointer();
9861       const int *ptrc=other->getConstPointer();
9862       for(int i=0;i<nbOfTuple;i++)
9863         std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::minus<int>());
9864     }
9865   else
9866     throw INTERP_KERNEL::Exception(msg);
9867   declareAsNew();
9868 }
9869
9870 /*!
9871  * Returns a new DataArrayInt that is a product of two given arrays. There are 3
9872  * valid cases.
9873  * 1.  The arrays have same number of tuples and components. Then each value of
9874  *   the result array (_a_) is a product of the corresponding values of \a a1 and
9875  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ i, j ].
9876  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
9877  *   component. Then
9878  *   _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ i, 0 ].
9879  * 3.  The arrays have same number of components and one array, say _a2_, has one
9880  *   tuple. Then
9881  *   _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ 0, j ].
9882  *
9883  * Info on components is copied either from the first array (in the first case) or from
9884  * the array with maximal number of elements (getNbOfElems()).
9885  *  \param [in] a1 - a factor array.
9886  *  \param [in] a2 - another factor array.
9887  *  \return DataArrayInt * - the new instance of DataArrayInt.
9888  *          The caller is to delete this result array using decrRef() as it is no more
9889  *          needed.
9890  *  \throw If either \a a1 or \a a2 is NULL.
9891  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
9892  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
9893  *         none of them has number of tuples or components equal to 1.
9894  */
9895 DataArrayInt *DataArrayInt::Multiply(const DataArrayInt *a1, const DataArrayInt *a2) throw(INTERP_KERNEL::Exception)
9896 {
9897   if(!a1 || !a2)
9898     throw INTERP_KERNEL::Exception("DataArrayInt::Multiply : input DataArrayInt instance is NULL !");
9899   int nbOfTuple=a1->getNumberOfTuples();
9900   int nbOfTuple2=a2->getNumberOfTuples();
9901   int nbOfComp=a1->getNumberOfComponents();
9902   int nbOfComp2=a2->getNumberOfComponents();
9903   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=0;
9904   if(nbOfTuple==nbOfTuple2)
9905     {
9906       if(nbOfComp==nbOfComp2)
9907         {
9908           ret=DataArrayInt::New();
9909           ret->alloc(nbOfTuple,nbOfComp);
9910           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::multiplies<int>());
9911           ret->copyStringInfoFrom(*a1);
9912         }
9913       else
9914         {
9915           int nbOfCompMin,nbOfCompMax;
9916           const DataArrayInt *aMin, *aMax;
9917           if(nbOfComp>nbOfComp2)
9918             {
9919               nbOfCompMin=nbOfComp2; nbOfCompMax=nbOfComp;
9920               aMin=a2; aMax=a1;
9921             }
9922           else
9923             {
9924               nbOfCompMin=nbOfComp; nbOfCompMax=nbOfComp2;
9925               aMin=a1; aMax=a2;
9926             }
9927           if(nbOfCompMin==1)
9928             {
9929               ret=DataArrayInt::New();
9930               ret->alloc(nbOfTuple,nbOfCompMax);
9931               const int *aMinPtr=aMin->getConstPointer();
9932               const int *aMaxPtr=aMax->getConstPointer();
9933               int *res=ret->getPointer();
9934               for(int i=0;i<nbOfTuple;i++)
9935                 res=std::transform(aMaxPtr+i*nbOfCompMax,aMaxPtr+(i+1)*nbOfCompMax,res,std::bind2nd(std::multiplies<int>(),aMinPtr[i]));
9936               ret->copyStringInfoFrom(*aMax);
9937             }
9938           else
9939             throw INTERP_KERNEL::Exception("Nb of components mismatch for array Multiply !");
9940         }
9941     }
9942   else if((nbOfTuple==1 && nbOfTuple2>1) || (nbOfTuple>1 && nbOfTuple2==1))
9943     {
9944       if(nbOfComp==nbOfComp2)
9945         {
9946           int nbOfTupleMax=std::max(nbOfTuple,nbOfTuple2);
9947           const DataArrayInt *aMin=nbOfTuple>nbOfTuple2?a2:a1;
9948           const DataArrayInt *aMax=nbOfTuple>nbOfTuple2?a1:a2;
9949           const int *aMinPtr=aMin->getConstPointer(),*aMaxPtr=aMax->getConstPointer();
9950           ret=DataArrayInt::New();
9951           ret->alloc(nbOfTupleMax,nbOfComp);
9952           int *res=ret->getPointer();
9953           for(int i=0;i<nbOfTupleMax;i++)
9954             res=std::transform(aMaxPtr+i*nbOfComp,aMaxPtr+(i+1)*nbOfComp,aMinPtr,res,std::multiplies<int>());
9955           ret->copyStringInfoFrom(*aMax);
9956         }
9957       else
9958         throw INTERP_KERNEL::Exception("Nb of components mismatch for array Multiply !");
9959     }
9960   else
9961     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Multiply !");
9962   return ret.retn();
9963 }
9964
9965
9966 /*!
9967  * Multiply values of another DataArrayInt to values of \a this one. There are 3
9968  * valid cases.
9969  * 1.  The arrays have same number of tuples and components. Then each value of
9970  *   \a other array is multiplied to the corresponding value of \a this array, i.e.:
9971  *   _a_ [ i, j ] *= _other_ [ i, j ].
9972  * 2.  The arrays have same number of tuples and \a other array has one component. Then
9973  *   _a_ [ i, j ] *= _other_ [ i, 0 ].
9974  * 3.  The arrays have same number of components and \a other array has one tuple. Then
9975  *   _a_ [ i, j ] *= _a2_ [ 0, j ].
9976  *
9977  *  \param [in] other - an array to multiply to \a this one.
9978  *  \throw If \a other is NULL.
9979  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
9980  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
9981  *         \a other has number of both tuples and components not equal to 1.
9982  */
9983 void DataArrayInt::multiplyEqual(const DataArrayInt *other) throw(INTERP_KERNEL::Exception)
9984 {
9985   if(!other)
9986     throw INTERP_KERNEL::Exception("DataArrayInt::multiplyEqual : input DataArrayInt instance is NULL !");
9987   const char *msg="Nb of tuples mismatch for DataArrayInt::multiplyEqual !";
9988   checkAllocated(); other->checkAllocated();
9989   int nbOfTuple=getNumberOfTuples();
9990   int nbOfTuple2=other->getNumberOfTuples();
9991   int nbOfComp=getNumberOfComponents();
9992   int nbOfComp2=other->getNumberOfComponents();
9993   if(nbOfTuple==nbOfTuple2)
9994     {
9995       if(nbOfComp==nbOfComp2)
9996         {
9997           std::transform(begin(),end(),other->begin(),getPointer(),std::multiplies<int>());
9998         }
9999       else if(nbOfComp2==1)
10000         {
10001           int *ptr=getPointer();
10002           const int *ptrc=other->getConstPointer();
10003           for(int i=0;i<nbOfTuple;i++)
10004             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::multiplies<int>(),*ptrc++));    
10005         }
10006       else
10007         throw INTERP_KERNEL::Exception(msg);
10008     }
10009   else if(nbOfTuple2==1)
10010     {
10011       if(nbOfComp2==nbOfComp)
10012         {
10013           int *ptr=getPointer();
10014           const int *ptrc=other->getConstPointer();
10015           for(int i=0;i<nbOfTuple;i++)
10016             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::multiplies<int>());
10017         }
10018       else
10019         throw INTERP_KERNEL::Exception(msg);
10020     }
10021   else
10022     throw INTERP_KERNEL::Exception(msg);
10023   declareAsNew();
10024 }
10025
10026
10027 /*!
10028  * Returns a new DataArrayInt that is a division of two given arrays. There are 3
10029  * valid cases.
10030  * 1.  The arrays have same number of tuples and components. Then each value of
10031  *   the result array (_a_) is a division of the corresponding values of \a a1 and
10032  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ i, j ].
10033  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
10034  *   component. Then
10035  *   _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ i, 0 ].
10036  * 3.  The arrays have same number of components and one array, say _a2_, has one
10037  *   tuple. Then
10038  *   _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ 0, j ].
10039  *
10040  * Info on components is copied either from the first array (in the first case) or from
10041  * the array with maximal number of elements (getNbOfElems()).
10042  *  \warning No check of division by zero is performed!
10043  *  \param [in] a1 - a numerator array.
10044  *  \param [in] a2 - a denominator array.
10045  *  \return DataArrayInt * - the new instance of DataArrayInt.
10046  *          The caller is to delete this result array using decrRef() as it is no more
10047  *          needed.
10048  *  \throw If either \a a1 or \a a2 is NULL.
10049  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
10050  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
10051  *         none of them has number of tuples or components equal to 1.
10052  */
10053 DataArrayInt *DataArrayInt::Divide(const DataArrayInt *a1, const DataArrayInt *a2) throw(INTERP_KERNEL::Exception)
10054 {
10055   if(!a1 || !a2)
10056     throw INTERP_KERNEL::Exception("DataArrayInt::Divide : input DataArrayInt instance is NULL !");
10057   int nbOfTuple1=a1->getNumberOfTuples();
10058   int nbOfTuple2=a2->getNumberOfTuples();
10059   int nbOfComp1=a1->getNumberOfComponents();
10060   int nbOfComp2=a2->getNumberOfComponents();
10061   if(nbOfTuple2==nbOfTuple1)
10062     {
10063       if(nbOfComp1==nbOfComp2)
10064         {
10065           MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
10066           ret->alloc(nbOfTuple2,nbOfComp1);
10067           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::divides<int>());
10068           ret->copyStringInfoFrom(*a1);
10069           return ret.retn();
10070         }
10071       else if(nbOfComp2==1)
10072         {
10073           MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
10074           ret->alloc(nbOfTuple1,nbOfComp1);
10075           const int *a2Ptr=a2->getConstPointer();
10076           const int *a1Ptr=a1->getConstPointer();
10077           int *res=ret->getPointer();
10078           for(int i=0;i<nbOfTuple1;i++)
10079             res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::divides<int>(),a2Ptr[i]));
10080           ret->copyStringInfoFrom(*a1);
10081           return ret.retn();
10082         }
10083       else
10084         {
10085           a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Divide !");
10086           return 0;
10087         }
10088     }
10089   else if(nbOfTuple2==1)
10090     {
10091       a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Divide !");
10092       MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
10093       ret->alloc(nbOfTuple1,nbOfComp1);
10094       const int *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
10095       int *pt=ret->getPointer();
10096       for(int i=0;i<nbOfTuple1;i++)
10097         pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::divides<int>());
10098       ret->copyStringInfoFrom(*a1);
10099       return ret.retn();
10100     }
10101   else
10102     {
10103       a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Divide !");//will always throw an exception
10104       return 0;
10105     }
10106 }
10107
10108 /*!
10109  * Divide values of \a this array by values of another DataArrayInt. There are 3
10110  * valid cases.
10111  * 1.  The arrays have same number of tuples and components. Then each value of
10112  *    \a this array is divided by the corresponding value of \a other one, i.e.:
10113  *   _a_ [ i, j ] /= _other_ [ i, j ].
10114  * 2.  The arrays have same number of tuples and \a other array has one component. Then
10115  *   _a_ [ i, j ] /= _other_ [ i, 0 ].
10116  * 3.  The arrays have same number of components and \a other array has one tuple. Then
10117  *   _a_ [ i, j ] /= _a2_ [ 0, j ].
10118  *
10119  *  \warning No check of division by zero is performed!
10120  *  \param [in] other - an array to divide \a this one by.
10121  *  \throw If \a other is NULL.
10122  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
10123  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
10124  *         \a other has number of both tuples and components not equal to 1.
10125  */
10126 void DataArrayInt::divideEqual(const DataArrayInt *other) throw(INTERP_KERNEL::Exception)
10127 {
10128   if(!other)
10129     throw INTERP_KERNEL::Exception("DataArrayInt::divideEqual : input DataArrayInt instance is NULL !");
10130   const char *msg="Nb of tuples mismatch for DataArrayInt::divideEqual !";
10131   checkAllocated(); other->checkAllocated();
10132   int nbOfTuple=getNumberOfTuples();
10133   int nbOfTuple2=other->getNumberOfTuples();
10134   int nbOfComp=getNumberOfComponents();
10135   int nbOfComp2=other->getNumberOfComponents();
10136   if(nbOfTuple==nbOfTuple2)
10137     {
10138       if(nbOfComp==nbOfComp2)
10139         {
10140           std::transform(begin(),end(),other->begin(),getPointer(),std::divides<int>());
10141         }
10142       else if(nbOfComp2==1)
10143         {
10144           int *ptr=getPointer();
10145           const int *ptrc=other->getConstPointer();
10146           for(int i=0;i<nbOfTuple;i++)
10147             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::divides<int>(),*ptrc++));
10148         }
10149       else
10150         throw INTERP_KERNEL::Exception(msg);
10151     }
10152   else if(nbOfTuple2==1)
10153     {
10154       if(nbOfComp2==nbOfComp)
10155         {
10156           int *ptr=getPointer();
10157           const int *ptrc=other->getConstPointer();
10158           for(int i=0;i<nbOfTuple;i++)
10159             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::divides<int>());
10160         }
10161       else
10162         throw INTERP_KERNEL::Exception(msg);
10163     }
10164   else
10165     throw INTERP_KERNEL::Exception(msg);
10166   declareAsNew();
10167 }
10168
10169
10170 /*!
10171  * Returns a new DataArrayInt that is a modulus of two given arrays. There are 3
10172  * valid cases.
10173  * 1.  The arrays have same number of tuples and components. Then each value of
10174  *   the result array (_a_) is a division of the corresponding values of \a a1 and
10175  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] % _a2_ [ i, j ].
10176  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
10177  *   component. Then
10178  *   _a_ [ i, j ] = _a1_ [ i, j ] % _a2_ [ i, 0 ].
10179  * 3.  The arrays have same number of components and one array, say _a2_, has one
10180  *   tuple. Then
10181  *   _a_ [ i, j ] = _a1_ [ i, j ] % _a2_ [ 0, j ].
10182  *
10183  * Info on components is copied either from the first array (in the first case) or from
10184  * the array with maximal number of elements (getNbOfElems()).
10185  *  \warning No check of division by zero is performed!
10186  *  \param [in] a1 - a dividend array.
10187  *  \param [in] a2 - a divisor array.
10188  *  \return DataArrayInt * - the new instance of DataArrayInt.
10189  *          The caller is to delete this result array using decrRef() as it is no more
10190  *          needed.
10191  *  \throw If either \a a1 or \a a2 is NULL.
10192  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
10193  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
10194  *         none of them has number of tuples or components equal to 1.
10195  */
10196 DataArrayInt *DataArrayInt::Modulus(const DataArrayInt *a1, const DataArrayInt *a2) throw(INTERP_KERNEL::Exception)
10197 {
10198     if(!a1 || !a2)
10199     throw INTERP_KERNEL::Exception("DataArrayInt::Modulus : input DataArrayInt instance is NULL !");
10200   int nbOfTuple1=a1->getNumberOfTuples();
10201   int nbOfTuple2=a2->getNumberOfTuples();
10202   int nbOfComp1=a1->getNumberOfComponents();
10203   int nbOfComp2=a2->getNumberOfComponents();
10204   if(nbOfTuple2==nbOfTuple1)
10205     {
10206       if(nbOfComp1==nbOfComp2)
10207         {
10208           MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
10209           ret->alloc(nbOfTuple2,nbOfComp1);
10210           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::modulus<int>());
10211           ret->copyStringInfoFrom(*a1);
10212           return ret.retn();
10213         }
10214       else if(nbOfComp2==1)
10215         {
10216           MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
10217           ret->alloc(nbOfTuple1,nbOfComp1);
10218           const int *a2Ptr=a2->getConstPointer();
10219           const int *a1Ptr=a1->getConstPointer();
10220           int *res=ret->getPointer();
10221           for(int i=0;i<nbOfTuple1;i++)
10222             res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::modulus<int>(),a2Ptr[i]));
10223           ret->copyStringInfoFrom(*a1);
10224           return ret.retn();
10225         }
10226       else
10227         {
10228           a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Modulus !");
10229           return 0;
10230         }
10231     }
10232   else if(nbOfTuple2==1)
10233     {
10234       a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Modulus !");
10235       MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
10236       ret->alloc(nbOfTuple1,nbOfComp1);
10237       const int *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
10238       int *pt=ret->getPointer();
10239       for(int i=0;i<nbOfTuple1;i++)
10240         pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::modulus<int>());
10241       ret->copyStringInfoFrom(*a1);
10242       return ret.retn();
10243     }
10244   else
10245     {
10246       a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Modulus !");//will always throw an exception
10247       return 0;
10248     }
10249 }
10250
10251 /*!
10252  * Modify \a this array so that each value becomes a modulus of division of this value by
10253  * a value of another DataArrayInt. There are 3 valid cases.
10254  * 1.  The arrays have same number of tuples and components. Then each value of
10255  *    \a this array is divided by the corresponding value of \a other one, i.e.:
10256  *   _a_ [ i, j ] %= _other_ [ i, j ].
10257  * 2.  The arrays have same number of tuples and \a other array has one component. Then
10258  *   _a_ [ i, j ] %= _other_ [ i, 0 ].
10259  * 3.  The arrays have same number of components and \a other array has one tuple. Then
10260  *   _a_ [ i, j ] %= _a2_ [ 0, j ].
10261  *
10262  *  \warning No check of division by zero is performed!
10263  *  \param [in] other - a divisor array.
10264  *  \throw If \a other is NULL.
10265  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
10266  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
10267  *         \a other has number of both tuples and components not equal to 1.
10268  */
10269 void DataArrayInt::modulusEqual(const DataArrayInt *other) throw(INTERP_KERNEL::Exception)
10270 {
10271   if(!other)
10272     throw INTERP_KERNEL::Exception("DataArrayInt::modulusEqual : input DataArrayInt instance is NULL !");
10273   const char *msg="Nb of tuples mismatch for DataArrayInt::modulusEqual !";
10274   checkAllocated(); other->checkAllocated();
10275   int nbOfTuple=getNumberOfTuples();
10276   int nbOfTuple2=other->getNumberOfTuples();
10277   int nbOfComp=getNumberOfComponents();
10278   int nbOfComp2=other->getNumberOfComponents();
10279   if(nbOfTuple==nbOfTuple2)
10280     {
10281       if(nbOfComp==nbOfComp2)
10282         {
10283           std::transform(begin(),end(),other->begin(),getPointer(),std::modulus<int>());
10284         }
10285       else if(nbOfComp2==1)
10286         {
10287           if(nbOfComp2==nbOfComp)
10288             {
10289               int *ptr=getPointer();
10290               const int *ptrc=other->getConstPointer();
10291               for(int i=0;i<nbOfTuple;i++)
10292                 std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::modulus<int>(),*ptrc++));
10293             }
10294           else
10295             throw INTERP_KERNEL::Exception(msg);
10296         }
10297       else
10298         throw INTERP_KERNEL::Exception(msg);
10299     }
10300   else if(nbOfTuple2==1)
10301     {
10302       int *ptr=getPointer();
10303       const int *ptrc=other->getConstPointer();
10304       for(int i=0;i<nbOfTuple;i++)
10305         std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::modulus<int>());
10306     }
10307   else
10308     throw INTERP_KERNEL::Exception(msg);
10309   declareAsNew();
10310 }
10311
10312 /*!
10313  * Returns a new DataArrayInt that is the result of pow of two given arrays. There are 3
10314  * valid cases.
10315  *
10316  *  \param [in] a1 - an array to pow up.
10317  *  \param [in] a2 - another array to sum up.
10318  *  \return DataArrayInt * - the new instance of DataArrayInt.
10319  *          The caller is to delete this result array using decrRef() as it is no more
10320  *          needed.
10321  *  \throw If either \a a1 or \a a2 is NULL.
10322  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
10323  *  \throw If \a a1->getNumberOfComponents() != 1 or \a a2->getNumberOfComponents() != 1.
10324  *  \throw If there is a negative value in \a a2.
10325  */
10326 DataArrayInt *DataArrayInt::Pow(const DataArrayInt *a1, const DataArrayInt *a2) throw(INTERP_KERNEL::Exception)
10327 {
10328   if(!a1 || !a2)
10329     throw INTERP_KERNEL::Exception("DataArrayInt::Pow : at least one of input instances is null !");
10330   int nbOfTuple=a1->getNumberOfTuples();
10331   int nbOfTuple2=a2->getNumberOfTuples();
10332   int nbOfComp=a1->getNumberOfComponents();
10333   int nbOfComp2=a2->getNumberOfComponents();
10334   if(nbOfTuple!=nbOfTuple2)
10335     throw INTERP_KERNEL::Exception("DataArrayInt::Pow : number of tuples mismatches !");
10336   if(nbOfComp!=1 || nbOfComp2!=1)
10337     throw INTERP_KERNEL::Exception("DataArrayInt::Pow : number of components of both arrays must be equal to 1 !");
10338   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbOfTuple,1);
10339   const int *ptr1(a1->begin()),*ptr2(a2->begin());
10340   int *ptr=ret->getPointer();
10341   for(int i=0;i<nbOfTuple;i++,ptr1++,ptr2++,ptr++)
10342     {
10343       if(*ptr2>=0)
10344         {
10345           int tmp=1;
10346           for(int j=0;j<*ptr2;j++)
10347             tmp*=*ptr1;
10348           *ptr=tmp;
10349         }
10350       else
10351         {
10352           std::ostringstream oss; oss << "DataArrayInt::Pow : on tuple #" << i << " of a2 value is < 0 (" << *ptr2 << ") !";
10353           throw INTERP_KERNEL::Exception(oss.str().c_str());
10354         }
10355     }
10356   return ret.retn();
10357 }
10358
10359 /*!
10360  * Apply pow on values of another DataArrayInt to values of \a this one.
10361  *
10362  *  \param [in] other - an array to pow to \a this one.
10363  *  \throw If \a other is NULL.
10364  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples()
10365  *  \throw If \a this->getNumberOfComponents() != 1 or \a other->getNumberOfComponents() != 1
10366  *  \throw If there is a negative value in \a other.
10367  */
10368 void DataArrayInt::powEqual(const DataArrayInt *other) throw(INTERP_KERNEL::Exception)
10369 {
10370   if(!other)
10371     throw INTERP_KERNEL::Exception("DataArrayInt::powEqual : input instance is null !");
10372   int nbOfTuple=getNumberOfTuples();
10373   int nbOfTuple2=other->getNumberOfTuples();
10374   int nbOfComp=getNumberOfComponents();
10375   int nbOfComp2=other->getNumberOfComponents();
10376   if(nbOfTuple!=nbOfTuple2)
10377     throw INTERP_KERNEL::Exception("DataArrayInt::powEqual : number of tuples mismatches !");
10378   if(nbOfComp!=1 || nbOfComp2!=1)
10379     throw INTERP_KERNEL::Exception("DataArrayInt::powEqual : number of components of both arrays must be equal to 1 !");
10380   int *ptr=getPointer();
10381   const int *ptrc=other->begin();
10382   for(int i=0;i<nbOfTuple;i++,ptrc++,ptr++)
10383     {
10384       if(*ptrc>=0)
10385         {
10386           int tmp=1;
10387           for(int j=0;j<*ptrc;j++)
10388             tmp*=*ptr;
10389           *ptr=tmp;
10390         }
10391       else
10392         {
10393           std::ostringstream oss; oss << "DataArrayInt::powEqual : on tuple #" << i << " of other value is < 0 (" << *ptrc << ") !";
10394           throw INTERP_KERNEL::Exception(oss.str().c_str());
10395         }
10396     }
10397   declareAsNew();
10398 }
10399
10400 /*!
10401  * Returns a C array which is a renumbering map in "Old to New" mode for the input array.
10402  * This map, if applied to \a start array, would make it sorted. For example, if
10403  * \a start array contents are [9,10,0,6,4,11,3,7] then the contents of the result array is
10404  * [5,6,0,3,2,7,1,4].
10405  *  \param [in] start - pointer to the first element of the array for which the
10406  *         permutation map is computed.
10407  *  \param [in] end - pointer specifying the end of the array \a start, so that
10408  *         the last value of \a start is \a end[ -1 ].
10409  *  \return int * - the result permutation array that the caller is to delete as it is no
10410  *         more needed.
10411  *  \throw If there are equal values in the input array.
10412  */
10413 int *DataArrayInt::CheckAndPreparePermutation(const int *start, const int *end)
10414 {
10415   std::size_t sz=std::distance(start,end);
10416   int *ret=(int *)malloc(sz*sizeof(int));
10417   int *work=new int[sz];
10418   std::copy(start,end,work);
10419   std::sort(work,work+sz);
10420   if(std::unique(work,work+sz)!=work+sz)
10421     {
10422       delete [] work;
10423       free(ret);
10424       throw INTERP_KERNEL::Exception("Some elements are equals in the specified array !");
10425     }
10426   std::map<int,int> m;
10427   for(int *workPt=work;workPt!=work+sz;workPt++)
10428     m[*workPt]=(int)std::distance(work,workPt);
10429   int *iter2=ret;
10430   for(const int *iter=start;iter!=end;iter++,iter2++)
10431     *iter2=m[*iter];
10432   delete [] work;
10433   return ret;
10434 }
10435
10436 /*!
10437  * Returns a new DataArrayInt containing an arithmetic progression
10438  * that is equal to the sequence returned by Python \c range(\a begin,\a  end,\a  step )
10439  * function.
10440  *  \param [in] begin - the start value of the result sequence.
10441  *  \param [in] end - limiting value, so that every value of the result array is less than
10442  *              \a end.
10443  *  \param [in] step - specifies the increment or decrement.
10444  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
10445  *          array using decrRef() as it is no more needed.
10446  *  \throw If \a step == 0.
10447  *  \throw If \a end < \a begin && \a step > 0.
10448  *  \throw If \a end > \a begin && \a step < 0.
10449  */
10450 DataArrayInt *DataArrayInt::Range(int begin, int end, int step) throw(INTERP_KERNEL::Exception)
10451 {
10452   int nbOfTuples=GetNumberOfItemGivenBESRelative(begin,end,step,"DataArrayInt::Range");
10453   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
10454   ret->alloc(nbOfTuples,1);
10455   int *ptr=ret->getPointer();
10456   if(step>0)
10457     {
10458       for(int i=begin;i<end;i+=step,ptr++)
10459         *ptr=i;
10460     }
10461   else
10462     {
10463       for(int i=begin;i>end;i+=step,ptr++)
10464         *ptr=i;
10465     }
10466   return ret.retn();
10467 }
10468
10469 /*!
10470  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
10471  * Server side.
10472  */
10473 void DataArrayInt::getTinySerializationIntInformation(std::vector<int>& tinyInfo) const
10474 {
10475   tinyInfo.resize(2);
10476   if(isAllocated())
10477     {
10478       tinyInfo[0]=getNumberOfTuples();
10479       tinyInfo[1]=getNumberOfComponents();
10480     }
10481   else
10482     {
10483       tinyInfo[0]=-1;
10484       tinyInfo[1]=-1;
10485     }
10486 }
10487
10488 /*!
10489  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
10490  * Server side.
10491  */
10492 void DataArrayInt::getTinySerializationStrInformation(std::vector<std::string>& tinyInfo) const
10493 {
10494   if(isAllocated())
10495     {
10496       int nbOfCompo=getNumberOfComponents();
10497       tinyInfo.resize(nbOfCompo+1);
10498       tinyInfo[0]=getName();
10499       for(int i=0;i<nbOfCompo;i++)
10500         tinyInfo[i+1]=getInfoOnComponent(i);
10501     }
10502   else
10503     {
10504       tinyInfo.resize(1);
10505       tinyInfo[0]=getName();
10506     }
10507 }
10508
10509 /*!
10510  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
10511  * This method returns if a feeding is needed.
10512  */
10513 bool DataArrayInt::resizeForUnserialization(const std::vector<int>& tinyInfoI)
10514 {
10515   int nbOfTuple=tinyInfoI[0];
10516   int nbOfComp=tinyInfoI[1];
10517   if(nbOfTuple!=-1 || nbOfComp!=-1)
10518     {
10519       alloc(nbOfTuple,nbOfComp);
10520       return true;
10521     }
10522   return false;
10523 }
10524
10525 /*!
10526  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
10527  * This method returns if a feeding is needed.
10528  */
10529 void DataArrayInt::finishUnserialization(const std::vector<int>& tinyInfoI, const std::vector<std::string>& tinyInfoS)
10530 {
10531   setName(tinyInfoS[0].c_str());
10532   if(isAllocated())
10533     {
10534       int nbOfCompo=getNumberOfComponents();
10535       for(int i=0;i<nbOfCompo;i++)
10536         setInfoOnComponent(i,tinyInfoS[i+1].c_str());
10537     }
10538 }
10539
10540 DataArrayIntIterator::DataArrayIntIterator(DataArrayInt *da):_da(da),_pt(0),_tuple_id(0),_nb_comp(0),_nb_tuple(0)
10541 {
10542   if(_da)
10543     {
10544       _da->incrRef();
10545       if(_da->isAllocated())
10546         {
10547           _nb_comp=da->getNumberOfComponents();
10548           _nb_tuple=da->getNumberOfTuples();
10549           _pt=da->getPointer();
10550         }
10551     }
10552 }
10553
10554 DataArrayIntIterator::~DataArrayIntIterator()
10555 {
10556   if(_da)
10557     _da->decrRef();
10558 }
10559
10560 DataArrayIntTuple *DataArrayIntIterator::nextt() throw(INTERP_KERNEL::Exception)
10561 {
10562   if(_tuple_id<_nb_tuple)
10563     {
10564       _tuple_id++;
10565       DataArrayIntTuple *ret=new DataArrayIntTuple(_pt,_nb_comp);
10566       _pt+=_nb_comp;
10567       return ret;
10568     }
10569   else
10570     return 0;
10571 }
10572
10573 DataArrayIntTuple::DataArrayIntTuple(int *pt, int nbOfComp):_pt(pt),_nb_of_compo(nbOfComp)
10574 {
10575 }
10576
10577 std::string DataArrayIntTuple::repr() const throw(INTERP_KERNEL::Exception)
10578 {
10579   std::ostringstream oss; oss << "(";
10580   for(int i=0;i<_nb_of_compo-1;i++)
10581     oss << _pt[i] << ", ";
10582   oss << _pt[_nb_of_compo-1] << ")";
10583   return oss.str();
10584 }
10585
10586 int DataArrayIntTuple::intValue() const throw(INTERP_KERNEL::Exception)
10587 {
10588   if(_nb_of_compo==1)
10589     return *_pt;
10590   throw INTERP_KERNEL::Exception("DataArrayIntTuple::intValue : DataArrayIntTuple instance has not exactly 1 component -> Not possible to convert it into an integer !");
10591 }
10592
10593 /*!
10594  * This method returns a newly allocated instance the caller should dealed with by a ParaMEDMEM::DataArrayInt::decrRef.
10595  * This method performs \b no copy of data. The content is only referenced using ParaMEDMEM::DataArrayInt::useArray with ownership set to \b false.
10596  * 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
10597  * \b nbOfCompo=1 and \bnbOfTuples==this->_nb_of_elem.
10598  */
10599 DataArrayInt *DataArrayIntTuple::buildDAInt(int nbOfTuples, int nbOfCompo) const throw(INTERP_KERNEL::Exception)
10600 {
10601   if((_nb_of_compo==nbOfCompo && nbOfTuples==1) || (_nb_of_compo==nbOfTuples && nbOfCompo==1))
10602     {
10603       DataArrayInt *ret=DataArrayInt::New();
10604       ret->useExternalArrayWithRWAccess(_pt,nbOfTuples,nbOfCompo);
10605       return ret;
10606     }
10607   else
10608     {
10609       std::ostringstream oss; oss << "DataArrayIntTuple::buildDAInt : unable to build a requested DataArrayInt instance with nbofTuple=" << nbOfTuples << " and nbOfCompo=" << nbOfCompo;
10610       oss << ".\nBecause the number of elements in this is " << _nb_of_compo << " !";
10611       throw INTERP_KERNEL::Exception(oss.str().c_str());
10612     }
10613 }