Salome HOME
8459ce8fe5dfac6a83b8e40f4f9c6fd73227f62f
[tools/medcoupling.git] / src / MEDCoupling / MEDCouplingMemArray.cxx
1 // Copyright (C) 2007-2016  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, or (at your option) any later version.
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 "MCAuto.hxx"
23
24 #include "BBTree.txx"
25 #include "GenMathFormulae.hxx"
26 #include "InterpKernelAutoPtr.hxx"
27 #include "InterpKernelExprParser.hxx"
28
29 #include <set>
30 #include <cmath>
31 #include <limits>
32 #include <numeric>
33 #include <algorithm>
34 #include <functional>
35
36 typedef double (*MYFUNCPTR)(double);
37
38 using namespace MEDCoupling;
39
40 template class DataArrayTemplate<int>;
41 template class DataArrayTemplate<double>;
42
43 template<int SPACEDIM>
44 void DataArrayDouble::findCommonTuplesAlg(const double *bbox, int nbNodes, int limitNodeId, double prec, DataArrayInt *c, DataArrayInt *cI) const
45 {
46   const double *coordsPtr=getConstPointer();
47   BBTreePts<SPACEDIM,int> myTree(bbox,0,0,nbNodes,prec);
48   std::vector<bool> isDone(nbNodes);
49   for(int i=0;i<nbNodes;i++)
50     {
51       if(!isDone[i])
52         {
53           std::vector<int> intersectingElems;
54           myTree.getElementsAroundPoint(coordsPtr+i*SPACEDIM,intersectingElems);
55           if(intersectingElems.size()>1)
56             {
57               std::vector<int> commonNodes;
58               for(std::vector<int>::const_iterator it=intersectingElems.begin();it!=intersectingElems.end();it++)
59                 if(*it!=i)
60                   if(*it>=limitNodeId)
61                     {
62                       commonNodes.push_back(*it);
63                       isDone[*it]=true;
64                     }
65               if(!commonNodes.empty())
66                 {
67                   cI->pushBackSilent(cI->back()+(int)commonNodes.size()+1);
68                   c->pushBackSilent(i);
69                   c->insertAtTheEnd(commonNodes.begin(),commonNodes.end());
70                 }
71             }
72         }
73     }
74 }
75
76 template<int SPACEDIM>
77 void DataArrayDouble::FindTupleIdsNearTuplesAlg(const BBTreePts<SPACEDIM,int>& myTree, const double *pos, int nbOfTuples, double eps,
78                                                 DataArrayInt *c, DataArrayInt *cI)
79 {
80   for(int i=0;i<nbOfTuples;i++)
81     {
82       std::vector<int> intersectingElems;
83       myTree.getElementsAroundPoint(pos+i*SPACEDIM,intersectingElems);
84       std::vector<int> commonNodes;
85       for(std::vector<int>::const_iterator it=intersectingElems.begin();it!=intersectingElems.end();it++)
86         commonNodes.push_back(*it);
87       cI->pushBackSilent(cI->back()+(int)commonNodes.size());
88       c->insertAtTheEnd(commonNodes.begin(),commonNodes.end());
89     }
90 }
91
92 template<int SPACEDIM>
93 void DataArrayDouble::FindClosestTupleIdAlg(const BBTreePts<SPACEDIM,int>& myTree, double dist, const double *pos, int nbOfTuples, const double *thisPt, int thisNbOfTuples, int *res)
94 {
95   double distOpt(dist);
96   const double *p(pos);
97   int *r(res);
98   for(int i=0;i<nbOfTuples;i++,p+=SPACEDIM,r++)
99     {
100       while(true)
101         {
102           int elem=-1;
103           double ret=myTree.getElementsAroundPoint2(p,distOpt,elem);
104           if(ret!=std::numeric_limits<double>::max())
105             {
106               distOpt=std::max(ret,1e-4);
107               *r=elem;
108               break;
109             }
110           else
111             { distOpt=2*distOpt; continue; }
112         }
113     }
114 }
115
116 std::size_t DataArray::getHeapMemorySizeWithoutChildren() const
117 {
118   std::size_t sz1=_name.capacity();
119   std::size_t sz2=_info_on_compo.capacity();
120   std::size_t sz3=0;
121   for(std::vector<std::string>::const_iterator it=_info_on_compo.begin();it!=_info_on_compo.end();it++)
122     sz3+=(*it).capacity();
123   return sz1+sz2+sz3;
124 }
125
126 std::vector<const BigMemoryObject *> DataArray::getDirectChildrenWithNull() const
127 {
128   return std::vector<const BigMemoryObject *>();
129 }
130
131 /*!
132  * Sets the attribute \a _name of \a this array.
133  * See \ref MEDCouplingArrayBasicsName "DataArrays infos" for more information.
134  *  \param [in] name - new array name
135  */
136 void DataArray::setName(const std::string& name)
137 {
138   _name=name;
139 }
140
141 /*!
142  * Copies textual data from an \a other DataArray. The copied data are
143  * - the name attribute,
144  * - the information of components.
145  *
146  * For more information on these data see \ref MEDCouplingArrayBasicsName "DataArrays infos".
147  *
148  *  \param [in] other - another instance of DataArray to copy the textual data from.
149  *  \throw If number of components of \a this array differs from that of the \a other.
150  */
151 void DataArray::copyStringInfoFrom(const DataArray& other)
152 {
153   if(_info_on_compo.size()!=other._info_on_compo.size())
154     throw INTERP_KERNEL::Exception("Size of arrays mismatches on copyStringInfoFrom !");
155   _name=other._name;
156   _info_on_compo=other._info_on_compo;
157 }
158
159 void DataArray::copyPartOfStringInfoFrom(const DataArray& other, const std::vector<int>& compoIds)
160 {
161   int nbOfCompoOth=other.getNumberOfComponents();
162   std::size_t newNbOfCompo=compoIds.size();
163   for(std::size_t i=0;i<newNbOfCompo;i++)
164     if(compoIds[i]>=nbOfCompoOth || compoIds[i]<0)
165       {
166         std::ostringstream oss; oss << "Specified component id is out of range (" << compoIds[i] << ") compared with nb of actual components (" << nbOfCompoOth << ")";
167         throw INTERP_KERNEL::Exception(oss.str().c_str());
168       }
169   for(std::size_t i=0;i<newNbOfCompo;i++)
170     setInfoOnComponent((int)i,other.getInfoOnComponent(compoIds[i]));
171 }
172
173 void DataArray::copyPartOfStringInfoFrom2(const std::vector<int>& compoIds, const DataArray& other)
174 {
175   int nbOfCompo=getNumberOfComponents();
176   std::size_t partOfCompoToSet=compoIds.size();
177   if((int)partOfCompoToSet!=other.getNumberOfComponents())
178     throw INTERP_KERNEL::Exception("Given compoIds has not the same size as number of components of given array !");
179   for(std::size_t i=0;i<partOfCompoToSet;i++)
180     if(compoIds[i]>=nbOfCompo || compoIds[i]<0)
181       {
182         std::ostringstream oss; oss << "Specified component id is out of range (" << compoIds[i] << ") compared with nb of actual components (" << nbOfCompo << ")";
183         throw INTERP_KERNEL::Exception(oss.str().c_str());
184       }
185   for(std::size_t i=0;i<partOfCompoToSet;i++)
186     setInfoOnComponent(compoIds[i],other.getInfoOnComponent((int)i));
187 }
188
189 bool DataArray::areInfoEqualsIfNotWhy(const DataArray& other, std::string& reason) const
190 {
191   std::ostringstream oss;
192   if(_name!=other._name)
193     {
194       oss << "Names DataArray mismatch : this name=\"" << _name << " other name=\"" << other._name << "\" !";
195       reason=oss.str();
196       return false;
197     }
198   if(_info_on_compo!=other._info_on_compo)
199     {
200       oss << "Components DataArray mismatch : \nThis components=";
201       for(std::vector<std::string>::const_iterator it=_info_on_compo.begin();it!=_info_on_compo.end();it++)
202         oss << "\"" << *it << "\",";
203       oss << "\nOther components=";
204       for(std::vector<std::string>::const_iterator it=other._info_on_compo.begin();it!=other._info_on_compo.end();it++)
205         oss << "\"" << *it << "\",";
206       reason=oss.str();
207       return false;
208     }
209   return true;
210 }
211
212 /*!
213  * Compares textual information of \a this DataArray with that of an \a other one.
214  * The compared data are
215  * - the name attribute,
216  * - the information of components.
217  *
218  * For more information on these data see \ref MEDCouplingArrayBasicsName "DataArrays infos".
219  *  \param [in] other - another instance of DataArray to compare the textual data of.
220  *  \return bool - \a true if the textual information is same, \a false else.
221  */
222 bool DataArray::areInfoEquals(const DataArray& other) const
223 {
224   std::string tmp;
225   return areInfoEqualsIfNotWhy(other,tmp);
226 }
227
228 void DataArray::reprWithoutNameStream(std::ostream& stream) const
229 {
230   stream << "Number of components : "<< getNumberOfComponents() << "\n";
231   stream << "Info of these components : ";
232   for(std::vector<std::string>::const_iterator iter=_info_on_compo.begin();iter!=_info_on_compo.end();iter++)
233     stream << "\"" << *iter << "\"   ";
234   stream << "\n";
235 }
236
237 std::string DataArray::cppRepr(const std::string& varName) const
238 {
239   std::ostringstream ret;
240   reprCppStream(varName,ret);
241   return ret.str();
242 }
243
244 /*!
245  * Sets information on all components. To know more on format of this information
246  * see \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
247  *  \param [in] info - a vector of strings.
248  *  \throw If size of \a info differs from the number of components of \a this.
249  */
250 void DataArray::setInfoOnComponents(const std::vector<std::string>& info)
251 {
252   if(getNumberOfComponents()!=(int)info.size())
253     {
254       std::ostringstream oss; oss << "DataArray::setInfoOnComponents : input is of size " << info.size() << " whereas number of components is equal to " << getNumberOfComponents() << " !";
255       throw INTERP_KERNEL::Exception(oss.str().c_str());
256     }
257   _info_on_compo=info;
258 }
259
260 /*!
261  * This method is only a dispatcher towards DataArrayDouble::setPartOfValues3, DataArrayInt::setPartOfValues3, DataArrayChar::setPartOfValues3 depending on the true
262  * type of \a this and \a aBase.
263  *
264  * \throw If \a aBase and \a this do not have the same type.
265  *
266  * \sa DataArrayDouble::setPartOfValues3, DataArrayInt::setPartOfValues3, DataArrayChar::setPartOfValues3.
267  */
268 void DataArray::setPartOfValuesBase3(const DataArray *aBase, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare)
269 {
270   if(!aBase)
271     throw INTERP_KERNEL::Exception("DataArray::setPartOfValuesBase3 : input aBase object is NULL !");
272   DataArrayDouble *this1(dynamic_cast<DataArrayDouble *>(this));
273   DataArrayInt *this2(dynamic_cast<DataArrayInt *>(this));
274   DataArrayChar *this3(dynamic_cast<DataArrayChar *>(this));
275   const DataArrayDouble *a1(dynamic_cast<const DataArrayDouble *>(aBase));
276   const DataArrayInt *a2(dynamic_cast<const DataArrayInt *>(aBase));
277   const DataArrayChar *a3(dynamic_cast<const DataArrayChar *>(aBase));
278   if(this1 && a1)
279     {
280       this1->setPartOfValues3(a1,bgTuples,endTuples,bgComp,endComp,stepComp,strictCompoCompare);
281       return ;
282     }
283   if(this2 && a2)
284     {
285       this2->setPartOfValues3(a2,bgTuples,endTuples,bgComp,endComp,stepComp,strictCompoCompare);
286       return ;
287     }
288   if(this3 && a3)
289     {
290       this3->setPartOfValues3(a3,bgTuples,endTuples,bgComp,endComp,stepComp,strictCompoCompare);
291       return ;
292     }
293   throw INTERP_KERNEL::Exception("DataArray::setPartOfValuesBase3 : input aBase object and this do not have the same type !");
294 }
295
296 std::vector<std::string> DataArray::getVarsOnComponent() const
297 {
298   int nbOfCompo=(int)_info_on_compo.size();
299   std::vector<std::string> ret(nbOfCompo);
300   for(int i=0;i<nbOfCompo;i++)
301     ret[i]=getVarOnComponent(i);
302   return ret;
303 }
304
305 std::vector<std::string> DataArray::getUnitsOnComponent() const
306 {
307   int nbOfCompo=(int)_info_on_compo.size();
308   std::vector<std::string> ret(nbOfCompo);
309   for(int i=0;i<nbOfCompo;i++)
310     ret[i]=getUnitOnComponent(i);
311   return ret;
312 }
313
314 /*!
315  * Returns information on a component specified by an index.
316  * To know more on format of this information
317  * see \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
318  *  \param [in] i - the index (zero based) of the component of interest.
319  *  \return std::string - a string containing the information on \a i-th component.
320  *  \throw If \a i is not a valid component index.
321  */
322 std::string DataArray::getInfoOnComponent(int i) const
323 {
324   if(i<(int)_info_on_compo.size() && i>=0)
325     return _info_on_compo[i];
326   else
327     {
328       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();
329       throw INTERP_KERNEL::Exception(oss.str().c_str());
330     }
331 }
332
333 /*!
334  * Returns the var part of the full information of the \a i-th component.
335  * For example, if \c getInfoOnComponent(0) returns "SIGXY [N/m^2]", then
336  * \c getVarOnComponent(0) returns "SIGXY".
337  * If a unit part of information is not detected by presence of
338  * two square brackets, then the full information is returned.
339  * To read more about the component information format, see
340  * \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
341  *  \param [in] i - the index (zero based) of the component of interest.
342  *  \return std::string - a string containing the var information, or the full info.
343  *  \throw If \a i is not a valid component index.
344  */
345 std::string DataArray::getVarOnComponent(int i) const
346 {
347   if(i<(int)_info_on_compo.size() && i>=0)
348     {
349       return GetVarNameFromInfo(_info_on_compo[i]);
350     }
351   else
352     {
353       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();
354       throw INTERP_KERNEL::Exception(oss.str().c_str());
355     }
356 }
357
358 /*!
359  * Returns the unit part of the full information of the \a i-th component.
360  * For example, if \c getInfoOnComponent(0) returns "SIGXY [ N/m^2]", then
361  * \c getUnitOnComponent(0) returns " N/m^2".
362  * If a unit part of information is not detected by presence of
363  * two square brackets, then an empty string is returned.
364  * To read more about the component information format, see
365  * \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
366  *  \param [in] i - the index (zero based) of the component of interest.
367  *  \return std::string - a string containing the unit information, if any, or "".
368  *  \throw If \a i is not a valid component index.
369  */
370 std::string DataArray::getUnitOnComponent(int i) const
371 {
372   if(i<(int)_info_on_compo.size() && i>=0)
373     {
374       return GetUnitFromInfo(_info_on_compo[i]);
375     }
376   else
377     {
378       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();
379       throw INTERP_KERNEL::Exception(oss.str().c_str());
380     }
381 }
382
383 /*!
384  * Returns the var part of the full component information.
385  * For example, if \a info == "SIGXY [N/m^2]", then this method returns "SIGXY".
386  * If a unit part of information is not detected by presence of
387  * two square brackets, then the whole \a info is returned.
388  * To read more about the component information format, see
389  * \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
390  *  \param [in] info - the full component information.
391  *  \return std::string - a string containing only var information, or the \a info.
392  */
393 std::string DataArray::GetVarNameFromInfo(const std::string& info)
394 {
395   std::size_t p1=info.find_last_of('[');
396   std::size_t p2=info.find_last_of(']');
397   if(p1==std::string::npos || p2==std::string::npos)
398     return info;
399   if(p1>p2)
400     return info;
401   if(p1==0)
402     return std::string();
403   std::size_t p3=info.find_last_not_of(' ',p1-1);
404   return info.substr(0,p3+1);
405 }
406
407 /*!
408  * Returns the unit part of the full component information.
409  * For example, if \a info == "SIGXY [ N/m^2]", then this method returns " N/m^2".
410  * If a unit part of information is not detected by presence of
411  * two square brackets, then an empty string is returned.
412  * To read more about the component information format, see
413  * \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
414  *  \param [in] info - the full component information.
415  *  \return std::string - a string containing only unit information, if any, or "".
416  */
417 std::string DataArray::GetUnitFromInfo(const std::string& info)
418 {
419   std::size_t p1=info.find_last_of('[');
420   std::size_t p2=info.find_last_of(']');
421   if(p1==std::string::npos || p2==std::string::npos)
422     return std::string();
423   if(p1>p2)
424     return std::string();
425   return info.substr(p1+1,p2-p1-1);
426 }
427
428 /*!
429  * This method put in info format the result of the merge of \a var and \a unit.
430  * The standard format for that is "var [unit]".
431  * Inversely you can retrieve the var part or the unit part of info string using resp. GetVarNameFromInfo and GetUnitFromInfo.
432  */
433 std::string DataArray::BuildInfoFromVarAndUnit(const std::string& var, const std::string& unit)
434 {
435   std::ostringstream oss;
436   oss << var << " [" << unit << "]";
437   return oss.str();
438 }
439
440 std::string DataArray::GetAxisTypeRepr(MEDCouplingAxisType at)
441 {
442   switch(at)
443     {
444     case AX_CART:
445       return std::string("AX_CART");
446     case AX_CYL:
447       return std::string("AX_CYL");
448     case AX_SPHER:
449       return std::string("AX_SPHER");
450     default:
451       throw INTERP_KERNEL::Exception("DataArray::GetAxisTypeRepr : unrecognized axis type enum !");
452     }
453 }
454
455 /*!
456  * Returns a new DataArray by concatenating all given arrays, so that (1) the number
457  * of tuples in the result array is a sum of the number of tuples of given arrays and (2)
458  * the number of component in the result array is same as that of each of given arrays.
459  * Info on components is copied from the first of the given arrays. Number of components
460  * in the given arrays must be  the same.
461  *  \param [in] arrs - a sequence of arrays to include in the result array. All arrays must have the same type.
462  *  \return DataArray * - the new instance of DataArray (that can be either DataArrayInt, DataArrayDouble, DataArrayChar).
463  *          The caller is to delete this result array using decrRef() as it is no more
464  *          needed.
465  *  \throw If all arrays within \a arrs are NULL.
466  *  \throw If all not null arrays in \a arrs have not the same type.
467  *  \throw If getNumberOfComponents() of arrays within \a arrs.
468  */
469 DataArray *DataArray::Aggregate(const std::vector<const DataArray *>& arrs)
470 {
471   std::vector<const DataArray *> arr2;
472   for(std::vector<const DataArray *>::const_iterator it=arrs.begin();it!=arrs.end();it++)
473     if(*it)
474       arr2.push_back(*it);
475   if(arr2.empty())
476     throw INTERP_KERNEL::Exception("DataArray::Aggregate : only null instance in input vector !");
477   std::vector<const DataArrayDouble *> arrd;
478   std::vector<const DataArrayInt *> arri;
479   std::vector<const DataArrayChar *> arrc;
480   for(std::vector<const DataArray *>::const_iterator it=arr2.begin();it!=arr2.end();it++)
481     {
482       const DataArrayDouble *a=dynamic_cast<const DataArrayDouble *>(*it);
483       if(a)
484         { arrd.push_back(a); continue; }
485       const DataArrayInt *b=dynamic_cast<const DataArrayInt *>(*it);
486       if(b)
487         { arri.push_back(b); continue; }
488       const DataArrayChar *c=dynamic_cast<const DataArrayChar *>(*it);
489       if(c)
490         { arrc.push_back(c); continue; }
491       throw INTERP_KERNEL::Exception("DataArray::Aggregate : presence of not null instance in inuput that is not in [DataArrayDouble, DataArrayInt, DataArrayChar] !");
492     }
493   if(arr2.size()==arrd.size())
494     return DataArrayDouble::Aggregate(arrd);
495   if(arr2.size()==arri.size())
496     return DataArrayInt::Aggregate(arri);
497   if(arr2.size()==arrc.size())
498     return DataArrayChar::Aggregate(arrc);
499   throw INTERP_KERNEL::Exception("DataArray::Aggregate : all input arrays must have the same type !");
500 }
501
502 /*!
503  * Sets information on a component specified by an index.
504  * To know more on format of this information
505  * see \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
506  *  \warning Don't pass NULL as \a info!
507  *  \param [in] i - the index (zero based) of the component of interest.
508  *  \param [in] info - the string containing the information.
509  *  \throw If \a i is not a valid component index.
510  */
511 void DataArray::setInfoOnComponent(int i, const std::string& info)
512 {
513   if(i<(int)_info_on_compo.size() && i>=0)
514     _info_on_compo[i]=info;
515   else
516     {
517       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();
518       throw INTERP_KERNEL::Exception(oss.str().c_str());
519     }
520 }
521
522 /*!
523  * Sets information on all components. This method can change number of components
524  * at certain conditions; if the conditions are not respected, an exception is thrown.
525  * The number of components can be changed in \a this only if \a this is not allocated.
526  * The condition of number of components must not be changed.
527  *
528  * To know more on format of the component information see
529  * \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
530  *  \param [in] info - a vector of component infos.
531  *  \throw If \a this->getNumberOfComponents() != \a info.size() && \a this->isAllocated()
532  */
533 void DataArray::setInfoAndChangeNbOfCompo(const std::vector<std::string>& info)
534 {
535   if(getNumberOfComponents()!=(int)info.size())
536     {
537       if(!isAllocated())
538         _info_on_compo=info;
539       else
540         {
541           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 !";
542           throw INTERP_KERNEL::Exception(oss.str().c_str());
543         }
544     }
545   else
546     _info_on_compo=info;
547 }
548
549 void DataArray::checkNbOfTuples(int nbOfTuples, const std::string& msg) const
550 {
551   if(getNumberOfTuples()!=nbOfTuples)
552     {
553       std::ostringstream oss; oss << msg << " : mismatch number of tuples : expected " <<  nbOfTuples << " having " << getNumberOfTuples() << " !";
554       throw INTERP_KERNEL::Exception(oss.str().c_str());
555     }
556 }
557
558 void DataArray::checkNbOfComps(int nbOfCompo, const std::string& msg) const
559 {
560   if(getNumberOfComponents()!=nbOfCompo)
561     {
562       std::ostringstream oss; oss << msg << " : mismatch number of components : expected " << nbOfCompo << " having " << getNumberOfComponents() << " !";
563       throw INTERP_KERNEL::Exception(oss.str().c_str());
564     }
565 }
566
567 void DataArray::checkNbOfElems(std::size_t nbOfElems, const std::string& msg) const
568 {
569   if(getNbOfElems()!=nbOfElems)
570     {
571       std::ostringstream oss; oss << msg << " : mismatch number of elems : Expected " << nbOfElems << " having " << getNbOfElems() << " !";
572       throw INTERP_KERNEL::Exception(oss.str().c_str());
573     }
574 }
575
576 void DataArray::checkNbOfTuplesAndComp(const DataArray& other, const std::string& msg) const
577 {
578   if(getNumberOfTuples()!=other.getNumberOfTuples())
579     {
580       std::ostringstream oss; oss << msg << " : mismatch number of tuples : expected " <<  other.getNumberOfTuples() << " having " << getNumberOfTuples() << " !";
581       throw INTERP_KERNEL::Exception(oss.str().c_str());
582     }
583   if(getNumberOfComponents()!=other.getNumberOfComponents())
584     {
585       std::ostringstream oss; oss << msg << " : mismatch number of components : expected " << other.getNumberOfComponents() << " having " << getNumberOfComponents() << " !";
586       throw INTERP_KERNEL::Exception(oss.str().c_str());
587     }
588 }
589
590 void DataArray::checkNbOfTuplesAndComp(int nbOfTuples, int nbOfCompo, const std::string& msg) const
591 {
592   checkNbOfTuples(nbOfTuples,msg);
593   checkNbOfComps(nbOfCompo,msg);
594 }
595
596 /*!
597  * Simply this method checks that \b value is in [0,\b ref).
598  */
599 void DataArray::CheckValueInRange(int ref, int value, const std::string& msg)
600 {
601   if(value<0 || value>=ref)
602     {
603       std::ostringstream oss; oss << "DataArray::CheckValueInRange : " << msg  << " ! Expected in range [0," << ref << "[ having " << value << " !";
604       throw INTERP_KERNEL::Exception(oss.str().c_str());
605     }
606 }
607
608 /*!
609  * This method checks that [\b start, \b end) is compliant with ref length \b value.
610  * typicaly start in [0,\b value) and end in [0,\b value). If value==start and start==end, it is supported.
611  */
612 void DataArray::CheckValueInRangeEx(int value, int start, int end, const std::string& msg)
613 {
614   if(start<0 || start>=value)
615     {
616       if(value!=start || end!=start)
617         {
618           std::ostringstream oss; oss << "DataArray::CheckValueInRangeEx : " << msg  << " ! Expected start " << start << " of input range, in [0," << value << "[ !";
619           throw INTERP_KERNEL::Exception(oss.str().c_str());
620         }
621     }
622   if(end<0 || end>value)
623     {
624       std::ostringstream oss; oss << "DataArray::CheckValueInRangeEx : " << msg  << " ! Expected end " << end << " of input range, in [0," << value << "] !";
625       throw INTERP_KERNEL::Exception(oss.str().c_str());
626     }
627 }
628
629 void DataArray::CheckClosingParInRange(int ref, int value, const std::string& msg)
630 {
631   if(value<0 || value>ref)
632     {
633       std::ostringstream oss; oss << "DataArray::CheckClosingParInRange : " << msg  << " ! Expected input range in [0," << ref << "] having closing open parenthesis " << value << " !";
634       throw INTERP_KERNEL::Exception(oss.str().c_str());
635     }
636 }
637
638 /*!
639  * 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, 
640  * typically it is a whole slice of tuples of DataArray or cells, nodes of a mesh...
641  *
642  * The input \a sliceId should be an id in [0, \a nbOfSlices) that specifies the slice of work.
643  *
644  * \param [in] start - the start of the input slice of the whole work to perform splitted into slices.
645  * \param [in] stop - the stop of the input slice of the whole work to perform splitted into slices.
646  * \param [in] step - the step (that can be <0) of the input slice of the whole work to perform splitted into slices.
647  * \param [in] sliceId - the slice id considered
648  * \param [in] nbOfSlices - the number of slices (typically the number of cores on which the work is expected to be sliced)
649  * \param [out] startSlice - the start of the slice considered
650  * \param [out] stopSlice - the stop of the slice consided
651  * 
652  * \throw If \a step == 0
653  * \throw If \a nbOfSlices not > 0
654  * \throw If \a sliceId not in [0,nbOfSlices)
655  */
656 void DataArray::GetSlice(int start, int stop, int step, int sliceId, int nbOfSlices, int& startSlice, int& stopSlice)
657 {
658   if(nbOfSlices<=0)
659     {
660       std::ostringstream oss; oss << "DataArray::GetSlice : nbOfSlices (" << nbOfSlices << ") must be > 0 !";
661       throw INTERP_KERNEL::Exception(oss.str().c_str());
662     }
663   if(sliceId<0 || sliceId>=nbOfSlices)
664     {
665       std::ostringstream oss; oss << "DataArray::GetSlice : sliceId (" << nbOfSlices << ") must be in [0 , nbOfSlices (" << nbOfSlices << ") ) !";
666       throw INTERP_KERNEL::Exception(oss.str().c_str());
667     }
668   int nbElems=GetNumberOfItemGivenBESRelative(start,stop,step,"DataArray::GetSlice");
669   int minNbOfElemsPerSlice=nbElems/nbOfSlices;
670   startSlice=start+minNbOfElemsPerSlice*step*sliceId;
671   if(sliceId<nbOfSlices-1)
672     stopSlice=start+minNbOfElemsPerSlice*step*(sliceId+1);
673   else
674     stopSlice=stop;
675 }
676
677 int DataArray::GetNumberOfItemGivenBES(int begin, int end, int step, const std::string& msg)
678 {
679   if(end<begin)
680     {
681       std::ostringstream oss; oss << msg << " : end before begin !";
682       throw INTERP_KERNEL::Exception(oss.str().c_str());
683     }
684   if(end==begin)
685     return 0;
686   if(step<=0)
687     {
688       std::ostringstream oss; oss << msg << " : invalid step should be > 0 !";
689       throw INTERP_KERNEL::Exception(oss.str().c_str());
690     }
691   return (end-1-begin)/step+1;
692 }
693
694 int DataArray::GetNumberOfItemGivenBESRelative(int begin, int end, int step, const std::string& msg)
695 {
696   if(step==0)
697     throw INTERP_KERNEL::Exception("DataArray::GetNumberOfItemGivenBES : step=0 is not allowed !");
698   if(end<begin && step>0)
699     {
700       std::ostringstream oss; oss << msg << " : end before begin whereas step is positive !";
701       throw INTERP_KERNEL::Exception(oss.str().c_str());
702     }
703   if(begin<end && step<0)
704     {
705       std::ostringstream oss; oss << msg << " : invalid step should be > 0 !";
706       throw INTERP_KERNEL::Exception(oss.str().c_str());
707     }
708   if(begin!=end)
709     return (std::max(begin,end)-1-std::min(begin,end))/std::abs(step)+1;
710   else
711     return 0;
712 }
713
714 int DataArray::GetPosOfItemGivenBESRelativeNoThrow(int value, int begin, int end, int step)
715 {
716   if(step!=0)
717     {
718       if(step>0)
719         {
720           if(begin<=value && value<end)
721             {
722               if((value-begin)%step==0)
723                 return (value-begin)/step;
724               else
725                 return -1;
726             }
727           else
728             return -1;
729         }
730       else
731         {
732           if(begin>=value && value>end)
733             {
734               if((begin-value)%(-step)==0)
735                 return (begin-value)/(-step);
736               else
737                 return -1;
738             }
739           else
740             return -1;
741         }
742     }
743   else
744     return -1;
745 }
746
747 /*!
748  * Returns a new instance of DataArrayDouble. The caller is to delete this array
749  * using decrRef() as it is no more needed. 
750  */
751 DataArrayDouble *DataArrayDouble::New()
752 {
753   return new DataArrayDouble;
754 }
755
756 /*!
757  * Returns the only one value in \a this, if and only if number of elements
758  * (nb of tuples * nb of components) is equal to 1, and that \a this is allocated.
759  *  \return double - the sole value stored in \a this array.
760  *  \throw If at least one of conditions stated above is not fulfilled.
761  */
762 double DataArrayDouble::doubleValue() const
763 {
764   if(isAllocated())
765     {
766       if(getNbOfElems()==1)
767         {
768           return *getConstPointer();
769         }
770       else
771         throw INTERP_KERNEL::Exception("DataArrayDouble::doubleValue : DataArrayDouble instance is allocated but number of elements is not equal to 1 !");
772     }
773   else
774     throw INTERP_KERNEL::Exception("DataArrayDouble::doubleValue : DataArrayDouble instance is not allocated !");
775 }
776
777 /*!
778  * Returns a full copy of \a this. For more info on copying data arrays see
779  * \ref MEDCouplingArrayBasicsCopyDeep.
780  *  \return DataArrayDouble * - a new instance of DataArrayDouble. The caller is to
781  *          delete this array using decrRef() as it is no more needed. 
782  */
783 DataArrayDouble *DataArrayDouble::deepCopy() const
784 {
785   return new DataArrayDouble(*this);
786 }
787
788 /*!
789  * Returns either a \a deep or \a shallow copy of this array. For more info see
790  * \ref MEDCouplingArrayBasicsCopyDeep and \ref MEDCouplingArrayBasicsCopyShallow.
791  *  \param [in] dCpy - if \a true, a deep copy is returned, else, a shallow one.
792  *  \return DataArrayDouble * - either a new instance of DataArrayDouble (if \a dCpy
793  *          == \a true) or \a this instance (if \a dCpy == \a false).
794  */
795 DataArrayDouble *DataArrayDouble::performCopyOrIncrRef(bool dCpy) const
796 {
797   if(dCpy)
798     return deepCopy();
799   else
800     {
801       incrRef();
802       return const_cast<DataArrayDouble *>(this);
803     }
804 }
805
806 /*!
807  * Assign zero to all values in \a this array. To know more on filling arrays see
808  * \ref MEDCouplingArrayFill.
809  * \throw If \a this is not allocated.
810  */
811 void DataArrayDouble::fillWithZero()
812 {
813   fillWithValue(0.);
814 }
815
816 /*!
817  * Set all values in \a this array so that the i-th element equals to \a init + i
818  * (i starts from zero). To know more on filling arrays see \ref MEDCouplingArrayFill.
819  *  \param [in] init - value to assign to the first element of array.
820  *  \throw If \a this->getNumberOfComponents() != 1
821  *  \throw If \a this is not allocated.
822  */
823 void DataArrayDouble::iota(double init)
824 {
825   checkAllocated();
826   if(getNumberOfComponents()!=1)
827     throw INTERP_KERNEL::Exception("DataArrayDouble::iota : works only for arrays with only one component, you can call 'rearrange' method before !");
828   double *ptr=getPointer();
829   int ntuples=getNumberOfTuples();
830   for(int i=0;i<ntuples;i++)
831     ptr[i]=init+double(i);
832   declareAsNew();
833 }
834
835 /*!
836  * Checks if all values in \a this array are equal to \a val at precision \a eps.
837  *  \param [in] val - value to check equality of array values to.
838  *  \param [in] eps - precision to check the equality.
839  *  \return bool - \a true if all values are in range (_val_ - _eps_; _val_ + _eps_),
840  *                 \a false else.
841  *  \throw If \a this->getNumberOfComponents() != 1
842  *  \throw If \a this is not allocated.
843  */
844 bool DataArrayDouble::isUniform(double val, double eps) const
845 {
846   checkAllocated();
847   if(getNumberOfComponents()!=1)
848     throw INTERP_KERNEL::Exception("DataArrayDouble::isUniform : must be applied on DataArrayDouble with only one component, you can call 'rearrange' method before !");
849   int nbOfTuples=getNumberOfTuples();
850   const double *w=getConstPointer();
851   const double *end2=w+nbOfTuples;
852   const double vmin=val-eps;
853   const double vmax=val+eps;
854   for(;w!=end2;w++)
855     if(*w<vmin || *w>vmax)
856       return false;
857   return true;
858 }
859
860 /*!
861  * Checks that \a this array is consistently **increasing** or **decreasing** in value,
862  * with at least absolute difference value of |\a eps| at each step.
863  * If not an exception is thrown.
864  *  \param [in] increasing - if \a true, the array values should be increasing.
865  *  \param [in] eps - minimal absolute difference between the neighbor values at which 
866  *                    the values are considered different.
867  *  \throw If sequence of values is not strictly monotonic in agreement with \a
868  *         increasing arg.
869  *  \throw If \a this->getNumberOfComponents() != 1.
870  *  \throw If \a this is not allocated.
871  */
872 void DataArrayDouble::checkMonotonic(bool increasing, double eps) const
873 {
874   if(!isMonotonic(increasing,eps))
875     {
876       if (increasing)
877         throw INTERP_KERNEL::Exception("DataArrayDouble::checkMonotonic : 'this' is not INCREASING monotonic !");
878       else
879         throw INTERP_KERNEL::Exception("DataArrayDouble::checkMonotonic : 'this' is not DECREASING monotonic !");
880     }
881 }
882
883 /*!
884  * Checks that \a this array is consistently **increasing** or **decreasing** in value,
885  * with at least absolute difference value of |\a eps| at each step.
886  *  \param [in] increasing - if \a true, array values should be increasing.
887  *  \param [in] eps - minimal absolute difference between the neighbor values at which 
888  *                    the values are considered different.
889  *  \return bool - \a true if values change in accordance with \a increasing arg.
890  *  \throw If \a this->getNumberOfComponents() != 1.
891  *  \throw If \a this is not allocated.
892  */
893 bool DataArrayDouble::isMonotonic(bool increasing, double eps) const
894 {
895   checkAllocated();
896   if(getNumberOfComponents()!=1)
897     throw INTERP_KERNEL::Exception("DataArrayDouble::isMonotonic : only supported with 'this' array with ONE component !");
898   int nbOfElements=getNumberOfTuples();
899   const double *ptr=getConstPointer();
900   if(nbOfElements==0)
901     return true;
902   double ref=ptr[0];
903   double absEps=fabs(eps);
904   if(increasing)
905     {
906       for(int i=1;i<nbOfElements;i++)
907         {
908           if(ptr[i]<(ref+absEps))
909             return false;
910           ref=ptr[i];
911         }
912       return true;
913     }
914   else
915     {
916       for(int i=1;i<nbOfElements;i++)
917         {
918           if(ptr[i]>(ref-absEps))
919             return false;
920           ref=ptr[i];
921         }
922       return true;
923     }
924 }
925
926 /*!
927  * Returns a textual and human readable representation of \a this instance of
928  * DataArrayDouble. This text is shown when a DataArrayDouble is printed in Python.
929  * \return std::string - text describing \a this DataArrayDouble.
930  *
931  * \sa reprNotTooLong, reprZip
932  */
933 std::string DataArrayDouble::repr() const
934 {
935   std::ostringstream ret;
936   reprStream(ret);
937   return ret.str();
938 }
939
940 std::string DataArrayDouble::reprZip() const
941 {
942   std::ostringstream ret;
943   reprZipStream(ret);
944   return ret.str();
945 }
946
947 /*!
948  * This method is close to repr method except that when \a this has more than 1000 tuples, all tuples are not
949  * printed out to avoid to consume too much space in interpretor.
950  * \sa repr
951  */
952 std::string DataArrayDouble::reprNotTooLong() const
953 {
954   std::ostringstream ret;
955   reprNotTooLongStream(ret);
956   return ret.str();
957 }
958
959 void DataArrayDouble::writeVTK(std::ostream& ofs, int indent, const std::string& nameInFile, DataArrayByte *byteArr) const
960 {
961   static const char SPACE[4]={' ',' ',' ',' '};
962   checkAllocated();
963   std::string idt(indent,' ');
964   ofs.precision(17);
965   ofs << idt << "<DataArray type=\"Float32\" Name=\"" << nameInFile << "\" NumberOfComponents=\"" << getNumberOfComponents() << "\"";
966   //
967   bool areAllEmpty(true);
968   for(std::vector<std::string>::const_iterator it=_info_on_compo.begin();it!=_info_on_compo.end();it++)
969     if(!(*it).empty())
970       areAllEmpty=false;
971   if(!areAllEmpty)
972     for(std::size_t i=0;i<_info_on_compo.size();i++)
973       ofs << " ComponentName" << i << "=\"" << _info_on_compo[i] << "\"";
974   //
975   if(byteArr)
976     {
977       ofs << " format=\"appended\" offset=\"" << byteArr->getNumberOfTuples() << "\">";
978       INTERP_KERNEL::AutoPtr<float> tmp(new float[getNbOfElems()]);
979       float *pt(tmp);
980       // to make Visual C++ happy : instead of std::copy(begin(),end(),(float *)tmp);
981       for(const double *src=begin();src!=end();src++,pt++)
982         *pt=float(*src);
983       const char *data(reinterpret_cast<const char *>((float *)tmp));
984       std::size_t sz(getNbOfElems()*sizeof(float));
985       byteArr->insertAtTheEnd(data,data+sz);
986       byteArr->insertAtTheEnd(SPACE,SPACE+4);
987     }
988   else
989     {
990       ofs << " RangeMin=\"" << getMinValueInArray() << "\" RangeMax=\"" << getMaxValueInArray() << "\" format=\"ascii\">\n" << idt;
991       std::copy(begin(),end(),std::ostream_iterator<double>(ofs," "));
992     }
993   ofs << std::endl << idt << "</DataArray>\n";
994 }
995
996 void DataArrayDouble::reprStream(std::ostream& stream) const
997 {
998   stream << "Name of double array : \"" << _name << "\"\n";
999   reprWithoutNameStream(stream);
1000 }
1001
1002 void DataArrayDouble::reprZipStream(std::ostream& stream) const
1003 {
1004   stream << "Name of double array : \"" << _name << "\"\n";
1005   reprZipWithoutNameStream(stream);
1006 }
1007
1008 void DataArrayDouble::reprNotTooLongStream(std::ostream& stream) const
1009 {
1010   stream << "Name of double array : \"" << _name << "\"\n";
1011   reprNotTooLongWithoutNameStream(stream);
1012 }
1013
1014 void DataArrayDouble::reprWithoutNameStream(std::ostream& stream) const
1015 {
1016   DataArray::reprWithoutNameStream(stream);
1017   stream.precision(17);
1018   _mem.repr(getNumberOfComponents(),stream);
1019 }
1020
1021 void DataArrayDouble::reprZipWithoutNameStream(std::ostream& stream) const
1022 {
1023   DataArray::reprWithoutNameStream(stream);
1024   stream.precision(17);
1025   _mem.reprZip(getNumberOfComponents(),stream);
1026 }
1027
1028 void DataArrayDouble::reprNotTooLongWithoutNameStream(std::ostream& stream) const
1029 {
1030   DataArray::reprWithoutNameStream(stream);
1031   stream.precision(17);
1032   _mem.reprNotTooLong(getNumberOfComponents(),stream);
1033 }
1034
1035 void DataArrayDouble::reprCppStream(const std::string& varName, std::ostream& stream) const
1036 {
1037   int nbTuples=getNumberOfTuples(),nbComp=getNumberOfComponents();
1038   const double *data=getConstPointer();
1039   stream.precision(17);
1040   stream << "DataArrayDouble *" << varName << "=DataArrayDouble::New();" << std::endl;
1041   if(nbTuples*nbComp>=1)
1042     {
1043       stream << "const double " << varName << "Data[" << nbTuples*nbComp << "]={";
1044       std::copy(data,data+nbTuples*nbComp-1,std::ostream_iterator<double>(stream,","));
1045       stream << data[nbTuples*nbComp-1] << "};" << std::endl;
1046       stream << varName << "->useArray(" << varName << "Data,false,CPP_DEALLOC," << nbTuples << "," << nbComp << ");" << std::endl;
1047     }
1048   else
1049     stream << varName << "->alloc(" << nbTuples << "," << nbComp << ");" << std::endl;
1050   stream << varName << "->setName(\"" << getName() << "\");" << std::endl;
1051 }
1052
1053 /*!
1054  * Method that gives a quick overvien of \a this for python.
1055  */
1056 void DataArrayDouble::reprQuickOverview(std::ostream& stream) const
1057 {
1058   static const std::size_t MAX_NB_OF_BYTE_IN_REPR=300;
1059   stream << "DataArrayDouble C++ instance at " << this << ". ";
1060   if(isAllocated())
1061     {
1062       int nbOfCompo=(int)_info_on_compo.size();
1063       if(nbOfCompo>=1)
1064         {
1065           int nbOfTuples=getNumberOfTuples();
1066           stream << "Number of tuples : " << nbOfTuples << ". Number of components : " << nbOfCompo << "." << std::endl;
1067           reprQuickOverviewData(stream,MAX_NB_OF_BYTE_IN_REPR);
1068         }
1069       else
1070         stream << "Number of components : 0.";
1071     }
1072   else
1073     stream << "*** No data allocated ****";
1074 }
1075
1076 void DataArrayDouble::reprQuickOverviewData(std::ostream& stream, std::size_t maxNbOfByteInRepr) const
1077 {
1078   const double *data=begin();
1079   int nbOfTuples=getNumberOfTuples();
1080   int nbOfCompo=(int)_info_on_compo.size();
1081   std::ostringstream oss2; oss2 << "[";
1082   oss2.precision(17);
1083   std::string oss2Str(oss2.str());
1084   bool isFinished=true;
1085   for(int i=0;i<nbOfTuples && isFinished;i++)
1086     {
1087       if(nbOfCompo>1)
1088         {
1089           oss2 << "(";
1090           for(int j=0;j<nbOfCompo;j++,data++)
1091             {
1092               oss2 << *data;
1093               if(j!=nbOfCompo-1) oss2 << ", ";
1094             }
1095           oss2 << ")";
1096         }
1097       else
1098         oss2 << *data++;
1099       if(i!=nbOfTuples-1) oss2 << ", ";
1100       std::string oss3Str(oss2.str());
1101       if(oss3Str.length()<maxNbOfByteInRepr)
1102         oss2Str=oss3Str;
1103       else
1104         isFinished=false;
1105     }
1106   stream << oss2Str;
1107   if(!isFinished)
1108     stream << "... ";
1109   stream << "]";
1110 }
1111
1112 /*!
1113  * Equivalent to DataArrayDouble::isEqual except that if false the reason of
1114  * mismatch is given.
1115  * 
1116  * \param [in] other the instance to be compared with \a this
1117  * \param [in] prec the precision to compare numeric data of the arrays.
1118  * \param [out] reason In case of inequality returns the reason.
1119  * \sa DataArrayDouble::isEqual
1120  */
1121 bool DataArrayDouble::isEqualIfNotWhy(const DataArrayDouble& other, double prec, std::string& reason) const
1122 {
1123   if(!areInfoEqualsIfNotWhy(other,reason))
1124     return false;
1125   return _mem.isEqual(other._mem,prec,reason);
1126 }
1127
1128 /*!
1129  * Checks if \a this and another DataArrayDouble are fully equal. For more info see
1130  * \ref MEDCouplingArrayBasicsCompare.
1131  *  \param [in] other - an instance of DataArrayDouble to compare with \a this one.
1132  *  \param [in] prec - precision value to compare numeric data of the arrays.
1133  *  \return bool - \a true if the two arrays are equal, \a false else.
1134  */
1135 bool DataArrayDouble::isEqual(const DataArrayDouble& other, double prec) const
1136 {
1137   std::string tmp;
1138   return isEqualIfNotWhy(other,prec,tmp);
1139 }
1140
1141 /*!
1142  * Checks if values of \a this and another DataArrayDouble are equal. For more info see
1143  * \ref MEDCouplingArrayBasicsCompare.
1144  *  \param [in] other - an instance of DataArrayDouble to compare with \a this one.
1145  *  \param [in] prec - precision value to compare numeric data of the arrays.
1146  *  \return bool - \a true if the values of two arrays are equal, \a false else.
1147  */
1148 bool DataArrayDouble::isEqualWithoutConsideringStr(const DataArrayDouble& other, double prec) const
1149 {
1150   std::string tmp;
1151   return _mem.isEqual(other._mem,prec,tmp);
1152 }
1153
1154 /*!
1155  * Creates a new DataArrayInt and assigns all (textual and numerical) data of \a this
1156  * array to the new one.
1157  *  \return DataArrayInt * - the new instance of DataArrayInt.
1158  */
1159 DataArrayInt *DataArrayDouble::convertToIntArr() const
1160 {
1161   DataArrayInt *ret=DataArrayInt::New();
1162   ret->alloc(getNumberOfTuples(),getNumberOfComponents());
1163   int *dest=ret->getPointer();
1164   // to make Visual C++ happy : instead of std::size_t nbOfVals=getNbOfElems(); std::copy(src,src+nbOfVals,dest);
1165   for(const double *src=begin();src!=end();src++,dest++)
1166     *dest=(int)*src;
1167   ret->copyStringInfoFrom(*this);
1168   return ret;
1169 }
1170
1171 /*!
1172  * Returns a new DataArrayDouble holding the same values as \a this array but differently
1173  * arranged in memory. If \a this array holds 2 components of 3 values:
1174  * \f$ x_0,x_1,x_2,y_0,y_1,y_2 \f$, then the result array holds these values arranged
1175  * as follows: \f$ x_0,y_0,x_1,y_1,x_2,y_2 \f$.
1176  *  \warning Do not confuse this method with transpose()!
1177  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1178  *          is to delete using decrRef() as it is no more needed.
1179  *  \throw If \a this is not allocated.
1180  */
1181 DataArrayDouble *DataArrayDouble::fromNoInterlace() const
1182 {
1183   if(_mem.isNull())
1184     throw INTERP_KERNEL::Exception("DataArrayDouble::fromNoInterlace : Not defined array !");
1185   double *tab=_mem.fromNoInterlace(getNumberOfComponents());
1186   DataArrayDouble *ret=DataArrayDouble::New();
1187   ret->useArray(tab,true,C_DEALLOC,getNumberOfTuples(),getNumberOfComponents());
1188   return ret;
1189 }
1190
1191 /*!
1192  * Returns a new DataArrayDouble holding the same values as \a this array but differently
1193  * arranged in memory. If \a this array holds 2 components of 3 values:
1194  * \f$ x_0,y_0,x_1,y_1,x_2,y_2 \f$, then the result array holds these values arranged
1195  * as follows: \f$ x_0,x_1,x_2,y_0,y_1,y_2 \f$.
1196  *  \warning Do not confuse this method with transpose()!
1197  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1198  *          is to delete using decrRef() as it is no more needed.
1199  *  \throw If \a this is not allocated.
1200  */
1201 DataArrayDouble *DataArrayDouble::toNoInterlace() const
1202 {
1203   if(_mem.isNull())
1204     throw INTERP_KERNEL::Exception("DataArrayDouble::toNoInterlace : Not defined array !");
1205   double *tab=_mem.toNoInterlace(getNumberOfComponents());
1206   DataArrayDouble *ret=DataArrayDouble::New();
1207   ret->useArray(tab,true,C_DEALLOC,getNumberOfTuples(),getNumberOfComponents());
1208   return ret;
1209 }
1210
1211 /*!
1212  * Returns a copy of \a this array with values permuted as required by \a new2Old array.
1213  * The values are permuted so that  \c new[ i ] = \c old[ \a new2Old[ i ]]. Number of
1214  * tuples in the result array remains the same as in \c this one.
1215  * If a permutation reduction is needed, subArray() or selectByTupleId() should be used.
1216  * For more info on renumbering see \ref numbering.
1217  *  \param [in] new2Old - C array of length equal to \a this->getNumberOfTuples()
1218  *     giving a previous position of i-th new value.
1219  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1220  *          is to delete using decrRef() as it is no more needed.
1221  */
1222 DataArrayDouble *DataArrayDouble::renumberR(const int *new2Old) const
1223 {
1224   checkAllocated();
1225   int nbTuples=getNumberOfTuples();
1226   int nbOfCompo=getNumberOfComponents();
1227   MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
1228   ret->alloc(nbTuples,nbOfCompo);
1229   ret->copyStringInfoFrom(*this);
1230   const double *iptr=getConstPointer();
1231   double *optr=ret->getPointer();
1232   for(int i=0;i<nbTuples;i++)
1233     std::copy(iptr+nbOfCompo*new2Old[i],iptr+nbOfCompo*(new2Old[i]+1),optr+i*nbOfCompo);
1234   ret->copyStringInfoFrom(*this);
1235   return ret.retn();
1236 }
1237
1238 /*!
1239  * Returns a shorten and permuted copy of \a this array. The new DataArrayDouble is
1240  * of size \a newNbOfTuple and it's values are permuted as required by \a old2New array.
1241  * The values are permuted so that  \c new[ \a old2New[ i ]] = \c old[ i ] for all
1242  * \a old2New[ i ] >= 0. In other words every i-th tuple in \a this array, for which 
1243  * \a old2New[ i ] is negative, is missing from the result array.
1244  * For more info on renumbering see \ref numbering.
1245  *  \param [in] old2New - C array of length equal to \a this->getNumberOfTuples()
1246  *     giving a new position for i-th old tuple and giving negative position for
1247  *     for i-th old tuple that should be omitted.
1248  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1249  *          is to delete using decrRef() as it is no more needed.
1250  */
1251 DataArrayDouble *DataArrayDouble::renumberAndReduce(const int *old2New, int newNbOfTuple) const
1252 {
1253   checkAllocated();
1254   int nbTuples=getNumberOfTuples();
1255   int nbOfCompo=getNumberOfComponents();
1256   MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
1257   ret->alloc(newNbOfTuple,nbOfCompo);
1258   const double *iptr=getConstPointer();
1259   double *optr=ret->getPointer();
1260   for(int i=0;i<nbTuples;i++)
1261     {
1262       int w=old2New[i];
1263       if(w>=0)
1264         std::copy(iptr+i*nbOfCompo,iptr+(i+1)*nbOfCompo,optr+w*nbOfCompo);
1265     }
1266   ret->copyStringInfoFrom(*this);
1267   return ret.retn();
1268 }
1269
1270 /*!
1271  * Returns a shorten and permuted copy of \a this array. The new DataArrayDouble is
1272  * of size \a new2OldEnd - \a new2OldBg and it's values are permuted as required by
1273  * \a new2OldBg array.
1274  * The values are permuted so that  \c new[ i ] = \c old[ \a new2OldBg[ i ]].
1275  * This method is equivalent to renumberAndReduce() except that convention in input is
1276  * \c new2old and \b not \c old2new.
1277  * For more info on renumbering see \ref numbering.
1278  *  \param [in] new2OldBg - pointer to the beginning of a permutation array that gives a
1279  *              tuple index in \a this array to fill the i-th tuple in the new array.
1280  *  \param [in] new2OldEnd - specifies the end of the permutation array that starts at
1281  *              \a new2OldBg, so that pointer to a tuple index (\a pi) varies as this:
1282  *              \a new2OldBg <= \a pi < \a new2OldEnd.
1283  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1284  *          is to delete using decrRef() as it is no more needed.
1285  */
1286 DataArrayDouble *DataArrayDouble::selectByTupleId(const int *new2OldBg, const int *new2OldEnd) const
1287 {
1288   checkAllocated();
1289   MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
1290   int nbComp=getNumberOfComponents();
1291   ret->alloc((int)std::distance(new2OldBg,new2OldEnd),nbComp);
1292   ret->copyStringInfoFrom(*this);
1293   double *pt=ret->getPointer();
1294   const double *srcPt=getConstPointer();
1295   int i=0;
1296   for(const int *w=new2OldBg;w!=new2OldEnd;w++,i++)
1297     std::copy(srcPt+(*w)*nbComp,srcPt+((*w)+1)*nbComp,pt+i*nbComp);
1298   ret->copyStringInfoFrom(*this);
1299   return ret.retn();
1300 }
1301
1302 DataArrayDouble *DataArrayDouble::selectByTupleId(const DataArrayInt & di) const
1303 {
1304   return selectByTupleId(di.getConstPointer(), di.getConstPointer()+di.getNumberOfTuples());
1305 }
1306
1307 /*!
1308  * Returns a shorten and permuted copy of \a this array. The new DataArrayDouble is
1309  * of size \a new2OldEnd - \a new2OldBg and it's values are permuted as required by
1310  * \a new2OldBg array.
1311  * The values are permuted so that  \c new[ i ] = \c old[ \a new2OldBg[ i ]].
1312  * This method is equivalent to renumberAndReduce() except that convention in input is
1313  * \c new2old and \b not \c old2new.
1314  * This method is equivalent to selectByTupleId() except that it prevents coping data
1315  * from behind the end of \a this array.
1316  * For more info on renumbering see \ref numbering.
1317  *  \param [in] new2OldBg - pointer to the beginning of a permutation array that gives a
1318  *              tuple index in \a this array to fill the i-th tuple in the new array.
1319  *  \param [in] new2OldEnd - specifies the end of the permutation array that starts at
1320  *              \a new2OldBg, so that pointer to a tuple index (\a pi) varies as this:
1321  *              \a new2OldBg <= \a pi < \a new2OldEnd.
1322  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1323  *          is to delete using decrRef() as it is no more needed.
1324  *  \throw If \a new2OldEnd - \a new2OldBg > \a this->getNumberOfTuples().
1325  */
1326 DataArrayDouble *DataArrayDouble::selectByTupleIdSafe(const int *new2OldBg, const int *new2OldEnd) const
1327 {
1328   checkAllocated();
1329   MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
1330   int nbComp=getNumberOfComponents();
1331   int oldNbOfTuples=getNumberOfTuples();
1332   ret->alloc((int)std::distance(new2OldBg,new2OldEnd),nbComp);
1333   ret->copyStringInfoFrom(*this);
1334   double *pt=ret->getPointer();
1335   const double *srcPt=getConstPointer();
1336   int i=0;
1337   for(const int *w=new2OldBg;w!=new2OldEnd;w++,i++)
1338     if(*w>=0 && *w<oldNbOfTuples)
1339       std::copy(srcPt+(*w)*nbComp,srcPt+((*w)+1)*nbComp,pt+i*nbComp);
1340     else
1341       throw INTERP_KERNEL::Exception("DataArrayDouble::selectByTupleIdSafe : some ids has been detected to be out of [0,this->getNumberOfTuples) !");
1342   ret->copyStringInfoFrom(*this);
1343   return ret.retn();
1344 }
1345
1346 /*!
1347  * Returns a shorten copy of \a this array. The new DataArrayDouble contains every
1348  * (\a bg + \c i * \a step)-th tuple of \a this array located before the \a end2-th
1349  * tuple. Indices of the selected tuples are the same as ones returned by the Python
1350  * command \c range( \a bg, \a end2, \a step ).
1351  * This method is equivalent to selectByTupleIdSafe() except that the input array is
1352  * not constructed explicitly.
1353  * For more info on renumbering see \ref numbering.
1354  *  \param [in] bg - index of the first tuple to copy from \a this array.
1355  *  \param [in] end2 - index of the tuple before which the tuples to copy are located.
1356  *  \param [in] step - index increment to get index of the next tuple to copy.
1357  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1358  *          is to delete using decrRef() as it is no more needed.
1359  *  \sa DataArrayDouble::subArray.
1360  */
1361 DataArrayDouble *DataArrayDouble::selectByTupleIdSafeSlice(int bg, int end2, int step) const
1362 {
1363   checkAllocated();
1364   MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
1365   int nbComp=getNumberOfComponents();
1366   int newNbOfTuples=GetNumberOfItemGivenBESRelative(bg,end2,step,"DataArrayDouble::selectByTupleIdSafeSlice : ");
1367   ret->alloc(newNbOfTuples,nbComp);
1368   double *pt=ret->getPointer();
1369   const double *srcPt=getConstPointer()+bg*nbComp;
1370   for(int i=0;i<newNbOfTuples;i++,srcPt+=step*nbComp)
1371     std::copy(srcPt,srcPt+nbComp,pt+i*nbComp);
1372   ret->copyStringInfoFrom(*this);
1373   return ret.retn();
1374 }
1375
1376 /*!
1377  * Returns a shorten copy of \a this array. The new DataArrayDouble contains ranges
1378  * of tuples specified by \a ranges parameter.
1379  * For more info on renumbering see \ref numbering.
1380  *  \param [in] ranges - std::vector of std::pair's each of which defines a range
1381  *              of tuples in [\c begin,\c end) format.
1382  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1383  *          is to delete using decrRef() as it is no more needed.
1384  *  \throw If \a end < \a begin.
1385  *  \throw If \a end > \a this->getNumberOfTuples().
1386  *  \throw If \a this is not allocated.
1387  */
1388 DataArray *DataArrayDouble::selectByTupleRanges(const std::vector<std::pair<int,int> >& ranges) const
1389 {
1390   checkAllocated();
1391   int nbOfComp=getNumberOfComponents();
1392   int nbOfTuplesThis=getNumberOfTuples();
1393   if(ranges.empty())
1394     {
1395       DataArrayDouble *ret=DataArrayDouble::New();
1396       ret->alloc(0,nbOfComp);
1397       ret->copyStringInfoFrom(*this);
1398       return ret;
1399     }
1400   int ref=ranges.front().first;
1401   int nbOfTuples=0;
1402   bool isIncreasing=true;
1403   for(std::vector<std::pair<int,int> >::const_iterator it=ranges.begin();it!=ranges.end();it++)
1404     {
1405       if((*it).first<=(*it).second)
1406         {
1407           if((*it).first>=0 && (*it).second<=nbOfTuplesThis)
1408             {
1409               nbOfTuples+=(*it).second-(*it).first;
1410               if(isIncreasing)
1411                 isIncreasing=ref<=(*it).first;
1412               ref=(*it).second;
1413             }
1414           else
1415             {
1416               std::ostringstream oss; oss << "DataArrayDouble::selectByTupleRanges : on range #" << std::distance(ranges.begin(),it);
1417               oss << " (" << (*it).first << "," << (*it).second << ") is greater than number of tuples of this :" << nbOfTuples << " !";
1418               throw INTERP_KERNEL::Exception(oss.str().c_str());
1419             }
1420         }
1421       else
1422         {
1423           std::ostringstream oss; oss << "DataArrayDouble::selectByTupleRanges : on range #" << std::distance(ranges.begin(),it);
1424           oss << " (" << (*it).first << "," << (*it).second << ") end is before begin !";
1425           throw INTERP_KERNEL::Exception(oss.str().c_str());
1426         }
1427     }
1428   if(isIncreasing && nbOfTuplesThis==nbOfTuples)
1429     return deepCopy();
1430   MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
1431   ret->alloc(nbOfTuples,nbOfComp);
1432   ret->copyStringInfoFrom(*this);
1433   const double *src=getConstPointer();
1434   double *work=ret->getPointer();
1435   for(std::vector<std::pair<int,int> >::const_iterator it=ranges.begin();it!=ranges.end();it++)
1436     work=std::copy(src+(*it).first*nbOfComp,src+(*it).second*nbOfComp,work);
1437   return ret.retn();
1438 }
1439
1440 /*!
1441  * Returns a shorten copy of \a this array. The new DataArrayDouble contains all
1442  * tuples starting from the \a tupleIdBg-th tuple and including all tuples located before
1443  * the \a tupleIdEnd-th one. This methods has a similar behavior as std::string::substr().
1444  * This method is a specialization of selectByTupleIdSafeSlice().
1445  *  \param [in] tupleIdBg - index of the first tuple to copy from \a this array.
1446  *  \param [in] tupleIdEnd - index of the tuple before which the tuples to copy are located.
1447  *          If \a tupleIdEnd == -1, all the tuples till the end of \a this array are copied.
1448  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1449  *          is to delete using decrRef() as it is no more needed.
1450  *  \throw If \a tupleIdBg < 0.
1451  *  \throw If \a tupleIdBg > \a this->getNumberOfTuples().
1452     \throw If \a tupleIdEnd != -1 && \a tupleIdEnd < \a this->getNumberOfTuples().
1453  *  \sa DataArrayDouble::selectByTupleIdSafeSlice
1454  */
1455 DataArrayDouble *DataArrayDouble::subArray(int tupleIdBg, int tupleIdEnd) const
1456 {
1457   checkAllocated();
1458   int nbt=getNumberOfTuples();
1459   if(tupleIdBg<0)
1460     throw INTERP_KERNEL::Exception("DataArrayDouble::subArray : The tupleIdBg parameter must be greater than 0 !");
1461   if(tupleIdBg>nbt)
1462     throw INTERP_KERNEL::Exception("DataArrayDouble::subArray : The tupleIdBg parameter is greater than number of tuples !");
1463   int trueEnd=tupleIdEnd;
1464   if(tupleIdEnd!=-1)
1465     {
1466       if(tupleIdEnd>nbt)
1467         throw INTERP_KERNEL::Exception("DataArrayDouble::subArray : The tupleIdBg parameter is greater or equal than number of tuples !");
1468     }
1469   else
1470     trueEnd=nbt;
1471   int nbComp=getNumberOfComponents();
1472   MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
1473   ret->alloc(trueEnd-tupleIdBg,nbComp);
1474   ret->copyStringInfoFrom(*this);
1475   std::copy(getConstPointer()+tupleIdBg*nbComp,getConstPointer()+trueEnd*nbComp,ret->getPointer());
1476   return ret.retn();
1477 }
1478
1479 /*!
1480  * Returns a shorten or extended copy of \a this array. If \a newNbOfComp is less
1481  * than \a this->getNumberOfComponents() then the result array is shorten as each tuple
1482  * is truncated to have \a newNbOfComp components, keeping first components. If \a
1483  * newNbOfComp is more than \a this->getNumberOfComponents() then the result array is
1484  * expanded as each tuple is populated with \a dftValue to have \a newNbOfComp
1485  * components.  
1486  *  \param [in] newNbOfComp - number of components for the new array to have.
1487  *  \param [in] dftValue - value assigned to new values added to the new array.
1488  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1489  *          is to delete using decrRef() as it is no more needed.
1490  *  \throw If \a this is not allocated.
1491  */
1492 DataArrayDouble *DataArrayDouble::changeNbOfComponents(int newNbOfComp, double dftValue) const
1493 {
1494   checkAllocated();
1495   MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
1496   ret->alloc(getNumberOfTuples(),newNbOfComp);
1497   const double *oldc=getConstPointer();
1498   double *nc=ret->getPointer();
1499   int nbOfTuples=getNumberOfTuples();
1500   int oldNbOfComp=getNumberOfComponents();
1501   int dim=std::min(oldNbOfComp,newNbOfComp);
1502   for(int i=0;i<nbOfTuples;i++)
1503     {
1504       int j=0;
1505       for(;j<dim;j++)
1506         nc[newNbOfComp*i+j]=oldc[i*oldNbOfComp+j];
1507       for(;j<newNbOfComp;j++)
1508         nc[newNbOfComp*i+j]=dftValue;
1509     }
1510   ret->setName(getName());
1511   for(int i=0;i<dim;i++)
1512     ret->setInfoOnComponent(i,getInfoOnComponent(i));
1513   ret->setName(getName());
1514   return ret.retn();
1515 }
1516
1517 /*!
1518  * Changes the number of components within \a this array so that its raw data **does
1519  * not** change, instead splitting this data into tuples changes.
1520  *  \warning This method erases all (name and unit) component info set before!
1521  *  \param [in] newNbOfComp - number of components for \a this array to have.
1522  *  \throw If \a this is not allocated
1523  *  \throw If getNbOfElems() % \a newNbOfCompo != 0.
1524  *  \throw If \a newNbOfCompo is lower than 1.
1525  *  \throw If the rearrange method would lead to a number of tuples higher than 2147483647 (maximal capacity of int32 !).
1526  *  \warning This method erases all (name and unit) component info set before!
1527  */
1528 void DataArrayDouble::rearrange(int newNbOfCompo)
1529 {
1530   checkAllocated();
1531   if(newNbOfCompo<1)
1532     throw INTERP_KERNEL::Exception("DataArrayDouble::rearrange : input newNbOfCompo must be > 0 !");
1533   std::size_t nbOfElems=getNbOfElems();
1534   if(nbOfElems%newNbOfCompo!=0)
1535     throw INTERP_KERNEL::Exception("DataArrayDouble::rearrange : nbOfElems%newNbOfCompo!=0 !");
1536   if(nbOfElems/newNbOfCompo>(std::size_t)std::numeric_limits<int>::max())
1537     throw INTERP_KERNEL::Exception("DataArrayDouble::rearrange : the rearrangement leads to too high number of tuples (> 2147483647) !");
1538   _info_on_compo.clear();
1539   _info_on_compo.resize(newNbOfCompo);
1540   declareAsNew();
1541 }
1542
1543 /*!
1544  * Changes the number of components within \a this array to be equal to its number
1545  * of tuples, and inversely its number of tuples to become equal to its number of 
1546  * components. So that its raw data **does not** change, instead splitting this
1547  * data into tuples changes.
1548  *  \warning This method erases all (name and unit) component info set before!
1549  *  \warning Do not confuse this method with fromNoInterlace() and toNoInterlace()!
1550  *  \throw If \a this is not allocated.
1551  *  \sa rearrange()
1552  */
1553 void DataArrayDouble::transpose()
1554 {
1555   checkAllocated();
1556   int nbOfTuples=getNumberOfTuples();
1557   rearrange(nbOfTuples);
1558 }
1559
1560 /*!
1561  * Returns a copy of \a this array composed of selected components.
1562  * The new DataArrayDouble has the same number of tuples but includes components
1563  * specified by \a compoIds parameter. So that getNbOfElems() of the result array
1564  * can be either less, same or more than \a this->getNbOfElems().
1565  *  \param [in] compoIds - sequence of zero based indices of components to include
1566  *              into the new array.
1567  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1568  *          is to delete using decrRef() as it is no more needed.
1569  *  \throw If \a this is not allocated.
1570  *  \throw If a component index (\a i) is not valid: 
1571  *         \a i < 0 || \a i >= \a this->getNumberOfComponents().
1572  *
1573  *  \if ENABLE_EXAMPLES
1574  *  \ref py_mcdataarraydouble_KeepSelectedComponents "Here is a Python example".
1575  *  \endif
1576  */
1577 DataArrayDouble *DataArrayDouble::keepSelectedComponents(const std::vector<int>& compoIds) const
1578 {
1579   checkAllocated();
1580   MCAuto<DataArrayDouble> ret(DataArrayDouble::New());
1581   std::size_t newNbOfCompo=compoIds.size();
1582   int oldNbOfCompo=getNumberOfComponents();
1583   for(std::vector<int>::const_iterator it=compoIds.begin();it!=compoIds.end();it++)
1584     if((*it)<0 || (*it)>=oldNbOfCompo)
1585       {
1586         std::ostringstream oss; oss << "DataArrayDouble::keepSelectedComponents : invalid requested component : " << *it << " whereas it should be in [0," << oldNbOfCompo << ") !";
1587         throw INTERP_KERNEL::Exception(oss.str().c_str());
1588       }
1589   int nbOfTuples=getNumberOfTuples();
1590   ret->alloc(nbOfTuples,(int)newNbOfCompo);
1591   ret->copyPartOfStringInfoFrom(*this,compoIds);
1592   const double *oldc=getConstPointer();
1593   double *nc=ret->getPointer();
1594   for(int i=0;i<nbOfTuples;i++)
1595     for(std::size_t j=0;j<newNbOfCompo;j++,nc++)
1596       *nc=oldc[i*oldNbOfCompo+compoIds[j]];
1597   return ret.retn();
1598 }
1599
1600 /*!
1601  * Appends components of another array to components of \a this one, tuple by tuple.
1602  * So that the number of tuples of \a this array remains the same and the number of 
1603  * components increases.
1604  *  \param [in] other - the DataArrayDouble to append to \a this one.
1605  *  \throw If \a this is not allocated.
1606  *  \throw If \a this and \a other arrays have different number of tuples.
1607  *
1608  *  \if ENABLE_EXAMPLES
1609  *  \ref cpp_mcdataarraydouble_meldwith "Here is a C++ example".
1610  *
1611  *  \ref py_mcdataarraydouble_meldwith "Here is a Python example".
1612  *  \endif
1613  */
1614 void DataArrayDouble::meldWith(const DataArrayDouble *other)
1615 {
1616   checkAllocated();
1617   other->checkAllocated();
1618   int nbOfTuples=getNumberOfTuples();
1619   if(nbOfTuples!=other->getNumberOfTuples())
1620     throw INTERP_KERNEL::Exception("DataArrayDouble::meldWith : mismatch of number of tuples !");
1621   int nbOfComp1=getNumberOfComponents();
1622   int nbOfComp2=other->getNumberOfComponents();
1623   double *newArr=(double *)malloc((nbOfTuples*(nbOfComp1+nbOfComp2))*sizeof(double));
1624   double *w=newArr;
1625   const double *inp1=getConstPointer();
1626   const double *inp2=other->getConstPointer();
1627   for(int i=0;i<nbOfTuples;i++,inp1+=nbOfComp1,inp2+=nbOfComp2)
1628     {
1629       w=std::copy(inp1,inp1+nbOfComp1,w);
1630       w=std::copy(inp2,inp2+nbOfComp2,w);
1631     }
1632   useArray(newArr,true,C_DEALLOC,nbOfTuples,nbOfComp1+nbOfComp2);
1633   std::vector<int> compIds(nbOfComp2);
1634   for(int i=0;i<nbOfComp2;i++)
1635     compIds[i]=nbOfComp1+i;
1636   copyPartOfStringInfoFrom2(compIds,*other);
1637 }
1638
1639 /*!
1640  * This method checks that all tuples in \a other are in \a this.
1641  * If true, the output param \a tupleIds contains the tuples ids of \a this that correspond to tupes in \a this.
1642  * 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.
1643  *
1644  * \param [in] other - the array having the same number of components than \a this.
1645  * \param [out] tupleIds - the tuple ids containing the same number of tuples than \a other has.
1646  * \sa DataArrayDouble::findCommonTuples
1647  */
1648 bool DataArrayDouble::areIncludedInMe(const DataArrayDouble *other, double prec, DataArrayInt *&tupleIds) const
1649 {
1650   if(!other)
1651     throw INTERP_KERNEL::Exception("DataArrayDouble::areIncludedInMe : input array is NULL !");
1652   checkAllocated(); other->checkAllocated();
1653   if(getNumberOfComponents()!=other->getNumberOfComponents())
1654     throw INTERP_KERNEL::Exception("DataArrayDouble::areIncludedInMe : the number of components does not match !");
1655   MCAuto<DataArrayDouble> a=DataArrayDouble::Aggregate(this,other);
1656   DataArrayInt *c=0,*ci=0;
1657   a->findCommonTuples(prec,getNumberOfTuples(),c,ci);
1658   MCAuto<DataArrayInt> cSafe(c),ciSafe(ci);
1659   int newNbOfTuples=-1;
1660   MCAuto<DataArrayInt> ids=DataArrayInt::ConvertIndexArrayToO2N(a->getNumberOfTuples(),c->begin(),ci->begin(),ci->end(),newNbOfTuples);
1661   MCAuto<DataArrayInt> ret1=ids->selectByTupleIdSafeSlice(getNumberOfTuples(),a->getNumberOfTuples(),1);
1662   tupleIds=ret1.retn();
1663   return newNbOfTuples==getNumberOfTuples();
1664 }
1665
1666 /*!
1667  * Searches for tuples coincident within \a prec tolerance. Each tuple is considered
1668  * as coordinates of a point in getNumberOfComponents()-dimensional space. The
1669  * distance separating two points is computed with the infinite norm.
1670  *
1671  * Indices of coincident tuples are stored in output arrays.
1672  * A pair of arrays (\a comm, \a commIndex) is called "Surjective Format 2".
1673  *
1674  * This method is typically used by MEDCouplingPointSet::findCommonNodes() and
1675  * MEDCouplingUMesh::mergeNodes().
1676  *  \param [in] prec - minimal absolute distance between two tuples (infinite norm) at which they are
1677  *              considered not coincident.
1678  *  \param [in] limitTupleId - limit tuple id. If all tuples within a group of coincident
1679  *              tuples have id strictly lower than \a limitTupleId then they are not returned.
1680  *  \param [out] comm - the array holding ids (== indices) of coincident tuples. 
1681  *               \a comm->getNumberOfComponents() == 1. 
1682  *               \a comm->getNumberOfTuples() == \a commIndex->back().
1683  *  \param [out] commIndex - the array dividing all indices stored in \a comm into
1684  *               groups of (indices of) coincident tuples. Its every value is a tuple
1685  *               index where a next group of tuples begins. For example the second
1686  *               group of tuples in \a comm is described by following range of indices:
1687  *               [ \a commIndex[1], \a commIndex[2] ). \a commIndex->getNumberOfTuples()-1
1688  *               gives the number of groups of coincident tuples.
1689  *  \throw If \a this is not allocated.
1690  *  \throw If the number of components is not in [1,2,3,4].
1691  *
1692  *  \if ENABLE_EXAMPLES
1693  *  \ref cpp_mcdataarraydouble_findcommontuples "Here is a C++ example".
1694  *
1695  *  \ref py_mcdataarraydouble_findcommontuples  "Here is a Python example".
1696  *  \endif
1697  *  \sa DataArrayInt::ConvertIndexArrayToO2N(), DataArrayDouble::areIncludedInMe
1698  */
1699 void DataArrayDouble::findCommonTuples(double prec, int limitTupleId, DataArrayInt *&comm, DataArrayInt *&commIndex) const
1700 {
1701   checkAllocated();
1702   int nbOfCompo=getNumberOfComponents();
1703   if ((nbOfCompo<1) || (nbOfCompo>4)) //test before work
1704     throw INTERP_KERNEL::Exception("DataArrayDouble::findCommonTuples : Unexpected spacedim of coords. Must be 1, 2, 3 or 4.");
1705
1706   int nbOfTuples=getNumberOfTuples();
1707   //
1708   MCAuto<DataArrayInt> c(DataArrayInt::New()),cI(DataArrayInt::New()); c->alloc(0,1); cI->pushBackSilent(0);
1709   switch(nbOfCompo)
1710   {
1711     case 4:
1712       findCommonTuplesAlg<4>(begin(),nbOfTuples,limitTupleId,prec,c,cI);
1713       break;
1714     case 3:
1715       findCommonTuplesAlg<3>(begin(),nbOfTuples,limitTupleId,prec,c,cI);
1716       break;
1717     case 2:
1718       findCommonTuplesAlg<2>(begin(),nbOfTuples,limitTupleId,prec,c,cI);
1719       break;
1720     case 1:
1721       findCommonTuplesAlg<1>(begin(),nbOfTuples,limitTupleId,prec,c,cI);
1722       break;
1723     default:
1724       throw INTERP_KERNEL::Exception("DataArrayDouble::findCommonTuples : nb of components managed are 1,2,3 and 4 ! not implemented for other number of components !");
1725   }
1726   comm=c.retn();
1727   commIndex=cI.retn();
1728 }
1729
1730 /*!
1731  * 
1732  * \param [in] nbTimes specifies the nb of times each tuples in \a this will be duplicated contiguouly in returned DataArrayDouble instance.
1733  *             \a nbTimes  should be at least equal to 1.
1734  * \return a newly allocated DataArrayDouble having one component and number of tuples equal to \a nbTimes * \c this->getNumberOfTuples.
1735  * \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.
1736  */
1737 DataArrayDouble *DataArrayDouble::duplicateEachTupleNTimes(int nbTimes) const
1738 {
1739   checkAllocated();
1740   if(getNumberOfComponents()!=1)
1741     throw INTERP_KERNEL::Exception("DataArrayDouble::duplicateEachTupleNTimes : this should have only one component !");
1742   if(nbTimes<1)
1743     throw INTERP_KERNEL::Exception("DataArrayDouble::duplicateEachTupleNTimes : nb times should be >= 1 !");
1744   int nbTuples=getNumberOfTuples();
1745   const double *inPtr=getConstPointer();
1746   MCAuto<DataArrayDouble> ret=DataArrayDouble::New(); ret->alloc(nbTimes*nbTuples,1);
1747   double *retPtr=ret->getPointer();
1748   for(int i=0;i<nbTuples;i++,inPtr++)
1749     {
1750       double val=*inPtr;
1751       for(int j=0;j<nbTimes;j++,retPtr++)
1752         *retPtr=val;
1753     }
1754   ret->copyStringInfoFrom(*this);
1755   return ret.retn();
1756 }
1757
1758 /*!
1759  * This methods returns the minimal distance between the two set of points \a this and \a other.
1760  * So \a this and \a other have to have the same number of components. If not an INTERP_KERNEL::Exception will be thrown.
1761  * This method works only if number of components of \a this (equal to those of \a other) is in 1, 2 or 3.
1762  *
1763  * \param [out] thisTupleId the tuple id in \a this corresponding to the returned minimal distance
1764  * \param [out] otherTupleId the tuple id in \a other corresponding to the returned minimal distance
1765  * \return the minimal distance between the two set of points \a this and \a other.
1766  * \sa DataArrayDouble::findClosestTupleId
1767  */
1768 double DataArrayDouble::minimalDistanceTo(const DataArrayDouble *other, int& thisTupleId, int& otherTupleId) const
1769 {
1770   MCAuto<DataArrayInt> part1=findClosestTupleId(other);
1771   int nbOfCompo(getNumberOfComponents());
1772   int otherNbTuples(other->getNumberOfTuples());
1773   const double *thisPt(begin()),*otherPt(other->begin());
1774   const int *part1Pt(part1->begin());
1775   double ret=std::numeric_limits<double>::max();
1776   for(int i=0;i<otherNbTuples;i++,part1Pt++,otherPt+=nbOfCompo)
1777     {
1778       double tmp(0.);
1779       for(int j=0;j<nbOfCompo;j++)
1780         tmp+=(otherPt[j]-thisPt[nbOfCompo*(*part1Pt)+j])*(otherPt[j]-thisPt[nbOfCompo*(*part1Pt)+j]);
1781       if(tmp<ret)
1782         { ret=tmp; thisTupleId=*part1Pt; otherTupleId=i; }
1783     }
1784   return sqrt(ret);
1785 }
1786
1787 /*!
1788  * This methods returns for each tuple in \a other which tuple in \a this is the closest.
1789  * So \a this and \a other have to have the same number of components. If not an INTERP_KERNEL::Exception will be thrown.
1790  * This method works only if number of components of \a this (equal to those of \a other) is in 1, 2 or 3.
1791  *
1792  * \return a newly allocated (new object to be dealt by the caller) DataArrayInt having \c other->getNumberOfTuples() tuples and one components.
1793  * \sa DataArrayDouble::minimalDistanceTo
1794  */
1795 DataArrayInt *DataArrayDouble::findClosestTupleId(const DataArrayDouble *other) const
1796 {
1797   if(!other)
1798     throw INTERP_KERNEL::Exception("DataArrayDouble::findClosestTupleId : other instance is NULL !");
1799   checkAllocated(); other->checkAllocated();
1800   int nbOfCompo=getNumberOfComponents();
1801   if(nbOfCompo!=other->getNumberOfComponents())
1802     {
1803       std::ostringstream oss; oss << "DataArrayDouble::findClosestTupleId : number of components in this is " << nbOfCompo;
1804       oss << ", whereas number of components in other is " << other->getNumberOfComponents() << "! Should be equal !";
1805       throw INTERP_KERNEL::Exception(oss.str().c_str());
1806     }
1807   int nbOfTuples=other->getNumberOfTuples();
1808   int thisNbOfTuples=getNumberOfTuples();
1809   MCAuto<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbOfTuples,1);
1810   double bounds[6];
1811   getMinMaxPerComponent(bounds);
1812   switch(nbOfCompo)
1813   {
1814     case 3:
1815       {
1816         double xDelta(fabs(bounds[1]-bounds[0])),yDelta(fabs(bounds[3]-bounds[2])),zDelta(fabs(bounds[5]-bounds[4]));
1817         double delta=std::max(xDelta,yDelta); delta=std::max(delta,zDelta);
1818         double characSize=pow((delta*delta*delta)/((double)thisNbOfTuples),1./3.);
1819         BBTreePts<3,int> myTree(begin(),0,0,getNumberOfTuples(),characSize*1e-12);
1820         FindClosestTupleIdAlg<3>(myTree,3.*characSize*characSize,other->begin(),nbOfTuples,begin(),thisNbOfTuples,ret->getPointer());
1821         break;
1822       }
1823     case 2:
1824       {
1825         double xDelta(fabs(bounds[1]-bounds[0])),yDelta(fabs(bounds[3]-bounds[2]));
1826         double delta=std::max(xDelta,yDelta);
1827         double characSize=sqrt(delta/(double)thisNbOfTuples);
1828         BBTreePts<2,int> myTree(begin(),0,0,getNumberOfTuples(),characSize*1e-12);
1829         FindClosestTupleIdAlg<2>(myTree,2.*characSize*characSize,other->begin(),nbOfTuples,begin(),thisNbOfTuples,ret->getPointer());
1830         break;
1831       }
1832     case 1:
1833       {
1834         double characSize=fabs(bounds[1]-bounds[0])/thisNbOfTuples;
1835         BBTreePts<1,int> myTree(begin(),0,0,getNumberOfTuples(),characSize*1e-12);
1836         FindClosestTupleIdAlg<1>(myTree,1.*characSize*characSize,other->begin(),nbOfTuples,begin(),thisNbOfTuples,ret->getPointer());
1837         break;
1838       }
1839     default:
1840       throw INTERP_KERNEL::Exception("Unexpected spacedim of coords for findClosestTupleId. Must be 1, 2 or 3.");
1841   }
1842   return ret.retn();
1843 }
1844
1845 /*!
1846  * This method expects that \a this and \a otherBBoxFrmt arrays are bounding box arrays ( as the output of MEDCouplingPointSet::getBoundingBoxForBBTree method ).
1847  * This method will return a DataArrayInt array having the same number of tuples than \a this. This returned array tells for each cell in \a this
1848  * how many bounding boxes in \a otherBBoxFrmt.
1849  * So, this method expects that \a this and \a otherBBoxFrmt have the same number of components.
1850  *
1851  * \param [in] otherBBoxFrmt - It is an array .
1852  * \param [in] eps - the absolute precision of the detection. when eps < 0 the bboxes are enlarged so more interactions are detected. Inversely when > 0 the bboxes are stretched.
1853  * \sa MEDCouplingPointSet::getBoundingBoxForBBTree
1854  * \throw If \a this and \a otherBBoxFrmt have not the same number of components.
1855  * \throw If \a this and \a otherBBoxFrmt number of components is not even (BBox format).
1856  */
1857 DataArrayInt *DataArrayDouble::computeNbOfInteractionsWith(const DataArrayDouble *otherBBoxFrmt, double eps) const
1858 {
1859   if(!otherBBoxFrmt)
1860     throw INTERP_KERNEL::Exception("DataArrayDouble::computeNbOfInteractionsWith : input array is NULL !");
1861   if(!isAllocated() || !otherBBoxFrmt->isAllocated())
1862     throw INTERP_KERNEL::Exception("DataArrayDouble::computeNbOfInteractionsWith : this and input array must be allocated !");
1863   int nbOfComp(getNumberOfComponents()),nbOfTuples(getNumberOfTuples());
1864   if(nbOfComp!=otherBBoxFrmt->getNumberOfComponents())
1865     {
1866       std::ostringstream oss; oss << "DataArrayDouble::computeNbOfInteractionsWith : this number of components (" << nbOfComp << ") must be equal to the number of components of input array (" << otherBBoxFrmt->getNumberOfComponents() << ") !";
1867       throw INTERP_KERNEL::Exception(oss.str().c_str());
1868     }
1869   if(nbOfComp%2!=0)
1870     {
1871       std::ostringstream oss; oss << "DataArrayDouble::computeNbOfInteractionsWith : Number of components (" << nbOfComp << ") is not even ! It should be to be compatible with bbox format !";
1872       throw INTERP_KERNEL::Exception(oss.str().c_str());
1873     }
1874   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(nbOfTuples,1);
1875   const double *thisBBPtr(begin());
1876   int *retPtr(ret->getPointer());
1877   switch(nbOfComp/2)
1878   {
1879     case 3:
1880       {
1881         BBTree<3,int> bbt(otherBBoxFrmt->begin(),0,0,otherBBoxFrmt->getNumberOfTuples(),eps);
1882         for(int i=0;i<nbOfTuples;i++,retPtr++,thisBBPtr+=nbOfComp)
1883           *retPtr=bbt.getNbOfIntersectingElems(thisBBPtr);
1884         break;
1885       }
1886     case 2:
1887       {
1888         BBTree<2,int> bbt(otherBBoxFrmt->begin(),0,0,otherBBoxFrmt->getNumberOfTuples(),eps);
1889         for(int i=0;i<nbOfTuples;i++,retPtr++,thisBBPtr+=nbOfComp)
1890           *retPtr=bbt.getNbOfIntersectingElems(thisBBPtr);
1891         break;
1892       }
1893     case 1:
1894       {
1895         BBTree<1,int> bbt(otherBBoxFrmt->begin(),0,0,otherBBoxFrmt->getNumberOfTuples(),eps);
1896         for(int i=0;i<nbOfTuples;i++,retPtr++,thisBBPtr+=nbOfComp)
1897           *retPtr=bbt.getNbOfIntersectingElems(thisBBPtr);
1898         break;
1899       }
1900     default:
1901       throw INTERP_KERNEL::Exception("DataArrayDouble::computeNbOfInteractionsWith : space dimension supported are [1,2,3] !");
1902   }
1903
1904   return ret.retn();
1905 }
1906
1907 /*!
1908  * Returns a copy of \a this array by excluding coincident tuples. Each tuple is
1909  * considered as coordinates of a point in getNumberOfComponents()-dimensional
1910  * space. The distance between tuples is computed using norm2. If several tuples are
1911  * not far each from other than \a prec, only one of them remains in the result
1912  * array. The order of tuples in the result array is same as in \a this one except
1913  * that coincident tuples are excluded.
1914  *  \param [in] prec - minimal absolute distance between two tuples at which they are
1915  *              considered not coincident.
1916  *  \param [in] limitTupleId - limit tuple id. If all tuples within a group of coincident
1917  *              tuples have id strictly lower than \a limitTupleId then they are not excluded.
1918  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1919  *          is to delete using decrRef() as it is no more needed.
1920  *  \throw If \a this is not allocated.
1921  *  \throw If the number of components is not in [1,2,3,4].
1922  *
1923  *  \if ENABLE_EXAMPLES
1924  *  \ref py_mcdataarraydouble_getdifferentvalues "Here is a Python example".
1925  *  \endif
1926  */
1927 DataArrayDouble *DataArrayDouble::getDifferentValues(double prec, int limitTupleId) const
1928 {
1929   checkAllocated();
1930   DataArrayInt *c0=0,*cI0=0;
1931   findCommonTuples(prec,limitTupleId,c0,cI0);
1932   MCAuto<DataArrayInt> c(c0),cI(cI0);
1933   int newNbOfTuples=-1;
1934   MCAuto<DataArrayInt> o2n=DataArrayInt::ConvertIndexArrayToO2N(getNumberOfTuples(),c0->begin(),cI0->begin(),cI0->end(),newNbOfTuples);
1935   return renumberAndReduce(o2n->getConstPointer(),newNbOfTuples);
1936 }
1937
1938 /*!
1939  * Copy all components in a specified order from another DataArrayDouble.
1940  * Both numerical and textual data is copied. The number of tuples in \a this and
1941  * the other array can be different.
1942  *  \param [in] a - the array to copy data from.
1943  *  \param [in] compoIds - sequence of zero based indices of components, data of which is
1944  *              to be copied.
1945  *  \throw If \a a is NULL.
1946  *  \throw If \a compoIds.size() != \a a->getNumberOfComponents().
1947  *  \throw If \a compoIds[i] < 0 or \a compoIds[i] > \a this->getNumberOfComponents().
1948  *
1949  *  \if ENABLE_EXAMPLES
1950  *  \ref py_mcdataarraydouble_setselectedcomponents "Here is a Python example".
1951  *  \endif
1952  */
1953 void DataArrayDouble::setSelectedComponents(const DataArrayDouble *a, const std::vector<int>& compoIds)
1954 {
1955   if(!a)
1956     throw INTERP_KERNEL::Exception("DataArrayDouble::setSelectedComponents : input DataArrayDouble is NULL !");
1957   checkAllocated();
1958   copyPartOfStringInfoFrom2(compoIds,*a);
1959   std::size_t partOfCompoSz=compoIds.size();
1960   int nbOfCompo=getNumberOfComponents();
1961   int nbOfTuples=std::min(getNumberOfTuples(),a->getNumberOfTuples());
1962   const double *ac=a->getConstPointer();
1963   double *nc=getPointer();
1964   for(int i=0;i<nbOfTuples;i++)
1965     for(std::size_t j=0;j<partOfCompoSz;j++,ac++)
1966       nc[nbOfCompo*i+compoIds[j]]=*ac;
1967 }
1968
1969 /*!
1970  * Copy all values from another DataArrayDouble into specified tuples and components
1971  * of \a this array. Textual data is not copied.
1972  * The tree parameters defining set of indices of tuples and components are similar to
1973  * the tree parameters of the Python function \c range(\c start,\c stop,\c step).
1974  *  \param [in] a - the array to copy values from.
1975  *  \param [in] bgTuples - index of the first tuple of \a this array to assign values to.
1976  *  \param [in] endTuples - index of the tuple before which the tuples to assign to
1977  *              are located.
1978  *  \param [in] stepTuples - index increment to get index of the next tuple to assign to.
1979  *  \param [in] bgComp - index of the first component of \a this array to assign values to.
1980  *  \param [in] endComp - index of the component before which the components to assign
1981  *              to are located.
1982  *  \param [in] stepComp - index increment to get index of the next component to assign to.
1983  *  \param [in] strictCompoCompare - if \a true (by default), then \a a->getNumberOfComponents() 
1984  *              must be equal to the number of columns to assign to, else an
1985  *              exception is thrown; if \a false, then it is only required that \a
1986  *              a->getNbOfElems() equals to number of values to assign to (this condition
1987  *              must be respected even if \a strictCompoCompare is \a true). The number of 
1988  *              values to assign to is given by following Python expression:
1989  *              \a nbTargetValues = 
1990  *              \c len(\c range(\a bgTuples,\a endTuples,\a stepTuples)) *
1991  *              \c len(\c range(\a bgComp,\a endComp,\a stepComp)).
1992  *  \throw If \a a is NULL.
1993  *  \throw If \a a is not allocated.
1994  *  \throw If \a this is not allocated.
1995  *  \throw If parameters specifying tuples and components to assign to do not give a
1996  *            non-empty range of increasing indices.
1997  *  \throw If \a a->getNbOfElems() != \a nbTargetValues.
1998  *  \throw If \a strictCompoCompare == \a true && \a a->getNumberOfComponents() !=
1999  *            \c len(\c range(\a bgComp,\a endComp,\a stepComp)).
2000  *
2001  *  \if ENABLE_EXAMPLES
2002  *  \ref py_mcdataarraydouble_setpartofvalues1 "Here is a Python example".
2003  *  \endif
2004  */
2005 void DataArrayDouble::setPartOfValues1(const DataArrayDouble *a, int bgTuples, int endTuples, int stepTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare)
2006 {
2007   if(!a)
2008     throw INTERP_KERNEL::Exception("DataArrayDouble::setPartOfValues1 : input DataArrayDouble is NULL !");
2009   const char msg[]="DataArrayDouble::setPartOfValues1";
2010   checkAllocated();
2011   a->checkAllocated();
2012   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
2013   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
2014   int nbComp=getNumberOfComponents();
2015   int nbOfTuples=getNumberOfTuples();
2016   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
2017   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
2018   bool assignTech=true;
2019   if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
2020     {
2021       if(strictCompoCompare)
2022         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
2023     }
2024   else
2025     {
2026       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
2027       assignTech=false;
2028     }
2029   const double *srcPt=a->getConstPointer();
2030   double *pt=getPointer()+bgTuples*nbComp+bgComp;
2031   if(assignTech)
2032     {
2033       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
2034         for(int j=0;j<newNbOfComp;j++,srcPt++)
2035           pt[j*stepComp]=*srcPt;
2036     }
2037   else
2038     {
2039       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
2040         {
2041           const double *srcPt2=srcPt;
2042           for(int j=0;j<newNbOfComp;j++,srcPt2++)
2043             pt[j*stepComp]=*srcPt2;
2044         }
2045     }
2046 }
2047
2048 /*!
2049  * Assign a given value to values at specified tuples and components of \a this array.
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 value to assign.
2053  *  \param [in] bgTuples - index of the first tuple of \a this array to assign 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 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  *  \throw If \a this is not allocated.
2062  *  \throw If parameters specifying tuples and components to assign to, do not give a
2063  *            non-empty range of increasing indices or indices are out of a valid range
2064  *            for \c this array.
2065  *
2066  *  \if ENABLE_EXAMPLES
2067  *  \ref py_mcdataarraydouble_setpartofvaluessimple1 "Here is a Python example".
2068  *  \endif
2069  */
2070 void DataArrayDouble::setPartOfValuesSimple1(double a, int bgTuples, int endTuples, int stepTuples, int bgComp, int endComp, int stepComp)
2071 {
2072   const char msg[]="DataArrayDouble::setPartOfValuesSimple1";
2073   checkAllocated();
2074   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
2075   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
2076   int nbComp=getNumberOfComponents();
2077   int nbOfTuples=getNumberOfTuples();
2078   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
2079   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
2080   double *pt=getPointer()+bgTuples*nbComp+bgComp;
2081   for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
2082     for(int j=0;j<newNbOfComp;j++)
2083       pt[j*stepComp]=a;
2084 }
2085
2086 /*!
2087  * Copy all values from another DataArrayDouble (\a a) into specified tuples and 
2088  * components of \a this array. Textual data is not copied.
2089  * The tuples and components to assign to are defined by C arrays of indices.
2090  * There are two *modes of usage*:
2091  * - If \a a->getNbOfElems() equals to number of values to assign to, then every value
2092  *   of \a a is assigned to its own location within \a this array. 
2093  * - If \a a includes one tuple, then all values of \a a are assigned to the specified
2094  *   components of every specified tuple of \a this array. In this mode it is required
2095  *   that \a a->getNumberOfComponents() equals to the number of specified components.
2096  *
2097  *  \param [in] a - the array to copy values from.
2098  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
2099  *              assign values of \a a to.
2100  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
2101  *              pointer to a tuple index <em>(pi)</em> varies as this: 
2102  *              \a bgTuples <= \a pi < \a endTuples.
2103  *  \param [in] bgComp - pointer to an array of component indices of \a this array to
2104  *              assign values of \a a to.
2105  *  \param [in] endComp - specifies the end of the array \a bgTuples, so that
2106  *              pointer to a component index <em>(pi)</em> varies as this: 
2107  *              \a bgComp <= \a pi < \a endComp.
2108  *  \param [in] strictCompoCompare - this parameter is checked only if the
2109  *               *mode of usage* is the first; if it is \a true (default), 
2110  *               then \a a->getNumberOfComponents() must be equal 
2111  *               to the number of specified columns, else this is not required.
2112  *  \throw If \a a is NULL.
2113  *  \throw If \a a is not allocated.
2114  *  \throw If \a this is not allocated.
2115  *  \throw If any index of tuple/component given by <em>bgTuples / bgComp</em> is
2116  *         out of a valid range for \a this array.
2117  *  \throw In the first *mode of usage*, if <em>strictCompoCompare == true </em> and
2118  *         if <em> a->getNumberOfComponents() != (endComp - bgComp) </em>.
2119  *  \throw In the second *mode of usage*, if \a a->getNumberOfTuples() != 1 or
2120  *         <em> a->getNumberOfComponents() != (endComp - bgComp)</em>.
2121  *
2122  *  \if ENABLE_EXAMPLES
2123  *  \ref py_mcdataarraydouble_setpartofvalues2 "Here is a Python example".
2124  *  \endif
2125  */
2126 void DataArrayDouble::setPartOfValues2(const DataArrayDouble *a, const int *bgTuples, const int *endTuples, const int *bgComp, const int *endComp, bool strictCompoCompare)
2127 {
2128   if(!a)
2129     throw INTERP_KERNEL::Exception("DataArrayDouble::setPartOfValues2 : input DataArrayDouble is NULL !");
2130   const char msg[]="DataArrayDouble::setPartOfValues2";
2131   checkAllocated();
2132   a->checkAllocated();
2133   int nbComp=getNumberOfComponents();
2134   int nbOfTuples=getNumberOfTuples();
2135   for(const int *z=bgComp;z!=endComp;z++)
2136     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
2137   int newNbOfTuples=(int)std::distance(bgTuples,endTuples);
2138   int newNbOfComp=(int)std::distance(bgComp,endComp);
2139   bool assignTech=true;
2140   if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
2141     {
2142       if(strictCompoCompare)
2143         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
2144     }
2145   else
2146     {
2147       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
2148       assignTech=false;
2149     }
2150   double *pt=getPointer();
2151   const double *srcPt=a->getConstPointer();
2152   if(assignTech)
2153     {    
2154       for(const int *w=bgTuples;w!=endTuples;w++)
2155         {
2156           DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
2157           for(const int *z=bgComp;z!=endComp;z++,srcPt++)
2158             {    
2159               pt[(std::size_t)(*w)*nbComp+(*z)]=*srcPt;
2160             }
2161         }
2162     }
2163   else
2164     {
2165       for(const int *w=bgTuples;w!=endTuples;w++)
2166         {
2167           const double *srcPt2=srcPt;
2168           DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
2169           for(const int *z=bgComp;z!=endComp;z++,srcPt2++)
2170             {    
2171               pt[(std::size_t)(*w)*nbComp+(*z)]=*srcPt2;
2172             }
2173         }
2174     }
2175 }
2176
2177 /*!
2178  * Assign a given value to values at specified tuples and components of \a this array.
2179  * The tuples and components to assign to are defined by C arrays of indices.
2180  *  \param [in] a - the value to assign.
2181  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
2182  *              assign \a a to.
2183  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
2184  *              pointer to a tuple index (\a pi) varies as this: 
2185  *              \a bgTuples <= \a pi < \a endTuples.
2186  *  \param [in] bgComp - pointer to an array of component indices of \a this array to
2187  *              assign \a a to.
2188  *  \param [in] endComp - specifies the end of the array \a bgTuples, so that
2189  *              pointer to a component index (\a pi) varies as this: 
2190  *              \a bgComp <= \a pi < \a endComp.
2191  *  \throw If \a this is not allocated.
2192  *  \throw If any index of tuple/component given by <em>bgTuples / bgComp</em> is
2193  *         out of a valid range for \a this array.
2194  *
2195  *  \if ENABLE_EXAMPLES
2196  *  \ref py_mcdataarraydouble_setpartofvaluessimple2 "Here is a Python example".
2197  *  \endif
2198  */
2199 void DataArrayDouble::setPartOfValuesSimple2(double a, const int *bgTuples, const int *endTuples, const int *bgComp, const int *endComp)
2200 {
2201   checkAllocated();
2202   int nbComp=getNumberOfComponents();
2203   int nbOfTuples=getNumberOfTuples();
2204   for(const int *z=bgComp;z!=endComp;z++)
2205     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
2206   double *pt=getPointer();
2207   for(const int *w=bgTuples;w!=endTuples;w++)
2208     for(const int *z=bgComp;z!=endComp;z++)
2209       {
2210         DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
2211         pt[(std::size_t)(*w)*nbComp+(*z)]=a;
2212       }
2213 }
2214
2215 /*!
2216  * Copy all values from another DataArrayDouble (\a a) into specified tuples and 
2217  * components of \a this array. Textual data is not copied.
2218  * The tuples to assign to are defined by a C array of indices.
2219  * The components to assign to are defined by three values similar to parameters of
2220  * the Python function \c range(\c start,\c stop,\c step).
2221  * There are two *modes of usage*:
2222  * - If \a a->getNbOfElems() equals to number of values to assign to, then every value
2223  *   of \a a is assigned to its own location within \a this array. 
2224  * - If \a a includes one tuple, then all values of \a a are assigned to the specified
2225  *   components of every specified tuple of \a this array. In this mode it is required
2226  *   that \a a->getNumberOfComponents() equals to the number of specified components.
2227  *
2228  *  \param [in] a - the array to copy values from.
2229  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
2230  *              assign values of \a a to.
2231  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
2232  *              pointer to a tuple index <em>(pi)</em> varies as this: 
2233  *              \a bgTuples <= \a pi < \a endTuples.
2234  *  \param [in] bgComp - index of the first component of \a this array to assign to.
2235  *  \param [in] endComp - index of the component before which the components to assign
2236  *              to are located.
2237  *  \param [in] stepComp - index increment to get index of the next component to assign to.
2238  *  \param [in] strictCompoCompare - this parameter is checked only in the first
2239  *               *mode of usage*; if \a strictCompoCompare is \a true (default), 
2240  *               then \a a->getNumberOfComponents() must be equal 
2241  *               to the number of specified columns, else this is not required.
2242  *  \throw If \a a is NULL.
2243  *  \throw If \a a is not allocated.
2244  *  \throw If \a this is not allocated.
2245  *  \throw If any index of tuple given by \a bgTuples is out of a valid range for 
2246  *         \a this array.
2247  *  \throw In the first *mode of usage*, if <em>strictCompoCompare == true </em> and
2248  *         if <em> a->getNumberOfComponents()</em> is unequal to the number of components
2249  *         defined by <em>(bgComp,endComp,stepComp)</em>.
2250  *  \throw In the second *mode of usage*, if \a a->getNumberOfTuples() != 1 or
2251  *         <em> a->getNumberOfComponents()</em> is unequal to the number of components
2252  *         defined by <em>(bgComp,endComp,stepComp)</em>.
2253  *  \throw If parameters specifying components to assign to, do not give a
2254  *            non-empty range of increasing indices or indices are out of a valid range
2255  *            for \c this array.
2256  *
2257  *  \if ENABLE_EXAMPLES
2258  *  \ref py_mcdataarraydouble_setpartofvalues3 "Here is a Python example".
2259  *  \endif
2260  */
2261 void DataArrayDouble::setPartOfValues3(const DataArrayDouble *a, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare)
2262 {
2263   if(!a)
2264     throw INTERP_KERNEL::Exception("DataArrayDouble::setPartOfValues3 : input DataArrayDouble is NULL !");
2265   const char msg[]="DataArrayDouble::setPartOfValues3";
2266   checkAllocated();
2267   a->checkAllocated();
2268   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
2269   int nbComp=getNumberOfComponents();
2270   int nbOfTuples=getNumberOfTuples();
2271   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
2272   int newNbOfTuples=(int)std::distance(bgTuples,endTuples);
2273   bool assignTech=true;
2274   if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
2275     {
2276       if(strictCompoCompare)
2277         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
2278     }
2279   else
2280     {
2281       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
2282       assignTech=false;
2283     }
2284   double *pt=getPointer()+bgComp;
2285   const double *srcPt=a->getConstPointer();
2286   if(assignTech)
2287     {
2288       for(const int *w=bgTuples;w!=endTuples;w++)
2289         for(int j=0;j<newNbOfComp;j++,srcPt++)
2290           {
2291             DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
2292             pt[(std::size_t)(*w)*nbComp+j*stepComp]=*srcPt;
2293           }
2294     }
2295   else
2296     {
2297       for(const int *w=bgTuples;w!=endTuples;w++)
2298         {
2299           const double *srcPt2=srcPt;
2300           for(int j=0;j<newNbOfComp;j++,srcPt2++)
2301             {
2302               DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
2303               pt[(std::size_t)(*w)*nbComp+j*stepComp]=*srcPt2;
2304             }
2305         }
2306     }
2307 }
2308
2309 /*!
2310  * Assign a given value to values at specified tuples and components of \a this array.
2311  * The tuples to assign to are defined by a C array of indices.
2312  * The components to assign to are defined by three values similar to parameters of
2313  * the Python function \c range(\c start,\c stop,\c step).
2314  *  \param [in] a - the value to assign.
2315  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
2316  *              assign \a a to.
2317  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
2318  *              pointer to a tuple index <em>(pi)</em> varies as this: 
2319  *              \a bgTuples <= \a pi < \a endTuples.
2320  *  \param [in] bgComp - index of the first component of \a this array to assign to.
2321  *  \param [in] endComp - index of the component before which the components to assign
2322  *              to are located.
2323  *  \param [in] stepComp - index increment to get index of the next component to assign to.
2324  *  \throw If \a this is not allocated.
2325  *  \throw If any index of tuple given by \a bgTuples is out of a valid range for 
2326  *         \a this array.
2327  *  \throw If parameters specifying components to assign to, do not give a
2328  *            non-empty range of increasing indices or indices are out of a valid range
2329  *            for \c this array.
2330  *
2331  *  \if ENABLE_EXAMPLES
2332  *  \ref py_mcdataarraydouble_setpartofvaluessimple3 "Here is a Python example".
2333  *  \endif
2334  */
2335 void DataArrayDouble::setPartOfValuesSimple3(double a, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp)
2336 {
2337   const char msg[]="DataArrayDouble::setPartOfValuesSimple3";
2338   checkAllocated();
2339   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
2340   int nbComp=getNumberOfComponents();
2341   int nbOfTuples=getNumberOfTuples();
2342   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
2343   double *pt=getPointer()+bgComp;
2344   for(const int *w=bgTuples;w!=endTuples;w++)
2345     for(int j=0;j<newNbOfComp;j++)
2346       {
2347         DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
2348         pt[(std::size_t)(*w)*nbComp+j*stepComp]=a;
2349       }
2350 }
2351
2352 /*!
2353  * Copy all values from another DataArrayDouble into specified tuples and components
2354  * of \a this array. Textual data is not copied.
2355  * The tree parameters defining set of indices of tuples and components are similar to
2356  * the tree parameters of the Python function \c range(\c start,\c stop,\c step).
2357  *  \param [in] a - the array to copy values from.
2358  *  \param [in] bgTuples - index of the first tuple of \a this array to assign values to.
2359  *  \param [in] endTuples - index of the tuple before which the tuples to assign to
2360  *              are located.
2361  *  \param [in] stepTuples - index increment to get index of the next tuple to assign to.
2362  *  \param [in] bgComp - pointer to an array of component indices of \a this array to
2363  *              assign \a a to.
2364  *  \param [in] endComp - specifies the end of the array \a bgTuples, so that
2365  *              pointer to a component index (\a pi) varies as this: 
2366  *              \a bgComp <= \a pi < \a endComp.
2367  *  \param [in] strictCompoCompare - if \a true (by default), then \a a->getNumberOfComponents() 
2368  *              must be equal to the number of columns to assign to, else an
2369  *              exception is thrown; if \a false, then it is only required that \a
2370  *              a->getNbOfElems() equals to number of values to assign to (this condition
2371  *              must be respected even if \a strictCompoCompare is \a true). The number of 
2372  *              values to assign to is given by following Python expression:
2373  *              \a nbTargetValues = 
2374  *              \c len(\c range(\a bgTuples,\a endTuples,\a stepTuples)) *
2375  *              \c len(\c range(\a bgComp,\a endComp,\a stepComp)).
2376  *  \throw If \a a is NULL.
2377  *  \throw If \a a is not allocated.
2378  *  \throw If \a this is not allocated.
2379  *  \throw If parameters specifying tuples and components to assign to do not give a
2380  *            non-empty range of increasing indices.
2381  *  \throw If \a a->getNbOfElems() != \a nbTargetValues.
2382  *  \throw If \a strictCompoCompare == \a true && \a a->getNumberOfComponents() !=
2383  *            \c len(\c range(\a bgComp,\a endComp,\a stepComp)).
2384  *
2385  */
2386 void DataArrayDouble::setPartOfValues4(const DataArrayDouble *a, int bgTuples, int endTuples, int stepTuples, const int *bgComp, const int *endComp, bool strictCompoCompare)
2387 {
2388   if(!a)
2389     throw INTERP_KERNEL::Exception("DataArrayDouble::setPartOfValues4 : input DataArrayDouble is NULL !");
2390   const char msg[]="DataArrayDouble::setPartOfValues4";
2391   checkAllocated();
2392   a->checkAllocated();
2393   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
2394   int newNbOfComp=(int)std::distance(bgComp,endComp);
2395   int nbComp=getNumberOfComponents();
2396   for(const int *z=bgComp;z!=endComp;z++)
2397     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
2398   int nbOfTuples=getNumberOfTuples();
2399   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
2400   bool assignTech=true;
2401   if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
2402     {
2403       if(strictCompoCompare)
2404         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
2405     }
2406   else
2407     {
2408       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
2409       assignTech=false;
2410     }
2411   const double *srcPt=a->getConstPointer();
2412   double *pt=getPointer()+bgTuples*nbComp;
2413   if(assignTech)
2414     {
2415       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
2416         for(const int *z=bgComp;z!=endComp;z++,srcPt++)
2417           pt[*z]=*srcPt;
2418     }
2419   else
2420     {
2421       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
2422         {
2423           const double *srcPt2=srcPt;
2424           for(const int *z=bgComp;z!=endComp;z++,srcPt2++)
2425             pt[*z]=*srcPt2;
2426         }
2427     }
2428 }
2429
2430 void DataArrayDouble::setPartOfValuesSimple4(double a, int bgTuples, int endTuples, int stepTuples, const int *bgComp, const int *endComp)
2431 {
2432   const char msg[]="DataArrayDouble::setPartOfValuesSimple4";
2433   checkAllocated();
2434   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
2435   int nbComp=getNumberOfComponents();
2436   for(const int *z=bgComp;z!=endComp;z++)
2437     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
2438   int nbOfTuples=getNumberOfTuples();
2439   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
2440   double *pt=getPointer()+bgTuples*nbComp;
2441   for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
2442     for(const int *z=bgComp;z!=endComp;z++)
2443       pt[*z]=a;
2444 }
2445
2446 /*!
2447  * Copy some tuples from another DataArrayDouble into specified tuples
2448  * of \a this array. Textual data is not copied. Both arrays must have equal number of
2449  * components.
2450  * Both the tuples to assign and the tuples to assign to are defined by a DataArrayInt.
2451  * All components of selected tuples are copied.
2452  *  \param [in] a - the array to copy values from.
2453  *  \param [in] tuplesSelec - the array specifying both source tuples of \a a and
2454  *              target tuples of \a this. \a tuplesSelec has two components, and the
2455  *              first component specifies index of the source tuple and the second
2456  *              one specifies index of the target tuple.
2457  *  \throw If \a this is not allocated.
2458  *  \throw If \a a is NULL.
2459  *  \throw If \a a is not allocated.
2460  *  \throw If \a tuplesSelec is NULL.
2461  *  \throw If \a tuplesSelec is not allocated.
2462  *  \throw If <em>this->getNumberOfComponents() != a->getNumberOfComponents()</em>.
2463  *  \throw If \a tuplesSelec->getNumberOfComponents() != 2.
2464  *  \throw If any tuple index given by \a tuplesSelec is out of a valid range for 
2465  *         the corresponding (\a this or \a a) array.
2466  */
2467 void DataArrayDouble::setPartOfValuesAdv(const DataArrayDouble *a, const DataArrayInt *tuplesSelec)
2468 {
2469   if(!a || !tuplesSelec)
2470     throw INTERP_KERNEL::Exception("DataArrayDouble::setPartOfValuesAdv : input DataArrayDouble is NULL !");
2471   checkAllocated();
2472   a->checkAllocated();
2473   tuplesSelec->checkAllocated();
2474   int nbOfComp=getNumberOfComponents();
2475   if(nbOfComp!=a->getNumberOfComponents())
2476     throw INTERP_KERNEL::Exception("DataArrayDouble::setPartOfValuesAdv : This and a do not have the same number of components !");
2477   if(tuplesSelec->getNumberOfComponents()!=2)
2478     throw INTERP_KERNEL::Exception("DataArrayDouble::setPartOfValuesAdv : Expecting to have a tuple selector DataArrayInt instance with exactly 2 components !");
2479   int thisNt=getNumberOfTuples();
2480   int aNt=a->getNumberOfTuples();
2481   double *valsToSet=getPointer();
2482   const double *valsSrc=a->getConstPointer();
2483   for(const int *tuple=tuplesSelec->begin();tuple!=tuplesSelec->end();tuple+=2)
2484     {
2485       if(tuple[1]>=0 && tuple[1]<aNt)
2486         {
2487           if(tuple[0]>=0 && tuple[0]<thisNt)
2488             std::copy(valsSrc+nbOfComp*tuple[1],valsSrc+nbOfComp*(tuple[1]+1),valsToSet+nbOfComp*tuple[0]);
2489           else
2490             {
2491               std::ostringstream oss; oss << "DataArrayDouble::setPartOfValuesAdv : Tuple #" << std::distance(tuplesSelec->begin(),tuple)/2;
2492               oss << " of 'tuplesSelec' request of tuple id #" << tuple[0] << " in 'this' ! It should be in [0," << thisNt << ") !";
2493               throw INTERP_KERNEL::Exception(oss.str().c_str());
2494             }
2495         }
2496       else
2497         {
2498           std::ostringstream oss; oss << "DataArrayDouble::setPartOfValuesAdv : Tuple #" << std::distance(tuplesSelec->begin(),tuple)/2;
2499           oss << " of 'tuplesSelec' request of tuple id #" << tuple[1] << " in 'a' ! It should be in [0," << aNt << ") !";
2500           throw INTERP_KERNEL::Exception(oss.str().c_str());
2501         }
2502     }
2503 }
2504
2505 /*!
2506  * Copy some tuples from another DataArrayDouble (\a aBase) into contiguous tuples
2507  * of \a this array. Textual data is not copied. Both arrays must have equal number of
2508  * components.
2509  * The tuples to assign to are defined by index of the first tuple, and
2510  * their number is defined by \a tuplesSelec->getNumberOfTuples().
2511  * The tuples to copy are defined by values of a DataArrayInt.
2512  * All components of selected tuples are copied.
2513  *  \param [in] tupleIdStart - index of the first tuple of \a this array to assign
2514  *              values to.
2515  *  \param [in] aBase - the array to copy values from.
2516  *  \param [in] tuplesSelec - the array specifying tuples of \a a to copy.
2517  *  \throw If \a this is not allocated.
2518  *  \throw If \a aBase is NULL.
2519  *  \throw If \a aBase is not allocated.
2520  *  \throw If \a tuplesSelec is NULL.
2521  *  \throw If \a tuplesSelec is not allocated.
2522  *  \throw If <em>this->getNumberOfComponents() != aBase->getNumberOfComponents()</em>.
2523  *  \throw If \a tuplesSelec->getNumberOfComponents() != 1.
2524  *  \throw If <em>tupleIdStart + tuplesSelec->getNumberOfTuples() > this->getNumberOfTuples().</em>
2525  *  \throw If any tuple index given by \a tuplesSelec is out of a valid range for 
2526  *         \a aBase array.
2527  */
2528 void DataArrayDouble::setContigPartOfSelectedValues(int tupleIdStart, const DataArray *aBase, const DataArrayInt *tuplesSelec)
2529 {
2530   if(!aBase || !tuplesSelec)
2531     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues : input DataArray is NULL !");
2532   const DataArrayDouble *a=dynamic_cast<const DataArrayDouble *>(aBase);
2533   if(!a)
2534     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues : input DataArray aBase is not a DataArrayDouble !");
2535   checkAllocated();
2536   a->checkAllocated();
2537   tuplesSelec->checkAllocated();
2538   int nbOfComp=getNumberOfComponents();
2539   if(nbOfComp!=a->getNumberOfComponents())
2540     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues : This and a do not have the same number of components !");
2541   if(tuplesSelec->getNumberOfComponents()!=1)
2542     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues : Expecting to have a tuple selector DataArrayInt instance with exactly 1 component !");
2543   int thisNt=getNumberOfTuples();
2544   int aNt=a->getNumberOfTuples();
2545   int nbOfTupleToWrite=tuplesSelec->getNumberOfTuples();
2546   double *valsToSet=getPointer()+tupleIdStart*nbOfComp;
2547   if(tupleIdStart+nbOfTupleToWrite>thisNt)
2548     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues : invalid number range of values to write !");
2549   const double *valsSrc=a->getConstPointer();
2550   for(const int *tuple=tuplesSelec->begin();tuple!=tuplesSelec->end();tuple++,valsToSet+=nbOfComp)
2551     {
2552       if(*tuple>=0 && *tuple<aNt)
2553         {
2554           std::copy(valsSrc+nbOfComp*(*tuple),valsSrc+nbOfComp*(*tuple+1),valsToSet);
2555         }
2556       else
2557         {
2558           std::ostringstream oss; oss << "DataArrayDouble::setContigPartOfSelectedValues : Tuple #" << std::distance(tuplesSelec->begin(),tuple);
2559           oss << " of 'tuplesSelec' request of tuple id #" << *tuple << " in 'a' ! It should be in [0," << aNt << ") !";
2560           throw INTERP_KERNEL::Exception(oss.str().c_str());
2561         }
2562     }
2563 }
2564
2565 /*!
2566  * Copy some tuples from another DataArrayDouble (\a aBase) into contiguous tuples
2567  * of \a this array. Textual data is not copied. Both arrays must have equal number of
2568  * components.
2569  * The tuples to copy are defined by three values similar to parameters of
2570  * the Python function \c range(\c start,\c stop,\c step).
2571  * The tuples to assign to are defined by index of the first tuple, and
2572  * their number is defined by number of tuples to copy.
2573  * All components of selected tuples are copied.
2574  *  \param [in] tupleIdStart - index of the first tuple of \a this array to assign
2575  *              values to.
2576  *  \param [in] aBase - the array to copy values from.
2577  *  \param [in] bg - index of the first tuple to copy of the array \a aBase.
2578  *  \param [in] end2 - index of the tuple of \a aBase before which the tuples to copy
2579  *              are located.
2580  *  \param [in] step - index increment to get index of the next tuple to copy.
2581  *  \throw If \a this is not allocated.
2582  *  \throw If \a aBase is NULL.
2583  *  \throw If \a aBase is not allocated.
2584  *  \throw If <em>this->getNumberOfComponents() != aBase->getNumberOfComponents()</em>.
2585  *  \throw If <em>tupleIdStart + len(range(bg,end2,step)) > this->getNumberOfTuples().</em>
2586  *  \throw If parameters specifying tuples to copy, do not give a
2587  *            non-empty range of increasing indices or indices are out of a valid range
2588  *            for the array \a aBase.
2589  */
2590 void DataArrayDouble::setContigPartOfSelectedValuesSlice(int tupleIdStart, const DataArray *aBase, int bg, int end2, int step)
2591 {
2592   if(!aBase)
2593     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValuesSlice : input DataArray is NULL !");
2594   const DataArrayDouble *a=dynamic_cast<const DataArrayDouble *>(aBase);
2595   if(!a)
2596     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValuesSlice : input DataArray aBase is not a DataArrayDouble !");
2597   checkAllocated();
2598   a->checkAllocated();
2599   int nbOfComp=getNumberOfComponents();
2600   const char msg[]="DataArrayDouble::setContigPartOfSelectedValuesSlice";
2601   int nbOfTupleToWrite=DataArray::GetNumberOfItemGivenBES(bg,end2,step,msg);
2602   if(nbOfComp!=a->getNumberOfComponents())
2603     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValuesSlice : This and a do not have the same number of components !");
2604   int thisNt=getNumberOfTuples();
2605   int aNt=a->getNumberOfTuples();
2606   double *valsToSet=getPointer()+tupleIdStart*nbOfComp;
2607   if(tupleIdStart+nbOfTupleToWrite>thisNt)
2608     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValuesSlice : invalid number range of values to write !");
2609   if(end2>aNt)
2610     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValuesSlice : invalid range of values to read !");
2611   const double *valsSrc=a->getConstPointer()+bg*nbOfComp;
2612   for(int i=0;i<nbOfTupleToWrite;i++,valsToSet+=nbOfComp,valsSrc+=step*nbOfComp)
2613     {
2614       std::copy(valsSrc,valsSrc+nbOfComp,valsToSet);
2615     }
2616 }
2617
2618 /*!
2619  * Returns the first value of \a this. 
2620  *  \return double - the last value of \a this array.
2621  *  \throw If \a this is not allocated.
2622  *  \throw If \a this->getNumberOfComponents() != 1.
2623  *  \throw If \a this->getNumberOfTuples() < 1.
2624  */
2625 double DataArrayDouble::front() const
2626 {
2627   checkAllocated();
2628   if(getNumberOfComponents()!=1)
2629     throw INTERP_KERNEL::Exception("DataArrayDouble::front : number of components not equal to one !");
2630   int nbOfTuples=getNumberOfTuples();
2631   if(nbOfTuples<1)
2632     throw INTERP_KERNEL::Exception("DataArrayDouble::front : number of tuples must be >= 1 !");
2633   return *(getConstPointer());
2634 }
2635
2636 /*!
2637  * Returns the last value of \a this. 
2638  *  \return double - the last value of \a this array.
2639  *  \throw If \a this is not allocated.
2640  *  \throw If \a this->getNumberOfComponents() != 1.
2641  *  \throw If \a this->getNumberOfTuples() < 1.
2642  */
2643 double DataArrayDouble::back() const
2644 {
2645   checkAllocated();
2646   if(getNumberOfComponents()!=1)
2647     throw INTERP_KERNEL::Exception("DataArrayDouble::back : number of components not equal to one !");
2648   int nbOfTuples=getNumberOfTuples();
2649   if(nbOfTuples<1)
2650     throw INTERP_KERNEL::Exception("DataArrayDouble::back : number of tuples must be >= 1 !");
2651   return *(getConstPointer()+nbOfTuples-1);
2652 }
2653
2654 void DataArrayDouble::SetArrayIn(DataArrayDouble *newArray, DataArrayDouble* &arrayToSet)
2655 {
2656   if(newArray!=arrayToSet)
2657     {
2658       if(arrayToSet)
2659         arrayToSet->decrRef();
2660       arrayToSet=newArray;
2661       if(arrayToSet)
2662         arrayToSet->incrRef();
2663     }
2664 }
2665
2666 void DataArrayDouble::aggregate(const DataArrayDouble *other)
2667 {
2668   if(!other)
2669     throw INTERP_KERNEL::Exception("DataArrayDouble::aggregate : null pointer !");
2670   if(getNumberOfComponents()!=other->getNumberOfComponents())
2671     throw INTERP_KERNEL::Exception("DataArrayDouble::aggregate : mismatch number of components !");
2672   _mem.insertAtTheEnd(other->begin(),other->end());
2673 }
2674
2675 /*!
2676  * Checks if 0.0 value is present in \a this array. If it is the case, an exception
2677  * is thrown.
2678  * \throw If zero is found in \a this array.
2679  */
2680 void DataArrayDouble::checkNoNullValues() const
2681 {
2682   const double *tmp=getConstPointer();
2683   std::size_t nbOfElems=getNbOfElems();
2684   const double *where=std::find(tmp,tmp+nbOfElems,0.);
2685   if(where!=tmp+nbOfElems)
2686     throw INTERP_KERNEL::Exception("A value 0.0 have been detected !");
2687 }
2688
2689 /*!
2690  * Computes minimal and maximal value in each component. An output array is filled
2691  * with \c 2 * \a this->getNumberOfComponents() values, so the caller is to allocate
2692  * enough memory before calling this method.
2693  *  \param [out] bounds - array of size at least 2 *\a this->getNumberOfComponents().
2694  *               It is filled as follows:<br>
2695  *               \a bounds[0] = \c min_of_component_0 <br>
2696  *               \a bounds[1] = \c max_of_component_0 <br>
2697  *               \a bounds[2] = \c min_of_component_1 <br>
2698  *               \a bounds[3] = \c max_of_component_1 <br>
2699  *               ...
2700  */
2701 void DataArrayDouble::getMinMaxPerComponent(double *bounds) const
2702 {
2703   checkAllocated();
2704   int dim=getNumberOfComponents();
2705   for (int idim=0; idim<dim; idim++)
2706     {
2707       bounds[idim*2]=std::numeric_limits<double>::max();
2708       bounds[idim*2+1]=-std::numeric_limits<double>::max();
2709     } 
2710   const double *ptr=getConstPointer();
2711   int nbOfTuples=getNumberOfTuples();
2712   for(int i=0;i<nbOfTuples;i++)
2713     {
2714       for(int idim=0;idim<dim;idim++)
2715         {
2716           if(bounds[idim*2]>ptr[i*dim+idim])
2717             {
2718               bounds[idim*2]=ptr[i*dim+idim];
2719             }
2720           if(bounds[idim*2+1]<ptr[i*dim+idim])
2721             {
2722               bounds[idim*2+1]=ptr[i*dim+idim];
2723             }
2724         }
2725     }
2726 }
2727
2728 /*!
2729  * This method retrieves a newly allocated DataArrayDouble instance having same number of tuples than \a this and twice number of components than \a this
2730  * to store both the min and max per component of each tuples. 
2731  * \param [in] epsilon the width of the bbox (identical in each direction) - 0.0 by default
2732  *
2733  * \return a newly created DataArrayDouble instance having \c this->getNumberOfTuples() tuples and 2 * \c this->getNumberOfComponent() components
2734  *
2735  * \throw If \a this is not allocated yet.
2736  */
2737 DataArrayDouble *DataArrayDouble::computeBBoxPerTuple(double epsilon) const
2738 {
2739   checkAllocated();
2740   const double *dataPtr=getConstPointer();
2741   int nbOfCompo=getNumberOfComponents();
2742   int nbTuples=getNumberOfTuples();
2743   MCAuto<DataArrayDouble> bbox=DataArrayDouble::New();
2744   bbox->alloc(nbTuples,2*nbOfCompo);
2745   double *bboxPtr=bbox->getPointer();
2746   for(int i=0;i<nbTuples;i++)
2747     {
2748       for(int j=0;j<nbOfCompo;j++)
2749         {
2750           bboxPtr[2*nbOfCompo*i+2*j]=dataPtr[nbOfCompo*i+j]-epsilon;
2751           bboxPtr[2*nbOfCompo*i+2*j+1]=dataPtr[nbOfCompo*i+j]+epsilon;
2752         }
2753     }
2754   return bbox.retn();
2755 }
2756
2757 /*!
2758  * For each tuples **t** in \a other, this method retrieves tuples in \a this that are equal to **t**.
2759  * Two tuples are considered equal if the euclidian distance between the two tuples is lower than \a eps.
2760  * 
2761  * \param [in] other a DataArrayDouble having same number of components than \a this.
2762  * \param [in] eps absolute precision representing distance (using infinite norm) between 2 tuples behind which 2 tuples are considered equal.
2763  * \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.
2764  *             \a cI allows to extract information in \a c.
2765  * \param [out] cI is an indirection array that allows to extract the data contained in \a c.
2766  *
2767  * \throw In case of:
2768  *  - \a this is not allocated
2769  *  - \a other is not allocated or null
2770  *  - \a this and \a other do not have the same number of components
2771  *  - if number of components of \a this is not in [1,2,3]
2772  *
2773  * \sa MEDCouplingPointSet::getNodeIdsNearPoints, DataArrayDouble::getDifferentValues
2774  */
2775 void DataArrayDouble::computeTupleIdsNearTuples(const DataArrayDouble *other, double eps, DataArrayInt *& c, DataArrayInt *& cI) const
2776 {
2777   if(!other)
2778     throw INTERP_KERNEL::Exception("DataArrayDouble::computeTupleIdsNearTuples : input pointer other is null !");
2779   checkAllocated();
2780   other->checkAllocated();
2781   int nbOfCompo=getNumberOfComponents();
2782   int otherNbOfCompo=other->getNumberOfComponents();
2783   if(nbOfCompo!=otherNbOfCompo)
2784     throw INTERP_KERNEL::Exception("DataArrayDouble::computeTupleIdsNearTuples : number of components should be equal between this and other !");
2785   int nbOfTuplesOther=other->getNumberOfTuples();
2786   MCAuto<DataArrayInt> cArr(DataArrayInt::New()),cIArr(DataArrayInt::New()); cArr->alloc(0,1); cIArr->pushBackSilent(0);
2787   switch(nbOfCompo)
2788   {
2789     case 3:
2790       {
2791         BBTreePts<3,int> myTree(begin(),0,0,getNumberOfTuples(),eps);
2792         FindTupleIdsNearTuplesAlg<3>(myTree,other->getConstPointer(),nbOfTuplesOther,eps,cArr,cIArr);
2793         break;
2794       }
2795     case 2:
2796       {
2797         BBTreePts<2,int> myTree(begin(),0,0,getNumberOfTuples(),eps);
2798         FindTupleIdsNearTuplesAlg<2>(myTree,other->getConstPointer(),nbOfTuplesOther,eps,cArr,cIArr);
2799         break;
2800       }
2801     case 1:
2802       {
2803         BBTreePts<1,int> myTree(begin(),0,0,getNumberOfTuples(),eps);
2804         FindTupleIdsNearTuplesAlg<1>(myTree,other->getConstPointer(),nbOfTuplesOther,eps,cArr,cIArr);
2805         break;
2806       }
2807     default:
2808       throw INTERP_KERNEL::Exception("Unexpected spacedim of coords for computeTupleIdsNearTuples. Must be 1, 2 or 3.");
2809   }
2810   c=cArr.retn(); cI=cIArr.retn();
2811 }
2812
2813 /*!
2814  * 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
2815  * around origin of 'radius' 1.
2816  * 
2817  * \param [in] eps absolute epsilon. under that value of delta between max and min no scale is performed.
2818  */
2819 void DataArrayDouble::recenterForMaxPrecision(double eps)
2820 {
2821   checkAllocated();
2822   int dim=getNumberOfComponents();
2823   std::vector<double> bounds(2*dim);
2824   getMinMaxPerComponent(&bounds[0]);
2825   for(int i=0;i<dim;i++)
2826     {
2827       double delta=bounds[2*i+1]-bounds[2*i];
2828       double offset=(bounds[2*i]+bounds[2*i+1])/2.;
2829       if(delta>eps)
2830         applyLin(1./delta,-offset/delta,i);
2831       else
2832         applyLin(1.,-offset,i);
2833     }
2834 }
2835
2836 /*!
2837  * Returns the maximal value and its location within \a this one-dimensional array.
2838  *  \param [out] tupleId - index of the tuple holding the maximal value.
2839  *  \return double - the maximal value among all values of \a this array.
2840  *  \throw If \a this->getNumberOfComponents() != 1
2841  *  \throw If \a this->getNumberOfTuples() < 1
2842  */
2843 double DataArrayDouble::getMaxValue(int& tupleId) const
2844 {
2845   checkAllocated();
2846   if(getNumberOfComponents()!=1)
2847     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 !");
2848   int nbOfTuples=getNumberOfTuples();
2849   if(nbOfTuples<=0)
2850     throw INTERP_KERNEL::Exception("DataArrayDouble::getMaxValue : array exists but number of tuples must be > 0 !");
2851   const double *vals=getConstPointer();
2852   const double *loc=std::max_element(vals,vals+nbOfTuples);
2853   tupleId=(int)std::distance(vals,loc);
2854   return *loc;
2855 }
2856
2857 /*!
2858  * Returns the maximal value within \a this array that is allowed to have more than
2859  *  one component.
2860  *  \return double - the maximal value among all values of \a this array.
2861  *  \throw If \a this is not allocated.
2862  */
2863 double DataArrayDouble::getMaxValueInArray() const
2864 {
2865   checkAllocated();
2866   const double *loc=std::max_element(begin(),end());
2867   return *loc;
2868 }
2869
2870 /*!
2871  * Returns the maximal value and all its locations within \a this one-dimensional array.
2872  *  \param [out] tupleIds - a new instance of DataArrayInt containg indices of
2873  *               tuples holding the maximal value. The caller is to delete it using
2874  *               decrRef() as it is no more needed.
2875  *  \return double - the maximal value among all values of \a this array.
2876  *  \throw If \a this->getNumberOfComponents() != 1
2877  *  \throw If \a this->getNumberOfTuples() < 1
2878  */
2879 double DataArrayDouble::getMaxValue2(DataArrayInt*& tupleIds) const
2880 {
2881   int tmp;
2882   tupleIds=0;
2883   double ret=getMaxValue(tmp);
2884   tupleIds=findIdsInRange(ret,ret);
2885   return ret;
2886 }
2887
2888 /*!
2889  * Returns the minimal value and its location within \a this one-dimensional array.
2890  *  \param [out] tupleId - index of the tuple holding the minimal value.
2891  *  \return double - the minimal value among all values of \a this array.
2892  *  \throw If \a this->getNumberOfComponents() != 1
2893  *  \throw If \a this->getNumberOfTuples() < 1
2894  */
2895 double DataArrayDouble::getMinValue(int& tupleId) const
2896 {
2897   checkAllocated();
2898   if(getNumberOfComponents()!=1)
2899     throw INTERP_KERNEL::Exception("DataArrayDouble::getMinValue : must be applied on DataArrayDouble with only one component, you can call 'rearrange' method before call 'getMinValueInArray' method !");
2900   int nbOfTuples=getNumberOfTuples();
2901   if(nbOfTuples<=0)
2902     throw INTERP_KERNEL::Exception("DataArrayDouble::getMinValue : array exists but number of tuples must be > 0 !");
2903   const double *vals=getConstPointer();
2904   const double *loc=std::min_element(vals,vals+nbOfTuples);
2905   tupleId=(int)std::distance(vals,loc);
2906   return *loc;
2907 }
2908
2909 /*!
2910  * Returns the minimal value within \a this array that is allowed to have more than
2911  *  one component.
2912  *  \return double - the minimal value among all values of \a this array.
2913  *  \throw If \a this is not allocated.
2914  */
2915 double DataArrayDouble::getMinValueInArray() const
2916 {
2917   checkAllocated();
2918   const double *loc=std::min_element(begin(),end());
2919   return *loc;
2920 }
2921
2922 /*!
2923  * Returns the minimal value and all its locations within \a this one-dimensional array.
2924  *  \param [out] tupleIds - a new instance of DataArrayInt containg indices of
2925  *               tuples holding the minimal value. The caller is to delete it using
2926  *               decrRef() as it is no more needed.
2927  *  \return double - the minimal value among all values of \a this array.
2928  *  \throw If \a this->getNumberOfComponents() != 1
2929  *  \throw If \a this->getNumberOfTuples() < 1
2930  */
2931 double DataArrayDouble::getMinValue2(DataArrayInt*& tupleIds) const
2932 {
2933   int tmp;
2934   tupleIds=0;
2935   double ret=getMinValue(tmp);
2936   tupleIds=findIdsInRange(ret,ret);
2937   return ret;
2938 }
2939
2940 /*!
2941  * 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.
2942  * This method only works for single component array.
2943  *
2944  * \return a value in [ 0, \c this->getNumberOfTuples() )
2945  *
2946  * \throw If \a this is not allocated
2947  *
2948  */
2949 int DataArrayDouble::count(double value, double eps) const
2950 {
2951   int ret=0;
2952   checkAllocated();
2953   if(getNumberOfComponents()!=1)
2954     throw INTERP_KERNEL::Exception("DataArrayDouble::count : must be applied on DataArrayDouble with only one component, you can call 'rearrange' method before !");
2955   const double *vals=begin();
2956   int nbOfTuples=getNumberOfTuples();
2957   for(int i=0;i<nbOfTuples;i++,vals++)
2958     if(fabs(*vals-value)<=eps)
2959       ret++;
2960   return ret;
2961 }
2962
2963 /*!
2964  * Returns the average value of \a this one-dimensional array.
2965  *  \return double - the average value over all values of \a this array.
2966  *  \throw If \a this->getNumberOfComponents() != 1
2967  *  \throw If \a this->getNumberOfTuples() < 1
2968  */
2969 double DataArrayDouble::getAverageValue() const
2970 {
2971   if(getNumberOfComponents()!=1)
2972     throw INTERP_KERNEL::Exception("DataArrayDouble::getAverageValue : must be applied on DataArrayDouble with only one component, you can call 'rearrange' method before !");
2973   int nbOfTuples=getNumberOfTuples();
2974   if(nbOfTuples<=0)
2975     throw INTERP_KERNEL::Exception("DataArrayDouble::getAverageValue : array exists but number of tuples must be > 0 !");
2976   const double *vals=getConstPointer();
2977   double ret=std::accumulate(vals,vals+nbOfTuples,0.);
2978   return ret/nbOfTuples;
2979 }
2980
2981 /*!
2982  * Returns the Euclidean norm of the vector defined by \a this array.
2983  *  \return double - the value of the Euclidean norm, i.e.
2984  *          the square root of the inner product of vector.
2985  *  \throw If \a this is not allocated.
2986  */
2987 double DataArrayDouble::norm2() const
2988 {
2989   checkAllocated();
2990   double ret=0.;
2991   std::size_t nbOfElems=getNbOfElems();
2992   const double *pt=getConstPointer();
2993   for(std::size_t i=0;i<nbOfElems;i++,pt++)
2994     ret+=(*pt)*(*pt);
2995   return sqrt(ret);
2996 }
2997
2998 /*!
2999  * Returns the maximum norm of the vector defined by \a this array.
3000  * This method works even if the number of components is diferent from one.
3001  * If the number of elements in \a this is 0, -1. is returned.
3002  *  \return double - the value of the maximum norm, i.e.
3003  *          the maximal absolute value among values of \a this array (whatever its number of components).
3004  *  \throw If \a this is not allocated.
3005  */
3006 double DataArrayDouble::normMax() const
3007 {
3008   checkAllocated();
3009   double ret(-1.);
3010   std::size_t nbOfElems(getNbOfElems());
3011   const double *pt(getConstPointer());
3012   for(std::size_t i=0;i<nbOfElems;i++,pt++)
3013     {
3014       double val(std::abs(*pt));
3015       if(val>ret)
3016         ret=val;
3017     }
3018   return ret;
3019 }
3020
3021 /*!
3022  * Returns the minimum norm (absolute value) of the vector defined by \a this array.
3023  * This method works even if the number of components is diferent from one.
3024  * If the number of elements in \a this is 0, std::numeric_limits<double>::max() is returned.
3025  *  \return double - the value of the minimum norm, i.e.
3026  *          the minimal absolute value among values of \a this array (whatever its number of components).
3027  *  \throw If \a this is not allocated.
3028  */
3029 double DataArrayDouble::normMin() const
3030 {
3031   checkAllocated();
3032   double ret(std::numeric_limits<double>::max());
3033   std::size_t nbOfElems(getNbOfElems());
3034   const double *pt(getConstPointer());
3035   for(std::size_t i=0;i<nbOfElems;i++,pt++)
3036     {
3037       double val(std::abs(*pt));
3038       if(val<ret)
3039         ret=val;
3040     }
3041   return ret;
3042 }
3043
3044 /*!
3045  * Accumulates values of each component of \a this array.
3046  *  \param [out] res - an array of length \a this->getNumberOfComponents(), allocated 
3047  *         by the caller, that is filled by this method with sum value for each
3048  *         component.
3049  *  \throw If \a this is not allocated.
3050  */
3051 void DataArrayDouble::accumulate(double *res) const
3052 {
3053   checkAllocated();
3054   const double *ptr=getConstPointer();
3055   int nbTuple=getNumberOfTuples();
3056   int nbComps=getNumberOfComponents();
3057   std::fill(res,res+nbComps,0.);
3058   for(int i=0;i<nbTuple;i++)
3059     std::transform(ptr+i*nbComps,ptr+(i+1)*nbComps,res,res,std::plus<double>());
3060 }
3061
3062 /*!
3063  * This method returns the min distance from an external tuple defined by [ \a tupleBg , \a tupleEnd ) to \a this and
3064  * the first tuple in \a this that matches the returned distance. If there is no tuples in \a this an exception will be thrown.
3065  *
3066  *
3067  * \a this is expected to be allocated and expected to have a number of components equal to the distance from \a tupleBg to
3068  * \a tupleEnd. If not an exception will be thrown.
3069  *
3070  * \param [in] tupleBg start pointer (included) of input external tuple
3071  * \param [in] tupleEnd end pointer (not included) of input external tuple
3072  * \param [out] tupleId the tuple id in \a this that matches the min of distance between \a this and input external tuple
3073  * \return the min distance.
3074  * \sa MEDCouplingUMesh::distanceToPoint
3075  */
3076 double DataArrayDouble::distanceToTuple(const double *tupleBg, const double *tupleEnd, int& tupleId) const
3077 {
3078   checkAllocated();
3079   int nbTuple=getNumberOfTuples();
3080   int nbComps=getNumberOfComponents();
3081   if(nbComps!=(int)std::distance(tupleBg,tupleEnd))
3082     { 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()); }
3083   if(nbTuple==0)
3084     throw INTERP_KERNEL::Exception("DataArrayDouble::distanceToTuple : no tuple in this ! No distance to compute !");
3085   double ret0=std::numeric_limits<double>::max();
3086   tupleId=-1;
3087   const double *work=getConstPointer();
3088   for(int i=0;i<nbTuple;i++)
3089     {
3090       double val=0.;
3091       for(int j=0;j<nbComps;j++,work++) 
3092         val+=(*work-tupleBg[j])*((*work-tupleBg[j]));
3093       if(val>=ret0)
3094         continue;
3095       else
3096         { ret0=val; tupleId=i; }
3097     }
3098   return sqrt(ret0);
3099 }
3100
3101 /*!
3102  * Accumulate values of the given component of \a this array.
3103  *  \param [in] compId - the index of the component of interest.
3104  *  \return double - a sum value of \a compId-th component.
3105  *  \throw If \a this is not allocated.
3106  *  \throw If \a the condition ( 0 <= \a compId < \a this->getNumberOfComponents() ) is
3107  *         not respected.
3108  */
3109 double DataArrayDouble::accumulate(int compId) const
3110 {
3111   checkAllocated();
3112   const double *ptr=getConstPointer();
3113   int nbTuple=getNumberOfTuples();
3114   int nbComps=getNumberOfComponents();
3115   if(compId<0 || compId>=nbComps)
3116     throw INTERP_KERNEL::Exception("DataArrayDouble::accumulate : Invalid compId specified : No such nb of components !");
3117   double ret=0.;
3118   for(int i=0;i<nbTuple;i++)
3119     ret+=ptr[i*nbComps+compId];
3120   return ret;
3121 }
3122
3123 /*!
3124  * This method accumulate using addition tuples in \a this using input index array [ \a bgOfIndex, \a endOfIndex ).
3125  * The returned array will have same number of components than \a this and number of tuples equal to
3126  * \c std::distance(bgOfIndex,endOfIndex) \b minus \b one.
3127  *
3128  * The input index array is expected to be ascendingly sorted in which the all referenced ids should be in [0, \c this->getNumberOfTuples).
3129  * 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.
3130  *
3131  * \param [in] bgOfIndex - begin (included) of the input index array.
3132  * \param [in] endOfIndex - end (excluded) of the input index array.
3133  * \return DataArrayDouble * - the new instance having the same number of components than \a this.
3134  * 
3135  * \throw If bgOfIndex or end is NULL.
3136  * \throw If input index array is not ascendingly sorted.
3137  * \throw If there is an id in [ \a bgOfIndex, \a endOfIndex ) not in [0, \c this->getNumberOfTuples).
3138  * \throw If std::distance(bgOfIndex,endOfIndex)==0.
3139  */
3140 DataArrayDouble *DataArrayDouble::accumulatePerChunck(const int *bgOfIndex, const int *endOfIndex) const
3141 {
3142   if(!bgOfIndex || !endOfIndex)
3143     throw INTERP_KERNEL::Exception("DataArrayDouble::accumulatePerChunck : input pointer NULL !");
3144   checkAllocated();
3145   int nbCompo=getNumberOfComponents();
3146   int nbOfTuples=getNumberOfTuples();
3147   int sz=(int)std::distance(bgOfIndex,endOfIndex);
3148   if(sz<1)
3149     throw INTERP_KERNEL::Exception("DataArrayDouble::accumulatePerChunck : invalid size of input index array !");
3150   sz--;
3151   MCAuto<DataArrayDouble> ret=DataArrayDouble::New(); ret->alloc(sz,nbCompo);
3152   const int *w=bgOfIndex;
3153   if(*w<0 || *w>=nbOfTuples)
3154     throw INTERP_KERNEL::Exception("DataArrayDouble::accumulatePerChunck : The first element of the input index not in [0,nbOfTuples) !");
3155   const double *srcPt=begin()+(*w)*nbCompo;
3156   double *tmp=ret->getPointer();
3157   for(int i=0;i<sz;i++,tmp+=nbCompo,w++)
3158     {
3159       std::fill(tmp,tmp+nbCompo,0.);
3160       if(w[1]>=w[0])
3161         {
3162           for(int j=w[0];j<w[1];j++,srcPt+=nbCompo)
3163             {
3164               if(j>=0 && j<nbOfTuples)
3165                 std::transform(srcPt,srcPt+nbCompo,tmp,tmp,std::plus<double>());
3166               else
3167                 {
3168                   std::ostringstream oss; oss << "DataArrayDouble::accumulatePerChunck : At rank #" << i << " the input index array points to id " << j << " should be in [0," << nbOfTuples << ") !";
3169                   throw INTERP_KERNEL::Exception(oss.str().c_str());
3170                 }
3171             }
3172         }
3173       else
3174         {
3175           std::ostringstream oss; oss << "DataArrayDouble::accumulatePerChunck : At rank #" << i << " the input index array is not in ascendingly sorted.";
3176           throw INTERP_KERNEL::Exception(oss.str().c_str());
3177         }
3178     }
3179   ret->copyStringInfoFrom(*this);
3180   return ret.retn();
3181 }
3182
3183 /*!
3184  * Converts each 2D point defined by the tuple of \a this array from the Polar to the
3185  * Cartesian coordinate system. The two components of the tuple of \a this array are 
3186  * considered to contain (1) radius and (2) angle of the point in the Polar CS.
3187  *  \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
3188  *          contains X and Y coordinates of the point in the Cartesian CS. The caller
3189  *          is to delete this array using decrRef() as it is no more needed. The array
3190  *          does not contain any textual info on components.
3191  *  \throw If \a this->getNumberOfComponents() != 2.
3192  */
3193 DataArrayDouble *DataArrayDouble::fromPolarToCart() const
3194 {
3195   checkAllocated();
3196   int nbOfComp(getNumberOfComponents());
3197   if(nbOfComp!=2)
3198     throw INTERP_KERNEL::Exception("DataArrayDouble::fromPolarToCart : must be an array with exactly 2 components !");
3199   int nbOfTuple(getNumberOfTuples());
3200   DataArrayDouble *ret(DataArrayDouble::New());
3201   ret->alloc(nbOfTuple,2);
3202   double *w(ret->getPointer());
3203   const double *wIn(getConstPointer());
3204   for(int i=0;i<nbOfTuple;i++,w+=2,wIn+=2)
3205     {
3206       w[0]=wIn[0]*cos(wIn[1]);
3207       w[1]=wIn[0]*sin(wIn[1]);
3208     }
3209   return ret;
3210 }
3211
3212 /*!
3213  * Converts each 3D point defined by the tuple of \a this array from the Cylindrical to
3214  * the Cartesian coordinate system. The three components of the tuple of \a this array 
3215  * are considered to contain (1) radius, (2) azimuth and (3) altitude of the point in
3216  * the Cylindrical CS.
3217  *  \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
3218  *          contains X, Y and Z coordinates of the point in the Cartesian CS. The info
3219  *          on the third component is copied from \a this array. The caller
3220  *          is to delete this array using decrRef() as it is no more needed. 
3221  *  \throw If \a this->getNumberOfComponents() != 3.
3222  */
3223 DataArrayDouble *DataArrayDouble::fromCylToCart() const
3224 {
3225   checkAllocated();
3226   int nbOfComp(getNumberOfComponents());
3227   if(nbOfComp!=3)
3228     throw INTERP_KERNEL::Exception("DataArrayDouble::fromCylToCart : must be an array with exactly 3 components !");
3229   int nbOfTuple(getNumberOfTuples());
3230   DataArrayDouble *ret(DataArrayDouble::New());
3231   ret->alloc(getNumberOfTuples(),3);
3232   double *w(ret->getPointer());
3233   const double *wIn(getConstPointer());
3234   for(int i=0;i<nbOfTuple;i++,w+=3,wIn+=3)
3235     {
3236       w[0]=wIn[0]*cos(wIn[1]);
3237       w[1]=wIn[0]*sin(wIn[1]);
3238       w[2]=wIn[2];
3239     }
3240   ret->setInfoOnComponent(2,getInfoOnComponent(2));
3241   return ret;
3242 }
3243
3244 /*!
3245  * Converts each 3D point defined by the tuple of \a this array from the Spherical to
3246  * the Cartesian coordinate system. The three components of the tuple of \a this array 
3247  * are considered to contain (1) radius, (2) polar angle and (3) azimuthal angle of the
3248  * point in the Cylindrical CS.
3249  *  \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
3250  *          contains X, Y and Z coordinates of the point in the Cartesian CS. The info
3251  *          on the third component is copied from \a this array. The caller
3252  *          is to delete this array using decrRef() as it is no more needed.
3253  *  \throw If \a this->getNumberOfComponents() != 3.
3254  */
3255 DataArrayDouble *DataArrayDouble::fromSpherToCart() const
3256 {
3257   checkAllocated();
3258   int nbOfComp(getNumberOfComponents());
3259   if(nbOfComp!=3)
3260     throw INTERP_KERNEL::Exception("DataArrayDouble::fromSpherToCart : must be an array with exactly 3 components !");
3261   int nbOfTuple(getNumberOfTuples());
3262   DataArrayDouble *ret(DataArrayDouble::New());
3263   ret->alloc(getNumberOfTuples(),3);
3264   double *w(ret->getPointer());
3265   const double *wIn(getConstPointer());
3266   for(int i=0;i<nbOfTuple;i++,w+=3,wIn+=3)
3267     {
3268       w[0]=wIn[0]*cos(wIn[2])*sin(wIn[1]);
3269       w[1]=wIn[0]*sin(wIn[2])*sin(wIn[1]);
3270       w[2]=wIn[0]*cos(wIn[1]);
3271     }
3272   return ret;
3273 }
3274
3275 /*!
3276  * This method returns a new array containing the same number of tuples than \a this. To do this, this method needs \a at parameter to specify the convention of \a this.
3277  * All the tuples of the returned array will be in cartesian sense. So if \a at equals to AX_CART the returned array is basically a deep copy of \a this.
3278  * If \a at equals to AX_CYL the returned array will be the result of operation cylindric to cartesian of \a this...
3279  *
3280  * \param [in] atOfThis - The axis type of \a this.
3281  * \return DataArrayDouble * - the new instance of DataArrayDouble (that must be dealed by caller) containing the result of the cartesianizification of \a this.
3282  */
3283 DataArrayDouble *DataArrayDouble::cartesianize(MEDCouplingAxisType atOfThis) const
3284 {
3285   checkAllocated();
3286   int nbOfComp(getNumberOfComponents());
3287   MCAuto<DataArrayDouble> ret;
3288   switch(atOfThis)
3289     {
3290     case AX_CART:
3291       ret=deepCopy();
3292     case AX_CYL:
3293       if(nbOfComp==3)
3294         {
3295           ret=fromCylToCart();
3296           break;
3297         }
3298       if(nbOfComp==2)
3299         {
3300           ret=fromPolarToCart();
3301           break;
3302         }
3303       else
3304         throw INTERP_KERNEL::Exception("DataArrayDouble::cartesianize : For AX_CYL, number of components must be in [2,3] !");
3305     case AX_SPHER:
3306       if(nbOfComp==3)
3307         {
3308           ret=fromSpherToCart();
3309           break;
3310         }
3311       if(nbOfComp==2)
3312         {
3313           ret=fromPolarToCart();
3314           break;
3315         }
3316       else
3317         throw INTERP_KERNEL::Exception("DataArrayDouble::cartesianize : For AX_CYL, number of components must be in [2,3] !");
3318     default:
3319       throw INTERP_KERNEL::Exception("DataArrayDouble::cartesianize : not recognized axis type ! Only AX_CART, AX_CYL and AX_SPHER supported !");
3320     }
3321   ret->copyStringInfoFrom(*this);
3322   return ret.retn();
3323 }
3324
3325 /*!
3326  * Computes the doubly contracted product of every tensor defined by the tuple of \a this
3327  * array contating 6 components.
3328  *  \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
3329  *          is calculated from the tuple <em>(t)</em> of \a this array as follows:
3330  *          \f$ t[0]^2+t[1]^2+t[2]^2+2*t[3]^2+2*t[4]^2+2*t[5]^2\f$.
3331  *         The caller is to delete this result array using decrRef() as it is no more needed. 
3332  *  \throw If \a this->getNumberOfComponents() != 6.
3333  */
3334 DataArrayDouble *DataArrayDouble::doublyContractedProduct() const
3335 {
3336   checkAllocated();
3337   int nbOfComp(getNumberOfComponents());
3338   if(nbOfComp!=6)
3339     throw INTERP_KERNEL::Exception("DataArrayDouble::doublyContractedProduct : must be an array with exactly 6 components !");
3340   DataArrayDouble *ret=DataArrayDouble::New();
3341   int nbOfTuple=getNumberOfTuples();
3342   ret->alloc(nbOfTuple,1);
3343   const double *src=getConstPointer();
3344   double *dest=ret->getPointer();
3345   for(int i=0;i<nbOfTuple;i++,dest++,src+=6)
3346     *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];
3347   return ret;
3348 }
3349
3350 /*!
3351  * Computes the determinant of every square matrix defined by the tuple of \a this
3352  * array, which contains either 4, 6 or 9 components. The case of 6 components
3353  * corresponds to that of the upper triangular matrix.
3354  *  \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
3355  *          is the determinant of matrix of the corresponding tuple of \a this array.
3356  *          The caller is to delete this result array using decrRef() as it is no more
3357  *          needed. 
3358  *  \throw If \a this->getNumberOfComponents() is not in [4,6,9].
3359  */
3360 DataArrayDouble *DataArrayDouble::determinant() const
3361 {
3362   checkAllocated();
3363   DataArrayDouble *ret=DataArrayDouble::New();
3364   int nbOfTuple=getNumberOfTuples();
3365   ret->alloc(nbOfTuple,1);
3366   const double *src=getConstPointer();
3367   double *dest=ret->getPointer();
3368   switch(getNumberOfComponents())
3369   {
3370     case 6:
3371       for(int i=0;i<nbOfTuple;i++,dest++,src+=6)
3372         *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];
3373       return ret;
3374     case 4:
3375       for(int i=0;i<nbOfTuple;i++,dest++,src+=4)
3376         *dest=src[0]*src[3]-src[1]*src[2];
3377       return ret;
3378     case 9:
3379       for(int i=0;i<nbOfTuple;i++,dest++,src+=9)
3380         *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];
3381       return ret;
3382     default:
3383       ret->decrRef();
3384       throw INTERP_KERNEL::Exception("DataArrayDouble::determinant : Invalid number of components ! must be in 4,6,9 !");
3385   }
3386 }
3387
3388 /*!
3389  * Computes 3 eigenvalues of every upper triangular matrix defined by the tuple of
3390  * \a this array, which contains 6 components.
3391  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing 3
3392  *          components, whose each tuple contains the eigenvalues of the matrix of
3393  *          corresponding tuple of \a this array. 
3394  *          The caller is to delete this result array using decrRef() as it is no more
3395  *          needed. 
3396  *  \throw If \a this->getNumberOfComponents() != 6.
3397  */
3398 DataArrayDouble *DataArrayDouble::eigenValues() const
3399 {
3400   checkAllocated();
3401   int nbOfComp=getNumberOfComponents();
3402   if(nbOfComp!=6)
3403     throw INTERP_KERNEL::Exception("DataArrayDouble::eigenValues : must be an array with exactly 6 components !");
3404   DataArrayDouble *ret=DataArrayDouble::New();
3405   int nbOfTuple=getNumberOfTuples();
3406   ret->alloc(nbOfTuple,3);
3407   const double *src=getConstPointer();
3408   double *dest=ret->getPointer();
3409   for(int i=0;i<nbOfTuple;i++,dest+=3,src+=6)
3410     INTERP_KERNEL::computeEigenValues6(src,dest);
3411   return ret;
3412 }
3413
3414 /*!
3415  * Computes 3 eigenvectors of every upper triangular matrix defined by the tuple of
3416  * \a this array, which contains 6 components.
3417  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing 9
3418  *          components, whose each tuple contains 3 eigenvectors of the matrix of
3419  *          corresponding tuple of \a this array.
3420  *          The caller is to delete this result array using decrRef() as it is no more
3421  *          needed.
3422  *  \throw If \a this->getNumberOfComponents() != 6.
3423  */
3424 DataArrayDouble *DataArrayDouble::eigenVectors() const
3425 {
3426   checkAllocated();
3427   int nbOfComp=getNumberOfComponents();
3428   if(nbOfComp!=6)
3429     throw INTERP_KERNEL::Exception("DataArrayDouble::eigenVectors : must be an array with exactly 6 components !");
3430   DataArrayDouble *ret=DataArrayDouble::New();
3431   int nbOfTuple=getNumberOfTuples();
3432   ret->alloc(nbOfTuple,9);
3433   const double *src=getConstPointer();
3434   double *dest=ret->getPointer();
3435   for(int i=0;i<nbOfTuple;i++,src+=6)
3436     {
3437       double tmp[3];
3438       INTERP_KERNEL::computeEigenValues6(src,tmp);
3439       for(int j=0;j<3;j++,dest+=3)
3440         INTERP_KERNEL::computeEigenVectorForEigenValue6(src,tmp[j],1e-12,dest);
3441     }
3442   return ret;
3443 }
3444
3445 /*!
3446  * Computes the inverse matrix of every matrix defined by the tuple of \a this
3447  * array, which contains either 4, 6 or 9 components. The case of 6 components
3448  * corresponds to that of the upper triangular matrix.
3449  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
3450  *          same number of components as \a this one, whose each tuple is the inverse
3451  *          matrix of the matrix of corresponding tuple of \a this array. 
3452  *          The caller is to delete this result array using decrRef() as it is no more
3453  *          needed. 
3454  *  \throw If \a this->getNumberOfComponents() is not in [4,6,9].
3455  */
3456 DataArrayDouble *DataArrayDouble::inverse() const
3457 {
3458   checkAllocated();
3459   int nbOfComp=getNumberOfComponents();
3460   if(nbOfComp!=6 && nbOfComp!=9 && nbOfComp!=4)
3461     throw INTERP_KERNEL::Exception("DataArrayDouble::inversion : must be an array with 4,6 or 9 components !");
3462   DataArrayDouble *ret=DataArrayDouble::New();
3463   int nbOfTuple=getNumberOfTuples();
3464   ret->alloc(nbOfTuple,nbOfComp);
3465   const double *src=getConstPointer();
3466   double *dest=ret->getPointer();
3467   if(nbOfComp==6)
3468     for(int i=0;i<nbOfTuple;i++,dest+=6,src+=6)
3469       {
3470         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];
3471         dest[0]=(src[1]*src[2]-src[4]*src[4])/det;
3472         dest[1]=(src[0]*src[2]-src[5]*src[5])/det;
3473         dest[2]=(src[0]*src[1]-src[3]*src[3])/det;
3474         dest[3]=(src[5]*src[4]-src[3]*src[2])/det;
3475         dest[4]=(src[5]*src[3]-src[0]*src[4])/det;
3476         dest[5]=(src[3]*src[4]-src[1]*src[5])/det;
3477       }
3478   else if(nbOfComp==4)
3479     for(int i=0;i<nbOfTuple;i++,dest+=4,src+=4)
3480       {
3481         double det=src[0]*src[3]-src[1]*src[2];
3482         dest[0]=src[3]/det;
3483         dest[1]=-src[1]/det;
3484         dest[2]=-src[2]/det;
3485         dest[3]=src[0]/det;
3486       }
3487   else
3488     for(int i=0;i<nbOfTuple;i++,dest+=9,src+=9)
3489       {
3490         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];
3491         dest[0]=(src[4]*src[8]-src[7]*src[5])/det;
3492         dest[1]=(src[7]*src[2]-src[1]*src[8])/det;
3493         dest[2]=(src[1]*src[5]-src[4]*src[2])/det;
3494         dest[3]=(src[6]*src[5]-src[3]*src[8])/det;
3495         dest[4]=(src[0]*src[8]-src[6]*src[2])/det;
3496         dest[5]=(src[2]*src[3]-src[0]*src[5])/det;
3497         dest[6]=(src[3]*src[7]-src[6]*src[4])/det;
3498         dest[7]=(src[6]*src[1]-src[0]*src[7])/det;
3499         dest[8]=(src[0]*src[4]-src[1]*src[3])/det;
3500       }
3501   return ret;
3502 }
3503
3504 /*!
3505  * Computes the trace of every matrix defined by the tuple of \a this
3506  * array, which contains either 4, 6 or 9 components. The case of 6 components
3507  * corresponds to that of the upper triangular matrix.
3508  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing 
3509  *          1 component, whose each tuple is the trace of
3510  *          the matrix of corresponding tuple of \a this array. 
3511  *          The caller is to delete this result array using decrRef() as it is no more
3512  *          needed. 
3513  *  \throw If \a this->getNumberOfComponents() is not in [4,6,9].
3514  */
3515 DataArrayDouble *DataArrayDouble::trace() const
3516 {
3517   checkAllocated();
3518   int nbOfComp=getNumberOfComponents();
3519   if(nbOfComp!=6 && nbOfComp!=9 && nbOfComp!=4)
3520     throw INTERP_KERNEL::Exception("DataArrayDouble::trace : must be an array with 4,6 or 9 components !");
3521   DataArrayDouble *ret=DataArrayDouble::New();
3522   int nbOfTuple=getNumberOfTuples();
3523   ret->alloc(nbOfTuple,1);
3524   const double *src=getConstPointer();
3525   double *dest=ret->getPointer();
3526   if(nbOfComp==6)
3527     for(int i=0;i<nbOfTuple;i++,dest++,src+=6)
3528       *dest=src[0]+src[1]+src[2];
3529   else if(nbOfComp==4)
3530     for(int i=0;i<nbOfTuple;i++,dest++,src+=4)
3531       *dest=src[0]+src[3];
3532   else
3533     for(int i=0;i<nbOfTuple;i++,dest++,src+=9)
3534       *dest=src[0]+src[4]+src[8];
3535   return ret;
3536 }
3537
3538 /*!
3539  * Computes the stress deviator tensor of every stress tensor defined by the tuple of
3540  * \a this array, which contains 6 components.
3541  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
3542  *          same number of components and tuples as \a this array.
3543  *          The caller is to delete this result array using decrRef() as it is no more
3544  *          needed.
3545  *  \throw If \a this->getNumberOfComponents() != 6.
3546  */
3547 DataArrayDouble *DataArrayDouble::deviator() const
3548 {
3549   checkAllocated();
3550   int nbOfComp=getNumberOfComponents();
3551   if(nbOfComp!=6)
3552     throw INTERP_KERNEL::Exception("DataArrayDouble::deviator : must be an array with exactly 6 components !");
3553   DataArrayDouble *ret=DataArrayDouble::New();
3554   int nbOfTuple=getNumberOfTuples();
3555   ret->alloc(nbOfTuple,6);
3556   const double *src=getConstPointer();
3557   double *dest=ret->getPointer();
3558   for(int i=0;i<nbOfTuple;i++,dest+=6,src+=6)
3559     {
3560       double tr=(src[0]+src[1]+src[2])/3.;
3561       dest[0]=src[0]-tr;
3562       dest[1]=src[1]-tr;
3563       dest[2]=src[2]-tr;
3564       dest[3]=src[3];
3565       dest[4]=src[4];
3566       dest[5]=src[5];
3567     }
3568   return ret;
3569 }
3570
3571 /*!
3572  * Computes the magnitude of every vector defined by the tuple of
3573  * \a this array.
3574  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
3575  *          same number of tuples as \a this array and one component.
3576  *          The caller is to delete this result array using decrRef() as it is no more
3577  *          needed.
3578  *  \throw If \a this is not allocated.
3579  */
3580 DataArrayDouble *DataArrayDouble::magnitude() const
3581 {
3582   checkAllocated();
3583   int nbOfComp=getNumberOfComponents();
3584   DataArrayDouble *ret=DataArrayDouble::New();
3585   int nbOfTuple=getNumberOfTuples();
3586   ret->alloc(nbOfTuple,1);
3587   const double *src=getConstPointer();
3588   double *dest=ret->getPointer();
3589   for(int i=0;i<nbOfTuple;i++,dest++)
3590     {
3591       double sum=0.;
3592       for(int j=0;j<nbOfComp;j++,src++)
3593         sum+=(*src)*(*src);
3594       *dest=sqrt(sum);
3595     }
3596   return ret;
3597 }
3598
3599 /*!
3600  * Computes for each tuple the sum of number of components values in the tuple and return it.
3601  * 
3602  * \return DataArrayDouble * - the new instance of DataArrayDouble containing the
3603  *          same number of tuples as \a this array and one component.
3604  *          The caller is to delete this result array using decrRef() as it is no more
3605  *          needed.
3606  *  \throw If \a this is not allocated.
3607  */
3608 DataArrayDouble *DataArrayDouble::sumPerTuple() const
3609 {
3610   checkAllocated();
3611   int nbOfComp(getNumberOfComponents()),nbOfTuple(getNumberOfTuples());
3612   MCAuto<DataArrayDouble> ret(DataArrayDouble::New());
3613   ret->alloc(nbOfTuple,1);
3614   const double *src(getConstPointer());
3615   double *dest(ret->getPointer());
3616   for(int i=0;i<nbOfTuple;i++,dest++,src+=nbOfComp)
3617     *dest=std::accumulate(src,src+nbOfComp,0.);
3618   return ret.retn();
3619 }
3620
3621 /*!
3622  * Computes the maximal value within every tuple of \a this array.
3623  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
3624  *          same number of tuples as \a this array and one component.
3625  *          The caller is to delete this result array using decrRef() as it is no more
3626  *          needed.
3627  *  \throw If \a this is not allocated.
3628  *  \sa DataArrayDouble::maxPerTupleWithCompoId
3629  */
3630 DataArrayDouble *DataArrayDouble::maxPerTuple() const
3631 {
3632   checkAllocated();
3633   int nbOfComp=getNumberOfComponents();
3634   MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
3635   int nbOfTuple=getNumberOfTuples();
3636   ret->alloc(nbOfTuple,1);
3637   const double *src=getConstPointer();
3638   double *dest=ret->getPointer();
3639   for(int i=0;i<nbOfTuple;i++,dest++,src+=nbOfComp)
3640     *dest=*std::max_element(src,src+nbOfComp);
3641   return ret.retn();
3642 }
3643
3644 /*!
3645  * Computes the maximal value within every tuple of \a this array and it returns the first component
3646  * id for each tuple that corresponds to the maximal value within the tuple.
3647  * 
3648  *  \param [out] compoIdOfMaxPerTuple - the new new instance of DataArrayInt containing the
3649  *          same number of tuples and only one component.
3650  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
3651  *          same number of tuples as \a this array and one component.
3652  *          The caller is to delete this result array using decrRef() as it is no more
3653  *          needed.
3654  *  \throw If \a this is not allocated.
3655  *  \sa DataArrayDouble::maxPerTuple
3656  */
3657 DataArrayDouble *DataArrayDouble::maxPerTupleWithCompoId(DataArrayInt* &compoIdOfMaxPerTuple) const
3658 {
3659   checkAllocated();
3660   int nbOfComp=getNumberOfComponents();
3661   MCAuto<DataArrayDouble> ret0=DataArrayDouble::New();
3662   MCAuto<DataArrayInt> ret1=DataArrayInt::New();
3663   int nbOfTuple=getNumberOfTuples();
3664   ret0->alloc(nbOfTuple,1); ret1->alloc(nbOfTuple,1);
3665   const double *src=getConstPointer();
3666   double *dest=ret0->getPointer(); int *dest1=ret1->getPointer();
3667   for(int i=0;i<nbOfTuple;i++,dest++,dest1++,src+=nbOfComp)
3668     {
3669       const double *loc=std::max_element(src,src+nbOfComp);
3670       *dest=*loc;
3671       *dest1=(int)std::distance(src,loc);
3672     }
3673   compoIdOfMaxPerTuple=ret1.retn();
3674   return ret0.retn();
3675 }
3676
3677 /*!
3678  * This method returns a newly allocated DataArrayDouble instance having one component and \c this->getNumberOfTuples() * \c this->getNumberOfTuples() tuples.
3679  * \n This returned array contains the euclidian distance for each tuple in \a this. 
3680  * \n So the returned array can be seen as a dense symmetrical matrix whose diagonal elements are equal to 0.
3681  * \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)
3682  *
3683  * \warning use this method with care because it can leads to big amount of consumed memory !
3684  * 
3685  * \return A newly allocated (huge) MEDCoupling::DataArrayDouble instance that the caller should deal with.
3686  *
3687  * \throw If \a this is not allocated.
3688  *
3689  * \sa DataArrayDouble::buildEuclidianDistanceDenseMatrixWith
3690  */
3691 DataArrayDouble *DataArrayDouble::buildEuclidianDistanceDenseMatrix() const
3692 {
3693   checkAllocated();
3694   int nbOfComp=getNumberOfComponents();
3695   int nbOfTuples=getNumberOfTuples();
3696   const double *inData=getConstPointer();
3697   MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
3698   ret->alloc(nbOfTuples*nbOfTuples,1);
3699   double *outData=ret->getPointer();
3700   for(int i=0;i<nbOfTuples;i++)
3701     {
3702       outData[i*nbOfTuples+i]=0.;
3703       for(int j=i+1;j<nbOfTuples;j++)
3704         {
3705           double dist=0.;
3706           for(int k=0;k<nbOfComp;k++)
3707             { double delta=inData[i*nbOfComp+k]-inData[j*nbOfComp+k]; dist+=delta*delta; }
3708           dist=sqrt(dist);
3709           outData[i*nbOfTuples+j]=dist;
3710           outData[j*nbOfTuples+i]=dist;
3711         }
3712     }
3713   return ret.retn();
3714 }
3715
3716 /*!
3717  * This method returns a newly allocated DataArrayDouble instance having one component and \c this->getNumberOfTuples() * \c other->getNumberOfTuples() tuples.
3718  * \n This returned array contains the euclidian distance for each tuple in \a other with each tuple in \a this. 
3719  * \n So the returned array can be seen as a dense rectangular matrix with \c other->getNumberOfTuples() rows and \c this->getNumberOfTuples() columns.
3720  * \n Output rectangular matrix is sorted along rows.
3721  * \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)
3722  *
3723  * \warning use this method with care because it can leads to big amount of consumed memory !
3724  * 
3725  * \param [in] other DataArrayDouble instance having same number of components than \a this.
3726  * \return A newly allocated (huge) MEDCoupling::DataArrayDouble instance that the caller should deal with.
3727  *
3728  * \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.
3729  *
3730  * \sa DataArrayDouble::buildEuclidianDistanceDenseMatrix
3731  */
3732 DataArrayDouble *DataArrayDouble::buildEuclidianDistanceDenseMatrixWith(const DataArrayDouble *other) const
3733 {
3734   if(!other)
3735     throw INTERP_KERNEL::Exception("DataArrayDouble::buildEuclidianDistanceDenseMatrixWith : input parameter is null !");
3736   checkAllocated();
3737   other->checkAllocated();
3738   int nbOfComp=getNumberOfComponents();
3739   int otherNbOfComp=other->getNumberOfComponents();
3740   if(nbOfComp!=otherNbOfComp)
3741     {
3742       std::ostringstream oss; oss << "DataArrayDouble::buildEuclidianDistanceDenseMatrixWith : this nb of compo=" << nbOfComp << " and other nb of compo=" << otherNbOfComp << ". It should match !";
3743       throw INTERP_KERNEL::Exception(oss.str().c_str());
3744     }
3745   int nbOfTuples=getNumberOfTuples();
3746   int otherNbOfTuples=other->getNumberOfTuples();
3747   const double *inData=getConstPointer();
3748   const double *inDataOther=other->getConstPointer();
3749   MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
3750   ret->alloc(otherNbOfTuples*nbOfTuples,1);
3751   double *outData=ret->getPointer();
3752   for(int i=0;i<otherNbOfTuples;i++,inDataOther+=nbOfComp)
3753     {
3754       for(int j=0;j<nbOfTuples;j++)
3755         {
3756           double dist=0.;
3757           for(int k=0;k<nbOfComp;k++)
3758             { double delta=inDataOther[k]-inData[j*nbOfComp+k]; dist+=delta*delta; }
3759           dist=sqrt(dist);
3760           outData[i*nbOfTuples+j]=dist;
3761         }
3762     }
3763   return ret.retn();
3764 }
3765
3766 /*!
3767  * Sorts value within every tuple of \a this array.
3768  *  \param [in] asc - if \a true, the values are sorted in ascending order, else,
3769  *              in descending order.
3770  *  \throw If \a this is not allocated.
3771  */
3772 void DataArrayDouble::sortPerTuple(bool asc)
3773 {
3774   checkAllocated();
3775   double *pt=getPointer();
3776   int nbOfTuple=getNumberOfTuples();
3777   int nbOfComp=getNumberOfComponents();
3778   if(asc)
3779     for(int i=0;i<nbOfTuple;i++,pt+=nbOfComp)
3780       std::sort(pt,pt+nbOfComp);
3781   else
3782     for(int i=0;i<nbOfTuple;i++,pt+=nbOfComp)
3783       std::sort(pt,pt+nbOfComp,std::greater<double>());
3784   declareAsNew();
3785 }
3786
3787 /*!
3788  * Converts every value of \a this array to its absolute value.
3789  * \b WARNING this method is non const. If a new DataArrayDouble instance should be built containing the result of abs DataArrayDouble::computeAbs
3790  * should be called instead.
3791  *
3792  * \throw If \a this is not allocated.
3793  * \sa DataArrayDouble::computeAbs
3794  */
3795 void DataArrayDouble::abs()
3796 {
3797   checkAllocated();
3798   double *ptr(getPointer());
3799   std::size_t nbOfElems(getNbOfElems());
3800   std::transform(ptr,ptr+nbOfElems,ptr,std::ptr_fun<double,double>(fabs));
3801   declareAsNew();
3802 }
3803
3804 /*!
3805  * This method builds a new instance of \a this object containing the result of std::abs applied of all elements in \a this.
3806  * This method is a const method (that do not change any values in \a this) contrary to  DataArrayDouble::abs method.
3807  *
3808  * \return DataArrayDouble * - the new instance of DataArrayDouble containing the
3809  *         same number of tuples and component as \a this array.
3810  *         The caller is to delete this result array using decrRef() as it is no more
3811  *         needed.
3812  * \throw If \a this is not allocated.
3813  * \sa DataArrayDouble::abs
3814  */
3815 DataArrayDouble *DataArrayDouble::computeAbs() const
3816 {
3817   checkAllocated();
3818   DataArrayDouble *newArr(DataArrayDouble::New());
3819   int nbOfTuples(getNumberOfTuples());
3820   int nbOfComp(getNumberOfComponents());
3821   newArr->alloc(nbOfTuples,nbOfComp);
3822   std::transform(begin(),end(),newArr->getPointer(),std::ptr_fun<double,double>(fabs));
3823   newArr->copyStringInfoFrom(*this);
3824   return newArr;
3825 }
3826
3827 /*!
3828  * Apply a linear function to a given component of \a this array, so that
3829  * an array element <em>(x)</em> becomes \f$ a * x + b \f$.
3830  *  \param [in] a - the first coefficient of the function.
3831  *  \param [in] b - the second coefficient of the function.
3832  *  \param [in] compoId - the index of component to modify.
3833  *  \throw If \a this is not allocated, or \a compoId is not in [0,\c this->getNumberOfComponents() ).
3834  */
3835 void DataArrayDouble::applyLin(double a, double b, int compoId)
3836 {
3837   checkAllocated();
3838   double *ptr(getPointer()+compoId);
3839   int nbOfComp(getNumberOfComponents()),nbOfTuple(getNumberOfTuples());
3840   if(compoId<0 || compoId>=nbOfComp)
3841     {
3842       std::ostringstream oss; oss << "DataArrayDouble::applyLin : The compoId requested (" << compoId << ") is not valid ! Must be in [0," << nbOfComp << ") !";
3843       throw INTERP_KERNEL::Exception(oss.str().c_str());
3844     }
3845   for(int i=0;i<nbOfTuple;i++,ptr+=nbOfComp)
3846     *ptr=a*(*ptr)+b;
3847   declareAsNew();
3848 }
3849
3850 /*!
3851  * Apply a linear function to all elements of \a this array, so that
3852  * an element _x_ becomes \f$ a * x + b \f$.
3853  *  \param [in] a - the first coefficient of the function.
3854  *  \param [in] b - the second coefficient of the function.
3855  *  \throw If \a this is not allocated.
3856  */
3857 void DataArrayDouble::applyLin(double a, double b)
3858 {
3859   checkAllocated();
3860   double *ptr=getPointer();
3861   std::size_t nbOfElems=getNbOfElems();
3862   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
3863     *ptr=a*(*ptr)+b;
3864   declareAsNew();
3865 }
3866
3867 /*!
3868  * Modify all elements of \a this array, so that
3869  * an element _x_ becomes \f$ numerator / x \f$.
3870  *  \warning If an exception is thrown because of presence of 0.0 element in \a this 
3871  *           array, all elements processed before detection of the zero element remain
3872  *           modified.
3873  *  \param [in] numerator - the numerator used to modify array elements.
3874  *  \throw If \a this is not allocated.
3875  *  \throw If there is an element equal to 0.0 in \a this array.
3876  */
3877 void DataArrayDouble::applyInv(double numerator)
3878 {
3879   checkAllocated();
3880   double *ptr=getPointer();
3881   std::size_t nbOfElems=getNbOfElems();
3882   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
3883     {
3884       if(std::abs(*ptr)>std::numeric_limits<double>::min())
3885         {
3886           *ptr=numerator/(*ptr);
3887         }
3888       else
3889         {
3890           std::ostringstream oss; oss << "DataArrayDouble::applyInv : presence of null value in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
3891           oss << " !";
3892           throw INTERP_KERNEL::Exception(oss.str().c_str());
3893         }
3894     }
3895   declareAsNew();
3896 }
3897
3898 /*!
3899  * Returns a full copy of \a this array except that sign of all elements is reversed.
3900  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
3901  *          same number of tuples and component as \a this array.
3902  *          The caller is to delete this result array using decrRef() as it is no more
3903  *          needed.
3904  *  \throw If \a this is not allocated.
3905  */
3906 DataArrayDouble *DataArrayDouble::negate() const
3907 {
3908   checkAllocated();
3909   DataArrayDouble *newArr=DataArrayDouble::New();
3910   int nbOfTuples=getNumberOfTuples();
3911   int nbOfComp=getNumberOfComponents();
3912   newArr->alloc(nbOfTuples,nbOfComp);
3913   const double *cptr=getConstPointer();
3914   std::transform(cptr,cptr+nbOfTuples*nbOfComp,newArr->getPointer(),std::negate<double>());
3915   newArr->copyStringInfoFrom(*this);
3916   return newArr;
3917 }
3918
3919 /*!
3920  * Modify all elements of \a this array, so that
3921  * an element _x_ becomes <em> val ^ x </em>. Contrary to DataArrayInt::applyPow
3922  * all values in \a this have to be >= 0 if val is \b not integer.
3923  *  \param [in] val - the value used to apply pow on all array elements.
3924  *  \throw If \a this is not allocated.
3925  *  \warning If an exception is thrown because of presence of 0 element in \a this 
3926  *           array and \a val is \b not integer, all elements processed before detection of the zero element remain
3927  *           modified.
3928  */
3929 void DataArrayDouble::applyPow(double val)
3930 {
3931   checkAllocated();
3932   double *ptr=getPointer();
3933   std::size_t nbOfElems=getNbOfElems();
3934   int val2=(int)val;
3935   bool isInt=((double)val2)==val;
3936   if(!isInt)
3937     {
3938       for(std::size_t i=0;i<nbOfElems;i++,ptr++)
3939         {
3940           if(*ptr>=0)
3941             *ptr=pow(*ptr,val);
3942           else
3943             {
3944               std::ostringstream oss; oss << "DataArrayDouble::applyPow (double) : At elem # " << i << " value is " << *ptr << " ! must be >=0. !";
3945               throw INTERP_KERNEL::Exception(oss.str().c_str());
3946             }
3947         }
3948     }
3949   else
3950     {
3951       for(std::size_t i=0;i<nbOfElems;i++,ptr++)
3952         *ptr=pow(*ptr,val2);
3953     }
3954   declareAsNew();
3955 }
3956
3957 /*!
3958  * Modify all elements of \a this array, so that
3959  * an element _x_ becomes \f$ val ^ x \f$.
3960  *  \param [in] val - the value used to apply pow on all array elements.
3961  *  \throw If \a this is not allocated.
3962  *  \throw If \a val < 0.
3963  *  \warning If an exception is thrown because of presence of 0 element in \a this 
3964  *           array, all elements processed before detection of the zero element remain
3965  *           modified.
3966  */
3967 void DataArrayDouble::applyRPow(double val)
3968 {
3969   checkAllocated();
3970   if(val<0.)
3971     throw INTERP_KERNEL::Exception("DataArrayDouble::applyRPow : the input value has to be >= 0 !");
3972   double *ptr=getPointer();
3973   std::size_t nbOfElems=getNbOfElems();
3974   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
3975     *ptr=pow(val,*ptr);
3976   declareAsNew();
3977 }
3978
3979 /*!
3980  * Returns a new DataArrayDouble created from \a this one by applying \a
3981  * FunctionToEvaluate to every tuple of \a this array. Textual data is not copied.
3982  * For more info see \ref MEDCouplingArrayApplyFunc
3983  *  \param [in] nbOfComp - number of components in the result array.
3984  *  \param [in] func - the \a FunctionToEvaluate declared as 
3985  *              \c bool (*\a func)(\c const \c double *\a pos, \c double *\a res), 
3986  *              where \a pos points to the first component of a tuple of \a this array
3987  *              and \a res points to the first component of a tuple of the result array.
3988  *              Note that length (number of components) of \a pos can differ from
3989  *              that of \a res.
3990  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
3991  *          same number of tuples as \a this array.
3992  *          The caller is to delete this result array using decrRef() as it is no more
3993  *          needed.
3994  *  \throw If \a this is not allocated.
3995  *  \throw If \a func returns \a false.
3996  */
3997 DataArrayDouble *DataArrayDouble::applyFunc(int nbOfComp, FunctionToEvaluate func) const
3998 {
3999   checkAllocated();
4000   DataArrayDouble *newArr=DataArrayDouble::New();
4001   int nbOfTuples=getNumberOfTuples();
4002   int oldNbOfComp=getNumberOfComponents();
4003   newArr->alloc(nbOfTuples,nbOfComp);
4004   const double *ptr=getConstPointer();
4005   double *ptrToFill=newArr->getPointer();
4006   for(int i=0;i<nbOfTuples;i++)
4007     {
4008       if(!func(ptr+i*oldNbOfComp,ptrToFill+i*nbOfComp))
4009         {
4010           std::ostringstream oss; oss << "For tuple # " << i << " with value (";
4011           std::copy(ptr+oldNbOfComp*i,ptr+oldNbOfComp*(i+1),std::ostream_iterator<double>(oss,", "));
4012           oss << ") : Evaluation of function failed !";
4013           newArr->decrRef();
4014           throw INTERP_KERNEL::Exception(oss.str().c_str());
4015         }
4016     }
4017   return newArr;
4018 }
4019
4020 /*!
4021  * Returns a new DataArrayDouble created from \a this one by applying a function to every
4022  * tuple of \a this array. Textual data is not copied.
4023  * For more info see \ref MEDCouplingArrayApplyFunc1.
4024  *  \param [in] nbOfComp - number of components in the result array.
4025  *  \param [in] func - the expression defining how to transform a tuple of \a this array.
4026  *              Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
4027  *  \param [in] isSafe - By default true. If true invalid operation (division by 0. acos of value > 1. ...) leads to a throw of an exception.
4028  *              If false the computation is carried on without any notification. When false the evaluation is a little faster.
4029  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
4030  *          same number of tuples as \a this array and \a nbOfComp components.
4031  *          The caller is to delete this result array using decrRef() as it is no more
4032  *          needed.
4033  *  \throw If \a this is not allocated.
4034  *  \throw If computing \a func fails.
4035  */
4036 DataArrayDouble *DataArrayDouble::applyFunc(int nbOfComp, const std::string& func, bool isSafe) const
4037 {
4038   INTERP_KERNEL::ExprParser expr(func);
4039   expr.parse();
4040   std::set<std::string> vars;
4041   expr.getTrueSetOfVars(vars);
4042   std::vector<std::string> varsV(vars.begin(),vars.end());
4043   return applyFuncNamedCompo(nbOfComp,varsV,func,isSafe);
4044 }
4045
4046 /*!
4047  * Returns a new DataArrayDouble created from \a this one by applying a function to every
4048  * tuple of \a this array. Textual data is not copied. This method works by tuples (whatever its size).
4049  * If \a this is a one component array, call applyFuncOnThis instead that performs the same work faster.
4050  *
4051  * For more info see \ref MEDCouplingArrayApplyFunc0.
4052  *  \param [in] func - the expression defining how to transform a tuple of \a this array.
4053  *              Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
4054  *  \param [in] isSafe - By default true. If true invalid operation (division by 0. acos of value > 1. ...) leads to a throw of an exception.
4055  *                       If false the computation is carried on without any notification. When false the evaluation is a little faster.
4056  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
4057  *          same number of tuples and components as \a this array.
4058  *          The caller is to delete this result array using decrRef() as it is no more
4059  *          needed.
4060  *  \sa applyFuncOnThis
4061  *  \throw If \a this is not allocated.
4062  *  \throw If computing \a func fails.
4063  */
4064 DataArrayDouble *DataArrayDouble::applyFunc(const std::string& func, bool isSafe) const
4065 {
4066   int nbOfComp(getNumberOfComponents());
4067   if(nbOfComp<=0)
4068     throw INTERP_KERNEL::Exception("DataArrayDouble::applyFunc : output number of component must be > 0 !");
4069   checkAllocated();
4070   int nbOfTuples(getNumberOfTuples());
4071   MCAuto<DataArrayDouble> newArr(DataArrayDouble::New());
4072   newArr->alloc(nbOfTuples,nbOfComp);
4073   INTERP_KERNEL::ExprParser expr(func);
4074   expr.parse();
4075   std::set<std::string> vars;
4076   expr.getTrueSetOfVars(vars);
4077   if((int)vars.size()>1)
4078     {
4079       std::ostringstream oss; oss << "DataArrayDouble::applyFunc : this method works only with at most one var func expression ! If you need to map comps on variables please use applyFuncCompo or applyFuncNamedCompo instead ! Vars in expr are : ";
4080       std::copy(vars.begin(),vars.end(),std::ostream_iterator<std::string>(oss," "));
4081       throw INTERP_KERNEL::Exception(oss.str().c_str());
4082     }
4083   if(vars.empty())
4084     {
4085       expr.prepareFastEvaluator();
4086       newArr->rearrange(1);
4087       newArr->fillWithValue(expr.evaluateDouble());
4088       newArr->rearrange(nbOfComp);
4089       return newArr.retn();
4090     }
4091   std::vector<std::string> vars2(vars.begin(),vars.end());
4092   double buff,*ptrToFill(newArr->getPointer());
4093   const double *ptr(begin());
4094   std::vector<double> stck;
4095   expr.prepareExprEvaluationDouble(vars2,1,1,0,&buff,&buff+1);
4096   expr.prepareFastEvaluator();
4097   if(!isSafe)
4098     {
4099       for(int i=0;i<nbOfTuples;i++)
4100         {
4101           for(int iComp=0;iComp<nbOfComp;iComp++,ptr++,ptrToFill++)
4102             {
4103               buff=*ptr;
4104               expr.evaluateDoubleInternal(stck);
4105               *ptrToFill=stck.back();
4106               stck.pop_back();
4107             }
4108         }
4109     }
4110   else
4111     {
4112       for(int i=0;i<nbOfTuples;i++)
4113         {
4114           for(int iComp=0;iComp<nbOfComp;iComp++,ptr++,ptrToFill++)
4115             {
4116               buff=*ptr;
4117               try
4118               {
4119                   expr.evaluateDoubleInternalSafe(stck);
4120               }
4121               catch(INTERP_KERNEL::Exception& e)
4122               {
4123                   std::ostringstream oss; oss << "For tuple # " << i << " component # " << iComp << " with value (";
4124                   oss << buff;
4125                   oss << ") : Evaluation of function failed !" << e.what();
4126                   throw INTERP_KERNEL::Exception(oss.str().c_str());
4127               }
4128               *ptrToFill=stck.back();
4129               stck.pop_back();
4130             }
4131         }
4132     }
4133   return newArr.retn();
4134 }
4135
4136 /*!
4137  * This method is a non const method that modify the array in \a this.
4138  * This method only works on one component array. It means that function \a func must
4139  * contain at most one variable.
4140  * This method is a specialization of applyFunc method with one parameter on one component array.
4141  *
4142  *  \param [in] func - the expression defining how to transform a tuple of \a this array.
4143  *              Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
4144  *  \param [in] isSafe - By default true. If true invalid operation (division by 0. acos of value > 1. ...) leads to a throw of an exception.
4145  *              If false the computation is carried on without any notification. When false the evaluation is a little faster.
4146  *
4147  * \sa applyFunc
4148  */
4149 void DataArrayDouble::applyFuncOnThis(const std::string& func, bool isSafe)
4150 {
4151   int nbOfComp(getNumberOfComponents());
4152   if(nbOfComp<=0)
4153     throw INTERP_KERNEL::Exception("DataArrayDouble::applyFuncOnThis : output number of component must be > 0 !");
4154   checkAllocated();
4155   int nbOfTuples(getNumberOfTuples());
4156   INTERP_KERNEL::ExprParser expr(func);
4157   expr.parse();
4158   std::set<std::string> vars;
4159   expr.getTrueSetOfVars(vars);
4160   if((int)vars.size()>1)
4161     {
4162       std::ostringstream oss; oss << "DataArrayDouble::applyFuncOnThis : this method works only with at most one var func expression ! If you need to map comps on variables please use applyFuncCompo or applyFuncNamedCompo instead ! Vars in expr are : ";
4163       std::copy(vars.begin(),vars.end(),std::ostream_iterator<std::string>(oss," "));
4164       throw INTERP_KERNEL::Exception(oss.str().c_str());
4165     }
4166   if(vars.empty())
4167     {
4168       expr.prepareFastEvaluator();
4169       std::vector<std::string> compInfo(getInfoOnComponents());
4170       rearrange(1);
4171       fillWithValue(expr.evaluateDouble());
4172       rearrange(nbOfComp);
4173       setInfoOnComponents(compInfo);
4174       return ;
4175     }
4176   std::vector<std::string> vars2(vars.begin(),vars.end());
4177   double buff,*ptrToFill(getPointer());
4178   const double *ptr(begin());
4179   std::vector<double> stck;
4180   expr.prepareExprEvaluationDouble(vars2,1,1,0,&buff,&buff+1);
4181   expr.prepareFastEvaluator();
4182   if(!isSafe)
4183     {
4184       for(int i=0;i<nbOfTuples;i++)
4185         {
4186           for(int iComp=0;iComp<nbOfComp;iComp++,ptr++,ptrToFill++)
4187             {
4188               buff=*ptr;
4189               expr.evaluateDoubleInternal(stck);
4190               *ptrToFill=stck.back();
4191               stck.pop_back();
4192             }
4193         }
4194     }
4195   else
4196     {
4197       for(int i=0;i<nbOfTuples;i++)
4198         {
4199           for(int iComp=0;iComp<nbOfComp;iComp++,ptr++,ptrToFill++)
4200             {
4201               buff=*ptr;
4202               try
4203               {
4204                   expr.evaluateDoubleInternalSafe(stck);
4205               }
4206               catch(INTERP_KERNEL::Exception& e)
4207               {
4208                   std::ostringstream oss; oss << "For tuple # " << i << " component # " << iComp << " with value (";
4209                   oss << buff;
4210                   oss << ") : Evaluation of function failed !" << e.what();
4211                   throw INTERP_KERNEL::Exception(oss.str().c_str());
4212               }
4213               *ptrToFill=stck.back();
4214               stck.pop_back();
4215             }
4216         }
4217     }
4218 }
4219
4220 /*!
4221  * Returns a new DataArrayDouble created from \a this one by applying a function to every
4222  * tuple of \a this array. Textual data is not copied.
4223  * For more info see \ref MEDCouplingArrayApplyFunc2.
4224  *  \param [in] nbOfComp - number of components in the result array.
4225  *  \param [in] func - the expression defining how to transform a tuple of \a this array.
4226  *              Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
4227  *  \param [in] isSafe - By default true. If true invalid operation (division by 0. acos of value > 1. ...) leads to a throw of an exception.
4228  *              If false the computation is carried on without any notification. When false the evaluation is a little faster.
4229  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
4230  *          same number of tuples as \a this array.
4231  *          The caller is to delete this result array using decrRef() as it is no more
4232  *          needed.
4233  *  \throw If \a this is not allocated.
4234  *  \throw If \a func contains vars that are not in \a this->getInfoOnComponent().
4235  *  \throw If computing \a func fails.
4236  */
4237 DataArrayDouble *DataArrayDouble::applyFuncCompo(int nbOfComp, const std::string& func, bool isSafe) const
4238 {
4239   return applyFuncNamedCompo(nbOfComp,getVarsOnComponent(),func,isSafe);
4240 }
4241
4242 /*!
4243  * Returns a new DataArrayDouble created from \a this one by applying a function to every
4244  * tuple of \a this array. Textual data is not copied.
4245  * For more info see \ref MEDCouplingArrayApplyFunc3.
4246  *  \param [in] nbOfComp - number of components in the result array.
4247  *  \param [in] varsOrder - sequence of vars defining their order.
4248  *  \param [in] func - the expression defining how to transform a tuple of \a this array.
4249  *              Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
4250  *  \param [in] isSafe - By default true. If true invalid operation (division by 0. acos of value > 1. ...) leads to a throw of an exception.
4251  *              If false the computation is carried on without any notification. When false the evaluation is a little faster.
4252  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
4253  *          same number of tuples as \a this array.
4254  *          The caller is to delete this result array using decrRef() as it is no more
4255  *          needed.
4256  *  \throw If \a this is not allocated.
4257  *  \throw If \a func contains vars not in \a varsOrder.
4258  *  \throw If computing \a func fails.
4259  */
4260 DataArrayDouble *DataArrayDouble::applyFuncNamedCompo(int nbOfComp, const std::vector<std::string>& varsOrder, const std::string& func, bool isSafe) const
4261 {
4262   if(nbOfComp<=0)
4263     throw INTERP_KERNEL::Exception("DataArrayDouble::applyFuncNamedCompo : output number of component must be > 0 !");
4264   std::vector<std::string> varsOrder2(varsOrder);
4265   int oldNbOfComp(getNumberOfComponents());
4266   for(int i=(int)varsOrder.size();i<oldNbOfComp;i++)
4267     varsOrder2.push_back(std::string());
4268   checkAllocated();
4269   int nbOfTuples(getNumberOfTuples());
4270   INTERP_KERNEL::ExprParser expr(func);
4271   expr.parse();
4272   std::set<std::string> vars;
4273   expr.getTrueSetOfVars(vars);
4274   if((int)vars.size()>oldNbOfComp)
4275     {
4276       std::ostringstream oss; oss << "The field has " << oldNbOfComp << " components and there are ";
4277       oss << vars.size() << " variables : ";
4278       std::copy(vars.begin(),vars.end(),std::ostream_iterator<std::string>(oss," "));
4279       throw INTERP_KERNEL::Exception(oss.str().c_str());
4280     }
4281   MCAuto<DataArrayDouble> newArr(DataArrayDouble::New());
4282   newArr->alloc(nbOfTuples,nbOfComp);
4283   INTERP_KERNEL::AutoPtr<double> buff(new double[oldNbOfComp]);
4284   double *buffPtr(buff),*ptrToFill;
4285   std::vector<double> stck;
4286   for(int iComp=0;iComp<nbOfComp;iComp++)
4287     {
4288       expr.prepareExprEvaluationDouble(varsOrder2,oldNbOfComp,nbOfComp,iComp,buffPtr,buffPtr+oldNbOfComp);
4289       expr.prepareFastEvaluator();
4290       const double *ptr(getConstPointer());
4291       ptrToFill=newArr->getPointer()+iComp;
4292       if(!isSafe)
4293         {
4294           for(int i=0;i<nbOfTuples;i++,ptrToFill+=nbOfComp,ptr+=oldNbOfComp)
4295             {
4296               std::copy(ptr,ptr+oldNbOfComp,buffPtr);
4297               expr.evaluateDoubleInternal(stck);
4298               *ptrToFill=stck.back();
4299               stck.pop_back();
4300             }
4301         }
4302       else
4303         {
4304           for(int i=0;i<nbOfTuples;i++,ptrToFill+=nbOfComp,ptr+=oldNbOfComp)
4305             {
4306               std::copy(ptr,ptr+oldNbOfComp,buffPtr);
4307               try
4308               {
4309                   expr.evaluateDoubleInternalSafe(stck);
4310                   *ptrToFill=stck.back();
4311                   stck.pop_back();
4312               }
4313               catch(INTERP_KERNEL::Exception& e)
4314               {
4315                   std::ostringstream oss; oss << "For tuple # " << i << " with value (";
4316                   std::copy(ptr+oldNbOfComp*i,ptr+oldNbOfComp*(i+1),std::ostream_iterator<double>(oss,", "));
4317                   oss << ") : Evaluation of function failed !" << e.what();
4318                   throw INTERP_KERNEL::Exception(oss.str().c_str());
4319               }
4320             }
4321         }
4322     }
4323   return newArr.retn();
4324 }
4325
4326 void DataArrayDouble::applyFuncFast32(const std::string& func)
4327 {
4328   checkAllocated();
4329   INTERP_KERNEL::ExprParser expr(func);
4330   expr.parse();
4331   char *funcStr=expr.compileX86();
4332   MYFUNCPTR funcPtr;
4333   *((void **)&funcPtr)=funcStr;//he he...
4334   //
4335   double *ptr=getPointer();
4336   int nbOfComp=getNumberOfComponents();
4337   int nbOfTuples=getNumberOfTuples();
4338   int nbOfElems=nbOfTuples*nbOfComp;
4339   for(int i=0;i<nbOfElems;i++,ptr++)
4340     *ptr=funcPtr(*ptr);
4341   declareAsNew();
4342 }
4343
4344 void DataArrayDouble::applyFuncFast64(const std::string& func)
4345 {
4346   checkAllocated();
4347   INTERP_KERNEL::ExprParser expr(func);
4348   expr.parse();
4349   char *funcStr=expr.compileX86_64();
4350   MYFUNCPTR funcPtr;
4351   *((void **)&funcPtr)=funcStr;//he he...
4352   //
4353   double *ptr=getPointer();
4354   int nbOfComp=getNumberOfComponents();
4355   int nbOfTuples=getNumberOfTuples();
4356   int nbOfElems=nbOfTuples*nbOfComp;
4357   for(int i=0;i<nbOfElems;i++,ptr++)
4358     *ptr=funcPtr(*ptr);
4359   declareAsNew();
4360 }
4361
4362 DataArrayDoubleIterator *DataArrayDouble::iterator()
4363 {
4364   return new DataArrayDoubleIterator(this);
4365 }
4366
4367 /*!
4368  * Returns a new DataArrayInt contating indices of tuples of \a this one-dimensional
4369  * array whose values are within a given range. Textual data is not copied.
4370  *  \param [in] vmin - a lowest acceptable value (included).
4371  *  \param [in] vmax - a greatest acceptable value (included).
4372  *  \return DataArrayInt * - the new instance of DataArrayInt.
4373  *          The caller is to delete this result array using decrRef() as it is no more
4374  *          needed.
4375  *  \throw If \a this->getNumberOfComponents() != 1.
4376  *
4377  *  \sa DataArrayDouble::findIdsNotInRange
4378  *
4379  *  \if ENABLE_EXAMPLES
4380  *  \ref cpp_mcdataarraydouble_getidsinrange "Here is a C++ example".<br>
4381  *  \ref py_mcdataarraydouble_getidsinrange "Here is a Python example".
4382  *  \endif
4383  */
4384 DataArrayInt *DataArrayDouble::findIdsInRange(double vmin, double vmax) const
4385 {
4386   checkAllocated();
4387   if(getNumberOfComponents()!=1)
4388     throw INTERP_KERNEL::Exception("DataArrayDouble::findIdsInRange : this must have exactly one component !");
4389   const double *cptr(begin());
4390   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
4391   int nbOfTuples(getNumberOfTuples());
4392   for(int i=0;i<nbOfTuples;i++,cptr++)
4393     if(*cptr>=vmin && *cptr<=vmax)
4394       ret->pushBackSilent(i);
4395   return ret.retn();
4396 }
4397
4398 /*!
4399  * Returns a new DataArrayInt contating indices of tuples of \a this one-dimensional
4400  * array whose values are not within a given range. Textual data is not copied.
4401  *  \param [in] vmin - a lowest not acceptable value (excluded).
4402  *  \param [in] vmax - a greatest not acceptable value (excluded).
4403  *  \return DataArrayInt * - the new instance of DataArrayInt.
4404  *          The caller is to delete this result array using decrRef() as it is no more
4405  *          needed.
4406  *  \throw If \a this->getNumberOfComponents() != 1.
4407  *
4408  *  \sa DataArrayDouble::findIdsInRange
4409  */
4410 DataArrayInt *DataArrayDouble::findIdsNotInRange(double vmin, double vmax) const
4411 {
4412   checkAllocated();
4413   if(getNumberOfComponents()!=1)
4414     throw INTERP_KERNEL::Exception("DataArrayDouble::findIdsNotInRange : this must have exactly one component !");
4415   const double *cptr(begin());
4416   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
4417   int nbOfTuples(getNumberOfTuples());
4418   for(int i=0;i<nbOfTuples;i++,cptr++)
4419     if(*cptr<vmin || *cptr>vmax)
4420       ret->pushBackSilent(i);
4421   return ret.retn();
4422 }
4423
4424 /*!
4425  * Returns a new DataArrayDouble by concatenating two given arrays, so that (1) the number
4426  * of tuples in the result array is a sum of the number of tuples of given arrays and (2)
4427  * the number of component in the result array is same as that of each of given arrays.
4428  * Info on components is copied from the first of the given arrays. Number of components
4429  * in the given arrays must be  the same.
4430  *  \param [in] a1 - an array to include in the result array.
4431  *  \param [in] a2 - another array to include in the result array.
4432  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4433  *          The caller is to delete this result array using decrRef() as it is no more
4434  *          needed.
4435  *  \throw If both \a a1 and \a a2 are NULL.
4436  *  \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents().
4437  */
4438 DataArrayDouble *DataArrayDouble::Aggregate(const DataArrayDouble *a1, const DataArrayDouble *a2)
4439 {
4440   std::vector<const DataArrayDouble *> tmp(2);
4441   tmp[0]=a1; tmp[1]=a2;
4442   return Aggregate(tmp);
4443 }
4444
4445 /*!
4446  * Returns a new DataArrayDouble by concatenating all given arrays, so that (1) the number
4447  * of tuples in the result array is a sum of the number of tuples of given arrays and (2)
4448  * the number of component in the result array is same as that of each of given arrays.
4449  * Info on components is copied from the first of the given arrays. Number of components
4450  * in the given arrays must be  the same.
4451  * If the number of non null of elements in \a arr is equal to one the returned object is a copy of it
4452  * not the object itself.
4453  *  \param [in] arr - a sequence of arrays to include in the result array.
4454  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4455  *          The caller is to delete this result array using decrRef() as it is no more
4456  *          needed.
4457  *  \throw If all arrays within \a arr are NULL.
4458  *  \throw If getNumberOfComponents() of arrays within \a arr.
4459  */
4460 DataArrayDouble *DataArrayDouble::Aggregate(const std::vector<const DataArrayDouble *>& arr)
4461 {
4462   std::vector<const DataArrayDouble *> a;
4463   for(std::vector<const DataArrayDouble *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
4464     if(*it4)
4465       a.push_back(*it4);
4466   if(a.empty())
4467     throw INTERP_KERNEL::Exception("DataArrayDouble::Aggregate : input list must contain at least one NON EMPTY DataArrayDouble !");
4468   std::vector<const DataArrayDouble *>::const_iterator it=a.begin();
4469   int nbOfComp=(*it)->getNumberOfComponents();
4470   int nbt=(*it++)->getNumberOfTuples();
4471   for(int i=1;it!=a.end();it++,i++)
4472     {
4473       if((*it)->getNumberOfComponents()!=nbOfComp)
4474         throw INTERP_KERNEL::Exception("DataArrayDouble::Aggregate : Nb of components mismatch for array aggregation !");
4475       nbt+=(*it)->getNumberOfTuples();
4476     }
4477   MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
4478   ret->alloc(nbt,nbOfComp);
4479   double *pt=ret->getPointer();
4480   for(it=a.begin();it!=a.end();it++)
4481     pt=std::copy((*it)->getConstPointer(),(*it)->getConstPointer()+(*it)->getNbOfElems(),pt);
4482   ret->copyStringInfoFrom(*(a[0]));
4483   return ret.retn();
4484 }
4485
4486 /*!
4487  * Returns a new DataArrayDouble by aggregating two given arrays, so that (1) the number
4488  * of components in the result array is a sum of the number of components of given arrays
4489  * and (2) the number of tuples in the result array is same as that of each of given
4490  * arrays. In other words the i-th tuple of result array includes all components of
4491  * i-th tuples of all given arrays.
4492  * Number of tuples in the given arrays must be  the same.
4493  *  \param [in] a1 - an array to include in the result array.
4494  *  \param [in] a2 - another array to include in the result array.
4495  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4496  *          The caller is to delete this result array using decrRef() as it is no more
4497  *          needed.
4498  *  \throw If both \a a1 and \a a2 are NULL.
4499  *  \throw If any given array is not allocated.
4500  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
4501  */
4502 DataArrayDouble *DataArrayDouble::Meld(const DataArrayDouble *a1, const DataArrayDouble *a2)
4503 {
4504   std::vector<const DataArrayDouble *> arr(2);
4505   arr[0]=a1; arr[1]=a2;
4506   return Meld(arr);
4507 }
4508
4509 /*!
4510  * Returns a new DataArrayDouble by aggregating all given arrays, so that (1) the number
4511  * of components in the result array is a sum of the number of components of given arrays
4512  * and (2) the number of tuples in the result array is same as that of each of given
4513  * arrays. In other words the i-th tuple of result array includes all components of
4514  * i-th tuples of all given arrays.
4515  * Number of tuples in the given arrays must be  the same.
4516  *  \param [in] arr - a sequence of arrays to include in the result array.
4517  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4518  *          The caller is to delete this result array using decrRef() as it is no more
4519  *          needed.
4520  *  \throw If all arrays within \a arr are NULL.
4521  *  \throw If any given array is not allocated.
4522  *  \throw If getNumberOfTuples() of arrays within \a arr is different.
4523  */
4524 DataArrayDouble *DataArrayDouble::Meld(const std::vector<const DataArrayDouble *>& arr)
4525 {
4526   std::vector<const DataArrayDouble *> a;
4527   for(std::vector<const DataArrayDouble *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
4528     if(*it4)
4529       a.push_back(*it4);
4530   if(a.empty())
4531     throw INTERP_KERNEL::Exception("DataArrayDouble::Meld : input list must contain at least one NON EMPTY DataArrayDouble !");
4532   std::vector<const DataArrayDouble *>::const_iterator it;
4533   for(it=a.begin();it!=a.end();it++)
4534     (*it)->checkAllocated();
4535   it=a.begin();
4536   int nbOfTuples=(*it)->getNumberOfTuples();
4537   std::vector<int> nbc(a.size());
4538   std::vector<const double *> pts(a.size());
4539   nbc[0]=(*it)->getNumberOfComponents();
4540   pts[0]=(*it++)->getConstPointer();
4541   for(int i=1;it!=a.end();it++,i++)
4542     {
4543       if(nbOfTuples!=(*it)->getNumberOfTuples())
4544         throw INTERP_KERNEL::Exception("DataArrayDouble::Meld : mismatch of number of tuples !");
4545       nbc[i]=(*it)->getNumberOfComponents();
4546       pts[i]=(*it)->getConstPointer();
4547     }
4548   int totalNbOfComp=std::accumulate(nbc.begin(),nbc.end(),0);
4549   DataArrayDouble *ret=DataArrayDouble::New();
4550   ret->alloc(nbOfTuples,totalNbOfComp);
4551   double *retPtr=ret->getPointer();
4552   for(int i=0;i<nbOfTuples;i++)
4553     for(int j=0;j<(int)a.size();j++)
4554       {
4555         retPtr=std::copy(pts[j],pts[j]+nbc[j],retPtr);
4556         pts[j]+=nbc[j];
4557       }
4558   int k=0;
4559   for(int i=0;i<(int)a.size();i++)
4560     for(int j=0;j<nbc[i];j++,k++)
4561       ret->setInfoOnComponent(k,a[i]->getInfoOnComponent(j));
4562   return ret;
4563 }
4564
4565 /*!
4566  * Returns a new DataArrayDouble containing a dot product of two given arrays, so that
4567  * the i-th tuple of the result array is a sum of products of j-th components of i-th
4568  * tuples of given arrays (\f$ a_i = \sum_{j=1}^n a1_j * a2_j \f$).
4569  * Info on components and name is copied from the first of the given arrays.
4570  * Number of tuples and components in the given arrays must be the same.
4571  *  \param [in] a1 - a given array.
4572  *  \param [in] a2 - another given array.
4573  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4574  *          The caller is to delete this result array using decrRef() as it is no more
4575  *          needed.
4576  *  \throw If either \a a1 or \a a2 is NULL.
4577  *  \throw If any given array is not allocated.
4578  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
4579  *  \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents()
4580  */
4581 DataArrayDouble *DataArrayDouble::Dot(const DataArrayDouble *a1, const DataArrayDouble *a2)
4582 {
4583   if(!a1 || !a2)
4584     throw INTERP_KERNEL::Exception("DataArrayDouble::Dot : input DataArrayDouble instance is NULL !");
4585   a1->checkAllocated();
4586   a2->checkAllocated();
4587   int nbOfComp=a1->getNumberOfComponents();
4588   if(nbOfComp!=a2->getNumberOfComponents())
4589     throw INTERP_KERNEL::Exception("Nb of components mismatch for array Dot !");
4590   int nbOfTuple=a1->getNumberOfTuples();
4591   if(nbOfTuple!=a2->getNumberOfTuples())
4592     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Dot !");
4593   DataArrayDouble *ret=DataArrayDouble::New();
4594   ret->alloc(nbOfTuple,1);
4595   double *retPtr=ret->getPointer();
4596   const double *a1Ptr=a1->getConstPointer();
4597   const double *a2Ptr=a2->getConstPointer();
4598   for(int i=0;i<nbOfTuple;i++)
4599     {
4600       double sum=0.;
4601       for(int j=0;j<nbOfComp;j++)
4602         sum+=a1Ptr[i*nbOfComp+j]*a2Ptr[i*nbOfComp+j];
4603       retPtr[i]=sum;
4604     }
4605   ret->setInfoOnComponent(0,a1->getInfoOnComponent(0));
4606   ret->setName(a1->getName());
4607   return ret;
4608 }
4609
4610 /*!
4611  * Returns a new DataArrayDouble containing a cross product of two given arrays, so that
4612  * the i-th tuple of the result array contains 3 components of a vector which is a cross
4613  * product of two vectors defined by the i-th tuples of given arrays.
4614  * Info on components is copied from the first of the given arrays.
4615  * Number of tuples in the given arrays must be the same.
4616  * Number of components in the given arrays must be 3.
4617  *  \param [in] a1 - a given array.
4618  *  \param [in] a2 - another given array.
4619  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4620  *          The caller is to delete this result array using decrRef() as it is no more
4621  *          needed.
4622  *  \throw If either \a a1 or \a a2 is NULL.
4623  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
4624  *  \throw If \a a1->getNumberOfComponents() != 3
4625  *  \throw If \a a2->getNumberOfComponents() != 3
4626  */
4627 DataArrayDouble *DataArrayDouble::CrossProduct(const DataArrayDouble *a1, const DataArrayDouble *a2)
4628 {
4629   if(!a1 || !a2)
4630     throw INTERP_KERNEL::Exception("DataArrayDouble::CrossProduct : input DataArrayDouble instance is NULL !");
4631   int nbOfComp=a1->getNumberOfComponents();
4632   if(nbOfComp!=a2->getNumberOfComponents())
4633     throw INTERP_KERNEL::Exception("Nb of components mismatch for array crossProduct !");
4634   if(nbOfComp!=3)
4635     throw INTERP_KERNEL::Exception("Nb of components must be equal to 3 for array crossProduct !");
4636   int nbOfTuple=a1->getNumberOfTuples();
4637   if(nbOfTuple!=a2->getNumberOfTuples())
4638     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array crossProduct !");
4639   DataArrayDouble *ret=DataArrayDouble::New();
4640   ret->alloc(nbOfTuple,3);
4641   double *retPtr=ret->getPointer();
4642   const double *a1Ptr=a1->getConstPointer();
4643   const double *a2Ptr=a2->getConstPointer();
4644   for(int i=0;i<nbOfTuple;i++)
4645     {
4646       retPtr[3*i]=a1Ptr[3*i+1]*a2Ptr[3*i+2]-a1Ptr[3*i+2]*a2Ptr[3*i+1];
4647       retPtr[3*i+1]=a1Ptr[3*i+2]*a2Ptr[3*i]-a1Ptr[3*i]*a2Ptr[3*i+2];
4648       retPtr[3*i+2]=a1Ptr[3*i]*a2Ptr[3*i+1]-a1Ptr[3*i+1]*a2Ptr[3*i];
4649     }
4650   ret->copyStringInfoFrom(*a1);
4651   return ret;
4652 }
4653
4654 /*!
4655  * Returns a new DataArrayDouble containing maximal values of two given arrays.
4656  * Info on components is copied from the first of the given arrays.
4657  * Number of tuples and components in the given arrays must be the same.
4658  *  \param [in] a1 - an array to compare values with another one.
4659  *  \param [in] a2 - another array to compare values with the first one.
4660  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4661  *          The caller is to delete this result array using decrRef() as it is no more
4662  *          needed.
4663  *  \throw If either \a a1 or \a a2 is NULL.
4664  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
4665  *  \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents()
4666  */
4667 DataArrayDouble *DataArrayDouble::Max(const DataArrayDouble *a1, const DataArrayDouble *a2)
4668 {
4669   if(!a1 || !a2)
4670     throw INTERP_KERNEL::Exception("DataArrayDouble::Max : input DataArrayDouble instance is NULL !");
4671   int nbOfComp=a1->getNumberOfComponents();
4672   if(nbOfComp!=a2->getNumberOfComponents())
4673     throw INTERP_KERNEL::Exception("Nb of components mismatch for array Max !");
4674   int nbOfTuple=a1->getNumberOfTuples();
4675   if(nbOfTuple!=a2->getNumberOfTuples())
4676     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Max !");
4677   DataArrayDouble *ret=DataArrayDouble::New();
4678   ret->alloc(nbOfTuple,nbOfComp);
4679   double *retPtr=ret->getPointer();
4680   const double *a1Ptr=a1->getConstPointer();
4681   const double *a2Ptr=a2->getConstPointer();
4682   int nbElem=nbOfTuple*nbOfComp;
4683   for(int i=0;i<nbElem;i++)
4684     retPtr[i]=std::max(a1Ptr[i],a2Ptr[i]);
4685   ret->copyStringInfoFrom(*a1);
4686   return ret;
4687 }
4688
4689 /*!
4690  * Returns a new DataArrayDouble containing minimal values of two given arrays.
4691  * Info on components is copied from the first of the given arrays.
4692  * Number of tuples and components in the given arrays must be the same.
4693  *  \param [in] a1 - an array to compare values with another one.
4694  *  \param [in] a2 - another array to compare values with the first one.
4695  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4696  *          The caller is to delete this result array using decrRef() as it is no more
4697  *          needed.
4698  *  \throw If either \a a1 or \a a2 is NULL.
4699  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
4700  *  \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents()
4701  */
4702 DataArrayDouble *DataArrayDouble::Min(const DataArrayDouble *a1, const DataArrayDouble *a2)
4703 {
4704   if(!a1 || !a2)
4705     throw INTERP_KERNEL::Exception("DataArrayDouble::Min : input DataArrayDouble instance is NULL !");
4706   int nbOfComp=a1->getNumberOfComponents();
4707   if(nbOfComp!=a2->getNumberOfComponents())
4708     throw INTERP_KERNEL::Exception("Nb of components mismatch for array min !");
4709   int nbOfTuple=a1->getNumberOfTuples();
4710   if(nbOfTuple!=a2->getNumberOfTuples())
4711     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array min !");
4712   DataArrayDouble *ret=DataArrayDouble::New();
4713   ret->alloc(nbOfTuple,nbOfComp);
4714   double *retPtr=ret->getPointer();
4715   const double *a1Ptr=a1->getConstPointer();
4716   const double *a2Ptr=a2->getConstPointer();
4717   int nbElem=nbOfTuple*nbOfComp;
4718   for(int i=0;i<nbElem;i++)
4719     retPtr[i]=std::min(a1Ptr[i],a2Ptr[i]);
4720   ret->copyStringInfoFrom(*a1);
4721   return ret;
4722 }
4723
4724 /*!
4725  * Returns a new DataArrayDouble that is a sum of two given arrays. There are 3
4726  * valid cases.
4727  * 1.  The arrays have same number of tuples and components. Then each value of
4728  *   the result array (_a_) is a sum of the corresponding values of \a a1 and \a a2,
4729  *   i.e.: _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ i, j ].
4730  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
4731  *   component. Then
4732  *   _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ i, 0 ].
4733  * 3.  The arrays have same number of components and one array, say _a2_, has one
4734  *   tuple. Then
4735  *   _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ 0, j ].
4736  *
4737  * Info on components is copied either from the first array (in the first case) or from
4738  * the array with maximal number of elements (getNbOfElems()).
4739  *  \param [in] a1 - an array to sum up.
4740  *  \param [in] a2 - another array to sum up.
4741  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4742  *          The caller is to delete this result array using decrRef() as it is no more
4743  *          needed.
4744  *  \throw If either \a a1 or \a a2 is NULL.
4745  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
4746  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
4747  *         none of them has number of tuples or components equal to 1.
4748  */
4749 DataArrayDouble *DataArrayDouble::Add(const DataArrayDouble *a1, const DataArrayDouble *a2)
4750 {
4751   if(!a1 || !a2)
4752     throw INTERP_KERNEL::Exception("DataArrayDouble::Add : input DataArrayDouble instance is NULL !");
4753   int nbOfTuple=a1->getNumberOfTuples();
4754   int nbOfTuple2=a2->getNumberOfTuples();
4755   int nbOfComp=a1->getNumberOfComponents();
4756   int nbOfComp2=a2->getNumberOfComponents();
4757   MCAuto<DataArrayDouble> ret=0;
4758   if(nbOfTuple==nbOfTuple2)
4759     {
4760       if(nbOfComp==nbOfComp2)
4761         {
4762           ret=DataArrayDouble::New();
4763           ret->alloc(nbOfTuple,nbOfComp);
4764           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::plus<double>());
4765           ret->copyStringInfoFrom(*a1);
4766         }
4767       else
4768         {
4769           int nbOfCompMin,nbOfCompMax;
4770           const DataArrayDouble *aMin, *aMax;
4771           if(nbOfComp>nbOfComp2)
4772             {
4773               nbOfCompMin=nbOfComp2; nbOfCompMax=nbOfComp;
4774               aMin=a2; aMax=a1;
4775             }
4776           else
4777             {
4778               nbOfCompMin=nbOfComp; nbOfCompMax=nbOfComp2;
4779               aMin=a1; aMax=a2;
4780             }
4781           if(nbOfCompMin==1)
4782             {
4783               ret=DataArrayDouble::New();
4784               ret->alloc(nbOfTuple,nbOfCompMax);
4785               const double *aMinPtr=aMin->getConstPointer();
4786               const double *aMaxPtr=aMax->getConstPointer();
4787               double *res=ret->getPointer();
4788               for(int i=0;i<nbOfTuple;i++)
4789                 res=std::transform(aMaxPtr+i*nbOfCompMax,aMaxPtr+(i+1)*nbOfCompMax,res,std::bind2nd(std::plus<double>(),aMinPtr[i]));
4790               ret->copyStringInfoFrom(*aMax);
4791             }
4792           else
4793             throw INTERP_KERNEL::Exception("Nb of components mismatch for array Add !");
4794         }
4795     }
4796   else if((nbOfTuple==1 && nbOfTuple2>1) || (nbOfTuple>1 && nbOfTuple2==1))
4797     {
4798       if(nbOfComp==nbOfComp2)
4799         {
4800           int nbOfTupleMax=std::max(nbOfTuple,nbOfTuple2);
4801           const DataArrayDouble *aMin=nbOfTuple>nbOfTuple2?a2:a1;
4802           const DataArrayDouble *aMax=nbOfTuple>nbOfTuple2?a1:a2;
4803           const double *aMinPtr=aMin->getConstPointer(),*aMaxPtr=aMax->getConstPointer();
4804           ret=DataArrayDouble::New();
4805           ret->alloc(nbOfTupleMax,nbOfComp);
4806           double *res=ret->getPointer();
4807           for(int i=0;i<nbOfTupleMax;i++)
4808             res=std::transform(aMaxPtr+i*nbOfComp,aMaxPtr+(i+1)*nbOfComp,aMinPtr,res,std::plus<double>());
4809           ret->copyStringInfoFrom(*aMax);
4810         }
4811       else
4812         throw INTERP_KERNEL::Exception("Nb of components mismatch for array Add !");
4813     }
4814   else
4815     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Add !");
4816   return ret.retn();
4817 }
4818
4819 /*!
4820  * Adds values of another DataArrayDouble to values of \a this one. There are 3
4821  * valid cases.
4822  * 1.  The arrays have same number of tuples and components. Then each value of
4823  *   \a other array is added to the corresponding value of \a this array, i.e.:
4824  *   _a_ [ i, j ] += _other_ [ i, j ].
4825  * 2.  The arrays have same number of tuples and \a other array has one component. Then
4826  *   _a_ [ i, j ] += _other_ [ i, 0 ].
4827  * 3.  The arrays have same number of components and \a other array has one tuple. Then
4828  *   _a_ [ i, j ] += _a2_ [ 0, j ].
4829  *
4830  *  \param [in] other - an array to add to \a this one.
4831  *  \throw If \a other is NULL.
4832  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
4833  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
4834  *         \a other has number of both tuples and components not equal to 1.
4835  */
4836 void DataArrayDouble::addEqual(const DataArrayDouble *other)
4837 {
4838   if(!other)
4839     throw INTERP_KERNEL::Exception("DataArrayDouble::addEqual : input DataArrayDouble instance is NULL !");
4840   const char *msg="Nb of tuples mismatch for DataArrayDouble::addEqual  !";
4841   checkAllocated();
4842   other->checkAllocated();
4843   int nbOfTuple=getNumberOfTuples();
4844   int nbOfTuple2=other->getNumberOfTuples();
4845   int nbOfComp=getNumberOfComponents();
4846   int nbOfComp2=other->getNumberOfComponents();
4847   if(nbOfTuple==nbOfTuple2)
4848     {
4849       if(nbOfComp==nbOfComp2)
4850         {
4851           std::transform(begin(),end(),other->begin(),getPointer(),std::plus<double>());
4852         }
4853       else if(nbOfComp2==1)
4854         {
4855           double *ptr=getPointer();
4856           const double *ptrc=other->getConstPointer();
4857           for(int i=0;i<nbOfTuple;i++)
4858             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::plus<double>(),*ptrc++));
4859         }
4860       else
4861         throw INTERP_KERNEL::Exception(msg);
4862     }
4863   else if(nbOfTuple2==1)
4864     {
4865       if(nbOfComp2==nbOfComp)
4866         {
4867           double *ptr=getPointer();
4868           const double *ptrc=other->getConstPointer();
4869           for(int i=0;i<nbOfTuple;i++)
4870             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::plus<double>());
4871         }
4872       else
4873         throw INTERP_KERNEL::Exception(msg);
4874     }
4875   else
4876     throw INTERP_KERNEL::Exception(msg);
4877   declareAsNew();
4878 }
4879
4880 /*!
4881  * Returns a new DataArrayDouble that is a subtraction of two given arrays. There are 3
4882  * valid cases.
4883  * 1.  The arrays have same number of tuples and components. Then each value of
4884  *   the result array (_a_) is a subtraction of the corresponding values of \a a1 and
4885  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ i, j ].
4886  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
4887  *   component. Then
4888  *   _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ i, 0 ].
4889  * 3.  The arrays have same number of components and one array, say _a2_, has one
4890  *   tuple. Then
4891  *   _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ 0, j ].
4892  *
4893  * Info on components is copied either from the first array (in the first case) or from
4894  * the array with maximal number of elements (getNbOfElems()).
4895  *  \param [in] a1 - an array to subtract from.
4896  *  \param [in] a2 - an array to subtract.
4897  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4898  *          The caller is to delete this result array using decrRef() as it is no more
4899  *          needed.
4900  *  \throw If either \a a1 or \a a2 is NULL.
4901  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
4902  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
4903  *         none of them has number of tuples or components equal to 1.
4904  */
4905 DataArrayDouble *DataArrayDouble::Substract(const DataArrayDouble *a1, const DataArrayDouble *a2)
4906 {
4907   if(!a1 || !a2)
4908     throw INTERP_KERNEL::Exception("DataArrayDouble::Substract : input DataArrayDouble instance is NULL !");
4909   int nbOfTuple1=a1->getNumberOfTuples();
4910   int nbOfTuple2=a2->getNumberOfTuples();
4911   int nbOfComp1=a1->getNumberOfComponents();
4912   int nbOfComp2=a2->getNumberOfComponents();
4913   if(nbOfTuple2==nbOfTuple1)
4914     {
4915       if(nbOfComp1==nbOfComp2)
4916         {
4917           MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
4918           ret->alloc(nbOfTuple2,nbOfComp1);
4919           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::minus<double>());
4920           ret->copyStringInfoFrom(*a1);
4921           return ret.retn();
4922         }
4923       else if(nbOfComp2==1)
4924         {
4925           MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
4926           ret->alloc(nbOfTuple1,nbOfComp1);
4927           const double *a2Ptr=a2->getConstPointer();
4928           const double *a1Ptr=a1->getConstPointer();
4929           double *res=ret->getPointer();
4930           for(int i=0;i<nbOfTuple1;i++)
4931             res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::minus<double>(),a2Ptr[i]));
4932           ret->copyStringInfoFrom(*a1);
4933           return ret.retn();
4934         }
4935       else
4936         {
4937           a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Substract !");
4938           return 0;
4939         }
4940     }
4941   else if(nbOfTuple2==1)
4942     {
4943       a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Substract !");
4944       MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
4945       ret->alloc(nbOfTuple1,nbOfComp1);
4946       const double *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
4947       double *pt=ret->getPointer();
4948       for(int i=0;i<nbOfTuple1;i++)
4949         pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::minus<double>());
4950       ret->copyStringInfoFrom(*a1);
4951       return ret.retn();
4952     }
4953   else
4954     {
4955       a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Substract !");//will always throw an exception
4956       return 0;
4957     }
4958 }
4959
4960 /*!
4961  * Subtract values of another DataArrayDouble from values of \a this one. There are 3
4962  * valid cases.
4963  * 1.  The arrays have same number of tuples and components. Then each value of
4964  *   \a other array is subtracted from the corresponding value of \a this array, i.e.:
4965  *   _a_ [ i, j ] -= _other_ [ i, j ].
4966  * 2.  The arrays have same number of tuples and \a other array has one component. Then
4967  *   _a_ [ i, j ] -= _other_ [ i, 0 ].
4968  * 3.  The arrays have same number of components and \a other array has one tuple. Then
4969  *   _a_ [ i, j ] -= _a2_ [ 0, j ].
4970  *
4971  *  \param [in] other - an array to subtract from \a this one.
4972  *  \throw If \a other is NULL.
4973  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
4974  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
4975  *         \a other has number of both tuples and components not equal to 1.
4976  */
4977 void DataArrayDouble::substractEqual(const DataArrayDouble *other)
4978 {
4979   if(!other)
4980     throw INTERP_KERNEL::Exception("DataArrayDouble::substractEqual : input DataArrayDouble instance is NULL !");
4981   const char *msg="Nb of tuples mismatch for DataArrayDouble::substractEqual  !";
4982   checkAllocated();
4983   other->checkAllocated();
4984   int nbOfTuple=getNumberOfTuples();
4985   int nbOfTuple2=other->getNumberOfTuples();
4986   int nbOfComp=getNumberOfComponents();
4987   int nbOfComp2=other->getNumberOfComponents();
4988   if(nbOfTuple==nbOfTuple2)
4989     {
4990       if(nbOfComp==nbOfComp2)
4991         {
4992           std::transform(begin(),end(),other->begin(),getPointer(),std::minus<double>());
4993         }
4994       else if(nbOfComp2==1)
4995         {
4996           double *ptr=getPointer();
4997           const double *ptrc=other->getConstPointer();
4998           for(int i=0;i<nbOfTuple;i++)
4999             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::minus<double>(),*ptrc++)); 
5000         }
5001       else
5002         throw INTERP_KERNEL::Exception(msg);
5003     }
5004   else if(nbOfTuple2==1)
5005     {
5006       if(nbOfComp2==nbOfComp)
5007         {
5008           double *ptr=getPointer();
5009           const double *ptrc=other->getConstPointer();
5010           for(int i=0;i<nbOfTuple;i++)
5011             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::minus<double>());
5012         }
5013       else
5014         throw INTERP_KERNEL::Exception(msg);
5015     }
5016   else
5017     throw INTERP_KERNEL::Exception(msg);
5018   declareAsNew();
5019 }
5020
5021 /*!
5022  * Returns a new DataArrayDouble that is a product of two given arrays. There are 3
5023  * valid cases.
5024  * 1.  The arrays have same number of tuples and components. Then each value of
5025  *   the result array (_a_) is a product of the corresponding values of \a a1 and
5026  *   \a a2, i.e. _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ i, j ].
5027  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
5028  *   component. Then
5029  *   _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ i, 0 ].
5030  * 3.  The arrays have same number of components and one array, say _a2_, has one
5031  *   tuple. Then
5032  *   _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ 0, j ].
5033  *
5034  * Info on components is copied either from the first array (in the first case) or from
5035  * the array with maximal number of elements (getNbOfElems()).
5036  *  \param [in] a1 - a factor array.
5037  *  \param [in] a2 - another factor array.
5038  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
5039  *          The caller is to delete this result array using decrRef() as it is no more
5040  *          needed.
5041  *  \throw If either \a a1 or \a a2 is NULL.
5042  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
5043  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
5044  *         none of them has number of tuples or components equal to 1.
5045  */
5046 DataArrayDouble *DataArrayDouble::Multiply(const DataArrayDouble *a1, const DataArrayDouble *a2)
5047 {
5048   if(!a1 || !a2)
5049     throw INTERP_KERNEL::Exception("DataArrayDouble::Multiply : input DataArrayDouble instance is NULL !");
5050   int nbOfTuple=a1->getNumberOfTuples();
5051   int nbOfTuple2=a2->getNumberOfTuples();
5052   int nbOfComp=a1->getNumberOfComponents();
5053   int nbOfComp2=a2->getNumberOfComponents();
5054   MCAuto<DataArrayDouble> ret=0;
5055   if(nbOfTuple==nbOfTuple2)
5056     {
5057       if(nbOfComp==nbOfComp2)
5058         {
5059           ret=DataArrayDouble::New();
5060           ret->alloc(nbOfTuple,nbOfComp);
5061           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::multiplies<double>());
5062           ret->copyStringInfoFrom(*a1);
5063         }
5064       else
5065         {
5066           int nbOfCompMin,nbOfCompMax;
5067           const DataArrayDouble *aMin, *aMax;
5068           if(nbOfComp>nbOfComp2)
5069             {
5070               nbOfCompMin=nbOfComp2; nbOfCompMax=nbOfComp;
5071               aMin=a2; aMax=a1;
5072             }
5073           else
5074             {
5075               nbOfCompMin=nbOfComp; nbOfCompMax=nbOfComp2;
5076               aMin=a1; aMax=a2;
5077             }
5078           if(nbOfCompMin==1)
5079             {
5080               ret=DataArrayDouble::New();
5081               ret->alloc(nbOfTuple,nbOfCompMax);
5082               const double *aMinPtr=aMin->getConstPointer();
5083               const double *aMaxPtr=aMax->getConstPointer();
5084               double *res=ret->getPointer();
5085               for(int i=0;i<nbOfTuple;i++)
5086                 res=std::transform(aMaxPtr+i*nbOfCompMax,aMaxPtr+(i+1)*nbOfCompMax,res,std::bind2nd(std::multiplies<double>(),aMinPtr[i]));
5087               ret->copyStringInfoFrom(*aMax);
5088             }
5089           else
5090             throw INTERP_KERNEL::Exception("Nb of components mismatch for array Multiply !");
5091         }
5092     }
5093   else if((nbOfTuple==1 && nbOfTuple2>1) || (nbOfTuple>1 && nbOfTuple2==1))
5094     {
5095       if(nbOfComp==nbOfComp2)
5096         {
5097           int nbOfTupleMax=std::max(nbOfTuple,nbOfTuple2);
5098           const DataArrayDouble *aMin=nbOfTuple>nbOfTuple2?a2:a1;
5099           const DataArrayDouble *aMax=nbOfTuple>nbOfTuple2?a1:a2;
5100           const double *aMinPtr=aMin->getConstPointer(),*aMaxPtr=aMax->getConstPointer();
5101           ret=DataArrayDouble::New();
5102           ret->alloc(nbOfTupleMax,nbOfComp);
5103           double *res=ret->getPointer();
5104           for(int i=0;i<nbOfTupleMax;i++)
5105             res=std::transform(aMaxPtr+i*nbOfComp,aMaxPtr+(i+1)*nbOfComp,aMinPtr,res,std::multiplies<double>());
5106           ret->copyStringInfoFrom(*aMax);
5107         }
5108       else
5109         throw INTERP_KERNEL::Exception("Nb of components mismatch for array Multiply !");
5110     }
5111   else
5112     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Multiply !");
5113   return ret.retn();
5114 }
5115
5116 /*!
5117  * Multiply values of another DataArrayDouble to values of \a this one. There are 3
5118  * valid cases.
5119  * 1.  The arrays have same number of tuples and components. Then each value of
5120  *   \a other array is multiplied to the corresponding value of \a this array, i.e.
5121  *   _this_ [ i, j ] *= _other_ [ i, j ].
5122  * 2.  The arrays have same number of tuples and \a other array has one component. Then
5123  *   _this_ [ i, j ] *= _other_ [ i, 0 ].
5124  * 3.  The arrays have same number of components and \a other array has one tuple. Then
5125  *   _this_ [ i, j ] *= _a2_ [ 0, j ].
5126  *
5127  *  \param [in] other - an array to multiply to \a this one.
5128  *  \throw If \a other is NULL.
5129  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
5130  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
5131  *         \a other has number of both tuples and components not equal to 1.
5132  */
5133 void DataArrayDouble::multiplyEqual(const DataArrayDouble *other)
5134 {
5135   if(!other)
5136     throw INTERP_KERNEL::Exception("DataArrayDouble::multiplyEqual : input DataArrayDouble instance is NULL !");
5137   const char *msg="Nb of tuples mismatch for DataArrayDouble::multiplyEqual !";
5138   checkAllocated();
5139   other->checkAllocated();
5140   int nbOfTuple=getNumberOfTuples();
5141   int nbOfTuple2=other->getNumberOfTuples();
5142   int nbOfComp=getNumberOfComponents();
5143   int nbOfComp2=other->getNumberOfComponents();
5144   if(nbOfTuple==nbOfTuple2)
5145     {
5146       if(nbOfComp==nbOfComp2)
5147         {
5148           std::transform(begin(),end(),other->begin(),getPointer(),std::multiplies<double>());
5149         }
5150       else if(nbOfComp2==1)
5151         {
5152           double *ptr=getPointer();
5153           const double *ptrc=other->getConstPointer();
5154           for(int i=0;i<nbOfTuple;i++)
5155             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::multiplies<double>(),*ptrc++));
5156         }
5157       else
5158         throw INTERP_KERNEL::Exception(msg);
5159     }
5160   else if(nbOfTuple2==1)
5161     {
5162       if(nbOfComp2==nbOfComp)
5163         {
5164           double *ptr=getPointer();
5165           const double *ptrc=other->getConstPointer();
5166           for(int i=0;i<nbOfTuple;i++)
5167             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::multiplies<double>());
5168         }
5169       else
5170         throw INTERP_KERNEL::Exception(msg);
5171     }
5172   else
5173     throw INTERP_KERNEL::Exception(msg);
5174   declareAsNew();
5175 }
5176
5177 /*!
5178  * Returns a new DataArrayDouble that is a division of two given arrays. There are 3
5179  * valid cases.
5180  * 1.  The arrays have same number of tuples and components. Then each value of
5181  *   the result array (_a_) is a division of the corresponding values of \a a1 and
5182  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ i, j ].
5183  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
5184  *   component. Then
5185  *   _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ i, 0 ].
5186  * 3.  The arrays have same number of components and one array, say _a2_, has one
5187  *   tuple. Then
5188  *   _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ 0, j ].
5189  *
5190  * Info on components is copied either from the first array (in the first case) or from
5191  * the array with maximal number of elements (getNbOfElems()).
5192  *  \warning No check of division by zero is performed!
5193  *  \param [in] a1 - a numerator array.
5194  *  \param [in] a2 - a denominator array.
5195  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
5196  *          The caller is to delete this result array using decrRef() as it is no more
5197  *          needed.
5198  *  \throw If either \a a1 or \a a2 is NULL.
5199  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
5200  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
5201  *         none of them has number of tuples or components equal to 1.
5202  */
5203 DataArrayDouble *DataArrayDouble::Divide(const DataArrayDouble *a1, const DataArrayDouble *a2)
5204 {
5205   if(!a1 || !a2)
5206     throw INTERP_KERNEL::Exception("DataArrayDouble::Divide : input DataArrayDouble instance is NULL !");
5207   int nbOfTuple1=a1->getNumberOfTuples();
5208   int nbOfTuple2=a2->getNumberOfTuples();
5209   int nbOfComp1=a1->getNumberOfComponents();
5210   int nbOfComp2=a2->getNumberOfComponents();
5211   if(nbOfTuple2==nbOfTuple1)
5212     {
5213       if(nbOfComp1==nbOfComp2)
5214         {
5215           MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
5216           ret->alloc(nbOfTuple2,nbOfComp1);
5217           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::divides<double>());
5218           ret->copyStringInfoFrom(*a1);
5219           return ret.retn();
5220         }
5221       else if(nbOfComp2==1)
5222         {
5223           MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
5224           ret->alloc(nbOfTuple1,nbOfComp1);
5225           const double *a2Ptr=a2->getConstPointer();
5226           const double *a1Ptr=a1->getConstPointer();
5227           double *res=ret->getPointer();
5228           for(int i=0;i<nbOfTuple1;i++)
5229             res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::divides<double>(),a2Ptr[i]));
5230           ret->copyStringInfoFrom(*a1);
5231           return ret.retn();
5232         }
5233       else
5234         {
5235           a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Divide !");
5236           return 0;
5237         }
5238     }
5239   else if(nbOfTuple2==1)
5240     {
5241       a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Divide !");
5242       MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
5243       ret->alloc(nbOfTuple1,nbOfComp1);
5244       const double *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
5245       double *pt=ret->getPointer();
5246       for(int i=0;i<nbOfTuple1;i++)
5247         pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::divides<double>());
5248       ret->copyStringInfoFrom(*a1);
5249       return ret.retn();
5250     }
5251   else
5252     {
5253       a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Divide !");//will always throw an exception
5254       return 0;
5255     }
5256 }
5257
5258 /*!
5259  * Divide values of \a this array by values of another DataArrayDouble. There are 3
5260  * valid cases.
5261  * 1.  The arrays have same number of tuples and components. Then each value of
5262  *    \a this array is divided by the corresponding value of \a other one, i.e.:
5263  *   _a_ [ i, j ] /= _other_ [ i, j ].
5264  * 2.  The arrays have same number of tuples and \a other array has one component. Then
5265  *   _a_ [ i, j ] /= _other_ [ i, 0 ].
5266  * 3.  The arrays have same number of components and \a other array has one tuple. Then
5267  *   _a_ [ i, j ] /= _a2_ [ 0, j ].
5268  *
5269  *  \warning No check of division by zero is performed!
5270  *  \param [in] other - an array to divide \a this one by.
5271  *  \throw If \a other is NULL.
5272  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
5273  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
5274  *         \a other has number of both tuples and components not equal to 1.
5275  */
5276 void DataArrayDouble::divideEqual(const DataArrayDouble *other)
5277 {
5278   if(!other)
5279     throw INTERP_KERNEL::Exception("DataArrayDouble::divideEqual : input DataArrayDouble instance is NULL !");
5280   const char *msg="Nb of tuples mismatch for DataArrayDouble::divideEqual !";
5281   checkAllocated();
5282   other->checkAllocated();
5283   int nbOfTuple=getNumberOfTuples();
5284   int nbOfTuple2=other->getNumberOfTuples();
5285   int nbOfComp=getNumberOfComponents();
5286   int nbOfComp2=other->getNumberOfComponents();
5287   if(nbOfTuple==nbOfTuple2)
5288     {
5289       if(nbOfComp==nbOfComp2)
5290         {
5291           std::transform(begin(),end(),other->begin(),getPointer(),std::divides<double>());
5292         }
5293       else if(nbOfComp2==1)
5294         {
5295           double *ptr=getPointer();
5296           const double *ptrc=other->getConstPointer();
5297           for(int i=0;i<nbOfTuple;i++)
5298             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::divides<double>(),*ptrc++));
5299         }
5300       else
5301         throw INTERP_KERNEL::Exception(msg);
5302     }
5303   else if(nbOfTuple2==1)
5304     {
5305       if(nbOfComp2==nbOfComp)
5306         {
5307           double *ptr=getPointer();
5308           const double *ptrc=other->getConstPointer();
5309           for(int i=0;i<nbOfTuple;i++)
5310             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::divides<double>());
5311         }
5312       else
5313         throw INTERP_KERNEL::Exception(msg);
5314     }
5315   else
5316     throw INTERP_KERNEL::Exception(msg);
5317   declareAsNew();
5318 }
5319
5320 /*!
5321  * Returns a new DataArrayDouble that is the result of pow of two given arrays. There are 3
5322  * valid cases.
5323  *
5324  *  \param [in] a1 - an array to pow up.
5325  *  \param [in] a2 - another array to sum up.
5326  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
5327  *          The caller is to delete this result array using decrRef() as it is no more
5328  *          needed.
5329  *  \throw If either \a a1 or \a a2 is NULL.
5330  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
5331  *  \throw If \a a1->getNumberOfComponents() != 1 or \a a2->getNumberOfComponents() != 1.
5332  *  \throw If there is a negative value in \a a1.
5333  */
5334 DataArrayDouble *DataArrayDouble::Pow(const DataArrayDouble *a1, const DataArrayDouble *a2)
5335 {
5336   if(!a1 || !a2)
5337     throw INTERP_KERNEL::Exception("DataArrayDouble::Pow : at least one of input instances is null !");
5338   int nbOfTuple=a1->getNumberOfTuples();
5339   int nbOfTuple2=a2->getNumberOfTuples();
5340   int nbOfComp=a1->getNumberOfComponents();
5341   int nbOfComp2=a2->getNumberOfComponents();
5342   if(nbOfTuple!=nbOfTuple2)
5343     throw INTERP_KERNEL::Exception("DataArrayDouble::Pow : number of tuples mismatches !");
5344   if(nbOfComp!=1 || nbOfComp2!=1)
5345     throw INTERP_KERNEL::Exception("DataArrayDouble::Pow : number of components of both arrays must be equal to 1 !");
5346   MCAuto<DataArrayDouble> ret=DataArrayDouble::New(); ret->alloc(nbOfTuple,1);
5347   const double *ptr1(a1->begin()),*ptr2(a2->begin());
5348   double *ptr=ret->getPointer();
5349   for(int i=0;i<nbOfTuple;i++,ptr1++,ptr2++,ptr++)
5350     {
5351       if(*ptr1>=0)
5352         {
5353           *ptr=pow(*ptr1,*ptr2);
5354         }
5355       else
5356         {
5357           std::ostringstream oss; oss << "DataArrayDouble::Pow : on tuple #" << i << " of a1 value is < 0 (" << *ptr1 << ") !";
5358           throw INTERP_KERNEL::Exception(oss.str().c_str());
5359         }
5360     }
5361   return ret.retn();
5362 }
5363
5364 /*!
5365  * Apply pow on values of another DataArrayDouble to values of \a this one.
5366  *
5367  *  \param [in] other - an array to pow to \a this one.
5368  *  \throw If \a other is NULL.
5369  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples()
5370  *  \throw If \a this->getNumberOfComponents() != 1 or \a other->getNumberOfComponents() != 1
5371  *  \throw If there is a negative value in \a this.
5372  */
5373 void DataArrayDouble::powEqual(const DataArrayDouble *other)
5374 {
5375   if(!other)
5376     throw INTERP_KERNEL::Exception("DataArrayDouble::powEqual : input instance is null !");
5377   int nbOfTuple=getNumberOfTuples();
5378   int nbOfTuple2=other->getNumberOfTuples();
5379   int nbOfComp=getNumberOfComponents();
5380   int nbOfComp2=other->getNumberOfComponents();
5381   if(nbOfTuple!=nbOfTuple2)
5382     throw INTERP_KERNEL::Exception("DataArrayDouble::powEqual : number of tuples mismatches !");
5383   if(nbOfComp!=1 || nbOfComp2!=1)
5384     throw INTERP_KERNEL::Exception("DataArrayDouble::powEqual : number of components of both arrays must be equal to 1 !");
5385   double *ptr=getPointer();
5386   const double *ptrc=other->begin();
5387   for(int i=0;i<nbOfTuple;i++,ptrc++,ptr++)
5388     {
5389       if(*ptr>=0)
5390         *ptr=pow(*ptr,*ptrc);
5391       else
5392         {
5393           std::ostringstream oss; oss << "DataArrayDouble::powEqual : on tuple #" << i << " of this value is < 0 (" << *ptr << ") !";
5394           throw INTERP_KERNEL::Exception(oss.str().c_str());
5395         }
5396     }
5397   declareAsNew();
5398 }
5399
5400 /*!
5401  * This method is \b NOT wrapped into python because it can be useful only for performance reasons in C++ context.
5402  * All values in \a this must be 0. or 1. within eps error. 0 means false, 1 means true.
5403  * If an another value than 0 or 1 appear (within eps precision) an INTERP_KERNEL::Exception will be thrown.
5404  *
5405  * \throw if \a this is not allocated.
5406  * \throw if \a this has not exactly one component.
5407  */
5408 std::vector<bool> DataArrayDouble::toVectorOfBool(double eps) const
5409 {
5410   checkAllocated();
5411   if(getNumberOfComponents()!=1)
5412     throw INTERP_KERNEL::Exception("DataArrayDouble::toVectorOfBool : must be applied on single component array !");
5413   int nbt(getNumberOfTuples());
5414   std::vector<bool> ret(nbt);
5415   const double *pt(begin());
5416   for(int i=0;i<nbt;i++)
5417     {
5418       if(fabs(pt[i])<eps)
5419         ret[i]=false;
5420       else if(fabs(pt[i]-1.)<eps)
5421         ret[i]=true;
5422       else
5423         {
5424           std::ostringstream oss; oss << "DataArrayDouble::toVectorOfBool : the tuple #" << i << " has value " << pt[i] << " is invalid ! must be 0. or 1. !";
5425           throw INTERP_KERNEL::Exception(oss.str().c_str());
5426         }
5427     }
5428   return ret;
5429 }
5430
5431 /*!
5432  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
5433  * Server side.
5434  */
5435 void DataArrayDouble::getTinySerializationIntInformation(std::vector<int>& tinyInfo) const
5436 {
5437   tinyInfo.resize(2);
5438   if(isAllocated())
5439     {
5440       tinyInfo[0]=getNumberOfTuples();
5441       tinyInfo[1]=getNumberOfComponents();
5442     }
5443   else
5444     {
5445       tinyInfo[0]=-1;
5446       tinyInfo[1]=-1;
5447     }
5448 }
5449
5450 /*!
5451  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
5452  * Server side.
5453  */
5454 void DataArrayDouble::getTinySerializationStrInformation(std::vector<std::string>& tinyInfo) const
5455 {
5456   if(isAllocated())
5457     {
5458       int nbOfCompo=getNumberOfComponents();
5459       tinyInfo.resize(nbOfCompo+1);
5460       tinyInfo[0]=getName();
5461       for(int i=0;i<nbOfCompo;i++)
5462         tinyInfo[i+1]=getInfoOnComponent(i);
5463     }
5464   else
5465     {
5466       tinyInfo.resize(1);
5467       tinyInfo[0]=getName();
5468     }
5469 }
5470
5471 /*!
5472  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
5473  * This method returns if a feeding is needed.
5474  */
5475 bool DataArrayDouble::resizeForUnserialization(const std::vector<int>& tinyInfoI)
5476 {
5477   int nbOfTuple=tinyInfoI[0];
5478   int nbOfComp=tinyInfoI[1];
5479   if(nbOfTuple!=-1 || nbOfComp!=-1)
5480     {
5481       alloc(nbOfTuple,nbOfComp);
5482       return true;
5483     }
5484   return false;
5485 }
5486
5487 /*!
5488  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
5489  */
5490 void DataArrayDouble::finishUnserialization(const std::vector<int>& tinyInfoI, const std::vector<std::string>& tinyInfoS)
5491 {
5492   setName(tinyInfoS[0]);
5493   if(isAllocated())
5494     {
5495       int nbOfCompo=getNumberOfComponents();
5496       for(int i=0;i<nbOfCompo;i++)
5497         setInfoOnComponent(i,tinyInfoS[i+1]);
5498     }
5499 }
5500
5501 DataArrayDoubleIterator::DataArrayDoubleIterator(DataArrayDouble *da):_da(da),_tuple_id(0),_nb_comp(0),_nb_tuple(0)
5502 {
5503   if(_da)
5504     {
5505       _da->incrRef();
5506       if(_da->isAllocated())
5507         {
5508           _nb_comp=da->getNumberOfComponents();
5509           _nb_tuple=da->getNumberOfTuples();
5510           _pt=da->getPointer();
5511         }
5512     }
5513 }
5514
5515 DataArrayDoubleIterator::~DataArrayDoubleIterator()
5516 {
5517   if(_da)
5518     _da->decrRef();
5519 }
5520
5521 DataArrayDoubleTuple *DataArrayDoubleIterator::nextt()
5522 {
5523   if(_tuple_id<_nb_tuple)
5524     {
5525       _tuple_id++;
5526       DataArrayDoubleTuple *ret=new DataArrayDoubleTuple(_pt,_nb_comp);
5527       _pt+=_nb_comp;
5528       return ret;
5529     }
5530   else
5531     return 0;
5532 }
5533
5534 DataArrayDoubleTuple::DataArrayDoubleTuple(double *pt, int nbOfComp):_pt(pt),_nb_of_compo(nbOfComp)
5535 {
5536 }
5537
5538
5539 std::string DataArrayDoubleTuple::repr() const
5540 {
5541   std::ostringstream oss; oss.precision(17); oss << "(";
5542   for(int i=0;i<_nb_of_compo-1;i++)
5543     oss << _pt[i] << ", ";
5544   oss << _pt[_nb_of_compo-1] << ")";
5545   return oss.str();
5546 }
5547
5548 double DataArrayDoubleTuple::doubleValue() const
5549 {
5550   if(_nb_of_compo==1)
5551     return *_pt;
5552   throw INTERP_KERNEL::Exception("DataArrayDoubleTuple::doubleValue : DataArrayDoubleTuple instance has not exactly 1 component -> Not possible to convert it into a double precision float !");
5553 }
5554
5555 /*!
5556  * This method returns a newly allocated instance the caller should dealed with by a MEDCoupling::DataArrayDouble::decrRef.
5557  * This method performs \b no copy of data. The content is only referenced using MEDCoupling::DataArrayDouble::useArray with ownership set to \b false.
5558  * 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
5559  * \b nbOfCompo=1 and \bnbOfTuples==this->_nb_of_elem.
5560  */
5561 DataArrayDouble *DataArrayDoubleTuple::buildDADouble(int nbOfTuples, int nbOfCompo) const
5562 {
5563   if((_nb_of_compo==nbOfCompo && nbOfTuples==1) || (_nb_of_compo==nbOfTuples && nbOfCompo==1))
5564     {
5565       DataArrayDouble *ret=DataArrayDouble::New();
5566       ret->useExternalArrayWithRWAccess(_pt,nbOfTuples,nbOfCompo);
5567       return ret;
5568     }
5569   else
5570     {
5571       std::ostringstream oss; oss << "DataArrayDoubleTuple::buildDADouble : unable to build a requested DataArrayDouble instance with nbofTuple=" << nbOfTuples << " and nbOfCompo=" << nbOfCompo;
5572       oss << ".\nBecause the number of elements in this is " << _nb_of_compo << " !";
5573       throw INTERP_KERNEL::Exception(oss.str().c_str());
5574     }
5575 }
5576
5577 /*!
5578  * Returns a new instance of DataArrayInt. The caller is to delete this array
5579  * using decrRef() as it is no more needed. 
5580  */
5581 DataArrayInt *DataArrayInt::New()
5582 {
5583   return new DataArrayInt;
5584 }
5585
5586 /*!
5587  * Returns the only one value in \a this, if and only if number of elements
5588  * (nb of tuples * nb of components) is equal to 1, and that \a this is allocated.
5589  *  \return double - the sole value stored in \a this array.
5590  *  \throw If at least one of conditions stated above is not fulfilled.
5591  */
5592 int DataArrayInt::intValue() const
5593 {
5594   if(isAllocated())
5595     {
5596       if(getNbOfElems()==1)
5597         {
5598           return *getConstPointer();
5599         }
5600       else
5601         throw INTERP_KERNEL::Exception("DataArrayInt::intValue : DataArrayInt instance is allocated but number of elements is not equal to 1 !");
5602     }
5603   else
5604     throw INTERP_KERNEL::Exception("DataArrayInt::intValue : DataArrayInt instance is not allocated !");
5605 }
5606
5607 /*!
5608  * Returns an integer value characterizing \a this array, which is useful for a quick
5609  * comparison of many instances of DataArrayInt.
5610  *  \return int - the hash value.
5611  *  \throw If \a this is not allocated.
5612  */
5613 int DataArrayInt::getHashCode() const
5614 {
5615   checkAllocated();
5616   std::size_t nbOfElems=getNbOfElems();
5617   int ret=nbOfElems*65536;
5618   int delta=3;
5619   if(nbOfElems>48)
5620     delta=nbOfElems/8;
5621   int ret0=0;
5622   const int *pt=begin();
5623   for(std::size_t i=0;i<nbOfElems;i+=delta)
5624     ret0+=pt[i] & 0x1FFF;
5625   return ret+ret0;
5626 }
5627
5628 /*!
5629  * Returns a full copy of \a this. For more info on copying data arrays see
5630  * \ref MEDCouplingArrayBasicsCopyDeep.
5631  *  \return DataArrayInt * - a new instance of DataArrayInt.
5632  */
5633 DataArrayInt *DataArrayInt::deepCopy() const
5634 {
5635   return new DataArrayInt(*this);
5636 }
5637
5638 /*!
5639  * Returns either a \a deep or \a shallow copy of this array. For more info see
5640  * \ref MEDCouplingArrayBasicsCopyDeep and \ref MEDCouplingArrayBasicsCopyShallow.
5641  *  \param [in] dCpy - if \a true, a deep copy is returned, else, a shallow one.
5642  *  \return DataArrayInt * - either a new instance of DataArrayInt (if \a dCpy
5643  *          == \a true) or \a this instance (if \a dCpy == \a false).
5644  */
5645 DataArrayInt *DataArrayInt::performCopyOrIncrRef(bool dCpy) const
5646 {
5647   if(dCpy)
5648     return deepCopy();
5649   else
5650     {
5651       incrRef();
5652       return const_cast<DataArrayInt *>(this);
5653     }
5654 }
5655
5656 /*!
5657  * Assign zero to all values in \a this array. To know more on filling arrays see
5658  * \ref MEDCouplingArrayFill.
5659  * \throw If \a this is not allocated.
5660  */
5661 void DataArrayInt::fillWithZero()
5662 {
5663   fillWithValue(0);
5664 }
5665
5666 /*!
5667  * Set all values in \a this array so that the i-th element equals to \a init + i
5668  * (i starts from zero). To know more on filling arrays see \ref MEDCouplingArrayFill.
5669  *  \param [in] init - value to assign to the first element of array.
5670  *  \throw If \a this->getNumberOfComponents() != 1
5671  *  \throw If \a this is not allocated.
5672  */
5673 void DataArrayInt::iota(int init)
5674 {
5675   checkAllocated();
5676   if(getNumberOfComponents()!=1)
5677     throw INTERP_KERNEL::Exception("DataArrayInt::iota : works only for arrays with only one component, you can call 'rearrange' method before !");
5678   int *ptr=getPointer();
5679   int ntuples=getNumberOfTuples();
5680   for(int i=0;i<ntuples;i++)
5681     ptr[i]=init+i;
5682   declareAsNew();
5683 }
5684
5685 /*!
5686  * Returns a textual and human readable representation of \a this instance of
5687  * DataArrayInt. This text is shown when a DataArrayInt is printed in Python.
5688  * \return std::string - text describing \a this DataArrayInt.
5689  * 
5690  * \sa reprNotTooLong, reprZip
5691  */
5692 std::string DataArrayInt::repr() const
5693 {
5694   std::ostringstream ret;
5695   reprStream(ret);
5696   return ret.str();
5697 }
5698
5699 std::string DataArrayInt::reprZip() const
5700 {
5701   std::ostringstream ret;
5702   reprZipStream(ret);
5703   return ret.str();
5704 }
5705
5706 /*!
5707  * This method is close to repr method except that when \a this has more than 1000 tuples, all tuples are not
5708  * printed out to avoid to consume too much space in interpretor.
5709  * \sa repr
5710  */
5711 std::string DataArrayInt::reprNotTooLong() const
5712 {
5713   std::ostringstream ret;
5714   reprNotTooLongStream(ret);
5715   return ret.str();
5716 }
5717
5718 void DataArrayInt::writeVTK(std::ostream& ofs, int indent, const std::string& type, const std::string& nameInFile, DataArrayByte *byteArr) const
5719 {
5720   static const char SPACE[4]={' ',' ',' ',' '};
5721   checkAllocated();
5722   std::string idt(indent,' ');
5723   ofs << idt << "<DataArray type=\"" << type << "\" Name=\"" << nameInFile << "\" NumberOfComponents=\"" << getNumberOfComponents() << "\"";
5724   if(byteArr)
5725     {
5726       ofs << " format=\"appended\" offset=\"" << byteArr->getNumberOfTuples() << "\">";
5727       if(std::string(type)=="Int32")
5728         {
5729           const char *data(reinterpret_cast<const char *>(begin()));
5730           std::size_t sz(getNbOfElems()*sizeof(int));
5731           byteArr->insertAtTheEnd(data,data+sz);
5732           byteArr->insertAtTheEnd(SPACE,SPACE+4);
5733         }
5734       else if(std::string(type)=="Int8")
5735         {
5736           INTERP_KERNEL::AutoPtr<char> tmp(new char[getNbOfElems()]);
5737           std::copy(begin(),end(),(char *)tmp);
5738           byteArr->insertAtTheEnd((char *)tmp,(char *)tmp+getNbOfElems());
5739           byteArr->insertAtTheEnd(SPACE,SPACE+4);
5740         }
5741       else if(std::string(type)=="UInt8")
5742         {
5743           INTERP_KERNEL::AutoPtr<unsigned char> tmp(new unsigned char[getNbOfElems()]);
5744           std::copy(begin(),end(),(unsigned char *)tmp);
5745           byteArr->insertAtTheEnd((unsigned char *)tmp,(unsigned char *)tmp+getNbOfElems());
5746           byteArr->insertAtTheEnd(SPACE,SPACE+4);
5747         }
5748       else
5749         throw INTERP_KERNEL::Exception("DataArrayInt::writeVTK : Only Int32, Int8 and UInt8 supported !");
5750     }
5751   else
5752     {
5753       ofs << " RangeMin=\"" << getMinValueInArray() << "\" RangeMax=\"" << getMaxValueInArray() << "\" format=\"ascii\">\n" << idt;
5754       std::copy(begin(),end(),std::ostream_iterator<int>(ofs," "));
5755     }
5756   ofs << std::endl << idt << "</DataArray>\n";
5757 }
5758
5759 void DataArrayInt::reprStream(std::ostream& stream) const
5760 {
5761   stream << "Name of int array : \"" << _name << "\"\n";
5762   reprWithoutNameStream(stream);
5763 }
5764
5765 void DataArrayInt::reprZipStream(std::ostream& stream) const
5766 {
5767   stream << "Name of int array : \"" << _name << "\"\n";
5768   reprZipWithoutNameStream(stream);
5769 }
5770
5771 void DataArrayInt::reprNotTooLongStream(std::ostream& stream) const
5772 {
5773   stream << "Name of int array : \"" << _name << "\"\n";
5774   reprNotTooLongWithoutNameStream(stream);
5775 }
5776
5777 void DataArrayInt::reprWithoutNameStream(std::ostream& stream) const
5778 {
5779   DataArray::reprWithoutNameStream(stream);
5780   _mem.repr(getNumberOfComponents(),stream);
5781 }
5782
5783 void DataArrayInt::reprZipWithoutNameStream(std::ostream& stream) const
5784 {
5785   DataArray::reprWithoutNameStream(stream);
5786   _mem.reprZip(getNumberOfComponents(),stream);
5787 }
5788
5789 void DataArrayInt::reprNotTooLongWithoutNameStream(std::ostream& stream) const
5790 {
5791   DataArray::reprWithoutNameStream(stream);
5792   stream.precision(17);
5793   _mem.reprNotTooLong(getNumberOfComponents(),stream);
5794 }
5795
5796 void DataArrayInt::reprCppStream(const std::string& varName, std::ostream& stream) const
5797 {
5798   int nbTuples=getNumberOfTuples(),nbComp=getNumberOfComponents();
5799   const int *data=getConstPointer();
5800   stream << "DataArrayInt *" << varName << "=DataArrayInt::New();" << std::endl;
5801   if(nbTuples*nbComp>=1)
5802     {
5803       stream << "const int " << varName << "Data[" << nbTuples*nbComp << "]={";
5804       std::copy(data,data+nbTuples*nbComp-1,std::ostream_iterator<int>(stream,","));
5805       stream << data[nbTuples*nbComp-1] << "};" << std::endl;
5806       stream << varName << "->useArray(" << varName << "Data,false,CPP_DEALLOC," << nbTuples << "," << nbComp << ");" << std::endl;
5807     }
5808   else
5809     stream << varName << "->alloc(" << nbTuples << "," << nbComp << ");" << std::endl;
5810   stream << varName << "->setName(\"" << getName() << "\");" << std::endl;
5811 }
5812
5813 /*!
5814  * Method that gives a quick overvien of \a this for python.
5815  */
5816 void DataArrayInt::reprQuickOverview(std::ostream& stream) const
5817 {
5818   static const std::size_t MAX_NB_OF_BYTE_IN_REPR=300;
5819   stream << "DataArrayInt C++ instance at " << this << ". ";
5820   if(isAllocated())
5821     {
5822       int nbOfCompo=(int)_info_on_compo.size();
5823       if(nbOfCompo>=1)
5824         {
5825           int nbOfTuples=getNumberOfTuples();
5826           stream << "Number of tuples : " << nbOfTuples << ". Number of components : " << nbOfCompo << "." << std::endl;
5827           reprQuickOverviewData(stream,MAX_NB_OF_BYTE_IN_REPR);
5828         }
5829       else
5830         stream << "Number of components : 0.";
5831     }
5832   else
5833     stream << "*** No data allocated ****";
5834 }
5835
5836 void DataArrayInt::reprQuickOverviewData(std::ostream& stream, std::size_t maxNbOfByteInRepr) const
5837 {
5838   const int *data=begin();
5839   int nbOfTuples=getNumberOfTuples();
5840   int nbOfCompo=(int)_info_on_compo.size();
5841   std::ostringstream oss2; oss2 << "[";
5842   std::string oss2Str(oss2.str());
5843   bool isFinished=true;
5844   for(int i=0;i<nbOfTuples && isFinished;i++)
5845     {
5846       if(nbOfCompo>1)
5847         {
5848           oss2 << "(";
5849           for(int j=0;j<nbOfCompo;j++,data++)
5850             {
5851               oss2 << *data;
5852               if(j!=nbOfCompo-1) oss2 << ", ";
5853             }
5854           oss2 << ")";
5855         }
5856       else
5857         oss2 << *data++;
5858       if(i!=nbOfTuples-1) oss2 << ", ";
5859       std::string oss3Str(oss2.str());
5860       if(oss3Str.length()<maxNbOfByteInRepr)
5861         oss2Str=oss3Str;
5862       else
5863         isFinished=false;
5864     }
5865   stream << oss2Str;
5866   if(!isFinished)
5867     stream << "... ";
5868   stream << "]";
5869 }
5870
5871 /*!
5872  * Modifies in place \a this one-dimensional array so that each value \a v = \a indArrBg[ \a v ],
5873  * i.e. a current value is used as in index to get a new value from \a indArrBg.
5874  *  \param [in] indArrBg - pointer to the first element of array of new values to assign
5875  *         to \a this array.
5876  *  \param [in] indArrEnd - specifies the end of the array \a indArrBg, so that
5877  *              the last value of \a indArrBg is \a indArrEnd[ -1 ].
5878  *  \throw If \a this->getNumberOfComponents() != 1
5879  *  \throw If any value of \a this can't be used as a valid index for 
5880  *         [\a indArrBg, \a indArrEnd).
5881  *
5882  *  \sa changeValue
5883  */
5884 void DataArrayInt::transformWithIndArr(const int *indArrBg, const int *indArrEnd)
5885 {
5886   checkAllocated();
5887   if(getNumberOfComponents()!=1)
5888     throw INTERP_KERNEL::Exception("Call transformWithIndArr method on DataArrayInt with only one component, you can call 'rearrange' method before !");
5889   int nbElemsIn((int)std::distance(indArrBg,indArrEnd)),nbOfTuples(getNumberOfTuples()),*pt(getPointer());
5890   for(int i=0;i<nbOfTuples;i++,pt++)
5891     {
5892       if(*pt>=0 && *pt<nbElemsIn)
5893         *pt=indArrBg[*pt];
5894       else
5895         {
5896           std::ostringstream oss; oss << "DataArrayInt::transformWithIndArr : error on tuple #" << i << " of this value is " << *pt << ", should be in [0," << nbElemsIn << ") !";
5897           throw INTERP_KERNEL::Exception(oss.str().c_str());
5898         }
5899     }
5900   declareAsNew();
5901 }
5902
5903 /*!
5904  * Computes distribution of values of \a this one-dimensional array between given value
5905  * ranges (casts). This method is typically useful for entity number spliting by types,
5906  * for example. 
5907  *  \warning The values contained in \a arrBg should be sorted ascendently. No
5908  *           check of this is be done. If not, the result is not warranted. 
5909  *  \param [in] arrBg - the array of ascending values defining the value ranges. The i-th
5910  *         value of \a arrBg (\a arrBg[ i ]) gives the lowest value of the i-th range,
5911  *         and the greatest value of the i-th range equals to \a arrBg[ i+1 ] - 1. \a
5912  *         arrBg containing \a n values defines \a n-1 ranges. The last value of \a arrBg
5913  *         should be more than every value in \a this array.
5914  *  \param [in] arrEnd - specifies the end of the array \a arrBg, so that
5915  *              the last value of \a arrBg is \a arrEnd[ -1 ].
5916  *  \param [out] castArr - a new instance of DataArrayInt, of same size as \a this array
5917  *         (same number of tuples and components), the caller is to delete 
5918  *         using decrRef() as it is no more needed.
5919  *         This array contains indices of ranges for every value of \a this array. I.e.
5920  *         the i-th value of \a castArr gives the index of range the i-th value of \a this
5921  *         belongs to. Or, in other words, this parameter contains for each tuple in \a
5922  *         this in which cast it holds.
5923  *  \param [out] rankInsideCast - a new instance of DataArrayInt, of same size as \a this
5924  *         array, the caller is to delete using decrRef() as it is no more needed.
5925  *         This array contains ranks of values of \a this array within ranges
5926  *         they belongs to. I.e. the i-th value of \a rankInsideCast gives the rank of
5927  *         the i-th value of \a this array within the \a castArr[ i ]-th range, to which
5928  *         the i-th value of \a this belongs to. Or, in other words, this param contains 
5929  *         for each tuple its rank inside its cast. The rank is computed as difference
5930  *         between the value and the lowest value of range.
5931  *  \param [out] castsPresent - a new instance of DataArrayInt, containing indices of
5932  *         ranges (casts) to which at least one value of \a this array belongs.
5933  *         Or, in other words, this param contains the casts that \a this contains.
5934  *         The caller is to delete this array using decrRef() as it is no more needed.
5935  *
5936  * \b Example: If \a this contains [6,5,0,3,2,7,8,1,4] and \a arrBg contains [0,4,9] then
5937  *            the output of this method will be : 
5938  * - \a castArr       : [1,1,0,0,0,1,1,0,1]
5939  * - \a rankInsideCast: [2,1,0,3,2,3,4,1,0]
5940  * - \a castsPresent  : [0,1]
5941  *
5942  * I.e. values of \a this array belong to 2 ranges: #0 and #1. Value 6 belongs to the
5943  * range #1 and its rank within this range is 2; etc.
5944  *
5945  *  \throw If \a this->getNumberOfComponents() != 1.
5946  *  \throw If \a arrEnd - arrBg < 2.
5947  *  \throw If any value of \a this is not less than \a arrEnd[-1].
5948  */
5949 void DataArrayInt::splitByValueRange(const int *arrBg, const int *arrEnd,
5950                                      DataArrayInt *& castArr, DataArrayInt *& rankInsideCast, DataArrayInt *& castsPresent) const
5951 {
5952   checkAllocated();
5953   if(getNumberOfComponents()!=1)
5954     throw INTERP_KERNEL::Exception("Call splitByValueRange  method on DataArrayInt with only one component, you can call 'rearrange' method before !");
5955   int nbOfTuples=getNumberOfTuples();
5956   std::size_t nbOfCast=std::distance(arrBg,arrEnd);
5957   if(nbOfCast<2)
5958     throw INTERP_KERNEL::Exception("DataArrayInt::splitByValueRange : The input array giving the cast range values should be of size >=2 !");
5959   nbOfCast--;
5960   const int *work=getConstPointer();
5961   typedef std::reverse_iterator<const int *> rintstart;
5962   rintstart bg(arrEnd);//OK no problem because size of 'arr' is greater or equal 2
5963   rintstart end2(arrBg);
5964   MCAuto<DataArrayInt> ret1=DataArrayInt::New();
5965   MCAuto<DataArrayInt> ret2=DataArrayInt::New();
5966   MCAuto<DataArrayInt> ret3=DataArrayInt::New();
5967   ret1->alloc(nbOfTuples,1);
5968   ret2->alloc(nbOfTuples,1);
5969   int *ret1Ptr=ret1->getPointer();
5970   int *ret2Ptr=ret2->getPointer();
5971   std::set<std::size_t> castsDetected;
5972   for(int i=0;i<nbOfTuples;i++)
5973     {
5974       rintstart res=std::find_if(bg,end2,std::bind2nd(std::less_equal<int>(), work[i]));
5975       std::size_t pos=std::distance(bg,res);
5976       std::size_t pos2=nbOfCast-pos;
5977       if(pos2<nbOfCast)
5978         {
5979           ret1Ptr[i]=(int)pos2;
5980           ret2Ptr[i]=work[i]-arrBg[pos2];
5981           castsDetected.insert(pos2);
5982         }
5983       else
5984         {
5985           std::ostringstream oss; oss << "DataArrayInt::splitByValueRange : At rank #" << i << " the value is " << work[i] << " should be in [0," << *bg << ") !";
5986           throw INTERP_KERNEL::Exception(oss.str().c_str());
5987         }
5988     }
5989   ret3->alloc((int)castsDetected.size(),1);
5990   std::copy(castsDetected.begin(),castsDetected.end(),ret3->getPointer());
5991   castArr=ret1.retn();
5992   rankInsideCast=ret2.retn();
5993   castsPresent=ret3.retn();
5994 }
5995
5996 /*!
5997  * This method look at \a this if it can be considered as a range defined by the 3-tuple ( \a strt , \a sttoopp , \a stteepp ).
5998  * If false is returned the tuple must be ignored. If true is returned \a this can be considered by a range( \a strt , \a sttoopp , \a stteepp ).
5999  * This method works only if \a this is allocated and single component. If not an exception will be thrown.
6000  *
6001  * \param [out] strt - the start of the range (included) if true is returned.
6002  * \param [out] sttoopp - the end of the range (not included) if true is returned.
6003  * \param [out] stteepp - the step of the range if true is returned.
6004  * \return the verdict of the check.
6005  *
6006  * \sa DataArray::GetNumberOfItemGivenBES
6007  */
6008 bool DataArrayInt::isRange(int& strt, int& sttoopp, int& stteepp) const
6009 {
6010   checkAllocated();
6011   if(getNumberOfComponents()!=1)
6012     throw INTERP_KERNEL::Exception("DataArrayInt::isRange : this must be single component array !");
6013   int nbTuples(getNumberOfTuples());
6014   if(nbTuples==0)
6015     { strt=0; sttoopp=0; stteepp=1; return true; }
6016   const int *pt(begin());
6017   strt=*pt; 
6018   if(nbTuples==1)
6019     { sttoopp=strt+1; stteepp=1; return true; }
6020   strt=*pt; sttoopp=pt[nbTuples-1];
6021   if(strt==sttoopp)
6022     return false;
6023   if(sttoopp>strt)
6024     {
6025       sttoopp++;
6026       int a(sttoopp-1-strt),tmp(strt);
6027       if(a%(nbTuples-1)!=0)
6028         return false;
6029       stteepp=a/(nbTuples-1);
6030       for(int i=0;i<nbTuples;i++,tmp+=stteepp)
6031         if(pt[i]!=tmp)
6032           return false;
6033       return true;
6034     }
6035   else
6036     {
6037       sttoopp--;
6038       int a(strt-sttoopp-1),tmp(strt);
6039       if(a%(nbTuples-1)!=0)
6040         return false;
6041       stteepp=-(a/(nbTuples-1));
6042       for(int i=0;i<nbTuples;i++,tmp+=stteepp)
6043         if(pt[i]!=tmp)
6044           return false;
6045       return true;
6046     }
6047 }
6048
6049 /*!
6050  * Creates a one-dimensional DataArrayInt (\a res) whose contents are computed from 
6051  * values of \a this (\a a) and the given (\a indArr) arrays as follows:
6052  * \a res[ \a indArr[ \a a[ i ]]] = i. I.e. for each value in place i \a v = \a a[ i ],
6053  * new value in place \a indArr[ \a v ] is i.
6054  *  \param [in] indArrBg - the array holding indices within the result array to assign
6055  *         indices of values of \a this array pointing to values of \a indArrBg.
6056  *  \param [in] indArrEnd - specifies the end of the array \a indArrBg, so that
6057  *              the last value of \a indArrBg is \a indArrEnd[ -1 ].
6058  *  \return DataArrayInt * - the new instance of DataArrayInt.
6059  *          The caller is to delete this result array using decrRef() as it is no more
6060  *          needed.
6061  *  \throw If \a this->getNumberOfComponents() != 1.
6062  *  \throw If any value of \a this array is not a valid index for \a indArrBg array.
6063  *  \throw If any value of \a indArrBg is not a valid index for \a this array.
6064  */
6065 DataArrayInt *DataArrayInt::transformWithIndArrR(const int *indArrBg, const int *indArrEnd) const
6066 {
6067   checkAllocated();
6068   if(getNumberOfComponents()!=1)
6069     throw INTERP_KERNEL::Exception("Call transformWithIndArrR method on DataArrayInt with only one component, you can call 'rearrange' method before !");
6070   int nbElemsIn=(int)std::distance(indArrBg,indArrEnd);
6071   int nbOfTuples=getNumberOfTuples();
6072   const int *pt=getConstPointer();
6073   MCAuto<DataArrayInt> ret=DataArrayInt::New();
6074   ret->alloc(nbOfTuples,1);
6075   ret->fillWithValue(-1);
6076   int *tmp=ret->getPointer();
6077   for(int i=0;i<nbOfTuples;i++,pt++)
6078     {
6079       if(*pt>=0 && *pt<nbElemsIn)
6080         {
6081           int pos=indArrBg[*pt];
6082           if(pos>=0 && pos<nbOfTuples)
6083             tmp[pos]=i;
6084           else
6085             {
6086               std::ostringstream oss; oss << "DataArrayInt::transformWithIndArrR : error on tuple #" << i << " value of new pos is " << pos << " ( indArrBg[" << *pt << "]) ! Should be in [0," << nbOfTuples << ") !";
6087               throw INTERP_KERNEL::Exception(oss.str().c_str());
6088             }
6089         }
6090       else
6091         {
6092           std::ostringstream oss; oss << "DataArrayInt::transformWithIndArrR : error on tuple #" << i << " value is " << *pt << " and indirectionnal array as a size equal to " << nbElemsIn << " !";
6093           throw INTERP_KERNEL::Exception(oss.str().c_str());
6094         }
6095     }
6096   return ret.retn();
6097 }
6098
6099 /*!
6100  * Creates a one-dimensional DataArrayInt of given length, whose contents are computed
6101  * from values of \a this array, which is supposed to contain a renumbering map in 
6102  * "Old to New" mode. The result array contains a renumbering map in "New to Old" mode.
6103  * To know how to use the renumbering maps see \ref numbering.
6104  *  \param [in] newNbOfElem - the number of tuples in the result array.
6105  *  \return DataArrayInt * - the new instance of DataArrayInt.
6106  *          The caller is to delete this result array using decrRef() as it is no more
6107  *          needed.
6108  * 
6109  *  \if ENABLE_EXAMPLES
6110  *  \ref cpp_mcdataarrayint_invertarrayo2n2n2o "Here is a C++ example".<br>
6111  *  \ref py_mcdataarrayint_invertarrayo2n2n2o  "Here is a Python example".
6112  *  \endif
6113  */
6114 DataArrayInt *DataArrayInt::invertArrayO2N2N2O(int newNbOfElem) const
6115 {
6116   MCAuto<DataArrayInt> ret=DataArrayInt::New();
6117   ret->alloc(newNbOfElem,1);
6118   int nbOfOldNodes=getNumberOfTuples();
6119   const int *old2New=getConstPointer();
6120   int *pt=ret->getPointer();
6121   for(int i=0;i!=nbOfOldNodes;i++)
6122     {
6123       int newp(old2New[i]);
6124       if(newp!=-1)
6125         {
6126           if(newp>=0 && newp<newNbOfElem)
6127             pt[newp]=i;
6128           else
6129             {
6130               std::ostringstream oss; oss << "DataArrayInt::invertArrayO2N2N2O : At place #" << i << " the newplace is " << newp << " must be in [0," << newNbOfElem << ") !";
6131               throw INTERP_KERNEL::Exception(oss.str().c_str());
6132             }
6133         }
6134     }
6135   return ret.retn();
6136 }
6137
6138 /*!
6139  * This method is similar to DataArrayInt::invertArrayO2N2N2O except that 
6140  * 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]
6141  */
6142 DataArrayInt *DataArrayInt::invertArrayO2N2N2OBis(int newNbOfElem) const
6143 {
6144   MCAuto<DataArrayInt> ret=DataArrayInt::New();
6145   ret->alloc(newNbOfElem,1);
6146   int nbOfOldNodes=getNumberOfTuples();
6147   const int *old2New=getConstPointer();
6148   int *pt=ret->getPointer();
6149   for(int i=nbOfOldNodes-1;i>=0;i--)
6150     {
6151       int newp(old2New[i]);
6152       if(newp!=-1)
6153         {
6154           if(newp>=0 && newp<newNbOfElem)
6155             pt[newp]=i;
6156           else
6157             {
6158               std::ostringstream oss; oss << "DataArrayInt::invertArrayO2N2N2OBis : At place #" << i << " the newplace is " << newp << " must be in [0," << newNbOfElem << ") !";
6159               throw INTERP_KERNEL::Exception(oss.str().c_str());
6160             }
6161         }
6162     }
6163   return ret.retn();
6164 }
6165
6166 /*!
6167  * Creates a one-dimensional DataArrayInt of given length, whose contents are computed
6168  * from values of \a this array, which is supposed to contain a renumbering map in 
6169  * "New to Old" mode. The result array contains a renumbering map in "Old to New" mode.
6170  * To know how to use the renumbering maps see \ref numbering.
6171  *  \param [in] newNbOfElem - the number of tuples in the result array.
6172  *  \return DataArrayInt * - the new instance of DataArrayInt.
6173  *          The caller is to delete this result array using decrRef() as it is no more
6174  *          needed.
6175  * 
6176  *  \if ENABLE_EXAMPLES
6177  *  \ref cpp_mcdataarrayint_invertarrayn2o2o2n "Here is a C++ example".
6178  *
6179  *  \ref py_mcdataarrayint_invertarrayn2o2o2n "Here is a Python example".
6180  *  \endif
6181  */
6182 DataArrayInt *DataArrayInt::invertArrayN2O2O2N(int oldNbOfElem) const
6183 {
6184   checkAllocated();
6185   MCAuto<DataArrayInt> ret=DataArrayInt::New();
6186   ret->alloc(oldNbOfElem,1);
6187   const int *new2Old=getConstPointer();
6188   int *pt=ret->getPointer();
6189   std::fill(pt,pt+oldNbOfElem,-1);
6190   int nbOfNewElems=getNumberOfTuples();
6191   for(int i=0;i<nbOfNewElems;i++)
6192     {
6193       int v(new2Old[i]);
6194       if(v>=0 && v<oldNbOfElem)
6195         pt[v]=i;
6196       else
6197         {
6198           std::ostringstream oss; oss << "DataArrayInt::invertArrayN2O2O2N : in new id #" << i << " old value is " << v << " expected to be in [0," << oldNbOfElem << ") !";
6199           throw INTERP_KERNEL::Exception(oss.str().c_str());
6200         }
6201     }
6202   return ret.retn();
6203 }
6204
6205 /*!
6206  * Equivalent to DataArrayInt::isEqual except that if false the reason of
6207  * mismatch is given.
6208  * 
6209  * \param [in] other the instance to be compared with \a this
6210  * \param [out] reason In case of inequality returns the reason.
6211  * \sa DataArrayInt::isEqual
6212  */
6213 bool DataArrayInt::isEqualIfNotWhy(const DataArrayInt& other, std::string& reason) const
6214 {
6215   if(!areInfoEqualsIfNotWhy(other,reason))
6216     return false;
6217   return _mem.isEqual(other._mem,0,reason);
6218 }
6219
6220 /*!
6221  * Checks if \a this and another DataArrayInt are fully equal. For more info see
6222  * \ref MEDCouplingArrayBasicsCompare.
6223  *  \param [in] other - an instance of DataArrayInt to compare with \a this one.
6224  *  \return bool - \a true if the two arrays are equal, \a false else.
6225  */
6226 bool DataArrayInt::isEqual(const DataArrayInt& other) const
6227 {
6228   std::string tmp;
6229   return isEqualIfNotWhy(other,tmp);
6230 }
6231
6232 /*!
6233  * Checks if values of \a this and another DataArrayInt are equal. For more info see
6234  * \ref MEDCouplingArrayBasicsCompare.
6235  *  \param [in] other - an instance of DataArrayInt to compare with \a this one.
6236  *  \return bool - \a true if the values of two arrays are equal, \a false else.
6237  */
6238 bool DataArrayInt::isEqualWithoutConsideringStr(const DataArrayInt& other) const
6239 {
6240   std::string tmp;
6241   return _mem.isEqual(other._mem,0,tmp);
6242 }
6243
6244 /*!
6245  * Checks if values of \a this and another DataArrayInt are equal. Comparison is
6246  * performed on sorted value sequences.
6247  * For more info see\ref MEDCouplingArrayBasicsCompare.
6248  *  \param [in] other - an instance of DataArrayInt to compare with \a this one.
6249  *  \return bool - \a true if the sorted values of two arrays are equal, \a false else.
6250  */
6251 bool DataArrayInt::isEqualWithoutConsideringStrAndOrder(const DataArrayInt& other) const
6252 {
6253   MCAuto<DataArrayInt> a=deepCopy();
6254   MCAuto<DataArrayInt> b=other.deepCopy();
6255   a->sort();
6256   b->sort();
6257   return a->isEqualWithoutConsideringStr(*b);
6258 }
6259
6260 /*!
6261  * This method compares content of input vector \a v and \a this.
6262  * If for each id in \a this v[id]==True and for all other ids id2 not in \a this v[id2]==False, true is returned.
6263  * For performance reasons \a this is expected to be sorted ascendingly. If not an exception will be thrown.
6264  *
6265  * \param [in] v - the vector of 'flags' to be compared with \a this.
6266  *
6267  * \throw If \a this is not sorted ascendingly.
6268  * \throw If \a this has not exactly one component.
6269  * \throw If \a this is not allocated.
6270  */
6271 bool DataArrayInt::isFittingWith(const std::vector<bool>& v) const
6272 {
6273   checkAllocated();
6274   if(getNumberOfComponents()!=1)
6275     throw INTERP_KERNEL::Exception("DataArrayInt::isFittingWith : number of components of this should be equal to one !");
6276   const int *w(begin()),*end2(end());
6277   int refVal=-std::numeric_limits<int>::max();
6278   int i=0;
6279   std::vector<bool>::const_iterator it(v.begin());
6280   for(;it!=v.end();it++,i++)
6281     {
6282       if(*it)
6283         {
6284           if(w!=end2)
6285             {
6286               if(*w++==i)
6287                 {
6288                   if(i>refVal)
6289                     refVal=i;
6290                   else
6291                     {
6292                       std::ostringstream oss; oss << "DataArrayInt::isFittingWith : At pos #" << std::distance(begin(),w-1) << " this is not sorted ascendingly !";
6293                       throw INTERP_KERNEL::Exception(oss.str().c_str());
6294                     }
6295                 }
6296               else
6297                 return false;
6298             }
6299           else
6300             return false;
6301         }
6302     }
6303   return w==end2;
6304 }
6305
6306 /*!
6307  * This method assumes that \a this has one component and is allocated. This method scans all tuples in \a this and for all tuple equal to \a val
6308  * put True to the corresponding entry in \a vec.
6309  * \a vec is expected to be with the same size than the number of tuples of \a this.
6310  *
6311  *  \sa DataArrayInt::switchOnTupleNotEqualTo.
6312  */
6313 void DataArrayInt::switchOnTupleEqualTo(int val, std::vector<bool>& vec) const
6314 {
6315   checkAllocated();
6316   if(getNumberOfComponents()!=1)
6317     throw INTERP_KERNEL::Exception("DataArrayInt::switchOnTupleEqualTo : number of components of this should be equal to one !");
6318   int nbOfTuples(getNumberOfTuples());
6319   if(nbOfTuples!=(int)vec.size())
6320     throw INTERP_KERNEL::Exception("DataArrayInt::switchOnTupleEqualTo : number of tuples of this should be equal to size of input vector of bool !");
6321   const int *pt(begin());
6322   for(int i=0;i<nbOfTuples;i++)
6323     if(pt[i]==val)
6324       vec[i]=true;
6325 }
6326
6327 /*!
6328  * This method assumes that \a this has one component and is allocated. This method scans all tuples in \a this and for all tuple different from \a val
6329  * put True to the corresponding entry in \a vec.
6330  * \a vec is expected to be with the same size than the number of tuples of \a this.
6331  * 
6332  *  \sa DataArrayInt::switchOnTupleEqualTo.
6333  */
6334 void DataArrayInt::switchOnTupleNotEqualTo(int val, std::vector<bool>& vec) const
6335 {
6336   checkAllocated();
6337   if(getNumberOfComponents()!=1)
6338     throw INTERP_KERNEL::Exception("DataArrayInt::switchOnTupleNotEqualTo : number of components of this should be equal to one !");
6339   int nbOfTuples(getNumberOfTuples());
6340   if(nbOfTuples!=(int)vec.size())
6341     throw INTERP_KERNEL::Exception("DataArrayInt::switchOnTupleNotEqualTo : number of tuples of this should be equal to size of input vector of bool !");
6342   const int *pt(begin());
6343   for(int i=0;i<nbOfTuples;i++)
6344     if(pt[i]!=val)
6345       vec[i]=true;
6346 }
6347
6348 /*!
6349  * Computes for each tuple the sum of number of components values in the tuple and return it.
6350  * 
6351  * \return DataArrayInt * - the new instance of DataArrayInt containing the
6352  *          same number of tuples as \a this array and one component.
6353  *          The caller is to delete this result array using decrRef() as it is no more
6354  *          needed.
6355  *  \throw If \a this is not allocated.
6356  */
6357 DataArrayInt *DataArrayInt::sumPerTuple() const
6358 {
6359   checkAllocated();
6360   int nbOfComp(getNumberOfComponents()),nbOfTuple(getNumberOfTuples());
6361   MCAuto<DataArrayInt> ret(DataArrayInt::New());
6362   ret->alloc(nbOfTuple,1);
6363   const int *src(getConstPointer());
6364   int *dest(ret->getPointer());
6365   for(int i=0;i<nbOfTuple;i++,dest++,src+=nbOfComp)
6366     *dest=std::accumulate(src,src+nbOfComp,0);
6367   return ret.retn();
6368 }
6369
6370 /*!
6371  * Checks that \a this array is consistently **increasing** or **decreasing** in value.
6372  * If not an exception is thrown.
6373  *  \param [in] increasing - if \a true, the array values should be increasing.
6374  *  \throw If sequence of values is not strictly monotonic in agreement with \a
6375  *         increasing arg.
6376  *  \throw If \a this->getNumberOfComponents() != 1.
6377  *  \throw If \a this is not allocated.
6378  */
6379 void DataArrayInt::checkMonotonic(bool increasing) const
6380 {
6381   if(!isMonotonic(increasing))
6382     {
6383       if (increasing)
6384         throw INTERP_KERNEL::Exception("DataArrayInt::checkMonotonic : 'this' is not INCREASING monotonic !");
6385       else
6386         throw INTERP_KERNEL::Exception("DataArrayInt::checkMonotonic : 'this' is not DECREASING monotonic !");
6387     }
6388 }
6389
6390 /*!
6391  * Checks that \a this array is consistently **increasing** or **decreasing** in value.
6392  *  \param [in] increasing - if \a true, array values should be increasing.
6393  *  \return bool - \a true if values change in accordance with \a increasing arg.
6394  *  \throw If \a this->getNumberOfComponents() != 1.
6395  *  \throw If \a this is not allocated.
6396  */
6397 bool DataArrayInt::isMonotonic(bool increasing) const
6398 {
6399   checkAllocated();
6400   if(getNumberOfComponents()!=1)
6401     throw INTERP_KERNEL::Exception("DataArrayInt::isMonotonic : only supported with 'this' array with ONE component !");
6402   int nbOfElements=getNumberOfTuples();
6403   const int *ptr=getConstPointer();
6404   if(nbOfElements==0)
6405     return true;
6406   int ref=ptr[0];
6407   if(increasing)
6408     {
6409       for(int i=1;i<nbOfElements;i++)
6410         {
6411           if(ptr[i]>=ref)
6412             ref=ptr[i];
6413           else
6414             return false;
6415         }
6416     }
6417   else
6418     {
6419       for(int i=1;i<nbOfElements;i++)
6420         {
6421           if(ptr[i]<=ref)
6422             ref=ptr[i];
6423           else
6424             return false;
6425         }
6426     }
6427   return true;
6428 }
6429
6430 /*!
6431  * This method check that array consistently INCREASING or DECREASING in value.
6432  */
6433 bool DataArrayInt::isStrictlyMonotonic(bool increasing) const
6434 {
6435   checkAllocated();
6436   if(getNumberOfComponents()!=1)
6437     throw INTERP_KERNEL::Exception("DataArrayInt::isStrictlyMonotonic : only supported with 'this' array with ONE component !");
6438   int nbOfElements=getNumberOfTuples();
6439   const int *ptr=getConstPointer();
6440   if(nbOfElements==0)
6441     return true;
6442   int ref=ptr[0];
6443   if(increasing)
6444     {
6445       for(int i=1;i<nbOfElements;i++)
6446         {
6447           if(ptr[i]>ref)
6448             ref=ptr[i];
6449           else
6450             return false;
6451         }
6452     }
6453   else
6454     {
6455       for(int i=1;i<nbOfElements;i++)
6456         {
6457           if(ptr[i]<ref)
6458             ref=ptr[i];
6459           else
6460             return false;
6461         }
6462     }
6463   return true;
6464 }
6465
6466 /*!
6467  * This method check that array consistently INCREASING or DECREASING in value.
6468  */
6469 void DataArrayInt::checkStrictlyMonotonic(bool increasing) const
6470 {
6471   if(!isStrictlyMonotonic(increasing))
6472     {
6473       if (increasing)
6474         throw INTERP_KERNEL::Exception("DataArrayInt::checkStrictlyMonotonic : 'this' is not strictly INCREASING monotonic !");
6475       else
6476         throw INTERP_KERNEL::Exception("DataArrayInt::checkStrictlyMonotonic : 'this' is not strictly DECREASING monotonic !");
6477     }
6478 }
6479
6480 /*!
6481  * Creates a new one-dimensional DataArrayInt of the same size as \a this and a given
6482  * one-dimensional arrays that must be of the same length. The result array describes
6483  * correspondence between \a this and \a other arrays, so that 
6484  * <em> other.getIJ(i,0) == this->getIJ(ret->getIJ(i),0)</em>. If such a permutation is
6485  * not possible because some element in \a other is not in \a this, an exception is thrown.
6486  *  \param [in] other - an array to compute permutation to.
6487  *  \return DataArrayInt * - a new instance of DataArrayInt, which is a permutation array
6488  * from \a this to \a other. The caller is to delete this array using decrRef() as it is
6489  * no more needed.
6490  *  \throw If \a this->getNumberOfComponents() != 1.
6491  *  \throw If \a other->getNumberOfComponents() != 1.
6492  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples().
6493  *  \throw If \a other includes a value which is not in \a this array.
6494  * 
6495  *  \if ENABLE_EXAMPLES
6496  *  \ref cpp_mcdataarrayint_buildpermutationarr "Here is a C++ example".
6497  *
6498  *  \ref py_mcdataarrayint_buildpermutationarr "Here is a Python example".
6499  *  \endif
6500  */
6501 DataArrayInt *DataArrayInt::buildPermutationArr(const DataArrayInt& other) const
6502 {
6503   checkAllocated();
6504   if(getNumberOfComponents()!=1 || other.getNumberOfComponents()!=1)
6505     throw INTERP_KERNEL::Exception("DataArrayInt::buildPermutationArr : 'this' and 'other' have to have exactly ONE component !");
6506   int nbTuple=getNumberOfTuples();
6507   other.checkAllocated();
6508   if(nbTuple!=other.getNumberOfTuples())
6509     throw INTERP_KERNEL::Exception("DataArrayInt::buildPermutationArr : 'this' and 'other' must have the same number of tuple !");
6510   MCAuto<DataArrayInt> ret=DataArrayInt::New();
6511   ret->alloc(nbTuple,1);
6512   ret->fillWithValue(-1);
6513   const int *pt=getConstPointer();
6514   std::map<int,int> mm;
6515   for(int i=0;i<nbTuple;i++)
6516     mm[pt[i]]=i;
6517   pt=other.getConstPointer();
6518   int *retToFill=ret->getPointer();
6519   for(int i=0;i<nbTuple;i++)
6520     {
6521       std::map<int,int>::const_iterator it=mm.find(pt[i]);
6522       if(it==mm.end())
6523         {
6524           std::ostringstream oss; oss << "DataArrayInt::buildPermutationArr : Arrays mismatch : element (" << pt[i] << ") in 'other' not findable in 'this' !";
6525           throw INTERP_KERNEL::Exception(oss.str().c_str());
6526         }
6527       retToFill[i]=(*it).second;
6528     }
6529   return ret.retn();
6530 }
6531
6532 void DataArrayInt::aggregate(const DataArrayInt *other)
6533 {
6534   if(!other)
6535     throw INTERP_KERNEL::Exception("DataArrayInt::aggregate : null pointer !");
6536   if(getNumberOfComponents()!=other->getNumberOfComponents())
6537     throw INTERP_KERNEL::Exception("DataArrayInt::aggregate : mismatch number of components !");
6538   _mem.insertAtTheEnd(other->begin(),other->end());
6539 }
6540
6541 /*!
6542  * Returns a new DataArrayInt holding the same values as \a this array but differently
6543  * arranged in memory. If \a this array holds 2 components of 3 values:
6544  * \f$ x_0,x_1,x_2,y_0,y_1,y_2 \f$, then the result array holds these values arranged
6545  * as follows: \f$ x_0,y_0,x_1,y_1,x_2,y_2 \f$.
6546  *  \warning Do not confuse this method with transpose()!
6547  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
6548  *          is to delete using decrRef() as it is no more needed.
6549  *  \throw If \a this is not allocated.
6550  */
6551 DataArrayInt *DataArrayInt::fromNoInterlace() const
6552 {
6553   checkAllocated();
6554   if(_mem.isNull())
6555     throw INTERP_KERNEL::Exception("DataArrayInt::fromNoInterlace : Not defined array !");
6556   int *tab=_mem.fromNoInterlace(getNumberOfComponents());
6557   DataArrayInt *ret=DataArrayInt::New();
6558   ret->useArray(tab,true,C_DEALLOC,getNumberOfTuples(),getNumberOfComponents());
6559   return ret;
6560 }
6561
6562 /*!
6563  * Returns a new DataArrayInt holding the same values as \a this array but differently
6564  * arranged in memory. If \a this array holds 2 components of 3 values:
6565  * \f$ x_0,y_0,x_1,y_1,x_2,y_2 \f$, then the result array holds these values arranged
6566  * as follows: \f$ x_0,x_1,x_2,y_0,y_1,y_2 \f$.
6567  *  \warning Do not confuse this method with transpose()!
6568  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
6569  *          is to delete using decrRef() as it is no more needed.
6570  *  \throw If \a this is not allocated.
6571  */
6572 DataArrayInt *DataArrayInt::toNoInterlace() const
6573 {
6574   checkAllocated();
6575   if(_mem.isNull())
6576     throw INTERP_KERNEL::Exception("DataArrayInt::toNoInterlace : Not defined array !");
6577   int *tab=_mem.toNoInterlace(getNumberOfComponents());
6578   DataArrayInt *ret=DataArrayInt::New();
6579   ret->useArray(tab,true,C_DEALLOC,getNumberOfTuples(),getNumberOfComponents());
6580   return ret;
6581 }
6582
6583 /*!
6584  * Returns a copy of \a this array with values permuted as required by \a new2Old array.
6585  * The values are permuted so that  \c new[ i ] = \c old[ \a new2Old[ i ]]. Number of
6586  * tuples in the result array remains the same as in \c this one.
6587  * If a permutation reduction is needed, subArray() or selectByTupleId() should be used.
6588  * For more info on renumbering see \ref numbering.
6589  *  \param [in] new2Old - C array of length equal to \a this->getNumberOfTuples()
6590  *     giving a previous position of i-th new value.
6591  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
6592  *          is to delete using decrRef() as it is no more needed.
6593  */
6594 DataArrayInt *DataArrayInt::renumberR(const int *new2Old) const
6595 {
6596   checkAllocated();
6597   int nbTuples=getNumberOfTuples();
6598   int nbOfCompo=getNumberOfComponents();
6599   MCAuto<DataArrayInt> ret=DataArrayInt::New();
6600   ret->alloc(nbTuples,nbOfCompo);
6601   ret->copyStringInfoFrom(*this);
6602   const int *iptr=getConstPointer();
6603   int *optr=ret->getPointer();
6604   for(int i=0;i<nbTuples;i++)
6605     std::copy(iptr+nbOfCompo*new2Old[i],iptr+nbOfCompo*(new2Old[i]+1),optr+nbOfCompo*i);
6606   ret->copyStringInfoFrom(*this);
6607   return ret.retn();
6608 }
6609
6610 /*!
6611  * Returns a shorten and permuted copy of \a this array. The new DataArrayInt is
6612  * of size \a newNbOfTuple and it's values are permuted as required by \a old2New array.
6613  * The values are permuted so that  \c new[ \a old2New[ i ]] = \c old[ i ] for all
6614  * \a old2New[ i ] >= 0. In other words every i-th tuple in \a this array, for which 
6615  * \a old2New[ i ] is negative, is missing from the result array.
6616  * For more info on renumbering see \ref numbering.
6617  *  \param [in] old2New - C array of length equal to \a this->getNumberOfTuples()
6618  *     giving a new position for i-th old tuple and giving negative position for
6619  *     for i-th old tuple that should be omitted.
6620  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
6621  *          is to delete using decrRef() as it is no more needed.
6622  */
6623 DataArrayInt *DataArrayInt::renumberAndReduce(const int *old2New, int newNbOfTuple) const
6624 {
6625   checkAllocated();
6626   int nbTuples=getNumberOfTuples();
6627   int nbOfCompo=getNumberOfComponents();
6628   MCAuto<DataArrayInt> ret=DataArrayInt::New();
6629   ret->alloc(newNbOfTuple,nbOfCompo);
6630   const int *iptr=getConstPointer();
6631   int *optr=ret->getPointer();
6632   for(int i=0;i<nbTuples;i++)
6633     {
6634       int w=old2New[i];
6635       if(w>=0)
6636         std::copy(iptr+i*nbOfCompo,iptr+(i+1)*nbOfCompo,optr+w*nbOfCompo);
6637     }
6638   ret->copyStringInfoFrom(*this);
6639   return ret.retn();
6640 }
6641
6642 /*!
6643  * Returns a shorten and permuted copy of \a this array. The new DataArrayInt is
6644  * of size \a new2OldEnd - \a new2OldBg and it's values are permuted as required by
6645  * \a new2OldBg array.
6646  * The values are permuted so that  \c new[ i ] = \c old[ \a new2OldBg[ i ]].
6647  * This method is equivalent to renumberAndReduce() except that convention in input is
6648  * \c new2old and \b not \c old2new.
6649  * For more info on renumbering see \ref numbering.
6650  *  \param [in] new2OldBg - pointer to the beginning of a permutation array that gives a
6651  *              tuple index in \a this array to fill the i-th tuple in the new array.
6652  *  \param [in] new2OldEnd - specifies the end of the permutation array that starts at
6653  *              \a new2OldBg, so that pointer to a tuple index (\a pi) varies as this:
6654  *              \a new2OldBg <= \a pi < \a new2OldEnd.
6655  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
6656  *          is to delete using decrRef() as it is no more needed.
6657  */
6658 DataArrayInt *DataArrayInt::selectByTupleId(const int *new2OldBg, const int *new2OldEnd) const
6659 {
6660   checkAllocated();
6661   MCAuto<DataArrayInt> ret=DataArrayInt::New();
6662   int nbComp=getNumberOfComponents();
6663   ret->alloc((int)std::distance(new2OldBg,new2OldEnd),nbComp);
6664   ret->copyStringInfoFrom(*this);
6665   int *pt=ret->getPointer();
6666   const int *srcPt=getConstPointer();
6667   int i=0;
6668   for(const int *w=new2OldBg;w!=new2OldEnd;w++,i++)
6669     std::copy(srcPt+(*w)*nbComp,srcPt+((*w)+1)*nbComp,pt+i*nbComp);
6670   ret->copyStringInfoFrom(*this);
6671   return ret.retn();
6672 }
6673
6674 /*!
6675  * Returns a shorten and permuted copy of \a this array. The new DataArrayInt is
6676  * of size \a new2OldEnd - \a new2OldBg and it's values are permuted as required by
6677  * \a new2OldBg array.
6678  * The values are permuted so that  \c new[ i ] = \c old[ \a new2OldBg[ i ]].
6679  * This method is equivalent to renumberAndReduce() except that convention in input is
6680  * \c new2old and \b not \c old2new.
6681  * This method is equivalent to selectByTupleId() except that it prevents coping data
6682  * from behind the end of \a this array.
6683  * For more info on renumbering see \ref numbering.
6684  *  \param [in] new2OldBg - pointer to the beginning of a permutation array that gives a
6685  *              tuple index in \a this array to fill the i-th tuple in the new array.
6686  *  \param [in] new2OldEnd - specifies the end of the permutation array that starts at
6687  *              \a new2OldBg, so that pointer to a tuple index (\a pi) varies as this:
6688  *              \a new2OldBg <= \a pi < \a new2OldEnd.
6689  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
6690  *          is to delete using decrRef() as it is no more needed.
6691  *  \throw If \a new2OldEnd - \a new2OldBg > \a this->getNumberOfTuples().
6692  */
6693 DataArrayInt *DataArrayInt::selectByTupleIdSafe(const int *new2OldBg, const int *new2OldEnd) const
6694 {
6695   checkAllocated();
6696   MCAuto<DataArrayInt> ret=DataArrayInt::New();
6697   int nbComp=getNumberOfComponents();
6698   int oldNbOfTuples=getNumberOfTuples();
6699   ret->alloc((int)std::distance(new2OldBg,new2OldEnd),nbComp);
6700   ret->copyStringInfoFrom(*this);
6701   int *pt=ret->getPointer();
6702   const int *srcPt=getConstPointer();
6703   int i=0;
6704   for(const int *w=new2OldBg;w!=new2OldEnd;w++,i++)
6705     if(*w>=0 && *w<oldNbOfTuples)
6706       std::copy(srcPt+(*w)*nbComp,srcPt+((*w)+1)*nbComp,pt+i*nbComp);
6707     else
6708       throw INTERP_KERNEL::Exception("DataArrayInt::selectByTupleIdSafe : some ids has been detected to be out of [0,this->getNumberOfTuples) !");
6709   ret->copyStringInfoFrom(*this);
6710   return ret.retn();
6711 }
6712
6713 /*!
6714  * Returns a shorten copy of \a this array. The new DataArrayInt contains every
6715  * (\a bg + \c i * \a step)-th tuple of \a this array located before the \a end2-th
6716  * tuple. Indices of the selected tuples are the same as ones returned by the Python
6717  * command \c range( \a bg, \a end2, \a step ).
6718  * This method is equivalent to selectByTupleIdSafe() except that the input array is
6719  * not constructed explicitly.
6720  * For more info on renumbering see \ref numbering.
6721  *  \param [in] bg - index of the first tuple to copy from \a this array.
6722  *  \param [in] end2 - index of the tuple before which the tuples to copy are located.
6723  *  \param [in] step - index increment to get index of the next tuple to copy.
6724  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
6725  *          is to delete using decrRef() as it is no more needed.
6726  *  \sa DataArrayInt::subArray.
6727  */
6728 DataArrayInt *DataArrayInt::selectByTupleIdSafeSlice(int bg, int end2, int step) const
6729 {
6730   checkAllocated();
6731   MCAuto<DataArrayInt> ret=DataArrayInt::New();
6732   int nbComp=getNumberOfComponents();
6733   int newNbOfTuples=GetNumberOfItemGivenBESRelative(bg,end2,step,"DataArrayInt::selectByTupleIdSafeSlice : ");
6734   ret->alloc(newNbOfTuples,nbComp);
6735   int *pt=ret->getPointer();
6736   const int *srcPt=getConstPointer()+bg*nbComp;
6737   for(int i=0;i<newNbOfTuples;i++,srcPt+=step*nbComp)
6738     std::copy(srcPt,srcPt+nbComp,pt+i*nbComp);
6739   ret->copyStringInfoFrom(*this);
6740   return ret.retn();
6741 }
6742
6743 /*!
6744  * Returns a shorten copy of \a this array. The new DataArrayInt contains ranges
6745  * of tuples specified by \a ranges parameter.
6746  * For more info on renumbering see \ref numbering.
6747  *  \param [in] ranges - std::vector of std::pair's each of which defines a range
6748  *              of tuples in [\c begin,\c end) format.
6749  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
6750  *          is to delete using decrRef() as it is no more needed.
6751  *  \throw If \a end < \a begin.
6752  *  \throw If \a end > \a this->getNumberOfTuples().
6753  *  \throw If \a this is not allocated.
6754  */
6755 DataArray *DataArrayInt::selectByTupleRanges(const std::vector<std::pair<int,int> >& ranges) const
6756 {
6757   checkAllocated();
6758   int nbOfComp=getNumberOfComponents();
6759   int nbOfTuplesThis=getNumberOfTuples();
6760   if(ranges.empty())
6761     {
6762       MCAuto<DataArrayInt> ret=DataArrayInt::New();
6763       ret->alloc(0,nbOfComp);
6764       ret->copyStringInfoFrom(*this);
6765       return ret.retn();
6766     }
6767   int ref=ranges.front().first;
6768   int nbOfTuples=0;
6769   bool isIncreasing=true;
6770   for(std::vector<std::pair<int,int> >::const_iterator it=ranges.begin();it!=ranges.end();it++)
6771     {
6772       if((*it).first<=(*it).second)
6773         {
6774           if((*it).first>=0 && (*it).second<=nbOfTuplesThis)
6775             {
6776               nbOfTuples+=(*it).second-(*it).first;
6777               if(isIncreasing)
6778                 isIncreasing=ref<=(*it).first;
6779               ref=(*it).second;
6780             }
6781           else
6782             {
6783               std::ostringstream oss; oss << "DataArrayInt::selectByTupleRanges : on range #" << std::distance(ranges.begin(),it);
6784               oss << " (" << (*it).first << "," << (*it).second << ") is greater than number of tuples of this :" << nbOfTuples << " !";
6785               throw INTERP_KERNEL::Exception(oss.str().c_str());
6786             }
6787         }
6788       else
6789         {
6790           std::ostringstream oss; oss << "DataArrayInt::selectByTupleRanges : on range #" << std::distance(ranges.begin(),it);
6791           oss << " (" << (*it).first << "," << (*it).second << ") end is before begin !";
6792           throw INTERP_KERNEL::Exception(oss.str().c_str());
6793         }
6794     }
6795   if(isIncreasing && nbOfTuplesThis==nbOfTuples)
6796     return deepCopy();
6797   MCAuto<DataArrayInt> ret=DataArrayInt::New();
6798   ret->alloc(nbOfTuples,nbOfComp);
6799   ret->copyStringInfoFrom(*this);
6800   const int *src=getConstPointer();
6801   int *work=ret->getPointer();
6802   for(std::vector<std::pair<int,int> >::const_iterator it=ranges.begin();it!=ranges.end();it++)
6803     work=std::copy(src+(*it).first*nbOfComp,src+(*it).second*nbOfComp,work);
6804   return ret.retn();
6805 }
6806
6807 /*!
6808  * Returns a new DataArrayInt containing a renumbering map in "Old to New" mode.
6809  * This map, if applied to \a this array, would make it sorted. For example, if
6810  * \a this array contents are [9,10,0,6,4,11,3,7] then the contents of the result array
6811  * are [5,6,0,3,2,7,1,4]; if this result array (\a res) is used as an argument in call
6812  * \a this->renumber(\a res) then the returned array contains [0,3,4,6,7,9,10,11].
6813  * This method is useful for renumbering (in MED file for example). For more info
6814  * on renumbering see \ref numbering.
6815  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
6816  *          array using decrRef() as it is no more needed.
6817  *  \throw If \a this is not allocated.
6818  *  \throw If \a this->getNumberOfComponents() != 1.
6819  *  \throw If there are equal values in \a this array.
6820  */
6821 DataArrayInt *DataArrayInt::checkAndPreparePermutation() const
6822 {
6823   checkAllocated();
6824   if(getNumberOfComponents()!=1)
6825     throw INTERP_KERNEL::Exception("DataArrayInt::checkAndPreparePermutation : number of components must == 1 !");
6826   int nbTuples=getNumberOfTuples();
6827   const int *pt=getConstPointer();
6828   int *pt2=CheckAndPreparePermutation(pt,pt+nbTuples);
6829   DataArrayInt *ret=DataArrayInt::New();
6830   ret->useArray(pt2,true,C_DEALLOC,nbTuples,1);
6831   return ret;
6832 }
6833
6834 /*!
6835  * This method tries to find the permutation to apply to the first input \a ids1 to obtain the same array (without considering strings informations) the second
6836  * input array \a ids2.
6837  * \a ids1 and \a ids2 are expected to be both a list of ids (both with number of components equal to one) not sorted and with values that can be negative.
6838  * This method will throw an exception is no such permutation array can be obtained. It is typically the case if there is some ids in \a ids1 not in \a ids2 or
6839  * inversely.
6840  * In case of success (no throw) : \c ids1->renumber(ret)->isEqual(ids2) where \a ret is the return of this method.
6841  *
6842  * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
6843  *          array using decrRef() as it is no more needed.
6844  * \throw If either ids1 or ids2 is null not allocated or not with one components.
6845  * 
6846  */
6847 DataArrayInt *DataArrayInt::FindPermutationFromFirstToSecond(const DataArrayInt *ids1, const DataArrayInt *ids2)
6848 {
6849   if(!ids1 || !ids2)
6850     throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two input arrays must be not null !");
6851   if(!ids1->isAllocated() || !ids2->isAllocated())
6852     throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two input arrays must be allocated !");
6853   if(ids1->getNumberOfComponents()!=1 || ids2->getNumberOfComponents()!=1)
6854     throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two input arrays have exactly one component !");
6855   if(ids1->getNumberOfTuples()!=ids2->getNumberOfTuples())
6856     {
6857       std::ostringstream oss; oss << "DataArrayInt::FindPermutationFromFirstToSecond : first array has " << ids1->getNumberOfTuples() << " tuples and the second one " << ids2->getNumberOfTuples() << " tuples ! No chance to find a permutation between the 2 arrays !";
6858       throw INTERP_KERNEL::Exception(oss.str().c_str());
6859     }
6860   MCAuto<DataArrayInt> p1(ids1->deepCopy());
6861   MCAuto<DataArrayInt> p2(ids2->deepCopy());
6862   p1->sort(true); p2->sort(true);
6863   if(!p1->isEqualWithoutConsideringStr(*p2))
6864     throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two arrays are not lying on same ids ! Impossible to find a permutation between the 2 arrays !");
6865   p1=ids1->checkAndPreparePermutation();
6866   p2=ids2->checkAndPreparePermutation();
6867   p2=p2->invertArrayO2N2N2O(p2->getNumberOfTuples());
6868   p2=p2->selectByTupleIdSafe(p1->begin(),p1->end());
6869   return p2.retn();
6870 }
6871
6872 /*!
6873  * Returns two arrays describing a surjective mapping from \a this set of values (\a A)
6874  * onto a set of values of size \a targetNb (\a B). The surjective function is 
6875  * \a B[ \a A[ i ]] = i. That is to say that for each \a id in [0,\a targetNb), where \a
6876  * targetNb < \a this->getNumberOfTuples(), there exists at least one tupleId (\a tid) so
6877  * that <em> this->getIJ( tid, 0 ) == id</em>. <br>
6878  * The first of out arrays returns indices of elements of \a this array, grouped by their
6879  * place in the set \a B. The second out array is the index of the first one; it shows how
6880  * many elements of \a A are mapped into each element of \a B. <br>
6881  * For more info on
6882  * mapping and its usage in renumbering see \ref numbering. <br>
6883  * \b Example:
6884  * - \a this: [0,3,2,3,2,2,1,2]
6885  * - \a targetNb: 4
6886  * - \a arr:  [0,  6,  2,4,5,7,  1,3]
6887  * - \a arrI: [0,1,2,6,8]
6888  *
6889  * This result means: <br>
6890  * the element of \a B 0 encounters within \a A once (\a arrI[ 0+1 ] - \a arrI[ 0 ]) and
6891  * its index within \a A is 0 ( \a arr[ 0:1 ] == \a arr[ \a arrI[ 0 ] : \a arrI[ 0+1 ]]);<br>
6892  * the element of \a B 2 encounters within \a A 4 times (\a arrI[ 2+1 ] - \a arrI[ 2 ]) and
6893  * its indices within \a A are [2,4,5,7] ( \a arr[ 2:6 ] == \a arr[ \a arrI[ 2 ] : 
6894  * \a arrI[ 2+1 ]]); <br> etc.
6895  *  \param [in] targetNb - the size of the set \a B. \a targetNb must be equal or more
6896  *         than the maximal value of \a A.
6897  *  \param [out] arr - a new instance of DataArrayInt returning indices of
6898  *         elements of \a this, grouped by their place in the set \a B. The caller is to delete
6899  *         this array using decrRef() as it is no more needed.
6900  *  \param [out] arrI - a new instance of DataArrayInt returning size of groups of equal
6901  *         elements of \a this. The caller is to delete this array using decrRef() as it
6902  *         is no more needed.
6903  *  \throw If \a this is not allocated.
6904  *  \throw If \a this->getNumberOfComponents() != 1.
6905  *  \throw If any value in \a this is more or equal to \a targetNb.
6906  */
6907 void DataArrayInt::changeSurjectiveFormat(int targetNb, DataArrayInt *&arr, DataArrayInt *&arrI) const
6908 {
6909   checkAllocated();
6910   if(getNumberOfComponents()!=1)
6911     throw INTERP_KERNEL::Exception("DataArrayInt::changeSurjectiveFormat : number of components must == 1 !");
6912   int nbOfTuples=getNumberOfTuples();
6913   MCAuto<DataArrayInt> ret(DataArrayInt::New());
6914   MCAuto<DataArrayInt> retI(DataArrayInt::New());
6915   retI->alloc(targetNb+1,1);
6916   const int *input=getConstPointer();
6917   std::vector< std::vector<int> > tmp(targetNb);
6918   for(int i=0;i<nbOfTuples;i++)
6919     {
6920       int tmp2=input[i];
6921       if(tmp2>=0 && tmp2<targetNb)
6922         tmp[tmp2].push_back(i);
6923       else
6924         {
6925           std::ostringstream oss; oss << "DataArrayInt::changeSurjectiveFormat : At pos " << i << " presence of element " << tmp2 << " ! should be in [0," << targetNb << ") !";
6926           throw INTERP_KERNEL::Exception(oss.str().c_str());
6927         }
6928     }
6929   int *retIPtr=retI->getPointer();
6930   *retIPtr=0;
6931   for(std::vector< std::vector<int> >::const_iterator it1=tmp.begin();it1!=tmp.end();it1++,retIPtr++)
6932     retIPtr[1]=retIPtr[0]+(int)((*it1).size());
6933   if(nbOfTuples!=retI->getIJ(targetNb,0))
6934     throw INTERP_KERNEL::Exception("DataArrayInt::changeSurjectiveFormat : big problem should never happen !");
6935   ret->alloc(nbOfTuples,1);
6936   int *retPtr=ret->getPointer();
6937   for(std::vector< std::vector<int> >::const_iterator it1=tmp.begin();it1!=tmp.end();it1++)
6938     retPtr=std::copy((*it1).begin(),(*it1).end(),retPtr);
6939   arr=ret.retn();
6940   arrI=retI.retn();
6941 }
6942
6943
6944 /*!
6945  * Returns a new DataArrayInt containing a renumbering map in "Old to New" mode computed
6946  * from a zip representation of a surjective format (returned e.g. by
6947  * \ref MEDCoupling::DataArrayDouble::findCommonTuples() "DataArrayDouble::findCommonTuples()"
6948  * for example). The result array minimizes the permutation. <br>
6949  * For more info on renumbering see \ref numbering. <br>
6950  * \b Example: <br>
6951  * - \a nbOfOldTuples: 10 
6952  * - \a arr          : [0,3, 5,7,9]
6953  * - \a arrIBg       : [0,2,5]
6954  * - \a newNbOfTuples: 7
6955  * - result array    : [0,1,2,0,3,4,5,4,6,4]
6956  *
6957  *  \param [in] nbOfOldTuples - number of tuples in the initial array \a arr.
6958  *  \param [in] arr - the array of tuple indices grouped by \a arrIBg array.
6959  *  \param [in] arrIBg - the array dividing all indices stored in \a arr into groups of
6960  *         (indices of) equal values. Its every element (except the last one) points to
6961  *         the first element of a group of equal values.
6962  *  \param [in] arrIEnd - specifies the end of \a arrIBg, so that the last element of \a
6963  *          arrIBg is \a arrIEnd[ -1 ].
6964  *  \param [out] newNbOfTuples - number of tuples after surjection application.
6965  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
6966  *          array using decrRef() as it is no more needed.
6967  *  \throw If any value of \a arr breaks condition ( 0 <= \a arr[ i ] < \a nbOfOldTuples ).
6968  */
6969 DataArrayInt *DataArrayInt::ConvertIndexArrayToO2N(int nbOfOldTuples, const int *arr, const int *arrIBg, const int *arrIEnd, int &newNbOfTuples)
6970 {
6971   MCAuto<DataArrayInt> ret=DataArrayInt::New();
6972   ret->alloc(nbOfOldTuples,1);
6973   int *pt=ret->getPointer();
6974   std::fill(pt,pt+nbOfOldTuples,-1);
6975   int nbOfGrps=((int)std::distance(arrIBg,arrIEnd))-1;
6976   const int *cIPtr=arrIBg;
6977   for(int i=0;i<nbOfGrps;i++)
6978     pt[arr[cIPtr[i]]]=-(i+2);
6979   int newNb=0;
6980   for(int iNode=0;iNode<nbOfOldTuples;iNode++)
6981     {
6982       if(pt[iNode]<0)
6983         {
6984           if(pt[iNode]==-1)
6985             pt[iNode]=newNb++;
6986           else
6987             {
6988               int grpId=-(pt[iNode]+2);
6989               for(int j=cIPtr[grpId];j<cIPtr[grpId+1];j++)
6990                 {
6991                   if(arr[j]>=0 && arr[j]<nbOfOldTuples)
6992                     pt[arr[j]]=newNb;
6993                   else
6994                     {
6995                       std::ostringstream oss; oss << "DataArrayInt::ConvertIndexArrayToO2N : With element #" << j << " value is " << arr[j] << " should be in [0," << nbOfOldTuples << ") !";
6996                       throw INTERP_KERNEL::Exception(oss.str().c_str());
6997                     }
6998                 }
6999               newNb++;
7000             }
7001         }
7002     }
7003   newNbOfTuples=newNb;
7004   return ret.retn();
7005 }
7006
7007 /*!
7008  * Returns a new DataArrayInt containing a renumbering map in "New to Old" mode,
7009  * which if applied to \a this array would make it sorted ascendingly.
7010  * For more info on renumbering see \ref numbering. <br>
7011  * \b Example: <br>
7012  * - \a this: [2,0,1,1,0,1,2,0,1,1,0,0]
7013  * - result: [10,0,5,6,1,7,11,2,8,9,3,4]
7014  * - after applying result to \a this: [0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2] 
7015  *
7016  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
7017  *          array using decrRef() as it is no more needed.
7018  *  \throw If \a this is not allocated.
7019  *  \throw If \a this->getNumberOfComponents() != 1.
7020  */
7021 DataArrayInt *DataArrayInt::buildPermArrPerLevel() const
7022 {
7023   checkAllocated();
7024   if(getNumberOfComponents()!=1)
7025     throw INTERP_KERNEL::Exception("DataArrayInt::buildPermArrPerLevel : number of components must == 1 !");
7026   int nbOfTuples=getNumberOfTuples();
7027   const int *pt=getConstPointer();
7028   std::map<int,int> m;
7029   MCAuto<DataArrayInt> ret=DataArrayInt::New();
7030   ret->alloc(nbOfTuples,1);
7031   int *opt=ret->getPointer();
7032   for(int i=0;i<nbOfTuples;i++,pt++,opt++)
7033     {
7034       int val=*pt;
7035       std::map<int,int>::iterator it=m.find(val);
7036       if(it!=m.end())
7037         {
7038           *opt=(*it).second;
7039           (*it).second++;
7040         }
7041       else
7042         {
7043           *opt=0;
7044           m.insert(std::pair<int,int>(val,1));
7045         }
7046     }
7047   int sum=0;
7048   for(std::map<int,int>::iterator it=m.begin();it!=m.end();it++)
7049     {
7050       int vt=(*it).second;
7051       (*it).second=sum;
7052       sum+=vt;
7053     }
7054   pt=getConstPointer();
7055   opt=ret->getPointer();
7056   for(int i=0;i<nbOfTuples;i++,pt++,opt++)
7057     *opt+=m[*pt];
7058   //
7059   return ret.retn();
7060 }
7061
7062 /*!
7063  * Checks if contents of \a this array are equal to that of an array filled with
7064  * iota(). This method is particularly useful for DataArrayInt instances that represent
7065  * a renumbering array to check the real need in renumbering. This method checks than \a this can be considered as an identity function
7066  * of a set having \a sizeExpected elements into itself.
7067  *
7068  *  \param [in] sizeExpected - The number of elements expected.
7069  *  \return bool - \a true if \a this array contents == \a range( \a this->getNumberOfTuples())
7070  *  \throw If \a this is not allocated.
7071  *  \throw If \a this->getNumberOfComponents() != 1.
7072  */
7073 bool DataArrayInt::isIota(int sizeExpected) const
7074 {
7075   checkAllocated();
7076   if(getNumberOfComponents()!=1)
7077     return false;
7078   int nbOfTuples(getNumberOfTuples());
7079   if(nbOfTuples!=sizeExpected)
7080     return false;
7081   const int *pt=getConstPointer();
7082   for(int i=0;i<nbOfTuples;i++,pt++)
7083     if(*pt!=i)
7084       return false;
7085   return true;
7086 }
7087
7088 /*!
7089  * Checks if all values in \a this array are equal to \a val.
7090  *  \param [in] val - value to check equality of array values to.
7091  *  \return bool - \a true if all values are \a val.
7092  *  \throw If \a this is not allocated.
7093  *  \throw If \a this->getNumberOfComponents() != 1
7094  */
7095 bool DataArrayInt::isUniform(int val) const
7096 {
7097   checkAllocated();
7098   if(getNumberOfComponents()!=1)
7099     throw INTERP_KERNEL::Exception("DataArrayInt::isUniform : must be applied on DataArrayInt with only one component, you can call 'rearrange' method before !");
7100   int nbOfTuples=getNumberOfTuples();
7101   const int *w=getConstPointer();
7102   const int *end2=w+nbOfTuples;
7103   for(;w!=end2;w++)
7104     if(*w!=val)
7105       return false;
7106   return true;
7107 }
7108
7109 /*!
7110  * Checks if all values in \a this array are unique.
7111  *  \return bool - \a true if condition above is true
7112  *  \throw If \a this is not allocated.
7113  *  \throw If \a this->getNumberOfComponents() != 1
7114  */
7115 bool DataArrayInt::hasUniqueValues() const
7116 {
7117   checkAllocated();
7118   if(getNumberOfComponents()!=1)
7119     throw INTERP_KERNEL::Exception("DataArrayInt::hasOnlyUniqueValues: must be applied on DataArrayInt with only one component, you can call 'rearrange' method before !");
7120   int nbOfTuples(getNumberOfTuples());
7121   std::set<int> s(begin(),end());  // in C++11, should use unordered_set (O(1) complexity)
7122   if (s.size() != nbOfTuples)
7123     return false;
7124   return true;
7125 }
7126
7127 /*!
7128  * Creates a new DataArrayDouble and assigns all (textual and numerical) data of \a this
7129  * array to the new one.
7130  *  \return DataArrayDouble * - the new instance of DataArrayInt.
7131  */
7132 DataArrayDouble *DataArrayInt::convertToDblArr() const
7133 {
7134   checkAllocated();
7135   DataArrayDouble *ret=DataArrayDouble::New();
7136   ret->alloc(getNumberOfTuples(),getNumberOfComponents());
7137   std::size_t nbOfVals=getNbOfElems();
7138   const int *src=getConstPointer();
7139   double *dest=ret->getPointer();
7140   std::copy(src,src+nbOfVals,dest);
7141   ret->copyStringInfoFrom(*this);
7142   return ret;
7143 }
7144
7145 /*!
7146  * Returns a shorten copy of \a this array. The new DataArrayInt contains all
7147  * tuples starting from the \a tupleIdBg-th tuple and including all tuples located before
7148  * the \a tupleIdEnd-th one. This methods has a similar behavior as std::string::substr().
7149  * This method is a specialization of selectByTupleIdSafeSlice().
7150  *  \param [in] tupleIdBg - index of the first tuple to copy from \a this array.
7151  *  \param [in] tupleIdEnd - index of the tuple before which the tuples to copy are located.
7152  *          If \a tupleIdEnd == -1, all the tuples till the end of \a this array are copied.
7153  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
7154  *          is to delete using decrRef() as it is no more needed.
7155  *  \throw If \a tupleIdBg < 0.
7156  *  \throw If \a tupleIdBg > \a this->getNumberOfTuples().
7157     \throw If \a tupleIdEnd != -1 && \a tupleIdEnd < \a this->getNumberOfTuples().
7158  *  \sa DataArrayInt::selectByTupleIdSafeSlice
7159  */
7160 DataArrayInt *DataArrayInt::subArray(int tupleIdBg, int tupleIdEnd) const
7161 {
7162   checkAllocated();
7163   int nbt=getNumberOfTuples();
7164   if(tupleIdBg<0)
7165     throw INTERP_KERNEL::Exception("DataArrayInt::subArray : The tupleIdBg parameter must be greater than 0 !");
7166   if(tupleIdBg>nbt)
7167     throw INTERP_KERNEL::Exception("DataArrayInt::subArray : The tupleIdBg parameter is greater than number of tuples !");
7168   int trueEnd=tupleIdEnd;
7169   if(tupleIdEnd!=-1)
7170     {
7171       if(tupleIdEnd>nbt)
7172         throw INTERP_KERNEL::Exception("DataArrayInt::subArray : The tupleIdBg parameter is greater or equal than number of tuples !");
7173     }
7174   else
7175     trueEnd=nbt;
7176   int nbComp=getNumberOfComponents();
7177   MCAuto<DataArrayInt> ret=DataArrayInt::New();
7178   ret->alloc(trueEnd-tupleIdBg,nbComp);
7179   ret->copyStringInfoFrom(*this);
7180   std::copy(getConstPointer()+tupleIdBg*nbComp,getConstPointer()+trueEnd*nbComp,ret->getPointer());
7181   return ret.retn();
7182 }
7183
7184 /*!
7185  * Changes the number of components within \a this array so that its raw data **does
7186  * not** change, instead splitting this data into tuples changes.
7187  *  \warning This method erases all (name and unit) component info set before!
7188  *  \param [in] newNbOfComp - number of components for \a this array to have.
7189  *  \throw If \a this is not allocated
7190  *  \throw If getNbOfElems() % \a newNbOfCompo != 0.
7191  *  \throw If \a newNbOfCompo is lower than 1.
7192  *  \throw If the rearrange method would lead to a number of tuples higher than 2147483647 (maximal capacity of int32 !).
7193  *  \warning This method erases all (name and unit) component info set before!
7194  */
7195 void DataArrayInt::rearrange(int newNbOfCompo)
7196 {
7197   checkAllocated();
7198   if(newNbOfCompo<1)
7199     throw INTERP_KERNEL::Exception("DataArrayInt::rearrange : input newNbOfCompo must be > 0 !");
7200   std::size_t nbOfElems=getNbOfElems();
7201   if(nbOfElems%newNbOfCompo!=0)
7202     throw INTERP_KERNEL::Exception("DataArrayInt::rearrange : nbOfElems%newNbOfCompo!=0 !");
7203   if(nbOfElems/newNbOfCompo>(std::size_t)std::numeric_limits<int>::max())
7204     throw INTERP_KERNEL::Exception("DataArrayInt::rearrange : the rearrangement leads to too high number of tuples (> 2147483647) !");
7205   _info_on_compo.clear();
7206   _info_on_compo.resize(newNbOfCompo);
7207   declareAsNew();
7208 }
7209
7210 /*!
7211  * Changes the number of components within \a this array to be equal to its number
7212  * of tuples, and inversely its number of tuples to become equal to its number of 
7213  * components. So that its raw data **does not** change, instead splitting this
7214  * data into tuples changes.
7215  *  \warning This method erases all (name and unit) component info set before!
7216  *  \warning Do not confuse this method with fromNoInterlace() and toNoInterlace()!
7217  *  \throw If \a this is not allocated.
7218  *  \sa rearrange()
7219  */
7220 void DataArrayInt::transpose()
7221 {
7222   checkAllocated();
7223   int nbOfTuples=getNumberOfTuples();
7224   rearrange(nbOfTuples);
7225 }
7226
7227 /*!
7228  * Returns a shorten or extended copy of \a this array. If \a newNbOfComp is less
7229  * than \a this->getNumberOfComponents() then the result array is shorten as each tuple
7230  * is truncated to have \a newNbOfComp components, keeping first components. If \a
7231  * newNbOfComp is more than \a this->getNumberOfComponents() then the result array is
7232  * expanded as each tuple is populated with \a dftValue to have \a newNbOfComp
7233  * components.  
7234  *  \param [in] newNbOfComp - number of components for the new array to have.
7235  *  \param [in] dftValue - value assigned to new values added to the new array.
7236  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
7237  *          is to delete using decrRef() as it is no more needed.
7238  *  \throw If \a this is not allocated.
7239  */
7240 DataArrayInt *DataArrayInt::changeNbOfComponents(int newNbOfComp, int dftValue) const
7241 {
7242   checkAllocated();
7243   MCAuto<DataArrayInt> ret=DataArrayInt::New();
7244   ret->alloc(getNumberOfTuples(),newNbOfComp);
7245   const int *oldc=getConstPointer();
7246   int *nc=ret->getPointer();
7247   int nbOfTuples=getNumberOfTuples();
7248   int oldNbOfComp=getNumberOfComponents();
7249   int dim=std::min(oldNbOfComp,newNbOfComp);
7250   for(int i=0;i<nbOfTuples;i++)
7251     {
7252       int j=0;
7253       for(;j<dim;j++)
7254         nc[newNbOfComp*i+j]=oldc[i*oldNbOfComp+j];
7255       for(;j<newNbOfComp;j++)
7256         nc[newNbOfComp*i+j]=dftValue;
7257     }
7258   ret->setName(getName());
7259   for(int i=0;i<dim;i++)
7260     ret->setInfoOnComponent(i,getInfoOnComponent(i));
7261   ret->setName(getName());
7262   return ret.retn();
7263 }
7264
7265 /*!
7266  * Returns a copy of \a this array composed of selected components.
7267  * The new DataArrayInt has the same number of tuples but includes components
7268  * specified by \a compoIds parameter. So that getNbOfElems() of the result array
7269  * can be either less, same or more than \a this->getNbOfElems().
7270  *  \param [in] compoIds - sequence of zero based indices of components to include
7271  *              into the new array.
7272  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
7273  *          is to delete using decrRef() as it is no more needed.
7274  *  \throw If \a this is not allocated.
7275  *  \throw If a component index (\a i) is not valid: 
7276  *         \a i < 0 || \a i >= \a this->getNumberOfComponents().
7277  *
7278  *  \if ENABLE_EXAMPLES
7279  *  \ref py_mcdataarrayint_keepselectedcomponents "Here is a Python example".
7280  *  \endif
7281  */
7282 DataArrayInt *DataArrayInt::keepSelectedComponents(const std::vector<int>& compoIds) const
7283 {
7284   checkAllocated();
7285   MCAuto<DataArrayInt> ret(DataArrayInt::New());
7286   int newNbOfCompo=(int)compoIds.size();
7287   int oldNbOfCompo=getNumberOfComponents();
7288   for(std::vector<int>::const_iterator it=compoIds.begin();it!=compoIds.end();it++)
7289     DataArray::CheckValueInRange(oldNbOfCompo,(*it),"keepSelectedComponents invalid requested component");
7290   int nbOfTuples=getNumberOfTuples();
7291   ret->alloc(nbOfTuples,newNbOfCompo);
7292   ret->copyPartOfStringInfoFrom(*this,compoIds);
7293   const int *oldc=getConstPointer();
7294   int *nc=ret->getPointer();
7295   for(int i=0;i<nbOfTuples;i++)
7296     for(int j=0;j<newNbOfCompo;j++,nc++)
7297       *nc=oldc[i*oldNbOfCompo+compoIds[j]];
7298   return ret.retn();
7299 }
7300
7301 /*!
7302  * Appends components of another array to components of \a this one, tuple by tuple.
7303  * So that the number of tuples of \a this array remains the same and the number of 
7304  * components increases.
7305  *  \param [in] other - the DataArrayInt to append to \a this one.
7306  *  \throw If \a this is not allocated.
7307  *  \throw If \a this and \a other arrays have different number of tuples.
7308  *
7309  *  \if ENABLE_EXAMPLES
7310  *  \ref cpp_mcdataarrayint_meldwith "Here is a C++ example".
7311  *
7312  *  \ref py_mcdataarrayint_meldwith "Here is a Python example".
7313  *  \endif
7314  */
7315 void DataArrayInt::meldWith(const DataArrayInt *other)
7316 {
7317   if(!other)
7318     throw INTERP_KERNEL::Exception("DataArrayInt::meldWith : DataArrayInt pointer in input is NULL !");
7319   checkAllocated();
7320   other->checkAllocated();
7321   int nbOfTuples=getNumberOfTuples();
7322   if(nbOfTuples!=other->getNumberOfTuples())
7323     throw INTERP_KERNEL::Exception("DataArrayInt::meldWith : mismatch of number of tuples !");
7324   int nbOfComp1=getNumberOfComponents();
7325   int nbOfComp2=other->getNumberOfComponents();
7326   int *newArr=(int *)malloc(nbOfTuples*(nbOfComp1+nbOfComp2)*sizeof(int));
7327   int *w=newArr;
7328   const int *inp1=getConstPointer();
7329   const int *inp2=other->getConstPointer();
7330   for(int i=0;i<nbOfTuples;i++,inp1+=nbOfComp1,inp2+=nbOfComp2)
7331     {
7332       w=std::copy(inp1,inp1+nbOfComp1,w);
7333       w=std::copy(inp2,inp2+nbOfComp2,w);
7334     }
7335   useArray(newArr,true,C_DEALLOC,nbOfTuples,nbOfComp1+nbOfComp2);
7336   std::vector<int> compIds(nbOfComp2);
7337   for(int i=0;i<nbOfComp2;i++)
7338     compIds[i]=nbOfComp1+i;
7339   copyPartOfStringInfoFrom2(compIds,*other);
7340 }
7341
7342 /*!
7343  * Copy all components in a specified order from another DataArrayInt.
7344  * The specified components become the first ones in \a this array.
7345  * Both numerical and textual data is copied. The number of tuples in \a this and
7346  * the other array can be different.
7347  *  \param [in] a - the array to copy data from.
7348  *  \param [in] compoIds - sequence of zero based indices of components, data of which is
7349  *              to be copied.
7350  *  \throw If \a a is NULL.
7351  *  \throw If \a compoIds.size() != \a a->getNumberOfComponents().
7352  *  \throw If \a compoIds[i] < 0 or \a compoIds[i] > \a this->getNumberOfComponents().
7353  *
7354  *  \if ENABLE_EXAMPLES
7355  *  \ref py_mcdataarrayint_setselectedcomponents "Here is a Python example".
7356  *  \endif
7357  */
7358 void DataArrayInt::setSelectedComponents(const DataArrayInt *a, const std::vector<int>& compoIds)
7359 {
7360   if(!a)
7361     throw INTERP_KERNEL::Exception("DataArrayInt::setSelectedComponents : input DataArrayInt is NULL !");
7362   checkAllocated();
7363   a->checkAllocated();
7364   copyPartOfStringInfoFrom2(compoIds,*a);
7365   std::size_t partOfCompoSz=compoIds.size();
7366   int nbOfCompo=getNumberOfComponents();
7367   int nbOfTuples=std::min(getNumberOfTuples(),a->getNumberOfTuples());
7368   const int *ac=a->getConstPointer();
7369   int *nc=getPointer();
7370   for(int i=0;i<nbOfTuples;i++)
7371     for(std::size_t j=0;j<partOfCompoSz;j++,ac++)
7372       nc[nbOfCompo*i+compoIds[j]]=*ac;
7373 }
7374
7375 /*!
7376  * Copy all values from another DataArrayInt into specified tuples and components
7377  * of \a this array. Textual data is not copied.
7378  * The tree parameters defining set of indices of tuples and components are similar to
7379  * the tree parameters of the Python function \c range(\c start,\c stop,\c step).
7380  *  \param [in] a - the array to copy values from.
7381  *  \param [in] bgTuples - index of the first tuple of \a this array to assign values to.
7382  *  \param [in] endTuples - index of the tuple before which the tuples to assign to
7383  *              are located.
7384  *  \param [in] stepTuples - index increment to get index of the next tuple to assign to.
7385  *  \param [in] bgComp - index of the first component of \a this array to assign values to.
7386  *  \param [in] endComp - index of the component before which the components to assign
7387  *              to are located.
7388  *  \param [in] stepComp - index increment to get index of the next component to assign to.
7389  *  \param [in] strictCompoCompare - if \a true (by default), then \a a->getNumberOfComponents() 
7390  *              must be equal to the number of columns to assign to, else an
7391  *              exception is thrown; if \a false, then it is only required that \a
7392  *              a->getNbOfElems() equals to number of values to assign to (this condition
7393  *              must be respected even if \a strictCompoCompare is \a true). The number of 
7394  *              values to assign to is given by following Python expression:
7395  *              \a nbTargetValues = 
7396  *              \c len(\c range(\a bgTuples,\a endTuples,\a stepTuples)) *
7397  *              \c len(\c range(\a bgComp,\a endComp,\a stepComp)).
7398  *  \throw If \a a is NULL.
7399  *  \throw If \a a is not allocated.
7400  *  \throw If \a this is not allocated.
7401  *  \throw If parameters specifying tuples and components to assign to do not give a
7402  *            non-empty range of increasing indices.
7403  *  \throw If \a a->getNbOfElems() != \a nbTargetValues.
7404  *  \throw If \a strictCompoCompare == \a true && \a a->getNumberOfComponents() !=
7405  *            \c len(\c range(\a bgComp,\a endComp,\a stepComp)).
7406  *
7407  *  \if ENABLE_EXAMPLES
7408  *  \ref py_mcdataarrayint_setpartofvalues1 "Here is a Python example".
7409  *  \endif
7410  */
7411 void DataArrayInt::setPartOfValues1(const DataArrayInt *a, int bgTuples, int endTuples, int stepTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare)
7412 {
7413   if(!a)
7414     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValues1 : DataArrayInt pointer in input is NULL !");
7415   const char msg[]="DataArrayInt::setPartOfValues1";
7416   checkAllocated();
7417   a->checkAllocated();
7418   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
7419   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
7420   int nbComp=getNumberOfComponents();
7421   int nbOfTuples=getNumberOfTuples();
7422   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
7423   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
7424   bool assignTech=true;
7425   if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
7426     {
7427       if(strictCompoCompare)
7428         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
7429     }
7430   else
7431     {
7432       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
7433       assignTech=false;
7434     }
7435   int *pt=getPointer()+bgTuples*nbComp+bgComp;
7436   const int *srcPt=a->getConstPointer();
7437   if(assignTech)
7438     {
7439       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
7440         for(int j=0;j<newNbOfComp;j++,srcPt++)
7441           pt[j*stepComp]=*srcPt;
7442     }
7443   else
7444     {
7445       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
7446         {
7447           const int *srcPt2=srcPt;
7448           for(int j=0;j<newNbOfComp;j++,srcPt2++)
7449             pt[j*stepComp]=*srcPt2;
7450         }
7451     }
7452 }
7453
7454 /*!
7455  * Assign a given value to values at specified tuples and components of \a this array.
7456  * The tree parameters defining set of indices of tuples and components are similar to
7457  * the tree parameters of the Python function \c range(\c start,\c stop,\c step)..
7458  *  \param [in] a - the value to assign.
7459  *  \param [in] bgTuples - index of the first tuple of \a this array to assign to.
7460  *  \param [in] endTuples - index of the tuple before which the tuples to assign to
7461  *              are located.
7462  *  \param [in] stepTuples - index increment to get index of the next tuple to assign to.
7463  *  \param [in] bgComp - index of the first component of \a this array to assign to.
7464  *  \param [in] endComp - index of the component before which the components to assign
7465  *              to are located.
7466  *  \param [in] stepComp - index increment to get index of the next component to assign to.
7467  *  \throw If \a this is not allocated.
7468  *  \throw If parameters specifying tuples and components to assign to, do not give a
7469  *            non-empty range of increasing indices or indices are out of a valid range
7470  *            for \c this array.
7471  *
7472  *  \if ENABLE_EXAMPLES
7473  *  \ref py_mcdataarrayint_setpartofvaluessimple1 "Here is a Python example".
7474  *  \endif
7475  */
7476 void DataArrayInt::setPartOfValuesSimple1(int a, int bgTuples, int endTuples, int stepTuples, int bgComp, int endComp, int stepComp)
7477 {
7478   const char msg[]="DataArrayInt::setPartOfValuesSimple1";
7479   checkAllocated();
7480   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
7481   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
7482   int nbComp=getNumberOfComponents();
7483   int nbOfTuples=getNumberOfTuples();
7484   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
7485   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
7486   int *pt=getPointer()+bgTuples*nbComp+bgComp;
7487   for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
7488     for(int j=0;j<newNbOfComp;j++)
7489       pt[j*stepComp]=a;
7490 }
7491
7492
7493 /*!
7494  * Copy all values from another DataArrayInt (\a a) into specified tuples and 
7495  * components of \a this array. Textual data is not copied.
7496  * The tuples and components to assign to are defined by C arrays of indices.
7497  * There are two *modes of usage*:
7498  * - If \a a->getNbOfElems() equals to number of values to assign to, then every value
7499  *   of \a a is assigned to its own location within \a this array. 
7500  * - If \a a includes one tuple, then all values of \a a are assigned to the specified
7501  *   components of every specified tuple of \a this array. In this mode it is required
7502  *   that \a a->getNumberOfComponents() equals to the number of specified components.
7503  * 
7504  *  \param [in] a - the array to copy values from.
7505  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
7506  *              assign values of \a a to.
7507  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
7508  *              pointer to a tuple index <em>(pi)</em> varies as this: 
7509  *              \a bgTuples <= \a pi < \a endTuples.
7510  *  \param [in] bgComp - pointer to an array of component indices of \a this array to
7511  *              assign values of \a a to.
7512  *  \param [in] endComp - specifies the end of the array \a bgTuples, so that
7513  *              pointer to a component index <em>(pi)</em> varies as this: 
7514  *              \a bgComp <= \a pi < \a endComp.
7515  *  \param [in] strictCompoCompare - this parameter is checked only if the
7516  *               *mode of usage* is the first; if it is \a true (default), 
7517  *               then \a a->getNumberOfComponents() must be equal 
7518  *               to the number of specified columns, else this is not required.
7519  *  \throw If \a a is NULL.
7520  *  \throw If \a a is not allocated.
7521  *  \throw If \a this is not allocated.
7522  *  \throw If any index of tuple/component given by <em>bgTuples / bgComp</em> is
7523  *         out of a valid range for \a this array.
7524  *  \throw In the first *mode of usage*, if <em>strictCompoCompare == true </em> and
7525  *         if <em> a->getNumberOfComponents() != (endComp - bgComp) </em>.
7526  *  \throw In the second *mode of usage*, if \a a->getNumberOfTuples() != 1 or
7527  *         <em> a->getNumberOfComponents() != (endComp - bgComp)</em>.
7528  *
7529  *  \if ENABLE_EXAMPLES
7530  *  \ref py_mcdataarrayint_setpartofvalues2 "Here is a Python example".
7531  *  \endif
7532  */
7533 void DataArrayInt::setPartOfValues2(const DataArrayInt *a, const int *bgTuples, const int *endTuples, const int *bgComp, const int *endComp, bool strictCompoCompare)
7534 {
7535   if(!a)
7536     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValues2 : DataArrayInt pointer in input is NULL !");
7537   const char msg[]="DataArrayInt::setPartOfValues2";
7538   checkAllocated();
7539   a->checkAllocated();
7540   int nbComp=getNumberOfComponents();
7541   int nbOfTuples=getNumberOfTuples();
7542   for(const int *z=bgComp;z!=endComp;z++)
7543     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
7544   int newNbOfTuples=(int)std::distance(bgTuples,endTuples);
7545   int newNbOfComp=(int)std::distance(bgComp,endComp);
7546   bool assignTech=true;
7547   if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
7548     {
7549       if(strictCompoCompare)
7550         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
7551     }
7552   else
7553     {
7554       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
7555       assignTech=false;
7556     }
7557   int *pt=getPointer();
7558   const int *srcPt=a->getConstPointer();
7559   if(assignTech)
7560     {    
7561       for(const int *w=bgTuples;w!=endTuples;w++)
7562         {
7563           DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
7564           for(const int *z=bgComp;z!=endComp;z++,srcPt++)
7565             {    
7566               pt[(std::size_t)(*w)*nbComp+(*z)]=*srcPt;
7567             }
7568         }
7569     }
7570   else
7571     {
7572       for(const int *w=bgTuples;w!=endTuples;w++)
7573         {
7574           const int *srcPt2=srcPt;
7575           DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
7576           for(const int *z=bgComp;z!=endComp;z++,srcPt2++)
7577             {    
7578               pt[(std::size_t)(*w)*nbComp+(*z)]=*srcPt2;
7579             }
7580         }
7581     }
7582 }
7583
7584 /*!
7585  * Assign a given value to values at specified tuples and components of \a this array.
7586  * The tuples and components to assign to are defined by C arrays of indices.
7587  *  \param [in] a - the value to assign.
7588  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
7589  *              assign \a a to.
7590  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
7591  *              pointer to a tuple index (\a pi) varies as this: 
7592  *              \a bgTuples <= \a pi < \a endTuples.
7593  *  \param [in] bgComp - pointer to an array of component indices of \a this array to
7594  *              assign \a a to.
7595  *  \param [in] endComp - specifies the end of the array \a bgTuples, so that
7596  *              pointer to a component index (\a pi) varies as this: 
7597  *              \a bgComp <= \a pi < \a endComp.
7598  *  \throw If \a this is not allocated.
7599  *  \throw If any index of tuple/component given by <em>bgTuples / bgComp</em> is
7600  *         out of a valid range for \a this array.
7601  *
7602  *  \if ENABLE_EXAMPLES
7603  *  \ref py_mcdataarrayint_setpartofvaluessimple2 "Here is a Python example".
7604  *  \endif
7605  */
7606 void DataArrayInt::setPartOfValuesSimple2(int a, const int *bgTuples, const int *endTuples, const int *bgComp, const int *endComp)
7607 {
7608   checkAllocated();
7609   int nbComp=getNumberOfComponents();
7610   int nbOfTuples=getNumberOfTuples();
7611   for(const int *z=bgComp;z!=endComp;z++)
7612     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
7613   int *pt=getPointer();
7614   for(const int *w=bgTuples;w!=endTuples;w++)
7615     for(const int *z=bgComp;z!=endComp;z++)
7616       {
7617         DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
7618         pt[(std::size_t)(*w)*nbComp+(*z)]=a;
7619       }
7620 }
7621
7622 /*!
7623  * Copy all values from another DataArrayInt (\a a) into specified tuples and 
7624  * components of \a this array. Textual data is not copied.
7625  * The tuples to assign to are defined by a C array of indices.
7626  * The components to assign to are defined by three values similar to parameters of
7627  * the Python function \c range(\c start,\c stop,\c step).
7628  * There are two *modes of usage*:
7629  * - If \a a->getNbOfElems() equals to number of values to assign to, then every value
7630  *   of \a a is assigned to its own location within \a this array. 
7631  * - If \a a includes one tuple, then all values of \a a are assigned to the specified
7632  *   components of every specified tuple of \a this array. In this mode it is required
7633  *   that \a a->getNumberOfComponents() equals to the number of specified components.
7634  *
7635  *  \param [in] a - the array to copy values from.
7636  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
7637  *              assign values of \a a to.
7638  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
7639  *              pointer to a tuple index <em>(pi)</em> varies as this: 
7640  *              \a bgTuples <= \a pi < \a endTuples.
7641  *  \param [in] bgComp - index of the first component of \a this array to assign to.
7642  *  \param [in] endComp - index of the component before which the components to assign
7643  *              to are located.
7644  *  \param [in] stepComp - index increment to get index of the next component to assign to.
7645  *  \param [in] strictCompoCompare - this parameter is checked only in the first
7646  *               *mode of usage*; if \a strictCompoCompare is \a true (default), 
7647  *               then \a a->getNumberOfComponents() must be equal 
7648  *               to the number of specified columns, else this is not required.
7649  *  \throw If \a a is NULL.
7650  *  \throw If \a a is not allocated.
7651  *  \throw If \a this is not allocated.
7652  *  \throw If any index of tuple given by \a bgTuples is out of a valid range for 
7653  *         \a this array.
7654  *  \throw In the first *mode of usage*, if <em>strictCompoCompare == true </em> and
7655  *         if <em> a->getNumberOfComponents()</em> is unequal to the number of components
7656  *         defined by <em>(bgComp,endComp,stepComp)</em>.
7657  *  \throw In the second *mode of usage*, if \a a->getNumberOfTuples() != 1 or
7658  *         <em> a->getNumberOfComponents()</em> is unequal to the number of components
7659  *         defined by <em>(bgComp,endComp,stepComp)</em>.
7660  *  \throw If parameters specifying components to assign to, do not give a
7661  *            non-empty range of increasing indices or indices are out of a valid range
7662  *            for \c this array.
7663  *
7664  *  \if ENABLE_EXAMPLES
7665  *  \ref py_mcdataarrayint_setpartofvalues3 "Here is a Python example".
7666  *  \endif
7667  */
7668 void DataArrayInt::setPartOfValues3(const DataArrayInt *a, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare)
7669 {
7670   if(!a)
7671     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValues3 : DataArrayInt pointer in input is NULL !");
7672   const char msg[]="DataArrayInt::setPartOfValues3";
7673   checkAllocated();
7674   a->checkAllocated();
7675   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
7676   int nbComp=getNumberOfComponents();
7677   int nbOfTuples=getNumberOfTuples();
7678   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
7679   int newNbOfTuples=(int)std::distance(bgTuples,endTuples);
7680   bool assignTech=true;
7681   if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
7682     {
7683       if(strictCompoCompare)
7684         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
7685     }
7686   else
7687     {
7688       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
7689       assignTech=false;
7690     }
7691   int *pt=getPointer()+bgComp;
7692   const int *srcPt=a->getConstPointer();
7693   if(assignTech)
7694     {
7695       for(const int *w=bgTuples;w!=endTuples;w++)
7696         for(int j=0;j<newNbOfComp;j++,srcPt++)
7697           {
7698             DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
7699             pt[(std::size_t)(*w)*nbComp+j*stepComp]=*srcPt;
7700           }
7701     }
7702   else
7703     {
7704       for(const int *w=bgTuples;w!=endTuples;w++)
7705         {
7706           const int *srcPt2=srcPt;
7707           for(int j=0;j<newNbOfComp;j++,srcPt2++)
7708             {
7709               DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
7710               pt[(std::size_t)(*w)*nbComp+j*stepComp]=*srcPt2;
7711             }
7712         }
7713     }
7714 }
7715
7716 /*!
7717  * Assign a given value to values at specified tuples and components of \a this array.
7718  * The tuples to assign to are defined by a C array of indices.
7719  * The components to assign to are defined by three values similar to parameters of
7720  * the Python function \c range(\c start,\c stop,\c step).
7721  *  \param [in] a - the value to assign.
7722  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
7723  *              assign \a a to.
7724  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
7725  *              pointer to a tuple index <em>(pi)</em> varies as this: 
7726  *              \a bgTuples <= \a pi < \a endTuples.
7727  *  \param [in] bgComp - index of the first component of \a this array to assign to.
7728  *  \param [in] endComp - index of the component before which the components to assign
7729  *              to are located.
7730  *  \param [in] stepComp - index increment to get index of the next component to assign to.
7731  *  \throw If \a this is not allocated.
7732  *  \throw If any index of tuple given by \a bgTuples is out of a valid range for 
7733  *         \a this array.
7734  *  \throw If parameters specifying components to assign to, do not give a
7735  *            non-empty range of increasing indices or indices are out of a valid range
7736  *            for \c this array.
7737  *
7738  *  \if ENABLE_EXAMPLES
7739  *  \ref py_mcdataarrayint_setpartofvaluessimple3 "Here is a Python example".
7740  *  \endif
7741  */
7742 void DataArrayInt::setPartOfValuesSimple3(int a, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp)
7743 {
7744   const char msg[]="DataArrayInt::setPartOfValuesSimple3";
7745   checkAllocated();
7746   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
7747   int nbComp=getNumberOfComponents();
7748   int nbOfTuples=getNumberOfTuples();
7749   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
7750   int *pt=getPointer()+bgComp;
7751   for(const int *w=bgTuples;w!=endTuples;w++)
7752     for(int j=0;j<newNbOfComp;j++)
7753       {
7754         DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
7755         pt[(std::size_t)(*w)*nbComp+j*stepComp]=a;
7756       }
7757 }
7758
7759 void DataArrayInt::setPartOfValues4(const DataArrayInt *a, int bgTuples, int endTuples, int stepTuples, const int *bgComp, const int *endComp, bool strictCompoCompare)
7760 {
7761   if(!a)
7762     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValues4 : input DataArrayInt is NULL !");
7763   const char msg[]="DataArrayInt::setPartOfValues4";
7764   checkAllocated();
7765   a->checkAllocated();
7766   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
7767   int newNbOfComp=(int)std::distance(bgComp,endComp);
7768   int nbComp=getNumberOfComponents();
7769   for(const int *z=bgComp;z!=endComp;z++)
7770     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
7771   int nbOfTuples=getNumberOfTuples();
7772   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
7773   bool assignTech=true;
7774   if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
7775     {
7776       if(strictCompoCompare)
7777         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
7778     }
7779   else
7780     {
7781       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
7782       assignTech=false;
7783     }
7784   const int *srcPt=a->getConstPointer();
7785   int *pt=getPointer()+bgTuples*nbComp;
7786   if(assignTech)
7787     {
7788       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
7789         for(const int *z=bgComp;z!=endComp;z++,srcPt++)
7790           pt[*z]=*srcPt;
7791     }
7792   else
7793     {
7794       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
7795         {
7796           const int *srcPt2=srcPt;
7797           for(const int *z=bgComp;z!=endComp;z++,srcPt2++)
7798             pt[*z]=*srcPt2;
7799         }
7800     }
7801 }
7802
7803 void DataArrayInt::setPartOfValuesSimple4(int a, int bgTuples, int endTuples, int stepTuples, const int *bgComp, const int *endComp)
7804 {
7805   const char msg[]="DataArrayInt::setPartOfValuesSimple4";
7806   checkAllocated();
7807   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
7808   int nbComp=getNumberOfComponents();
7809   for(const int *z=bgComp;z!=endComp;z++)
7810     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
7811   int nbOfTuples=getNumberOfTuples();
7812   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
7813   int *pt=getPointer()+bgTuples*nbComp;
7814   for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
7815     for(const int *z=bgComp;z!=endComp;z++)
7816       pt[*z]=a;
7817 }
7818
7819 /*!
7820  * Copy some tuples from another DataArrayInt into specified tuples
7821  * of \a this array. Textual data is not copied. Both arrays must have equal number of
7822  * components.
7823  * Both the tuples to assign and the tuples to assign to are defined by a DataArrayInt.
7824  * All components of selected tuples are copied.
7825  *  \param [in] a - the array to copy values from.
7826  *  \param [in] tuplesSelec - the array specifying both source tuples of \a a and
7827  *              target tuples of \a this. \a tuplesSelec has two components, and the
7828  *              first component specifies index of the source tuple and the second
7829  *              one specifies index of the target tuple.
7830  *  \throw If \a this is not allocated.
7831  *  \throw If \a a is NULL.
7832  *  \throw If \a a is not allocated.
7833  *  \throw If \a tuplesSelec is NULL.
7834  *  \throw If \a tuplesSelec is not allocated.
7835  *  \throw If <em>this->getNumberOfComponents() != a->getNumberOfComponents()</em>.
7836  *  \throw If \a tuplesSelec->getNumberOfComponents() != 2.
7837  *  \throw If any tuple index given by \a tuplesSelec is out of a valid range for 
7838  *         the corresponding (\a this or \a a) array.
7839  */
7840 void DataArrayInt::setPartOfValuesAdv(const DataArrayInt *a, const DataArrayInt *tuplesSelec)
7841 {
7842   if(!a || !tuplesSelec)
7843     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValuesAdv : DataArrayInt pointer in input is NULL !");
7844   checkAllocated();
7845   a->checkAllocated();
7846   tuplesSelec->checkAllocated();
7847   int nbOfComp=getNumberOfComponents();
7848   if(nbOfComp!=a->getNumberOfComponents())
7849     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValuesAdv : This and a do not have the same number of components !");
7850   if(tuplesSelec->getNumberOfComponents()!=2)
7851     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValuesAdv : Expecting to have a tuple selector DataArrayInt instance with exactly 2 components !");
7852   int thisNt=getNumberOfTuples();
7853   int aNt=a->getNumberOfTuples();
7854   int *valsToSet=getPointer();
7855   const int *valsSrc=a->getConstPointer();
7856   for(const int *tuple=tuplesSelec->begin();tuple!=tuplesSelec->end();tuple+=2)
7857     {
7858       if(tuple[1]>=0 && tuple[1]<aNt)
7859         {
7860           if(tuple[0]>=0 && tuple[0]<thisNt)
7861             std::copy(valsSrc+nbOfComp*tuple[1],valsSrc+nbOfComp*(tuple[1]+1),valsToSet+nbOfComp*tuple[0]);
7862           else
7863             {
7864               std::ostringstream oss; oss << "DataArrayInt::setPartOfValuesAdv : Tuple #" << std::distance(tuplesSelec->begin(),tuple)/2;
7865               oss << " of 'tuplesSelec' request of tuple id #" << tuple[0] << " in 'this' ! It should be in [0," << thisNt << ") !";
7866               throw INTERP_KERNEL::Exception(oss.str().c_str());
7867             }
7868         }
7869       else
7870         {
7871           std::ostringstream oss; oss << "DataArrayInt::setPartOfValuesAdv : Tuple #" << std::distance(tuplesSelec->begin(),tuple)/2;
7872           oss << " of 'tuplesSelec' request of tuple id #" << tuple[1] << " in 'a' ! It should be in [0," << aNt << ") !";
7873           throw INTERP_KERNEL::Exception(oss.str().c_str());
7874         }
7875     }
7876 }
7877
7878 /*!
7879  * Copy some tuples from another DataArrayInt (\a aBase) into contiguous tuples
7880  * of \a this array. Textual data is not copied. Both arrays must have equal number of
7881  * components.
7882  * The tuples to assign to are defined by index of the first tuple, and
7883  * their number is defined by \a tuplesSelec->getNumberOfTuples().
7884  * The tuples to copy are defined by values of a DataArrayInt.
7885  * All components of selected tuples are copied.
7886  *  \param [in] tupleIdStart - index of the first tuple of \a this array to assign
7887  *              values to.
7888  *  \param [in] aBase - the array to copy values from.
7889  *  \param [in] tuplesSelec - the array specifying tuples of \a aBase to copy.
7890  *  \throw If \a this is not allocated.
7891  *  \throw If \a aBase is NULL.
7892  *  \throw If \a aBase is not allocated.
7893  *  \throw If \a tuplesSelec is NULL.
7894  *  \throw If \a tuplesSelec is not allocated.
7895  *  \throw If <em>this->getNumberOfComponents() != a->getNumberOfComponents()</em>.
7896  *  \throw If \a tuplesSelec->getNumberOfComponents() != 1.
7897  *  \throw If <em>tupleIdStart + tuplesSelec->getNumberOfTuples() > this->getNumberOfTuples().</em>
7898  *  \throw If any tuple index given by \a tuplesSelec is out of a valid range for 
7899  *         \a aBase array.
7900  */
7901 void DataArrayInt::setContigPartOfSelectedValues(int tupleIdStart, const DataArray *aBase, const DataArrayInt *tuplesSelec)
7902 {
7903   if(!aBase || !tuplesSelec)
7904     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues : input DataArray is NULL !");
7905   const DataArrayInt *a=dynamic_cast<const DataArrayInt *>(aBase);
7906   if(!a)
7907     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues : input DataArray aBase is not a DataArrayInt !");
7908   checkAllocated();
7909   a->checkAllocated();
7910   tuplesSelec->checkAllocated();
7911   int nbOfComp=getNumberOfComponents();
7912   if(nbOfComp!=a->getNumberOfComponents())
7913     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues : This and a do not have the same number of components !");
7914   if(tuplesSelec->getNumberOfComponents()!=1)
7915     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues : Expecting to have a tuple selector DataArrayInt instance with exactly 1 component !");
7916   int thisNt=getNumberOfTuples();
7917   int aNt=a->getNumberOfTuples();
7918   int nbOfTupleToWrite=tuplesSelec->getNumberOfTuples();
7919   int *valsToSet=getPointer()+tupleIdStart*nbOfComp;
7920   if(tupleIdStart+nbOfTupleToWrite>thisNt)
7921     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues : invalid number range of values to write !");
7922   const int *valsSrc=a->getConstPointer();
7923   for(const int *tuple=tuplesSelec->begin();tuple!=tuplesSelec->end();tuple++,valsToSet+=nbOfComp)
7924     {
7925       if(*tuple>=0 && *tuple<aNt)
7926         {
7927           std::copy(valsSrc+nbOfComp*(*tuple),valsSrc+nbOfComp*(*tuple+1),valsToSet);
7928         }
7929       else
7930         {
7931           std::ostringstream oss; oss << "DataArrayInt::setContigPartOfSelectedValues : Tuple #" << std::distance(tuplesSelec->begin(),tuple);
7932           oss << " of 'tuplesSelec' request of tuple id #" << *tuple << " in 'a' ! It should be in [0," << aNt << ") !";
7933           throw INTERP_KERNEL::Exception(oss.str().c_str());
7934         }
7935     }
7936 }
7937
7938 /*!
7939  * Copy some tuples from another DataArrayInt (\a aBase) into contiguous tuples
7940  * of \a this array. Textual data is not copied. Both arrays must have equal number of
7941  * components.
7942  * The tuples to copy are defined by three values similar to parameters of
7943  * the Python function \c range(\c start,\c stop,\c step).
7944  * The tuples to assign to are defined by index of the first tuple, and
7945  * their number is defined by number of tuples to copy.
7946  * All components of selected tuples are copied.
7947  *  \param [in] tupleIdStart - index of the first tuple of \a this array to assign
7948  *              values to.
7949  *  \param [in] aBase - the array to copy values from.
7950  *  \param [in] bg - index of the first tuple to copy of the array \a aBase.
7951  *  \param [in] end2 - index of the tuple of \a aBase before which the tuples to copy
7952  *              are located.
7953  *  \param [in] step - index increment to get index of the next tuple to copy.
7954  *  \throw If \a this is not allocated.
7955  *  \throw If \a aBase is NULL.
7956  *  \throw If \a aBase is not allocated.
7957  *  \throw If <em>this->getNumberOfComponents() != aBase->getNumberOfComponents()</em>.
7958  *  \throw If <em>tupleIdStart + len(range(bg,end2,step)) > this->getNumberOfTuples().</em>
7959  *  \throw If parameters specifying tuples to copy, do not give a
7960  *            non-empty range of increasing indices or indices are out of a valid range
7961  *            for the array \a aBase.
7962  */
7963 void DataArrayInt::setContigPartOfSelectedValuesSlice(int tupleIdStart, const DataArray *aBase, int bg, int end2, int step)
7964 {
7965   if(!aBase)
7966     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValuesSlice : input DataArray is NULL !");
7967   const DataArrayInt *a=dynamic_cast<const DataArrayInt *>(aBase);
7968   if(!a)
7969     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValuesSlice : input DataArray aBase is not a DataArrayInt !");
7970   checkAllocated();
7971   a->checkAllocated();
7972   int nbOfComp=getNumberOfComponents();
7973   const char msg[]="DataArrayInt::setContigPartOfSelectedValuesSlice";
7974   int nbOfTupleToWrite=DataArray::GetNumberOfItemGivenBES(bg,end2,step,msg);
7975   if(nbOfComp!=a->getNumberOfComponents())
7976     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValuesSlice : This and a do not have the same number of components !");
7977   int thisNt=getNumberOfTuples();
7978   int aNt=a->getNumberOfTuples();
7979   int *valsToSet=getPointer()+tupleIdStart*nbOfComp;
7980   if(tupleIdStart+nbOfTupleToWrite>thisNt)
7981     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValuesSlice : invalid number range of values to write !");
7982   if(end2>aNt)
7983     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValuesSlice : invalid range of values to read !");
7984   const int *valsSrc=a->getConstPointer()+bg*nbOfComp;
7985   for(int i=0;i<nbOfTupleToWrite;i++,valsToSet+=nbOfComp,valsSrc+=step*nbOfComp)
7986     {
7987       std::copy(valsSrc,valsSrc+nbOfComp,valsToSet);
7988     }
7989 }
7990
7991 /*!
7992  * Returns the first value of \a this. 
7993  *  \return int - the last value of \a this array.
7994  *  \throw If \a this is not allocated.
7995  *  \throw If \a this->getNumberOfComponents() != 1.
7996  *  \throw If \a this->getNumberOfTuples() < 1.
7997  */
7998 int DataArrayInt::front() const
7999 {
8000   checkAllocated();
8001   if(getNumberOfComponents()!=1)
8002     throw INTERP_KERNEL::Exception("DataArrayInt::front : number of components not equal to one !");
8003   int nbOfTuples=getNumberOfTuples();
8004   if(nbOfTuples<1)
8005     throw INTERP_KERNEL::Exception("DataArrayInt::front : number of tuples must be >= 1 !");
8006   return *(getConstPointer());
8007 }
8008
8009 /*!
8010  * Returns the last value of \a this. 
8011  *  \return int - the last value of \a this array.
8012  *  \throw If \a this is not allocated.
8013  *  \throw If \a this->getNumberOfComponents() != 1.
8014  *  \throw If \a this->getNumberOfTuples() < 1.
8015  */
8016 int DataArrayInt::back() const
8017 {
8018   checkAllocated();
8019   if(getNumberOfComponents()!=1)
8020     throw INTERP_KERNEL::Exception("DataArrayInt::back : number of components not equal to one !");
8021   int nbOfTuples=getNumberOfTuples();
8022   if(nbOfTuples<1)
8023     throw INTERP_KERNEL::Exception("DataArrayInt::back : number of tuples must be >= 1 !");
8024   return *(getConstPointer()+nbOfTuples-1);
8025 }
8026
8027 /*!
8028  * Assign pointer to one array to a pointer to another appay. Reference counter of
8029  * \a arrayToSet is incremented / decremented.
8030  *  \param [in] newArray - the pointer to array to assign to \a arrayToSet.
8031  *  \param [in,out] arrayToSet - the pointer to array to assign to.
8032  */
8033 void DataArrayInt::SetArrayIn(DataArrayInt *newArray, DataArrayInt* &arrayToSet)
8034 {
8035   if(newArray!=arrayToSet)
8036     {
8037       if(arrayToSet)
8038         arrayToSet->decrRef();
8039       arrayToSet=newArray;
8040       if(arrayToSet)
8041         arrayToSet->incrRef();
8042     }
8043 }
8044
8045 DataArrayIntIterator *DataArrayInt::iterator()
8046 {
8047   return new DataArrayIntIterator(this);
8048 }
8049
8050 /*!
8051  * Creates a new DataArrayInt containing IDs (indices) of tuples holding value equal to a
8052  * given one. The ids are sorted in the ascending order.
8053  *  \param [in] val - the value to find within \a this.
8054  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
8055  *          array using decrRef() as it is no more needed.
8056  *  \throw If \a this is not allocated.
8057  *  \throw If \a this->getNumberOfComponents() != 1.
8058  *  \sa DataArrayInt::findIdsEqualTuple
8059  */
8060 DataArrayInt *DataArrayInt::findIdsEqual(int val) const
8061 {
8062   checkAllocated();
8063   if(getNumberOfComponents()!=1)
8064     throw INTERP_KERNEL::Exception("DataArrayInt::findIdsEqual : the array must have only one component, you can call 'rearrange' method before !");
8065   const int *cptr(getConstPointer());
8066   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
8067   int nbOfTuples=getNumberOfTuples();
8068   for(int i=0;i<nbOfTuples;i++,cptr++)
8069     if(*cptr==val)
8070       ret->pushBackSilent(i);
8071   return ret.retn();
8072 }
8073
8074 /*!
8075  * Creates a new DataArrayInt containing IDs (indices) of tuples holding value \b not
8076  * equal to a given one. 
8077  *  \param [in] val - the value to ignore within \a this.
8078  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
8079  *          array using decrRef() as it is no more needed.
8080  *  \throw If \a this is not allocated.
8081  *  \throw If \a this->getNumberOfComponents() != 1.
8082  */
8083 DataArrayInt *DataArrayInt::findIdsNotEqual(int val) const
8084 {
8085   checkAllocated();
8086   if(getNumberOfComponents()!=1)
8087     throw INTERP_KERNEL::Exception("DataArrayInt::findIdsNotEqual : the array must have only one component, you can call 'rearrange' method before !");
8088   const int *cptr(getConstPointer());
8089   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
8090   int nbOfTuples=getNumberOfTuples();
8091   for(int i=0;i<nbOfTuples;i++,cptr++)
8092     if(*cptr!=val)
8093       ret->pushBackSilent(i);
8094   return ret.retn();
8095 }
8096
8097 /*!
8098  * Creates a new DataArrayInt containing IDs (indices) of tuples holding tuple equal to those defined by [ \a tupleBg , \a tupleEnd )
8099  * This method is an extension of  DataArrayInt::findIdsEqual method.
8100  *
8101  *  \param [in] tupleBg - the begin (included) of the input tuple to find within \a this.
8102  *  \param [in] tupleEnd - the end (excluded) of the input tuple to find within \a this.
8103  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
8104  *          array using decrRef() as it is no more needed.
8105  *  \throw If \a this is not allocated.
8106  *  \throw If \a this->getNumberOfComponents() != std::distance(tupleBg,tupleEnd).
8107  * \throw If \a this->getNumberOfComponents() is equal to 0.
8108  * \sa DataArrayInt::findIdsEqual
8109  */
8110 DataArrayInt *DataArrayInt::findIdsEqualTuple(const int *tupleBg, const int *tupleEnd) const
8111 {
8112   std::size_t nbOfCompoExp(std::distance(tupleBg,tupleEnd));
8113   checkAllocated();
8114   if(getNumberOfComponents()!=(int)nbOfCompoExp)
8115     {
8116       std::ostringstream oss; oss << "DataArrayInt::findIdsEqualTuple : mismatch of number of components. Input tuple has " << nbOfCompoExp << " whereas this array has " << getNumberOfComponents() << " components !";
8117       throw INTERP_KERNEL::Exception(oss.str().c_str());
8118     }
8119   if(nbOfCompoExp==0)
8120     throw INTERP_KERNEL::Exception("DataArrayInt::findIdsEqualTuple : number of components should be > 0 !");
8121   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
8122   const int *bg(begin()),*end2(end()),*work(begin());
8123   while(work!=end2)
8124     {
8125       work=std::search(work,end2,tupleBg,tupleEnd);
8126       if(work!=end2)
8127         {
8128           std::size_t pos(std::distance(bg,work));
8129           if(pos%nbOfCompoExp==0)
8130             ret->pushBackSilent(pos/nbOfCompoExp);
8131           work++;
8132         }
8133     }
8134   return ret.retn();
8135 }
8136
8137 /*!
8138  * Assigns \a newValue to all elements holding \a oldValue within \a this
8139  * one-dimensional array.
8140  *  \param [in] oldValue - the value to replace.
8141  *  \param [in] newValue - the value to assign.
8142  *  \return int - number of replacements performed.
8143  *  \throw If \a this is not allocated.
8144  *  \throw If \a this->getNumberOfComponents() != 1.
8145  */
8146 int DataArrayInt::changeValue(int oldValue, int newValue)
8147 {
8148   checkAllocated();
8149   if(getNumberOfComponents()!=1)
8150     throw INTERP_KERNEL::Exception("DataArrayInt::changeValue : the array must have only one component, you can call 'rearrange' method before !");
8151   if(oldValue==newValue)
8152     return 0;
8153   int *start(getPointer()),*end2(start+getNbOfElems());
8154   int ret(0);
8155   for(int *val=start;val!=end2;val++)
8156     {
8157       if(*val==oldValue)
8158         {
8159           *val=newValue;
8160           ret++;
8161         }
8162     }
8163   if(ret>0)
8164     declareAsNew();
8165   return ret;
8166 }
8167
8168 /*!
8169  * Creates a new DataArrayInt containing IDs (indices) of tuples holding value equal to
8170  * one of given values.
8171  *  \param [in] valsBg - an array of values to find within \a this array.
8172  *  \param [in] valsEnd - specifies the end of the array \a valsBg, so that
8173  *              the last value of \a valsBg is \a valsEnd[ -1 ].
8174  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
8175  *          array using decrRef() as it is no more needed.
8176  *  \throw If \a this->getNumberOfComponents() != 1.
8177  */
8178 DataArrayInt *DataArrayInt::findIdsEqualList(const int *valsBg, const int *valsEnd) const
8179 {
8180   if(getNumberOfComponents()!=1)
8181     throw INTERP_KERNEL::Exception("DataArrayInt::findIdsEqualList : the array must have only one component, you can call 'rearrange' method before !");
8182   std::set<int> vals2(valsBg,valsEnd);
8183   const int *cptr(getConstPointer());
8184   std::vector<int> res;
8185   int nbOfTuples(getNumberOfTuples());
8186   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
8187   for(int i=0;i<nbOfTuples;i++,cptr++)
8188     if(vals2.find(*cptr)!=vals2.end())
8189       ret->pushBackSilent(i);
8190   return ret.retn();
8191 }
8192
8193 /*!
8194  * Creates a new DataArrayInt containing IDs (indices) of tuples holding values \b not
8195  * equal to any of given values.
8196  *  \param [in] valsBg - an array of values to ignore within \a this array.
8197  *  \param [in] valsEnd - specifies the end of the array \a valsBg, so that
8198  *              the last value of \a valsBg is \a valsEnd[ -1 ].
8199  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
8200  *          array using decrRef() as it is no more needed.
8201  *  \throw If \a this->getNumberOfComponents() != 1.
8202  */
8203 DataArrayInt *DataArrayInt::findIdsNotEqualList(const int *valsBg, const int *valsEnd) const
8204 {
8205   if(getNumberOfComponents()!=1)
8206     throw INTERP_KERNEL::Exception("DataArrayInt::findIdsNotEqualList : the array must have only one component, you can call 'rearrange' method before !");
8207   std::set<int> vals2(valsBg,valsEnd);
8208   const int *cptr=getConstPointer();
8209   std::vector<int> res;
8210   int nbOfTuples=getNumberOfTuples();
8211   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
8212   for(int i=0;i<nbOfTuples;i++,cptr++)
8213     if(vals2.find(*cptr)==vals2.end())
8214       ret->pushBackSilent(i);
8215   return ret.retn();
8216 }
8217
8218 /*!
8219  * This method is an extension of DataArrayInt::findIdFirstEqual method because this method works for DataArrayInt with
8220  * any number of components excepted 0 (an INTERP_KERNEL::Exception is thrown in this case).
8221  * This method searches in \b this is there is a tuple that matched the input parameter \b tupl.
8222  * If any the tuple id is returned. If not -1 is returned.
8223  * 
8224  * This method throws an INTERP_KERNEL::Exception if the number of components in \b this mismatches with the size of
8225  * the input vector. An INTERP_KERNEL::Exception is thrown too if \b this is not allocated.
8226  *
8227  * \return tuple id where \b tupl is. -1 if no such tuple exists in \b this.
8228  * \sa DataArrayInt::findIdSequence, DataArrayInt::presenceOfTuple.
8229  */
8230 int DataArrayInt::findIdFirstEqualTuple(const std::vector<int>& tupl) const
8231 {
8232   checkAllocated();
8233   int nbOfCompo=getNumberOfComponents();
8234   if(nbOfCompo==0)
8235     throw INTERP_KERNEL::Exception("DataArrayInt::findIdFirstEqualTuple : 0 components in 'this' !");
8236   if(nbOfCompo!=(int)tupl.size())
8237     {
8238       std::ostringstream oss; oss << "DataArrayInt::findIdFirstEqualTuple : 'this' contains " << nbOfCompo << " components and searching for a tuple of length " << tupl.size() << " !";
8239       throw INTERP_KERNEL::Exception(oss.str().c_str());
8240     }
8241   const int *cptr=getConstPointer();
8242   std::size_t nbOfVals=getNbOfElems();
8243   for(const int *work=cptr;work!=cptr+nbOfVals;)
8244     {
8245       work=std::search(work,cptr+nbOfVals,tupl.begin(),tupl.end());
8246       if(work!=cptr+nbOfVals)
8247         {
8248           if(std::distance(cptr,work)%nbOfCompo!=0)
8249             work++;
8250           else
8251             return std::distance(cptr,work)/nbOfCompo;
8252         }
8253     }
8254   return -1;
8255 }
8256
8257 /*!
8258  * This method searches the sequence specified in input parameter \b vals in \b this.
8259  * This works only for DataArrayInt having number of components equal to one (if not an INTERP_KERNEL::Exception will be thrown).
8260  * This method differs from DataArrayInt::findIdFirstEqualTuple in that the position is internal raw data is not considered here contrary to DataArrayInt::findIdFirstEqualTuple.
8261  * \sa DataArrayInt::findIdFirstEqualTuple
8262  */
8263 int DataArrayInt::findIdSequence(const std::vector<int>& vals) const
8264 {
8265   checkAllocated();
8266   int nbOfCompo=getNumberOfComponents();
8267   if(nbOfCompo!=1)
8268     throw INTERP_KERNEL::Exception("DataArrayInt::findIdSequence : works only for DataArrayInt instance with one component !");
8269   const int *cptr=getConstPointer();
8270   std::size_t nbOfVals=getNbOfElems();
8271   const int *loc=std::search(cptr,cptr+nbOfVals,vals.begin(),vals.end());
8272   if(loc!=cptr+nbOfVals)
8273     return std::distance(cptr,loc);
8274   return -1;
8275 }
8276
8277 /*!
8278  * This method expects to be called when number of components of this is equal to one.
8279  * This method returns the tuple id, if it exists, of the first tuple equal to \b value.
8280  * If not any tuple contains \b value -1 is returned.
8281  * \sa DataArrayInt::presenceOfValue
8282  */
8283 int DataArrayInt::findIdFirstEqual(int value) const
8284 {
8285   checkAllocated();
8286   if(getNumberOfComponents()!=1)
8287     throw INTERP_KERNEL::Exception("DataArrayInt::presenceOfValue : the array must have only one component, you can call 'rearrange' method before !");
8288   const int *cptr=getConstPointer();
8289   int nbOfTuples=getNumberOfTuples();
8290   const int *ret=std::find(cptr,cptr+nbOfTuples,value);
8291   if(ret!=cptr+nbOfTuples)
8292     return std::distance(cptr,ret);
8293   return -1;
8294 }
8295
8296 /*!
8297  * This method expects to be called when number of components of this is equal to one.
8298  * This method returns the tuple id, if it exists, of the first tuple so that the value is contained in \b vals.
8299  * If not any tuple contains one of the values contained in 'vals' -1 is returned.
8300  * \sa DataArrayInt::presenceOfValue
8301  */
8302 int DataArrayInt::findIdFirstEqual(const std::vector<int>& vals) const
8303 {
8304   checkAllocated();
8305   if(getNumberOfComponents()!=1)
8306     throw INTERP_KERNEL::Exception("DataArrayInt::presenceOfValue : the array must have only one component, you can call 'rearrange' method before !");
8307   std::set<int> vals2(vals.begin(),vals.end());
8308   const int *cptr=getConstPointer();
8309   int nbOfTuples=getNumberOfTuples();
8310   for(const int *w=cptr;w!=cptr+nbOfTuples;w++)
8311     if(vals2.find(*w)!=vals2.end())
8312       return std::distance(cptr,w);
8313   return -1;
8314 }
8315
8316 /*!
8317  * This method returns the number of values in \a this that are equals to input parameter \a value.
8318  * This method only works for single component array.
8319  *
8320  * \return a value in [ 0, \c this->getNumberOfTuples() )
8321  *
8322  * \throw If \a this is not allocated
8323  *
8324  */
8325 int DataArrayInt::count(int value) const
8326 {
8327   int ret=0;
8328   checkAllocated();
8329   if(getNumberOfComponents()!=1)
8330     throw INTERP_KERNEL::Exception("DataArrayInt::count : must be applied on DataArrayInt with only one component, you can call 'rearrange' method before !");
8331   const int *vals=begin();
8332   int nbOfTuples=getNumberOfTuples();
8333   for(int i=0;i<nbOfTuples;i++,vals++)
8334     if(*vals==value)
8335       ret++;
8336   return ret;
8337 }
8338
8339 /*!
8340  * This method is an extension of DataArrayInt::presenceOfValue method because this method works for DataArrayInt with
8341  * any number of components excepted 0 (an INTERP_KERNEL::Exception is thrown in this case).
8342  * This method searches in \b this is there is a tuple that matched the input parameter \b tupl.
8343  * This method throws an INTERP_KERNEL::Exception if the number of components in \b this mismatches with the size of
8344  * the input vector. An INTERP_KERNEL::Exception is thrown too if \b this is not allocated.
8345  * \sa DataArrayInt::findIdFirstEqualTuple
8346  */
8347 bool DataArrayInt::presenceOfTuple(const std::vector<int>& tupl) const
8348 {
8349   return findIdFirstEqualTuple(tupl)!=-1;
8350 }
8351
8352
8353 /*!
8354  * Returns \a true if a given value is present within \a this one-dimensional array.
8355  *  \param [in] value - the value to find within \a this array.
8356  *  \return bool - \a true in case if \a value is present within \a this array.
8357  *  \throw If \a this is not allocated.
8358  *  \throw If \a this->getNumberOfComponents() != 1.
8359  *  \sa findIdFirstEqual()
8360  */
8361 bool DataArrayInt::presenceOfValue(int value) const
8362 {
8363   return findIdFirstEqual(value)!=-1;
8364 }
8365
8366 /*!
8367  * This method expects to be called when number of components of this is equal to one.
8368  * This method returns true if it exists a tuple so that the value is contained in \b vals.
8369  * If not any tuple contains one of the values contained in 'vals' false is returned.
8370  * \sa DataArrayInt::findIdFirstEqual
8371  */
8372 bool DataArrayInt::presenceOfValue(const std::vector<int>& vals) const
8373 {
8374   return findIdFirstEqual(vals)!=-1;
8375 }
8376
8377 /*!
8378  * Accumulates values of each component of \a this array.
8379  *  \param [out] res - an array of length \a this->getNumberOfComponents(), allocated 
8380  *         by the caller, that is filled by this method with sum value for each
8381  *         component.
8382  *  \throw If \a this is not allocated.
8383  */
8384 void DataArrayInt::accumulate(int *res) const
8385 {
8386   checkAllocated();
8387   const int *ptr=getConstPointer();
8388   int nbTuple=getNumberOfTuples();
8389   int nbComps=getNumberOfComponents();
8390   std::fill(res,res+nbComps,0);
8391   for(int i=0;i<nbTuple;i++)
8392     std::transform(ptr+i*nbComps,ptr+(i+1)*nbComps,res,res,std::plus<int>());
8393 }
8394
8395 int DataArrayInt::accumulate(int compId) const
8396 {
8397   checkAllocated();
8398   const int *ptr=getConstPointer();
8399   int nbTuple=getNumberOfTuples();
8400   int nbComps=getNumberOfComponents();
8401   if(compId<0 || compId>=nbComps)
8402     throw INTERP_KERNEL::Exception("DataArrayInt::accumulate : Invalid compId specified : No such nb of components !");
8403   int ret=0;
8404   for(int i=0;i<nbTuple;i++)
8405     ret+=ptr[i*nbComps+compId];
8406   return ret;
8407 }
8408
8409 /*!
8410  * This method accumulate using addition tuples in \a this using input index array [ \a bgOfIndex, \a endOfIndex ).
8411  * The returned array will have same number of components than \a this and number of tuples equal to
8412  * \c std::distance(bgOfIndex,endOfIndex) \b minus \b one.
8413  *
8414  * The input index array is expected to be ascendingly sorted in which the all referenced ids should be in [0, \c this->getNumberOfTuples).
8415  *
8416  * \param [in] bgOfIndex - begin (included) of the input index array.
8417  * \param [in] endOfIndex - end (excluded) of the input index array.
8418  * \return DataArrayInt * - the new instance having the same number of components than \a this.
8419  * 
8420  * \throw If bgOfIndex or end is NULL.
8421  * \throw If input index array is not ascendingly sorted.
8422  * \throw If there is an id in [ \a bgOfIndex, \a endOfIndex ) not in [0, \c this->getNumberOfTuples).
8423  * \throw If std::distance(bgOfIndex,endOfIndex)==0.
8424  */
8425 DataArrayInt *DataArrayInt::accumulatePerChunck(const int *bgOfIndex, const int *endOfIndex) const
8426 {
8427   if(!bgOfIndex || !endOfIndex)
8428     throw INTERP_KERNEL::Exception("DataArrayInt::accumulatePerChunck : input pointer NULL !");
8429   checkAllocated();
8430   int nbCompo=getNumberOfComponents();
8431   int nbOfTuples=getNumberOfTuples();
8432   int sz=(int)std::distance(bgOfIndex,endOfIndex);
8433   if(sz<1)
8434     throw INTERP_KERNEL::Exception("DataArrayInt::accumulatePerChunck : invalid size of input index array !");
8435   sz--;
8436   MCAuto<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(sz,nbCompo);
8437   const int *w=bgOfIndex;
8438   if(*w<0 || *w>=nbOfTuples)
8439     throw INTERP_KERNEL::Exception("DataArrayInt::accumulatePerChunck : The first element of the input index not in [0,nbOfTuples) !");
8440   const int *srcPt=begin()+(*w)*nbCompo;
8441   int *tmp=ret->getPointer();
8442   for(int i=0;i<sz;i++,tmp+=nbCompo,w++)
8443     {
8444       std::fill(tmp,tmp+nbCompo,0);
8445       if(w[1]>=w[0])
8446         {
8447           for(int j=w[0];j<w[1];j++,srcPt+=nbCompo)
8448             {
8449               if(j>=0 && j<nbOfTuples)
8450                 std::transform(srcPt,srcPt+nbCompo,tmp,tmp,std::plus<int>());
8451               else
8452                 {
8453                   std::ostringstream oss; oss << "DataArrayInt::accumulatePerChunck : At rank #" << i << " the input index array points to id " << j << " should be in [0," << nbOfTuples << ") !";
8454                   throw INTERP_KERNEL::Exception(oss.str().c_str());
8455                 }
8456             }
8457         }
8458       else
8459         {
8460           std::ostringstream oss; oss << "DataArrayInt::accumulatePerChunck : At rank #" << i << " the input index array is not in ascendingly sorted.";
8461           throw INTERP_KERNEL::Exception(oss.str().c_str());
8462         }
8463     }
8464   ret->copyStringInfoFrom(*this);
8465   return ret.retn();
8466 }
8467
8468 /*!
8469  * Returns a new DataArrayInt by concatenating two given arrays, so that (1) the number
8470  * of tuples in the result array is <em> a1->getNumberOfTuples() + a2->getNumberOfTuples() -
8471  * offsetA2</em> and (2)
8472  * the number of component in the result array is same as that of each of given arrays.
8473  * First \a offsetA2 tuples of \a a2 are skipped and thus are missing from the result array.
8474  * Info on components is copied from the first of the given arrays. Number of components
8475  * in the given arrays must be the same.
8476  *  \param [in] a1 - an array to include in the result array.
8477  *  \param [in] a2 - another array to include in the result array.
8478  *  \param [in] offsetA2 - number of tuples of \a a2 to skip.
8479  *  \return DataArrayInt * - the new instance of DataArrayInt.
8480  *          The caller is to delete this result array using decrRef() as it is no more
8481  *          needed.
8482  *  \throw If either \a a1 or \a a2 is NULL.
8483  *  \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents().
8484  */
8485 DataArrayInt *DataArrayInt::Aggregate(const DataArrayInt *a1, const DataArrayInt *a2, int offsetA2)
8486 {
8487   if(!a1 || !a2)
8488     throw INTERP_KERNEL::Exception("DataArrayInt::Aggregate : input DataArrayInt instance is NULL !");
8489   int nbOfComp=a1->getNumberOfComponents();
8490   if(nbOfComp!=a2->getNumberOfComponents())
8491     throw INTERP_KERNEL::Exception("Nb of components mismatch for array Aggregation !");
8492   int nbOfTuple1=a1->getNumberOfTuples();
8493   int nbOfTuple2=a2->getNumberOfTuples();
8494   DataArrayInt *ret=DataArrayInt::New();
8495   ret->alloc(nbOfTuple1+nbOfTuple2-offsetA2,nbOfComp);
8496   int *pt=std::copy(a1->getConstPointer(),a1->getConstPointer()+nbOfTuple1*nbOfComp,ret->getPointer());
8497   std::copy(a2->getConstPointer()+offsetA2*nbOfComp,a2->getConstPointer()+nbOfTuple2*nbOfComp,pt);
8498   ret->copyStringInfoFrom(*a1);
8499   return ret;
8500 }
8501
8502 /*!
8503  * Returns a new DataArrayInt by concatenating all given arrays, so that (1) the number
8504  * of tuples in the result array is a sum of the number of tuples of given arrays and (2)
8505  * the number of component in the result array is same as that of each of given arrays.
8506  * Info on components is copied from the first of the given arrays. Number of components
8507  * in the given arrays must be  the same.
8508  * If the number of non null of elements in \a arr is equal to one the returned object is a copy of it
8509  * not the object itself.
8510  *  \param [in] arr - a sequence of arrays to include in the result array.
8511  *  \return DataArrayInt * - the new instance of DataArrayInt.
8512  *          The caller is to delete this result array using decrRef() as it is no more
8513  *          needed.
8514  *  \throw If all arrays within \a arr are NULL.
8515  *  \throw If getNumberOfComponents() of arrays within \a arr.
8516  */
8517 DataArrayInt *DataArrayInt::Aggregate(const std::vector<const DataArrayInt *>& arr)
8518 {
8519   std::vector<const DataArrayInt *> a;
8520   for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
8521     if(*it4)
8522       a.push_back(*it4);
8523   if(a.empty())
8524     throw INTERP_KERNEL::Exception("DataArrayInt::Aggregate : input list must be NON EMPTY !");
8525   std::vector<const DataArrayInt *>::const_iterator it=a.begin();
8526   int nbOfComp=(*it)->getNumberOfComponents();
8527   int nbt=(*it++)->getNumberOfTuples();
8528   for(int i=1;it!=a.end();it++,i++)
8529     {
8530       if((*it)->getNumberOfComponents()!=nbOfComp)
8531         throw INTERP_KERNEL::Exception("DataArrayInt::Aggregate : Nb of components mismatch for array aggregation !");
8532       nbt+=(*it)->getNumberOfTuples();
8533     }
8534   MCAuto<DataArrayInt> ret=DataArrayInt::New();
8535   ret->alloc(nbt,nbOfComp);
8536   int *pt=ret->getPointer();
8537   for(it=a.begin();it!=a.end();it++)
8538     pt=std::copy((*it)->getConstPointer(),(*it)->getConstPointer()+(*it)->getNbOfElems(),pt);
8539   ret->copyStringInfoFrom(*(a[0]));
8540   return ret.retn();
8541 }
8542
8543 /*!
8544  * This method takes as input a list of DataArrayInt instances \a arrs that represent each a packed index arrays.
8545  * A packed index array is an allocated array with one component, and at least one tuple. The first element
8546  * of each array in \a arrs must be 0. Each array in \a arrs is expected to be increasingly monotonic.
8547  * 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.
8548  * 
8549  * \return DataArrayInt * - a new object to be managed by the caller.
8550  */
8551 DataArrayInt *DataArrayInt::AggregateIndexes(const std::vector<const DataArrayInt *>& arrs)
8552 {
8553   int retSz=1;
8554   for(std::vector<const DataArrayInt *>::const_iterator it4=arrs.begin();it4!=arrs.end();it4++)
8555     {
8556       if(*it4)
8557         {
8558           (*it4)->checkAllocated();
8559           if((*it4)->getNumberOfComponents()!=1)
8560             {
8561               std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a DataArrayInt instance with nb of compo != 1 at pos " << std::distance(arrs.begin(),it4) << " !";
8562               throw INTERP_KERNEL::Exception(oss.str().c_str());
8563             }
8564           int nbTupl=(*it4)->getNumberOfTuples();
8565           if(nbTupl<1)
8566             {
8567               std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a DataArrayInt instance with nb of tuples < 1 at pos " << std::distance(arrs.begin(),it4) << " !";
8568               throw INTERP_KERNEL::Exception(oss.str().c_str());
8569             }
8570           if((*it4)->front()!=0)
8571             {
8572               std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a DataArrayInt instance with front value != 0 at pos " << std::distance(arrs.begin(),it4) << " !";
8573               throw INTERP_KERNEL::Exception(oss.str().c_str());
8574             }
8575           retSz+=nbTupl-1;
8576         }
8577       else
8578         {
8579           std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a null instance at pos " << std::distance(arrs.begin(),it4) << " !";
8580           throw INTERP_KERNEL::Exception(oss.str().c_str());
8581         }
8582     }
8583   if(arrs.empty())
8584     throw INTERP_KERNEL::Exception("DataArrayInt::AggregateIndexes : input list must be NON EMPTY !");
8585   MCAuto<DataArrayInt> ret=DataArrayInt::New();
8586   ret->alloc(retSz,1);
8587   int *pt=ret->getPointer(); *pt++=0;
8588   for(std::vector<const DataArrayInt *>::const_iterator it=arrs.begin();it!=arrs.end();it++)
8589     pt=std::transform((*it)->begin()+1,(*it)->end(),pt,std::bind2nd(std::plus<int>(),pt[-1]));
8590   ret->copyStringInfoFrom(*(arrs[0]));
8591   return ret.retn();
8592 }
8593
8594 /*!
8595  * Returns the maximal value and its location within \a this one-dimensional array.
8596  *  \param [out] tupleId - index of the tuple holding the maximal value.
8597  *  \return int - the maximal value among all values of \a this array.
8598  *  \throw If \a this->getNumberOfComponents() != 1
8599  *  \throw If \a this->getNumberOfTuples() < 1
8600  */
8601 int DataArrayInt::getMaxValue(int& tupleId) const
8602 {
8603   checkAllocated();
8604   if(getNumberOfComponents()!=1)
8605     throw INTERP_KERNEL::Exception("DataArrayInt::getMaxValue : must be applied on DataArrayInt with only one component !");
8606   int nbOfTuples=getNumberOfTuples();
8607   if(nbOfTuples<=0)
8608     throw INTERP_KERNEL::Exception("DataArrayInt::getMaxValue : array exists but number of tuples must be > 0 !");
8609   const int *vals=getConstPointer();
8610   const int *loc=std::max_element(vals,vals+nbOfTuples);
8611   tupleId=(int)std::distance(vals,loc);
8612   return *loc;
8613 }
8614
8615 /*!
8616  * Returns the maximal value within \a this array that is allowed to have more than
8617  *  one component.
8618  *  \return int - the maximal value among all values of \a this array.
8619  *  \throw If \a this is not allocated.
8620  */
8621 int DataArrayInt::getMaxValueInArray() const
8622 {
8623   checkAllocated();
8624   const int *loc=std::max_element(begin(),end());
8625   return *loc;
8626 }
8627
8628 /*!
8629  * Returns the minimal value and its location within \a this one-dimensional array.
8630  *  \param [out] tupleId - index of the tuple holding the minimal value.
8631  *  \return int - the minimal value among all values of \a this array.
8632  *  \throw If \a this->getNumberOfComponents() != 1
8633  *  \throw If \a this->getNumberOfTuples() < 1
8634  */
8635 int DataArrayInt::getMinValue(int& tupleId) const
8636 {
8637   checkAllocated();
8638   if(getNumberOfComponents()!=1)
8639     throw INTERP_KERNEL::Exception("DataArrayInt::getMaxValue : must be applied on DataArrayInt with only one component !");
8640   int nbOfTuples=getNumberOfTuples();
8641   if(nbOfTuples<=0)
8642     throw INTERP_KERNEL::Exception("DataArrayInt::getMaxValue : array exists but number of tuples must be > 0 !");
8643   const int *vals=getConstPointer();
8644   const int *loc=std::min_element(vals,vals+nbOfTuples);
8645   tupleId=(int)std::distance(vals,loc);
8646   return *loc;
8647 }
8648
8649 /*!
8650  * Returns the minimal value within \a this array that is allowed to have more than
8651  *  one component.
8652  *  \return int - the minimal value among all values of \a this array.
8653  *  \throw If \a this is not allocated.
8654  */
8655 int DataArrayInt::getMinValueInArray() const
8656 {
8657   checkAllocated();
8658   const int *loc=std::min_element(begin(),end());
8659   return *loc;
8660 }
8661
8662 /*!
8663  * Returns in a single walk in \a this the min value and the max value in \a this.
8664  * \a this is expected to be single component array.
8665  *
8666  * \param [out] minValue - the min value in \a this.
8667  * \param [out] maxValue - the max value in \a this.
8668  *
8669  * \sa getMinValueInArray, getMinValue, getMaxValueInArray, getMaxValue
8670  */
8671 void DataArrayInt::getMinMaxValues(int& minValue, int& maxValue) const
8672 {
8673   checkAllocated();
8674   if(getNumberOfComponents()!=1)
8675     throw INTERP_KERNEL::Exception("DataArrayInt::getMinMaxValues : must be applied on DataArrayInt with only one component !");
8676   int nbTuples(getNumberOfTuples());
8677   const int *pt(begin());
8678   minValue=std::numeric_limits<int>::max(); maxValue=-std::numeric_limits<int>::max();
8679   for(int i=0;i<nbTuples;i++,pt++)
8680     {
8681       if(*pt<minValue)
8682         minValue=*pt;
8683       if(*pt>maxValue)
8684         maxValue=*pt;
8685     }
8686 }
8687
8688 /*!
8689  * Converts every value of \a this array to its absolute value.
8690  * \b WARNING this method is non const. If a new DataArrayInt instance should be built containing the result of abs DataArrayInt::computeAbs
8691  * should be called instead.
8692  *
8693  * \throw If \a this is not allocated.
8694  * \sa DataArrayInt::computeAbs
8695  */
8696 void DataArrayInt::abs()
8697 {
8698   checkAllocated();
8699   int *ptr(getPointer());
8700   std::size_t nbOfElems(getNbOfElems());
8701   std::transform(ptr,ptr+nbOfElems,ptr,std::ptr_fun<int,int>(std::abs));
8702   declareAsNew();
8703 }
8704
8705 /*!
8706  * This method builds a new instance of \a this object containing the result of std::abs applied of all elements in \a this.
8707  * This method is a const method (that do not change any values in \a this) contrary to  DataArrayInt::abs method.
8708  *
8709  * \return DataArrayInt * - the new instance of DataArrayInt containing the
8710  *         same number of tuples and component as \a this array.
8711  *         The caller is to delete this result array using decrRef() as it is no more
8712  *         needed.
8713  * \throw If \a this is not allocated.
8714  * \sa DataArrayInt::abs
8715  */
8716 DataArrayInt *DataArrayInt::computeAbs() const
8717 {
8718   checkAllocated();
8719   DataArrayInt *newArr(DataArrayInt::New());
8720   int nbOfTuples(getNumberOfTuples());
8721   int nbOfComp(getNumberOfComponents());
8722   newArr->alloc(nbOfTuples,nbOfComp);
8723   std::transform(begin(),end(),newArr->getPointer(),std::ptr_fun<int,int>(std::abs));
8724   newArr->copyStringInfoFrom(*this);
8725   return newArr;
8726 }
8727
8728 /*!
8729  * Apply a liner function to a given component of \a this array, so that
8730  * an array element <em>(x)</em> becomes \f$ a * x + b \f$.
8731  *  \param [in] a - the first coefficient of the function.
8732  *  \param [in] b - the second coefficient of the function.
8733  *  \param [in] compoId - the index of component to modify.
8734  *  \throw If \a this is not allocated.
8735  */
8736 void DataArrayInt::applyLin(int a, int b, int compoId)
8737 {
8738   checkAllocated();
8739   int *ptr=getPointer()+compoId;
8740   int nbOfComp=getNumberOfComponents();
8741   int nbOfTuple=getNumberOfTuples();
8742   for(int i=0;i<nbOfTuple;i++,ptr+=nbOfComp)
8743     *ptr=a*(*ptr)+b;
8744   declareAsNew();
8745 }
8746
8747 /*!
8748  * Apply a liner function to all elements of \a this array, so that
8749  * an element _x_ becomes \f$ a * x + b \f$.
8750  *  \param [in] a - the first coefficient of the function.
8751  *  \param [in] b - the second coefficient of the function.
8752  *  \throw If \a this is not allocated.
8753  */
8754 void DataArrayInt::applyLin(int a, int b)
8755 {
8756   checkAllocated();
8757   int *ptr=getPointer();
8758   std::size_t nbOfElems=getNbOfElems();
8759   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
8760     *ptr=a*(*ptr)+b;
8761   declareAsNew();
8762 }
8763
8764 /*!
8765  * Returns a full copy of \a this array except that sign of all elements is reversed.
8766  *  \return DataArrayInt * - the new instance of DataArrayInt containing the
8767  *          same number of tuples and component as \a this array.
8768  *          The caller is to delete this result array using decrRef() as it is no more
8769  *          needed.
8770  *  \throw If \a this is not allocated.
8771  */
8772 DataArrayInt *DataArrayInt::negate() const
8773 {
8774   checkAllocated();
8775   DataArrayInt *newArr=DataArrayInt::New();
8776   int nbOfTuples=getNumberOfTuples();
8777   int nbOfComp=getNumberOfComponents();
8778   newArr->alloc(nbOfTuples,nbOfComp);
8779   const int *cptr=getConstPointer();
8780   std::transform(cptr,cptr+nbOfTuples*nbOfComp,newArr->getPointer(),std::negate<int>());
8781   newArr->copyStringInfoFrom(*this);
8782   return newArr;
8783 }
8784
8785 /*!
8786  * Modify all elements of \a this array, so that
8787  * an element _x_ becomes \f$ numerator / x \f$.
8788  *  \warning If an exception is thrown because of presence of 0 element in \a this 
8789  *           array, all elements processed before detection of the zero element remain
8790  *           modified.
8791  *  \param [in] numerator - the numerator used to modify array elements.
8792  *  \throw If \a this is not allocated.
8793  *  \throw If there is an element equal to 0 in \a this array.
8794  */
8795 void DataArrayInt::applyInv(int numerator)
8796 {
8797   checkAllocated();
8798   int *ptr=getPointer();
8799   std::size_t nbOfElems=getNbOfElems();
8800   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
8801     {
8802       if(*ptr!=0)
8803         {
8804           *ptr=numerator/(*ptr);
8805         }
8806       else
8807         {
8808           std::ostringstream oss; oss << "DataArrayInt::applyInv : presence of null value in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
8809           oss << " !";
8810           throw INTERP_KERNEL::Exception(oss.str().c_str());
8811         }
8812     }
8813   declareAsNew();
8814 }
8815
8816 /*!
8817  * Modify all elements of \a this array, so that
8818  * an element _x_ becomes \f$ x / val \f$.
8819  *  \param [in] val - the denominator used to modify array elements.
8820  *  \throw If \a this is not allocated.
8821  *  \throw If \a val == 0.
8822  */
8823 void DataArrayInt::applyDivideBy(int val)
8824 {
8825   if(val==0)
8826     throw INTERP_KERNEL::Exception("DataArrayInt::applyDivideBy : Trying to divide by 0 !");
8827   checkAllocated();
8828   int *ptr=getPointer();
8829   std::size_t nbOfElems=getNbOfElems();
8830   std::transform(ptr,ptr+nbOfElems,ptr,std::bind2nd(std::divides<int>(),val));
8831   declareAsNew();
8832 }
8833
8834 /*!
8835  * Modify all elements of \a this array, so that
8836  * an element _x_ becomes  <em> x % val </em>.
8837  *  \param [in] val - the divisor used to modify array elements.
8838  *  \throw If \a this is not allocated.
8839  *  \throw If \a val <= 0.
8840  */
8841 void DataArrayInt::applyModulus(int val)
8842 {
8843   if(val<=0)
8844     throw INTERP_KERNEL::Exception("DataArrayInt::applyDivideBy : Trying to operate modulus on value <= 0 !");
8845   checkAllocated();
8846   int *ptr=getPointer();
8847   std::size_t nbOfElems=getNbOfElems();
8848   std::transform(ptr,ptr+nbOfElems,ptr,std::bind2nd(std::modulus<int>(),val));
8849   declareAsNew();
8850 }
8851
8852 /*!
8853  * This method works only on data array with one component.
8854  * This method returns a newly allocated array storing stored ascendantly tuple ids in \b this so that
8855  * this[*id] in [\b vmin,\b vmax)
8856  * 
8857  * \param [in] vmin begin of range. This value is included in range (included).
8858  * \param [in] vmax end of range. This value is \b not included in range (excluded).
8859  * \return a newly allocated data array that the caller should deal with.
8860  *
8861  * \sa DataArrayInt::findIdsNotInRange , DataArrayInt::findIdsStricltyNegative
8862  */
8863 DataArrayInt *DataArrayInt::findIdsInRange(int vmin, int vmax) const
8864 {
8865   checkAllocated();
8866   if(getNumberOfComponents()!=1)
8867     throw INTERP_KERNEL::Exception("DataArrayInt::findIdsInRange : this must have exactly one component !");
8868   const int *cptr(begin());
8869   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
8870   int nbOfTuples(getNumberOfTuples());
8871   for(int i=0;i<nbOfTuples;i++,cptr++)
8872     if(*cptr>=vmin && *cptr<vmax)
8873       ret->pushBackSilent(i);
8874   return ret.retn();
8875 }
8876
8877 /*!
8878  * This method works only on data array with one component.
8879  * This method returns a newly allocated array storing stored ascendantly tuple ids in \b this so that
8880  * this[*id] \b not in [\b vmin,\b vmax)
8881  * 
8882  * \param [in] vmin begin of range. This value is \b not included in range (excluded).
8883  * \param [in] vmax end of range. This value is included in range (included).
8884  * \return a newly allocated data array that the caller should deal with.
8885  * 
8886  * \sa DataArrayInt::findIdsInRange , DataArrayInt::findIdsStricltyNegative
8887  */
8888 DataArrayInt *DataArrayInt::findIdsNotInRange(int vmin, int vmax) const
8889 {
8890   checkAllocated();
8891   if(getNumberOfComponents()!=1)
8892     throw INTERP_KERNEL::Exception("DataArrayInt::findIdsNotInRange : this must have exactly one component !");
8893   const int *cptr(getConstPointer());
8894   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
8895   int nbOfTuples(getNumberOfTuples());
8896   for(int i=0;i<nbOfTuples;i++,cptr++)
8897     if(*cptr<vmin || *cptr>=vmax)
8898       ret->pushBackSilent(i);
8899   return ret.retn();
8900 }
8901
8902 /*!
8903  * This method works only on data array with one component. This method returns a newly allocated array storing stored ascendantly of tuple ids in \a this so that this[id]<0.
8904  *
8905  * \return a newly allocated data array that the caller should deal with.
8906  * \sa DataArrayInt::findIdsInRange
8907  */
8908 DataArrayInt *DataArrayInt::findIdsStricltyNegative() const
8909 {
8910   checkAllocated();
8911   if(getNumberOfComponents()!=1)
8912     throw INTERP_KERNEL::Exception("DataArrayInt::findIdsStricltyNegative : this must have exactly one component !");
8913   const int *cptr(getConstPointer());
8914   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
8915   int nbOfTuples(getNumberOfTuples());
8916   for(int i=0;i<nbOfTuples;i++,cptr++)
8917     if(*cptr<0)
8918       ret->pushBackSilent(i);
8919   return ret.retn();
8920 }
8921
8922 /*!
8923  * This method works only on data array with one component.
8924  * 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.
8925  * 
8926  * \param [in] vmin begin of range. This value is included in range (included).
8927  * \param [in] vmax end of range. This value is \b not included in range (excluded).
8928  * \return if all ids in \a this are so that (*this)[i]==i for all i in [ 0, \c this->getNumberOfTuples() ). */
8929 bool DataArrayInt::checkAllIdsInRange(int vmin, int vmax) const
8930 {
8931   checkAllocated();
8932   if(getNumberOfComponents()!=1)
8933     throw INTERP_KERNEL::Exception("DataArrayInt::checkAllIdsInRange : this must have exactly one component !");
8934   int nbOfTuples=getNumberOfTuples();
8935   bool ret=true;
8936   const int *cptr=getConstPointer();
8937   for(int i=0;i<nbOfTuples;i++,cptr++)
8938     {
8939       if(*cptr>=vmin && *cptr<vmax)
8940         { ret=ret && *cptr==i; }
8941       else
8942         {
8943           std::ostringstream oss; oss << "DataArrayInt::checkAllIdsInRange : tuple #" << i << " has value " << *cptr << " should be in [" << vmin << "," << vmax << ") !";
8944           throw INTERP_KERNEL::Exception(oss.str().c_str());
8945         }
8946     }
8947   return ret;
8948 }
8949
8950 /*!
8951  * Modify all elements of \a this array, so that
8952  * an element _x_ becomes <em> val % x </em>.
8953  *  \warning If an exception is thrown because of presence of an element <= 0 in \a this 
8954  *           array, all elements processed before detection of the zero element remain
8955  *           modified.
8956  *  \param [in] val - the divident used to modify array elements.
8957  *  \throw If \a this is not allocated.
8958  *  \throw If there is an element equal to or less than 0 in \a this array.
8959  */
8960 void DataArrayInt::applyRModulus(int val)
8961 {
8962   checkAllocated();
8963   int *ptr=getPointer();
8964   std::size_t nbOfElems=getNbOfElems();
8965   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
8966     {
8967       if(*ptr>0)
8968         {
8969           *ptr=val%(*ptr);
8970         }
8971       else
8972         {
8973           std::ostringstream oss; oss << "DataArrayInt::applyRModulus : presence of value <=0 in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
8974           oss << " !";
8975           throw INTERP_KERNEL::Exception(oss.str().c_str());
8976         }
8977     }
8978   declareAsNew();
8979 }
8980
8981 /*!
8982  * Modify all elements of \a this array, so that
8983  * an element _x_ becomes <em> val ^ x </em>.
8984  *  \param [in] val - the value used to apply pow on all array elements.
8985  *  \throw If \a this is not allocated.
8986  *  \throw If \a val < 0.
8987  */
8988 void DataArrayInt::applyPow(int val)
8989 {
8990   checkAllocated();
8991   if(val<0)
8992     throw INTERP_KERNEL::Exception("DataArrayInt::applyPow : input pow in < 0 !");
8993   int *ptr=getPointer();
8994   std::size_t nbOfElems=getNbOfElems();
8995   if(val==0)
8996     {
8997       std::fill(ptr,ptr+nbOfElems,1);
8998       return ;
8999     }
9000   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
9001     {
9002       int tmp=1;
9003       for(int j=0;j<val;j++)
9004         tmp*=*ptr;
9005       *ptr=tmp;
9006     }
9007   declareAsNew();
9008 }
9009
9010 /*!
9011  * Modify all elements of \a this array, so that
9012  * an element _x_ becomes \f$ val ^ x \f$.
9013  *  \param [in] val - the value used to apply pow on all array elements.
9014  *  \throw If \a this is not allocated.
9015  *  \throw If there is an element < 0 in \a this array.
9016  *  \warning If an exception is thrown because of presence of 0 element in \a this 
9017  *           array, all elements processed before detection of the zero element remain
9018  *           modified.
9019  */
9020 void DataArrayInt::applyRPow(int val)
9021 {
9022   checkAllocated();
9023   int *ptr=getPointer();
9024   std::size_t nbOfElems=getNbOfElems();
9025   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
9026     {
9027       if(*ptr>=0)
9028         {
9029           int tmp=1;
9030           for(int j=0;j<*ptr;j++)
9031             tmp*=val;
9032           *ptr=tmp;
9033         }
9034       else
9035         {
9036           std::ostringstream oss; oss << "DataArrayInt::applyRPow : presence of negative value in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
9037           oss << " !";
9038           throw INTERP_KERNEL::Exception(oss.str().c_str());
9039         }
9040     }
9041   declareAsNew();
9042 }
9043
9044 /*!
9045  * Returns a new DataArrayInt by aggregating two given arrays, so that (1) the number
9046  * of components in the result array is a sum of the number of components of given arrays
9047  * and (2) the number of tuples in the result array is same as that of each of given
9048  * arrays. In other words the i-th tuple of result array includes all components of
9049  * i-th tuples of all given arrays.
9050  * Number of tuples in the given arrays must be the same.
9051  *  \param [in] a1 - an array to include in the result array.
9052  *  \param [in] a2 - another array to include in the result array.
9053  *  \return DataArrayInt * - the new instance of DataArrayInt.
9054  *          The caller is to delete this result array using decrRef() as it is no more
9055  *          needed.
9056  *  \throw If both \a a1 and \a a2 are NULL.
9057  *  \throw If any given array is not allocated.
9058  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
9059  */
9060 DataArrayInt *DataArrayInt::Meld(const DataArrayInt *a1, const DataArrayInt *a2)
9061 {
9062   std::vector<const DataArrayInt *> arr(2);
9063   arr[0]=a1; arr[1]=a2;
9064   return Meld(arr);
9065 }
9066
9067 /*!
9068  * Returns a new DataArrayInt by aggregating all given arrays, so that (1) the number
9069  * of components in the result array is a sum of the number of components of given arrays
9070  * and (2) the number of tuples in the result array is same as that of each of given
9071  * arrays. In other words the i-th tuple of result array includes all components of
9072  * i-th tuples of all given arrays.
9073  * Number of tuples in the given arrays must be  the same.
9074  *  \param [in] arr - a sequence of arrays to include in the result array.
9075  *  \return DataArrayInt * - the new instance of DataArrayInt.
9076  *          The caller is to delete this result array using decrRef() as it is no more
9077  *          needed.
9078  *  \throw If all arrays within \a arr are NULL.
9079  *  \throw If any given array is not allocated.
9080  *  \throw If getNumberOfTuples() of arrays within \a arr is different.
9081  */
9082 DataArrayInt *DataArrayInt::Meld(const std::vector<const DataArrayInt *>& arr)
9083 {
9084   std::vector<const DataArrayInt *> a;
9085   for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
9086     if(*it4)
9087       a.push_back(*it4);
9088   if(a.empty())
9089     throw INTERP_KERNEL::Exception("DataArrayInt::Meld : array must be NON empty !");
9090   std::vector<const DataArrayInt *>::const_iterator it;
9091   for(it=a.begin();it!=a.end();it++)
9092     (*it)->checkAllocated();
9093   it=a.begin();
9094   int nbOfTuples=(*it)->getNumberOfTuples();
9095   std::vector<int> nbc(a.size());
9096   std::vector<const int *> pts(a.size());
9097   nbc[0]=(*it)->getNumberOfComponents();
9098   pts[0]=(*it++)->getConstPointer();
9099   for(int i=1;it!=a.end();it++,i++)
9100     {
9101       if(nbOfTuples!=(*it)->getNumberOfTuples())
9102         throw INTERP_KERNEL::Exception("DataArrayInt::meld : mismatch of number of tuples !");
9103       nbc[i]=(*it)->getNumberOfComponents();
9104       pts[i]=(*it)->getConstPointer();
9105     }
9106   int totalNbOfComp=std::accumulate(nbc.begin(),nbc.end(),0);
9107   DataArrayInt *ret=DataArrayInt::New();
9108   ret->alloc(nbOfTuples,totalNbOfComp);
9109   int *retPtr=ret->getPointer();
9110   for(int i=0;i<nbOfTuples;i++)
9111     for(int j=0;j<(int)a.size();j++)
9112       {
9113         retPtr=std::copy(pts[j],pts[j]+nbc[j],retPtr);
9114         pts[j]+=nbc[j];
9115       }
9116   int k=0;
9117   for(int i=0;i<(int)a.size();i++)
9118     for(int j=0;j<nbc[i];j++,k++)
9119       ret->setInfoOnComponent(k,a[i]->getInfoOnComponent(j));
9120   return ret;
9121 }
9122
9123 /*!
9124  * Returns a new DataArrayInt which is a minimal partition of elements of \a groups.
9125  * The i-th item of the result array is an ID of a set of elements belonging to a
9126  * unique set of groups, which the i-th element is a part of. This set of elements
9127  * belonging to a unique set of groups is called \a family, so the result array contains
9128  * IDs of families each element belongs to.
9129  *
9130  * \b Example: if we have two groups of elements: \a group1 [0,4] and \a group2 [ 0,1,2 ],
9131  * then there are 3 families:
9132  * - \a family1 (with ID 1) contains element [0] belonging to ( \a group1 + \a group2 ),
9133  * - \a family2 (with ID 2) contains elements [4] belonging to ( \a group1 ),
9134  * - \a family3 (with ID 3) contains element [1,2] belonging to ( \a group2 ), <br>
9135  * and the result array contains IDs of families [ 1,3,3,0,2 ]. <br> Note a family ID 0 which
9136  * stands for the element #3 which is in none of groups.
9137  *
9138  *  \param [in] groups - sequence of groups of element IDs.
9139  *  \param [in] newNb - total number of elements; it must be more than max ID of element
9140  *         in \a groups.
9141  *  \param [out] fidsOfGroups - IDs of families the elements of each group belong to.
9142  *  \return DataArrayInt * - a new instance of DataArrayInt containing IDs of families
9143  *         each element with ID from range [0, \a newNb ) belongs to. The caller is to
9144  *         delete this array using decrRef() as it is no more needed.
9145  *  \throw If any element ID in \a groups violates condition ( 0 <= ID < \a newNb ).
9146  */
9147 DataArrayInt *DataArrayInt::MakePartition(const std::vector<const DataArrayInt *>& groups, int newNb, std::vector< std::vector<int> >& fidsOfGroups)
9148 {
9149   std::vector<const DataArrayInt *> groups2;
9150   for(std::vector<const DataArrayInt *>::const_iterator it4=groups.begin();it4!=groups.end();it4++)
9151     if(*it4)
9152       groups2.push_back(*it4);
9153   MCAuto<DataArrayInt> ret=DataArrayInt::New();
9154   ret->alloc(newNb,1);
9155   int *retPtr=ret->getPointer();
9156   std::fill(retPtr,retPtr+newNb,0);
9157   int fid=1;
9158   for(std::vector<const DataArrayInt *>::const_iterator iter=groups2.begin();iter!=groups2.end();iter++)
9159     {
9160       const int *ptr=(*iter)->getConstPointer();
9161       std::size_t nbOfElem=(*iter)->getNbOfElems();
9162       int sfid=fid;
9163       for(int j=0;j<sfid;j++)
9164         {
9165           bool found=false;
9166           for(std::size_t i=0;i<nbOfElem;i++)
9167             {
9168               if(ptr[i]>=0 && ptr[i]<newNb)
9169                 {
9170                   if(retPtr[ptr[i]]==j)
9171                     {
9172                       retPtr[ptr[i]]=fid;
9173                       found=true;
9174                     }
9175                 }
9176               else
9177                 {
9178                   std::ostringstream oss; oss << "DataArrayInt::MakePartition : In group \"" << (*iter)->getName() << "\" in tuple #" << i << " value = " << ptr[i] << " ! Should be in [0," << newNb;
9179                   oss << ") !";
9180                   throw INTERP_KERNEL::Exception(oss.str().c_str());
9181                 }
9182             }
9183           if(found)
9184             fid++;
9185         }
9186     }
9187   fidsOfGroups.clear();
9188   fidsOfGroups.resize(groups2.size());
9189   int grId=0;
9190   for(std::vector<const DataArrayInt *>::const_iterator iter=groups2.begin();iter!=groups2.end();iter++,grId++)
9191     {
9192       std::set<int> tmp;
9193       const int *ptr=(*iter)->getConstPointer();
9194       std::size_t nbOfElem=(*iter)->getNbOfElems();
9195       for(const int *p=ptr;p!=ptr+nbOfElem;p++)
9196         tmp.insert(retPtr[*p]);
9197       fidsOfGroups[grId].insert(fidsOfGroups[grId].end(),tmp.begin(),tmp.end());
9198     }
9199   return ret.retn();
9200 }
9201
9202 /*!
9203  * Returns a new DataArrayInt which contains all elements of given one-dimensional
9204  * arrays. The result array does not contain any duplicates and its values
9205  * are sorted in ascending order.
9206  *  \param [in] arr - sequence of DataArrayInt's to unite.
9207  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
9208  *         array using decrRef() as it is no more needed.
9209  *  \throw If any \a arr[i] is not allocated.
9210  *  \throw If \a arr[i]->getNumberOfComponents() != 1.
9211  */
9212 DataArrayInt *DataArrayInt::BuildUnion(const std::vector<const DataArrayInt *>& arr)
9213 {
9214   std::vector<const DataArrayInt *> a;
9215   for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
9216     if(*it4)
9217       a.push_back(*it4);
9218   for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
9219     {
9220       (*it)->checkAllocated();
9221       if((*it)->getNumberOfComponents()!=1)
9222         throw INTERP_KERNEL::Exception("DataArrayInt::BuildUnion : only single component allowed !");
9223     }
9224   //
9225   std::set<int> r;
9226   for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
9227     {
9228       const int *pt=(*it)->getConstPointer();
9229       int nbOfTuples=(*it)->getNumberOfTuples();
9230       r.insert(pt,pt+nbOfTuples);
9231     }
9232   DataArrayInt *ret=DataArrayInt::New();
9233   ret->alloc((int)r.size(),1);
9234   std::copy(r.begin(),r.end(),ret->getPointer());
9235   return ret;
9236 }
9237
9238 /*!
9239  * Returns a new DataArrayInt which contains elements present in each of given one-dimensional
9240  * arrays. The result array does not contain any duplicates and its values
9241  * are sorted in ascending order.
9242  *  \param [in] arr - sequence of DataArrayInt's to intersect.
9243  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
9244  *         array using decrRef() as it is no more needed.
9245  *  \throw If any \a arr[i] is not allocated.
9246  *  \throw If \a arr[i]->getNumberOfComponents() != 1.
9247  */
9248 DataArrayInt *DataArrayInt::BuildIntersection(const std::vector<const DataArrayInt *>& arr)
9249 {
9250   std::vector<const DataArrayInt *> a;
9251   for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
9252     if(*it4)
9253       a.push_back(*it4);
9254   for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
9255     {
9256       (*it)->checkAllocated();
9257       if((*it)->getNumberOfComponents()!=1)
9258         throw INTERP_KERNEL::Exception("DataArrayInt::BuildIntersection : only single component allowed !");
9259     }
9260   //
9261   std::set<int> r;
9262   for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
9263     {
9264       const int *pt=(*it)->getConstPointer();
9265       int nbOfTuples=(*it)->getNumberOfTuples();
9266       std::set<int> s1(pt,pt+nbOfTuples);
9267       if(it!=a.begin())
9268         {
9269           std::set<int> r2;
9270           std::set_intersection(r.begin(),r.end(),s1.begin(),s1.end(),inserter(r2,r2.end()));
9271           r=r2;
9272         }
9273       else
9274         r=s1;
9275     }
9276   DataArrayInt *ret(DataArrayInt::New());
9277   ret->alloc((int)r.size(),1);
9278   std::copy(r.begin(),r.end(),ret->getPointer());
9279   return ret;
9280 }
9281
9282 /// @cond INTERNAL
9283 namespace MEDCouplingImpl
9284 {
9285   class OpSwitchedOn
9286   {
9287   public:
9288     OpSwitchedOn(int *pt):_pt(pt),_cnt(0) { }
9289     void operator()(const bool& b) { if(b) *_pt++=_cnt; _cnt++; }
9290   private:
9291     int *_pt;
9292     int _cnt;
9293   };
9294
9295   class OpSwitchedOff
9296   {
9297   public:
9298     OpSwitchedOff(int *pt):_pt(pt),_cnt(0) { }
9299     void operator()(const bool& b) { if(!b) *_pt++=_cnt; _cnt++; }
9300   private:
9301     int *_pt;
9302     int _cnt;
9303   };
9304 }
9305 /// @endcond
9306
9307 /*!
9308  * This method returns the list of ids in ascending mode so that v[id]==true.
9309  */
9310 DataArrayInt *DataArrayInt::BuildListOfSwitchedOn(const std::vector<bool>& v)
9311 {
9312   int sz((int)std::count(v.begin(),v.end(),true));
9313   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(sz,1);
9314   std::for_each(v.begin(),v.end(),MEDCouplingImpl::OpSwitchedOn(ret->getPointer()));
9315   return ret.retn();
9316 }
9317
9318 /*!
9319  * This method returns the list of ids in ascending mode so that v[id]==false.
9320  */
9321 DataArrayInt *DataArrayInt::BuildListOfSwitchedOff(const std::vector<bool>& v)
9322 {
9323   int sz((int)std::count(v.begin(),v.end(),false));
9324   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(sz,1);
9325   std::for_each(v.begin(),v.end(),MEDCouplingImpl::OpSwitchedOff(ret->getPointer()));
9326   return ret.retn();
9327 }
9328
9329 /*!
9330  * This method allows to put a vector of vector of integer into a more compact data stucture (skyline). 
9331  * This method is not available into python because no available optimized data structure available to map std::vector< std::vector<int> >.
9332  *
9333  * \param [in] v the input data structure to be translate into skyline format.
9334  * \param [out] data the first element of the skyline format. The user is expected to deal with newly allocated array.
9335  * \param [out] dataIndex the second element of the skyline format.
9336  */
9337 void DataArrayInt::PutIntoToSkylineFrmt(const std::vector< std::vector<int> >& v, DataArrayInt *& data, DataArrayInt *& dataIndex)
9338 {
9339   int sz((int)v.size());
9340   MCAuto<DataArrayInt> ret0(DataArrayInt::New()),ret1(DataArrayInt::New());
9341   ret1->alloc(sz+1,1);
9342   int *pt(ret1->getPointer()); *pt=0;
9343   for(int i=0;i<sz;i++,pt++)
9344     pt[1]=pt[0]+(int)v[i].size();
9345   ret0->alloc(ret1->back(),1);
9346   pt=ret0->getPointer();
9347   for(int i=0;i<sz;i++)
9348     pt=std::copy(v[i].begin(),v[i].end(),pt);
9349   data=ret0.retn(); dataIndex=ret1.retn();
9350 }
9351
9352 /*!
9353  * Returns a new DataArrayInt which contains a complement of elements of \a this
9354  * one-dimensional array. I.e. the result array contains all elements from the range [0,
9355  * \a nbOfElement) not present in \a this array.
9356  *  \param [in] nbOfElement - maximal size of the result array.
9357  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
9358  *         array using decrRef() as it is no more needed.
9359  *  \throw If \a this is not allocated.
9360  *  \throw If \a this->getNumberOfComponents() != 1.
9361  *  \throw If any element \a x of \a this array violates condition ( 0 <= \a x < \a
9362  *         nbOfElement ).
9363  */
9364 DataArrayInt *DataArrayInt::buildComplement(int nbOfElement) const
9365 {
9366   checkAllocated();
9367   if(getNumberOfComponents()!=1)
9368     throw INTERP_KERNEL::Exception("DataArrayInt::buildComplement : only single component allowed !");
9369   std::vector<bool> tmp(nbOfElement);
9370   const int *pt=getConstPointer();
9371   int nbOfTuples=getNumberOfTuples();
9372   for(const int *w=pt;w!=pt+nbOfTuples;w++)
9373     if(*w>=0 && *w<nbOfElement)
9374       tmp[*w]=true;
9375     else
9376       throw INTERP_KERNEL::Exception("DataArrayInt::buildComplement : an element is not in valid range : [0,nbOfElement) !");
9377   int nbOfRetVal=(int)std::count(tmp.begin(),tmp.end(),false);
9378   DataArrayInt *ret=DataArrayInt::New();
9379   ret->alloc(nbOfRetVal,1);
9380   int j=0;
9381   int *retPtr=ret->getPointer();
9382   for(int i=0;i<nbOfElement;i++)
9383     if(!tmp[i])
9384       retPtr[j++]=i;
9385   return ret;
9386 }
9387
9388 /*!
9389  * Returns a new DataArrayInt containing elements of \a this one-dimensional missing
9390  * from an \a other one-dimensional array.
9391  *  \param [in] other - a DataArrayInt containing elements not to include in the result array.
9392  *  \return DataArrayInt * - a new instance of DataArrayInt with one component. The
9393  *         caller is to delete this array using decrRef() as it is no more needed.
9394  *  \throw If \a other is NULL.
9395  *  \throw If \a other is not allocated.
9396  *  \throw If \a other->getNumberOfComponents() != 1.
9397  *  \throw If \a this is not allocated.
9398  *  \throw If \a this->getNumberOfComponents() != 1.
9399  *  \sa DataArrayInt::buildSubstractionOptimized()
9400  */
9401 DataArrayInt *DataArrayInt::buildSubstraction(const DataArrayInt *other) const
9402 {
9403   if(!other)
9404     throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstraction : DataArrayInt pointer in input is NULL !");
9405   checkAllocated();
9406   other->checkAllocated();
9407   if(getNumberOfComponents()!=1)
9408     throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstraction : only single component allowed !");
9409   if(other->getNumberOfComponents()!=1)
9410     throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstraction : only single component allowed for other type !");
9411   const int *pt=getConstPointer();
9412   int nbOfTuples=getNumberOfTuples();
9413   std::set<int> s1(pt,pt+nbOfTuples);
9414   pt=other->getConstPointer();
9415   nbOfTuples=other->getNumberOfTuples();
9416   std::set<int> s2(pt,pt+nbOfTuples);
9417   std::vector<int> r;
9418   std::set_difference(s1.begin(),s1.end(),s2.begin(),s2.end(),std::back_insert_iterator< std::vector<int> >(r));
9419   DataArrayInt *ret=DataArrayInt::New();
9420   ret->alloc((int)r.size(),1);
9421   std::copy(r.begin(),r.end(),ret->getPointer());
9422   return ret;
9423 }
9424
9425 /*!
9426  * \a this is expected to have one component and to be sorted ascendingly (as for \a other).
9427  * \a other is expected to be a part of \a this. If not DataArrayInt::buildSubstraction should be called instead.
9428  * 
9429  * \param [in] other an array with one component and expected to be sorted ascendingly.
9430  * \ret list of ids in \a this but not in \a other.
9431  * \sa DataArrayInt::buildSubstraction
9432  */
9433 DataArrayInt *DataArrayInt::buildSubstractionOptimized(const DataArrayInt *other) const
9434 {
9435   static const char *MSG="DataArrayInt::buildSubstractionOptimized : only single component allowed !";
9436   if(!other) throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstractionOptimized : NULL input array !");
9437   checkAllocated(); other->checkAllocated();
9438   if(getNumberOfComponents()!=1) throw INTERP_KERNEL::Exception(MSG);
9439   if(other->getNumberOfComponents()!=1) throw INTERP_KERNEL::Exception(MSG);
9440   const int *pt1Bg(begin()),*pt1End(end()),*pt2Bg(other->begin()),*pt2End(other->end());
9441   const int *work1(pt1Bg),*work2(pt2Bg);
9442   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
9443   for(;work1!=pt1End;work1++)
9444     {
9445       if(work2!=pt2End && *work1==*work2)
9446         work2++;
9447       else
9448         ret->pushBackSilent(*work1);
9449     }
9450   return ret.retn();
9451 }
9452
9453
9454 /*!
9455  * Returns a new DataArrayInt which contains all elements of \a this and a given
9456  * one-dimensional arrays. The result array does not contain any duplicates
9457  * and its values are sorted in ascending order.
9458  *  \param [in] other - an array to unite with \a this one.
9459  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
9460  *         array using decrRef() as it is no more needed.
9461  *  \throw If \a this or \a other is not allocated.
9462  *  \throw If \a this->getNumberOfComponents() != 1.
9463  *  \throw If \a other->getNumberOfComponents() != 1.
9464  */
9465 DataArrayInt *DataArrayInt::buildUnion(const DataArrayInt *other) const
9466 {
9467   std::vector<const DataArrayInt *>arrs(2);
9468   arrs[0]=this; arrs[1]=other;
9469   return BuildUnion(arrs);
9470 }
9471
9472
9473 /*!
9474  * Returns a new DataArrayInt which contains elements present in both \a this and a given
9475  * one-dimensional arrays. The result array does not contain any duplicates
9476  * and its values are sorted in ascending order.
9477  *  \param [in] other - an array to intersect with \a this one.
9478  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
9479  *         array using decrRef() as it is no more needed.
9480  *  \throw If \a this or \a other is not allocated.
9481  *  \throw If \a this->getNumberOfComponents() != 1.
9482  *  \throw If \a other->getNumberOfComponents() != 1.
9483  */
9484 DataArrayInt *DataArrayInt::buildIntersection(const DataArrayInt *other) const
9485 {
9486   std::vector<const DataArrayInt *>arrs(2);
9487   arrs[0]=this; arrs[1]=other;
9488   return BuildIntersection(arrs);
9489 }
9490
9491 /*!
9492  * This method can be applied on allocated with one component DataArrayInt instance.
9493  * This method is typically relevant for sorted arrays. All consecutive duplicated items in \a this will appear only once in returned DataArrayInt instance.
9494  * 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]
9495  * 
9496  * \return a newly allocated array that contain the result of the unique operation applied on \a this.
9497  * \throw if \a this is not allocated or if \a this has not exactly one component.
9498  * \sa DataArrayInt::buildUniqueNotSorted
9499  */
9500 DataArrayInt *DataArrayInt::buildUnique() const
9501 {
9502   checkAllocated();
9503   if(getNumberOfComponents()!=1)
9504     throw INTERP_KERNEL::Exception("DataArrayInt::buildUnique : only single component allowed !");
9505   int nbOfTuples=getNumberOfTuples();
9506   MCAuto<DataArrayInt> tmp=deepCopy();
9507   int *data=tmp->getPointer();
9508   int *last=std::unique(data,data+nbOfTuples);
9509   MCAuto<DataArrayInt> ret=DataArrayInt::New();
9510   ret->alloc(std::distance(data,last),1);
9511   std::copy(data,last,ret->getPointer());
9512   return ret.retn();
9513 }
9514
9515 /*!
9516  * This method can be applied on allocated with one component DataArrayInt instance.
9517  * This method keep elements only once by keeping the same order in \a this that is not expected to be sorted.
9518  *
9519  * \return a newly allocated array that contain the result of the unique operation applied on \a this.
9520  *
9521  * \throw if \a this is not allocated or if \a this has not exactly one component.
9522  *
9523  * \sa DataArrayInt::buildUnique
9524  */
9525 DataArrayInt *DataArrayInt::buildUniqueNotSorted() const
9526 {
9527   checkAllocated();
9528     if(getNumberOfComponents()!=1)
9529       throw INTERP_KERNEL::Exception("DataArrayInt::buildUniqueNotSorted : only single component allowed !");
9530   int minVal,maxVal;
9531   getMinMaxValues(minVal,maxVal);
9532   std::vector<bool> b(maxVal-minVal+1,false);
9533   const int *ptBg(begin()),*endBg(end());
9534   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
9535   for(const int *pt=ptBg;pt!=endBg;pt++)
9536     {
9537       if(!b[*pt-minVal])
9538         {
9539           ret->pushBackSilent(*pt);
9540           b[*pt-minVal]=true;
9541         }
9542     }
9543   ret->copyStringInfoFrom(*this);
9544   return ret.retn();
9545 }
9546
9547 /*!
9548  * Returns a new DataArrayInt which contains size of every of groups described by \a this
9549  * "index" array. Such "index" array is returned for example by 
9550  * \ref MEDCoupling::MEDCouplingUMesh::buildDescendingConnectivity
9551  * "MEDCouplingUMesh::buildDescendingConnectivity" and
9552  * \ref MEDCoupling::MEDCouplingUMesh::getNodalConnectivityIndex
9553  * "MEDCouplingUMesh::getNodalConnectivityIndex" etc.
9554  * This method preforms the reverse operation of DataArrayInt::computeOffsetsFull.
9555  *  \return DataArrayInt * - a new instance of DataArrayInt, whose number of tuples
9556  *          equals to \a this->getNumberOfComponents() - 1, and number of components is 1.
9557  *          The caller is to delete this array using decrRef() as it is no more needed. 
9558  *  \throw If \a this is not allocated.
9559  *  \throw If \a this->getNumberOfComponents() != 1.
9560  *  \throw If \a this->getNumberOfTuples() < 2.
9561  *
9562  *  \b Example: <br> 
9563  *         - this contains [1,3,6,7,7,9,15]
9564  *         - result array contains [2,3,1,0,2,6],
9565  *          where 2 = 3 - 1, 3 = 6 - 3, 1 = 7 - 6 etc.
9566  *
9567  * \sa DataArrayInt::computeOffsetsFull
9568  */
9569 DataArrayInt *DataArrayInt::deltaShiftIndex() const
9570 {
9571   checkAllocated();
9572   if(getNumberOfComponents()!=1)
9573     throw INTERP_KERNEL::Exception("DataArrayInt::deltaShiftIndex : only single component allowed !");
9574   int nbOfTuples=getNumberOfTuples();
9575   if(nbOfTuples<2)
9576     throw INTERP_KERNEL::Exception("DataArrayInt::deltaShiftIndex : 1 tuple at least must be present in 'this' !");
9577   const int *ptr=getConstPointer();
9578   DataArrayInt *ret=DataArrayInt::New();
9579   ret->alloc(nbOfTuples-1,1);
9580   int *out=ret->getPointer();
9581   std::transform(ptr+1,ptr+nbOfTuples,ptr,out,std::minus<int>());
9582   return ret;
9583 }
9584
9585 /*!
9586  * Modifies \a this one-dimensional array so that value of each element \a x
9587  * of \a this array (\a a) is computed as \f$ x_i = \sum_{j=0}^{i-1} a[ j ] \f$.
9588  * Or: for each i>0 new[i]=new[i-1]+old[i-1] for i==0 new[i]=0. Number of tuples
9589  * and components remains the same.<br>
9590  * This method is useful for allToAllV in MPI with contiguous policy. This method
9591  * differs from computeOffsetsFull() in that the number of tuples is \b not changed by
9592  * this one.
9593  *  \throw If \a this is not allocated.
9594  *  \throw If \a this->getNumberOfComponents() != 1.
9595  *
9596  *  \b Example: <br>
9597  *          - Before \a this contains [3,5,1,2,0,8]
9598  *          - After \a this contains  [0,3,8,9,11,11]<br>
9599  *          Note that the last element 19 = 11 + 8 is missing because size of \a this
9600  *          array is retained and thus there is no space to store the last element.
9601  */
9602 void DataArrayInt::computeOffsets()
9603 {
9604   checkAllocated();
9605   if(getNumberOfComponents()!=1)
9606     throw INTERP_KERNEL::Exception("DataArrayInt::computeOffsets : only single component allowed !");
9607   int nbOfTuples=getNumberOfTuples();
9608   if(nbOfTuples==0)
9609     return ;
9610   int *work=getPointer();
9611   int tmp=work[0];
9612   work[0]=0;
9613   for(int i=1;i<nbOfTuples;i++)
9614     {
9615       int tmp2=work[i];
9616       work[i]=work[i-1]+tmp;
9617       tmp=tmp2;
9618     }
9619   declareAsNew();
9620 }
9621
9622
9623 /*!
9624  * Modifies \a this one-dimensional array so that value of each element \a x
9625  * of \a this array (\a a) is computed as \f$ x_i = \sum_{j=0}^{i-1} a[ j ] \f$.
9626  * Or: for each i>0 new[i]=new[i-1]+old[i-1] for i==0 new[i]=0. Number
9627  * components remains the same and number of tuples is inceamented by one.<br>
9628  * This method is useful for allToAllV in MPI with contiguous policy. This method
9629  * differs from computeOffsets() in that the number of tuples is changed by this one.
9630  * This method preforms the reverse operation of DataArrayInt::deltaShiftIndex.
9631  *  \throw If \a this is not allocated.
9632  *  \throw If \a this->getNumberOfComponents() != 1.
9633  *
9634  *  \b Example: <br>
9635  *          - Before \a this contains [3,5,1,2,0,8]
9636  *          - After \a this contains  [0,3,8,9,11,11,19]<br>
9637  * \sa DataArrayInt::deltaShiftIndex
9638  */
9639 void DataArrayInt::computeOffsetsFull()
9640 {
9641   checkAllocated();
9642   if(getNumberOfComponents()!=1)
9643     throw INTERP_KERNEL::Exception("DataArrayInt::computeOffsetsFull : only single component allowed !");
9644   int nbOfTuples=getNumberOfTuples();
9645   int *ret=(int *)malloc((nbOfTuples+1)*sizeof(int));
9646   const int *work=getConstPointer();
9647   ret[0]=0;
9648   for(int i=0;i<nbOfTuples;i++)
9649     ret[i+1]=work[i]+ret[i];
9650   useArray(ret,true,C_DEALLOC,nbOfTuples+1,1);
9651   declareAsNew();
9652 }
9653
9654 /*!
9655  * Returns two new DataArrayInt instances whose contents is computed from that of \a this and \a listOfIds arrays as follows.
9656  * \a this is expected to be an offset format ( as returned by DataArrayInt::computeOffsetsFull ) that is to say with one component
9657  * and ** sorted strictly increasingly **. \a listOfIds is expected to be sorted ascendingly (not strictly needed for \a listOfIds).
9658  * This methods searches in \a this, considered as a set of contiguous \c this->getNumberOfComponents() ranges, all ids in \a listOfIds
9659  * filling completely one of the ranges in \a this.
9660  *
9661  * \param [in] listOfIds a list of ids that has to be sorted ascendingly.
9662  * \param [out] rangeIdsFetched the range ids fetched
9663  * \param [out] idsInInputListThatFetch contains the list of ids in \a listOfIds that are \b fully included in a range in \a this. So
9664  *              \a idsInInputListThatFetch is a part of input \a listOfIds.
9665  *
9666  * \sa DataArrayInt::computeOffsetsFull
9667  *
9668  *  \b Example: <br>
9669  *          - \a this : [0,3,7,9,15,18]
9670  *          - \a listOfIds contains  [0,1,2,3,7,8,15,16,17]
9671  *          - \a rangeIdsFetched result array: [0,2,4]
9672  *          - \a idsInInputListThatFetch result array: [0,1,2,7,8,15,16,17]
9673  * In this example id 3 in input \a listOfIds is alone so it do not appear in output \a idsInInputListThatFetch.
9674  * <br>
9675  */
9676 void DataArrayInt::findIdsRangesInListOfIds(const DataArrayInt *listOfIds, DataArrayInt *& rangeIdsFetched, DataArrayInt *& idsInInputListThatFetch) const
9677 {
9678   if(!listOfIds)
9679     throw INTERP_KERNEL::Exception("DataArrayInt::findIdsRangesInListOfIds : input list of ids is null !");
9680   listOfIds->checkAllocated(); checkAllocated();
9681   if(listOfIds->getNumberOfComponents()!=1)
9682     throw INTERP_KERNEL::Exception("DataArrayInt::findIdsRangesInListOfIds : input list of ids must have exactly one component !");
9683   if(getNumberOfComponents()!=1)
9684     throw INTERP_KERNEL::Exception("DataArrayInt::findIdsRangesInListOfIds : this must have exactly one component !");
9685   MCAuto<DataArrayInt> ret0=DataArrayInt::New(); ret0->alloc(0,1);
9686   MCAuto<DataArrayInt> ret1=DataArrayInt::New(); ret1->alloc(0,1);
9687   const int *tupEnd(listOfIds->end()),*offBg(begin()),*offEnd(end()-1);
9688   const int *tupPtr(listOfIds->begin()),*offPtr(offBg);
9689   while(tupPtr!=tupEnd && offPtr!=offEnd)
9690     {
9691       if(*tupPtr==*offPtr)
9692         {
9693           int i=offPtr[0];
9694           while(i<offPtr[1] && *tupPtr==i && tupPtr!=tupEnd) { i++; tupPtr++; }
9695           if(i==offPtr[1])
9696             {
9697               ret0->pushBackSilent((int)std::distance(offBg,offPtr));
9698               ret1->pushBackValsSilent(tupPtr-(offPtr[1]-offPtr[0]),tupPtr);
9699               offPtr++;
9700             }
9701         }
9702       else
9703         { if(*tupPtr<*offPtr) tupPtr++; else offPtr++; }
9704     }
9705   rangeIdsFetched=ret0.retn();
9706   idsInInputListThatFetch=ret1.retn();
9707 }
9708
9709 /*!
9710  * Returns a new DataArrayInt whose contents is computed from that of \a this and \a
9711  * offsets arrays as follows. \a offsets is a one-dimensional array considered as an
9712  * "index" array of a "iota" array, thus, whose each element gives an index of a group
9713  * beginning within the "iota" array. And \a this is a one-dimensional array
9714  * considered as a selector of groups described by \a offsets to include into the result array.
9715  *  \throw If \a offsets is NULL.
9716  *  \throw If \a offsets is not allocated.
9717  *  \throw If \a offsets->getNumberOfComponents() != 1.
9718  *  \throw If \a offsets is not monotonically increasing.
9719  *  \throw If \a this is not allocated.
9720  *  \throw If \a this->getNumberOfComponents() != 1.
9721  *  \throw If any element of \a this is not a valid index for \a offsets array.
9722  *
9723  *  \b Example: <br>
9724  *          - \a this: [0,2,3]
9725  *          - \a offsets: [0,3,6,10,14,20]
9726  *          - result array: [0,1,2,6,7,8,9,10,11,12,13] == <br>
9727  *            \c range(0,3) + \c range(6,10) + \c range(10,14) ==<br>
9728  *            \c range( \a offsets[ \a this[0] ], offsets[ \a this[0]+1 ]) + 
9729  *            \c range( \a offsets[ \a this[1] ], offsets[ \a this[1]+1 ]) + 
9730  *            \c range( \a offsets[ \a this[2] ], offsets[ \a this[2]+1 ])
9731  */
9732 DataArrayInt *DataArrayInt::buildExplicitArrByRanges(const DataArrayInt *offsets) const
9733 {
9734   if(!offsets)
9735     throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrByRanges : DataArrayInt pointer in input is NULL !");
9736   checkAllocated();
9737   if(getNumberOfComponents()!=1)
9738     throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrByRanges : only single component allowed !");
9739   offsets->checkAllocated();
9740   if(offsets->getNumberOfComponents()!=1)
9741     throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrByRanges : input array should have only single component !");
9742   int othNbTuples=offsets->getNumberOfTuples()-1;
9743   int nbOfTuples=getNumberOfTuples();
9744   int retNbOftuples=0;
9745   const int *work=getConstPointer();
9746   const int *offPtr=offsets->getConstPointer();
9747   for(int i=0;i<nbOfTuples;i++)
9748     {
9749       int val=work[i];
9750       if(val>=0 && val<othNbTuples)
9751         {
9752           int delta=offPtr[val+1]-offPtr[val];
9753           if(delta>=0)
9754             retNbOftuples+=delta;
9755           else
9756             {
9757               std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrByRanges : Tuple #" << val << " of offset array has a delta < 0 !";
9758               throw INTERP_KERNEL::Exception(oss.str().c_str());
9759             }
9760         }
9761       else
9762         {
9763           std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrByRanges : Tuple #" << i << " in this contains " << val;
9764           oss << " whereas offsets array is of size " << othNbTuples+1 << " !";
9765           throw INTERP_KERNEL::Exception(oss.str().c_str());
9766         }
9767     }
9768   MCAuto<DataArrayInt> ret=DataArrayInt::New();
9769   ret->alloc(retNbOftuples,1);
9770   int *retPtr=ret->getPointer();
9771   for(int i=0;i<nbOfTuples;i++)
9772     {
9773       int val=work[i];
9774       int start=offPtr[val];
9775       int off=offPtr[val+1]-start;
9776       for(int j=0;j<off;j++,retPtr++)
9777         *retPtr=start+j;
9778     }
9779   return ret.retn();
9780 }
9781
9782 /*!
9783  * Returns a new DataArrayInt whose contents is computed using \a this that must be a 
9784  * scaled array (monotonically increasing).
9785 from that of \a this and \a
9786  * offsets arrays as follows. \a offsets is a one-dimensional array considered as an
9787  * "index" array of a "iota" array, thus, whose each element gives an index of a group
9788  * beginning within the "iota" array. And \a this is a one-dimensional array
9789  * considered as a selector of groups described by \a offsets to include into the result array.
9790  *  \throw If \a  is NULL.
9791  *  \throw If \a this is not allocated.
9792  *  \throw If \a this->getNumberOfComponents() != 1.
9793  *  \throw If \a this->getNumberOfTuples() == 0.
9794  *  \throw If \a this is not monotonically increasing.
9795  *  \throw If any element of ids in ( \a bg \a stop \a step ) points outside the scale in \a this.
9796  *
9797  *  \b Example: <br>
9798  *          - \a bg , \a stop and \a step : (0,5,2)
9799  *          - \a this: [0,3,6,10,14,20]
9800  *          - result array: [0,0,0, 2,2,2,2, 4,4,4,4,4,4] == <br>
9801  */
9802 DataArrayInt *DataArrayInt::buildExplicitArrOfSliceOnScaledArr(int bg, int stop, int step) const
9803 {
9804   if(!isAllocated())
9805     throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrOfSliceOnScaledArr : not allocated array !");
9806   if(getNumberOfComponents()!=1)
9807     throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrOfSliceOnScaledArr : number of components is expected to be equal to one !");
9808   int nbOfTuples(getNumberOfTuples());
9809   if(nbOfTuples==0)
9810     throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrOfSliceOnScaledArr : number of tuples must be != 0 !");
9811   const int *ids(begin());
9812   int nbOfEltsInSlc(GetNumberOfItemGivenBESRelative(bg,stop,step,"DataArrayInt::buildExplicitArrOfSliceOnScaledArr")),sz(0),pos(bg);
9813   for(int i=0;i<nbOfEltsInSlc;i++,pos+=step)
9814     {
9815       if(pos>=0 && pos<nbOfTuples-1)
9816         {
9817           int delta(ids[pos+1]-ids[pos]);
9818           sz+=delta;
9819           if(delta<0)
9820             {
9821               std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrOfSliceOnScaledArr : At pos #" << i << " of input slice, value is " << pos << " and at this pos this is not monotonically increasing !";
9822               throw INTERP_KERNEL::Exception(oss.str().c_str());
9823             }          
9824         }
9825       else
9826         {
9827           std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrOfSliceOnScaledArr : At pos #" << i << " of input slice, value is " << pos << " should be in [0," << nbOfTuples-1 << ") !";  
9828           throw INTERP_KERNEL::Exception(oss.str().c_str());
9829         }
9830     }
9831   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(sz,1);
9832   int *retPtr(ret->getPointer());
9833   pos=bg;
9834   for(int i=0;i<nbOfEltsInSlc;i++,pos+=step)
9835     {
9836       int delta(ids[pos+1]-ids[pos]);
9837       for(int j=0;j<delta;j++,retPtr++)
9838         *retPtr=pos;
9839     }
9840   return ret.retn();
9841 }
9842
9843 /*!
9844  * 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.
9845  * 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
9846  * in tuple **i** of returned DataArrayInt.
9847  * If ranges overlapped (in theory it should not) this method do not detect it and always returns the first range.
9848  *
9849  * 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)]
9850  * The return DataArrayInt will contain : **[0,4,1,2,2,3]**
9851  * 
9852  * \param [in] ranges typically come from output of MEDCouplingUMesh::ComputeRangesFromTypeDistribution. Each range is specified like this : 1st component is
9853  *             for lower value included and 2nd component is the upper value of corresponding range **excluded**.
9854  * \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
9855  *        is thrown if no ranges in \a ranges contains value in \a this.
9856  * 
9857  * \sa DataArrayInt::findIdInRangeForEachTuple
9858  */
9859 DataArrayInt *DataArrayInt::findRangeIdForEachTuple(const DataArrayInt *ranges) const
9860 {
9861   if(!ranges)
9862     throw INTERP_KERNEL::Exception("DataArrayInt::findRangeIdForEachTuple : null input pointer !");
9863   if(ranges->getNumberOfComponents()!=2)
9864     throw INTERP_KERNEL::Exception("DataArrayInt::findRangeIdForEachTuple : input DataArrayInt instance should have 2 components !");
9865   checkAllocated();
9866   if(getNumberOfComponents()!=1)
9867     throw INTERP_KERNEL::Exception("DataArrayInt::findRangeIdForEachTuple : this should have only one component !");
9868   int nbTuples=getNumberOfTuples();
9869   MCAuto<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbTuples,1);
9870   int nbOfRanges=ranges->getNumberOfTuples();
9871   const int *rangesPtr=ranges->getConstPointer();
9872   int *retPtr=ret->getPointer();
9873   const int *inPtr=getConstPointer();
9874   for(int i=0;i<nbTuples;i++,retPtr++)
9875     {
9876       int val=inPtr[i];
9877       bool found=false;
9878       for(int j=0;j<nbOfRanges && !found;j++)
9879         if(val>=rangesPtr[2*j] && val<rangesPtr[2*j+1])
9880           { *retPtr=j; found=true; }
9881       if(found)
9882         continue;
9883       else
9884         {
9885           std::ostringstream oss; oss << "DataArrayInt::findRangeIdForEachTuple : tuple #" << i << " not found by any ranges !";
9886           throw INTERP_KERNEL::Exception(oss.str().c_str());
9887         }
9888     }
9889   return ret.retn();
9890 }
9891
9892 /*!
9893  * 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.
9894  * 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
9895  * in tuple **i** of returned DataArrayInt.
9896  * If ranges overlapped (in theory it should not) this method do not detect it and always returns the sub position of the first range.
9897  *
9898  * 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)]
9899  * The return DataArrayInt will contain : **[1,2,4,0,2,2]**
9900  * This method is often called in pair with DataArrayInt::findRangeIdForEachTuple method.
9901  * 
9902  * \param [in] ranges typically come from output of MEDCouplingUMesh::ComputeRangesFromTypeDistribution. Each range is specified like this : 1st component is
9903  *             for lower value included and 2nd component is the upper value of corresponding range **excluded**.
9904  * \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
9905  *        is thrown if no ranges in \a ranges contains value in \a this.
9906  * \sa DataArrayInt::findRangeIdForEachTuple
9907  */
9908 DataArrayInt *DataArrayInt::findIdInRangeForEachTuple(const DataArrayInt *ranges) const
9909 {
9910   if(!ranges)
9911     throw INTERP_KERNEL::Exception("DataArrayInt::findIdInRangeForEachTuple : null input pointer !");
9912   if(ranges->getNumberOfComponents()!=2)
9913     throw INTERP_KERNEL::Exception("DataArrayInt::findIdInRangeForEachTuple : input DataArrayInt instance should have 2 components !");
9914   checkAllocated();
9915   if(getNumberOfComponents()!=1)
9916     throw INTERP_KERNEL::Exception("DataArrayInt::findIdInRangeForEachTuple : this should have only one component !");
9917   int nbTuples=getNumberOfTuples();
9918   MCAuto<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbTuples,1);
9919   int nbOfRanges=ranges->getNumberOfTuples();
9920   const int *rangesPtr=ranges->getConstPointer();
9921   int *retPtr=ret->getPointer();
9922   const int *inPtr=getConstPointer();
9923   for(int i=0;i<nbTuples;i++,retPtr++)
9924     {
9925       int val=inPtr[i];
9926       bool found=false;
9927       for(int j=0;j<nbOfRanges && !found;j++)
9928         if(val>=rangesPtr[2*j] && val<rangesPtr[2*j+1])
9929           { *retPtr=val-rangesPtr[2*j]; found=true; }
9930       if(found)
9931         continue;
9932       else
9933         {
9934           std::ostringstream oss; oss << "DataArrayInt::findIdInRangeForEachTuple : tuple #" << i << " not found by any ranges !";
9935           throw INTERP_KERNEL::Exception(oss.str().c_str());
9936         }
9937     }
9938   return ret.retn();
9939 }
9940
9941 /*!
9942  * \b WARNING this method is a \b non \a const \b method. This method works tuple by tuple. Each tuple is expected to be pairs (number of components must be equal to 2).
9943  * This method rearrange each pair in \a this so that, tuple with id \b tid will be after the call \c this->getIJ(tid,0)==this->getIJ(tid-1,1) and \c this->getIJ(tid,1)==this->getIJ(tid+1,0).
9944  * If it is impossible to reach such condition an exception will be thrown ! \b WARNING In case of throw \a this can be partially modified !
9945  * If this method has correctly worked, \a this will be able to be considered as a linked list.
9946  * This method does nothing if number of tuples is lower of equal to 1.
9947  *
9948  * This method is useful for users having an unstructured mesh having only SEG2 to rearrange internaly the connectibity without any coordinates consideration.
9949  *
9950  * \sa MEDCouplingUMesh::orderConsecutiveCells1D
9951  */
9952 void DataArrayInt::sortEachPairToMakeALinkedList()
9953 {
9954   checkAllocated();
9955   if(getNumberOfComponents()!=2)
9956     throw INTERP_KERNEL::Exception("DataArrayInt::sortEachPairToMakeALinkedList : Only works on DataArrayInt instance with nb of components equal to 2 !");
9957   int nbOfTuples(getNumberOfTuples());
9958   if(nbOfTuples<=1)
9959     return ;
9960   int *conn(getPointer());
9961   for(int i=1;i<nbOfTuples;i++,conn+=2)
9962     {
9963       if(i>1)
9964         {
9965           if(conn[2]==conn[3])
9966             {
9967               std::ostringstream oss; oss << "DataArrayInt::sortEachPairToMakeALinkedList : In the tuple #" << i << " presence of a pair filled with same ids !";
9968               throw INTERP_KERNEL::Exception(oss.str().c_str());
9969             }
9970           if(conn[2]!=conn[1] && conn[3]==conn[1] && conn[2]!=conn[0])
9971             std::swap(conn[2],conn[3]);
9972           //not(conn[2]==conn[1] && conn[3]!=conn[1] && conn[3]!=conn[0])
9973           if(conn[2]!=conn[1] || conn[3]==conn[1] || conn[3]==conn[0])
9974             {
9975               std::ostringstream oss; oss << "DataArrayInt::sortEachPairToMakeALinkedList : In the tuple #" << i << " something is invalid !";
9976               throw INTERP_KERNEL::Exception(oss.str().c_str());
9977             }
9978         }
9979       else
9980         {
9981           if(conn[0]==conn[1] || conn[2]==conn[3])
9982             throw INTERP_KERNEL::Exception("DataArrayInt::sortEachPairToMakeALinkedList : In the 2 first tuples presence of a pair filled with same ids !");
9983           int tmp[4];
9984           std::set<int> s;
9985           s.insert(conn,conn+4);
9986           if(s.size()!=3)
9987             throw INTERP_KERNEL::Exception("DataArrayInt::sortEachPairToMakeALinkedList : This can't be considered as a linked list regarding 2 first tuples !");
9988           if(std::count(conn,conn+4,conn[0])==2)
9989             {
9990               tmp[0]=conn[1];
9991               tmp[1]=conn[0];
9992               tmp[2]=conn[0];
9993               if(conn[2]==conn[0])
9994                 { tmp[3]=conn[3]; }
9995               else
9996                 { tmp[3]=conn[2];}
9997               std::copy(tmp,tmp+4,conn);
9998             }
9999           else
10000             {//here we are sure to have (std::count(conn,conn+4,conn[1])==2)
10001               if(conn[1]==conn[3])
10002                 std::swap(conn[2],conn[3]);
10003             }
10004         }
10005     }
10006 }
10007
10008 /*!
10009  * 
10010  * \param [in] nbTimes specifies the nb of times each tuples in \a this will be duplicated contiguouly in returned DataArrayInt instance.
10011  *             \a nbTimes  should be at least equal to 1.
10012  * \return a newly allocated DataArrayInt having one component and number of tuples equal to \a nbTimes * \c this->getNumberOfTuples.
10013  * \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.
10014  */
10015 DataArrayInt *DataArrayInt::duplicateEachTupleNTimes(int nbTimes) const
10016 {
10017   checkAllocated();
10018   if(getNumberOfComponents()!=1)
10019     throw INTERP_KERNEL::Exception("DataArrayInt::duplicateEachTupleNTimes : this should have only one component !");
10020   if(nbTimes<1)
10021     throw INTERP_KERNEL::Exception("DataArrayInt::duplicateEachTupleNTimes : nb times should be >= 1 !");
10022   int nbTuples=getNumberOfTuples();
10023   const int *inPtr=getConstPointer();
10024   MCAuto<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbTimes*nbTuples,1);
10025   int *retPtr=ret->getPointer();
10026   for(int i=0;i<nbTuples;i++,inPtr++)
10027     {
10028       int val=*inPtr;
10029       for(int j=0;j<nbTimes;j++,retPtr++)
10030         *retPtr=val;
10031     }
10032   ret->copyStringInfoFrom(*this);
10033   return ret.retn();
10034 }
10035
10036 /*!
10037  * This method returns all different values found in \a this. This method throws if \a this has not been allocated.
10038  * But the number of components can be different from one.
10039  * \return a newly allocated array (that should be dealt by the caller) containing different values in \a this.
10040  */
10041 DataArrayInt *DataArrayInt::getDifferentValues() const
10042 {
10043   checkAllocated();
10044   std::set<int> ret;
10045   ret.insert(begin(),end());
10046   MCAuto<DataArrayInt> ret2=DataArrayInt::New(); ret2->alloc((int)ret.size(),1);
10047   std::copy(ret.begin(),ret.end(),ret2->getPointer());
10048   return ret2.retn();
10049 }
10050
10051 /*!
10052  * This method is a refinement of DataArrayInt::getDifferentValues because it returns not only different values in \a this but also, for each of
10053  * them it tells which tuple id have this id.
10054  * This method works only on arrays with one component (if it is not the case call DataArrayInt::rearrange(1) ).
10055  * This method returns two arrays having same size.
10056  * 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.
10057  * 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]]
10058  */
10059 std::vector<DataArrayInt *> DataArrayInt::partitionByDifferentValues(std::vector<int>& differentIds) const
10060 {
10061   checkAllocated();
10062   if(getNumberOfComponents()!=1)
10063     throw INTERP_KERNEL::Exception("DataArrayInt::partitionByDifferentValues : this should have only one component !");
10064   int id=0;
10065   std::map<int,int> m,m2,m3;
10066   for(const int *w=begin();w!=end();w++)
10067     m[*w]++;
10068   differentIds.resize(m.size());
10069   std::vector<DataArrayInt *> ret(m.size());
10070   std::vector<int *> retPtr(m.size());
10071   for(std::map<int,int>::const_iterator it=m.begin();it!=m.end();it++,id++)
10072     {
10073       m2[(*it).first]=id;
10074       ret[id]=DataArrayInt::New();
10075       ret[id]->alloc((*it).second,1);
10076       retPtr[id]=ret[id]->getPointer();
10077       differentIds[id]=(*it).first;
10078     }
10079   id=0;
10080   for(const int *w=begin();w!=end();w++,id++)
10081     {
10082       retPtr[m2[*w]][m3[*w]++]=id;
10083     }
10084   return ret;
10085 }
10086
10087 /*!
10088  * This method split ids in [0, \c this->getNumberOfTuples() ) using \a this array as a field of weight (>=0 each).
10089  * The aim of this method is to return a set of \a nbOfSlices chunk of contiguous ids as balanced as possible.
10090  *
10091  * \param [in] nbOfSlices - number of slices expected.
10092  * \return - a vector having a size equal to \a nbOfSlices giving the start (included) and the stop (excluded) of each chunks.
10093  * 
10094  * \sa DataArray::GetSlice
10095  * \throw If \a this is not allocated or not with exactly one component.
10096  * \throw If an element in \a this if < 0.
10097  */
10098 std::vector< std::pair<int,int> > DataArrayInt::splitInBalancedSlices(int nbOfSlices) const
10099 {
10100   if(!isAllocated() || getNumberOfComponents()!=1)
10101     throw INTERP_KERNEL::Exception("DataArrayInt::splitInBalancedSlices : this array should have number of components equal to one and must be allocated !");
10102   if(nbOfSlices<=0)
10103     throw INTERP_KERNEL::Exception("DataArrayInt::splitInBalancedSlices : number of slices must be >= 1 !");
10104   int sum(accumulate(0)),nbOfTuples(getNumberOfTuples());
10105   int sumPerSlc(sum/nbOfSlices),pos(0);
10106   const int *w(begin());
10107   std::vector< std::pair<int,int> > ret(nbOfSlices);
10108   for(int i=0;i<nbOfSlices;i++)
10109     {
10110       std::pair<int,int> p(pos,-1);
10111       int locSum(0);
10112       while(locSum<sumPerSlc && pos<nbOfTuples) { pos++; locSum+=*w++; }
10113       if(i!=nbOfSlices-1)
10114         p.second=pos;
10115       else
10116         p.second=nbOfTuples;
10117       ret[i]=p;
10118     }
10119   return ret;
10120 }
10121
10122 /*!
10123  * Returns a new DataArrayInt that is a sum of two given arrays. There are 3
10124  * valid cases.
10125  * 1.  The arrays have same number of tuples and components. Then each value of
10126  *   the result array (_a_) is a sum of the corresponding values of \a a1 and \a a2,
10127  *   i.e.: _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ i, j ].
10128  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
10129  *   component. Then
10130  *   _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ i, 0 ].
10131  * 3.  The arrays have same number of components and one array, say _a2_, has one
10132  *   tuple. Then
10133  *   _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ 0, j ].
10134  *
10135  * Info on components is copied either from the first array (in the first case) or from
10136  * the array with maximal number of elements (getNbOfElems()).
10137  *  \param [in] a1 - an array to sum up.
10138  *  \param [in] a2 - another array to sum up.
10139  *  \return DataArrayInt * - the new instance of DataArrayInt.
10140  *          The caller is to delete this result array using decrRef() as it is no more
10141  *          needed.
10142  *  \throw If either \a a1 or \a a2 is NULL.
10143  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
10144  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
10145  *         none of them has number of tuples or components equal to 1.
10146  */
10147 DataArrayInt *DataArrayInt::Add(const DataArrayInt *a1, const DataArrayInt *a2)
10148 {
10149   if(!a1 || !a2)
10150     throw INTERP_KERNEL::Exception("DataArrayInt::Add : input DataArrayInt instance is NULL !");
10151   int nbOfTuple=a1->getNumberOfTuples();
10152   int nbOfTuple2=a2->getNumberOfTuples();
10153   int nbOfComp=a1->getNumberOfComponents();
10154   int nbOfComp2=a2->getNumberOfComponents();
10155   MCAuto<DataArrayInt> ret=0;
10156   if(nbOfTuple==nbOfTuple2)
10157     {
10158       if(nbOfComp==nbOfComp2)
10159         {
10160           ret=DataArrayInt::New();
10161           ret->alloc(nbOfTuple,nbOfComp);
10162           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::plus<int>());
10163           ret->copyStringInfoFrom(*a1);
10164         }
10165       else
10166         {
10167           int nbOfCompMin,nbOfCompMax;
10168           const DataArrayInt *aMin, *aMax;
10169           if(nbOfComp>nbOfComp2)
10170             {
10171               nbOfCompMin=nbOfComp2; nbOfCompMax=nbOfComp;
10172               aMin=a2; aMax=a1;
10173             }
10174           else
10175             {
10176               nbOfCompMin=nbOfComp; nbOfCompMax=nbOfComp2;
10177               aMin=a1; aMax=a2;
10178             }
10179           if(nbOfCompMin==1)
10180             {
10181               ret=DataArrayInt::New();
10182               ret->alloc(nbOfTuple,nbOfCompMax);
10183               const int *aMinPtr=aMin->getConstPointer();
10184               const int *aMaxPtr=aMax->getConstPointer();
10185               int *res=ret->getPointer();
10186               for(int i=0;i<nbOfTuple;i++)
10187                 res=std::transform(aMaxPtr+i*nbOfCompMax,aMaxPtr+(i+1)*nbOfCompMax,res,std::bind2nd(std::plus<int>(),aMinPtr[i]));
10188               ret->copyStringInfoFrom(*aMax);
10189             }
10190           else
10191             throw INTERP_KERNEL::Exception("Nb of components mismatch for array Add !");
10192         }
10193     }
10194   else if((nbOfTuple==1 && nbOfTuple2>1) || (nbOfTuple>1 && nbOfTuple2==1))
10195     {
10196       if(nbOfComp==nbOfComp2)
10197         {
10198           int nbOfTupleMax=std::max(nbOfTuple,nbOfTuple2);
10199           const DataArrayInt *aMin=nbOfTuple>nbOfTuple2?a2:a1;
10200           const DataArrayInt *aMax=nbOfTuple>nbOfTuple2?a1:a2;
10201           const int *aMinPtr=aMin->getConstPointer(),*aMaxPtr=aMax->getConstPointer();
10202           ret=DataArrayInt::New();
10203           ret->alloc(nbOfTupleMax,nbOfComp);
10204           int *res=ret->getPointer();
10205           for(int i=0;i<nbOfTupleMax;i++)
10206             res=std::transform(aMaxPtr+i*nbOfComp,aMaxPtr+(i+1)*nbOfComp,aMinPtr,res,std::plus<int>());
10207           ret->copyStringInfoFrom(*aMax);
10208         }
10209       else
10210         throw INTERP_KERNEL::Exception("Nb of components mismatch for array Add !");
10211     }
10212   else
10213     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Add !");
10214   return ret.retn();
10215 }
10216
10217 /*!
10218  * Adds values of another DataArrayInt to values of \a this one. There are 3
10219  * valid cases.
10220  * 1.  The arrays have same number of tuples and components. Then each value of
10221  *   \a other array is added to the corresponding value of \a this array, i.e.:
10222  *   _a_ [ i, j ] += _other_ [ i, j ].
10223  * 2.  The arrays have same number of tuples and \a other array has one component. Then
10224  *   _a_ [ i, j ] += _other_ [ i, 0 ].
10225  * 3.  The arrays have same number of components and \a other array has one tuple. Then
10226  *   _a_ [ i, j ] += _a2_ [ 0, j ].
10227  *
10228  *  \param [in] other - an array to add to \a this one.
10229  *  \throw If \a other is NULL.
10230  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
10231  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
10232  *         \a other has number of both tuples and components not equal to 1.
10233  */
10234 void DataArrayInt::addEqual(const DataArrayInt *other)
10235 {
10236   if(!other)
10237     throw INTERP_KERNEL::Exception("DataArrayInt::addEqual : input DataArrayInt instance is NULL !");
10238   const char *msg="Nb of tuples mismatch for DataArrayInt::addEqual  !";
10239   checkAllocated(); other->checkAllocated();
10240   int nbOfTuple=getNumberOfTuples();
10241   int nbOfTuple2=other->getNumberOfTuples();
10242   int nbOfComp=getNumberOfComponents();
10243   int nbOfComp2=other->getNumberOfComponents();
10244   if(nbOfTuple==nbOfTuple2)
10245     {
10246       if(nbOfComp==nbOfComp2)
10247         {
10248           std::transform(begin(),end(),other->begin(),getPointer(),std::plus<int>());
10249         }
10250       else if(nbOfComp2==1)
10251         {
10252           int *ptr=getPointer();
10253           const int *ptrc=other->getConstPointer();
10254           for(int i=0;i<nbOfTuple;i++)
10255             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::plus<int>(),*ptrc++));
10256         }
10257       else
10258         throw INTERP_KERNEL::Exception(msg);
10259     }
10260   else if(nbOfTuple2==1)
10261     {
10262       if(nbOfComp2==nbOfComp)
10263         {
10264           int *ptr=getPointer();
10265           const int *ptrc=other->getConstPointer();
10266           for(int i=0;i<nbOfTuple;i++)
10267             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::plus<int>());
10268         }
10269       else
10270         throw INTERP_KERNEL::Exception(msg);
10271     }
10272   else
10273     throw INTERP_KERNEL::Exception(msg);
10274   declareAsNew();
10275 }
10276
10277 /*!
10278  * Returns a new DataArrayInt that is a subtraction of two given arrays. There are 3
10279  * valid cases.
10280  * 1.  The arrays have same number of tuples and components. Then each value of
10281  *   the result array (_a_) is a subtraction of the corresponding values of \a a1 and
10282  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ i, j ].
10283  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
10284  *   component. Then
10285  *   _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ i, 0 ].
10286  * 3.  The arrays have same number of components and one array, say _a2_, has one
10287  *   tuple. Then
10288  *   _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ 0, j ].
10289  *
10290  * Info on components is copied either from the first array (in the first case) or from
10291  * the array with maximal number of elements (getNbOfElems()).
10292  *  \param [in] a1 - an array to subtract from.
10293  *  \param [in] a2 - an array to subtract.
10294  *  \return DataArrayInt * - the new instance of DataArrayInt.
10295  *          The caller is to delete this result array using decrRef() as it is no more
10296  *          needed.
10297  *  \throw If either \a a1 or \a a2 is NULL.
10298  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
10299  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
10300  *         none of them has number of tuples or components equal to 1.
10301  */
10302 DataArrayInt *DataArrayInt::Substract(const DataArrayInt *a1, const DataArrayInt *a2)
10303 {
10304   if(!a1 || !a2)
10305     throw INTERP_KERNEL::Exception("DataArrayInt::Substract : input DataArrayInt instance is NULL !");
10306   int nbOfTuple1=a1->getNumberOfTuples();
10307   int nbOfTuple2=a2->getNumberOfTuples();
10308   int nbOfComp1=a1->getNumberOfComponents();
10309   int nbOfComp2=a2->getNumberOfComponents();
10310   if(nbOfTuple2==nbOfTuple1)
10311     {
10312       if(nbOfComp1==nbOfComp2)
10313         {
10314           MCAuto<DataArrayInt> ret=DataArrayInt::New();
10315           ret->alloc(nbOfTuple2,nbOfComp1);
10316           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::minus<int>());
10317           ret->copyStringInfoFrom(*a1);
10318           return ret.retn();
10319         }
10320       else if(nbOfComp2==1)
10321         {
10322           MCAuto<DataArrayInt> ret=DataArrayInt::New();
10323           ret->alloc(nbOfTuple1,nbOfComp1);
10324           const int *a2Ptr=a2->getConstPointer();
10325           const int *a1Ptr=a1->getConstPointer();
10326           int *res=ret->getPointer();
10327           for(int i=0;i<nbOfTuple1;i++)
10328             res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::minus<int>(),a2Ptr[i]));
10329           ret->copyStringInfoFrom(*a1);
10330           return ret.retn();
10331         }
10332       else
10333         {
10334           a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Substract !");
10335           return 0;
10336         }
10337     }
10338   else if(nbOfTuple2==1)
10339     {
10340       a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Substract !");
10341       MCAuto<DataArrayInt> ret=DataArrayInt::New();
10342       ret->alloc(nbOfTuple1,nbOfComp1);
10343       const int *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
10344       int *pt=ret->getPointer();
10345       for(int i=0;i<nbOfTuple1;i++)
10346         pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::minus<int>());
10347       ret->copyStringInfoFrom(*a1);
10348       return ret.retn();
10349     }
10350   else
10351     {
10352       a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Substract !");//will always throw an exception
10353       return 0;
10354     }
10355 }
10356
10357 /*!
10358  * Subtract values of another DataArrayInt from values of \a this one. There are 3
10359  * valid cases.
10360  * 1.  The arrays have same number of tuples and components. Then each value of
10361  *   \a other array is subtracted from the corresponding value of \a this array, i.e.:
10362  *   _a_ [ i, j ] -= _other_ [ i, j ].
10363  * 2.  The arrays have same number of tuples and \a other array has one component. Then
10364  *   _a_ [ i, j ] -= _other_ [ i, 0 ].
10365  * 3.  The arrays have same number of components and \a other array has one tuple. Then
10366  *   _a_ [ i, j ] -= _a2_ [ 0, j ].
10367  *
10368  *  \param [in] other - an array to subtract from \a this one.
10369  *  \throw If \a other is NULL.
10370  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
10371  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
10372  *         \a other has number of both tuples and components not equal to 1.
10373  */
10374 void DataArrayInt::substractEqual(const DataArrayInt *other)
10375 {
10376   if(!other)
10377     throw INTERP_KERNEL::Exception("DataArrayInt::substractEqual : input DataArrayInt instance is NULL !");
10378   const char *msg="Nb of tuples mismatch for DataArrayInt::substractEqual  !";
10379   checkAllocated(); other->checkAllocated();
10380   int nbOfTuple=getNumberOfTuples();
10381   int nbOfTuple2=other->getNumberOfTuples();
10382   int nbOfComp=getNumberOfComponents();
10383   int nbOfComp2=other->getNumberOfComponents();
10384   if(nbOfTuple==nbOfTuple2)
10385     {
10386       if(nbOfComp==nbOfComp2)
10387         {
10388           std::transform(begin(),end(),other->begin(),getPointer(),std::minus<int>());
10389         }
10390       else if(nbOfComp2==1)
10391         {
10392           int *ptr=getPointer();
10393           const int *ptrc=other->getConstPointer();
10394           for(int i=0;i<nbOfTuple;i++)
10395             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::minus<int>(),*ptrc++));
10396         }
10397       else
10398         throw INTERP_KERNEL::Exception(msg);
10399     }
10400   else if(nbOfTuple2==1)
10401     {
10402       int *ptr=getPointer();
10403       const int *ptrc=other->getConstPointer();
10404       for(int i=0;i<nbOfTuple;i++)
10405         std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::minus<int>());
10406     }
10407   else
10408     throw INTERP_KERNEL::Exception(msg);
10409   declareAsNew();
10410 }
10411
10412 /*!
10413  * Returns a new DataArrayInt that is a product of two given arrays. There are 3
10414  * valid cases.
10415  * 1.  The arrays have same number of tuples and components. Then each value of
10416  *   the result array (_a_) is a product of the corresponding values of \a a1 and
10417  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ i, j ].
10418  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
10419  *   component. Then
10420  *   _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ i, 0 ].
10421  * 3.  The arrays have same number of components and one array, say _a2_, has one
10422  *   tuple. Then
10423  *   _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ 0, j ].
10424  *
10425  * Info on components is copied either from the first array (in the first case) or from
10426  * the array with maximal number of elements (getNbOfElems()).
10427  *  \param [in] a1 - a factor array.
10428  *  \param [in] a2 - another factor array.
10429  *  \return DataArrayInt * - the new instance of DataArrayInt.
10430  *          The caller is to delete this result array using decrRef() as it is no more
10431  *          needed.
10432  *  \throw If either \a a1 or \a a2 is NULL.
10433  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
10434  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
10435  *         none of them has number of tuples or components equal to 1.
10436  */
10437 DataArrayInt *DataArrayInt::Multiply(const DataArrayInt *a1, const DataArrayInt *a2)
10438 {
10439   if(!a1 || !a2)
10440     throw INTERP_KERNEL::Exception("DataArrayInt::Multiply : input DataArrayInt instance is NULL !");
10441   int nbOfTuple=a1->getNumberOfTuples();
10442   int nbOfTuple2=a2->getNumberOfTuples();
10443   int nbOfComp=a1->getNumberOfComponents();
10444   int nbOfComp2=a2->getNumberOfComponents();
10445   MCAuto<DataArrayInt> ret=0;
10446   if(nbOfTuple==nbOfTuple2)
10447     {
10448       if(nbOfComp==nbOfComp2)
10449         {
10450           ret=DataArrayInt::New();
10451           ret->alloc(nbOfTuple,nbOfComp);
10452           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::multiplies<int>());
10453           ret->copyStringInfoFrom(*a1);
10454         }
10455       else
10456         {
10457           int nbOfCompMin,nbOfCompMax;
10458           const DataArrayInt *aMin, *aMax;
10459           if(nbOfComp>nbOfComp2)
10460             {
10461               nbOfCompMin=nbOfComp2; nbOfCompMax=nbOfComp;
10462               aMin=a2; aMax=a1;
10463             }
10464           else
10465             {
10466               nbOfCompMin=nbOfComp; nbOfCompMax=nbOfComp2;
10467               aMin=a1; aMax=a2;
10468             }
10469           if(nbOfCompMin==1)
10470             {
10471               ret=DataArrayInt::New();
10472               ret->alloc(nbOfTuple,nbOfCompMax);
10473               const int *aMinPtr=aMin->getConstPointer();
10474               const int *aMaxPtr=aMax->getConstPointer();
10475               int *res=ret->getPointer();
10476               for(int i=0;i<nbOfTuple;i++)
10477                 res=std::transform(aMaxPtr+i*nbOfCompMax,aMaxPtr+(i+1)*nbOfCompMax,res,std::bind2nd(std::multiplies<int>(),aMinPtr[i]));
10478               ret->copyStringInfoFrom(*aMax);
10479             }
10480           else
10481             throw INTERP_KERNEL::Exception("Nb of components mismatch for array Multiply !");
10482         }
10483     }
10484   else if((nbOfTuple==1 && nbOfTuple2>1) || (nbOfTuple>1 && nbOfTuple2==1))
10485     {
10486       if(nbOfComp==nbOfComp2)
10487         {
10488           int nbOfTupleMax=std::max(nbOfTuple,nbOfTuple2);
10489           const DataArrayInt *aMin=nbOfTuple>nbOfTuple2?a2:a1;
10490           const DataArrayInt *aMax=nbOfTuple>nbOfTuple2?a1:a2;
10491           const int *aMinPtr=aMin->getConstPointer(),*aMaxPtr=aMax->getConstPointer();
10492           ret=DataArrayInt::New();
10493           ret->alloc(nbOfTupleMax,nbOfComp);
10494           int *res=ret->getPointer();
10495           for(int i=0;i<nbOfTupleMax;i++)
10496             res=std::transform(aMaxPtr+i*nbOfComp,aMaxPtr+(i+1)*nbOfComp,aMinPtr,res,std::multiplies<int>());
10497           ret->copyStringInfoFrom(*aMax);
10498         }
10499       else
10500         throw INTERP_KERNEL::Exception("Nb of components mismatch for array Multiply !");
10501     }
10502   else
10503     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Multiply !");
10504   return ret.retn();
10505 }
10506
10507
10508 /*!
10509  * Multiply values of another DataArrayInt to values of \a this one. There are 3
10510  * valid cases.
10511  * 1.  The arrays have same number of tuples and components. Then each value of
10512  *   \a other array is multiplied to the corresponding value of \a this array, i.e.:
10513  *   _a_ [ i, j ] *= _other_ [ i, j ].
10514  * 2.  The arrays have same number of tuples and \a other array has one component. Then
10515  *   _a_ [ i, j ] *= _other_ [ i, 0 ].
10516  * 3.  The arrays have same number of components and \a other array has one tuple. Then
10517  *   _a_ [ i, j ] *= _a2_ [ 0, j ].
10518  *
10519  *  \param [in] other - an array to multiply to \a this one.
10520  *  \throw If \a other is NULL.
10521  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
10522  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
10523  *         \a other has number of both tuples and components not equal to 1.
10524  */
10525 void DataArrayInt::multiplyEqual(const DataArrayInt *other)
10526 {
10527   if(!other)
10528     throw INTERP_KERNEL::Exception("DataArrayInt::multiplyEqual : input DataArrayInt instance is NULL !");
10529   const char *msg="Nb of tuples mismatch for DataArrayInt::multiplyEqual !";
10530   checkAllocated(); other->checkAllocated();
10531   int nbOfTuple=getNumberOfTuples();
10532   int nbOfTuple2=other->getNumberOfTuples();
10533   int nbOfComp=getNumberOfComponents();
10534   int nbOfComp2=other->getNumberOfComponents();
10535   if(nbOfTuple==nbOfTuple2)
10536     {
10537       if(nbOfComp==nbOfComp2)
10538         {
10539           std::transform(begin(),end(),other->begin(),getPointer(),std::multiplies<int>());
10540         }
10541       else if(nbOfComp2==1)
10542         {
10543           int *ptr=getPointer();
10544           const int *ptrc=other->getConstPointer();
10545           for(int i=0;i<nbOfTuple;i++)
10546             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::multiplies<int>(),*ptrc++));    
10547         }
10548       else
10549         throw INTERP_KERNEL::Exception(msg);
10550     }
10551   else if(nbOfTuple2==1)
10552     {
10553       if(nbOfComp2==nbOfComp)
10554         {
10555           int *ptr=getPointer();
10556           const int *ptrc=other->getConstPointer();
10557           for(int i=0;i<nbOfTuple;i++)
10558             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::multiplies<int>());
10559         }
10560       else
10561         throw INTERP_KERNEL::Exception(msg);
10562     }
10563   else
10564     throw INTERP_KERNEL::Exception(msg);
10565   declareAsNew();
10566 }
10567
10568
10569 /*!
10570  * Returns a new DataArrayInt that is a division of two given arrays. There are 3
10571  * valid cases.
10572  * 1.  The arrays have same number of tuples and components. Then each value of
10573  *   the result array (_a_) is a division of the corresponding values of \a a1 and
10574  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ i, j ].
10575  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
10576  *   component. Then
10577  *   _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ i, 0 ].
10578  * 3.  The arrays have same number of components and one array, say _a2_, has one
10579  *   tuple. Then
10580  *   _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ 0, j ].
10581  *
10582  * Info on components is copied either from the first array (in the first case) or from
10583  * the array with maximal number of elements (getNbOfElems()).
10584  *  \warning No check of division by zero is performed!
10585  *  \param [in] a1 - a numerator array.
10586  *  \param [in] a2 - a denominator array.
10587  *  \return DataArrayInt * - the new instance of DataArrayInt.
10588  *          The caller is to delete this result array using decrRef() as it is no more
10589  *          needed.
10590  *  \throw If either \a a1 or \a a2 is NULL.
10591  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
10592  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
10593  *         none of them has number of tuples or components equal to 1.
10594  */
10595 DataArrayInt *DataArrayInt::Divide(const DataArrayInt *a1, const DataArrayInt *a2)
10596 {
10597   if(!a1 || !a2)
10598     throw INTERP_KERNEL::Exception("DataArrayInt::Divide : input DataArrayInt instance is NULL !");
10599   int nbOfTuple1=a1->getNumberOfTuples();
10600   int nbOfTuple2=a2->getNumberOfTuples();
10601   int nbOfComp1=a1->getNumberOfComponents();
10602   int nbOfComp2=a2->getNumberOfComponents();
10603   if(nbOfTuple2==nbOfTuple1)
10604     {
10605       if(nbOfComp1==nbOfComp2)
10606         {
10607           MCAuto<DataArrayInt> ret=DataArrayInt::New();
10608           ret->alloc(nbOfTuple2,nbOfComp1);
10609           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::divides<int>());
10610           ret->copyStringInfoFrom(*a1);
10611           return ret.retn();
10612         }
10613       else if(nbOfComp2==1)
10614         {
10615           MCAuto<DataArrayInt> ret=DataArrayInt::New();
10616           ret->alloc(nbOfTuple1,nbOfComp1);
10617           const int *a2Ptr=a2->getConstPointer();
10618           const int *a1Ptr=a1->getConstPointer();
10619           int *res=ret->getPointer();
10620           for(int i=0;i<nbOfTuple1;i++)
10621             res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::divides<int>(),a2Ptr[i]));
10622           ret->copyStringInfoFrom(*a1);
10623           return ret.retn();
10624         }
10625       else
10626         {
10627           a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Divide !");
10628           return 0;
10629         }
10630     }
10631   else if(nbOfTuple2==1)
10632     {
10633       a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Divide !");
10634       MCAuto<DataArrayInt> ret=DataArrayInt::New();
10635       ret->alloc(nbOfTuple1,nbOfComp1);
10636       const int *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
10637       int *pt=ret->getPointer();
10638       for(int i=0;i<nbOfTuple1;i++)
10639         pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::divides<int>());
10640       ret->copyStringInfoFrom(*a1);
10641       return ret.retn();
10642     }
10643   else
10644     {
10645       a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Divide !");//will always throw an exception
10646       return 0;
10647     }
10648 }
10649
10650 /*!
10651  * Divide values of \a this array by values of another DataArrayInt. There are 3
10652  * valid cases.
10653  * 1.  The arrays have same number of tuples and components. Then each value of
10654  *    \a this array is divided by the corresponding value of \a other one, i.e.:
10655  *   _a_ [ i, j ] /= _other_ [ i, j ].
10656  * 2.  The arrays have same number of tuples and \a other array has one component. Then
10657  *   _a_ [ i, j ] /= _other_ [ i, 0 ].
10658  * 3.  The arrays have same number of components and \a other array has one tuple. Then
10659  *   _a_ [ i, j ] /= _a2_ [ 0, j ].
10660  *
10661  *  \warning No check of division by zero is performed!
10662  *  \param [in] other - an array to divide \a this one by.
10663  *  \throw If \a other is NULL.
10664  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
10665  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
10666  *         \a other has number of both tuples and components not equal to 1.
10667  */
10668 void DataArrayInt::divideEqual(const DataArrayInt *other)
10669 {
10670   if(!other)
10671     throw INTERP_KERNEL::Exception("DataArrayInt::divideEqual : input DataArrayInt instance is NULL !");
10672   const char *msg="Nb of tuples mismatch for DataArrayInt::divideEqual !";
10673   checkAllocated(); other->checkAllocated();
10674   int nbOfTuple=getNumberOfTuples();
10675   int nbOfTuple2=other->getNumberOfTuples();
10676   int nbOfComp=getNumberOfComponents();
10677   int nbOfComp2=other->getNumberOfComponents();
10678   if(nbOfTuple==nbOfTuple2)
10679     {
10680       if(nbOfComp==nbOfComp2)
10681         {
10682           std::transform(begin(),end(),other->begin(),getPointer(),std::divides<int>());
10683         }
10684       else if(nbOfComp2==1)
10685         {
10686           int *ptr=getPointer();
10687           const int *ptrc=other->getConstPointer();
10688           for(int i=0;i<nbOfTuple;i++)
10689             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::divides<int>(),*ptrc++));
10690         }
10691       else
10692         throw INTERP_KERNEL::Exception(msg);
10693     }
10694   else if(nbOfTuple2==1)
10695     {
10696       if(nbOfComp2==nbOfComp)
10697         {
10698           int *ptr=getPointer();
10699           const int *ptrc=other->getConstPointer();
10700           for(int i=0;i<nbOfTuple;i++)
10701             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::divides<int>());
10702         }
10703       else
10704         throw INTERP_KERNEL::Exception(msg);
10705     }
10706   else
10707     throw INTERP_KERNEL::Exception(msg);
10708   declareAsNew();
10709 }
10710
10711
10712 /*!
10713  * Returns a new DataArrayInt that is a modulus of two given arrays. There are 3
10714  * valid cases.
10715  * 1.  The arrays have same number of tuples and components. Then each value of
10716  *   the result array (_a_) is a division of the corresponding values of \a a1 and
10717  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] % _a2_ [ i, j ].
10718  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
10719  *   component. Then
10720  *   _a_ [ i, j ] = _a1_ [ i, j ] % _a2_ [ i, 0 ].
10721  * 3.  The arrays have same number of components and one array, say _a2_, has one
10722  *   tuple. Then
10723  *   _a_ [ i, j ] = _a1_ [ i, j ] % _a2_ [ 0, j ].
10724  *
10725  * Info on components is copied either from the first array (in the first case) or from
10726  * the array with maximal number of elements (getNbOfElems()).
10727  *  \warning No check of division by zero is performed!
10728  *  \param [in] a1 - a dividend array.
10729  *  \param [in] a2 - a divisor array.
10730  *  \return DataArrayInt * - the new instance of DataArrayInt.
10731  *          The caller is to delete this result array using decrRef() as it is no more
10732  *          needed.
10733  *  \throw If either \a a1 or \a a2 is NULL.
10734  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
10735  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
10736  *         none of them has number of tuples or components equal to 1.
10737  */
10738 DataArrayInt *DataArrayInt::Modulus(const DataArrayInt *a1, const DataArrayInt *a2)
10739 {
10740   if(!a1 || !a2)
10741     throw INTERP_KERNEL::Exception("DataArrayInt::Modulus : input DataArrayInt instance is NULL !");
10742   int nbOfTuple1=a1->getNumberOfTuples();
10743   int nbOfTuple2=a2->getNumberOfTuples();
10744   int nbOfComp1=a1->getNumberOfComponents();
10745   int nbOfComp2=a2->getNumberOfComponents();
10746   if(nbOfTuple2==nbOfTuple1)
10747     {
10748       if(nbOfComp1==nbOfComp2)
10749         {
10750           MCAuto<DataArrayInt> ret=DataArrayInt::New();
10751           ret->alloc(nbOfTuple2,nbOfComp1);
10752           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::modulus<int>());
10753           ret->copyStringInfoFrom(*a1);
10754           return ret.retn();
10755         }
10756       else if(nbOfComp2==1)
10757         {
10758           MCAuto<DataArrayInt> ret=DataArrayInt::New();
10759           ret->alloc(nbOfTuple1,nbOfComp1);
10760           const int *a2Ptr=a2->getConstPointer();
10761           const int *a1Ptr=a1->getConstPointer();
10762           int *res=ret->getPointer();
10763           for(int i=0;i<nbOfTuple1;i++)
10764             res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::modulus<int>(),a2Ptr[i]));
10765           ret->copyStringInfoFrom(*a1);
10766           return ret.retn();
10767         }
10768       else
10769         {
10770           a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Modulus !");
10771           return 0;
10772         }
10773     }
10774   else if(nbOfTuple2==1)
10775     {
10776       a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Modulus !");
10777       MCAuto<DataArrayInt> ret=DataArrayInt::New();
10778       ret->alloc(nbOfTuple1,nbOfComp1);
10779       const int *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
10780       int *pt=ret->getPointer();
10781       for(int i=0;i<nbOfTuple1;i++)
10782         pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::modulus<int>());
10783       ret->copyStringInfoFrom(*a1);
10784       return ret.retn();
10785     }
10786   else
10787     {
10788       a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Modulus !");//will always throw an exception
10789       return 0;
10790     }
10791 }
10792
10793 /*!
10794  * Modify \a this array so that each value becomes a modulus of division of this value by
10795  * a value of another DataArrayInt. There are 3 valid cases.
10796  * 1.  The arrays have same number of tuples and components. Then each value of
10797  *    \a this array is divided by the corresponding value of \a other one, i.e.:
10798  *   _a_ [ i, j ] %= _other_ [ i, j ].
10799  * 2.  The arrays have same number of tuples and \a other array has one component. Then
10800  *   _a_ [ i, j ] %= _other_ [ i, 0 ].
10801  * 3.  The arrays have same number of components and \a other array has one tuple. Then
10802  *   _a_ [ i, j ] %= _a2_ [ 0, j ].
10803  *
10804  *  \warning No check of division by zero is performed!
10805  *  \param [in] other - a divisor array.
10806  *  \throw If \a other is NULL.
10807  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
10808  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
10809  *         \a other has number of both tuples and components not equal to 1.
10810  */
10811 void DataArrayInt::modulusEqual(const DataArrayInt *other)
10812 {
10813   if(!other)
10814     throw INTERP_KERNEL::Exception("DataArrayInt::modulusEqual : input DataArrayInt instance is NULL !");
10815   const char *msg="Nb of tuples mismatch for DataArrayInt::modulusEqual !";
10816   checkAllocated(); other->checkAllocated();
10817   int nbOfTuple=getNumberOfTuples();
10818   int nbOfTuple2=other->getNumberOfTuples();
10819   int nbOfComp=getNumberOfComponents();
10820   int nbOfComp2=other->getNumberOfComponents();
10821   if(nbOfTuple==nbOfTuple2)
10822     {
10823       if(nbOfComp==nbOfComp2)
10824         {
10825           std::transform(begin(),end(),other->begin(),getPointer(),std::modulus<int>());
10826         }
10827       else if(nbOfComp2==1)
10828         {
10829           if(nbOfComp2==nbOfComp)
10830             {
10831               int *ptr=getPointer();
10832               const int *ptrc=other->getConstPointer();
10833               for(int i=0;i<nbOfTuple;i++)
10834                 std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::modulus<int>(),*ptrc++));
10835             }
10836           else
10837             throw INTERP_KERNEL::Exception(msg);
10838         }
10839       else
10840         throw INTERP_KERNEL::Exception(msg);
10841     }
10842   else if(nbOfTuple2==1)
10843     {
10844       int *ptr=getPointer();
10845       const int *ptrc=other->getConstPointer();
10846       for(int i=0;i<nbOfTuple;i++)
10847         std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::modulus<int>());
10848     }
10849   else
10850     throw INTERP_KERNEL::Exception(msg);
10851   declareAsNew();
10852 }
10853
10854 /*!
10855  * Returns a new DataArrayInt that is the result of pow of two given arrays. There are 3
10856  * valid cases.
10857  *
10858  *  \param [in] a1 - an array to pow up.
10859  *  \param [in] a2 - another array to sum up.
10860  *  \return DataArrayInt * - the new instance of DataArrayInt.
10861  *          The caller is to delete this result array using decrRef() as it is no more
10862  *          needed.
10863  *  \throw If either \a a1 or \a a2 is NULL.
10864  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
10865  *  \throw If \a a1->getNumberOfComponents() != 1 or \a a2->getNumberOfComponents() != 1.
10866  *  \throw If there is a negative value in \a a2.
10867  */
10868 DataArrayInt *DataArrayInt::Pow(const DataArrayInt *a1, const DataArrayInt *a2)
10869 {
10870   if(!a1 || !a2)
10871     throw INTERP_KERNEL::Exception("DataArrayInt::Pow : at least one of input instances is null !");
10872   int nbOfTuple=a1->getNumberOfTuples();
10873   int nbOfTuple2=a2->getNumberOfTuples();
10874   int nbOfComp=a1->getNumberOfComponents();
10875   int nbOfComp2=a2->getNumberOfComponents();
10876   if(nbOfTuple!=nbOfTuple2)
10877     throw INTERP_KERNEL::Exception("DataArrayInt::Pow : number of tuples mismatches !");
10878   if(nbOfComp!=1 || nbOfComp2!=1)
10879     throw INTERP_KERNEL::Exception("DataArrayInt::Pow : number of components of both arrays must be equal to 1 !");
10880   MCAuto<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbOfTuple,1);
10881   const int *ptr1(a1->begin()),*ptr2(a2->begin());
10882   int *ptr=ret->getPointer();
10883   for(int i=0;i<nbOfTuple;i++,ptr1++,ptr2++,ptr++)
10884     {
10885       if(*ptr2>=0)
10886         {
10887           int tmp=1;
10888           for(int j=0;j<*ptr2;j++)
10889             tmp*=*ptr1;
10890           *ptr=tmp;
10891         }
10892       else
10893         {
10894           std::ostringstream oss; oss << "DataArrayInt::Pow : on tuple #" << i << " of a2 value is < 0 (" << *ptr2 << ") !";
10895           throw INTERP_KERNEL::Exception(oss.str().c_str());
10896         }
10897     }
10898   return ret.retn();
10899 }
10900
10901 /*!
10902  * Apply pow on values of another DataArrayInt to values of \a this one.
10903  *
10904  *  \param [in] other - an array to pow to \a this one.
10905  *  \throw If \a other is NULL.
10906  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples()
10907  *  \throw If \a this->getNumberOfComponents() != 1 or \a other->getNumberOfComponents() != 1
10908  *  \throw If there is a negative value in \a other.
10909  */
10910 void DataArrayInt::powEqual(const DataArrayInt *other)
10911 {
10912   if(!other)
10913     throw INTERP_KERNEL::Exception("DataArrayInt::powEqual : input instance is null !");
10914   int nbOfTuple=getNumberOfTuples();
10915   int nbOfTuple2=other->getNumberOfTuples();
10916   int nbOfComp=getNumberOfComponents();
10917   int nbOfComp2=other->getNumberOfComponents();
10918   if(nbOfTuple!=nbOfTuple2)
10919     throw INTERP_KERNEL::Exception("DataArrayInt::powEqual : number of tuples mismatches !");
10920   if(nbOfComp!=1 || nbOfComp2!=1)
10921     throw INTERP_KERNEL::Exception("DataArrayInt::powEqual : number of components of both arrays must be equal to 1 !");
10922   int *ptr=getPointer();
10923   const int *ptrc=other->begin();
10924   for(int i=0;i<nbOfTuple;i++,ptrc++,ptr++)
10925     {
10926       if(*ptrc>=0)
10927         {
10928           int tmp=1;
10929           for(int j=0;j<*ptrc;j++)
10930             tmp*=*ptr;
10931           *ptr=tmp;
10932         }
10933       else
10934         {
10935           std::ostringstream oss; oss << "DataArrayInt::powEqual : on tuple #" << i << " of other value is < 0 (" << *ptrc << ") !";
10936           throw INTERP_KERNEL::Exception(oss.str().c_str());
10937         }
10938     }
10939   declareAsNew();
10940 }
10941
10942 /*!
10943  * Returns a C array which is a renumbering map in "Old to New" mode for the input array.
10944  * This map, if applied to \a start array, would make it sorted. For example, if
10945  * \a start array contents are [9,10,0,6,4,11,3,7] then the contents of the result array is
10946  * [5,6,0,3,2,7,1,4].
10947  *  \param [in] start - pointer to the first element of the array for which the
10948  *         permutation map is computed.
10949  *  \param [in] end - pointer specifying the end of the array \a start, so that
10950  *         the last value of \a start is \a end[ -1 ].
10951  *  \return int * - the result permutation array that the caller is to delete as it is no
10952  *         more needed.
10953  *  \throw If there are equal values in the input array.
10954  */
10955 int *DataArrayInt::CheckAndPreparePermutation(const int *start, const int *end)
10956 {
10957   std::size_t sz=std::distance(start,end);
10958   int *ret=(int *)malloc(sz*sizeof(int));
10959   int *work=new int[sz];
10960   std::copy(start,end,work);
10961   std::sort(work,work+sz);
10962   if(std::unique(work,work+sz)!=work+sz)
10963     {
10964       delete [] work;
10965       free(ret);
10966       throw INTERP_KERNEL::Exception("Some elements are equals in the specified array !");
10967     }
10968   std::map<int,int> m;
10969   for(int *workPt=work;workPt!=work+sz;workPt++)
10970     m[*workPt]=(int)std::distance(work,workPt);
10971   int *iter2=ret;
10972   for(const int *iter=start;iter!=end;iter++,iter2++)
10973     *iter2=m[*iter];
10974   delete [] work;
10975   return ret;
10976 }
10977
10978 /*!
10979  * Returns a new DataArrayInt containing an arithmetic progression
10980  * that is equal to the sequence returned by Python \c range(\a begin,\a  end,\a  step )
10981  * function.
10982  *  \param [in] begin - the start value of the result sequence.
10983  *  \param [in] end - limiting value, so that every value of the result array is less than
10984  *              \a end.
10985  *  \param [in] step - specifies the increment or decrement.
10986  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
10987  *          array using decrRef() as it is no more needed.
10988  *  \throw If \a step == 0.
10989  *  \throw If \a end < \a begin && \a step > 0.
10990  *  \throw If \a end > \a begin && \a step < 0.
10991  */
10992 DataArrayInt *DataArrayInt::Range(int begin, int end, int step)
10993 {
10994   int nbOfTuples=GetNumberOfItemGivenBESRelative(begin,end,step,"DataArrayInt::Range");
10995   MCAuto<DataArrayInt> ret=DataArrayInt::New();
10996   ret->alloc(nbOfTuples,1);
10997   int *ptr=ret->getPointer();
10998   if(step>0)
10999     {
11000       for(int i=begin;i<end;i+=step,ptr++)
11001         *ptr=i;
11002     }
11003   else
11004     {
11005       for(int i=begin;i>end;i+=step,ptr++)
11006         *ptr=i;
11007     }
11008   return ret.retn();
11009 }
11010
11011 /*!
11012  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
11013  * Server side.
11014  */
11015 void DataArrayInt::getTinySerializationIntInformation(std::vector<int>& tinyInfo) const
11016 {
11017   tinyInfo.resize(2);
11018   if(isAllocated())
11019     {
11020       tinyInfo[0]=getNumberOfTuples();
11021       tinyInfo[1]=getNumberOfComponents();
11022     }
11023   else
11024     {
11025       tinyInfo[0]=-1;
11026       tinyInfo[1]=-1;
11027     }
11028 }
11029
11030 /*!
11031  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
11032  * Server side.
11033  */
11034 void DataArrayInt::getTinySerializationStrInformation(std::vector<std::string>& tinyInfo) const
11035 {
11036   if(isAllocated())
11037     {
11038       int nbOfCompo=getNumberOfComponents();
11039       tinyInfo.resize(nbOfCompo+1);
11040       tinyInfo[0]=getName();
11041       for(int i=0;i<nbOfCompo;i++)
11042         tinyInfo[i+1]=getInfoOnComponent(i);
11043     }
11044   else
11045     {
11046       tinyInfo.resize(1);
11047       tinyInfo[0]=getName();
11048     }
11049 }
11050
11051 /*!
11052  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
11053  * This method returns if a feeding is needed.
11054  */
11055 bool DataArrayInt::resizeForUnserialization(const std::vector<int>& tinyInfoI)
11056 {
11057   int nbOfTuple=tinyInfoI[0];
11058   int nbOfComp=tinyInfoI[1];
11059   if(nbOfTuple!=-1 || nbOfComp!=-1)
11060     {
11061       alloc(nbOfTuple,nbOfComp);
11062       return true;
11063     }
11064   return false;
11065 }
11066
11067 /*!
11068  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
11069  * This method returns if a feeding is needed.
11070  */
11071 void DataArrayInt::finishUnserialization(const std::vector<int>& tinyInfoI, const std::vector<std::string>& tinyInfoS)
11072 {
11073   setName(tinyInfoS[0]);
11074   if(isAllocated())
11075     {
11076       int nbOfCompo=tinyInfoI[1];
11077       for(int i=0;i<nbOfCompo;i++)
11078         setInfoOnComponent(i,tinyInfoS[i+1]);
11079     }
11080 }
11081
11082 DataArrayIntIterator::DataArrayIntIterator(DataArrayInt *da):_da(da),_pt(0),_tuple_id(0),_nb_comp(0),_nb_tuple(0)
11083 {
11084   if(_da)
11085     {
11086       _da->incrRef();
11087       if(_da->isAllocated())
11088         {
11089           _nb_comp=da->getNumberOfComponents();
11090           _nb_tuple=da->getNumberOfTuples();
11091           _pt=da->getPointer();
11092         }
11093     }
11094 }
11095
11096 DataArrayIntIterator::~DataArrayIntIterator()
11097 {
11098   if(_da)
11099     _da->decrRef();
11100 }
11101
11102 DataArrayIntTuple *DataArrayIntIterator::nextt()
11103 {
11104   if(_tuple_id<_nb_tuple)
11105     {
11106       _tuple_id++;
11107       DataArrayIntTuple *ret=new DataArrayIntTuple(_pt,_nb_comp);
11108       _pt+=_nb_comp;
11109       return ret;
11110     }
11111   else
11112     return 0;
11113 }
11114
11115 DataArrayIntTuple::DataArrayIntTuple(int *pt, int nbOfComp):_pt(pt),_nb_of_compo(nbOfComp)
11116 {
11117 }
11118
11119 std::string DataArrayIntTuple::repr() const
11120 {
11121   std::ostringstream oss; oss << "(";
11122   for(int i=0;i<_nb_of_compo-1;i++)
11123     oss << _pt[i] << ", ";
11124   oss << _pt[_nb_of_compo-1] << ")";
11125   return oss.str();
11126 }
11127
11128 int DataArrayIntTuple::intValue() const
11129 {
11130   if(_nb_of_compo==1)
11131     return *_pt;
11132   throw INTERP_KERNEL::Exception("DataArrayIntTuple::intValue : DataArrayIntTuple instance has not exactly 1 component -> Not possible to convert it into an integer !");
11133 }
11134
11135 /*!
11136  * This method returns a newly allocated instance the caller should dealed with by a MEDCoupling::DataArrayInt::decrRef.
11137  * This method performs \b no copy of data. The content is only referenced using MEDCoupling::DataArrayInt::useArray with ownership set to \b false.
11138  * 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
11139  * \b nbOfCompo=1 and \bnbOfTuples==this->_nb_of_elem.
11140  */
11141 DataArrayInt *DataArrayIntTuple::buildDAInt(int nbOfTuples, int nbOfCompo) const
11142 {
11143   if((_nb_of_compo==nbOfCompo && nbOfTuples==1) || (_nb_of_compo==nbOfTuples && nbOfCompo==1))
11144     {
11145       DataArrayInt *ret=DataArrayInt::New();
11146       ret->useExternalArrayWithRWAccess(_pt,nbOfTuples,nbOfCompo);
11147       return ret;
11148     }
11149   else
11150     {
11151       std::ostringstream oss; oss << "DataArrayIntTuple::buildDAInt : unable to build a requested DataArrayInt instance with nbofTuple=" << nbOfTuples << " and nbOfCompo=" << nbOfCompo;
11152       oss << ".\nBecause the number of elements in this is " << _nb_of_compo << " !";
11153       throw INTERP_KERNEL::Exception(oss.str().c_str());
11154     }
11155 }