Salome HOME
5067c1373dbe12a61bde8103a3da473b1c0c2312
[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
23 #include "BBTree.txx"
24 #include "GenMathFormulae.hxx"
25 #include "InterpKernelAutoPtr.hxx"
26 #include "InterpKernelExprParser.hxx"
27
28 #include <set>
29 #include <cmath>
30 #include <limits>
31 #include <numeric>
32 #include <algorithm>
33 #include <functional>
34
35 typedef double (*MYFUNCPTR)(double);
36
37 using namespace MEDCoupling;
38
39 template class MEDCoupling::MemArray<int>;
40 template class MEDCoupling::MemArray<double>;
41 template class MEDCoupling::DataArrayTemplate<int>;
42 template class MEDCoupling::DataArrayTemplate<double>;
43 template class MEDCoupling::DataArrayTemplateFP<double>;
44
45 template<int SPACEDIM>
46 void DataArrayDouble::findCommonTuplesAlg(const double *bbox, int nbNodes, int limitNodeId, double prec, DataArrayInt *c, DataArrayInt *cI) const
47 {
48   const double *coordsPtr=getConstPointer();
49   BBTreePts<SPACEDIM,int> myTree(bbox,0,0,nbNodes,prec);
50   std::vector<bool> isDone(nbNodes);
51   for(int i=0;i<nbNodes;i++)
52     {
53       if(!isDone[i])
54         {
55           std::vector<int> intersectingElems;
56           myTree.getElementsAroundPoint(coordsPtr+i*SPACEDIM,intersectingElems);
57           if(intersectingElems.size()>1)
58             {
59               std::vector<int> commonNodes;
60               for(std::vector<int>::const_iterator it=intersectingElems.begin();it!=intersectingElems.end();it++)
61                 if(*it!=i)
62                   if(*it>=limitNodeId)
63                     {
64                       commonNodes.push_back(*it);
65                       isDone[*it]=true;
66                     }
67               if(!commonNodes.empty())
68                 {
69                   cI->pushBackSilent(cI->back()+(int)commonNodes.size()+1);
70                   c->pushBackSilent(i);
71                   c->insertAtTheEnd(commonNodes.begin(),commonNodes.end());
72                 }
73             }
74         }
75     }
76 }
77
78 template<int SPACEDIM>
79 void DataArrayDouble::FindTupleIdsNearTuplesAlg(const BBTreePts<SPACEDIM,int>& myTree, const double *pos, int nbOfTuples, double eps,
80                                                 DataArrayInt *c, DataArrayInt *cI)
81 {
82   for(int i=0;i<nbOfTuples;i++)
83     {
84       std::vector<int> intersectingElems;
85       myTree.getElementsAroundPoint(pos+i*SPACEDIM,intersectingElems);
86       std::vector<int> commonNodes;
87       for(std::vector<int>::const_iterator it=intersectingElems.begin();it!=intersectingElems.end();it++)
88         commonNodes.push_back(*it);
89       cI->pushBackSilent(cI->back()+(int)commonNodes.size());
90       c->insertAtTheEnd(commonNodes.begin(),commonNodes.end());
91     }
92 }
93
94 template<int SPACEDIM>
95 void DataArrayDouble::FindClosestTupleIdAlg(const BBTreePts<SPACEDIM,int>& myTree, double dist, const double *pos, int nbOfTuples, const double *thisPt, int thisNbOfTuples, int *res)
96 {
97   double distOpt(dist);
98   const double *p(pos);
99   int *r(res);
100   for(int i=0;i<nbOfTuples;i++,p+=SPACEDIM,r++)
101     {
102       while(true)
103         {
104           int elem=-1;
105           double ret=myTree.getElementsAroundPoint2(p,distOpt,elem);
106           if(ret!=std::numeric_limits<double>::max())
107             {
108               distOpt=std::max(ret,1e-4);
109               *r=elem;
110               break;
111             }
112           else
113             { distOpt=2*distOpt; continue; }
114         }
115     }
116 }
117
118 int DataArray::EffectiveCircPerm(int nbOfShift, int nbOfTuples)
119 {
120   if(nbOfTuples<=0)
121     throw INTERP_KERNEL::Exception("DataArray::EffectiveCircPerm : number of tuples is expected to be > 0 !");
122   if(nbOfShift>=0)
123     {
124       return nbOfShift%nbOfTuples;
125     }
126   else
127     {
128       int tmp(-nbOfShift);
129       tmp=tmp%nbOfTuples;
130       return nbOfTuples-tmp;
131     }
132 }
133
134 std::size_t DataArray::getHeapMemorySizeWithoutChildren() const
135 {
136   std::size_t sz1=_name.capacity();
137   std::size_t sz2=_info_on_compo.capacity();
138   std::size_t sz3=0;
139   for(std::vector<std::string>::const_iterator it=_info_on_compo.begin();it!=_info_on_compo.end();it++)
140     sz3+=(*it).capacity();
141   return sz1+sz2+sz3;
142 }
143
144 std::vector<const BigMemoryObject *> DataArray::getDirectChildrenWithNull() const
145 {
146   return std::vector<const BigMemoryObject *>();
147 }
148
149 /*!
150  * Sets the attribute \a _name of \a this array.
151  * See \ref MEDCouplingArrayBasicsName "DataArrays infos" for more information.
152  *  \param [in] name - new array name
153  */
154 void DataArray::setName(const std::string& name)
155 {
156   _name=name;
157 }
158
159 /*!
160  * Copies textual data from an \a other DataArray. The copied data are
161  * - the name attribute,
162  * - the information of components.
163  *
164  * For more information on these data see \ref MEDCouplingArrayBasicsName "DataArrays infos".
165  *
166  *  \param [in] other - another instance of DataArray to copy the textual data from.
167  *  \throw If number of components of \a this array differs from that of the \a other.
168  */
169 void DataArray::copyStringInfoFrom(const DataArray& other)
170 {
171   if(_info_on_compo.size()!=other._info_on_compo.size())
172     throw INTERP_KERNEL::Exception("Size of arrays mismatches on copyStringInfoFrom !");
173   _name=other._name;
174   _info_on_compo=other._info_on_compo;
175 }
176
177 void DataArray::copyPartOfStringInfoFrom(const DataArray& other, const std::vector<int>& compoIds)
178 {
179   int nbOfCompoOth=other.getNumberOfComponents();
180   std::size_t newNbOfCompo=compoIds.size();
181   for(std::size_t i=0;i<newNbOfCompo;i++)
182     if(compoIds[i]>=nbOfCompoOth || compoIds[i]<0)
183       {
184         std::ostringstream oss; oss << "Specified component id is out of range (" << compoIds[i] << ") compared with nb of actual components (" << nbOfCompoOth << ")";
185         throw INTERP_KERNEL::Exception(oss.str().c_str());
186       }
187   for(std::size_t i=0;i<newNbOfCompo;i++)
188     setInfoOnComponent((int)i,other.getInfoOnComponent(compoIds[i]));
189 }
190
191 void DataArray::copyPartOfStringInfoFrom2(const std::vector<int>& compoIds, const DataArray& other)
192 {
193   int nbOfCompo=getNumberOfComponents();
194   std::size_t partOfCompoToSet=compoIds.size();
195   if((int)partOfCompoToSet!=other.getNumberOfComponents())
196     throw INTERP_KERNEL::Exception("Given compoIds has not the same size as number of components of given array !");
197   for(std::size_t i=0;i<partOfCompoToSet;i++)
198     if(compoIds[i]>=nbOfCompo || compoIds[i]<0)
199       {
200         std::ostringstream oss; oss << "Specified component id is out of range (" << compoIds[i] << ") compared with nb of actual components (" << nbOfCompo << ")";
201         throw INTERP_KERNEL::Exception(oss.str().c_str());
202       }
203   for(std::size_t i=0;i<partOfCompoToSet;i++)
204     setInfoOnComponent(compoIds[i],other.getInfoOnComponent((int)i));
205 }
206
207 bool DataArray::areInfoEqualsIfNotWhy(const DataArray& other, std::string& reason) const
208 {
209   std::ostringstream oss;
210   if(_name!=other._name)
211     {
212       oss << "Names DataArray mismatch : this name=\"" << _name << " other name=\"" << other._name << "\" !";
213       reason=oss.str();
214       return false;
215     }
216   if(_info_on_compo!=other._info_on_compo)
217     {
218       oss << "Components DataArray mismatch : \nThis components=";
219       for(std::vector<std::string>::const_iterator it=_info_on_compo.begin();it!=_info_on_compo.end();it++)
220         oss << "\"" << *it << "\",";
221       oss << "\nOther components=";
222       for(std::vector<std::string>::const_iterator it=other._info_on_compo.begin();it!=other._info_on_compo.end();it++)
223         oss << "\"" << *it << "\",";
224       reason=oss.str();
225       return false;
226     }
227   return true;
228 }
229
230 /*!
231  * Compares textual information of \a this DataArray with that of an \a other one.
232  * The compared data are
233  * - the name attribute,
234  * - the information of components.
235  *
236  * For more information on these data see \ref MEDCouplingArrayBasicsName "DataArrays infos".
237  *  \param [in] other - another instance of DataArray to compare the textual data of.
238  *  \return bool - \a true if the textual information is same, \a false else.
239  */
240 bool DataArray::areInfoEquals(const DataArray& other) const
241 {
242   std::string tmp;
243   return areInfoEqualsIfNotWhy(other,tmp);
244 }
245
246 void DataArray::reprWithoutNameStream(std::ostream& stream) const
247 {
248   stream << "Number of components : "<< getNumberOfComponents() << "\n";
249   stream << "Info of these components : ";
250   for(std::vector<std::string>::const_iterator iter=_info_on_compo.begin();iter!=_info_on_compo.end();iter++)
251     stream << "\"" << *iter << "\"   ";
252   stream << "\n";
253 }
254
255 std::string DataArray::cppRepr(const std::string& varName) const
256 {
257   std::ostringstream ret;
258   reprCppStream(varName,ret);
259   return ret.str();
260 }
261
262 /*!
263  * Sets information on all components. To know more on format of this information
264  * see \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
265  *  \param [in] info - a vector of strings.
266  *  \throw If size of \a info differs from the number of components of \a this.
267  */
268 void DataArray::setInfoOnComponents(const std::vector<std::string>& info)
269 {
270   if(getNumberOfComponents()!=(int)info.size())
271     {
272       std::ostringstream oss; oss << "DataArray::setInfoOnComponents : input is of size " << info.size() << " whereas number of components is equal to " << getNumberOfComponents() << " !";
273       throw INTERP_KERNEL::Exception(oss.str().c_str());
274     }
275   _info_on_compo=info;
276 }
277
278 /*!
279  * This method is only a dispatcher towards DataArrayDouble::setPartOfValues3, DataArrayInt::setPartOfValues3, DataArrayChar::setPartOfValues3 depending on the true
280  * type of \a this and \a aBase.
281  *
282  * \throw If \a aBase and \a this do not have the same type.
283  *
284  * \sa DataArrayDouble::setPartOfValues3, DataArrayInt::setPartOfValues3, DataArrayChar::setPartOfValues3.
285  */
286 void DataArray::setPartOfValuesBase3(const DataArray *aBase, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare)
287 {
288   if(!aBase)
289     throw INTERP_KERNEL::Exception("DataArray::setPartOfValuesBase3 : input aBase object is NULL !");
290   DataArrayDouble *this1(dynamic_cast<DataArrayDouble *>(this));
291   DataArrayInt *this2(dynamic_cast<DataArrayInt *>(this));
292   DataArrayChar *this3(dynamic_cast<DataArrayChar *>(this));
293   const DataArrayDouble *a1(dynamic_cast<const DataArrayDouble *>(aBase));
294   const DataArrayInt *a2(dynamic_cast<const DataArrayInt *>(aBase));
295   const DataArrayChar *a3(dynamic_cast<const DataArrayChar *>(aBase));
296   if(this1 && a1)
297     {
298       this1->setPartOfValues3(a1,bgTuples,endTuples,bgComp,endComp,stepComp,strictCompoCompare);
299       return ;
300     }
301   if(this2 && a2)
302     {
303       this2->setPartOfValues3(a2,bgTuples,endTuples,bgComp,endComp,stepComp,strictCompoCompare);
304       return ;
305     }
306   if(this3 && a3)
307     {
308       this3->setPartOfValues3(a3,bgTuples,endTuples,bgComp,endComp,stepComp,strictCompoCompare);
309       return ;
310     }
311   throw INTERP_KERNEL::Exception("DataArray::setPartOfValuesBase3 : input aBase object and this do not have the same type !");
312 }
313
314 std::vector<std::string> DataArray::getVarsOnComponent() const
315 {
316   int nbOfCompo=(int)_info_on_compo.size();
317   std::vector<std::string> ret(nbOfCompo);
318   for(int i=0;i<nbOfCompo;i++)
319     ret[i]=getVarOnComponent(i);
320   return ret;
321 }
322
323 std::vector<std::string> DataArray::getUnitsOnComponent() const
324 {
325   int nbOfCompo=(int)_info_on_compo.size();
326   std::vector<std::string> ret(nbOfCompo);
327   for(int i=0;i<nbOfCompo;i++)
328     ret[i]=getUnitOnComponent(i);
329   return ret;
330 }
331
332 /*!
333  * Returns information on a component specified by an index.
334  * To know more on format of this information
335  * see \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
336  *  \param [in] i - the index (zero based) of the component of interest.
337  *  \return std::string - a string containing the information on \a i-th component.
338  *  \throw If \a i is not a valid component index.
339  */
340 std::string DataArray::getInfoOnComponent(int i) const
341 {
342   if(i<(int)_info_on_compo.size() && i>=0)
343     return _info_on_compo[i];
344   else
345     {
346       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();
347       throw INTERP_KERNEL::Exception(oss.str().c_str());
348     }
349 }
350
351 /*!
352  * Returns the var part of the full information of the \a i-th component.
353  * For example, if \c getInfoOnComponent(0) returns "SIGXY [N/m^2]", then
354  * \c getVarOnComponent(0) returns "SIGXY".
355  * If a unit part of information is not detected by presence of
356  * two square brackets, then the full information is returned.
357  * To read more about the component information format, see
358  * \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
359  *  \param [in] i - the index (zero based) of the component of interest.
360  *  \return std::string - a string containing the var information, or the full info.
361  *  \throw If \a i is not a valid component index.
362  */
363 std::string DataArray::getVarOnComponent(int i) const
364 {
365   if(i<(int)_info_on_compo.size() && i>=0)
366     {
367       return GetVarNameFromInfo(_info_on_compo[i]);
368     }
369   else
370     {
371       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();
372       throw INTERP_KERNEL::Exception(oss.str().c_str());
373     }
374 }
375
376 /*!
377  * Returns the unit part of the full information of the \a i-th component.
378  * For example, if \c getInfoOnComponent(0) returns "SIGXY [ N/m^2]", then
379  * \c getUnitOnComponent(0) returns " N/m^2".
380  * If a unit part of information is not detected by presence of
381  * two square brackets, then an empty string is returned.
382  * To read more about the component information format, see
383  * \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
384  *  \param [in] i - the index (zero based) of the component of interest.
385  *  \return std::string - a string containing the unit information, if any, or "".
386  *  \throw If \a i is not a valid component index.
387  */
388 std::string DataArray::getUnitOnComponent(int i) const
389 {
390   if(i<(int)_info_on_compo.size() && i>=0)
391     {
392       return GetUnitFromInfo(_info_on_compo[i]);
393     }
394   else
395     {
396       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();
397       throw INTERP_KERNEL::Exception(oss.str().c_str());
398     }
399 }
400
401 /*!
402  * Returns the var part of the full component information.
403  * For example, if \a info == "SIGXY [N/m^2]", then this method returns "SIGXY".
404  * If a unit part of information is not detected by presence of
405  * two square brackets, then the whole \a info is returned.
406  * To read more about the component information format, see
407  * \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
408  *  \param [in] info - the full component information.
409  *  \return std::string - a string containing only var information, or the \a info.
410  */
411 std::string DataArray::GetVarNameFromInfo(const std::string& info)
412 {
413   std::size_t p1=info.find_last_of('[');
414   std::size_t p2=info.find_last_of(']');
415   if(p1==std::string::npos || p2==std::string::npos)
416     return info;
417   if(p1>p2)
418     return info;
419   if(p1==0)
420     return std::string();
421   std::size_t p3=info.find_last_not_of(' ',p1-1);
422   return info.substr(0,p3+1);
423 }
424
425 /*!
426  * Returns the unit part of the full component information.
427  * For example, if \a info == "SIGXY [ N/m^2]", then this method returns " N/m^2".
428  * If a unit part of information is not detected by presence of
429  * two square brackets, then an empty string is returned.
430  * To read more about the component information format, see
431  * \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
432  *  \param [in] info - the full component information.
433  *  \return std::string - a string containing only unit information, if any, or "".
434  */
435 std::string DataArray::GetUnitFromInfo(const std::string& info)
436 {
437   std::size_t p1=info.find_last_of('[');
438   std::size_t p2=info.find_last_of(']');
439   if(p1==std::string::npos || p2==std::string::npos)
440     return std::string();
441   if(p1>p2)
442     return std::string();
443   return info.substr(p1+1,p2-p1-1);
444 }
445
446 /*!
447  * This method put in info format the result of the merge of \a var and \a unit.
448  * The standard format for that is "var [unit]".
449  * Inversely you can retrieve the var part or the unit part of info string using resp. GetVarNameFromInfo and GetUnitFromInfo.
450  */
451 std::string DataArray::BuildInfoFromVarAndUnit(const std::string& var, const std::string& unit)
452 {
453   std::ostringstream oss;
454   oss << var << " [" << unit << "]";
455   return oss.str();
456 }
457
458 std::string DataArray::GetAxisTypeRepr(MEDCouplingAxisType at)
459 {
460   switch(at)
461     {
462     case AX_CART:
463       return std::string("AX_CART");
464     case AX_CYL:
465       return std::string("AX_CYL");
466     case AX_SPHER:
467       return std::string("AX_SPHER");
468     default:
469       throw INTERP_KERNEL::Exception("DataArray::GetAxisTypeRepr : unrecognized axis type enum !");
470     }
471 }
472
473 /*!
474  * Returns a new DataArray by concatenating all given arrays, so that (1) the number
475  * of tuples in the result array is a sum of the number of tuples of given arrays and (2)
476  * the number of component in the result array is same as that of each of given arrays.
477  * Info on components is copied from the first of the given arrays. Number of components
478  * in the given arrays must be  the same.
479  *  \param [in] arrs - a sequence of arrays to include in the result array. All arrays must have the same type.
480  *  \return DataArray * - the new instance of DataArray (that can be either DataArrayInt, DataArrayDouble, DataArrayChar).
481  *          The caller is to delete this result array using decrRef() as it is no more
482  *          needed.
483  *  \throw If all arrays within \a arrs are NULL.
484  *  \throw If all not null arrays in \a arrs have not the same type.
485  *  \throw If getNumberOfComponents() of arrays within \a arrs.
486  */
487 DataArray *DataArray::Aggregate(const std::vector<const DataArray *>& arrs)
488 {
489   std::vector<const DataArray *> arr2;
490   for(std::vector<const DataArray *>::const_iterator it=arrs.begin();it!=arrs.end();it++)
491     if(*it)
492       arr2.push_back(*it);
493   if(arr2.empty())
494     throw INTERP_KERNEL::Exception("DataArray::Aggregate : only null instance in input vector !");
495   std::vector<const DataArrayDouble *> arrd;
496   std::vector<const DataArrayInt *> arri;
497   std::vector<const DataArrayChar *> arrc;
498   for(std::vector<const DataArray *>::const_iterator it=arr2.begin();it!=arr2.end();it++)
499     {
500       const DataArrayDouble *a=dynamic_cast<const DataArrayDouble *>(*it);
501       if(a)
502         { arrd.push_back(a); continue; }
503       const DataArrayInt *b=dynamic_cast<const DataArrayInt *>(*it);
504       if(b)
505         { arri.push_back(b); continue; }
506       const DataArrayChar *c=dynamic_cast<const DataArrayChar *>(*it);
507       if(c)
508         { arrc.push_back(c); continue; }
509       throw INTERP_KERNEL::Exception("DataArray::Aggregate : presence of not null instance in inuput that is not in [DataArrayDouble, DataArrayInt, DataArrayChar] !");
510     }
511   if(arr2.size()==arrd.size())
512     return DataArrayDouble::Aggregate(arrd);
513   if(arr2.size()==arri.size())
514     return DataArrayInt::Aggregate(arri);
515   if(arr2.size()==arrc.size())
516     return DataArrayChar::Aggregate(arrc);
517   throw INTERP_KERNEL::Exception("DataArray::Aggregate : all input arrays must have the same type !");
518 }
519
520 /*!
521  * Sets information on a component specified by an index.
522  * To know more on format of this information
523  * see \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
524  *  \warning Don't pass NULL as \a info!
525  *  \param [in] i - the index (zero based) of the component of interest.
526  *  \param [in] info - the string containing the information.
527  *  \throw If \a i is not a valid component index.
528  */
529 void DataArray::setInfoOnComponent(int i, const std::string& info)
530 {
531   if(i<(int)_info_on_compo.size() && i>=0)
532     _info_on_compo[i]=info;
533   else
534     {
535       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();
536       throw INTERP_KERNEL::Exception(oss.str().c_str());
537     }
538 }
539
540 /*!
541  * Sets information on all components. This method can change number of components
542  * at certain conditions; if the conditions are not respected, an exception is thrown.
543  * The number of components can be changed in \a this only if \a this is not allocated.
544  * The condition of number of components must not be changed.
545  *
546  * To know more on format of the component information see
547  * \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
548  *  \param [in] info - a vector of component infos.
549  *  \throw If \a this->getNumberOfComponents() != \a info.size() && \a this->isAllocated()
550  */
551 void DataArray::setInfoAndChangeNbOfCompo(const std::vector<std::string>& info)
552 {
553   if(getNumberOfComponents()!=(int)info.size())
554     {
555       if(!isAllocated())
556         _info_on_compo=info;
557       else
558         {
559           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 !";
560           throw INTERP_KERNEL::Exception(oss.str().c_str());
561         }
562     }
563   else
564     _info_on_compo=info;
565 }
566
567 void DataArray::checkNbOfTuples(int nbOfTuples, const std::string& msg) const
568 {
569   if(getNumberOfTuples()!=nbOfTuples)
570     {
571       std::ostringstream oss; oss << msg << " : mismatch number of tuples : expected " <<  nbOfTuples << " having " << getNumberOfTuples() << " !";
572       throw INTERP_KERNEL::Exception(oss.str().c_str());
573     }
574 }
575
576 void DataArray::checkNbOfComps(int nbOfCompo, const std::string& msg) const
577 {
578   if(getNumberOfComponents()!=nbOfCompo)
579     {
580       std::ostringstream oss; oss << msg << " : mismatch number of components : expected " << nbOfCompo << " having " << getNumberOfComponents() << " !";
581       throw INTERP_KERNEL::Exception(oss.str().c_str());
582     }
583 }
584
585 void DataArray::checkNbOfElems(std::size_t nbOfElems, const std::string& msg) const
586 {
587   if(getNbOfElems()!=nbOfElems)
588     {
589       std::ostringstream oss; oss << msg << " : mismatch number of elems : Expected " << nbOfElems << " having " << getNbOfElems() << " !";
590       throw INTERP_KERNEL::Exception(oss.str().c_str());
591     }
592 }
593
594 void DataArray::checkNbOfTuplesAndComp(const DataArray& other, const std::string& msg) const
595 {
596   if(getNumberOfTuples()!=other.getNumberOfTuples())
597     {
598       std::ostringstream oss; oss << msg << " : mismatch number of tuples : expected " <<  other.getNumberOfTuples() << " having " << getNumberOfTuples() << " !";
599       throw INTERP_KERNEL::Exception(oss.str().c_str());
600     }
601   if(getNumberOfComponents()!=other.getNumberOfComponents())
602     {
603       std::ostringstream oss; oss << msg << " : mismatch number of components : expected " << other.getNumberOfComponents() << " having " << getNumberOfComponents() << " !";
604       throw INTERP_KERNEL::Exception(oss.str().c_str());
605     }
606 }
607
608 void DataArray::checkNbOfTuplesAndComp(int nbOfTuples, int nbOfCompo, const std::string& msg) const
609 {
610   checkNbOfTuples(nbOfTuples,msg);
611   checkNbOfComps(nbOfCompo,msg);
612 }
613
614 /*!
615  * Simply this method checks that \b value is in [0,\b ref).
616  */
617 void DataArray::CheckValueInRange(int ref, int value, const std::string& msg)
618 {
619   if(value<0 || value>=ref)
620     {
621       std::ostringstream oss; oss << "DataArray::CheckValueInRange : " << msg  << " ! Expected in range [0," << ref << "[ having " << value << " !";
622       throw INTERP_KERNEL::Exception(oss.str().c_str());
623     }
624 }
625
626 /*!
627  * This method checks that [\b start, \b end) is compliant with ref length \b value.
628  * typicaly start in [0,\b value) and end in [0,\b value). If value==start and start==end, it is supported.
629  */
630 void DataArray::CheckValueInRangeEx(int value, int start, int end, const std::string& msg)
631 {
632   if(start<0 || start>=value)
633     {
634       if(value!=start || end!=start)
635         {
636           std::ostringstream oss; oss << "DataArray::CheckValueInRangeEx : " << msg  << " ! Expected start " << start << " of input range, in [0," << value << "[ !";
637           throw INTERP_KERNEL::Exception(oss.str().c_str());
638         }
639     }
640   if(end<0 || end>value)
641     {
642       std::ostringstream oss; oss << "DataArray::CheckValueInRangeEx : " << msg  << " ! Expected end " << end << " of input range, in [0," << value << "] !";
643       throw INTERP_KERNEL::Exception(oss.str().c_str());
644     }
645 }
646
647 void DataArray::CheckClosingParInRange(int ref, int value, const std::string& msg)
648 {
649   if(value<0 || value>ref)
650     {
651       std::ostringstream oss; oss << "DataArray::CheckClosingParInRange : " << msg  << " ! Expected input range in [0," << ref << "] having closing open parenthesis " << value << " !";
652       throw INTERP_KERNEL::Exception(oss.str().c_str());
653     }
654 }
655
656 /*!
657  * 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, 
658  * typically it is a whole slice of tuples of DataArray or cells, nodes of a mesh...
659  *
660  * The input \a sliceId should be an id in [0, \a nbOfSlices) that specifies the slice of work.
661  *
662  * \param [in] start - the start of the input slice of the whole work to perform splitted into slices.
663  * \param [in] stop - the stop of the input slice of the whole work to perform splitted into slices.
664  * \param [in] step - the step (that can be <0) of the input slice of the whole work to perform splitted into slices.
665  * \param [in] sliceId - the slice id considered
666  * \param [in] nbOfSlices - the number of slices (typically the number of cores on which the work is expected to be sliced)
667  * \param [out] startSlice - the start of the slice considered
668  * \param [out] stopSlice - the stop of the slice consided
669  * 
670  * \throw If \a step == 0
671  * \throw If \a nbOfSlices not > 0
672  * \throw If \a sliceId not in [0,nbOfSlices)
673  */
674 void DataArray::GetSlice(int start, int stop, int step, int sliceId, int nbOfSlices, int& startSlice, int& stopSlice)
675 {
676   if(nbOfSlices<=0)
677     {
678       std::ostringstream oss; oss << "DataArray::GetSlice : nbOfSlices (" << nbOfSlices << ") must be > 0 !";
679       throw INTERP_KERNEL::Exception(oss.str().c_str());
680     }
681   if(sliceId<0 || sliceId>=nbOfSlices)
682     {
683       std::ostringstream oss; oss << "DataArray::GetSlice : sliceId (" << nbOfSlices << ") must be in [0 , nbOfSlices (" << nbOfSlices << ") ) !";
684       throw INTERP_KERNEL::Exception(oss.str().c_str());
685     }
686   int nbElems=GetNumberOfItemGivenBESRelative(start,stop,step,"DataArray::GetSlice");
687   int minNbOfElemsPerSlice=nbElems/nbOfSlices;
688   startSlice=start+minNbOfElemsPerSlice*step*sliceId;
689   if(sliceId<nbOfSlices-1)
690     stopSlice=start+minNbOfElemsPerSlice*step*(sliceId+1);
691   else
692     stopSlice=stop;
693 }
694
695 int DataArray::GetNumberOfItemGivenBES(int begin, int end, int step, const std::string& msg)
696 {
697   if(end<begin)
698     {
699       std::ostringstream oss; oss << msg << " : end before begin !";
700       throw INTERP_KERNEL::Exception(oss.str().c_str());
701     }
702   if(end==begin)
703     return 0;
704   if(step<=0)
705     {
706       std::ostringstream oss; oss << msg << " : invalid step should be > 0 !";
707       throw INTERP_KERNEL::Exception(oss.str().c_str());
708     }
709   return (end-1-begin)/step+1;
710 }
711
712 int DataArray::GetNumberOfItemGivenBESRelative(int begin, int end, int step, const std::string& msg)
713 {
714   if(step==0)
715     throw INTERP_KERNEL::Exception("DataArray::GetNumberOfItemGivenBES : step=0 is not allowed !");
716   if(end<begin && step>0)
717     {
718       std::ostringstream oss; oss << msg << " : end before begin whereas step is positive !";
719       throw INTERP_KERNEL::Exception(oss.str().c_str());
720     }
721   if(begin<end && step<0)
722     {
723       std::ostringstream oss; oss << msg << " : invalid step should be > 0 !";
724       throw INTERP_KERNEL::Exception(oss.str().c_str());
725     }
726   if(begin!=end)
727     return (std::max(begin,end)-1-std::min(begin,end))/std::abs(step)+1;
728   else
729     return 0;
730 }
731
732 int DataArray::GetPosOfItemGivenBESRelativeNoThrow(int value, int begin, int end, int step)
733 {
734   if(step!=0)
735     {
736       if(step>0)
737         {
738           if(begin<=value && value<end)
739             {
740               if((value-begin)%step==0)
741                 return (value-begin)/step;
742               else
743                 return -1;
744             }
745           else
746             return -1;
747         }
748       else
749         {
750           if(begin>=value && value>end)
751             {
752               if((begin-value)%(-step)==0)
753                 return (begin-value)/(-step);
754               else
755                 return -1;
756             }
757           else
758             return -1;
759         }
760     }
761   else
762     return -1;
763 }
764
765 /*!
766  * Returns a new instance of DataArrayDouble. The caller is to delete this array
767  * using decrRef() as it is no more needed. 
768  */
769 DataArrayDouble *DataArrayDouble::New()
770 {
771   return new DataArrayDouble;
772 }
773
774 /*!
775  * Returns the only one value in \a this, if and only if number of elements
776  * (nb of tuples * nb of components) is equal to 1, and that \a this is allocated.
777  *  \return double - the sole value stored in \a this array.
778  *  \throw If at least one of conditions stated above is not fulfilled.
779  */
780 double DataArrayDouble::doubleValue() const
781 {
782   if(isAllocated())
783     {
784       if(getNbOfElems()==1)
785         {
786           return *getConstPointer();
787         }
788       else
789         throw INTERP_KERNEL::Exception("DataArrayDouble::doubleValue : DataArrayDouble instance is allocated but number of elements is not equal to 1 !");
790     }
791   else
792     throw INTERP_KERNEL::Exception("DataArrayDouble::doubleValue : DataArrayDouble instance is not allocated !");
793 }
794
795 /*!
796  * Returns a full copy of \a this. For more info on copying data arrays see
797  * \ref MEDCouplingArrayBasicsCopyDeep.
798  *  \return DataArrayDouble * - a new instance of DataArrayDouble. The caller is to
799  *          delete this array using decrRef() as it is no more needed. 
800  */
801 DataArrayDouble *DataArrayDouble::deepCopy() const
802 {
803   return new DataArrayDouble(*this);
804 }
805
806 /*!
807  * Returns either a \a deep or \a shallow copy of this array. For more info see
808  * \ref MEDCouplingArrayBasicsCopyDeep and \ref MEDCouplingArrayBasicsCopyShallow.
809  *  \param [in] dCpy - if \a true, a deep copy is returned, else, a shallow one.
810  *  \return DataArrayDouble * - either a new instance of DataArrayDouble (if \a dCpy
811  *          == \a true) or \a this instance (if \a dCpy == \a false).
812  */
813 DataArrayDouble *DataArrayDouble::performCopyOrIncrRef(bool dCpy) const
814 {
815   if(dCpy)
816     return deepCopy();
817   else
818     {
819       incrRef();
820       return const_cast<DataArrayDouble *>(this);
821     }
822 }
823
824 /*!
825  * Assign zero to all values in \a this array. To know more on filling arrays see
826  * \ref MEDCouplingArrayFill.
827  * \throw If \a this is not allocated.
828  */
829 void DataArrayDouble::fillWithZero()
830 {
831   fillWithValue(0.);
832 }
833
834 /*!
835  * Checks that \a this array is consistently **increasing** or **decreasing** in value,
836  * with at least absolute difference value of |\a eps| at each step.
837  * If not an exception is thrown.
838  *  \param [in] increasing - if \a true, the array values should be increasing.
839  *  \param [in] eps - minimal absolute difference between the neighbor values at which 
840  *                    the values are considered different.
841  *  \throw If sequence of values is not strictly monotonic in agreement with \a
842  *         increasing arg.
843  *  \throw If \a this->getNumberOfComponents() != 1.
844  *  \throw If \a this is not allocated.
845  */
846 void DataArrayDouble::checkMonotonic(bool increasing, double eps) const
847 {
848   if(!isMonotonic(increasing,eps))
849     {
850       if (increasing)
851         throw INTERP_KERNEL::Exception("DataArrayDouble::checkMonotonic : 'this' is not INCREASING monotonic !");
852       else
853         throw INTERP_KERNEL::Exception("DataArrayDouble::checkMonotonic : 'this' is not DECREASING monotonic !");
854     }
855 }
856
857 /*!
858  * Checks that \a this array is consistently **increasing** or **decreasing** in value,
859  * with at least absolute difference value of |\a eps| at each step.
860  *  \param [in] increasing - if \a true, array values should be increasing.
861  *  \param [in] eps - minimal absolute difference between the neighbor values at which 
862  *                    the values are considered different.
863  *  \return bool - \a true if values change in accordance with \a increasing arg.
864  *  \throw If \a this->getNumberOfComponents() != 1.
865  *  \throw If \a this is not allocated.
866  */
867 bool DataArrayDouble::isMonotonic(bool increasing, double eps) const
868 {
869   checkAllocated();
870   if(getNumberOfComponents()!=1)
871     throw INTERP_KERNEL::Exception("DataArrayDouble::isMonotonic : only supported with 'this' array with ONE component !");
872   int nbOfElements=getNumberOfTuples();
873   const double *ptr=getConstPointer();
874   if(nbOfElements==0)
875     return true;
876   double ref=ptr[0];
877   double absEps=fabs(eps);
878   if(increasing)
879     {
880       for(int i=1;i<nbOfElements;i++)
881         {
882           if(ptr[i]<(ref+absEps))
883             return false;
884           ref=ptr[i];
885         }
886       return true;
887     }
888   else
889     {
890       for(int i=1;i<nbOfElements;i++)
891         {
892           if(ptr[i]>(ref-absEps))
893             return false;
894           ref=ptr[i];
895         }
896       return true;
897     }
898 }
899
900 /*!
901  * Returns a textual and human readable representation of \a this instance of
902  * DataArrayDouble. This text is shown when a DataArrayDouble is printed in Python.
903  * \return std::string - text describing \a this DataArrayDouble.
904  *
905  * \sa reprNotTooLong, reprZip
906  */
907 std::string DataArrayDouble::repr() const
908 {
909   std::ostringstream ret;
910   reprStream(ret);
911   return ret.str();
912 }
913
914 std::string DataArrayDouble::reprZip() const
915 {
916   std::ostringstream ret;
917   reprZipStream(ret);
918   return ret.str();
919 }
920
921 /*!
922  * This method is close to repr method except that when \a this has more than 1000 tuples, all tuples are not
923  * printed out to avoid to consume too much space in interpretor.
924  * \sa repr
925  */
926 std::string DataArrayDouble::reprNotTooLong() const
927 {
928   std::ostringstream ret;
929   reprNotTooLongStream(ret);
930   return ret.str();
931 }
932
933 void DataArrayDouble::writeVTK(std::ostream& ofs, int indent, const std::string& nameInFile, DataArrayByte *byteArr) const
934 {
935   static const char SPACE[4]={' ',' ',' ',' '};
936   checkAllocated();
937   std::string idt(indent,' ');
938   ofs.precision(17);
939   ofs << idt << "<DataArray type=\"Float32\" Name=\"" << nameInFile << "\" NumberOfComponents=\"" << getNumberOfComponents() << "\"";
940   //
941   bool areAllEmpty(true);
942   for(std::vector<std::string>::const_iterator it=_info_on_compo.begin();it!=_info_on_compo.end();it++)
943     if(!(*it).empty())
944       areAllEmpty=false;
945   if(!areAllEmpty)
946     for(std::size_t i=0;i<_info_on_compo.size();i++)
947       ofs << " ComponentName" << i << "=\"" << _info_on_compo[i] << "\"";
948   //
949   if(byteArr)
950     {
951       ofs << " format=\"appended\" offset=\"" << byteArr->getNumberOfTuples() << "\">";
952       INTERP_KERNEL::AutoPtr<float> tmp(new float[getNbOfElems()]);
953       float *pt(tmp);
954       // to make Visual C++ happy : instead of std::copy(begin(),end(),(float *)tmp);
955       for(const double *src=begin();src!=end();src++,pt++)
956         *pt=float(*src);
957       const char *data(reinterpret_cast<const char *>((float *)tmp));
958       std::size_t sz(getNbOfElems()*sizeof(float));
959       byteArr->insertAtTheEnd(data,data+sz);
960       byteArr->insertAtTheEnd(SPACE,SPACE+4);
961     }
962   else
963     {
964       ofs << " RangeMin=\"" << getMinValueInArray() << "\" RangeMax=\"" << getMaxValueInArray() << "\" format=\"ascii\">\n" << idt;
965       std::copy(begin(),end(),std::ostream_iterator<double>(ofs," "));
966     }
967   ofs << std::endl << idt << "</DataArray>\n";
968 }
969
970 void DataArrayDouble::reprStream(std::ostream& stream) const
971 {
972   stream << "Name of double array : \"" << _name << "\"\n";
973   reprWithoutNameStream(stream);
974 }
975
976 void DataArrayDouble::reprZipStream(std::ostream& stream) const
977 {
978   stream << "Name of double array : \"" << _name << "\"\n";
979   reprZipWithoutNameStream(stream);
980 }
981
982 void DataArrayDouble::reprNotTooLongStream(std::ostream& stream) const
983 {
984   stream << "Name of double array : \"" << _name << "\"\n";
985   reprNotTooLongWithoutNameStream(stream);
986 }
987
988 void DataArrayDouble::reprWithoutNameStream(std::ostream& stream) const
989 {
990   DataArray::reprWithoutNameStream(stream);
991   stream.precision(17);
992   _mem.repr(getNumberOfComponents(),stream);
993 }
994
995 void DataArrayDouble::reprZipWithoutNameStream(std::ostream& stream) const
996 {
997   DataArray::reprWithoutNameStream(stream);
998   stream.precision(17);
999   _mem.reprZip(getNumberOfComponents(),stream);
1000 }
1001
1002 void DataArrayDouble::reprNotTooLongWithoutNameStream(std::ostream& stream) const
1003 {
1004   DataArray::reprWithoutNameStream(stream);
1005   stream.precision(17);
1006   _mem.reprNotTooLong(getNumberOfComponents(),stream);
1007 }
1008
1009 void DataArrayDouble::reprCppStream(const std::string& varName, std::ostream& stream) const
1010 {
1011   int nbTuples(getNumberOfTuples()),nbComp(getNumberOfComponents());
1012   const double *data(getConstPointer());
1013   stream.precision(17);
1014   stream << "DataArrayDouble *" << varName << "=DataArrayDouble::New();" << std::endl;
1015   if(nbTuples*nbComp>=1)
1016     {
1017       stream << "const double " << varName << "Data[" << nbTuples*nbComp << "]={";
1018       std::copy(data,data+nbTuples*nbComp-1,std::ostream_iterator<double>(stream,","));
1019       stream << data[nbTuples*nbComp-1] << "};" << std::endl;
1020       stream << varName << "->useArray(" << varName << "Data,false,CPP_DEALLOC," << nbTuples << "," << nbComp << ");" << std::endl;
1021     }
1022   else
1023     stream << varName << "->alloc(" << nbTuples << "," << nbComp << ");" << std::endl;
1024   stream << varName << "->setName(\"" << getName() << "\");" << std::endl;
1025 }
1026
1027 /*!
1028  * Method that gives a quick overvien of \a this for python.
1029  */
1030 void DataArrayDouble::reprQuickOverview(std::ostream& stream) const
1031 {
1032   static const std::size_t MAX_NB_OF_BYTE_IN_REPR=300;
1033   stream << "DataArrayDouble C++ instance at " << this << ". ";
1034   if(isAllocated())
1035     {
1036       int nbOfCompo=(int)_info_on_compo.size();
1037       if(nbOfCompo>=1)
1038         {
1039           int nbOfTuples=getNumberOfTuples();
1040           stream << "Number of tuples : " << nbOfTuples << ". Number of components : " << nbOfCompo << "." << std::endl;
1041           reprQuickOverviewData(stream,MAX_NB_OF_BYTE_IN_REPR);
1042         }
1043       else
1044         stream << "Number of components : 0.";
1045     }
1046   else
1047     stream << "*** No data allocated ****";
1048 }
1049
1050 void DataArrayDouble::reprQuickOverviewData(std::ostream& stream, std::size_t maxNbOfByteInRepr) const
1051 {
1052   const double *data=begin();
1053   int nbOfTuples=getNumberOfTuples();
1054   int nbOfCompo=(int)_info_on_compo.size();
1055   std::ostringstream oss2; oss2 << "[";
1056   oss2.precision(17);
1057   std::string oss2Str(oss2.str());
1058   bool isFinished=true;
1059   for(int i=0;i<nbOfTuples && isFinished;i++)
1060     {
1061       if(nbOfCompo>1)
1062         {
1063           oss2 << "(";
1064           for(int j=0;j<nbOfCompo;j++,data++)
1065             {
1066               oss2 << *data;
1067               if(j!=nbOfCompo-1) oss2 << ", ";
1068             }
1069           oss2 << ")";
1070         }
1071       else
1072         oss2 << *data++;
1073       if(i!=nbOfTuples-1) oss2 << ", ";
1074       std::string oss3Str(oss2.str());
1075       if(oss3Str.length()<maxNbOfByteInRepr)
1076         oss2Str=oss3Str;
1077       else
1078         isFinished=false;
1079     }
1080   stream << oss2Str;
1081   if(!isFinished)
1082     stream << "... ";
1083   stream << "]";
1084 }
1085
1086 /*!
1087  * Equivalent to DataArrayDouble::isEqual except that if false the reason of
1088  * mismatch is given.
1089  * 
1090  * \param [in] other the instance to be compared with \a this
1091  * \param [in] prec the precision to compare numeric data of the arrays.
1092  * \param [out] reason In case of inequality returns the reason.
1093  * \sa DataArrayDouble::isEqual
1094  */
1095 bool DataArrayDouble::isEqualIfNotWhy(const DataArrayDouble& other, double prec, std::string& reason) const
1096 {
1097   if(!areInfoEqualsIfNotWhy(other,reason))
1098     return false;
1099   return _mem.isEqual(other._mem,prec,reason);
1100 }
1101
1102 /*!
1103  * Checks if \a this and another DataArrayDouble are fully equal. For more info see
1104  * \ref MEDCouplingArrayBasicsCompare.
1105  *  \param [in] other - an instance of DataArrayDouble to compare with \a this one.
1106  *  \param [in] prec - precision value to compare numeric data of the arrays.
1107  *  \return bool - \a true if the two arrays are equal, \a false else.
1108  */
1109 bool DataArrayDouble::isEqual(const DataArrayDouble& other, double prec) const
1110 {
1111   std::string tmp;
1112   return isEqualIfNotWhy(other,prec,tmp);
1113 }
1114
1115 /*!
1116  * Checks if values of \a this and another DataArrayDouble are equal. For more info see
1117  * \ref MEDCouplingArrayBasicsCompare.
1118  *  \param [in] other - an instance of DataArrayDouble to compare with \a this one.
1119  *  \param [in] prec - precision value to compare numeric data of the arrays.
1120  *  \return bool - \a true if the values of two arrays are equal, \a false else.
1121  */
1122 bool DataArrayDouble::isEqualWithoutConsideringStr(const DataArrayDouble& other, double prec) const
1123 {
1124   std::string tmp;
1125   return _mem.isEqual(other._mem,prec,tmp);
1126 }
1127
1128 /*!
1129  * Creates a new DataArrayInt and assigns all (textual and numerical) data of \a this
1130  * array to the new one.
1131  *  \return DataArrayInt * - the new instance of DataArrayInt.
1132  */
1133 DataArrayInt *DataArrayDouble::convertToIntArr() const
1134 {
1135   DataArrayInt *ret=DataArrayInt::New();
1136   ret->alloc(getNumberOfTuples(),getNumberOfComponents());
1137   int *dest=ret->getPointer();
1138   // to make Visual C++ happy : instead of std::size_t nbOfVals=getNbOfElems(); std::copy(src,src+nbOfVals,dest);
1139   for(const double *src=begin();src!=end();src++,dest++)
1140     *dest=(int)*src;
1141   ret->copyStringInfoFrom(*this);
1142   return ret;
1143 }
1144
1145 /*!
1146  * Returns a new DataArrayDouble holding the same values as \a this array but differently
1147  * arranged in memory. If \a this array holds 2 components of 3 values:
1148  * \f$ x_0,x_1,x_2,y_0,y_1,y_2 \f$, then the result array holds these values arranged
1149  * as follows: \f$ x_0,y_0,x_1,y_1,x_2,y_2 \f$.
1150  *  \warning Do not confuse this method with transpose()!
1151  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1152  *          is to delete using decrRef() as it is no more needed.
1153  *  \throw If \a this is not allocated.
1154  */
1155 DataArrayDouble *DataArrayDouble::fromNoInterlace() const
1156 {
1157   if(_mem.isNull())
1158     throw INTERP_KERNEL::Exception("DataArrayDouble::fromNoInterlace : Not defined array !");
1159   double *tab=_mem.fromNoInterlace(getNumberOfComponents());
1160   DataArrayDouble *ret=DataArrayDouble::New();
1161   ret->useArray(tab,true,C_DEALLOC,getNumberOfTuples(),getNumberOfComponents());
1162   return ret;
1163 }
1164
1165 /*!
1166  * Returns a new DataArrayDouble holding the same values as \a this array but differently
1167  * arranged in memory. If \a this array holds 2 components of 3 values:
1168  * \f$ x_0,y_0,x_1,y_1,x_2,y_2 \f$, then the result array holds these values arranged
1169  * as follows: \f$ x_0,x_1,x_2,y_0,y_1,y_2 \f$.
1170  *  \warning Do not confuse this method with transpose()!
1171  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1172  *          is to delete using decrRef() as it is no more needed.
1173  *  \throw If \a this is not allocated.
1174  */
1175 DataArrayDouble *DataArrayDouble::toNoInterlace() const
1176 {
1177   if(_mem.isNull())
1178     throw INTERP_KERNEL::Exception("DataArrayDouble::toNoInterlace : Not defined array !");
1179   double *tab=_mem.toNoInterlace(getNumberOfComponents());
1180   DataArrayDouble *ret=DataArrayDouble::New();
1181   ret->useArray(tab,true,C_DEALLOC,getNumberOfTuples(),getNumberOfComponents());
1182   return ret;
1183 }
1184
1185 /*!
1186  * Appends components of another array to components of \a this one, tuple by tuple.
1187  * So that the number of tuples of \a this array remains the same and the number of 
1188  * components increases.
1189  *  \param [in] other - the DataArrayDouble to append to \a this one.
1190  *  \throw If \a this is not allocated.
1191  *  \throw If \a this and \a other arrays have different number of tuples.
1192  *
1193  *  \if ENABLE_EXAMPLES
1194  *  \ref cpp_mcdataarraydouble_meldwith "Here is a C++ example".
1195  *
1196  *  \ref py_mcdataarraydouble_meldwith "Here is a Python example".
1197  *  \endif
1198  */
1199 void DataArrayDouble::meldWith(const DataArrayDouble *other)
1200 {
1201   checkAllocated();
1202   other->checkAllocated();
1203   int nbOfTuples=getNumberOfTuples();
1204   if(nbOfTuples!=other->getNumberOfTuples())
1205     throw INTERP_KERNEL::Exception("DataArrayDouble::meldWith : mismatch of number of tuples !");
1206   int nbOfComp1=getNumberOfComponents();
1207   int nbOfComp2=other->getNumberOfComponents();
1208   double *newArr=(double *)malloc((nbOfTuples*(nbOfComp1+nbOfComp2))*sizeof(double));
1209   double *w=newArr;
1210   const double *inp1=getConstPointer();
1211   const double *inp2=other->getConstPointer();
1212   for(int i=0;i<nbOfTuples;i++,inp1+=nbOfComp1,inp2+=nbOfComp2)
1213     {
1214       w=std::copy(inp1,inp1+nbOfComp1,w);
1215       w=std::copy(inp2,inp2+nbOfComp2,w);
1216     }
1217   useArray(newArr,true,C_DEALLOC,nbOfTuples,nbOfComp1+nbOfComp2);
1218   std::vector<int> compIds(nbOfComp2);
1219   for(int i=0;i<nbOfComp2;i++)
1220     compIds[i]=nbOfComp1+i;
1221   copyPartOfStringInfoFrom2(compIds,*other);
1222 }
1223
1224 /*!
1225  * This method checks that all tuples in \a other are in \a this.
1226  * If true, the output param \a tupleIds contains the tuples ids of \a this that correspond to tupes in \a this.
1227  * 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.
1228  *
1229  * \param [in] other - the array having the same number of components than \a this.
1230  * \param [out] tupleIds - the tuple ids containing the same number of tuples than \a other has.
1231  * \sa DataArrayDouble::findCommonTuples
1232  */
1233 bool DataArrayDouble::areIncludedInMe(const DataArrayDouble *other, double prec, DataArrayInt *&tupleIds) const
1234 {
1235   if(!other)
1236     throw INTERP_KERNEL::Exception("DataArrayDouble::areIncludedInMe : input array is NULL !");
1237   checkAllocated(); other->checkAllocated();
1238   if(getNumberOfComponents()!=other->getNumberOfComponents())
1239     throw INTERP_KERNEL::Exception("DataArrayDouble::areIncludedInMe : the number of components does not match !");
1240   MCAuto<DataArrayDouble> a=DataArrayDouble::Aggregate(this,other);
1241   DataArrayInt *c=0,*ci=0;
1242   a->findCommonTuples(prec,getNumberOfTuples(),c,ci);
1243   MCAuto<DataArrayInt> cSafe(c),ciSafe(ci);
1244   int newNbOfTuples=-1;
1245   MCAuto<DataArrayInt> ids=DataArrayInt::ConvertIndexArrayToO2N(a->getNumberOfTuples(),c->begin(),ci->begin(),ci->end(),newNbOfTuples);
1246   MCAuto<DataArrayInt> ret1=ids->selectByTupleIdSafeSlice(getNumberOfTuples(),a->getNumberOfTuples(),1);
1247   tupleIds=ret1.retn();
1248   return newNbOfTuples==getNumberOfTuples();
1249 }
1250
1251 /*!
1252  * Searches for tuples coincident within \a prec tolerance. Each tuple is considered
1253  * as coordinates of a point in getNumberOfComponents()-dimensional space. The
1254  * distance separating two points is computed with the infinite norm.
1255  *
1256  * Indices of coincident tuples are stored in output arrays.
1257  * A pair of arrays (\a comm, \a commIndex) is called "Surjective Format 2".
1258  *
1259  * This method is typically used by MEDCouplingPointSet::findCommonNodes() and
1260  * MEDCouplingUMesh::mergeNodes().
1261  *  \param [in] prec - minimal absolute distance between two tuples (infinite norm) at which they are
1262  *              considered not coincident.
1263  *  \param [in] limitTupleId - limit tuple id. If all tuples within a group of coincident
1264  *              tuples have id strictly lower than \a limitTupleId then they are not returned.
1265  *  \param [out] comm - the array holding ids (== indices) of coincident tuples. 
1266  *               \a comm->getNumberOfComponents() == 1. 
1267  *               \a comm->getNumberOfTuples() == \a commIndex->back().
1268  *  \param [out] commIndex - the array dividing all indices stored in \a comm into
1269  *               groups of (indices of) coincident tuples. Its every value is a tuple
1270  *               index where a next group of tuples begins. For example the second
1271  *               group of tuples in \a comm is described by following range of indices:
1272  *               [ \a commIndex[1], \a commIndex[2] ). \a commIndex->getNumberOfTuples()-1
1273  *               gives the number of groups of coincident tuples.
1274  *  \throw If \a this is not allocated.
1275  *  \throw If the number of components is not in [1,2,3,4].
1276  *
1277  *  \if ENABLE_EXAMPLES
1278  *  \ref cpp_mcdataarraydouble_findcommontuples "Here is a C++ example".
1279  *
1280  *  \ref py_mcdataarraydouble_findcommontuples  "Here is a Python example".
1281  *  \endif
1282  *  \sa DataArrayInt::ConvertIndexArrayToO2N(), DataArrayDouble::areIncludedInMe
1283  */
1284 void DataArrayDouble::findCommonTuples(double prec, int limitTupleId, DataArrayInt *&comm, DataArrayInt *&commIndex) const
1285 {
1286   checkAllocated();
1287   int nbOfCompo=getNumberOfComponents();
1288   if ((nbOfCompo<1) || (nbOfCompo>4)) //test before work
1289     throw INTERP_KERNEL::Exception("DataArrayDouble::findCommonTuples : Unexpected spacedim of coords. Must be 1, 2, 3 or 4.");
1290
1291   int nbOfTuples=getNumberOfTuples();
1292   //
1293   MCAuto<DataArrayInt> c(DataArrayInt::New()),cI(DataArrayInt::New()); c->alloc(0,1); cI->pushBackSilent(0);
1294   switch(nbOfCompo)
1295   {
1296     case 4:
1297       findCommonTuplesAlg<4>(begin(),nbOfTuples,limitTupleId,prec,c,cI);
1298       break;
1299     case 3:
1300       findCommonTuplesAlg<3>(begin(),nbOfTuples,limitTupleId,prec,c,cI);
1301       break;
1302     case 2:
1303       findCommonTuplesAlg<2>(begin(),nbOfTuples,limitTupleId,prec,c,cI);
1304       break;
1305     case 1:
1306       findCommonTuplesAlg<1>(begin(),nbOfTuples,limitTupleId,prec,c,cI);
1307       break;
1308     default:
1309       throw INTERP_KERNEL::Exception("DataArrayDouble::findCommonTuples : nb of components managed are 1,2,3 and 4 ! not implemented for other number of components !");
1310   }
1311   comm=c.retn();
1312   commIndex=cI.retn();
1313 }
1314
1315 /*!
1316  * 
1317  * \param [in] nbTimes specifies the nb of times each tuples in \a this will be duplicated contiguouly in returned DataArrayDouble instance.
1318  *             \a nbTimes  should be at least equal to 1.
1319  * \return a newly allocated DataArrayDouble having one component and number of tuples equal to \a nbTimes * \c this->getNumberOfTuples.
1320  * \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.
1321  */
1322 DataArrayDouble *DataArrayDouble::duplicateEachTupleNTimes(int nbTimes) const
1323 {
1324   checkAllocated();
1325   if(getNumberOfComponents()!=1)
1326     throw INTERP_KERNEL::Exception("DataArrayDouble::duplicateEachTupleNTimes : this should have only one component !");
1327   if(nbTimes<1)
1328     throw INTERP_KERNEL::Exception("DataArrayDouble::duplicateEachTupleNTimes : nb times should be >= 1 !");
1329   int nbTuples=getNumberOfTuples();
1330   const double *inPtr=getConstPointer();
1331   MCAuto<DataArrayDouble> ret=DataArrayDouble::New(); ret->alloc(nbTimes*nbTuples,1);
1332   double *retPtr=ret->getPointer();
1333   for(int i=0;i<nbTuples;i++,inPtr++)
1334     {
1335       double val=*inPtr;
1336       for(int j=0;j<nbTimes;j++,retPtr++)
1337         *retPtr=val;
1338     }
1339   ret->copyStringInfoFrom(*this);
1340   return ret.retn();
1341 }
1342
1343 /*!
1344  * This methods returns the minimal distance between the two set of points \a this and \a other.
1345  * So \a this and \a other have to have the same number of components. If not an INTERP_KERNEL::Exception will be thrown.
1346  * This method works only if number of components of \a this (equal to those of \a other) is in 1, 2 or 3.
1347  *
1348  * \param [out] thisTupleId the tuple id in \a this corresponding to the returned minimal distance
1349  * \param [out] otherTupleId the tuple id in \a other corresponding to the returned minimal distance
1350  * \return the minimal distance between the two set of points \a this and \a other.
1351  * \sa DataArrayDouble::findClosestTupleId
1352  */
1353 double DataArrayDouble::minimalDistanceTo(const DataArrayDouble *other, int& thisTupleId, int& otherTupleId) const
1354 {
1355   MCAuto<DataArrayInt> part1=findClosestTupleId(other);
1356   int nbOfCompo(getNumberOfComponents());
1357   int otherNbTuples(other->getNumberOfTuples());
1358   const double *thisPt(begin()),*otherPt(other->begin());
1359   const int *part1Pt(part1->begin());
1360   double ret=std::numeric_limits<double>::max();
1361   for(int i=0;i<otherNbTuples;i++,part1Pt++,otherPt+=nbOfCompo)
1362     {
1363       double tmp(0.);
1364       for(int j=0;j<nbOfCompo;j++)
1365         tmp+=(otherPt[j]-thisPt[nbOfCompo*(*part1Pt)+j])*(otherPt[j]-thisPt[nbOfCompo*(*part1Pt)+j]);
1366       if(tmp<ret)
1367         { ret=tmp; thisTupleId=*part1Pt; otherTupleId=i; }
1368     }
1369   return sqrt(ret);
1370 }
1371
1372 /*!
1373  * This methods returns for each tuple in \a other which tuple in \a this is the closest.
1374  * So \a this and \a other have to have the same number of components. If not an INTERP_KERNEL::Exception will be thrown.
1375  * This method works only if number of components of \a this (equal to those of \a other) is in 1, 2 or 3.
1376  *
1377  * \return a newly allocated (new object to be dealt by the caller) DataArrayInt having \c other->getNumberOfTuples() tuples and one components.
1378  * \sa DataArrayDouble::minimalDistanceTo
1379  */
1380 DataArrayInt *DataArrayDouble::findClosestTupleId(const DataArrayDouble *other) const
1381 {
1382   if(!other)
1383     throw INTERP_KERNEL::Exception("DataArrayDouble::findClosestTupleId : other instance is NULL !");
1384   checkAllocated(); other->checkAllocated();
1385   int nbOfCompo=getNumberOfComponents();
1386   if(nbOfCompo!=other->getNumberOfComponents())
1387     {
1388       std::ostringstream oss; oss << "DataArrayDouble::findClosestTupleId : number of components in this is " << nbOfCompo;
1389       oss << ", whereas number of components in other is " << other->getNumberOfComponents() << "! Should be equal !";
1390       throw INTERP_KERNEL::Exception(oss.str().c_str());
1391     }
1392   int nbOfTuples=other->getNumberOfTuples();
1393   int thisNbOfTuples=getNumberOfTuples();
1394   MCAuto<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbOfTuples,1);
1395   double bounds[6];
1396   getMinMaxPerComponent(bounds);
1397   switch(nbOfCompo)
1398   {
1399     case 3:
1400       {
1401         double xDelta(fabs(bounds[1]-bounds[0])),yDelta(fabs(bounds[3]-bounds[2])),zDelta(fabs(bounds[5]-bounds[4]));
1402         double delta=std::max(xDelta,yDelta); delta=std::max(delta,zDelta);
1403         double characSize=pow((delta*delta*delta)/((double)thisNbOfTuples),1./3.);
1404         BBTreePts<3,int> myTree(begin(),0,0,getNumberOfTuples(),characSize*1e-12);
1405         FindClosestTupleIdAlg<3>(myTree,3.*characSize*characSize,other->begin(),nbOfTuples,begin(),thisNbOfTuples,ret->getPointer());
1406         break;
1407       }
1408     case 2:
1409       {
1410         double xDelta(fabs(bounds[1]-bounds[0])),yDelta(fabs(bounds[3]-bounds[2]));
1411         double delta=std::max(xDelta,yDelta);
1412         double characSize=sqrt(delta/(double)thisNbOfTuples);
1413         BBTreePts<2,int> myTree(begin(),0,0,getNumberOfTuples(),characSize*1e-12);
1414         FindClosestTupleIdAlg<2>(myTree,2.*characSize*characSize,other->begin(),nbOfTuples,begin(),thisNbOfTuples,ret->getPointer());
1415         break;
1416       }
1417     case 1:
1418       {
1419         double characSize=fabs(bounds[1]-bounds[0])/thisNbOfTuples;
1420         BBTreePts<1,int> myTree(begin(),0,0,getNumberOfTuples(),characSize*1e-12);
1421         FindClosestTupleIdAlg<1>(myTree,1.*characSize*characSize,other->begin(),nbOfTuples,begin(),thisNbOfTuples,ret->getPointer());
1422         break;
1423       }
1424     default:
1425       throw INTERP_KERNEL::Exception("Unexpected spacedim of coords for findClosestTupleId. Must be 1, 2 or 3.");
1426   }
1427   return ret.retn();
1428 }
1429
1430 /*!
1431  * This method expects that \a this and \a otherBBoxFrmt arrays are bounding box arrays ( as the output of MEDCouplingPointSet::getBoundingBoxForBBTree method ).
1432  * 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
1433  * how many bounding boxes in \a otherBBoxFrmt.
1434  * So, this method expects that \a this and \a otherBBoxFrmt have the same number of components.
1435  *
1436  * \param [in] otherBBoxFrmt - It is an array .
1437  * \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.
1438  * \sa MEDCouplingPointSet::getBoundingBoxForBBTree
1439  * \throw If \a this and \a otherBBoxFrmt have not the same number of components.
1440  * \throw If \a this and \a otherBBoxFrmt number of components is not even (BBox format).
1441  */
1442 DataArrayInt *DataArrayDouble::computeNbOfInteractionsWith(const DataArrayDouble *otherBBoxFrmt, double eps) const
1443 {
1444   if(!otherBBoxFrmt)
1445     throw INTERP_KERNEL::Exception("DataArrayDouble::computeNbOfInteractionsWith : input array is NULL !");
1446   if(!isAllocated() || !otherBBoxFrmt->isAllocated())
1447     throw INTERP_KERNEL::Exception("DataArrayDouble::computeNbOfInteractionsWith : this and input array must be allocated !");
1448   int nbOfComp(getNumberOfComponents()),nbOfTuples(getNumberOfTuples());
1449   if(nbOfComp!=otherBBoxFrmt->getNumberOfComponents())
1450     {
1451       std::ostringstream oss; oss << "DataArrayDouble::computeNbOfInteractionsWith : this number of components (" << nbOfComp << ") must be equal to the number of components of input array (" << otherBBoxFrmt->getNumberOfComponents() << ") !";
1452       throw INTERP_KERNEL::Exception(oss.str().c_str());
1453     }
1454   if(nbOfComp%2!=0)
1455     {
1456       std::ostringstream oss; oss << "DataArrayDouble::computeNbOfInteractionsWith : Number of components (" << nbOfComp << ") is not even ! It should be to be compatible with bbox format !";
1457       throw INTERP_KERNEL::Exception(oss.str().c_str());
1458     }
1459   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(nbOfTuples,1);
1460   const double *thisBBPtr(begin());
1461   int *retPtr(ret->getPointer());
1462   switch(nbOfComp/2)
1463   {
1464     case 3:
1465       {
1466         BBTree<3,int> bbt(otherBBoxFrmt->begin(),0,0,otherBBoxFrmt->getNumberOfTuples(),eps);
1467         for(int i=0;i<nbOfTuples;i++,retPtr++,thisBBPtr+=nbOfComp)
1468           *retPtr=bbt.getNbOfIntersectingElems(thisBBPtr);
1469         break;
1470       }
1471     case 2:
1472       {
1473         BBTree<2,int> bbt(otherBBoxFrmt->begin(),0,0,otherBBoxFrmt->getNumberOfTuples(),eps);
1474         for(int i=0;i<nbOfTuples;i++,retPtr++,thisBBPtr+=nbOfComp)
1475           *retPtr=bbt.getNbOfIntersectingElems(thisBBPtr);
1476         break;
1477       }
1478     case 1:
1479       {
1480         BBTree<1,int> bbt(otherBBoxFrmt->begin(),0,0,otherBBoxFrmt->getNumberOfTuples(),eps);
1481         for(int i=0;i<nbOfTuples;i++,retPtr++,thisBBPtr+=nbOfComp)
1482           *retPtr=bbt.getNbOfIntersectingElems(thisBBPtr);
1483         break;
1484       }
1485     default:
1486       throw INTERP_KERNEL::Exception("DataArrayDouble::computeNbOfInteractionsWith : space dimension supported are [1,2,3] !");
1487   }
1488
1489   return ret.retn();
1490 }
1491
1492 /*!
1493  * Returns a copy of \a this array by excluding coincident tuples. Each tuple is
1494  * considered as coordinates of a point in getNumberOfComponents()-dimensional
1495  * space. The distance between tuples is computed using norm2. If several tuples are
1496  * not far each from other than \a prec, only one of them remains in the result
1497  * array. The order of tuples in the result array is same as in \a this one except
1498  * that coincident tuples are excluded.
1499  *  \param [in] prec - minimal absolute distance between two tuples at which they are
1500  *              considered not coincident.
1501  *  \param [in] limitTupleId - limit tuple id. If all tuples within a group of coincident
1502  *              tuples have id strictly lower than \a limitTupleId then they are not excluded.
1503  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1504  *          is to delete using decrRef() as it is no more needed.
1505  *  \throw If \a this is not allocated.
1506  *  \throw If the number of components is not in [1,2,3,4].
1507  *
1508  *  \if ENABLE_EXAMPLES
1509  *  \ref py_mcdataarraydouble_getdifferentvalues "Here is a Python example".
1510  *  \endif
1511  */
1512 DataArrayDouble *DataArrayDouble::getDifferentValues(double prec, int limitTupleId) const
1513 {
1514   checkAllocated();
1515   DataArrayInt *c0=0,*cI0=0;
1516   findCommonTuples(prec,limitTupleId,c0,cI0);
1517   MCAuto<DataArrayInt> c(c0),cI(cI0);
1518   int newNbOfTuples=-1;
1519   MCAuto<DataArrayInt> o2n=DataArrayInt::ConvertIndexArrayToO2N(getNumberOfTuples(),c0->begin(),cI0->begin(),cI0->end(),newNbOfTuples);
1520   return renumberAndReduce(o2n->getConstPointer(),newNbOfTuples);
1521 }
1522
1523 /*!
1524  * Copy all components in a specified order from another DataArrayDouble.
1525  * Both numerical and textual data is copied. The number of tuples in \a this and
1526  * the other array can be different.
1527  *  \param [in] a - the array to copy data from.
1528  *  \param [in] compoIds - sequence of zero based indices of components, data of which is
1529  *              to be copied.
1530  *  \throw If \a a is NULL.
1531  *  \throw If \a compoIds.size() != \a a->getNumberOfComponents().
1532  *  \throw If \a compoIds[i] < 0 or \a compoIds[i] > \a this->getNumberOfComponents().
1533  *
1534  *  \if ENABLE_EXAMPLES
1535  *  \ref py_mcdataarraydouble_setselectedcomponents "Here is a Python example".
1536  *  \endif
1537  */
1538 void DataArrayDouble::setSelectedComponents(const DataArrayDouble *a, const std::vector<int>& compoIds)
1539 {
1540   if(!a)
1541     throw INTERP_KERNEL::Exception("DataArrayDouble::setSelectedComponents : input DataArrayDouble is NULL !");
1542   checkAllocated();
1543   copyPartOfStringInfoFrom2(compoIds,*a);
1544   std::size_t partOfCompoSz=compoIds.size();
1545   int nbOfCompo=getNumberOfComponents();
1546   int nbOfTuples=std::min(getNumberOfTuples(),a->getNumberOfTuples());
1547   const double *ac=a->getConstPointer();
1548   double *nc=getPointer();
1549   for(int i=0;i<nbOfTuples;i++)
1550     for(std::size_t j=0;j<partOfCompoSz;j++,ac++)
1551       nc[nbOfCompo*i+compoIds[j]]=*ac;
1552 }
1553
1554 void DataArrayDouble::SetArrayIn(DataArrayDouble *newArray, DataArrayDouble* &arrayToSet)
1555 {
1556   if(newArray!=arrayToSet)
1557     {
1558       if(arrayToSet)
1559         arrayToSet->decrRef();
1560       arrayToSet=newArray;
1561       if(arrayToSet)
1562         arrayToSet->incrRef();
1563     }
1564 }
1565
1566 void DataArrayDouble::aggregate(const DataArrayDouble *other)
1567 {
1568   if(!other)
1569     throw INTERP_KERNEL::Exception("DataArrayDouble::aggregate : null pointer !");
1570   if(getNumberOfComponents()!=other->getNumberOfComponents())
1571     throw INTERP_KERNEL::Exception("DataArrayDouble::aggregate : mismatch number of components !");
1572   _mem.insertAtTheEnd(other->begin(),other->end());
1573 }
1574
1575 /*!
1576  * Checks if 0.0 value is present in \a this array. If it is the case, an exception
1577  * is thrown.
1578  * \throw If zero is found in \a this array.
1579  */
1580 void DataArrayDouble::checkNoNullValues() const
1581 {
1582   const double *tmp=getConstPointer();
1583   std::size_t nbOfElems=getNbOfElems();
1584   const double *where=std::find(tmp,tmp+nbOfElems,0.);
1585   if(where!=tmp+nbOfElems)
1586     throw INTERP_KERNEL::Exception("A value 0.0 have been detected !");
1587 }
1588
1589 /*!
1590  * Computes minimal and maximal value in each component. An output array is filled
1591  * with \c 2 * \a this->getNumberOfComponents() values, so the caller is to allocate
1592  * enough memory before calling this method.
1593  *  \param [out] bounds - array of size at least 2 *\a this->getNumberOfComponents().
1594  *               It is filled as follows:<br>
1595  *               \a bounds[0] = \c min_of_component_0 <br>
1596  *               \a bounds[1] = \c max_of_component_0 <br>
1597  *               \a bounds[2] = \c min_of_component_1 <br>
1598  *               \a bounds[3] = \c max_of_component_1 <br>
1599  *               ...
1600  */
1601 void DataArrayDouble::getMinMaxPerComponent(double *bounds) const
1602 {
1603   checkAllocated();
1604   int dim=getNumberOfComponents();
1605   for (int idim=0; idim<dim; idim++)
1606     {
1607       bounds[idim*2]=std::numeric_limits<double>::max();
1608       bounds[idim*2+1]=-std::numeric_limits<double>::max();
1609     } 
1610   const double *ptr=getConstPointer();
1611   int nbOfTuples=getNumberOfTuples();
1612   for(int i=0;i<nbOfTuples;i++)
1613     {
1614       for(int idim=0;idim<dim;idim++)
1615         {
1616           if(bounds[idim*2]>ptr[i*dim+idim])
1617             {
1618               bounds[idim*2]=ptr[i*dim+idim];
1619             }
1620           if(bounds[idim*2+1]<ptr[i*dim+idim])
1621             {
1622               bounds[idim*2+1]=ptr[i*dim+idim];
1623             }
1624         }
1625     }
1626 }
1627
1628 /*!
1629  * This method retrieves a newly allocated DataArrayDouble instance having same number of tuples than \a this and twice number of components than \a this
1630  * to store both the min and max per component of each tuples. 
1631  * \param [in] epsilon the width of the bbox (identical in each direction) - 0.0 by default
1632  *
1633  * \return a newly created DataArrayDouble instance having \c this->getNumberOfTuples() tuples and 2 * \c this->getNumberOfComponent() components
1634  *
1635  * \throw If \a this is not allocated yet.
1636  */
1637 DataArrayDouble *DataArrayDouble::computeBBoxPerTuple(double epsilon) const
1638 {
1639   checkAllocated();
1640   const double *dataPtr=getConstPointer();
1641   int nbOfCompo=getNumberOfComponents();
1642   int nbTuples=getNumberOfTuples();
1643   MCAuto<DataArrayDouble> bbox=DataArrayDouble::New();
1644   bbox->alloc(nbTuples,2*nbOfCompo);
1645   double *bboxPtr=bbox->getPointer();
1646   for(int i=0;i<nbTuples;i++)
1647     {
1648       for(int j=0;j<nbOfCompo;j++)
1649         {
1650           bboxPtr[2*nbOfCompo*i+2*j]=dataPtr[nbOfCompo*i+j]-epsilon;
1651           bboxPtr[2*nbOfCompo*i+2*j+1]=dataPtr[nbOfCompo*i+j]+epsilon;
1652         }
1653     }
1654   return bbox.retn();
1655 }
1656
1657 /*!
1658  * For each tuples **t** in \a other, this method retrieves tuples in \a this that are equal to **t**.
1659  * Two tuples are considered equal if the euclidian distance between the two tuples is lower than \a eps.
1660  * 
1661  * \param [in] other a DataArrayDouble having same number of components than \a this.
1662  * \param [in] eps absolute precision representing distance (using infinite norm) between 2 tuples behind which 2 tuples are considered equal.
1663  * \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.
1664  *             \a cI allows to extract information in \a c.
1665  * \param [out] cI is an indirection array that allows to extract the data contained in \a c.
1666  *
1667  * \throw In case of:
1668  *  - \a this is not allocated
1669  *  - \a other is not allocated or null
1670  *  - \a this and \a other do not have the same number of components
1671  *  - if number of components of \a this is not in [1,2,3]
1672  *
1673  * \sa MEDCouplingPointSet::getNodeIdsNearPoints, DataArrayDouble::getDifferentValues
1674  */
1675 void DataArrayDouble::computeTupleIdsNearTuples(const DataArrayDouble *other, double eps, DataArrayInt *& c, DataArrayInt *& cI) const
1676 {
1677   if(!other)
1678     throw INTERP_KERNEL::Exception("DataArrayDouble::computeTupleIdsNearTuples : input pointer other is null !");
1679   checkAllocated();
1680   other->checkAllocated();
1681   int nbOfCompo=getNumberOfComponents();
1682   int otherNbOfCompo=other->getNumberOfComponents();
1683   if(nbOfCompo!=otherNbOfCompo)
1684     throw INTERP_KERNEL::Exception("DataArrayDouble::computeTupleIdsNearTuples : number of components should be equal between this and other !");
1685   int nbOfTuplesOther=other->getNumberOfTuples();
1686   MCAuto<DataArrayInt> cArr(DataArrayInt::New()),cIArr(DataArrayInt::New()); cArr->alloc(0,1); cIArr->pushBackSilent(0);
1687   switch(nbOfCompo)
1688   {
1689     case 3:
1690       {
1691         BBTreePts<3,int> myTree(begin(),0,0,getNumberOfTuples(),eps);
1692         FindTupleIdsNearTuplesAlg<3>(myTree,other->getConstPointer(),nbOfTuplesOther,eps,cArr,cIArr);
1693         break;
1694       }
1695     case 2:
1696       {
1697         BBTreePts<2,int> myTree(begin(),0,0,getNumberOfTuples(),eps);
1698         FindTupleIdsNearTuplesAlg<2>(myTree,other->getConstPointer(),nbOfTuplesOther,eps,cArr,cIArr);
1699         break;
1700       }
1701     case 1:
1702       {
1703         BBTreePts<1,int> myTree(begin(),0,0,getNumberOfTuples(),eps);
1704         FindTupleIdsNearTuplesAlg<1>(myTree,other->getConstPointer(),nbOfTuplesOther,eps,cArr,cIArr);
1705         break;
1706       }
1707     default:
1708       throw INTERP_KERNEL::Exception("Unexpected spacedim of coords for computeTupleIdsNearTuples. Must be 1, 2 or 3.");
1709   }
1710   c=cArr.retn(); cI=cIArr.retn();
1711 }
1712
1713 /*!
1714  * 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
1715  * around origin of 'radius' 1.
1716  * 
1717  * \param [in] eps absolute epsilon. under that value of delta between max and min no scale is performed.
1718  */
1719 void DataArrayDouble::recenterForMaxPrecision(double eps)
1720 {
1721   checkAllocated();
1722   int dim=getNumberOfComponents();
1723   std::vector<double> bounds(2*dim);
1724   getMinMaxPerComponent(&bounds[0]);
1725   for(int i=0;i<dim;i++)
1726     {
1727       double delta=bounds[2*i+1]-bounds[2*i];
1728       double offset=(bounds[2*i]+bounds[2*i+1])/2.;
1729       if(delta>eps)
1730         applyLin(1./delta,-offset/delta,i);
1731       else
1732         applyLin(1.,-offset,i);
1733     }
1734 }
1735
1736 /*!
1737  * Returns the maximal value and all its locations within \a this one-dimensional array.
1738  *  \param [out] tupleIds - a new instance of DataArrayInt containg indices of
1739  *               tuples holding the maximal value. The caller is to delete it using
1740  *               decrRef() as it is no more needed.
1741  *  \return double - the maximal value among all values of \a this array.
1742  *  \throw If \a this->getNumberOfComponents() != 1
1743  *  \throw If \a this->getNumberOfTuples() < 1
1744  */
1745 double DataArrayDouble::getMaxValue2(DataArrayInt*& tupleIds) const
1746 {
1747   int tmp;
1748   tupleIds=0;
1749   double ret=getMaxValue(tmp);
1750   tupleIds=findIdsInRange(ret,ret);
1751   return ret;
1752 }
1753
1754 /*!
1755  * Returns the minimal value and all its locations within \a this one-dimensional array.
1756  *  \param [out] tupleIds - a new instance of DataArrayInt containg indices of
1757  *               tuples holding the minimal value. The caller is to delete it using
1758  *               decrRef() as it is no more needed.
1759  *  \return double - the minimal value among all values of \a this array.
1760  *  \throw If \a this->getNumberOfComponents() != 1
1761  *  \throw If \a this->getNumberOfTuples() < 1
1762  */
1763 double DataArrayDouble::getMinValue2(DataArrayInt*& tupleIds) const
1764 {
1765   int tmp;
1766   tupleIds=0;
1767   double ret=getMinValue(tmp);
1768   tupleIds=findIdsInRange(ret,ret);
1769   return ret;
1770 }
1771
1772 /*!
1773  * 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.
1774  * This method only works for single component array.
1775  *
1776  * \return a value in [ 0, \c this->getNumberOfTuples() )
1777  *
1778  * \throw If \a this is not allocated
1779  *
1780  */
1781 int DataArrayDouble::count(double value, double eps) const
1782 {
1783   int ret=0;
1784   checkAllocated();
1785   if(getNumberOfComponents()!=1)
1786     throw INTERP_KERNEL::Exception("DataArrayDouble::count : must be applied on DataArrayDouble with only one component, you can call 'rearrange' method before !");
1787   const double *vals=begin();
1788   int nbOfTuples=getNumberOfTuples();
1789   for(int i=0;i<nbOfTuples;i++,vals++)
1790     if(fabs(*vals-value)<=eps)
1791       ret++;
1792   return ret;
1793 }
1794
1795 /*!
1796  * Returns the average value of \a this one-dimensional array.
1797  *  \return double - the average value over all values of \a this array.
1798  *  \throw If \a this->getNumberOfComponents() != 1
1799  *  \throw If \a this->getNumberOfTuples() < 1
1800  */
1801 double DataArrayDouble::getAverageValue() const
1802 {
1803   if(getNumberOfComponents()!=1)
1804     throw INTERP_KERNEL::Exception("DataArrayDouble::getAverageValue : must be applied on DataArrayDouble with only one component, you can call 'rearrange' method before !");
1805   int nbOfTuples=getNumberOfTuples();
1806   if(nbOfTuples<=0)
1807     throw INTERP_KERNEL::Exception("DataArrayDouble::getAverageValue : array exists but number of tuples must be > 0 !");
1808   const double *vals=getConstPointer();
1809   double ret=std::accumulate(vals,vals+nbOfTuples,0.);
1810   return ret/nbOfTuples;
1811 }
1812
1813 /*!
1814  * Returns the Euclidean norm of the vector defined by \a this array.
1815  *  \return double - the value of the Euclidean norm, i.e.
1816  *          the square root of the inner product of vector.
1817  *  \throw If \a this is not allocated.
1818  */
1819 double DataArrayDouble::norm2() const
1820 {
1821   checkAllocated();
1822   double ret=0.;
1823   std::size_t nbOfElems=getNbOfElems();
1824   const double *pt=getConstPointer();
1825   for(std::size_t i=0;i<nbOfElems;i++,pt++)
1826     ret+=(*pt)*(*pt);
1827   return sqrt(ret);
1828 }
1829
1830 /*!
1831  * Returns the maximum norm of the vector defined by \a this array.
1832  * This method works even if the number of components is diferent from one.
1833  * If the number of elements in \a this is 0, -1. is returned.
1834  *  \return double - the value of the maximum norm, i.e.
1835  *          the maximal absolute value among values of \a this array (whatever its number of components).
1836  *  \throw If \a this is not allocated.
1837  */
1838 double DataArrayDouble::normMax() const
1839 {
1840   checkAllocated();
1841   double ret(-1.);
1842   std::size_t nbOfElems(getNbOfElems());
1843   const double *pt(getConstPointer());
1844   for(std::size_t i=0;i<nbOfElems;i++,pt++)
1845     {
1846       double val(std::abs(*pt));
1847       if(val>ret)
1848         ret=val;
1849     }
1850   return ret;
1851 }
1852
1853 /*!
1854  * Returns the minimum norm (absolute value) of the vector defined by \a this array.
1855  * This method works even if the number of components is diferent from one.
1856  * If the number of elements in \a this is 0, std::numeric_limits<double>::max() is returned.
1857  *  \return double - the value of the minimum norm, i.e.
1858  *          the minimal absolute value among values of \a this array (whatever its number of components).
1859  *  \throw If \a this is not allocated.
1860  */
1861 double DataArrayDouble::normMin() const
1862 {
1863   checkAllocated();
1864   double ret(std::numeric_limits<double>::max());
1865   std::size_t nbOfElems(getNbOfElems());
1866   const double *pt(getConstPointer());
1867   for(std::size_t i=0;i<nbOfElems;i++,pt++)
1868     {
1869       double val(std::abs(*pt));
1870       if(val<ret)
1871         ret=val;
1872     }
1873   return ret;
1874 }
1875
1876 /*!
1877  * Accumulates values of each component of \a this array.
1878  *  \param [out] res - an array of length \a this->getNumberOfComponents(), allocated 
1879  *         by the caller, that is filled by this method with sum value for each
1880  *         component.
1881  *  \throw If \a this is not allocated.
1882  */
1883 void DataArrayDouble::accumulate(double *res) const
1884 {
1885   checkAllocated();
1886   const double *ptr=getConstPointer();
1887   int nbTuple=getNumberOfTuples();
1888   int nbComps=getNumberOfComponents();
1889   std::fill(res,res+nbComps,0.);
1890   for(int i=0;i<nbTuple;i++)
1891     std::transform(ptr+i*nbComps,ptr+(i+1)*nbComps,res,res,std::plus<double>());
1892 }
1893
1894 /*!
1895  * This method returns the min distance from an external tuple defined by [ \a tupleBg , \a tupleEnd ) to \a this and
1896  * the first tuple in \a this that matches the returned distance. If there is no tuples in \a this an exception will be thrown.
1897  *
1898  *
1899  * \a this is expected to be allocated and expected to have a number of components equal to the distance from \a tupleBg to
1900  * \a tupleEnd. If not an exception will be thrown.
1901  *
1902  * \param [in] tupleBg start pointer (included) of input external tuple
1903  * \param [in] tupleEnd end pointer (not included) of input external tuple
1904  * \param [out] tupleId the tuple id in \a this that matches the min of distance between \a this and input external tuple
1905  * \return the min distance.
1906  * \sa MEDCouplingUMesh::distanceToPoint
1907  */
1908 double DataArrayDouble::distanceToTuple(const double *tupleBg, const double *tupleEnd, int& tupleId) const
1909 {
1910   checkAllocated();
1911   int nbTuple=getNumberOfTuples();
1912   int nbComps=getNumberOfComponents();
1913   if(nbComps!=(int)std::distance(tupleBg,tupleEnd))
1914     { 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()); }
1915   if(nbTuple==0)
1916     throw INTERP_KERNEL::Exception("DataArrayDouble::distanceToTuple : no tuple in this ! No distance to compute !");
1917   double ret0=std::numeric_limits<double>::max();
1918   tupleId=-1;
1919   const double *work=getConstPointer();
1920   for(int i=0;i<nbTuple;i++)
1921     {
1922       double val=0.;
1923       for(int j=0;j<nbComps;j++,work++) 
1924         val+=(*work-tupleBg[j])*((*work-tupleBg[j]));
1925       if(val>=ret0)
1926         continue;
1927       else
1928         { ret0=val; tupleId=i; }
1929     }
1930   return sqrt(ret0);
1931 }
1932
1933 /*!
1934  * Accumulate values of the given component of \a this array.
1935  *  \param [in] compId - the index of the component of interest.
1936  *  \return double - a sum value of \a compId-th component.
1937  *  \throw If \a this is not allocated.
1938  *  \throw If \a the condition ( 0 <= \a compId < \a this->getNumberOfComponents() ) is
1939  *         not respected.
1940  */
1941 double DataArrayDouble::accumulate(int compId) const
1942 {
1943   checkAllocated();
1944   const double *ptr=getConstPointer();
1945   int nbTuple=getNumberOfTuples();
1946   int nbComps=getNumberOfComponents();
1947   if(compId<0 || compId>=nbComps)
1948     throw INTERP_KERNEL::Exception("DataArrayDouble::accumulate : Invalid compId specified : No such nb of components !");
1949   double ret=0.;
1950   for(int i=0;i<nbTuple;i++)
1951     ret+=ptr[i*nbComps+compId];
1952   return ret;
1953 }
1954
1955 /*!
1956  * This method accumulate using addition tuples in \a this using input index array [ \a bgOfIndex, \a endOfIndex ).
1957  * The returned array will have same number of components than \a this and number of tuples equal to
1958  * \c std::distance(bgOfIndex,endOfIndex) \b minus \b one.
1959  *
1960  * The input index array is expected to be ascendingly sorted in which the all referenced ids should be in [0, \c this->getNumberOfTuples).
1961  * 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.
1962  *
1963  * \param [in] bgOfIndex - begin (included) of the input index array.
1964  * \param [in] endOfIndex - end (excluded) of the input index array.
1965  * \return DataArrayDouble * - the new instance having the same number of components than \a this.
1966  * 
1967  * \throw If bgOfIndex or end is NULL.
1968  * \throw If input index array is not ascendingly sorted.
1969  * \throw If there is an id in [ \a bgOfIndex, \a endOfIndex ) not in [0, \c this->getNumberOfTuples).
1970  * \throw If std::distance(bgOfIndex,endOfIndex)==0.
1971  */
1972 DataArrayDouble *DataArrayDouble::accumulatePerChunck(const int *bgOfIndex, const int *endOfIndex) const
1973 {
1974   if(!bgOfIndex || !endOfIndex)
1975     throw INTERP_KERNEL::Exception("DataArrayDouble::accumulatePerChunck : input pointer NULL !");
1976   checkAllocated();
1977   int nbCompo=getNumberOfComponents();
1978   int nbOfTuples=getNumberOfTuples();
1979   int sz=(int)std::distance(bgOfIndex,endOfIndex);
1980   if(sz<1)
1981     throw INTERP_KERNEL::Exception("DataArrayDouble::accumulatePerChunck : invalid size of input index array !");
1982   sz--;
1983   MCAuto<DataArrayDouble> ret=DataArrayDouble::New(); ret->alloc(sz,nbCompo);
1984   const int *w=bgOfIndex;
1985   if(*w<0 || *w>=nbOfTuples)
1986     throw INTERP_KERNEL::Exception("DataArrayDouble::accumulatePerChunck : The first element of the input index not in [0,nbOfTuples) !");
1987   const double *srcPt=begin()+(*w)*nbCompo;
1988   double *tmp=ret->getPointer();
1989   for(int i=0;i<sz;i++,tmp+=nbCompo,w++)
1990     {
1991       std::fill(tmp,tmp+nbCompo,0.);
1992       if(w[1]>=w[0])
1993         {
1994           for(int j=w[0];j<w[1];j++,srcPt+=nbCompo)
1995             {
1996               if(j>=0 && j<nbOfTuples)
1997                 std::transform(srcPt,srcPt+nbCompo,tmp,tmp,std::plus<double>());
1998               else
1999                 {
2000                   std::ostringstream oss; oss << "DataArrayDouble::accumulatePerChunck : At rank #" << i << " the input index array points to id " << j << " should be in [0," << nbOfTuples << ") !";
2001                   throw INTERP_KERNEL::Exception(oss.str().c_str());
2002                 }
2003             }
2004         }
2005       else
2006         {
2007           std::ostringstream oss; oss << "DataArrayDouble::accumulatePerChunck : At rank #" << i << " the input index array is not in ascendingly sorted.";
2008           throw INTERP_KERNEL::Exception(oss.str().c_str());
2009         }
2010     }
2011   ret->copyStringInfoFrom(*this);
2012   return ret.retn();
2013 }
2014
2015 /*!
2016  * This method is close to numpy cumSum except that number of element is equal to \a this->getNumberOfTuples()+1. First element of DataArray returned is equal to 0.
2017  * This method expects that \a this as only one component. The returned array will have \a this->getNumberOfTuples()+1 tuple with also one component.
2018  * The ith element of returned array is equal to the sum of elements in \a this with rank strictly lower than i.
2019  *
2020  * \return DataArrayDouble - A newly built array containing cum sum of \a this.
2021  */
2022 MCAuto<DataArrayDouble> DataArrayDouble::cumSum() const
2023 {
2024   checkAllocated();
2025   checkNbOfComps(1,"DataArrayDouble::cumSum : this is expected to be single component");
2026   int nbOfTuple(getNumberOfTuples());
2027   MCAuto<DataArrayDouble> ret(DataArrayDouble::New()); ret->alloc(nbOfTuple+1,1);
2028   double *ptr(ret->getPointer());
2029   ptr[0]=0.;
2030   const double *thisPtr(begin());
2031   for(int i=0;i<nbOfTuple;i++)
2032     ptr[i+1]=ptr[i]+thisPtr[i];
2033   return ret;
2034 }
2035
2036 /*!
2037  * Converts each 2D point defined by the tuple of \a this array from the Polar to the
2038  * Cartesian coordinate system. The two components of the tuple of \a this array are 
2039  * considered to contain (1) radius and (2) angle of the point in the Polar CS.
2040  *  \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
2041  *          contains X and Y coordinates of the point in the Cartesian CS. The caller
2042  *          is to delete this array using decrRef() as it is no more needed. The array
2043  *          does not contain any textual info on components.
2044  *  \throw If \a this->getNumberOfComponents() != 2.
2045  * \sa fromCartToPolar
2046  */
2047 DataArrayDouble *DataArrayDouble::fromPolarToCart() const
2048 {
2049   checkAllocated();
2050   int nbOfComp(getNumberOfComponents());
2051   if(nbOfComp!=2)
2052     throw INTERP_KERNEL::Exception("DataArrayDouble::fromPolarToCart : must be an array with exactly 2 components !");
2053   int nbOfTuple(getNumberOfTuples());
2054   DataArrayDouble *ret(DataArrayDouble::New());
2055   ret->alloc(nbOfTuple,2);
2056   double *w(ret->getPointer());
2057   const double *wIn(getConstPointer());
2058   for(int i=0;i<nbOfTuple;i++,w+=2,wIn+=2)
2059     {
2060       w[0]=wIn[0]*cos(wIn[1]);
2061       w[1]=wIn[0]*sin(wIn[1]);
2062     }
2063   return ret;
2064 }
2065
2066 /*!
2067  * Converts each 3D point defined by the tuple of \a this array from the Cylindrical to
2068  * the Cartesian coordinate system. The three components of the tuple of \a this array 
2069  * are considered to contain (1) radius, (2) azimuth and (3) altitude of the point in
2070  * the Cylindrical CS.
2071  *  \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
2072  *          contains X, Y and Z coordinates of the point in the Cartesian CS. The info
2073  *          on the third component is copied from \a this array. The caller
2074  *          is to delete this array using decrRef() as it is no more needed. 
2075  *  \throw If \a this->getNumberOfComponents() != 3.
2076  * \sa fromCartToCyl
2077  */
2078 DataArrayDouble *DataArrayDouble::fromCylToCart() const
2079 {
2080   checkAllocated();
2081   int nbOfComp(getNumberOfComponents());
2082   if(nbOfComp!=3)
2083     throw INTERP_KERNEL::Exception("DataArrayDouble::fromCylToCart : must be an array with exactly 3 components !");
2084   int nbOfTuple(getNumberOfTuples());
2085   DataArrayDouble *ret(DataArrayDouble::New());
2086   ret->alloc(getNumberOfTuples(),3);
2087   double *w(ret->getPointer());
2088   const double *wIn(getConstPointer());
2089   for(int i=0;i<nbOfTuple;i++,w+=3,wIn+=3)
2090     {
2091       w[0]=wIn[0]*cos(wIn[1]);
2092       w[1]=wIn[0]*sin(wIn[1]);
2093       w[2]=wIn[2];
2094     }
2095   ret->setInfoOnComponent(2,getInfoOnComponent(2));
2096   return ret;
2097 }
2098
2099 /*!
2100  * Converts each 3D point defined by the tuple of \a this array from the Spherical to
2101  * the Cartesian coordinate system. The three components of the tuple of \a this array 
2102  * are considered to contain (1) radius, (2) polar angle and (3) azimuthal angle of the
2103  * point in the Cylindrical CS.
2104  *  \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
2105  *          contains X, Y and Z coordinates of the point in the Cartesian CS. The info
2106  *          on the third component is copied from \a this array. The caller
2107  *          is to delete this array using decrRef() as it is no more needed.
2108  *  \throw If \a this->getNumberOfComponents() != 3.
2109  * \sa fromCartToSpher
2110  */
2111 DataArrayDouble *DataArrayDouble::fromSpherToCart() const
2112 {
2113   checkAllocated();
2114   int nbOfComp(getNumberOfComponents());
2115   if(nbOfComp!=3)
2116     throw INTERP_KERNEL::Exception("DataArrayDouble::fromSpherToCart : must be an array with exactly 3 components !");
2117   int nbOfTuple(getNumberOfTuples());
2118   DataArrayDouble *ret(DataArrayDouble::New());
2119   ret->alloc(getNumberOfTuples(),3);
2120   double *w(ret->getPointer());
2121   const double *wIn(getConstPointer());
2122   for(int i=0;i<nbOfTuple;i++,w+=3,wIn+=3)
2123     {
2124       w[0]=wIn[0]*cos(wIn[2])*sin(wIn[1]);
2125       w[1]=wIn[0]*sin(wIn[2])*sin(wIn[1]);
2126       w[2]=wIn[0]*cos(wIn[1]);
2127     }
2128   return ret;
2129 }
2130
2131 /*!
2132  * 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.
2133  * 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.
2134  * If \a at equals to AX_CYL the returned array will be the result of operation cylindric to cartesian of \a this...
2135  *
2136  * \param [in] atOfThis - The axis type of \a this.
2137  * \return DataArrayDouble * - the new instance of DataArrayDouble (that must be dealed by caller) containing the result of the cartesianizification of \a this.
2138  */
2139 DataArrayDouble *DataArrayDouble::cartesianize(MEDCouplingAxisType atOfThis) const
2140 {
2141   checkAllocated();
2142   int nbOfComp(getNumberOfComponents());
2143   MCAuto<DataArrayDouble> ret;
2144   switch(atOfThis)
2145     {
2146     case AX_CART:
2147       ret=deepCopy();
2148     case AX_CYL:
2149       if(nbOfComp==3)
2150         {
2151           ret=fromCylToCart();
2152           break;
2153         }
2154       if(nbOfComp==2)
2155         {
2156           ret=fromPolarToCart();
2157           break;
2158         }
2159       else
2160         throw INTERP_KERNEL::Exception("DataArrayDouble::cartesianize : For AX_CYL, number of components must be in [2,3] !");
2161     case AX_SPHER:
2162       if(nbOfComp==3)
2163         {
2164           ret=fromSpherToCart();
2165           break;
2166         }
2167       if(nbOfComp==2)
2168         {
2169           ret=fromPolarToCart();
2170           break;
2171         }
2172       else
2173         throw INTERP_KERNEL::Exception("DataArrayDouble::cartesianize : For AX_CYL, number of components must be in [2,3] !");
2174     default:
2175       throw INTERP_KERNEL::Exception("DataArrayDouble::cartesianize : not recognized axis type ! Only AX_CART, AX_CYL and AX_SPHER supported !");
2176     }
2177   ret->copyStringInfoFrom(*this);
2178   return ret.retn();
2179 }
2180
2181 /*!
2182  * This method returns a newly created array to be deallocated that contains the result of conversion from cartesian to polar.
2183  * This method expects that \a this has exactly 2 components.
2184  * \sa fromPolarToCart
2185  */
2186 DataArrayDouble *DataArrayDouble::fromCartToPolar() const
2187 {
2188   MCAuto<DataArrayDouble> ret(DataArrayDouble::New());
2189   checkAllocated();
2190   int nbOfComp(getNumberOfComponents()),nbTuples(getNumberOfTuples());
2191   if(nbOfComp!=2)
2192     throw INTERP_KERNEL::Exception("DataArrayDouble::fromCartToPolar : must be an array with exactly 2 components !");
2193   ret->alloc(nbTuples,2);
2194   double *retPtr(ret->getPointer());
2195   const double *ptr(begin());
2196   for(int i=0;i<nbTuples;i++,ptr+=2,retPtr+=2)
2197     {
2198       retPtr[0]=sqrt(ptr[0]*ptr[0]+ptr[1]*ptr[1]);
2199       retPtr[1]=atan2(ptr[1],ptr[0]);
2200     }
2201   return ret.retn();
2202 }
2203
2204 /*!
2205  * This method returns a newly created array to be deallocated that contains the result of conversion from cartesian to cylindrical.
2206  * This method expects that \a this has exactly 3 components.
2207  * \sa fromCylToCart
2208  */
2209 DataArrayDouble *DataArrayDouble::fromCartToCyl() const
2210 {
2211   MCAuto<DataArrayDouble> ret(DataArrayDouble::New());
2212   checkAllocated();
2213   int nbOfComp(getNumberOfComponents()),nbTuples(getNumberOfTuples());
2214   if(nbOfComp!=3)
2215     throw INTERP_KERNEL::Exception("DataArrayDouble::fromCartToCyl : must be an array with exactly 3 components !");
2216   ret->alloc(nbTuples,3);
2217   double *retPtr(ret->getPointer());
2218   const double *ptr(begin());
2219   for(int i=0;i<nbTuples;i++,ptr+=3,retPtr+=3)
2220     {
2221       retPtr[0]=sqrt(ptr[0]*ptr[0]+ptr[1]*ptr[1]);
2222       retPtr[1]=atan2(ptr[1],ptr[0]);
2223       retPtr[2]=ptr[2];
2224     }
2225   return ret.retn();
2226 }
2227
2228 /*!
2229  * This method returns a newly created array to be deallocated that contains the result of conversion from cartesian to spherical coordinates.
2230  * \sa fromSpherToCart
2231  */
2232 DataArrayDouble *DataArrayDouble::fromCartToSpher() const
2233 {
2234   MCAuto<DataArrayDouble> ret(DataArrayDouble::New());
2235   checkAllocated();
2236   int nbOfComp(getNumberOfComponents()),nbTuples(getNumberOfTuples());
2237   if(nbOfComp!=3)
2238     throw INTERP_KERNEL::Exception("DataArrayDouble::fromCartToSpher : must be an array with exactly 3 components !");
2239   ret->alloc(nbTuples,3);
2240   double *retPtr(ret->getPointer());
2241   const double *ptr(begin());
2242   for(int i=0;i<nbTuples;i++,ptr+=3,retPtr+=3)
2243     {
2244       retPtr[0]=sqrt(ptr[0]*ptr[0]+ptr[1]*ptr[1]+ptr[2]*ptr[2]);
2245       retPtr[1]=acos(ptr[2]/retPtr[0]);
2246       retPtr[2]=atan2(ptr[1],ptr[0]);
2247     }
2248   return ret.retn();
2249 }
2250
2251 /*!
2252  * This method returns a newly created array to be deallocated that contains the result of conversion from cartesian to cylindrical relative to the given \a center and a \a vector.
2253  * This method expects that \a this has exactly 3 components.
2254  * \sa MEDCouplingFieldDouble::computeVectorFieldCyl
2255  */
2256 DataArrayDouble *DataArrayDouble::fromCartToCylGiven(const DataArrayDouble *coords, const double center[3], const double vect[3]) const
2257 {
2258   if(!coords)
2259     throw INTERP_KERNEL::Exception("DataArrayDouble::fromCartToCylGiven : input coords are NULL !");
2260   MCAuto<DataArrayDouble> ret(DataArrayDouble::New());
2261   checkAllocated(); coords->checkAllocated();
2262   int nbOfComp(getNumberOfComponents()),nbTuples(getNumberOfTuples());
2263   if(nbOfComp!=3)
2264     throw INTERP_KERNEL::Exception("DataArrayDouble::fromCartToCylGiven : must be an array with exactly 3 components !");
2265   if(coords->getNumberOfComponents()!=3)
2266     throw INTERP_KERNEL::Exception("DataArrayDouble::fromCartToCylGiven : coords array must have exactly 3 components !");
2267   if(coords->getNumberOfTuples()!=nbTuples)
2268     throw INTERP_KERNEL::Exception("DataArrayDouble::fromCartToCylGiven : coords array must have the same number of tuples !");
2269   ret->alloc(nbTuples,nbOfComp);
2270   double magOfVect(sqrt(vect[0]*vect[0]+vect[1]*vect[1]+vect[2]*vect[2]));
2271   if(magOfVect<1e-12)
2272     throw INTERP_KERNEL::Exception("DataArrayDouble::fromCartToCylGiven : magnitude of vect is too low !");
2273   double Ur[3],Uteta[3],Uz[3],*retPtr(ret->getPointer());
2274   const double *coo(coords->begin()),*vectField(begin());
2275   std::transform(vect,vect+3,Uz,std::bind2nd(std::multiplies<double>(),1./magOfVect));
2276   for(int i=0;i<nbTuples;i++,vectField+=3,retPtr+=3,coo+=3)
2277     {
2278       std::transform(coo,coo+3,center,Ur,std::minus<double>());
2279       Uteta[0]=Uz[1]*Ur[2]-Uz[2]*Ur[1]; Uteta[1]=Uz[2]*Ur[0]-Uz[0]*Ur[2]; Uteta[2]=Uz[0]*Ur[1]-Uz[1]*Ur[0];
2280       double magOfTeta(sqrt(Uteta[0]*Uteta[0]+Uteta[1]*Uteta[1]+Uteta[2]*Uteta[2]));
2281       std::transform(Uteta,Uteta+3,Uteta,std::bind2nd(std::multiplies<double>(),1./magOfTeta));
2282       Ur[0]=Uteta[1]*Uz[2]-Uteta[2]*Uz[1]; Ur[1]=Uteta[2]*Uz[0]-Uteta[0]*Uz[2]; Ur[2]=Uteta[0]*Uz[1]-Uteta[1]*Uz[0];
2283       retPtr[0]=Ur[0]*vectField[0]+Ur[1]*vectField[1]+Ur[2]*vectField[2];
2284       retPtr[1]=Uteta[0]*vectField[0]+Uteta[1]*vectField[1]+Uteta[2]*vectField[2];
2285       retPtr[2]=Uz[0]*vectField[0]+Uz[1]*vectField[1]+Uz[2]*vectField[2];
2286     }
2287   ret->copyStringInfoFrom(*this);
2288   return ret.retn();
2289 }
2290
2291 /*!
2292  * Computes the doubly contracted product of every tensor defined by the tuple of \a this
2293  * array contating 6 components.
2294  *  \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
2295  *          is calculated from the tuple <em>(t)</em> of \a this array as follows:
2296  *          \f$ t[0]^2+t[1]^2+t[2]^2+2*t[3]^2+2*t[4]^2+2*t[5]^2\f$.
2297  *         The caller is to delete this result array using decrRef() as it is no more needed. 
2298  *  \throw If \a this->getNumberOfComponents() != 6.
2299  */
2300 DataArrayDouble *DataArrayDouble::doublyContractedProduct() const
2301 {
2302   checkAllocated();
2303   int nbOfComp(getNumberOfComponents());
2304   if(nbOfComp!=6)
2305     throw INTERP_KERNEL::Exception("DataArrayDouble::doublyContractedProduct : must be an array with exactly 6 components !");
2306   DataArrayDouble *ret=DataArrayDouble::New();
2307   int nbOfTuple=getNumberOfTuples();
2308   ret->alloc(nbOfTuple,1);
2309   const double *src=getConstPointer();
2310   double *dest=ret->getPointer();
2311   for(int i=0;i<nbOfTuple;i++,dest++,src+=6)
2312     *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];
2313   return ret;
2314 }
2315
2316 /*!
2317  * Computes the determinant of every square matrix defined by the tuple of \a this
2318  * array, which contains either 4, 6 or 9 components. The case of 6 components
2319  * corresponds to that of the upper triangular matrix.
2320  *  \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
2321  *          is the determinant of matrix of the corresponding tuple of \a this array.
2322  *          The caller is to delete this result array using decrRef() as it is no more
2323  *          needed. 
2324  *  \throw If \a this->getNumberOfComponents() is not in [4,6,9].
2325  */
2326 DataArrayDouble *DataArrayDouble::determinant() const
2327 {
2328   checkAllocated();
2329   DataArrayDouble *ret=DataArrayDouble::New();
2330   int nbOfTuple=getNumberOfTuples();
2331   ret->alloc(nbOfTuple,1);
2332   const double *src=getConstPointer();
2333   double *dest=ret->getPointer();
2334   switch(getNumberOfComponents())
2335   {
2336     case 6:
2337       for(int i=0;i<nbOfTuple;i++,dest++,src+=6)
2338         *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];
2339       return ret;
2340     case 4:
2341       for(int i=0;i<nbOfTuple;i++,dest++,src+=4)
2342         *dest=src[0]*src[3]-src[1]*src[2];
2343       return ret;
2344     case 9:
2345       for(int i=0;i<nbOfTuple;i++,dest++,src+=9)
2346         *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];
2347       return ret;
2348     default:
2349       ret->decrRef();
2350       throw INTERP_KERNEL::Exception("DataArrayDouble::determinant : Invalid number of components ! must be in 4,6,9 !");
2351   }
2352 }
2353
2354 /*!
2355  * Computes 3 eigenvalues of every upper triangular matrix defined by the tuple of
2356  * \a this array, which contains 6 components.
2357  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing 3
2358  *          components, whose each tuple contains the eigenvalues of the matrix of
2359  *          corresponding tuple of \a this array. 
2360  *          The caller is to delete this result array using decrRef() as it is no more
2361  *          needed. 
2362  *  \throw If \a this->getNumberOfComponents() != 6.
2363  */
2364 DataArrayDouble *DataArrayDouble::eigenValues() const
2365 {
2366   checkAllocated();
2367   int nbOfComp=getNumberOfComponents();
2368   if(nbOfComp!=6)
2369     throw INTERP_KERNEL::Exception("DataArrayDouble::eigenValues : must be an array with exactly 6 components !");
2370   DataArrayDouble *ret=DataArrayDouble::New();
2371   int nbOfTuple=getNumberOfTuples();
2372   ret->alloc(nbOfTuple,3);
2373   const double *src=getConstPointer();
2374   double *dest=ret->getPointer();
2375   for(int i=0;i<nbOfTuple;i++,dest+=3,src+=6)
2376     INTERP_KERNEL::computeEigenValues6(src,dest);
2377   return ret;
2378 }
2379
2380 /*!
2381  * Computes 3 eigenvectors of every upper triangular matrix defined by the tuple of
2382  * \a this array, which contains 6 components.
2383  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing 9
2384  *          components, whose each tuple contains 3 eigenvectors of the matrix of
2385  *          corresponding tuple of \a this array.
2386  *          The caller is to delete this result array using decrRef() as it is no more
2387  *          needed.
2388  *  \throw If \a this->getNumberOfComponents() != 6.
2389  */
2390 DataArrayDouble *DataArrayDouble::eigenVectors() const
2391 {
2392   checkAllocated();
2393   int nbOfComp=getNumberOfComponents();
2394   if(nbOfComp!=6)
2395     throw INTERP_KERNEL::Exception("DataArrayDouble::eigenVectors : must be an array with exactly 6 components !");
2396   DataArrayDouble *ret=DataArrayDouble::New();
2397   int nbOfTuple=getNumberOfTuples();
2398   ret->alloc(nbOfTuple,9);
2399   const double *src=getConstPointer();
2400   double *dest=ret->getPointer();
2401   for(int i=0;i<nbOfTuple;i++,src+=6)
2402     {
2403       double tmp[3];
2404       INTERP_KERNEL::computeEigenValues6(src,tmp);
2405       for(int j=0;j<3;j++,dest+=3)
2406         INTERP_KERNEL::computeEigenVectorForEigenValue6(src,tmp[j],1e-12,dest);
2407     }
2408   return ret;
2409 }
2410
2411 /*!
2412  * Computes the inverse matrix of every matrix defined by the tuple of \a this
2413  * array, which contains either 4, 6 or 9 components. The case of 6 components
2414  * corresponds to that of the upper triangular matrix.
2415  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2416  *          same number of components as \a this one, whose each tuple is the inverse
2417  *          matrix of the matrix of corresponding tuple of \a this array. 
2418  *          The caller is to delete this result array using decrRef() as it is no more
2419  *          needed. 
2420  *  \throw If \a this->getNumberOfComponents() is not in [4,6,9].
2421  */
2422 DataArrayDouble *DataArrayDouble::inverse() const
2423 {
2424   checkAllocated();
2425   int nbOfComp=getNumberOfComponents();
2426   if(nbOfComp!=6 && nbOfComp!=9 && nbOfComp!=4)
2427     throw INTERP_KERNEL::Exception("DataArrayDouble::inversion : must be an array with 4,6 or 9 components !");
2428   DataArrayDouble *ret=DataArrayDouble::New();
2429   int nbOfTuple=getNumberOfTuples();
2430   ret->alloc(nbOfTuple,nbOfComp);
2431   const double *src=getConstPointer();
2432   double *dest=ret->getPointer();
2433   if(nbOfComp==6)
2434     for(int i=0;i<nbOfTuple;i++,dest+=6,src+=6)
2435       {
2436         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];
2437         dest[0]=(src[1]*src[2]-src[4]*src[4])/det;
2438         dest[1]=(src[0]*src[2]-src[5]*src[5])/det;
2439         dest[2]=(src[0]*src[1]-src[3]*src[3])/det;
2440         dest[3]=(src[5]*src[4]-src[3]*src[2])/det;
2441         dest[4]=(src[5]*src[3]-src[0]*src[4])/det;
2442         dest[5]=(src[3]*src[4]-src[1]*src[5])/det;
2443       }
2444   else if(nbOfComp==4)
2445     for(int i=0;i<nbOfTuple;i++,dest+=4,src+=4)
2446       {
2447         double det=src[0]*src[3]-src[1]*src[2];
2448         dest[0]=src[3]/det;
2449         dest[1]=-src[1]/det;
2450         dest[2]=-src[2]/det;
2451         dest[3]=src[0]/det;
2452       }
2453   else
2454     for(int i=0;i<nbOfTuple;i++,dest+=9,src+=9)
2455       {
2456         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];
2457         dest[0]=(src[4]*src[8]-src[7]*src[5])/det;
2458         dest[1]=(src[7]*src[2]-src[1]*src[8])/det;
2459         dest[2]=(src[1]*src[5]-src[4]*src[2])/det;
2460         dest[3]=(src[6]*src[5]-src[3]*src[8])/det;
2461         dest[4]=(src[0]*src[8]-src[6]*src[2])/det;
2462         dest[5]=(src[2]*src[3]-src[0]*src[5])/det;
2463         dest[6]=(src[3]*src[7]-src[6]*src[4])/det;
2464         dest[7]=(src[6]*src[1]-src[0]*src[7])/det;
2465         dest[8]=(src[0]*src[4]-src[1]*src[3])/det;
2466       }
2467   return ret;
2468 }
2469
2470 /*!
2471  * Computes the trace of every matrix defined by the tuple of \a this
2472  * array, which contains either 4, 6 or 9 components. The case of 6 components
2473  * corresponds to that of the upper triangular matrix.
2474  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing 
2475  *          1 component, whose each tuple is the trace of
2476  *          the matrix of corresponding tuple of \a this array. 
2477  *          The caller is to delete this result array using decrRef() as it is no more
2478  *          needed. 
2479  *  \throw If \a this->getNumberOfComponents() is not in [4,6,9].
2480  */
2481 DataArrayDouble *DataArrayDouble::trace() const
2482 {
2483   checkAllocated();
2484   int nbOfComp=getNumberOfComponents();
2485   if(nbOfComp!=6 && nbOfComp!=9 && nbOfComp!=4)
2486     throw INTERP_KERNEL::Exception("DataArrayDouble::trace : must be an array with 4,6 or 9 components !");
2487   DataArrayDouble *ret=DataArrayDouble::New();
2488   int nbOfTuple=getNumberOfTuples();
2489   ret->alloc(nbOfTuple,1);
2490   const double *src=getConstPointer();
2491   double *dest=ret->getPointer();
2492   if(nbOfComp==6)
2493     for(int i=0;i<nbOfTuple;i++,dest++,src+=6)
2494       *dest=src[0]+src[1]+src[2];
2495   else if(nbOfComp==4)
2496     for(int i=0;i<nbOfTuple;i++,dest++,src+=4)
2497       *dest=src[0]+src[3];
2498   else
2499     for(int i=0;i<nbOfTuple;i++,dest++,src+=9)
2500       *dest=src[0]+src[4]+src[8];
2501   return ret;
2502 }
2503
2504 /*!
2505  * Computes the stress deviator tensor of every stress tensor defined by the tuple of
2506  * \a this array, which contains 6 components.
2507  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2508  *          same number of components and tuples as \a this array.
2509  *          The caller is to delete this result array using decrRef() as it is no more
2510  *          needed.
2511  *  \throw If \a this->getNumberOfComponents() != 6.
2512  */
2513 DataArrayDouble *DataArrayDouble::deviator() const
2514 {
2515   checkAllocated();
2516   int nbOfComp=getNumberOfComponents();
2517   if(nbOfComp!=6)
2518     throw INTERP_KERNEL::Exception("DataArrayDouble::deviator : must be an array with exactly 6 components !");
2519   DataArrayDouble *ret=DataArrayDouble::New();
2520   int nbOfTuple=getNumberOfTuples();
2521   ret->alloc(nbOfTuple,6);
2522   const double *src=getConstPointer();
2523   double *dest=ret->getPointer();
2524   for(int i=0;i<nbOfTuple;i++,dest+=6,src+=6)
2525     {
2526       double tr=(src[0]+src[1]+src[2])/3.;
2527       dest[0]=src[0]-tr;
2528       dest[1]=src[1]-tr;
2529       dest[2]=src[2]-tr;
2530       dest[3]=src[3];
2531       dest[4]=src[4];
2532       dest[5]=src[5];
2533     }
2534   return ret;
2535 }
2536
2537 /*!
2538  * Computes the magnitude of every vector defined by the tuple of
2539  * \a this array.
2540  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2541  *          same number of tuples as \a this array and one component.
2542  *          The caller is to delete this result array using decrRef() as it is no more
2543  *          needed.
2544  *  \throw If \a this is not allocated.
2545  */
2546 DataArrayDouble *DataArrayDouble::magnitude() const
2547 {
2548   checkAllocated();
2549   int nbOfComp=getNumberOfComponents();
2550   DataArrayDouble *ret=DataArrayDouble::New();
2551   int nbOfTuple=getNumberOfTuples();
2552   ret->alloc(nbOfTuple,1);
2553   const double *src=getConstPointer();
2554   double *dest=ret->getPointer();
2555   for(int i=0;i<nbOfTuple;i++,dest++)
2556     {
2557       double sum=0.;
2558       for(int j=0;j<nbOfComp;j++,src++)
2559         sum+=(*src)*(*src);
2560       *dest=sqrt(sum);
2561     }
2562   return ret;
2563 }
2564
2565 /*!
2566  * Computes for each tuple the sum of number of components values in the tuple and return it.
2567  * 
2568  * \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2569  *          same number of tuples as \a this array and one component.
2570  *          The caller is to delete this result array using decrRef() as it is no more
2571  *          needed.
2572  *  \throw If \a this is not allocated.
2573  */
2574 DataArrayDouble *DataArrayDouble::sumPerTuple() const
2575 {
2576   checkAllocated();
2577   int nbOfComp(getNumberOfComponents()),nbOfTuple(getNumberOfTuples());
2578   MCAuto<DataArrayDouble> ret(DataArrayDouble::New());
2579   ret->alloc(nbOfTuple,1);
2580   const double *src(getConstPointer());
2581   double *dest(ret->getPointer());
2582   for(int i=0;i<nbOfTuple;i++,dest++,src+=nbOfComp)
2583     *dest=std::accumulate(src,src+nbOfComp,0.);
2584   return ret.retn();
2585 }
2586
2587 /*!
2588  * Computes the maximal value within every tuple of \a this array.
2589  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2590  *          same number of tuples as \a this array and one component.
2591  *          The caller is to delete this result array using decrRef() as it is no more
2592  *          needed.
2593  *  \throw If \a this is not allocated.
2594  *  \sa DataArrayDouble::maxPerTupleWithCompoId
2595  */
2596 DataArrayDouble *DataArrayDouble::maxPerTuple() const
2597 {
2598   checkAllocated();
2599   int nbOfComp=getNumberOfComponents();
2600   MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
2601   int nbOfTuple=getNumberOfTuples();
2602   ret->alloc(nbOfTuple,1);
2603   const double *src=getConstPointer();
2604   double *dest=ret->getPointer();
2605   for(int i=0;i<nbOfTuple;i++,dest++,src+=nbOfComp)
2606     *dest=*std::max_element(src,src+nbOfComp);
2607   return ret.retn();
2608 }
2609
2610 /*!
2611  * Computes the maximal value within every tuple of \a this array and it returns the first component
2612  * id for each tuple that corresponds to the maximal value within the tuple.
2613  * 
2614  *  \param [out] compoIdOfMaxPerTuple - the new new instance of DataArrayInt containing the
2615  *          same number of tuples and only one component.
2616  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2617  *          same number of tuples as \a this array and one component.
2618  *          The caller is to delete this result array using decrRef() as it is no more
2619  *          needed.
2620  *  \throw If \a this is not allocated.
2621  *  \sa DataArrayDouble::maxPerTuple
2622  */
2623 DataArrayDouble *DataArrayDouble::maxPerTupleWithCompoId(DataArrayInt* &compoIdOfMaxPerTuple) const
2624 {
2625   checkAllocated();
2626   int nbOfComp=getNumberOfComponents();
2627   MCAuto<DataArrayDouble> ret0=DataArrayDouble::New();
2628   MCAuto<DataArrayInt> ret1=DataArrayInt::New();
2629   int nbOfTuple=getNumberOfTuples();
2630   ret0->alloc(nbOfTuple,1); ret1->alloc(nbOfTuple,1);
2631   const double *src=getConstPointer();
2632   double *dest=ret0->getPointer(); int *dest1=ret1->getPointer();
2633   for(int i=0;i<nbOfTuple;i++,dest++,dest1++,src+=nbOfComp)
2634     {
2635       const double *loc=std::max_element(src,src+nbOfComp);
2636       *dest=*loc;
2637       *dest1=(int)std::distance(src,loc);
2638     }
2639   compoIdOfMaxPerTuple=ret1.retn();
2640   return ret0.retn();
2641 }
2642
2643 /*!
2644  * This method returns a newly allocated DataArrayDouble instance having one component and \c this->getNumberOfTuples() * \c this->getNumberOfTuples() tuples.
2645  * \n This returned array contains the euclidian distance for each tuple in \a this. 
2646  * \n So the returned array can be seen as a dense symmetrical matrix whose diagonal elements are equal to 0.
2647  * \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)
2648  *
2649  * \warning use this method with care because it can leads to big amount of consumed memory !
2650  * 
2651  * \return A newly allocated (huge) MEDCoupling::DataArrayDouble instance that the caller should deal with.
2652  *
2653  * \throw If \a this is not allocated.
2654  *
2655  * \sa DataArrayDouble::buildEuclidianDistanceDenseMatrixWith
2656  */
2657 DataArrayDouble *DataArrayDouble::buildEuclidianDistanceDenseMatrix() const
2658 {
2659   checkAllocated();
2660   int nbOfComp=getNumberOfComponents();
2661   int nbOfTuples=getNumberOfTuples();
2662   const double *inData=getConstPointer();
2663   MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
2664   ret->alloc(nbOfTuples*nbOfTuples,1);
2665   double *outData=ret->getPointer();
2666   for(int i=0;i<nbOfTuples;i++)
2667     {
2668       outData[i*nbOfTuples+i]=0.;
2669       for(int j=i+1;j<nbOfTuples;j++)
2670         {
2671           double dist=0.;
2672           for(int k=0;k<nbOfComp;k++)
2673             { double delta=inData[i*nbOfComp+k]-inData[j*nbOfComp+k]; dist+=delta*delta; }
2674           dist=sqrt(dist);
2675           outData[i*nbOfTuples+j]=dist;
2676           outData[j*nbOfTuples+i]=dist;
2677         }
2678     }
2679   return ret.retn();
2680 }
2681
2682 /*!
2683  * This method returns a newly allocated DataArrayDouble instance having one component and \c this->getNumberOfTuples() * \c other->getNumberOfTuples() tuples.
2684  * \n This returned array contains the euclidian distance for each tuple in \a other with each tuple in \a this. 
2685  * \n So the returned array can be seen as a dense rectangular matrix with \c other->getNumberOfTuples() rows and \c this->getNumberOfTuples() columns.
2686  * \n Output rectangular matrix is sorted along rows.
2687  * \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)
2688  *
2689  * \warning use this method with care because it can leads to big amount of consumed memory !
2690  * 
2691  * \param [in] other DataArrayDouble instance having same number of components than \a this.
2692  * \return A newly allocated (huge) MEDCoupling::DataArrayDouble instance that the caller should deal with.
2693  *
2694  * \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.
2695  *
2696  * \sa DataArrayDouble::buildEuclidianDistanceDenseMatrix
2697  */
2698 DataArrayDouble *DataArrayDouble::buildEuclidianDistanceDenseMatrixWith(const DataArrayDouble *other) const
2699 {
2700   if(!other)
2701     throw INTERP_KERNEL::Exception("DataArrayDouble::buildEuclidianDistanceDenseMatrixWith : input parameter is null !");
2702   checkAllocated();
2703   other->checkAllocated();
2704   int nbOfComp=getNumberOfComponents();
2705   int otherNbOfComp=other->getNumberOfComponents();
2706   if(nbOfComp!=otherNbOfComp)
2707     {
2708       std::ostringstream oss; oss << "DataArrayDouble::buildEuclidianDistanceDenseMatrixWith : this nb of compo=" << nbOfComp << " and other nb of compo=" << otherNbOfComp << ". It should match !";
2709       throw INTERP_KERNEL::Exception(oss.str().c_str());
2710     }
2711   int nbOfTuples=getNumberOfTuples();
2712   int otherNbOfTuples=other->getNumberOfTuples();
2713   const double *inData=getConstPointer();
2714   const double *inDataOther=other->getConstPointer();
2715   MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
2716   ret->alloc(otherNbOfTuples*nbOfTuples,1);
2717   double *outData=ret->getPointer();
2718   for(int i=0;i<otherNbOfTuples;i++,inDataOther+=nbOfComp)
2719     {
2720       for(int j=0;j<nbOfTuples;j++)
2721         {
2722           double dist=0.;
2723           for(int k=0;k<nbOfComp;k++)
2724             { double delta=inDataOther[k]-inData[j*nbOfComp+k]; dist+=delta*delta; }
2725           dist=sqrt(dist);
2726           outData[i*nbOfTuples+j]=dist;
2727         }
2728     }
2729   return ret.retn();
2730 }
2731
2732 /*!
2733  * Sorts value within every tuple of \a this array.
2734  *  \param [in] asc - if \a true, the values are sorted in ascending order, else,
2735  *              in descending order.
2736  *  \throw If \a this is not allocated.
2737  */
2738 void DataArrayDouble::sortPerTuple(bool asc)
2739 {
2740   checkAllocated();
2741   double *pt=getPointer();
2742   int nbOfTuple=getNumberOfTuples();
2743   int nbOfComp=getNumberOfComponents();
2744   if(asc)
2745     for(int i=0;i<nbOfTuple;i++,pt+=nbOfComp)
2746       std::sort(pt,pt+nbOfComp);
2747   else
2748     for(int i=0;i<nbOfTuple;i++,pt+=nbOfComp)
2749       std::sort(pt,pt+nbOfComp,std::greater<double>());
2750   declareAsNew();
2751 }
2752
2753 /*!
2754  * Converts every value of \a this array to its absolute value.
2755  * \b WARNING this method is non const. If a new DataArrayDouble instance should be built containing the result of abs DataArrayDouble::computeAbs
2756  * should be called instead.
2757  *
2758  * \throw If \a this is not allocated.
2759  * \sa DataArrayDouble::computeAbs
2760  */
2761 void DataArrayDouble::abs()
2762 {
2763   checkAllocated();
2764   double *ptr(getPointer());
2765   std::size_t nbOfElems(getNbOfElems());
2766   std::transform(ptr,ptr+nbOfElems,ptr,std::ptr_fun<double,double>(fabs));
2767   declareAsNew();
2768 }
2769
2770 /*!
2771  * This method builds a new instance of \a this object containing the result of std::abs applied of all elements in \a this.
2772  * This method is a const method (that do not change any values in \a this) contrary to  DataArrayDouble::abs method.
2773  *
2774  * \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2775  *         same number of tuples and component as \a this array.
2776  *         The caller is to delete this result array using decrRef() as it is no more
2777  *         needed.
2778  * \throw If \a this is not allocated.
2779  * \sa DataArrayDouble::abs
2780  */
2781 DataArrayDouble *DataArrayDouble::computeAbs() const
2782 {
2783   checkAllocated();
2784   DataArrayDouble *newArr(DataArrayDouble::New());
2785   int nbOfTuples(getNumberOfTuples());
2786   int nbOfComp(getNumberOfComponents());
2787   newArr->alloc(nbOfTuples,nbOfComp);
2788   std::transform(begin(),end(),newArr->getPointer(),std::ptr_fun<double,double>(fabs));
2789   newArr->copyStringInfoFrom(*this);
2790   return newArr;
2791 }
2792
2793 /*!
2794  * Apply a linear function to a given component of \a this array, so that
2795  * an array element <em>(x)</em> becomes \f$ a * x + b \f$.
2796  *  \param [in] a - the first coefficient of the function.
2797  *  \param [in] b - the second coefficient of the function.
2798  *  \param [in] compoId - the index of component to modify.
2799  *  \throw If \a this is not allocated, or \a compoId is not in [0,\c this->getNumberOfComponents() ).
2800  */
2801 void DataArrayDouble::applyLin(double a, double b, int compoId)
2802 {
2803   checkAllocated();
2804   double *ptr(getPointer()+compoId);
2805   int nbOfComp(getNumberOfComponents()),nbOfTuple(getNumberOfTuples());
2806   if(compoId<0 || compoId>=nbOfComp)
2807     {
2808       std::ostringstream oss; oss << "DataArrayDouble::applyLin : The compoId requested (" << compoId << ") is not valid ! Must be in [0," << nbOfComp << ") !";
2809       throw INTERP_KERNEL::Exception(oss.str().c_str());
2810     }
2811   for(int i=0;i<nbOfTuple;i++,ptr+=nbOfComp)
2812     *ptr=a*(*ptr)+b;
2813   declareAsNew();
2814 }
2815
2816 /*!
2817  * Apply a linear function to all elements of \a this array, so that
2818  * an element _x_ becomes \f$ a * x + b \f$.
2819  *  \param [in] a - the first coefficient of the function.
2820  *  \param [in] b - the second coefficient of the function.
2821  *  \throw If \a this is not allocated.
2822  */
2823 void DataArrayDouble::applyLin(double a, double b)
2824 {
2825   checkAllocated();
2826   double *ptr=getPointer();
2827   std::size_t nbOfElems=getNbOfElems();
2828   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
2829     *ptr=a*(*ptr)+b;
2830   declareAsNew();
2831 }
2832
2833 /*!
2834  * Modify all elements of \a this array, so that
2835  * an element _x_ becomes \f$ numerator / x \f$.
2836  *  \warning If an exception is thrown because of presence of 0.0 element in \a this 
2837  *           array, all elements processed before detection of the zero element remain
2838  *           modified.
2839  *  \param [in] numerator - the numerator used to modify array elements.
2840  *  \throw If \a this is not allocated.
2841  *  \throw If there is an element equal to 0.0 in \a this array.
2842  */
2843 void DataArrayDouble::applyInv(double numerator)
2844 {
2845   checkAllocated();
2846   double *ptr=getPointer();
2847   std::size_t nbOfElems=getNbOfElems();
2848   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
2849     {
2850       if(std::abs(*ptr)>std::numeric_limits<double>::min())
2851         {
2852           *ptr=numerator/(*ptr);
2853         }
2854       else
2855         {
2856           std::ostringstream oss; oss << "DataArrayDouble::applyInv : presence of null value in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
2857           oss << " !";
2858           throw INTERP_KERNEL::Exception(oss.str().c_str());
2859         }
2860     }
2861   declareAsNew();
2862 }
2863
2864 /*!
2865  * Returns a full copy of \a this array except that sign of all elements is reversed.
2866  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2867  *          same number of tuples and component as \a this array.
2868  *          The caller is to delete this result array using decrRef() as it is no more
2869  *          needed.
2870  *  \throw If \a this is not allocated.
2871  */
2872 DataArrayDouble *DataArrayDouble::negate() const
2873 {
2874   checkAllocated();
2875   DataArrayDouble *newArr=DataArrayDouble::New();
2876   int nbOfTuples=getNumberOfTuples();
2877   int nbOfComp=getNumberOfComponents();
2878   newArr->alloc(nbOfTuples,nbOfComp);
2879   const double *cptr=getConstPointer();
2880   std::transform(cptr,cptr+nbOfTuples*nbOfComp,newArr->getPointer(),std::negate<double>());
2881   newArr->copyStringInfoFrom(*this);
2882   return newArr;
2883 }
2884
2885 /*!
2886  * Modify all elements of \a this array, so that
2887  * an element _x_ becomes <em> val ^ x </em>. Contrary to DataArrayInt::applyPow
2888  * all values in \a this have to be >= 0 if val is \b not integer.
2889  *  \param [in] val - the value used to apply pow on all array elements.
2890  *  \throw If \a this is not allocated.
2891  *  \warning If an exception is thrown because of presence of 0 element in \a this 
2892  *           array and \a val is \b not integer, all elements processed before detection of the zero element remain
2893  *           modified.
2894  */
2895 void DataArrayDouble::applyPow(double val)
2896 {
2897   checkAllocated();
2898   double *ptr=getPointer();
2899   std::size_t nbOfElems=getNbOfElems();
2900   int val2=(int)val;
2901   bool isInt=((double)val2)==val;
2902   if(!isInt)
2903     {
2904       for(std::size_t i=0;i<nbOfElems;i++,ptr++)
2905         {
2906           if(*ptr>=0)
2907             *ptr=pow(*ptr,val);
2908           else
2909             {
2910               std::ostringstream oss; oss << "DataArrayDouble::applyPow (double) : At elem # " << i << " value is " << *ptr << " ! must be >=0. !";
2911               throw INTERP_KERNEL::Exception(oss.str().c_str());
2912             }
2913         }
2914     }
2915   else
2916     {
2917       for(std::size_t i=0;i<nbOfElems;i++,ptr++)
2918         *ptr=pow(*ptr,val2);
2919     }
2920   declareAsNew();
2921 }
2922
2923 /*!
2924  * Modify all elements of \a this array, so that
2925  * an element _x_ becomes \f$ val ^ x \f$.
2926  *  \param [in] val - the value used to apply pow on all array elements.
2927  *  \throw If \a this is not allocated.
2928  *  \throw If \a val < 0.
2929  *  \warning If an exception is thrown because of presence of 0 element in \a this 
2930  *           array, all elements processed before detection of the zero element remain
2931  *           modified.
2932  */
2933 void DataArrayDouble::applyRPow(double val)
2934 {
2935   checkAllocated();
2936   if(val<0.)
2937     throw INTERP_KERNEL::Exception("DataArrayDouble::applyRPow : the input value has to be >= 0 !");
2938   double *ptr=getPointer();
2939   std::size_t nbOfElems=getNbOfElems();
2940   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
2941     *ptr=pow(val,*ptr);
2942   declareAsNew();
2943 }
2944
2945 /*!
2946  * Returns a new DataArrayDouble created from \a this one by applying \a
2947  * FunctionToEvaluate to every tuple of \a this array. Textual data is not copied.
2948  * For more info see \ref MEDCouplingArrayApplyFunc
2949  *  \param [in] nbOfComp - number of components in the result array.
2950  *  \param [in] func - the \a FunctionToEvaluate declared as 
2951  *              \c bool (*\a func)(\c const \c double *\a pos, \c double *\a res), 
2952  *              where \a pos points to the first component of a tuple of \a this array
2953  *              and \a res points to the first component of a tuple of the result array.
2954  *              Note that length (number of components) of \a pos can differ from
2955  *              that of \a res.
2956  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2957  *          same number of tuples as \a this array.
2958  *          The caller is to delete this result array using decrRef() as it is no more
2959  *          needed.
2960  *  \throw If \a this is not allocated.
2961  *  \throw If \a func returns \a false.
2962  */
2963 DataArrayDouble *DataArrayDouble::applyFunc(int nbOfComp, FunctionToEvaluate func) const
2964 {
2965   checkAllocated();
2966   DataArrayDouble *newArr=DataArrayDouble::New();
2967   int nbOfTuples=getNumberOfTuples();
2968   int oldNbOfComp=getNumberOfComponents();
2969   newArr->alloc(nbOfTuples,nbOfComp);
2970   const double *ptr=getConstPointer();
2971   double *ptrToFill=newArr->getPointer();
2972   for(int i=0;i<nbOfTuples;i++)
2973     {
2974       if(!func(ptr+i*oldNbOfComp,ptrToFill+i*nbOfComp))
2975         {
2976           std::ostringstream oss; oss << "For tuple # " << i << " with value (";
2977           std::copy(ptr+oldNbOfComp*i,ptr+oldNbOfComp*(i+1),std::ostream_iterator<double>(oss,", "));
2978           oss << ") : Evaluation of function failed !";
2979           newArr->decrRef();
2980           throw INTERP_KERNEL::Exception(oss.str().c_str());
2981         }
2982     }
2983   return newArr;
2984 }
2985
2986 /*!
2987  * Returns a new DataArrayDouble created from \a this one by applying a function to every
2988  * tuple of \a this array. Textual data is not copied.
2989  * For more info see \ref MEDCouplingArrayApplyFunc1.
2990  *  \param [in] nbOfComp - number of components in the result array.
2991  *  \param [in] func - the expression defining how to transform a tuple of \a this array.
2992  *              Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
2993  *  \param [in] isSafe - By default true. If true invalid operation (division by 0. acos of value > 1. ...) leads to a throw of an exception.
2994  *              If false the computation is carried on without any notification. When false the evaluation is a little faster.
2995  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2996  *          same number of tuples as \a this array and \a nbOfComp components.
2997  *          The caller is to delete this result array using decrRef() as it is no more
2998  *          needed.
2999  *  \throw If \a this is not allocated.
3000  *  \throw If computing \a func fails.
3001  */
3002 DataArrayDouble *DataArrayDouble::applyFunc(int nbOfComp, const std::string& func, bool isSafe) const
3003 {
3004   INTERP_KERNEL::ExprParser expr(func);
3005   expr.parse();
3006   std::set<std::string> vars;
3007   expr.getTrueSetOfVars(vars);
3008   std::vector<std::string> varsV(vars.begin(),vars.end());
3009   return applyFuncNamedCompo(nbOfComp,varsV,func,isSafe);
3010 }
3011
3012 /*!
3013  * Returns a new DataArrayDouble created from \a this one by applying a function to every
3014  * tuple of \a this array. Textual data is not copied. This method works by tuples (whatever its size).
3015  * If \a this is a one component array, call applyFuncOnThis instead that performs the same work faster.
3016  *
3017  * For more info see \ref MEDCouplingArrayApplyFunc0.
3018  *  \param [in] func - the expression defining how to transform a tuple of \a this array.
3019  *              Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
3020  *  \param [in] isSafe - By default true. If true invalid operation (division by 0. acos of value > 1. ...) leads to a throw of an exception.
3021  *                       If false the computation is carried on without any notification. When false the evaluation is a little faster.
3022  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
3023  *          same number of tuples and components as \a this array.
3024  *          The caller is to delete this result array using decrRef() as it is no more
3025  *          needed.
3026  *  \sa applyFuncOnThis
3027  *  \throw If \a this is not allocated.
3028  *  \throw If computing \a func fails.
3029  */
3030 DataArrayDouble *DataArrayDouble::applyFunc(const std::string& func, bool isSafe) const
3031 {
3032   int nbOfComp(getNumberOfComponents());
3033   if(nbOfComp<=0)
3034     throw INTERP_KERNEL::Exception("DataArrayDouble::applyFunc : output number of component must be > 0 !");
3035   checkAllocated();
3036   int nbOfTuples(getNumberOfTuples());
3037   MCAuto<DataArrayDouble> newArr(DataArrayDouble::New());
3038   newArr->alloc(nbOfTuples,nbOfComp);
3039   INTERP_KERNEL::ExprParser expr(func);
3040   expr.parse();
3041   std::set<std::string> vars;
3042   expr.getTrueSetOfVars(vars);
3043   if((int)vars.size()>1)
3044     {
3045       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 : ";
3046       std::copy(vars.begin(),vars.end(),std::ostream_iterator<std::string>(oss," "));
3047       throw INTERP_KERNEL::Exception(oss.str().c_str());
3048     }
3049   if(vars.empty())
3050     {
3051       expr.prepareFastEvaluator();
3052       newArr->rearrange(1);
3053       newArr->fillWithValue(expr.evaluateDouble());
3054       newArr->rearrange(nbOfComp);
3055       return newArr.retn();
3056     }
3057   std::vector<std::string> vars2(vars.begin(),vars.end());
3058   double buff,*ptrToFill(newArr->getPointer());
3059   const double *ptr(begin());
3060   std::vector<double> stck;
3061   expr.prepareExprEvaluationDouble(vars2,1,1,0,&buff,&buff+1);
3062   expr.prepareFastEvaluator();
3063   if(!isSafe)
3064     {
3065       for(int i=0;i<nbOfTuples;i++)
3066         {
3067           for(int iComp=0;iComp<nbOfComp;iComp++,ptr++,ptrToFill++)
3068             {
3069               buff=*ptr;
3070               expr.evaluateDoubleInternal(stck);
3071               *ptrToFill=stck.back();
3072               stck.pop_back();
3073             }
3074         }
3075     }
3076   else
3077     {
3078       for(int i=0;i<nbOfTuples;i++)
3079         {
3080           for(int iComp=0;iComp<nbOfComp;iComp++,ptr++,ptrToFill++)
3081             {
3082               buff=*ptr;
3083               try
3084               {
3085                   expr.evaluateDoubleInternalSafe(stck);
3086               }
3087               catch(INTERP_KERNEL::Exception& e)
3088               {
3089                   std::ostringstream oss; oss << "For tuple # " << i << " component # " << iComp << " with value (";
3090                   oss << buff;
3091                   oss << ") : Evaluation of function failed !" << e.what();
3092                   throw INTERP_KERNEL::Exception(oss.str().c_str());
3093               }
3094               *ptrToFill=stck.back();
3095               stck.pop_back();
3096             }
3097         }
3098     }
3099   return newArr.retn();
3100 }
3101
3102 /*!
3103  * This method is a non const method that modify the array in \a this.
3104  * This method only works on one component array. It means that function \a func must
3105  * contain at most one variable.
3106  * This method is a specialization of applyFunc method with one parameter on one component array.
3107  *
3108  *  \param [in] func - the expression defining how to transform a tuple of \a this array.
3109  *              Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
3110  *  \param [in] isSafe - By default true. If true invalid operation (division by 0. acos of value > 1. ...) leads to a throw of an exception.
3111  *              If false the computation is carried on without any notification. When false the evaluation is a little faster.
3112  *
3113  * \sa applyFunc
3114  */
3115 void DataArrayDouble::applyFuncOnThis(const std::string& func, bool isSafe)
3116 {
3117   int nbOfComp(getNumberOfComponents());
3118   if(nbOfComp<=0)
3119     throw INTERP_KERNEL::Exception("DataArrayDouble::applyFuncOnThis : output number of component must be > 0 !");
3120   checkAllocated();
3121   int nbOfTuples(getNumberOfTuples());
3122   INTERP_KERNEL::ExprParser expr(func);
3123   expr.parse();
3124   std::set<std::string> vars;
3125   expr.getTrueSetOfVars(vars);
3126   if((int)vars.size()>1)
3127     {
3128       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 : ";
3129       std::copy(vars.begin(),vars.end(),std::ostream_iterator<std::string>(oss," "));
3130       throw INTERP_KERNEL::Exception(oss.str().c_str());
3131     }
3132   if(vars.empty())
3133     {
3134       expr.prepareFastEvaluator();
3135       std::vector<std::string> compInfo(getInfoOnComponents());
3136       rearrange(1);
3137       fillWithValue(expr.evaluateDouble());
3138       rearrange(nbOfComp);
3139       setInfoOnComponents(compInfo);
3140       return ;
3141     }
3142   std::vector<std::string> vars2(vars.begin(),vars.end());
3143   double buff,*ptrToFill(getPointer());
3144   const double *ptr(begin());
3145   std::vector<double> stck;
3146   expr.prepareExprEvaluationDouble(vars2,1,1,0,&buff,&buff+1);
3147   expr.prepareFastEvaluator();
3148   if(!isSafe)
3149     {
3150       for(int i=0;i<nbOfTuples;i++)
3151         {
3152           for(int iComp=0;iComp<nbOfComp;iComp++,ptr++,ptrToFill++)
3153             {
3154               buff=*ptr;
3155               expr.evaluateDoubleInternal(stck);
3156               *ptrToFill=stck.back();
3157               stck.pop_back();
3158             }
3159         }
3160     }
3161   else
3162     {
3163       for(int i=0;i<nbOfTuples;i++)
3164         {
3165           for(int iComp=0;iComp<nbOfComp;iComp++,ptr++,ptrToFill++)
3166             {
3167               buff=*ptr;
3168               try
3169               {
3170                   expr.evaluateDoubleInternalSafe(stck);
3171               }
3172               catch(INTERP_KERNEL::Exception& e)
3173               {
3174                   std::ostringstream oss; oss << "For tuple # " << i << " component # " << iComp << " with value (";
3175                   oss << buff;
3176                   oss << ") : Evaluation of function failed !" << e.what();
3177                   throw INTERP_KERNEL::Exception(oss.str().c_str());
3178               }
3179               *ptrToFill=stck.back();
3180               stck.pop_back();
3181             }
3182         }
3183     }
3184 }
3185
3186 /*!
3187  * Returns a new DataArrayDouble created from \a this one by applying a function to every
3188  * tuple of \a this array. Textual data is not copied.
3189  * For more info see \ref MEDCouplingArrayApplyFunc2.
3190  *  \param [in] nbOfComp - number of components in the result array.
3191  *  \param [in] func - the expression defining how to transform a tuple of \a this array.
3192  *              Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
3193  *  \param [in] isSafe - By default true. If true invalid operation (division by 0. acos of value > 1. ...) leads to a throw of an exception.
3194  *              If false the computation is carried on without any notification. When false the evaluation is a little faster.
3195  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
3196  *          same number of tuples as \a this array.
3197  *          The caller is to delete this result array using decrRef() as it is no more
3198  *          needed.
3199  *  \throw If \a this is not allocated.
3200  *  \throw If \a func contains vars that are not in \a this->getInfoOnComponent().
3201  *  \throw If computing \a func fails.
3202  */
3203 DataArrayDouble *DataArrayDouble::applyFuncCompo(int nbOfComp, const std::string& func, bool isSafe) const
3204 {
3205   return applyFuncNamedCompo(nbOfComp,getVarsOnComponent(),func,isSafe);
3206 }
3207
3208 /*!
3209  * Returns a new DataArrayDouble created from \a this one by applying a function to every
3210  * tuple of \a this array. Textual data is not copied.
3211  * For more info see \ref MEDCouplingArrayApplyFunc3.
3212  *  \param [in] nbOfComp - number of components in the result array.
3213  *  \param [in] varsOrder - sequence of vars defining their order.
3214  *  \param [in] func - the expression defining how to transform a tuple of \a this array.
3215  *              Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
3216  *  \param [in] isSafe - By default true. If true invalid operation (division by 0. acos of value > 1. ...) leads to a throw of an exception.
3217  *              If false the computation is carried on without any notification. When false the evaluation is a little faster.
3218  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
3219  *          same number of tuples as \a this array.
3220  *          The caller is to delete this result array using decrRef() as it is no more
3221  *          needed.
3222  *  \throw If \a this is not allocated.
3223  *  \throw If \a func contains vars not in \a varsOrder.
3224  *  \throw If computing \a func fails.
3225  */
3226 DataArrayDouble *DataArrayDouble::applyFuncNamedCompo(int nbOfComp, const std::vector<std::string>& varsOrder, const std::string& func, bool isSafe) const
3227 {
3228   if(nbOfComp<=0)
3229     throw INTERP_KERNEL::Exception("DataArrayDouble::applyFuncNamedCompo : output number of component must be > 0 !");
3230   std::vector<std::string> varsOrder2(varsOrder);
3231   int oldNbOfComp(getNumberOfComponents());
3232   for(int i=(int)varsOrder.size();i<oldNbOfComp;i++)
3233     varsOrder2.push_back(std::string());
3234   checkAllocated();
3235   int nbOfTuples(getNumberOfTuples());
3236   INTERP_KERNEL::ExprParser expr(func);
3237   expr.parse();
3238   std::set<std::string> vars;
3239   expr.getTrueSetOfVars(vars);
3240   if((int)vars.size()>oldNbOfComp)
3241     {
3242       std::ostringstream oss; oss << "The field has " << oldNbOfComp << " components and there are ";
3243       oss << vars.size() << " variables : ";
3244       std::copy(vars.begin(),vars.end(),std::ostream_iterator<std::string>(oss," "));
3245       throw INTERP_KERNEL::Exception(oss.str().c_str());
3246     }
3247   MCAuto<DataArrayDouble> newArr(DataArrayDouble::New());
3248   newArr->alloc(nbOfTuples,nbOfComp);
3249   INTERP_KERNEL::AutoPtr<double> buff(new double[oldNbOfComp]);
3250   double *buffPtr(buff),*ptrToFill;
3251   std::vector<double> stck;
3252   for(int iComp=0;iComp<nbOfComp;iComp++)
3253     {
3254       expr.prepareExprEvaluationDouble(varsOrder2,oldNbOfComp,nbOfComp,iComp,buffPtr,buffPtr+oldNbOfComp);
3255       expr.prepareFastEvaluator();
3256       const double *ptr(getConstPointer());
3257       ptrToFill=newArr->getPointer()+iComp;
3258       if(!isSafe)
3259         {
3260           for(int i=0;i<nbOfTuples;i++,ptrToFill+=nbOfComp,ptr+=oldNbOfComp)
3261             {
3262               std::copy(ptr,ptr+oldNbOfComp,buffPtr);
3263               expr.evaluateDoubleInternal(stck);
3264               *ptrToFill=stck.back();
3265               stck.pop_back();
3266             }
3267         }
3268       else
3269         {
3270           for(int i=0;i<nbOfTuples;i++,ptrToFill+=nbOfComp,ptr+=oldNbOfComp)
3271             {
3272               std::copy(ptr,ptr+oldNbOfComp,buffPtr);
3273               try
3274               {
3275                   expr.evaluateDoubleInternalSafe(stck);
3276                   *ptrToFill=stck.back();
3277                   stck.pop_back();
3278               }
3279               catch(INTERP_KERNEL::Exception& e)
3280               {
3281                   std::ostringstream oss; oss << "For tuple # " << i << " with value (";
3282                   std::copy(ptr+oldNbOfComp*i,ptr+oldNbOfComp*(i+1),std::ostream_iterator<double>(oss,", "));
3283                   oss << ") : Evaluation of function failed !" << e.what();
3284                   throw INTERP_KERNEL::Exception(oss.str().c_str());
3285               }
3286             }
3287         }
3288     }
3289   return newArr.retn();
3290 }
3291
3292 void DataArrayDouble::applyFuncFast32(const std::string& func)
3293 {
3294   checkAllocated();
3295   INTERP_KERNEL::ExprParser expr(func);
3296   expr.parse();
3297   char *funcStr=expr.compileX86();
3298   MYFUNCPTR funcPtr;
3299   *((void **)&funcPtr)=funcStr;//he he...
3300   //
3301   double *ptr=getPointer();
3302   int nbOfComp=getNumberOfComponents();
3303   int nbOfTuples=getNumberOfTuples();
3304   int nbOfElems=nbOfTuples*nbOfComp;
3305   for(int i=0;i<nbOfElems;i++,ptr++)
3306     *ptr=funcPtr(*ptr);
3307   declareAsNew();
3308 }
3309
3310 void DataArrayDouble::applyFuncFast64(const std::string& func)
3311 {
3312   checkAllocated();
3313   INTERP_KERNEL::ExprParser expr(func);
3314   expr.parse();
3315   char *funcStr=expr.compileX86_64();
3316   MYFUNCPTR funcPtr;
3317   *((void **)&funcPtr)=funcStr;//he he...
3318   //
3319   double *ptr=getPointer();
3320   int nbOfComp=getNumberOfComponents();
3321   int nbOfTuples=getNumberOfTuples();
3322   int nbOfElems=nbOfTuples*nbOfComp;
3323   for(int i=0;i<nbOfElems;i++,ptr++)
3324     *ptr=funcPtr(*ptr);
3325   declareAsNew();
3326 }
3327
3328 /*!
3329  * \return a new object that is the result of the symmetry along 3D plane defined by its normal vector \a normalVector and a point \a point.
3330  */
3331 MCAuto<DataArrayDouble> DataArrayDouble::symmetry3DPlane(const double point[3], const double normalVector[3]) const
3332 {
3333   checkAllocated();
3334   if(getNumberOfComponents()!=3)
3335     throw INTERP_KERNEL::Exception("DataArrayDouble::symmetry3DPlane : this is excepted to have 3 components !");
3336   int nbTuples(getNumberOfTuples());
3337   MCAuto<DataArrayDouble> ret(DataArrayDouble::New());
3338   ret->alloc(nbTuples,3);
3339   Symmetry3DPlane(point,normalVector,nbTuples,begin(),ret->getPointer());
3340   return ret;
3341 }
3342
3343 DataArrayDoubleIterator *DataArrayDouble::iterator()
3344 {
3345   return new DataArrayDoubleIterator(this);
3346 }
3347
3348 /*!
3349  * Returns a new DataArrayInt contating indices of tuples of \a this one-dimensional
3350  * array whose values are within a given range. Textual data is not copied.
3351  *  \param [in] vmin - a lowest acceptable value (included).
3352  *  \param [in] vmax - a greatest acceptable value (included).
3353  *  \return DataArrayInt * - the new instance of DataArrayInt.
3354  *          The caller is to delete this result array using decrRef() as it is no more
3355  *          needed.
3356  *  \throw If \a this->getNumberOfComponents() != 1.
3357  *
3358  *  \sa DataArrayDouble::findIdsNotInRange
3359  *
3360  *  \if ENABLE_EXAMPLES
3361  *  \ref cpp_mcdataarraydouble_getidsinrange "Here is a C++ example".<br>
3362  *  \ref py_mcdataarraydouble_getidsinrange "Here is a Python example".
3363  *  \endif
3364  */
3365 DataArrayInt *DataArrayDouble::findIdsInRange(double vmin, double vmax) const
3366 {
3367   checkAllocated();
3368   if(getNumberOfComponents()!=1)
3369     throw INTERP_KERNEL::Exception("DataArrayDouble::findIdsInRange : this must have exactly one component !");
3370   const double *cptr(begin());
3371   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
3372   int nbOfTuples(getNumberOfTuples());
3373   for(int i=0;i<nbOfTuples;i++,cptr++)
3374     if(*cptr>=vmin && *cptr<=vmax)
3375       ret->pushBackSilent(i);
3376   return ret.retn();
3377 }
3378
3379 /*!
3380  * Returns a new DataArrayInt contating indices of tuples of \a this one-dimensional
3381  * array whose values are not within a given range. Textual data is not copied.
3382  *  \param [in] vmin - a lowest not acceptable value (excluded).
3383  *  \param [in] vmax - a greatest not acceptable value (excluded).
3384  *  \return DataArrayInt * - the new instance of DataArrayInt.
3385  *          The caller is to delete this result array using decrRef() as it is no more
3386  *          needed.
3387  *  \throw If \a this->getNumberOfComponents() != 1.
3388  *
3389  *  \sa DataArrayDouble::findIdsInRange
3390  */
3391 DataArrayInt *DataArrayDouble::findIdsNotInRange(double vmin, double vmax) const
3392 {
3393   checkAllocated();
3394   if(getNumberOfComponents()!=1)
3395     throw INTERP_KERNEL::Exception("DataArrayDouble::findIdsNotInRange : this must have exactly one component !");
3396   const double *cptr(begin());
3397   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
3398   int nbOfTuples(getNumberOfTuples());
3399   for(int i=0;i<nbOfTuples;i++,cptr++)
3400     if(*cptr<vmin || *cptr>vmax)
3401       ret->pushBackSilent(i);
3402   return ret.retn();
3403 }
3404
3405 /*!
3406  * Returns a new DataArrayDouble by concatenating two given arrays, so that (1) the number
3407  * of tuples in the result array is a sum of the number of tuples of given arrays and (2)
3408  * the number of component in the result array is same as that of each of given arrays.
3409  * Info on components is copied from the first of the given arrays. Number of components
3410  * in the given arrays must be  the same.
3411  *  \param [in] a1 - an array to include in the result array.
3412  *  \param [in] a2 - another array to include in the result array.
3413  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
3414  *          The caller is to delete this result array using decrRef() as it is no more
3415  *          needed.
3416  *  \throw If both \a a1 and \a a2 are NULL.
3417  *  \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents().
3418  */
3419 DataArrayDouble *DataArrayDouble::Aggregate(const DataArrayDouble *a1, const DataArrayDouble *a2)
3420 {
3421   std::vector<const DataArrayDouble *> tmp(2);
3422   tmp[0]=a1; tmp[1]=a2;
3423   return Aggregate(tmp);
3424 }
3425
3426 /*!
3427  * Returns a new DataArrayDouble by concatenating all given arrays, so that (1) the number
3428  * of tuples in the result array is a sum of the number of tuples of given arrays and (2)
3429  * the number of component in the result array is same as that of each of given arrays.
3430  * Info on components is copied from the first of the given arrays. Number of components
3431  * in the given arrays must be  the same.
3432  * If the number of non null of elements in \a arr is equal to one the returned object is a copy of it
3433  * not the object itself.
3434  *  \param [in] arr - a sequence of arrays to include in the result array.
3435  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
3436  *          The caller is to delete this result array using decrRef() as it is no more
3437  *          needed.
3438  *  \throw If all arrays within \a arr are NULL.
3439  *  \throw If getNumberOfComponents() of arrays within \a arr.
3440  */
3441 DataArrayDouble *DataArrayDouble::Aggregate(const std::vector<const DataArrayDouble *>& arr)
3442 {
3443   std::vector<const DataArrayDouble *> a;
3444   for(std::vector<const DataArrayDouble *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
3445     if(*it4)
3446       a.push_back(*it4);
3447   if(a.empty())
3448     throw INTERP_KERNEL::Exception("DataArrayDouble::Aggregate : input list must contain at least one NON EMPTY DataArrayDouble !");
3449   std::vector<const DataArrayDouble *>::const_iterator it=a.begin();
3450   int nbOfComp=(*it)->getNumberOfComponents();
3451   int nbt=(*it++)->getNumberOfTuples();
3452   for(int i=1;it!=a.end();it++,i++)
3453     {
3454       if((*it)->getNumberOfComponents()!=nbOfComp)
3455         throw INTERP_KERNEL::Exception("DataArrayDouble::Aggregate : Nb of components mismatch for array aggregation !");
3456       nbt+=(*it)->getNumberOfTuples();
3457     }
3458   MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
3459   ret->alloc(nbt,nbOfComp);
3460   double *pt=ret->getPointer();
3461   for(it=a.begin();it!=a.end();it++)
3462     pt=std::copy((*it)->getConstPointer(),(*it)->getConstPointer()+(*it)->getNbOfElems(),pt);
3463   ret->copyStringInfoFrom(*(a[0]));
3464   return ret.retn();
3465 }
3466
3467 /*!
3468  * Returns a new DataArrayDouble by aggregating two given arrays, so that (1) the number
3469  * of components in the result array is a sum of the number of components of given arrays
3470  * and (2) the number of tuples in the result array is same as that of each of given
3471  * arrays. In other words the i-th tuple of result array includes all components of
3472  * i-th tuples of all given arrays.
3473  * Number of tuples in the given arrays must be  the same.
3474  *  \param [in] a1 - an array to include in the result array.
3475  *  \param [in] a2 - another array to include in the result array.
3476  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
3477  *          The caller is to delete this result array using decrRef() as it is no more
3478  *          needed.
3479  *  \throw If both \a a1 and \a a2 are NULL.
3480  *  \throw If any given array is not allocated.
3481  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
3482  */
3483 DataArrayDouble *DataArrayDouble::Meld(const DataArrayDouble *a1, const DataArrayDouble *a2)
3484 {
3485   std::vector<const DataArrayDouble *> arr(2);
3486   arr[0]=a1; arr[1]=a2;
3487   return Meld(arr);
3488 }
3489
3490 /*!
3491  * Returns a new DataArrayDouble by aggregating all given arrays, so that (1) the number
3492  * of components in the result array is a sum of the number of components of given arrays
3493  * and (2) the number of tuples in the result array is same as that of each of given
3494  * arrays. In other words the i-th tuple of result array includes all components of
3495  * i-th tuples of all given arrays.
3496  * Number of tuples in the given arrays must be  the same.
3497  *  \param [in] arr - a sequence of arrays to include in the result array.
3498  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
3499  *          The caller is to delete this result array using decrRef() as it is no more
3500  *          needed.
3501  *  \throw If all arrays within \a arr are NULL.
3502  *  \throw If any given array is not allocated.
3503  *  \throw If getNumberOfTuples() of arrays within \a arr is different.
3504  */
3505 DataArrayDouble *DataArrayDouble::Meld(const std::vector<const DataArrayDouble *>& arr)
3506 {
3507   std::vector<const DataArrayDouble *> a;
3508   for(std::vector<const DataArrayDouble *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
3509     if(*it4)
3510       a.push_back(*it4);
3511   if(a.empty())
3512     throw INTERP_KERNEL::Exception("DataArrayDouble::Meld : input list must contain at least one NON EMPTY DataArrayDouble !");
3513   std::vector<const DataArrayDouble *>::const_iterator it;
3514   for(it=a.begin();it!=a.end();it++)
3515     (*it)->checkAllocated();
3516   it=a.begin();
3517   int nbOfTuples=(*it)->getNumberOfTuples();
3518   std::vector<int> nbc(a.size());
3519   std::vector<const double *> pts(a.size());
3520   nbc[0]=(*it)->getNumberOfComponents();
3521   pts[0]=(*it++)->getConstPointer();
3522   for(int i=1;it!=a.end();it++,i++)
3523     {
3524       if(nbOfTuples!=(*it)->getNumberOfTuples())
3525         throw INTERP_KERNEL::Exception("DataArrayDouble::Meld : mismatch of number of tuples !");
3526       nbc[i]=(*it)->getNumberOfComponents();
3527       pts[i]=(*it)->getConstPointer();
3528     }
3529   int totalNbOfComp=std::accumulate(nbc.begin(),nbc.end(),0);
3530   DataArrayDouble *ret=DataArrayDouble::New();
3531   ret->alloc(nbOfTuples,totalNbOfComp);
3532   double *retPtr=ret->getPointer();
3533   for(int i=0;i<nbOfTuples;i++)
3534     for(int j=0;j<(int)a.size();j++)
3535       {
3536         retPtr=std::copy(pts[j],pts[j]+nbc[j],retPtr);
3537         pts[j]+=nbc[j];
3538       }
3539   int k=0;
3540   for(int i=0;i<(int)a.size();i++)
3541     for(int j=0;j<nbc[i];j++,k++)
3542       ret->setInfoOnComponent(k,a[i]->getInfoOnComponent(j));
3543   return ret;
3544 }
3545
3546 /*!
3547  * Returns a new DataArrayDouble containing a dot product of two given arrays, so that
3548  * the i-th tuple of the result array is a sum of products of j-th components of i-th
3549  * tuples of given arrays (\f$ a_i = \sum_{j=1}^n a1_j * a2_j \f$).
3550  * Info on components and name is copied from the first of the given arrays.
3551  * Number of tuples and components in the given arrays must be the same.
3552  *  \param [in] a1 - a given array.
3553  *  \param [in] a2 - another given array.
3554  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
3555  *          The caller is to delete this result array using decrRef() as it is no more
3556  *          needed.
3557  *  \throw If either \a a1 or \a a2 is NULL.
3558  *  \throw If any given array is not allocated.
3559  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
3560  *  \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents()
3561  */
3562 DataArrayDouble *DataArrayDouble::Dot(const DataArrayDouble *a1, const DataArrayDouble *a2)
3563 {
3564   if(!a1 || !a2)
3565     throw INTERP_KERNEL::Exception("DataArrayDouble::Dot : input DataArrayDouble instance is NULL !");
3566   a1->checkAllocated();
3567   a2->checkAllocated();
3568   int nbOfComp=a1->getNumberOfComponents();
3569   if(nbOfComp!=a2->getNumberOfComponents())
3570     throw INTERP_KERNEL::Exception("Nb of components mismatch for array Dot !");
3571   int nbOfTuple=a1->getNumberOfTuples();
3572   if(nbOfTuple!=a2->getNumberOfTuples())
3573     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Dot !");
3574   DataArrayDouble *ret=DataArrayDouble::New();
3575   ret->alloc(nbOfTuple,1);
3576   double *retPtr=ret->getPointer();
3577   const double *a1Ptr=a1->getConstPointer();
3578   const double *a2Ptr=a2->getConstPointer();
3579   for(int i=0;i<nbOfTuple;i++)
3580     {
3581       double sum=0.;
3582       for(int j=0;j<nbOfComp;j++)
3583         sum+=a1Ptr[i*nbOfComp+j]*a2Ptr[i*nbOfComp+j];
3584       retPtr[i]=sum;
3585     }
3586   ret->setInfoOnComponent(0,a1->getInfoOnComponent(0));
3587   ret->setName(a1->getName());
3588   return ret;
3589 }
3590
3591 /*!
3592  * Returns a new DataArrayDouble containing a cross product of two given arrays, so that
3593  * the i-th tuple of the result array contains 3 components of a vector which is a cross
3594  * product of two vectors defined by the i-th tuples of given arrays.
3595  * Info on components is copied from the first of the given arrays.
3596  * Number of tuples in the given arrays must be the same.
3597  * Number of components in the given arrays must be 3.
3598  *  \param [in] a1 - a given array.
3599  *  \param [in] a2 - another given array.
3600  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
3601  *          The caller is to delete this result array using decrRef() as it is no more
3602  *          needed.
3603  *  \throw If either \a a1 or \a a2 is NULL.
3604  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
3605  *  \throw If \a a1->getNumberOfComponents() != 3
3606  *  \throw If \a a2->getNumberOfComponents() != 3
3607  */
3608 DataArrayDouble *DataArrayDouble::CrossProduct(const DataArrayDouble *a1, const DataArrayDouble *a2)
3609 {
3610   if(!a1 || !a2)
3611     throw INTERP_KERNEL::Exception("DataArrayDouble::CrossProduct : input DataArrayDouble instance is NULL !");
3612   int nbOfComp=a1->getNumberOfComponents();
3613   if(nbOfComp!=a2->getNumberOfComponents())
3614     throw INTERP_KERNEL::Exception("Nb of components mismatch for array crossProduct !");
3615   if(nbOfComp!=3)
3616     throw INTERP_KERNEL::Exception("Nb of components must be equal to 3 for array crossProduct !");
3617   int nbOfTuple=a1->getNumberOfTuples();
3618   if(nbOfTuple!=a2->getNumberOfTuples())
3619     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array crossProduct !");
3620   DataArrayDouble *ret=DataArrayDouble::New();
3621   ret->alloc(nbOfTuple,3);
3622   double *retPtr=ret->getPointer();
3623   const double *a1Ptr=a1->getConstPointer();
3624   const double *a2Ptr=a2->getConstPointer();
3625   for(int i=0;i<nbOfTuple;i++)
3626     {
3627       retPtr[3*i]=a1Ptr[3*i+1]*a2Ptr[3*i+2]-a1Ptr[3*i+2]*a2Ptr[3*i+1];
3628       retPtr[3*i+1]=a1Ptr[3*i+2]*a2Ptr[3*i]-a1Ptr[3*i]*a2Ptr[3*i+2];
3629       retPtr[3*i+2]=a1Ptr[3*i]*a2Ptr[3*i+1]-a1Ptr[3*i+1]*a2Ptr[3*i];
3630     }
3631   ret->copyStringInfoFrom(*a1);
3632   return ret;
3633 }
3634
3635 /*!
3636  * Returns a new DataArrayDouble containing maximal values of two given arrays.
3637  * Info on components is copied from the first of the given arrays.
3638  * Number of tuples and components in the given arrays must be the same.
3639  *  \param [in] a1 - an array to compare values with another one.
3640  *  \param [in] a2 - another array to compare values with the first one.
3641  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
3642  *          The caller is to delete this result array using decrRef() as it is no more
3643  *          needed.
3644  *  \throw If either \a a1 or \a a2 is NULL.
3645  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
3646  *  \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents()
3647  */
3648 DataArrayDouble *DataArrayDouble::Max(const DataArrayDouble *a1, const DataArrayDouble *a2)
3649 {
3650   if(!a1 || !a2)
3651     throw INTERP_KERNEL::Exception("DataArrayDouble::Max : input DataArrayDouble instance is NULL !");
3652   int nbOfComp=a1->getNumberOfComponents();
3653   if(nbOfComp!=a2->getNumberOfComponents())
3654     throw INTERP_KERNEL::Exception("Nb of components mismatch for array Max !");
3655   int nbOfTuple=a1->getNumberOfTuples();
3656   if(nbOfTuple!=a2->getNumberOfTuples())
3657     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Max !");
3658   DataArrayDouble *ret=DataArrayDouble::New();
3659   ret->alloc(nbOfTuple,nbOfComp);
3660   double *retPtr=ret->getPointer();
3661   const double *a1Ptr=a1->getConstPointer();
3662   const double *a2Ptr=a2->getConstPointer();
3663   int nbElem=nbOfTuple*nbOfComp;
3664   for(int i=0;i<nbElem;i++)
3665     retPtr[i]=std::max(a1Ptr[i],a2Ptr[i]);
3666   ret->copyStringInfoFrom(*a1);
3667   return ret;
3668 }
3669
3670 /*!
3671  * Returns a new DataArrayDouble containing minimal values of two given arrays.
3672  * Info on components is copied from the first of the given arrays.
3673  * Number of tuples and components in the given arrays must be the same.
3674  *  \param [in] a1 - an array to compare values with another one.
3675  *  \param [in] a2 - another array to compare values with the first one.
3676  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
3677  *          The caller is to delete this result array using decrRef() as it is no more
3678  *          needed.
3679  *  \throw If either \a a1 or \a a2 is NULL.
3680  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
3681  *  \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents()
3682  */
3683 DataArrayDouble *DataArrayDouble::Min(const DataArrayDouble *a1, const DataArrayDouble *a2)
3684 {
3685   if(!a1 || !a2)
3686     throw INTERP_KERNEL::Exception("DataArrayDouble::Min : input DataArrayDouble instance is NULL !");
3687   int nbOfComp=a1->getNumberOfComponents();
3688   if(nbOfComp!=a2->getNumberOfComponents())
3689     throw INTERP_KERNEL::Exception("Nb of components mismatch for array min !");
3690   int nbOfTuple=a1->getNumberOfTuples();
3691   if(nbOfTuple!=a2->getNumberOfTuples())
3692     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array min !");
3693   DataArrayDouble *ret=DataArrayDouble::New();
3694   ret->alloc(nbOfTuple,nbOfComp);
3695   double *retPtr=ret->getPointer();
3696   const double *a1Ptr=a1->getConstPointer();
3697   const double *a2Ptr=a2->getConstPointer();
3698   int nbElem=nbOfTuple*nbOfComp;
3699   for(int i=0;i<nbElem;i++)
3700     retPtr[i]=std::min(a1Ptr[i],a2Ptr[i]);
3701   ret->copyStringInfoFrom(*a1);
3702   return ret;
3703 }
3704
3705 /*!
3706  * Returns a new DataArrayDouble that is a sum of two given arrays. There are 3
3707  * valid cases.
3708  * 1.  The arrays have same number of tuples and components. Then each value of
3709  *   the result array (_a_) is a sum of the corresponding values of \a a1 and \a a2,
3710  *   i.e.: _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ i, j ].
3711  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
3712  *   component. Then
3713  *   _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ i, 0 ].
3714  * 3.  The arrays have same number of components and one array, say _a2_, has one
3715  *   tuple. Then
3716  *   _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ 0, j ].
3717  *
3718  * Info on components is copied either from the first array (in the first case) or from
3719  * the array with maximal number of elements (getNbOfElems()).
3720  *  \param [in] a1 - an array to sum up.
3721  *  \param [in] a2 - another array to sum up.
3722  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
3723  *          The caller is to delete this result array using decrRef() as it is no more
3724  *          needed.
3725  *  \throw If either \a a1 or \a a2 is NULL.
3726  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
3727  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
3728  *         none of them has number of tuples or components equal to 1.
3729  */
3730 DataArrayDouble *DataArrayDouble::Add(const DataArrayDouble *a1, const DataArrayDouble *a2)
3731 {
3732   if(!a1 || !a2)
3733     throw INTERP_KERNEL::Exception("DataArrayDouble::Add : input DataArrayDouble instance is NULL !");
3734   int nbOfTuple=a1->getNumberOfTuples();
3735   int nbOfTuple2=a2->getNumberOfTuples();
3736   int nbOfComp=a1->getNumberOfComponents();
3737   int nbOfComp2=a2->getNumberOfComponents();
3738   MCAuto<DataArrayDouble> ret=0;
3739   if(nbOfTuple==nbOfTuple2)
3740     {
3741       if(nbOfComp==nbOfComp2)
3742         {
3743           ret=DataArrayDouble::New();
3744           ret->alloc(nbOfTuple,nbOfComp);
3745           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::plus<double>());
3746           ret->copyStringInfoFrom(*a1);
3747         }
3748       else
3749         {
3750           int nbOfCompMin,nbOfCompMax;
3751           const DataArrayDouble *aMin, *aMax;
3752           if(nbOfComp>nbOfComp2)
3753             {
3754               nbOfCompMin=nbOfComp2; nbOfCompMax=nbOfComp;
3755               aMin=a2; aMax=a1;
3756             }
3757           else
3758             {
3759               nbOfCompMin=nbOfComp; nbOfCompMax=nbOfComp2;
3760               aMin=a1; aMax=a2;
3761             }
3762           if(nbOfCompMin==1)
3763             {
3764               ret=DataArrayDouble::New();
3765               ret->alloc(nbOfTuple,nbOfCompMax);
3766               const double *aMinPtr=aMin->getConstPointer();
3767               const double *aMaxPtr=aMax->getConstPointer();
3768               double *res=ret->getPointer();
3769               for(int i=0;i<nbOfTuple;i++)
3770                 res=std::transform(aMaxPtr+i*nbOfCompMax,aMaxPtr+(i+1)*nbOfCompMax,res,std::bind2nd(std::plus<double>(),aMinPtr[i]));
3771               ret->copyStringInfoFrom(*aMax);
3772             }
3773           else
3774             throw INTERP_KERNEL::Exception("Nb of components mismatch for array Add !");
3775         }
3776     }
3777   else if((nbOfTuple==1 && nbOfTuple2>1) || (nbOfTuple>1 && nbOfTuple2==1))
3778     {
3779       if(nbOfComp==nbOfComp2)
3780         {
3781           int nbOfTupleMax=std::max(nbOfTuple,nbOfTuple2);
3782           const DataArrayDouble *aMin=nbOfTuple>nbOfTuple2?a2:a1;
3783           const DataArrayDouble *aMax=nbOfTuple>nbOfTuple2?a1:a2;
3784           const double *aMinPtr=aMin->getConstPointer(),*aMaxPtr=aMax->getConstPointer();
3785           ret=DataArrayDouble::New();
3786           ret->alloc(nbOfTupleMax,nbOfComp);
3787           double *res=ret->getPointer();
3788           for(int i=0;i<nbOfTupleMax;i++)
3789             res=std::transform(aMaxPtr+i*nbOfComp,aMaxPtr+(i+1)*nbOfComp,aMinPtr,res,std::plus<double>());
3790           ret->copyStringInfoFrom(*aMax);
3791         }
3792       else
3793         throw INTERP_KERNEL::Exception("Nb of components mismatch for array Add !");
3794     }
3795   else
3796     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Add !");
3797   return ret.retn();
3798 }
3799
3800 /*!
3801  * Adds values of another DataArrayDouble to values of \a this one. There are 3
3802  * valid cases.
3803  * 1.  The arrays have same number of tuples and components. Then each value of
3804  *   \a other array is added to the corresponding value of \a this array, i.e.:
3805  *   _a_ [ i, j ] += _other_ [ i, j ].
3806  * 2.  The arrays have same number of tuples and \a other array has one component. Then
3807  *   _a_ [ i, j ] += _other_ [ i, 0 ].
3808  * 3.  The arrays have same number of components and \a other array has one tuple. Then
3809  *   _a_ [ i, j ] += _a2_ [ 0, j ].
3810  *
3811  *  \param [in] other - an array to add to \a this one.
3812  *  \throw If \a other is NULL.
3813  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
3814  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
3815  *         \a other has number of both tuples and components not equal to 1.
3816  */
3817 void DataArrayDouble::addEqual(const DataArrayDouble *other)
3818 {
3819   if(!other)
3820     throw INTERP_KERNEL::Exception("DataArrayDouble::addEqual : input DataArrayDouble instance is NULL !");
3821   const char *msg="Nb of tuples mismatch for DataArrayDouble::addEqual  !";
3822   checkAllocated();
3823   other->checkAllocated();
3824   int nbOfTuple=getNumberOfTuples();
3825   int nbOfTuple2=other->getNumberOfTuples();
3826   int nbOfComp=getNumberOfComponents();
3827   int nbOfComp2=other->getNumberOfComponents();
3828   if(nbOfTuple==nbOfTuple2)
3829     {
3830       if(nbOfComp==nbOfComp2)
3831         {
3832           std::transform(begin(),end(),other->begin(),getPointer(),std::plus<double>());
3833         }
3834       else if(nbOfComp2==1)
3835         {
3836           double *ptr=getPointer();
3837           const double *ptrc=other->getConstPointer();
3838           for(int i=0;i<nbOfTuple;i++)
3839             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::plus<double>(),*ptrc++));
3840         }
3841       else
3842         throw INTERP_KERNEL::Exception(msg);
3843     }
3844   else if(nbOfTuple2==1)
3845     {
3846       if(nbOfComp2==nbOfComp)
3847         {
3848           double *ptr=getPointer();
3849           const double *ptrc=other->getConstPointer();
3850           for(int i=0;i<nbOfTuple;i++)
3851             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::plus<double>());
3852         }
3853       else
3854         throw INTERP_KERNEL::Exception(msg);
3855     }
3856   else
3857     throw INTERP_KERNEL::Exception(msg);
3858   declareAsNew();
3859 }
3860
3861 /*!
3862  * Returns a new DataArrayDouble that is a subtraction of two given arrays. There are 3
3863  * valid cases.
3864  * 1.  The arrays have same number of tuples and components. Then each value of
3865  *   the result array (_a_) is a subtraction of the corresponding values of \a a1 and
3866  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ i, j ].
3867  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
3868  *   component. Then
3869  *   _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ i, 0 ].
3870  * 3.  The arrays have same number of components and one array, say _a2_, has one
3871  *   tuple. Then
3872  *   _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ 0, j ].
3873  *
3874  * Info on components is copied either from the first array (in the first case) or from
3875  * the array with maximal number of elements (getNbOfElems()).
3876  *  \param [in] a1 - an array to subtract from.
3877  *  \param [in] a2 - an array to subtract.
3878  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
3879  *          The caller is to delete this result array using decrRef() as it is no more
3880  *          needed.
3881  *  \throw If either \a a1 or \a a2 is NULL.
3882  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
3883  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
3884  *         none of them has number of tuples or components equal to 1.
3885  */
3886 DataArrayDouble *DataArrayDouble::Substract(const DataArrayDouble *a1, const DataArrayDouble *a2)
3887 {
3888   if(!a1 || !a2)
3889     throw INTERP_KERNEL::Exception("DataArrayDouble::Substract : input DataArrayDouble instance is NULL !");
3890   int nbOfTuple1=a1->getNumberOfTuples();
3891   int nbOfTuple2=a2->getNumberOfTuples();
3892   int nbOfComp1=a1->getNumberOfComponents();
3893   int nbOfComp2=a2->getNumberOfComponents();
3894   if(nbOfTuple2==nbOfTuple1)
3895     {
3896       if(nbOfComp1==nbOfComp2)
3897         {
3898           MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
3899           ret->alloc(nbOfTuple2,nbOfComp1);
3900           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::minus<double>());
3901           ret->copyStringInfoFrom(*a1);
3902           return ret.retn();
3903         }
3904       else if(nbOfComp2==1)
3905         {
3906           MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
3907           ret->alloc(nbOfTuple1,nbOfComp1);
3908           const double *a2Ptr=a2->getConstPointer();
3909           const double *a1Ptr=a1->getConstPointer();
3910           double *res=ret->getPointer();
3911           for(int i=0;i<nbOfTuple1;i++)
3912             res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::minus<double>(),a2Ptr[i]));
3913           ret->copyStringInfoFrom(*a1);
3914           return ret.retn();
3915         }
3916       else
3917         {
3918           a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Substract !");
3919           return 0;
3920         }
3921     }
3922   else if(nbOfTuple2==1)
3923     {
3924       a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Substract !");
3925       MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
3926       ret->alloc(nbOfTuple1,nbOfComp1);
3927       const double *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
3928       double *pt=ret->getPointer();
3929       for(int i=0;i<nbOfTuple1;i++)
3930         pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::minus<double>());
3931       ret->copyStringInfoFrom(*a1);
3932       return ret.retn();
3933     }
3934   else
3935     {
3936       a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Substract !");//will always throw an exception
3937       return 0;
3938     }
3939 }
3940
3941 /*!
3942  * Subtract values of another DataArrayDouble from values of \a this one. There are 3
3943  * valid cases.
3944  * 1.  The arrays have same number of tuples and components. Then each value of
3945  *   \a other array is subtracted from the corresponding value of \a this array, i.e.:
3946  *   _a_ [ i, j ] -= _other_ [ i, j ].
3947  * 2.  The arrays have same number of tuples and \a other array has one component. Then
3948  *   _a_ [ i, j ] -= _other_ [ i, 0 ].
3949  * 3.  The arrays have same number of components and \a other array has one tuple. Then
3950  *   _a_ [ i, j ] -= _a2_ [ 0, j ].
3951  *
3952  *  \param [in] other - an array to subtract from \a this one.
3953  *  \throw If \a other is NULL.
3954  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
3955  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
3956  *         \a other has number of both tuples and components not equal to 1.
3957  */
3958 void DataArrayDouble::substractEqual(const DataArrayDouble *other)
3959 {
3960   if(!other)
3961     throw INTERP_KERNEL::Exception("DataArrayDouble::substractEqual : input DataArrayDouble instance is NULL !");
3962   const char *msg="Nb of tuples mismatch for DataArrayDouble::substractEqual  !";
3963   checkAllocated();
3964   other->checkAllocated();
3965   int nbOfTuple=getNumberOfTuples();
3966   int nbOfTuple2=other->getNumberOfTuples();
3967   int nbOfComp=getNumberOfComponents();
3968   int nbOfComp2=other->getNumberOfComponents();
3969   if(nbOfTuple==nbOfTuple2)
3970     {
3971       if(nbOfComp==nbOfComp2)
3972         {
3973           std::transform(begin(),end(),other->begin(),getPointer(),std::minus<double>());
3974         }
3975       else if(nbOfComp2==1)
3976         {
3977           double *ptr=getPointer();
3978           const double *ptrc=other->getConstPointer();
3979           for(int i=0;i<nbOfTuple;i++)
3980             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::minus<double>(),*ptrc++)); 
3981         }
3982       else
3983         throw INTERP_KERNEL::Exception(msg);
3984     }
3985   else if(nbOfTuple2==1)
3986     {
3987       if(nbOfComp2==nbOfComp)
3988         {
3989           double *ptr=getPointer();
3990           const double *ptrc=other->getConstPointer();
3991           for(int i=0;i<nbOfTuple;i++)
3992             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::minus<double>());
3993         }
3994       else
3995         throw INTERP_KERNEL::Exception(msg);
3996     }
3997   else
3998     throw INTERP_KERNEL::Exception(msg);
3999   declareAsNew();
4000 }
4001
4002 /*!
4003  * Returns a new DataArrayDouble that is a product of two given arrays. There are 3
4004  * valid cases.
4005  * 1.  The arrays have same number of tuples and components. Then each value of
4006  *   the result array (_a_) is a product of the corresponding values of \a a1 and
4007  *   \a a2, i.e. _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ i, j ].
4008  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
4009  *   component. Then
4010  *   _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ i, 0 ].
4011  * 3.  The arrays have same number of components and one array, say _a2_, has one
4012  *   tuple. Then
4013  *   _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ 0, j ].
4014  *
4015  * Info on components is copied either from the first array (in the first case) or from
4016  * the array with maximal number of elements (getNbOfElems()).
4017  *  \param [in] a1 - a factor array.
4018  *  \param [in] a2 - another factor array.
4019  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4020  *          The caller is to delete this result array using decrRef() as it is no more
4021  *          needed.
4022  *  \throw If either \a a1 or \a a2 is NULL.
4023  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
4024  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
4025  *         none of them has number of tuples or components equal to 1.
4026  */
4027 DataArrayDouble *DataArrayDouble::Multiply(const DataArrayDouble *a1, const DataArrayDouble *a2)
4028 {
4029   if(!a1 || !a2)
4030     throw INTERP_KERNEL::Exception("DataArrayDouble::Multiply : input DataArrayDouble instance is NULL !");
4031   int nbOfTuple=a1->getNumberOfTuples();
4032   int nbOfTuple2=a2->getNumberOfTuples();
4033   int nbOfComp=a1->getNumberOfComponents();
4034   int nbOfComp2=a2->getNumberOfComponents();
4035   MCAuto<DataArrayDouble> ret=0;
4036   if(nbOfTuple==nbOfTuple2)
4037     {
4038       if(nbOfComp==nbOfComp2)
4039         {
4040           ret=DataArrayDouble::New();
4041           ret->alloc(nbOfTuple,nbOfComp);
4042           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::multiplies<double>());
4043           ret->copyStringInfoFrom(*a1);
4044         }
4045       else
4046         {
4047           int nbOfCompMin,nbOfCompMax;
4048           const DataArrayDouble *aMin, *aMax;
4049           if(nbOfComp>nbOfComp2)
4050             {
4051               nbOfCompMin=nbOfComp2; nbOfCompMax=nbOfComp;
4052               aMin=a2; aMax=a1;
4053             }
4054           else
4055             {
4056               nbOfCompMin=nbOfComp; nbOfCompMax=nbOfComp2;
4057               aMin=a1; aMax=a2;
4058             }
4059           if(nbOfCompMin==1)
4060             {
4061               ret=DataArrayDouble::New();
4062               ret->alloc(nbOfTuple,nbOfCompMax);
4063               const double *aMinPtr=aMin->getConstPointer();
4064               const double *aMaxPtr=aMax->getConstPointer();
4065               double *res=ret->getPointer();
4066               for(int i=0;i<nbOfTuple;i++)
4067                 res=std::transform(aMaxPtr+i*nbOfCompMax,aMaxPtr+(i+1)*nbOfCompMax,res,std::bind2nd(std::multiplies<double>(),aMinPtr[i]));
4068               ret->copyStringInfoFrom(*aMax);
4069             }
4070           else
4071             throw INTERP_KERNEL::Exception("Nb of components mismatch for array Multiply !");
4072         }
4073     }
4074   else if((nbOfTuple==1 && nbOfTuple2>1) || (nbOfTuple>1 && nbOfTuple2==1))
4075     {
4076       if(nbOfComp==nbOfComp2)
4077         {
4078           int nbOfTupleMax=std::max(nbOfTuple,nbOfTuple2);
4079           const DataArrayDouble *aMin=nbOfTuple>nbOfTuple2?a2:a1;
4080           const DataArrayDouble *aMax=nbOfTuple>nbOfTuple2?a1:a2;
4081           const double *aMinPtr=aMin->getConstPointer(),*aMaxPtr=aMax->getConstPointer();
4082           ret=DataArrayDouble::New();
4083           ret->alloc(nbOfTupleMax,nbOfComp);
4084           double *res=ret->getPointer();
4085           for(int i=0;i<nbOfTupleMax;i++)
4086             res=std::transform(aMaxPtr+i*nbOfComp,aMaxPtr+(i+1)*nbOfComp,aMinPtr,res,std::multiplies<double>());
4087           ret->copyStringInfoFrom(*aMax);
4088         }
4089       else
4090         throw INTERP_KERNEL::Exception("Nb of components mismatch for array Multiply !");
4091     }
4092   else
4093     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Multiply !");
4094   return ret.retn();
4095 }
4096
4097 /*!
4098  * Multiply values of another DataArrayDouble to values of \a this one. There are 3
4099  * valid cases.
4100  * 1.  The arrays have same number of tuples and components. Then each value of
4101  *   \a other array is multiplied to the corresponding value of \a this array, i.e.
4102  *   _this_ [ i, j ] *= _other_ [ i, j ].
4103  * 2.  The arrays have same number of tuples and \a other array has one component. Then
4104  *   _this_ [ i, j ] *= _other_ [ i, 0 ].
4105  * 3.  The arrays have same number of components and \a other array has one tuple. Then
4106  *   _this_ [ i, j ] *= _a2_ [ 0, j ].
4107  *
4108  *  \param [in] other - an array to multiply to \a this one.
4109  *  \throw If \a other is NULL.
4110  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
4111  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
4112  *         \a other has number of both tuples and components not equal to 1.
4113  */
4114 void DataArrayDouble::multiplyEqual(const DataArrayDouble *other)
4115 {
4116   if(!other)
4117     throw INTERP_KERNEL::Exception("DataArrayDouble::multiplyEqual : input DataArrayDouble instance is NULL !");
4118   const char *msg="Nb of tuples mismatch for DataArrayDouble::multiplyEqual !";
4119   checkAllocated();
4120   other->checkAllocated();
4121   int nbOfTuple=getNumberOfTuples();
4122   int nbOfTuple2=other->getNumberOfTuples();
4123   int nbOfComp=getNumberOfComponents();
4124   int nbOfComp2=other->getNumberOfComponents();
4125   if(nbOfTuple==nbOfTuple2)
4126     {
4127       if(nbOfComp==nbOfComp2)
4128         {
4129           std::transform(begin(),end(),other->begin(),getPointer(),std::multiplies<double>());
4130         }
4131       else if(nbOfComp2==1)
4132         {
4133           double *ptr=getPointer();
4134           const double *ptrc=other->getConstPointer();
4135           for(int i=0;i<nbOfTuple;i++)
4136             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::multiplies<double>(),*ptrc++));
4137         }
4138       else
4139         throw INTERP_KERNEL::Exception(msg);
4140     }
4141   else if(nbOfTuple2==1)
4142     {
4143       if(nbOfComp2==nbOfComp)
4144         {
4145           double *ptr=getPointer();
4146           const double *ptrc=other->getConstPointer();
4147           for(int i=0;i<nbOfTuple;i++)
4148             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::multiplies<double>());
4149         }
4150       else
4151         throw INTERP_KERNEL::Exception(msg);
4152     }
4153   else
4154     throw INTERP_KERNEL::Exception(msg);
4155   declareAsNew();
4156 }
4157
4158 /*!
4159  * Returns a new DataArrayDouble that is a division of two given arrays. There are 3
4160  * valid cases.
4161  * 1.  The arrays have same number of tuples and components. Then each value of
4162  *   the result array (_a_) is a division of the corresponding values of \a a1 and
4163  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ i, j ].
4164  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
4165  *   component. Then
4166  *   _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ i, 0 ].
4167  * 3.  The arrays have same number of components and one array, say _a2_, has one
4168  *   tuple. Then
4169  *   _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ 0, j ].
4170  *
4171  * Info on components is copied either from the first array (in the first case) or from
4172  * the array with maximal number of elements (getNbOfElems()).
4173  *  \warning No check of division by zero is performed!
4174  *  \param [in] a1 - a numerator array.
4175  *  \param [in] a2 - a denominator array.
4176  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4177  *          The caller is to delete this result array using decrRef() as it is no more
4178  *          needed.
4179  *  \throw If either \a a1 or \a a2 is NULL.
4180  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
4181  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
4182  *         none of them has number of tuples or components equal to 1.
4183  */
4184 DataArrayDouble *DataArrayDouble::Divide(const DataArrayDouble *a1, const DataArrayDouble *a2)
4185 {
4186   if(!a1 || !a2)
4187     throw INTERP_KERNEL::Exception("DataArrayDouble::Divide : input DataArrayDouble instance is NULL !");
4188   int nbOfTuple1=a1->getNumberOfTuples();
4189   int nbOfTuple2=a2->getNumberOfTuples();
4190   int nbOfComp1=a1->getNumberOfComponents();
4191   int nbOfComp2=a2->getNumberOfComponents();
4192   if(nbOfTuple2==nbOfTuple1)
4193     {
4194       if(nbOfComp1==nbOfComp2)
4195         {
4196           MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
4197           ret->alloc(nbOfTuple2,nbOfComp1);
4198           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::divides<double>());
4199           ret->copyStringInfoFrom(*a1);
4200           return ret.retn();
4201         }
4202       else if(nbOfComp2==1)
4203         {
4204           MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
4205           ret->alloc(nbOfTuple1,nbOfComp1);
4206           const double *a2Ptr=a2->getConstPointer();
4207           const double *a1Ptr=a1->getConstPointer();
4208           double *res=ret->getPointer();
4209           for(int i=0;i<nbOfTuple1;i++)
4210             res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::divides<double>(),a2Ptr[i]));
4211           ret->copyStringInfoFrom(*a1);
4212           return ret.retn();
4213         }
4214       else
4215         {
4216           a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Divide !");
4217           return 0;
4218         }
4219     }
4220   else if(nbOfTuple2==1)
4221     {
4222       a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Divide !");
4223       MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
4224       ret->alloc(nbOfTuple1,nbOfComp1);
4225       const double *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
4226       double *pt=ret->getPointer();
4227       for(int i=0;i<nbOfTuple1;i++)
4228         pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::divides<double>());
4229       ret->copyStringInfoFrom(*a1);
4230       return ret.retn();
4231     }
4232   else
4233     {
4234       a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Divide !");//will always throw an exception
4235       return 0;
4236     }
4237 }
4238
4239 /*!
4240  * Divide values of \a this array by values of another DataArrayDouble. There are 3
4241  * valid cases.
4242  * 1.  The arrays have same number of tuples and components. Then each value of
4243  *    \a this array is divided by the corresponding value of \a other one, i.e.:
4244  *   _a_ [ i, j ] /= _other_ [ i, j ].
4245  * 2.  The arrays have same number of tuples and \a other array has one component. Then
4246  *   _a_ [ i, j ] /= _other_ [ i, 0 ].
4247  * 3.  The arrays have same number of components and \a other array has one tuple. Then
4248  *   _a_ [ i, j ] /= _a2_ [ 0, j ].
4249  *
4250  *  \warning No check of division by zero is performed!
4251  *  \param [in] other - an array to divide \a this one by.
4252  *  \throw If \a other is NULL.
4253  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
4254  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
4255  *         \a other has number of both tuples and components not equal to 1.
4256  */
4257 void DataArrayDouble::divideEqual(const DataArrayDouble *other)
4258 {
4259   if(!other)
4260     throw INTERP_KERNEL::Exception("DataArrayDouble::divideEqual : input DataArrayDouble instance is NULL !");
4261   const char *msg="Nb of tuples mismatch for DataArrayDouble::divideEqual !";
4262   checkAllocated();
4263   other->checkAllocated();
4264   int nbOfTuple=getNumberOfTuples();
4265   int nbOfTuple2=other->getNumberOfTuples();
4266   int nbOfComp=getNumberOfComponents();
4267   int nbOfComp2=other->getNumberOfComponents();
4268   if(nbOfTuple==nbOfTuple2)
4269     {
4270       if(nbOfComp==nbOfComp2)
4271         {
4272           std::transform(begin(),end(),other->begin(),getPointer(),std::divides<double>());
4273         }
4274       else if(nbOfComp2==1)
4275         {
4276           double *ptr=getPointer();
4277           const double *ptrc=other->getConstPointer();
4278           for(int i=0;i<nbOfTuple;i++)
4279             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::divides<double>(),*ptrc++));
4280         }
4281       else
4282         throw INTERP_KERNEL::Exception(msg);
4283     }
4284   else if(nbOfTuple2==1)
4285     {
4286       if(nbOfComp2==nbOfComp)
4287         {
4288           double *ptr=getPointer();
4289           const double *ptrc=other->getConstPointer();
4290           for(int i=0;i<nbOfTuple;i++)
4291             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::divides<double>());
4292         }
4293       else
4294         throw INTERP_KERNEL::Exception(msg);
4295     }
4296   else
4297     throw INTERP_KERNEL::Exception(msg);
4298   declareAsNew();
4299 }
4300
4301 /*!
4302  * Returns a new DataArrayDouble that is the result of pow of two given arrays. There are 3
4303  * valid cases.
4304  *
4305  *  \param [in] a1 - an array to pow up.
4306  *  \param [in] a2 - another array to sum up.
4307  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4308  *          The caller is to delete this result array using decrRef() as it is no more
4309  *          needed.
4310  *  \throw If either \a a1 or \a a2 is NULL.
4311  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
4312  *  \throw If \a a1->getNumberOfComponents() != 1 or \a a2->getNumberOfComponents() != 1.
4313  *  \throw If there is a negative value in \a a1.
4314  */
4315 DataArrayDouble *DataArrayDouble::Pow(const DataArrayDouble *a1, const DataArrayDouble *a2)
4316 {
4317   if(!a1 || !a2)
4318     throw INTERP_KERNEL::Exception("DataArrayDouble::Pow : at least one of input instances is null !");
4319   int nbOfTuple=a1->getNumberOfTuples();
4320   int nbOfTuple2=a2->getNumberOfTuples();
4321   int nbOfComp=a1->getNumberOfComponents();
4322   int nbOfComp2=a2->getNumberOfComponents();
4323   if(nbOfTuple!=nbOfTuple2)
4324     throw INTERP_KERNEL::Exception("DataArrayDouble::Pow : number of tuples mismatches !");
4325   if(nbOfComp!=1 || nbOfComp2!=1)
4326     throw INTERP_KERNEL::Exception("DataArrayDouble::Pow : number of components of both arrays must be equal to 1 !");
4327   MCAuto<DataArrayDouble> ret=DataArrayDouble::New(); ret->alloc(nbOfTuple,1);
4328   const double *ptr1(a1->begin()),*ptr2(a2->begin());
4329   double *ptr=ret->getPointer();
4330   for(int i=0;i<nbOfTuple;i++,ptr1++,ptr2++,ptr++)
4331     {
4332       if(*ptr1>=0)
4333         {
4334           *ptr=pow(*ptr1,*ptr2);
4335         }
4336       else
4337         {
4338           std::ostringstream oss; oss << "DataArrayDouble::Pow : on tuple #" << i << " of a1 value is < 0 (" << *ptr1 << ") !";
4339           throw INTERP_KERNEL::Exception(oss.str().c_str());
4340         }
4341     }
4342   return ret.retn();
4343 }
4344
4345 /*!
4346  * Apply pow on values of another DataArrayDouble to values of \a this one.
4347  *
4348  *  \param [in] other - an array to pow to \a this one.
4349  *  \throw If \a other is NULL.
4350  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples()
4351  *  \throw If \a this->getNumberOfComponents() != 1 or \a other->getNumberOfComponents() != 1
4352  *  \throw If there is a negative value in \a this.
4353  */
4354 void DataArrayDouble::powEqual(const DataArrayDouble *other)
4355 {
4356   if(!other)
4357     throw INTERP_KERNEL::Exception("DataArrayDouble::powEqual : input instance is null !");
4358   int nbOfTuple=getNumberOfTuples();
4359   int nbOfTuple2=other->getNumberOfTuples();
4360   int nbOfComp=getNumberOfComponents();
4361   int nbOfComp2=other->getNumberOfComponents();
4362   if(nbOfTuple!=nbOfTuple2)
4363     throw INTERP_KERNEL::Exception("DataArrayDouble::powEqual : number of tuples mismatches !");
4364   if(nbOfComp!=1 || nbOfComp2!=1)
4365     throw INTERP_KERNEL::Exception("DataArrayDouble::powEqual : number of components of both arrays must be equal to 1 !");
4366   double *ptr=getPointer();
4367   const double *ptrc=other->begin();
4368   for(int i=0;i<nbOfTuple;i++,ptrc++,ptr++)
4369     {
4370       if(*ptr>=0)
4371         *ptr=pow(*ptr,*ptrc);
4372       else
4373         {
4374           std::ostringstream oss; oss << "DataArrayDouble::powEqual : on tuple #" << i << " of this value is < 0 (" << *ptr << ") !";
4375           throw INTERP_KERNEL::Exception(oss.str().c_str());
4376         }
4377     }
4378   declareAsNew();
4379 }
4380
4381 /*!
4382  * This method is \b NOT wrapped into python because it can be useful only for performance reasons in C++ context.
4383  * All values in \a this must be 0. or 1. within eps error. 0 means false, 1 means true.
4384  * If an another value than 0 or 1 appear (within eps precision) an INTERP_KERNEL::Exception will be thrown.
4385  *
4386  * \throw if \a this is not allocated.
4387  * \throw if \a this has not exactly one component.
4388  */
4389 std::vector<bool> DataArrayDouble::toVectorOfBool(double eps) const
4390 {
4391   checkAllocated();
4392   if(getNumberOfComponents()!=1)
4393     throw INTERP_KERNEL::Exception("DataArrayDouble::toVectorOfBool : must be applied on single component array !");
4394   int nbt(getNumberOfTuples());
4395   std::vector<bool> ret(nbt);
4396   const double *pt(begin());
4397   for(int i=0;i<nbt;i++)
4398     {
4399       if(fabs(pt[i])<eps)
4400         ret[i]=false;
4401       else if(fabs(pt[i]-1.)<eps)
4402         ret[i]=true;
4403       else
4404         {
4405           std::ostringstream oss; oss << "DataArrayDouble::toVectorOfBool : the tuple #" << i << " has value " << pt[i] << " is invalid ! must be 0. or 1. !";
4406           throw INTERP_KERNEL::Exception(oss.str().c_str());
4407         }
4408     }
4409   return ret;
4410 }
4411
4412 /*!
4413  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
4414  * Server side.
4415  */
4416 void DataArrayDouble::getTinySerializationIntInformation(std::vector<int>& tinyInfo) const
4417 {
4418   tinyInfo.resize(2);
4419   if(isAllocated())
4420     {
4421       tinyInfo[0]=getNumberOfTuples();
4422       tinyInfo[1]=getNumberOfComponents();
4423     }
4424   else
4425     {
4426       tinyInfo[0]=-1;
4427       tinyInfo[1]=-1;
4428     }
4429 }
4430
4431 /*!
4432  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
4433  * Server side.
4434  */
4435 void DataArrayDouble::getTinySerializationStrInformation(std::vector<std::string>& tinyInfo) const
4436 {
4437   if(isAllocated())
4438     {
4439       int nbOfCompo=getNumberOfComponents();
4440       tinyInfo.resize(nbOfCompo+1);
4441       tinyInfo[0]=getName();
4442       for(int i=0;i<nbOfCompo;i++)
4443         tinyInfo[i+1]=getInfoOnComponent(i);
4444     }
4445   else
4446     {
4447       tinyInfo.resize(1);
4448       tinyInfo[0]=getName();
4449     }
4450 }
4451
4452 /*!
4453  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
4454  * This method returns if a feeding is needed.
4455  */
4456 bool DataArrayDouble::resizeForUnserialization(const std::vector<int>& tinyInfoI)
4457 {
4458   int nbOfTuple=tinyInfoI[0];
4459   int nbOfComp=tinyInfoI[1];
4460   if(nbOfTuple!=-1 || nbOfComp!=-1)
4461     {
4462       alloc(nbOfTuple,nbOfComp);
4463       return true;
4464     }
4465   return false;
4466 }
4467
4468 /*!
4469  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
4470  */
4471 void DataArrayDouble::finishUnserialization(const std::vector<int>& tinyInfoI, const std::vector<std::string>& tinyInfoS)
4472 {
4473   setName(tinyInfoS[0]);
4474   if(isAllocated())
4475     {
4476       int nbOfCompo=getNumberOfComponents();
4477       for(int i=0;i<nbOfCompo;i++)
4478         setInfoOnComponent(i,tinyInfoS[i+1]);
4479     }
4480 }
4481
4482 /*!
4483  * Low static method that operates 3D rotation of 'nbNodes' 3D nodes whose coordinates are arranged in \a coordsIn
4484  * around an axe ( \a center, \a vect) and with angle \a angle.
4485  */
4486 void DataArrayDouble::Rotate3DAlg(const double *center, const double *vect, double angle, int nbNodes, const double *coordsIn, double *coordsOut)
4487 {
4488   if(!center || !vect)
4489     throw INTERP_KERNEL::Exception("DataArrayDouble::Rotate3DAlg : null vector in input !");
4490   double sina(sin(angle));
4491   double cosa(cos(angle));
4492   double vectorNorm[3];
4493   double matrix[9];
4494   double matrixTmp[9];
4495   double norm(sqrt(vect[0]*vect[0]+vect[1]*vect[1]+vect[2]*vect[2]));
4496   if(norm<std::numeric_limits<double>::min())
4497     throw INTERP_KERNEL::Exception("DataArrayDouble::Rotate3DAlg : magnitude of input vector is too close of 0. !");
4498   std::transform(vect,vect+3,vectorNorm,std::bind2nd(std::multiplies<double>(),1/norm));
4499   //rotation matrix computation
4500   matrix[0]=cosa; matrix[1]=0.; matrix[2]=0.; matrix[3]=0.; matrix[4]=cosa; matrix[5]=0.; matrix[6]=0.; matrix[7]=0.; matrix[8]=cosa;
4501   matrixTmp[0]=vectorNorm[0]*vectorNorm[0]; matrixTmp[1]=vectorNorm[0]*vectorNorm[1]; matrixTmp[2]=vectorNorm[0]*vectorNorm[2];
4502   matrixTmp[3]=vectorNorm[1]*vectorNorm[0]; matrixTmp[4]=vectorNorm[1]*vectorNorm[1]; matrixTmp[5]=vectorNorm[1]*vectorNorm[2];
4503   matrixTmp[6]=vectorNorm[2]*vectorNorm[0]; matrixTmp[7]=vectorNorm[2]*vectorNorm[1]; matrixTmp[8]=vectorNorm[2]*vectorNorm[2];
4504   std::transform(matrixTmp,matrixTmp+9,matrixTmp,std::bind2nd(std::multiplies<double>(),1-cosa));
4505   std::transform(matrix,matrix+9,matrixTmp,matrix,std::plus<double>());
4506   matrixTmp[0]=0.; matrixTmp[1]=-vectorNorm[2]; matrixTmp[2]=vectorNorm[1];
4507   matrixTmp[3]=vectorNorm[2]; matrixTmp[4]=0.; matrixTmp[5]=-vectorNorm[0];
4508   matrixTmp[6]=-vectorNorm[1]; matrixTmp[7]=vectorNorm[0]; matrixTmp[8]=0.;
4509   std::transform(matrixTmp,matrixTmp+9,matrixTmp,std::bind2nd(std::multiplies<double>(),sina));
4510   std::transform(matrix,matrix+9,matrixTmp,matrix,std::plus<double>());
4511   //rotation matrix computed.
4512   double tmp[3];
4513   for(int i=0; i<nbNodes; i++)
4514     {
4515       std::transform(coordsIn+i*3,coordsIn+(i+1)*3,center,tmp,std::minus<double>());
4516       coordsOut[i*3]=matrix[0]*tmp[0]+matrix[1]*tmp[1]+matrix[2]*tmp[2]+center[0];
4517       coordsOut[i*3+1]=matrix[3]*tmp[0]+matrix[4]*tmp[1]+matrix[5]*tmp[2]+center[1];
4518       coordsOut[i*3+2]=matrix[6]*tmp[0]+matrix[7]*tmp[1]+matrix[8]*tmp[2]+center[2];
4519     }
4520 }
4521
4522 void DataArrayDouble::Symmetry3DPlane(const double point[3], const double normalVector[3], int nbNodes, const double *coordsIn, double *coordsOut)
4523 {
4524   double matrix[9],matrix2[9],matrix3[9];
4525   double vect[3],crossVect[3];
4526   INTERP_KERNEL::orthogonalVect3(normalVector,vect);
4527   crossVect[0]=normalVector[1]*vect[2]-normalVector[2]*vect[1];
4528   crossVect[1]=normalVector[2]*vect[0]-normalVector[0]*vect[2];
4529   crossVect[2]=normalVector[0]*vect[1]-normalVector[1]*vect[0];
4530   double nv(INTERP_KERNEL::norm<3>(vect)),ni(INTERP_KERNEL::norm<3>(normalVector)),nc(INTERP_KERNEL::norm<3>(crossVect));
4531   matrix[0]=vect[0]/nv; matrix[1]=crossVect[0]/nc; matrix[2]=-normalVector[0]/ni;
4532   matrix[3]=vect[1]/nv; matrix[4]=crossVect[1]/nc; matrix[5]=-normalVector[1]/ni;
4533   matrix[6]=vect[2]/nv; matrix[7]=crossVect[2]/nc; matrix[8]=-normalVector[2]/ni;
4534   matrix2[0]=vect[0]/nv; matrix2[1]=vect[1]/nv; matrix2[2]=vect[2]/nv;
4535   matrix2[3]=crossVect[0]/nc; matrix2[4]=crossVect[1]/nc; matrix2[5]=crossVect[2]/nc;
4536   matrix2[6]=normalVector[0]/ni; matrix2[7]=normalVector[1]/ni; matrix2[8]=normalVector[2]/ni;
4537   for(int i=0;i<3;i++)
4538     for(int j=0;j<3;j++)
4539       {
4540         double val(0.);
4541         for(int k=0;k<3;k++)
4542           val+=matrix[3*i+k]*matrix2[3*k+j];
4543         matrix3[3*i+j]=val;
4544       }
4545   //rotation matrix computed.
4546   double tmp[3];
4547   for(int i=0; i<nbNodes; i++)
4548     {
4549       std::transform(coordsIn+i*3,coordsIn+(i+1)*3,point,tmp,std::minus<double>());
4550       coordsOut[i*3]=matrix3[0]*tmp[0]+matrix3[1]*tmp[1]+matrix3[2]*tmp[2]+point[0];
4551       coordsOut[i*3+1]=matrix3[3]*tmp[0]+matrix3[4]*tmp[1]+matrix3[5]*tmp[2]+point[1];
4552       coordsOut[i*3+2]=matrix3[6]*tmp[0]+matrix3[7]*tmp[1]+matrix3[8]*tmp[2]+point[2];
4553     }
4554 }
4555
4556 void DataArrayDouble::GiveBaseForPlane(const double normalVector[3], double baseOfPlane[9])
4557 {
4558   double vect[3],crossVect[3];
4559   INTERP_KERNEL::orthogonalVect3(normalVector,vect);
4560   crossVect[0]=normalVector[1]*vect[2]-normalVector[2]*vect[1];
4561   crossVect[1]=normalVector[2]*vect[0]-normalVector[0]*vect[2];
4562   crossVect[2]=normalVector[0]*vect[1]-normalVector[1]*vect[0];
4563   double nv(INTERP_KERNEL::norm<3>(vect)),ni(INTERP_KERNEL::norm<3>(normalVector)),nc(INTERP_KERNEL::norm<3>(crossVect));
4564   baseOfPlane[0]=vect[0]/nv; baseOfPlane[1]=vect[1]/nv; baseOfPlane[2]=vect[2]/nv;
4565   baseOfPlane[3]=crossVect[0]/nc; baseOfPlane[4]=crossVect[1]/nc; baseOfPlane[5]=crossVect[2]/nc;
4566   baseOfPlane[6]=normalVector[0]/ni; baseOfPlane[7]=normalVector[1]/ni; baseOfPlane[8]=normalVector[2]/ni;
4567 }
4568
4569 /*!
4570  * Low static method that operates 3D rotation of \a nbNodes 3D nodes whose coordinates are arranged in \a coords
4571  * around the center point \a center and with angle \a angle.
4572  */
4573 void DataArrayDouble::Rotate2DAlg(const double *center, double angle, int nbNodes, const double *coordsIn, double *coordsOut)
4574 {
4575   double cosa=cos(angle);
4576   double sina=sin(angle);
4577   double matrix[4];
4578   matrix[0]=cosa; matrix[1]=-sina; matrix[2]=sina; matrix[3]=cosa;
4579   double tmp[2];
4580   for(int i=0; i<nbNodes; i++)
4581     {
4582       std::transform(coordsIn+i*2,coordsIn+(i+1)*2,center,tmp,std::minus<double>());
4583       coordsOut[i*2]=matrix[0]*tmp[0]+matrix[1]*tmp[1]+center[0];
4584       coordsOut[i*2+1]=matrix[2]*tmp[0]+matrix[3]*tmp[1]+center[1];
4585     }
4586 }
4587
4588 DataArrayDoubleIterator::DataArrayDoubleIterator(DataArrayDouble *da):_da(da),_tuple_id(0),_nb_comp(0),_nb_tuple(0)
4589 {
4590   if(_da)
4591     {
4592       _da->incrRef();
4593       if(_da->isAllocated())
4594         {
4595           _nb_comp=da->getNumberOfComponents();
4596           _nb_tuple=da->getNumberOfTuples();
4597           _pt=da->getPointer();
4598         }
4599     }
4600 }
4601
4602 DataArrayDoubleIterator::~DataArrayDoubleIterator()
4603 {
4604   if(_da)
4605     _da->decrRef();
4606 }
4607
4608 DataArrayDoubleTuple *DataArrayDoubleIterator::nextt()
4609 {
4610   if(_tuple_id<_nb_tuple)
4611     {
4612       _tuple_id++;
4613       DataArrayDoubleTuple *ret=new DataArrayDoubleTuple(_pt,_nb_comp);
4614       _pt+=_nb_comp;
4615       return ret;
4616     }
4617   else
4618     return 0;
4619 }
4620
4621 DataArrayDoubleTuple::DataArrayDoubleTuple(double *pt, int nbOfComp):_pt(pt),_nb_of_compo(nbOfComp)
4622 {
4623 }
4624
4625
4626 std::string DataArrayDoubleTuple::repr() const
4627 {
4628   std::ostringstream oss; oss.precision(17); oss << "(";
4629   for(int i=0;i<_nb_of_compo-1;i++)
4630     oss << _pt[i] << ", ";
4631   oss << _pt[_nb_of_compo-1] << ")";
4632   return oss.str();
4633 }
4634
4635 double DataArrayDoubleTuple::doubleValue() const
4636 {
4637   if(_nb_of_compo==1)
4638     return *_pt;
4639   throw INTERP_KERNEL::Exception("DataArrayDoubleTuple::doubleValue : DataArrayDoubleTuple instance has not exactly 1 component -> Not possible to convert it into a double precision float !");
4640 }
4641
4642 /*!
4643  * This method returns a newly allocated instance the caller should dealed with by a MEDCoupling::DataArrayDouble::decrRef.
4644  * This method performs \b no copy of data. The content is only referenced using MEDCoupling::DataArrayDouble::useArray with ownership set to \b false.
4645  * 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
4646  * \b nbOfCompo=1 and \bnbOfTuples==this->_nb_of_elem.
4647  */
4648 DataArrayDouble *DataArrayDoubleTuple::buildDADouble(int nbOfTuples, int nbOfCompo) const
4649 {
4650   if((_nb_of_compo==nbOfCompo && nbOfTuples==1) || (_nb_of_compo==nbOfTuples && nbOfCompo==1))
4651     {
4652       DataArrayDouble *ret=DataArrayDouble::New();
4653       ret->useExternalArrayWithRWAccess(_pt,nbOfTuples,nbOfCompo);
4654       return ret;
4655     }
4656   else
4657     {
4658       std::ostringstream oss; oss << "DataArrayDoubleTuple::buildDADouble : unable to build a requested DataArrayDouble instance with nbofTuple=" << nbOfTuples << " and nbOfCompo=" << nbOfCompo;
4659       oss << ".\nBecause the number of elements in this is " << _nb_of_compo << " !";
4660       throw INTERP_KERNEL::Exception(oss.str().c_str());
4661     }
4662 }
4663
4664 /*!
4665  * Returns a new instance of DataArrayInt. The caller is to delete this array
4666  * using decrRef() as it is no more needed. 
4667  */
4668 DataArrayInt *DataArrayInt::New()
4669 {
4670   return new DataArrayInt;
4671 }
4672
4673 /*!
4674  * Returns the only one value in \a this, if and only if number of elements
4675  * (nb of tuples * nb of components) is equal to 1, and that \a this is allocated.
4676  *  \return double - the sole value stored in \a this array.
4677  *  \throw If at least one of conditions stated above is not fulfilled.
4678  */
4679 int DataArrayInt::intValue() const
4680 {
4681   if(isAllocated())
4682     {
4683       if(getNbOfElems()==1)
4684         {
4685           return *getConstPointer();
4686         }
4687       else
4688         throw INTERP_KERNEL::Exception("DataArrayInt::intValue : DataArrayInt instance is allocated but number of elements is not equal to 1 !");
4689     }
4690   else
4691     throw INTERP_KERNEL::Exception("DataArrayInt::intValue : DataArrayInt instance is not allocated !");
4692 }
4693
4694 /*!
4695  * Returns an integer value characterizing \a this array, which is useful for a quick
4696  * comparison of many instances of DataArrayInt.
4697  *  \return int - the hash value.
4698  *  \throw If \a this is not allocated.
4699  */
4700 int DataArrayInt::getHashCode() const
4701 {
4702   checkAllocated();
4703   std::size_t nbOfElems=getNbOfElems();
4704   int ret=nbOfElems*65536;
4705   int delta=3;
4706   if(nbOfElems>48)
4707     delta=nbOfElems/8;
4708   int ret0=0;
4709   const int *pt=begin();
4710   for(std::size_t i=0;i<nbOfElems;i+=delta)
4711     ret0+=pt[i] & 0x1FFF;
4712   return ret+ret0;
4713 }
4714
4715 /*!
4716  * Returns a full copy of \a this. For more info on copying data arrays see
4717  * \ref MEDCouplingArrayBasicsCopyDeep.
4718  *  \return DataArrayInt * - a new instance of DataArrayInt.
4719  */
4720 DataArrayInt *DataArrayInt::deepCopy() const
4721 {
4722   return new DataArrayInt(*this);
4723 }
4724
4725 /*!
4726  * Returns either a \a deep or \a shallow copy of this array. For more info see
4727  * \ref MEDCouplingArrayBasicsCopyDeep and \ref MEDCouplingArrayBasicsCopyShallow.
4728  *  \param [in] dCpy - if \a true, a deep copy is returned, else, a shallow one.
4729  *  \return DataArrayInt * - either a new instance of DataArrayInt (if \a dCpy
4730  *          == \a true) or \a this instance (if \a dCpy == \a false).
4731  */
4732 DataArrayInt *DataArrayInt::performCopyOrIncrRef(bool dCpy) const
4733 {
4734   if(dCpy)
4735     return deepCopy();
4736   else
4737     {
4738       incrRef();
4739       return const_cast<DataArrayInt *>(this);
4740     }
4741 }
4742
4743 /*!
4744  * Assign zero to all values in \a this array. To know more on filling arrays see
4745  * \ref MEDCouplingArrayFill.
4746  * \throw If \a this is not allocated.
4747  */
4748 void DataArrayInt::fillWithZero()
4749 {
4750   fillWithValue(0);
4751 }
4752
4753 /*!
4754  * Set all values in \a this array so that the i-th element equals to \a init + i
4755  * (i starts from zero). To know more on filling arrays see \ref MEDCouplingArrayFill.
4756  *  \param [in] init - value to assign to the first element of array.
4757  *  \throw If \a this->getNumberOfComponents() != 1
4758  *  \throw If \a this is not allocated.
4759  */
4760 void DataArrayInt::iota(int init)
4761 {
4762   checkAllocated();
4763   if(getNumberOfComponents()!=1)
4764     throw INTERP_KERNEL::Exception("DataArrayInt::iota : works only for arrays with only one component, you can call 'rearrange' method before !");
4765   int *ptr=getPointer();
4766   int ntuples=getNumberOfTuples();
4767   for(int i=0;i<ntuples;i++)
4768     ptr[i]=init+i;
4769   declareAsNew();
4770 }
4771
4772 /*!
4773  * Returns a textual and human readable representation of \a this instance of
4774  * DataArrayInt. This text is shown when a DataArrayInt is printed in Python.
4775  * \return std::string - text describing \a this DataArrayInt.
4776  * 
4777  * \sa reprNotTooLong, reprZip
4778  */
4779 std::string DataArrayInt::repr() const
4780 {
4781   std::ostringstream ret;
4782   reprStream(ret);
4783   return ret.str();
4784 }
4785
4786 std::string DataArrayInt::reprZip() const
4787 {
4788   std::ostringstream ret;
4789   reprZipStream(ret);
4790   return ret.str();
4791 }
4792
4793 /*!
4794  * This method is close to repr method except that when \a this has more than 1000 tuples, all tuples are not
4795  * printed out to avoid to consume too much space in interpretor.
4796  * \sa repr
4797  */
4798 std::string DataArrayInt::reprNotTooLong() const
4799 {
4800   std::ostringstream ret;
4801   reprNotTooLongStream(ret);
4802   return ret.str();
4803 }
4804
4805 void DataArrayInt::writeVTK(std::ostream& ofs, int indent, const std::string& type, const std::string& nameInFile, DataArrayByte *byteArr) const
4806 {
4807   static const char SPACE[4]={' ',' ',' ',' '};
4808   checkAllocated();
4809   std::string idt(indent,' ');
4810   ofs << idt << "<DataArray type=\"" << type << "\" Name=\"" << nameInFile << "\" NumberOfComponents=\"" << getNumberOfComponents() << "\"";
4811   if(byteArr)
4812     {
4813       ofs << " format=\"appended\" offset=\"" << byteArr->getNumberOfTuples() << "\">";
4814       if(std::string(type)=="Int32")
4815         {
4816           const char *data(reinterpret_cast<const char *>(begin()));
4817           std::size_t sz(getNbOfElems()*sizeof(int));
4818           byteArr->insertAtTheEnd(data,data+sz);
4819           byteArr->insertAtTheEnd(SPACE,SPACE+4);
4820         }
4821       else if(std::string(type)=="Int8")
4822         {
4823           INTERP_KERNEL::AutoPtr<char> tmp(new char[getNbOfElems()]);
4824           std::copy(begin(),end(),(char *)tmp);
4825           byteArr->insertAtTheEnd((char *)tmp,(char *)tmp+getNbOfElems());
4826           byteArr->insertAtTheEnd(SPACE,SPACE+4);
4827         }
4828       else if(std::string(type)=="UInt8")
4829         {
4830           INTERP_KERNEL::AutoPtr<unsigned char> tmp(new unsigned char[getNbOfElems()]);
4831           std::copy(begin(),end(),(unsigned char *)tmp);
4832           byteArr->insertAtTheEnd((unsigned char *)tmp,(unsigned char *)tmp+getNbOfElems());
4833           byteArr->insertAtTheEnd(SPACE,SPACE+4);
4834         }
4835       else
4836         throw INTERP_KERNEL::Exception("DataArrayInt::writeVTK : Only Int32, Int8 and UInt8 supported !");
4837     }
4838   else
4839     {
4840       ofs << " RangeMin=\"" << getMinValueInArray() << "\" RangeMax=\"" << getMaxValueInArray() << "\" format=\"ascii\">\n" << idt;
4841       std::copy(begin(),end(),std::ostream_iterator<int>(ofs," "));
4842     }
4843   ofs << std::endl << idt << "</DataArray>\n";
4844 }
4845
4846 void DataArrayInt::reprStream(std::ostream& stream) const
4847 {
4848   stream << "Name of int array : \"" << _name << "\"\n";
4849   reprWithoutNameStream(stream);
4850 }
4851
4852 void DataArrayInt::reprZipStream(std::ostream& stream) const
4853 {
4854   stream << "Name of int array : \"" << _name << "\"\n";
4855   reprZipWithoutNameStream(stream);
4856 }
4857
4858 void DataArrayInt::reprNotTooLongStream(std::ostream& stream) const
4859 {
4860   stream << "Name of int array : \"" << _name << "\"\n";
4861   reprNotTooLongWithoutNameStream(stream);
4862 }
4863
4864 void DataArrayInt::reprWithoutNameStream(std::ostream& stream) const
4865 {
4866   DataArray::reprWithoutNameStream(stream);
4867   _mem.repr(getNumberOfComponents(),stream);
4868 }
4869
4870 void DataArrayInt::reprZipWithoutNameStream(std::ostream& stream) const
4871 {
4872   DataArray::reprWithoutNameStream(stream);
4873   _mem.reprZip(getNumberOfComponents(),stream);
4874 }
4875
4876 void DataArrayInt::reprNotTooLongWithoutNameStream(std::ostream& stream) const
4877 {
4878   DataArray::reprWithoutNameStream(stream);
4879   stream.precision(17);
4880   _mem.reprNotTooLong(getNumberOfComponents(),stream);
4881 }
4882
4883 void DataArrayInt::reprCppStream(const std::string& varName, std::ostream& stream) const
4884 {
4885   int nbTuples=getNumberOfTuples(),nbComp=getNumberOfComponents();
4886   const int *data=getConstPointer();
4887   stream << "DataArrayInt *" << varName << "=DataArrayInt::New();" << std::endl;
4888   if(nbTuples*nbComp>=1)
4889     {
4890       stream << "const int " << varName << "Data[" << nbTuples*nbComp << "]={";
4891       std::copy(data,data+nbTuples*nbComp-1,std::ostream_iterator<int>(stream,","));
4892       stream << data[nbTuples*nbComp-1] << "};" << std::endl;
4893       stream << varName << "->useArray(" << varName << "Data,false,CPP_DEALLOC," << nbTuples << "," << nbComp << ");" << std::endl;
4894     }
4895   else
4896     stream << varName << "->alloc(" << nbTuples << "," << nbComp << ");" << std::endl;
4897   stream << varName << "->setName(\"" << getName() << "\");" << std::endl;
4898 }
4899
4900 /*!
4901  * Method that gives a quick overvien of \a this for python.
4902  */
4903 void DataArrayInt::reprQuickOverview(std::ostream& stream) const
4904 {
4905   static const std::size_t MAX_NB_OF_BYTE_IN_REPR=300;
4906   stream << "DataArrayInt C++ instance at " << this << ". ";
4907   if(isAllocated())
4908     {
4909       int nbOfCompo=(int)_info_on_compo.size();
4910       if(nbOfCompo>=1)
4911         {
4912           int nbOfTuples=getNumberOfTuples();
4913           stream << "Number of tuples : " << nbOfTuples << ". Number of components : " << nbOfCompo << "." << std::endl;
4914           reprQuickOverviewData(stream,MAX_NB_OF_BYTE_IN_REPR);
4915         }
4916       else
4917         stream << "Number of components : 0.";
4918     }
4919   else
4920     stream << "*** No data allocated ****";
4921 }
4922
4923 void DataArrayInt::reprQuickOverviewData(std::ostream& stream, std::size_t maxNbOfByteInRepr) const
4924 {
4925   const int *data=begin();
4926   int nbOfTuples=getNumberOfTuples();
4927   int nbOfCompo=(int)_info_on_compo.size();
4928   std::ostringstream oss2; oss2 << "[";
4929   std::string oss2Str(oss2.str());
4930   bool isFinished=true;
4931   for(int i=0;i<nbOfTuples && isFinished;i++)
4932     {
4933       if(nbOfCompo>1)
4934         {
4935           oss2 << "(";
4936           for(int j=0;j<nbOfCompo;j++,data++)
4937             {
4938               oss2 << *data;
4939               if(j!=nbOfCompo-1) oss2 << ", ";
4940             }
4941           oss2 << ")";
4942         }
4943       else
4944         oss2 << *data++;
4945       if(i!=nbOfTuples-1) oss2 << ", ";
4946       std::string oss3Str(oss2.str());
4947       if(oss3Str.length()<maxNbOfByteInRepr)
4948         oss2Str=oss3Str;
4949       else
4950         isFinished=false;
4951     }
4952   stream << oss2Str;
4953   if(!isFinished)
4954     stream << "... ";
4955   stream << "]";
4956 }
4957
4958 /*!
4959  * Modifies in place \a this one-dimensional array so that each value \a v = \a indArrBg[ \a v ],
4960  * i.e. a current value is used as in index to get a new value from \a indArrBg.
4961  *  \param [in] indArrBg - pointer to the first element of array of new values to assign
4962  *         to \a this array.
4963  *  \param [in] indArrEnd - specifies the end of the array \a indArrBg, so that
4964  *              the last value of \a indArrBg is \a indArrEnd[ -1 ].
4965  *  \throw If \a this->getNumberOfComponents() != 1
4966  *  \throw If any value of \a this can't be used as a valid index for 
4967  *         [\a indArrBg, \a indArrEnd).
4968  *
4969  *  \sa changeValue
4970  */
4971 void DataArrayInt::transformWithIndArr(const int *indArrBg, const int *indArrEnd)
4972 {
4973   checkAllocated();
4974   if(getNumberOfComponents()!=1)
4975     throw INTERP_KERNEL::Exception("Call transformWithIndArr method on DataArrayInt with only one component, you can call 'rearrange' method before !");
4976   int nbElemsIn((int)std::distance(indArrBg,indArrEnd)),nbOfTuples(getNumberOfTuples()),*pt(getPointer());
4977   for(int i=0;i<nbOfTuples;i++,pt++)
4978     {
4979       if(*pt>=0 && *pt<nbElemsIn)
4980         *pt=indArrBg[*pt];
4981       else
4982         {
4983           std::ostringstream oss; oss << "DataArrayInt::transformWithIndArr : error on tuple #" << i << " of this value is " << *pt << ", should be in [0," << nbElemsIn << ") !";
4984           throw INTERP_KERNEL::Exception(oss.str().c_str());
4985         }
4986     }
4987   declareAsNew();
4988 }
4989
4990 /*!
4991  * Computes distribution of values of \a this one-dimensional array between given value
4992  * ranges (casts). This method is typically useful for entity number spliting by types,
4993  * for example. 
4994  *  \warning The values contained in \a arrBg should be sorted ascendently. No
4995  *           check of this is be done. If not, the result is not warranted. 
4996  *  \param [in] arrBg - the array of ascending values defining the value ranges. The i-th
4997  *         value of \a arrBg (\a arrBg[ i ]) gives the lowest value of the i-th range,
4998  *         and the greatest value of the i-th range equals to \a arrBg[ i+1 ] - 1. \a
4999  *         arrBg containing \a n values defines \a n-1 ranges. The last value of \a arrBg
5000  *         should be more than every value in \a this array.
5001  *  \param [in] arrEnd - specifies the end of the array \a arrBg, so that
5002  *              the last value of \a arrBg is \a arrEnd[ -1 ].
5003  *  \param [out] castArr - a new instance of DataArrayInt, of same size as \a this array
5004  *         (same number of tuples and components), the caller is to delete 
5005  *         using decrRef() as it is no more needed.
5006  *         This array contains indices of ranges for every value of \a this array. I.e.
5007  *         the i-th value of \a castArr gives the index of range the i-th value of \a this
5008  *         belongs to. Or, in other words, this parameter contains for each tuple in \a
5009  *         this in which cast it holds.
5010  *  \param [out] rankInsideCast - a new instance of DataArrayInt, of same size as \a this
5011  *         array, the caller is to delete using decrRef() as it is no more needed.
5012  *         This array contains ranks of values of \a this array within ranges
5013  *         they belongs to. I.e. the i-th value of \a rankInsideCast gives the rank of
5014  *         the i-th value of \a this array within the \a castArr[ i ]-th range, to which
5015  *         the i-th value of \a this belongs to. Or, in other words, this param contains 
5016  *         for each tuple its rank inside its cast. The rank is computed as difference
5017  *         between the value and the lowest value of range.
5018  *  \param [out] castsPresent - a new instance of DataArrayInt, containing indices of
5019  *         ranges (casts) to which at least one value of \a this array belongs.
5020  *         Or, in other words, this param contains the casts that \a this contains.
5021  *         The caller is to delete this array using decrRef() as it is no more needed.
5022  *
5023  * \b Example: If \a this contains [6,5,0,3,2,7,8,1,4] and \a arrBg contains [0,4,9] then
5024  *            the output of this method will be : 
5025  * - \a castArr       : [1,1,0,0,0,1,1,0,1]
5026  * - \a rankInsideCast: [2,1,0,3,2,3,4,1,0]
5027  * - \a castsPresent  : [0,1]
5028  *
5029  * I.e. values of \a this array belong to 2 ranges: #0 and #1. Value 6 belongs to the
5030  * range #1 and its rank within this range is 2; etc.
5031  *
5032  *  \throw If \a this->getNumberOfComponents() != 1.
5033  *  \throw If \a arrEnd - arrBg < 2.
5034  *  \throw If any value of \a this is not less than \a arrEnd[-1].
5035  */
5036 void DataArrayInt::splitByValueRange(const int *arrBg, const int *arrEnd,
5037                                      DataArrayInt *& castArr, DataArrayInt *& rankInsideCast, DataArrayInt *& castsPresent) const
5038 {
5039   checkAllocated();
5040   if(getNumberOfComponents()!=1)
5041     throw INTERP_KERNEL::Exception("Call splitByValueRange  method on DataArrayInt with only one component, you can call 'rearrange' method before !");
5042   int nbOfTuples=getNumberOfTuples();
5043   std::size_t nbOfCast=std::distance(arrBg,arrEnd);
5044   if(nbOfCast<2)
5045     throw INTERP_KERNEL::Exception("DataArrayInt::splitByValueRange : The input array giving the cast range values should be of size >=2 !");
5046   nbOfCast--;
5047   const int *work=getConstPointer();
5048   typedef std::reverse_iterator<const int *> rintstart;
5049   rintstart bg(arrEnd);//OK no problem because size of 'arr' is greater or equal 2
5050   rintstart end2(arrBg);
5051   MCAuto<DataArrayInt> ret1=DataArrayInt::New();
5052   MCAuto<DataArrayInt> ret2=DataArrayInt::New();
5053   MCAuto<DataArrayInt> ret3=DataArrayInt::New();
5054   ret1->alloc(nbOfTuples,1);
5055   ret2->alloc(nbOfTuples,1);
5056   int *ret1Ptr=ret1->getPointer();
5057   int *ret2Ptr=ret2->getPointer();
5058   std::set<std::size_t> castsDetected;
5059   for(int i=0;i<nbOfTuples;i++)
5060     {
5061       rintstart res=std::find_if(bg,end2,std::bind2nd(std::less_equal<int>(), work[i]));
5062       std::size_t pos=std::distance(bg,res);
5063       std::size_t pos2=nbOfCast-pos;
5064       if(pos2<nbOfCast)
5065         {
5066           ret1Ptr[i]=(int)pos2;
5067           ret2Ptr[i]=work[i]-arrBg[pos2];
5068           castsDetected.insert(pos2);
5069         }
5070       else
5071         {
5072           std::ostringstream oss; oss << "DataArrayInt::splitByValueRange : At rank #" << i << " the value is " << work[i] << " should be in [0," << *bg << ") !";
5073           throw INTERP_KERNEL::Exception(oss.str().c_str());
5074         }
5075     }
5076   ret3->alloc((int)castsDetected.size(),1);
5077   std::copy(castsDetected.begin(),castsDetected.end(),ret3->getPointer());
5078   castArr=ret1.retn();
5079   rankInsideCast=ret2.retn();
5080   castsPresent=ret3.retn();
5081 }
5082
5083 /*!
5084  * 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 ).
5085  * 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 ).
5086  * This method works only if \a this is allocated and single component. If not an exception will be thrown.
5087  *
5088  * \param [out] strt - the start of the range (included) if true is returned.
5089  * \param [out] sttoopp - the end of the range (not included) if true is returned.
5090  * \param [out] stteepp - the step of the range if true is returned.
5091  * \return the verdict of the check.
5092  *
5093  * \sa DataArray::GetNumberOfItemGivenBES
5094  */
5095 bool DataArrayInt::isRange(int& strt, int& sttoopp, int& stteepp) const
5096 {
5097   checkAllocated();
5098   if(getNumberOfComponents()!=1)
5099     throw INTERP_KERNEL::Exception("DataArrayInt::isRange : this must be single component array !");
5100   int nbTuples(getNumberOfTuples());
5101   if(nbTuples==0)
5102     { strt=0; sttoopp=0; stteepp=1; return true; }
5103   const int *pt(begin());
5104   strt=*pt; 
5105   if(nbTuples==1)
5106     { sttoopp=strt+1; stteepp=1; return true; }
5107   strt=*pt; sttoopp=pt[nbTuples-1];
5108   if(strt==sttoopp)
5109     return false;
5110   if(sttoopp>strt)
5111     {
5112       sttoopp++;
5113       int a(sttoopp-1-strt),tmp(strt);
5114       if(a%(nbTuples-1)!=0)
5115         return false;
5116       stteepp=a/(nbTuples-1);
5117       for(int i=0;i<nbTuples;i++,tmp+=stteepp)
5118         if(pt[i]!=tmp)
5119           return false;
5120       return true;
5121     }
5122   else
5123     {
5124       sttoopp--;
5125       int a(strt-sttoopp-1),tmp(strt);
5126       if(a%(nbTuples-1)!=0)
5127         return false;
5128       stteepp=-(a/(nbTuples-1));
5129       for(int i=0;i<nbTuples;i++,tmp+=stteepp)
5130         if(pt[i]!=tmp)
5131           return false;
5132       return true;
5133     }
5134 }
5135
5136 /*!
5137  * Creates a one-dimensional DataArrayInt (\a res) whose contents are computed from 
5138  * values of \a this (\a a) and the given (\a indArr) arrays as follows:
5139  * \a res[ \a indArr[ \a a[ i ]]] = i. I.e. for each value in place i \a v = \a a[ i ],
5140  * new value in place \a indArr[ \a v ] is i.
5141  *  \param [in] indArrBg - the array holding indices within the result array to assign
5142  *         indices of values of \a this array pointing to values of \a indArrBg.
5143  *  \param [in] indArrEnd - specifies the end of the array \a indArrBg, so that
5144  *              the last value of \a indArrBg is \a indArrEnd[ -1 ].
5145  *  \return DataArrayInt * - the new instance of DataArrayInt.
5146  *          The caller is to delete this result array using decrRef() as it is no more
5147  *          needed.
5148  *  \throw If \a this->getNumberOfComponents() != 1.
5149  *  \throw If any value of \a this array is not a valid index for \a indArrBg array.
5150  *  \throw If any value of \a indArrBg is not a valid index for \a this array.
5151  */
5152 DataArrayInt *DataArrayInt::transformWithIndArrR(const int *indArrBg, const int *indArrEnd) const
5153 {
5154   checkAllocated();
5155   if(getNumberOfComponents()!=1)
5156     throw INTERP_KERNEL::Exception("Call transformWithIndArrR method on DataArrayInt with only one component, you can call 'rearrange' method before !");
5157   int nbElemsIn=(int)std::distance(indArrBg,indArrEnd);
5158   int nbOfTuples=getNumberOfTuples();
5159   const int *pt=getConstPointer();
5160   MCAuto<DataArrayInt> ret=DataArrayInt::New();
5161   ret->alloc(nbOfTuples,1);
5162   ret->fillWithValue(-1);
5163   int *tmp=ret->getPointer();
5164   for(int i=0;i<nbOfTuples;i++,pt++)
5165     {
5166       if(*pt>=0 && *pt<nbElemsIn)
5167         {
5168           int pos=indArrBg[*pt];
5169           if(pos>=0 && pos<nbOfTuples)
5170             tmp[pos]=i;
5171           else
5172             {
5173               std::ostringstream oss; oss << "DataArrayInt::transformWithIndArrR : error on tuple #" << i << " value of new pos is " << pos << " ( indArrBg[" << *pt << "]) ! Should be in [0," << nbOfTuples << ") !";
5174               throw INTERP_KERNEL::Exception(oss.str().c_str());
5175             }
5176         }
5177       else
5178         {
5179           std::ostringstream oss; oss << "DataArrayInt::transformWithIndArrR : error on tuple #" << i << " value is " << *pt << " and indirectionnal array as a size equal to " << nbElemsIn << " !";
5180           throw INTERP_KERNEL::Exception(oss.str().c_str());
5181         }
5182     }
5183   return ret.retn();
5184 }
5185
5186 /*!
5187  * Creates a one-dimensional DataArrayInt of given length, whose contents are computed
5188  * from values of \a this array, which is supposed to contain a renumbering map in 
5189  * "Old to New" mode. The result array contains a renumbering map in "New to Old" mode.
5190  * To know how to use the renumbering maps see \ref numbering.
5191  *  \param [in] newNbOfElem - the number of tuples in the result array.
5192  *  \return DataArrayInt * - the new instance of DataArrayInt.
5193  *          The caller is to delete this result array using decrRef() as it is no more
5194  *          needed.
5195  * 
5196  *  \if ENABLE_EXAMPLES
5197  *  \ref cpp_mcdataarrayint_invertarrayo2n2n2o "Here is a C++ example".<br>
5198  *  \ref py_mcdataarrayint_invertarrayo2n2n2o  "Here is a Python example".
5199  *  \endif
5200  */
5201 DataArrayInt *DataArrayInt::invertArrayO2N2N2O(int newNbOfElem) const
5202 {
5203   MCAuto<DataArrayInt> ret=DataArrayInt::New();
5204   ret->alloc(newNbOfElem,1);
5205   int nbOfOldNodes=getNumberOfTuples();
5206   const int *old2New=getConstPointer();
5207   int *pt=ret->getPointer();
5208   for(int i=0;i!=nbOfOldNodes;i++)
5209     {
5210       int newp(old2New[i]);
5211       if(newp!=-1)
5212         {
5213           if(newp>=0 && newp<newNbOfElem)
5214             pt[newp]=i;
5215           else
5216             {
5217               std::ostringstream oss; oss << "DataArrayInt::invertArrayO2N2N2O : At place #" << i << " the newplace is " << newp << " must be in [0," << newNbOfElem << ") !";
5218               throw INTERP_KERNEL::Exception(oss.str().c_str());
5219             }
5220         }
5221     }
5222   return ret.retn();
5223 }
5224
5225 /*!
5226  * This method is similar to DataArrayInt::invertArrayO2N2N2O except that 
5227  * 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]
5228  */
5229 DataArrayInt *DataArrayInt::invertArrayO2N2N2OBis(int newNbOfElem) const
5230 {
5231   MCAuto<DataArrayInt> ret=DataArrayInt::New();
5232   ret->alloc(newNbOfElem,1);
5233   int nbOfOldNodes=getNumberOfTuples();
5234   const int *old2New=getConstPointer();
5235   int *pt=ret->getPointer();
5236   for(int i=nbOfOldNodes-1;i>=0;i--)
5237     {
5238       int newp(old2New[i]);
5239       if(newp!=-1)
5240         {
5241           if(newp>=0 && newp<newNbOfElem)
5242             pt[newp]=i;
5243           else
5244             {
5245               std::ostringstream oss; oss << "DataArrayInt::invertArrayO2N2N2OBis : At place #" << i << " the newplace is " << newp << " must be in [0," << newNbOfElem << ") !";
5246               throw INTERP_KERNEL::Exception(oss.str().c_str());
5247             }
5248         }
5249     }
5250   return ret.retn();
5251 }
5252
5253 /*!
5254  * Creates a one-dimensional DataArrayInt of given length, whose contents are computed
5255  * from values of \a this array, which is supposed to contain a renumbering map in 
5256  * "New to Old" mode. The result array contains a renumbering map in "Old to New" mode.
5257  * To know how to use the renumbering maps see \ref numbering.
5258  *  \param [in] newNbOfElem - the number of tuples in the result array.
5259  *  \return DataArrayInt * - the new instance of DataArrayInt.
5260  *          The caller is to delete this result array using decrRef() as it is no more
5261  *          needed.
5262  * 
5263  *  \if ENABLE_EXAMPLES
5264  *  \ref cpp_mcdataarrayint_invertarrayn2o2o2n "Here is a C++ example".
5265  *
5266  *  \ref py_mcdataarrayint_invertarrayn2o2o2n "Here is a Python example".
5267  *  \endif
5268  */
5269 DataArrayInt *DataArrayInt::invertArrayN2O2O2N(int oldNbOfElem) const
5270 {
5271   checkAllocated();
5272   MCAuto<DataArrayInt> ret=DataArrayInt::New();
5273   ret->alloc(oldNbOfElem,1);
5274   const int *new2Old=getConstPointer();
5275   int *pt=ret->getPointer();
5276   std::fill(pt,pt+oldNbOfElem,-1);
5277   int nbOfNewElems=getNumberOfTuples();
5278   for(int i=0;i<nbOfNewElems;i++)
5279     {
5280       int v(new2Old[i]);
5281       if(v>=0 && v<oldNbOfElem)
5282         pt[v]=i;
5283       else
5284         {
5285           std::ostringstream oss; oss << "DataArrayInt::invertArrayN2O2O2N : in new id #" << i << " old value is " << v << " expected to be in [0," << oldNbOfElem << ") !";
5286           throw INTERP_KERNEL::Exception(oss.str().c_str());
5287         }
5288     }
5289   return ret.retn();
5290 }
5291
5292 /*!
5293  * Equivalent to DataArrayInt::isEqual except that if false the reason of
5294  * mismatch is given.
5295  * 
5296  * \param [in] other the instance to be compared with \a this
5297  * \param [out] reason In case of inequality returns the reason.
5298  * \sa DataArrayInt::isEqual
5299  */
5300 bool DataArrayInt::isEqualIfNotWhy(const DataArrayInt& other, std::string& reason) const
5301 {
5302   if(!areInfoEqualsIfNotWhy(other,reason))
5303     return false;
5304   return _mem.isEqual(other._mem,0,reason);
5305 }
5306
5307 /*!
5308  * Checks if \a this and another DataArrayInt are fully equal. For more info see
5309  * \ref MEDCouplingArrayBasicsCompare.
5310  *  \param [in] other - an instance of DataArrayInt to compare with \a this one.
5311  *  \return bool - \a true if the two arrays are equal, \a false else.
5312  */
5313 bool DataArrayInt::isEqual(const DataArrayInt& other) const
5314 {
5315   std::string tmp;
5316   return isEqualIfNotWhy(other,tmp);
5317 }
5318
5319 /*!
5320  * Checks if values of \a this and another DataArrayInt are equal. For more info see
5321  * \ref MEDCouplingArrayBasicsCompare.
5322  *  \param [in] other - an instance of DataArrayInt to compare with \a this one.
5323  *  \return bool - \a true if the values of two arrays are equal, \a false else.
5324  */
5325 bool DataArrayInt::isEqualWithoutConsideringStr(const DataArrayInt& other) const
5326 {
5327   std::string tmp;
5328   return _mem.isEqual(other._mem,0,tmp);
5329 }
5330
5331 /*!
5332  * Checks if values of \a this and another DataArrayInt are equal. Comparison is
5333  * performed on sorted value sequences.
5334  * For more info see\ref MEDCouplingArrayBasicsCompare.
5335  *  \param [in] other - an instance of DataArrayInt to compare with \a this one.
5336  *  \return bool - \a true if the sorted values of two arrays are equal, \a false else.
5337  */
5338 bool DataArrayInt::isEqualWithoutConsideringStrAndOrder(const DataArrayInt& other) const
5339 {
5340   MCAuto<DataArrayInt> a=deepCopy();
5341   MCAuto<DataArrayInt> b=other.deepCopy();
5342   a->sort();
5343   b->sort();
5344   return a->isEqualWithoutConsideringStr(*b);
5345 }
5346
5347 /*!
5348  * This method compares content of input vector \a v and \a this.
5349  * 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.
5350  * For performance reasons \a this is expected to be sorted ascendingly. If not an exception will be thrown.
5351  *
5352  * \param [in] v - the vector of 'flags' to be compared with \a this.
5353  *
5354  * \throw If \a this is not sorted ascendingly.
5355  * \throw If \a this has not exactly one component.
5356  * \throw If \a this is not allocated.
5357  */
5358 bool DataArrayInt::isFittingWith(const std::vector<bool>& v) const
5359 {
5360   checkAllocated();
5361   if(getNumberOfComponents()!=1)
5362     throw INTERP_KERNEL::Exception("DataArrayInt::isFittingWith : number of components of this should be equal to one !");
5363   const int *w(begin()),*end2(end());
5364   int refVal=-std::numeric_limits<int>::max();
5365   int i=0;
5366   std::vector<bool>::const_iterator it(v.begin());
5367   for(;it!=v.end();it++,i++)
5368     {
5369       if(*it)
5370         {
5371           if(w!=end2)
5372             {
5373               if(*w++==i)
5374                 {
5375                   if(i>refVal)
5376                     refVal=i;
5377                   else
5378                     {
5379                       std::ostringstream oss; oss << "DataArrayInt::isFittingWith : At pos #" << std::distance(begin(),w-1) << " this is not sorted ascendingly !";
5380                       throw INTERP_KERNEL::Exception(oss.str().c_str());
5381                     }
5382                 }
5383               else
5384                 return false;
5385             }
5386           else
5387             return false;
5388         }
5389     }
5390   return w==end2;
5391 }
5392
5393 /*!
5394  * 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
5395  * put True to the corresponding entry in \a vec.
5396  * \a vec is expected to be with the same size than the number of tuples of \a this.
5397  *
5398  *  \sa DataArrayInt::switchOnTupleNotEqualTo.
5399  */
5400 void DataArrayInt::switchOnTupleEqualTo(int val, std::vector<bool>& vec) const
5401 {
5402   checkAllocated();
5403   if(getNumberOfComponents()!=1)
5404     throw INTERP_KERNEL::Exception("DataArrayInt::switchOnTupleEqualTo : number of components of this should be equal to one !");
5405   int nbOfTuples(getNumberOfTuples());
5406   if(nbOfTuples!=(int)vec.size())
5407     throw INTERP_KERNEL::Exception("DataArrayInt::switchOnTupleEqualTo : number of tuples of this should be equal to size of input vector of bool !");
5408   const int *pt(begin());
5409   for(int i=0;i<nbOfTuples;i++)
5410     if(pt[i]==val)
5411       vec[i]=true;
5412 }
5413
5414 /*!
5415  * 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
5416  * put True to the corresponding entry in \a vec.
5417  * \a vec is expected to be with the same size than the number of tuples of \a this.
5418  * 
5419  *  \sa DataArrayInt::switchOnTupleEqualTo.
5420  */
5421 void DataArrayInt::switchOnTupleNotEqualTo(int val, std::vector<bool>& vec) const
5422 {
5423   checkAllocated();
5424   if(getNumberOfComponents()!=1)
5425     throw INTERP_KERNEL::Exception("DataArrayInt::switchOnTupleNotEqualTo : number of components of this should be equal to one !");
5426   int nbOfTuples(getNumberOfTuples());
5427   if(nbOfTuples!=(int)vec.size())
5428     throw INTERP_KERNEL::Exception("DataArrayInt::switchOnTupleNotEqualTo : number of tuples of this should be equal to size of input vector of bool !");
5429   const int *pt(begin());
5430   for(int i=0;i<nbOfTuples;i++)
5431     if(pt[i]!=val)
5432       vec[i]=true;
5433 }
5434
5435 /*!
5436  * Computes for each tuple the sum of number of components values in the tuple and return it.
5437  * 
5438  * \return DataArrayInt * - the new instance of DataArrayInt containing the
5439  *          same number of tuples as \a this array and one component.
5440  *          The caller is to delete this result array using decrRef() as it is no more
5441  *          needed.
5442  *  \throw If \a this is not allocated.
5443  */
5444 DataArrayInt *DataArrayInt::sumPerTuple() const
5445 {
5446   checkAllocated();
5447   int nbOfComp(getNumberOfComponents()),nbOfTuple(getNumberOfTuples());
5448   MCAuto<DataArrayInt> ret(DataArrayInt::New());
5449   ret->alloc(nbOfTuple,1);
5450   const int *src(getConstPointer());
5451   int *dest(ret->getPointer());
5452   for(int i=0;i<nbOfTuple;i++,dest++,src+=nbOfComp)
5453     *dest=std::accumulate(src,src+nbOfComp,0);
5454   return ret.retn();
5455 }
5456
5457 /*!
5458  * Checks that \a this array is consistently **increasing** or **decreasing** in value.
5459  * If not an exception is thrown.
5460  *  \param [in] increasing - if \a true, the array values should be increasing.
5461  *  \throw If sequence of values is not strictly monotonic in agreement with \a
5462  *         increasing arg.
5463  *  \throw If \a this->getNumberOfComponents() != 1.
5464  *  \throw If \a this is not allocated.
5465  */
5466 void DataArrayInt::checkMonotonic(bool increasing) const
5467 {
5468   if(!isMonotonic(increasing))
5469     {
5470       if (increasing)
5471         throw INTERP_KERNEL::Exception("DataArrayInt::checkMonotonic : 'this' is not INCREASING monotonic !");
5472       else
5473         throw INTERP_KERNEL::Exception("DataArrayInt::checkMonotonic : 'this' is not DECREASING monotonic !");
5474     }
5475 }
5476
5477 /*!
5478  * Checks that \a this array is consistently **increasing** or **decreasing** in value.
5479  *  \param [in] increasing - if \a true, array values should be increasing.
5480  *  \return bool - \a true if values change in accordance with \a increasing arg.
5481  *  \throw If \a this->getNumberOfComponents() != 1.
5482  *  \throw If \a this is not allocated.
5483  */
5484 bool DataArrayInt::isMonotonic(bool increasing) const
5485 {
5486   checkAllocated();
5487   if(getNumberOfComponents()!=1)
5488     throw INTERP_KERNEL::Exception("DataArrayInt::isMonotonic : only supported with 'this' array with ONE component !");
5489   int nbOfElements=getNumberOfTuples();
5490   const int *ptr=getConstPointer();
5491   if(nbOfElements==0)
5492     return true;
5493   int ref=ptr[0];
5494   if(increasing)
5495     {
5496       for(int i=1;i<nbOfElements;i++)
5497         {
5498           if(ptr[i]>=ref)
5499             ref=ptr[i];
5500           else
5501             return false;
5502         }
5503     }
5504   else
5505     {
5506       for(int i=1;i<nbOfElements;i++)
5507         {
5508           if(ptr[i]<=ref)
5509             ref=ptr[i];
5510           else
5511             return false;
5512         }
5513     }
5514   return true;
5515 }
5516
5517 /*!
5518  * This method check that array consistently INCREASING or DECREASING in value.
5519  */
5520 bool DataArrayInt::isStrictlyMonotonic(bool increasing) const
5521 {
5522   checkAllocated();
5523   if(getNumberOfComponents()!=1)
5524     throw INTERP_KERNEL::Exception("DataArrayInt::isStrictlyMonotonic : only supported with 'this' array with ONE component !");
5525   int nbOfElements=getNumberOfTuples();
5526   const int *ptr=getConstPointer();
5527   if(nbOfElements==0)
5528     return true;
5529   int ref=ptr[0];
5530   if(increasing)
5531     {
5532       for(int i=1;i<nbOfElements;i++)
5533         {
5534           if(ptr[i]>ref)
5535             ref=ptr[i];
5536           else
5537             return false;
5538         }
5539     }
5540   else
5541     {
5542       for(int i=1;i<nbOfElements;i++)
5543         {
5544           if(ptr[i]<ref)
5545             ref=ptr[i];
5546           else
5547             return false;
5548         }
5549     }
5550   return true;
5551 }
5552
5553 /*!
5554  * This method check that array consistently INCREASING or DECREASING in value.
5555  */
5556 void DataArrayInt::checkStrictlyMonotonic(bool increasing) const
5557 {
5558   if(!isStrictlyMonotonic(increasing))
5559     {
5560       if (increasing)
5561         throw INTERP_KERNEL::Exception("DataArrayInt::checkStrictlyMonotonic : 'this' is not strictly INCREASING monotonic !");
5562       else
5563         throw INTERP_KERNEL::Exception("DataArrayInt::checkStrictlyMonotonic : 'this' is not strictly DECREASING monotonic !");
5564     }
5565 }
5566
5567 /*!
5568  * Creates a new one-dimensional DataArrayInt of the same size as \a this and a given
5569  * one-dimensional arrays that must be of the same length. The result array describes
5570  * correspondence between \a this and \a other arrays, so that 
5571  * <em> other.getIJ(i,0) == this->getIJ(ret->getIJ(i),0)</em>. If such a permutation is
5572  * not possible because some element in \a other is not in \a this, an exception is thrown.
5573  *  \param [in] other - an array to compute permutation to.
5574  *  \return DataArrayInt * - a new instance of DataArrayInt, which is a permutation array
5575  * from \a this to \a other. The caller is to delete this array using decrRef() as it is
5576  * no more needed.
5577  *  \throw If \a this->getNumberOfComponents() != 1.
5578  *  \throw If \a other->getNumberOfComponents() != 1.
5579  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples().
5580  *  \throw If \a other includes a value which is not in \a this array.
5581  * 
5582  *  \if ENABLE_EXAMPLES
5583  *  \ref cpp_mcdataarrayint_buildpermutationarr "Here is a C++ example".
5584  *
5585  *  \ref py_mcdataarrayint_buildpermutationarr "Here is a Python example".
5586  *  \endif
5587  */
5588 DataArrayInt *DataArrayInt::buildPermutationArr(const DataArrayInt& other) const
5589 {
5590   checkAllocated();
5591   if(getNumberOfComponents()!=1 || other.getNumberOfComponents()!=1)
5592     throw INTERP_KERNEL::Exception("DataArrayInt::buildPermutationArr : 'this' and 'other' have to have exactly ONE component !");
5593   int nbTuple=getNumberOfTuples();
5594   other.checkAllocated();
5595   if(nbTuple!=other.getNumberOfTuples())
5596     throw INTERP_KERNEL::Exception("DataArrayInt::buildPermutationArr : 'this' and 'other' must have the same number of tuple !");
5597   MCAuto<DataArrayInt> ret=DataArrayInt::New();
5598   ret->alloc(nbTuple,1);
5599   ret->fillWithValue(-1);
5600   const int *pt=getConstPointer();
5601   std::map<int,int> mm;
5602   for(int i=0;i<nbTuple;i++)
5603     mm[pt[i]]=i;
5604   pt=other.getConstPointer();
5605   int *retToFill=ret->getPointer();
5606   for(int i=0;i<nbTuple;i++)
5607     {
5608       std::map<int,int>::const_iterator it=mm.find(pt[i]);
5609       if(it==mm.end())
5610         {
5611           std::ostringstream oss; oss << "DataArrayInt::buildPermutationArr : Arrays mismatch : element (" << pt[i] << ") in 'other' not findable in 'this' !";
5612           throw INTERP_KERNEL::Exception(oss.str().c_str());
5613         }
5614       retToFill[i]=(*it).second;
5615     }
5616   return ret.retn();
5617 }
5618
5619 /*!
5620  * Elements of \a partOfThis are expected to be included in \a this.
5621  * The returned array \a ret is so that this[ret]==partOfThis
5622  *
5623  * For example, if \a this array contents are [9,10,0,6,4,11,3,8] and if \a partOfThis contains [6,0,11,8]
5624  * the return array will contain [3,2,5,7].
5625  *
5626  * \a this is expected to be a 1 compo allocated array.
5627  * \param [in] partOfThis - A 1 compo allocated array
5628  * \return - A newly allocated array to be dealed by caller having the same number of tuples than \a partOfThis.
5629  * \throw if two same element is present twice in \a this
5630  * \throw if an element in \a partOfThis is \b NOT in \a this.
5631  */
5632 DataArrayInt *DataArrayInt::indicesOfSubPart(const DataArrayInt& partOfThis) const
5633 {
5634   if(getNumberOfComponents()!=1 || partOfThis.getNumberOfComponents()!=1)
5635     throw INTERP_KERNEL::Exception("DataArrayInt::indicesOfSubPart : this and input array must be one component array !");
5636   checkAllocated(); partOfThis.checkAllocated();
5637   int thisNbTuples(getNumberOfTuples()),nbTuples(partOfThis.getNumberOfTuples());
5638   const int *thisPt(begin()),*pt(partOfThis.begin());
5639   MCAuto<DataArrayInt> ret(DataArrayInt::New());
5640   ret->alloc(nbTuples,1);
5641   int *retPt(ret->getPointer());
5642   std::map<int,int> m;
5643   for(int i=0;i<thisNbTuples;i++,thisPt++)
5644     m[*thisPt]=i;
5645   if(m.size()!=thisNbTuples)
5646     throw INTERP_KERNEL::Exception("DataArrayInt::indicesOfSubPart : some elements appears more than once !");
5647   for(int i=0;i<nbTuples;i++,retPt++,pt++)
5648     {
5649       std::map<int,int>::const_iterator it(m.find(*pt));
5650       if(it!=m.end())
5651         *retPt=(*it).second;
5652       else
5653         {
5654           std::ostringstream oss; oss << "DataArrayInt::indicesOfSubPart : At pos #" << i << " of input array value is " << *pt << " not in this !";
5655           throw INTERP_KERNEL::Exception(oss.str());
5656         }
5657     }
5658   return ret.retn();
5659 }
5660
5661 void DataArrayInt::aggregate(const DataArrayInt *other)
5662 {
5663   if(!other)
5664     throw INTERP_KERNEL::Exception("DataArrayInt::aggregate : null pointer !");
5665   if(getNumberOfComponents()!=other->getNumberOfComponents())
5666     throw INTERP_KERNEL::Exception("DataArrayInt::aggregate : mismatch number of components !");
5667   _mem.insertAtTheEnd(other->begin(),other->end());
5668 }
5669
5670 /*!
5671  * Returns a new DataArrayInt holding the same values as \a this array but differently
5672  * arranged in memory. If \a this array holds 2 components of 3 values:
5673  * \f$ x_0,x_1,x_2,y_0,y_1,y_2 \f$, then the result array holds these values arranged
5674  * as follows: \f$ x_0,y_0,x_1,y_1,x_2,y_2 \f$.
5675  *  \warning Do not confuse this method with transpose()!
5676  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
5677  *          is to delete using decrRef() as it is no more needed.
5678  *  \throw If \a this is not allocated.
5679  */
5680 DataArrayInt *DataArrayInt::fromNoInterlace() const
5681 {
5682   checkAllocated();
5683   if(_mem.isNull())
5684     throw INTERP_KERNEL::Exception("DataArrayInt::fromNoInterlace : Not defined array !");
5685   int *tab=_mem.fromNoInterlace(getNumberOfComponents());
5686   DataArrayInt *ret=DataArrayInt::New();
5687   ret->useArray(tab,true,C_DEALLOC,getNumberOfTuples(),getNumberOfComponents());
5688   return ret;
5689 }
5690
5691 /*!
5692  * Returns a new DataArrayInt holding the same values as \a this array but differently
5693  * arranged in memory. If \a this array holds 2 components of 3 values:
5694  * \f$ x_0,y_0,x_1,y_1,x_2,y_2 \f$, then the result array holds these values arranged
5695  * as follows: \f$ x_0,x_1,x_2,y_0,y_1,y_2 \f$.
5696  *  \warning Do not confuse this method with transpose()!
5697  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
5698  *          is to delete using decrRef() as it is no more needed.
5699  *  \throw If \a this is not allocated.
5700  */
5701 DataArrayInt *DataArrayInt::toNoInterlace() const
5702 {
5703   checkAllocated();
5704   if(_mem.isNull())
5705     throw INTERP_KERNEL::Exception("DataArrayInt::toNoInterlace : Not defined array !");
5706   int *tab=_mem.toNoInterlace(getNumberOfComponents());
5707   DataArrayInt *ret=DataArrayInt::New();
5708   ret->useArray(tab,true,C_DEALLOC,getNumberOfTuples(),getNumberOfComponents());
5709   return ret;
5710 }
5711
5712 /*!
5713  * Returns a new DataArrayInt containing a renumbering map in "Old to New" mode.
5714  * This map, if applied to \a this array, would make it sorted. For example, if
5715  * \a this array contents are [9,10,0,6,4,11,3,7] then the contents of the result array
5716  * are [5,6,0,3,2,7,1,4]; if this result array (\a res) is used as an argument in call
5717  * \a this->renumber(\a res) then the returned array contains [0,3,4,6,7,9,10,11].
5718  * This method is useful for renumbering (in MED file for example). For more info
5719  * on renumbering see \ref numbering.
5720  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
5721  *          array using decrRef() as it is no more needed.
5722  *  \throw If \a this is not allocated.
5723  *  \throw If \a this->getNumberOfComponents() != 1.
5724  *  \throw If there are equal values in \a this array.
5725  */
5726 DataArrayInt *DataArrayInt::checkAndPreparePermutation() const
5727 {
5728   checkAllocated();
5729   if(getNumberOfComponents()!=1)
5730     throw INTERP_KERNEL::Exception("DataArrayInt::checkAndPreparePermutation : number of components must == 1 !");
5731   int nbTuples=getNumberOfTuples();
5732   const int *pt=getConstPointer();
5733   int *pt2=CheckAndPreparePermutation(pt,pt+nbTuples);
5734   DataArrayInt *ret=DataArrayInt::New();
5735   ret->useArray(pt2,true,C_DEALLOC,nbTuples,1);
5736   return ret;
5737 }
5738
5739 /*!
5740  * 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
5741  * input array \a ids2.
5742  * \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.
5743  * 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
5744  * inversely.
5745  * In case of success (no throw) : \c ids1->renumber(ret)->isEqual(ids2) where \a ret is the return of this method.
5746  *
5747  * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
5748  *          array using decrRef() as it is no more needed.
5749  * \throw If either ids1 or ids2 is null not allocated or not with one components.
5750  * 
5751  */
5752 DataArrayInt *DataArrayInt::FindPermutationFromFirstToSecond(const DataArrayInt *ids1, const DataArrayInt *ids2)
5753 {
5754   if(!ids1 || !ids2)
5755     throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two input arrays must be not null !");
5756   if(!ids1->isAllocated() || !ids2->isAllocated())
5757     throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two input arrays must be allocated !");
5758   if(ids1->getNumberOfComponents()!=1 || ids2->getNumberOfComponents()!=1)
5759     throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two input arrays have exactly one component !");
5760   if(ids1->getNumberOfTuples()!=ids2->getNumberOfTuples())
5761     {
5762       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 !";
5763       throw INTERP_KERNEL::Exception(oss.str().c_str());
5764     }
5765   MCAuto<DataArrayInt> p1(ids1->deepCopy());
5766   MCAuto<DataArrayInt> p2(ids2->deepCopy());
5767   p1->sort(true); p2->sort(true);
5768   if(!p1->isEqualWithoutConsideringStr(*p2))
5769     throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two arrays are not lying on same ids ! Impossible to find a permutation between the 2 arrays !");
5770   p1=ids1->checkAndPreparePermutation();
5771   p2=ids2->checkAndPreparePermutation();
5772   p2=p2->invertArrayO2N2N2O(p2->getNumberOfTuples());
5773   p2=p2->selectByTupleIdSafe(p1->begin(),p1->end());
5774   return p2.retn();
5775 }
5776
5777 /*!
5778  * Returns two arrays describing a surjective mapping from \a this set of values (\a A)
5779  * onto a set of values of size \a targetNb (\a B). The surjective function is 
5780  * \a B[ \a A[ i ]] = i. That is to say that for each \a id in [0,\a targetNb), where \a
5781  * targetNb < \a this->getNumberOfTuples(), there exists at least one tupleId (\a tid) so
5782  * that <em> this->getIJ( tid, 0 ) == id</em>. <br>
5783  * The first of out arrays returns indices of elements of \a this array, grouped by their
5784  * place in the set \a B. The second out array is the index of the first one; it shows how
5785  * many elements of \a A are mapped into each element of \a B. <br>
5786  * For more info on
5787  * mapping and its usage in renumbering see \ref numbering. <br>
5788  * \b Example:
5789  * - \a this: [0,3,2,3,2,2,1,2]
5790  * - \a targetNb: 4
5791  * - \a arr:  [0,  6,  2,4,5,7,  1,3]
5792  * - \a arrI: [0,1,2,6,8]
5793  *
5794  * This result means: <br>
5795  * the element of \a B 0 encounters within \a A once (\a arrI[ 0+1 ] - \a arrI[ 0 ]) and
5796  * its index within \a A is 0 ( \a arr[ 0:1 ] == \a arr[ \a arrI[ 0 ] : \a arrI[ 0+1 ]]);<br>
5797  * the element of \a B 2 encounters within \a A 4 times (\a arrI[ 2+1 ] - \a arrI[ 2 ]) and
5798  * its indices within \a A are [2,4,5,7] ( \a arr[ 2:6 ] == \a arr[ \a arrI[ 2 ] : 
5799  * \a arrI[ 2+1 ]]); <br> etc.
5800  *  \param [in] targetNb - the size of the set \a B. \a targetNb must be equal or more
5801  *         than the maximal value of \a A.
5802  *  \param [out] arr - a new instance of DataArrayInt returning indices of
5803  *         elements of \a this, grouped by their place in the set \a B. The caller is to delete
5804  *         this array using decrRef() as it is no more needed.
5805  *  \param [out] arrI - a new instance of DataArrayInt returning size of groups of equal
5806  *         elements of \a this. The caller is to delete this array using decrRef() as it
5807  *         is no more needed.
5808  *  \throw If \a this is not allocated.
5809  *  \throw If \a this->getNumberOfComponents() != 1.
5810  *  \throw If any value in \a this is more or equal to \a targetNb.
5811  */
5812 void DataArrayInt::changeSurjectiveFormat(int targetNb, DataArrayInt *&arr, DataArrayInt *&arrI) const
5813 {
5814   checkAllocated();
5815   if(getNumberOfComponents()!=1)
5816     throw INTERP_KERNEL::Exception("DataArrayInt::changeSurjectiveFormat : number of components must == 1 !");
5817   int nbOfTuples=getNumberOfTuples();
5818   MCAuto<DataArrayInt> ret(DataArrayInt::New());
5819   MCAuto<DataArrayInt> retI(DataArrayInt::New());
5820   retI->alloc(targetNb+1,1);
5821   const int *input=getConstPointer();
5822   std::vector< std::vector<int> > tmp(targetNb);
5823   for(int i=0;i<nbOfTuples;i++)
5824     {
5825       int tmp2=input[i];
5826       if(tmp2>=0 && tmp2<targetNb)
5827         tmp[tmp2].push_back(i);
5828       else
5829         {
5830           std::ostringstream oss; oss << "DataArrayInt::changeSurjectiveFormat : At pos " << i << " presence of element " << tmp2 << " ! should be in [0," << targetNb << ") !";
5831           throw INTERP_KERNEL::Exception(oss.str().c_str());
5832         }
5833     }
5834   int *retIPtr=retI->getPointer();
5835   *retIPtr=0;
5836   for(std::vector< std::vector<int> >::const_iterator it1=tmp.begin();it1!=tmp.end();it1++,retIPtr++)
5837     retIPtr[1]=retIPtr[0]+(int)((*it1).size());
5838   if(nbOfTuples!=retI->getIJ(targetNb,0))
5839     throw INTERP_KERNEL::Exception("DataArrayInt::changeSurjectiveFormat : big problem should never happen !");
5840   ret->alloc(nbOfTuples,1);
5841   int *retPtr=ret->getPointer();
5842   for(std::vector< std::vector<int> >::const_iterator it1=tmp.begin();it1!=tmp.end();it1++)
5843     retPtr=std::copy((*it1).begin(),(*it1).end(),retPtr);
5844   arr=ret.retn();
5845   arrI=retI.retn();
5846 }
5847
5848
5849 /*!
5850  * Returns a new DataArrayInt containing a renumbering map in "Old to New" mode computed
5851  * from a zip representation of a surjective format (returned e.g. by
5852  * \ref MEDCoupling::DataArrayDouble::findCommonTuples() "DataArrayDouble::findCommonTuples()"
5853  * for example). The result array minimizes the permutation. <br>
5854  * For more info on renumbering see \ref numbering. <br>
5855  * \b Example: <br>
5856  * - \a nbOfOldTuples: 10 
5857  * - \a arr          : [0,3, 5,7,9]
5858  * - \a arrIBg       : [0,2,5]
5859  * - \a newNbOfTuples: 7
5860  * - result array    : [0,1,2,0,3,4,5,4,6,4]
5861  *
5862  *  \param [in] nbOfOldTuples - number of tuples in the initial array \a arr.
5863  *  \param [in] arr - the array of tuple indices grouped by \a arrIBg array.
5864  *  \param [in] arrIBg - the array dividing all indices stored in \a arr into groups of
5865  *         (indices of) equal values. Its every element (except the last one) points to
5866  *         the first element of a group of equal values.
5867  *  \param [in] arrIEnd - specifies the end of \a arrIBg, so that the last element of \a
5868  *          arrIBg is \a arrIEnd[ -1 ].
5869  *  \param [out] newNbOfTuples - number of tuples after surjection application.
5870  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
5871  *          array using decrRef() as it is no more needed.
5872  *  \throw If any value of \a arr breaks condition ( 0 <= \a arr[ i ] < \a nbOfOldTuples ).
5873  */
5874 DataArrayInt *DataArrayInt::ConvertIndexArrayToO2N(int nbOfOldTuples, const int *arr, const int *arrIBg, const int *arrIEnd, int &newNbOfTuples)
5875 {
5876   MCAuto<DataArrayInt> ret=DataArrayInt::New();
5877   ret->alloc(nbOfOldTuples,1);
5878   int *pt=ret->getPointer();
5879   std::fill(pt,pt+nbOfOldTuples,-1);
5880   int nbOfGrps=((int)std::distance(arrIBg,arrIEnd))-1;
5881   const int *cIPtr=arrIBg;
5882   for(int i=0;i<nbOfGrps;i++)
5883     pt[arr[cIPtr[i]]]=-(i+2);
5884   int newNb=0;
5885   for(int iNode=0;iNode<nbOfOldTuples;iNode++)
5886     {
5887       if(pt[iNode]<0)
5888         {
5889           if(pt[iNode]==-1)
5890             pt[iNode]=newNb++;
5891           else
5892             {
5893               int grpId=-(pt[iNode]+2);
5894               for(int j=cIPtr[grpId];j<cIPtr[grpId+1];j++)
5895                 {
5896                   if(arr[j]>=0 && arr[j]<nbOfOldTuples)
5897                     pt[arr[j]]=newNb;
5898                   else
5899                     {
5900                       std::ostringstream oss; oss << "DataArrayInt::ConvertIndexArrayToO2N : With element #" << j << " value is " << arr[j] << " should be in [0," << nbOfOldTuples << ") !";
5901                       throw INTERP_KERNEL::Exception(oss.str().c_str());
5902                     }
5903                 }
5904               newNb++;
5905             }
5906         }
5907     }
5908   newNbOfTuples=newNb;
5909   return ret.retn();
5910 }
5911
5912 /*!
5913  * Returns a new DataArrayInt containing a renumbering map in "New to Old" mode,
5914  * which if applied to \a this array would make it sorted ascendingly.
5915  * For more info on renumbering see \ref numbering. <br>
5916  * \b Example: <br>
5917  * - \a this: [2,0,1,1,0,1,2,0,1,1,0,0]
5918  * - result: [10,0,5,6,1,7,11,2,8,9,3,4]
5919  * - after applying result to \a this: [0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2] 
5920  *
5921  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
5922  *          array using decrRef() as it is no more needed.
5923  *  \throw If \a this is not allocated.
5924  *  \throw If \a this->getNumberOfComponents() != 1.
5925  */
5926 DataArrayInt *DataArrayInt::buildPermArrPerLevel() const
5927 {
5928   checkAllocated();
5929   if(getNumberOfComponents()!=1)
5930     throw INTERP_KERNEL::Exception("DataArrayInt::buildPermArrPerLevel : number of components must == 1 !");
5931   int nbOfTuples=getNumberOfTuples();
5932   const int *pt=getConstPointer();
5933   std::map<int,int> m;
5934   MCAuto<DataArrayInt> ret=DataArrayInt::New();
5935   ret->alloc(nbOfTuples,1);
5936   int *opt=ret->getPointer();
5937   for(int i=0;i<nbOfTuples;i++,pt++,opt++)
5938     {
5939       int val=*pt;
5940       std::map<int,int>::iterator it=m.find(val);
5941       if(it!=m.end())
5942         {
5943           *opt=(*it).second;
5944           (*it).second++;
5945         }
5946       else
5947         {
5948           *opt=0;
5949           m.insert(std::pair<int,int>(val,1));
5950         }
5951     }
5952   int sum=0;
5953   for(std::map<int,int>::iterator it=m.begin();it!=m.end();it++)
5954     {
5955       int vt=(*it).second;
5956       (*it).second=sum;
5957       sum+=vt;
5958     }
5959   pt=getConstPointer();
5960   opt=ret->getPointer();
5961   for(int i=0;i<nbOfTuples;i++,pt++,opt++)
5962     *opt+=m[*pt];
5963   //
5964   return ret.retn();
5965 }
5966
5967 /*!
5968  * Checks if \a this array has the given size, and if its contents is equal to an array filled with
5969  * iota(). This method is particularly useful for DataArrayInt instances that represent
5970  * a renumbering array, to check if there is a real need in renumbering.
5971  * This method checks than \a this can be considered as an identity mapping
5972  * of a set having \a sizeExpected elements into itself.
5973  *
5974  *  \param [in] sizeExpected - The number of elements expected.
5975  *  \return bool - \a true if \a this array contents == \a range( \a this->getNumberOfTuples())
5976  *  \throw If \a this is not allocated.
5977  *  \throw If \a this->getNumberOfComponents() != 1.
5978  */
5979 bool DataArrayInt::isIota(int sizeExpected) const
5980 {
5981   checkAllocated();
5982   if(getNumberOfComponents()!=1)
5983     return false;
5984   int nbOfTuples(getNumberOfTuples());
5985   if(nbOfTuples!=sizeExpected)
5986     return false;
5987   const int *pt=getConstPointer();
5988   for(int i=0;i<nbOfTuples;i++,pt++)
5989     if(*pt!=i)
5990       return false;
5991   return true;
5992 }
5993
5994 /*!
5995  * Checks if all values in \a this array are equal to \a val.
5996  *  \param [in] val - value to check equality of array values to.
5997  *  \return bool - \a true if all values are \a val.
5998  *  \throw If \a this is not allocated.
5999  *  \throw If \a this->getNumberOfComponents() != 1
6000  */
6001 bool DataArrayInt::isUniform(int val) const
6002 {
6003   checkAllocated();
6004   if(getNumberOfComponents()!=1)
6005     throw INTERP_KERNEL::Exception("DataArrayInt::isUniform : must be applied on DataArrayInt with only one component, you can call 'rearrange' method before !");
6006   int nbOfTuples=getNumberOfTuples();
6007   const int *w=getConstPointer();
6008   const int *end2=w+nbOfTuples;
6009   for(;w!=end2;w++)
6010     if(*w!=val)
6011       return false;
6012   return true;
6013 }
6014
6015 /*!
6016  * Checks if all values in \a this array are unique.
6017  *  \return bool - \a true if condition above is true
6018  *  \throw If \a this is not allocated.
6019  *  \throw If \a this->getNumberOfComponents() != 1
6020  */
6021 bool DataArrayInt::hasUniqueValues() const
6022 {
6023   checkAllocated();
6024   if(getNumberOfComponents()!=1)
6025     throw INTERP_KERNEL::Exception("DataArrayInt::hasOnlyUniqueValues: must be applied on DataArrayInt with only one component, you can call 'rearrange' method before !");
6026   int nbOfTuples(getNumberOfTuples());
6027   std::set<int> s(begin(),end());  // in C++11, should use unordered_set (O(1) complexity)
6028   if (s.size() != nbOfTuples)
6029     return false;
6030   return true;
6031 }
6032
6033 /*!
6034  * Creates a new DataArrayDouble and assigns all (textual and numerical) data of \a this
6035  * array to the new one.
6036  *  \return DataArrayDouble * - the new instance of DataArrayInt.
6037  */
6038 DataArrayDouble *DataArrayInt::convertToDblArr() const
6039 {
6040   checkAllocated();
6041   DataArrayDouble *ret=DataArrayDouble::New();
6042   ret->alloc(getNumberOfTuples(),getNumberOfComponents());
6043   std::size_t nbOfVals=getNbOfElems();
6044   const int *src=getConstPointer();
6045   double *dest=ret->getPointer();
6046   std::copy(src,src+nbOfVals,dest);
6047   ret->copyStringInfoFrom(*this);
6048   return ret;
6049 }
6050
6051 /*!
6052  * Appends components of another array to components of \a this one, tuple by tuple.
6053  * So that the number of tuples of \a this array remains the same and the number of 
6054  * components increases.
6055  *  \param [in] other - the DataArrayInt to append to \a this one.
6056  *  \throw If \a this is not allocated.
6057  *  \throw If \a this and \a other arrays have different number of tuples.
6058  *
6059  *  \if ENABLE_EXAMPLES
6060  *  \ref cpp_mcdataarrayint_meldwith "Here is a C++ example".
6061  *
6062  *  \ref py_mcdataarrayint_meldwith "Here is a Python example".
6063  *  \endif
6064  */
6065 void DataArrayInt::meldWith(const DataArrayInt *other)
6066 {
6067   if(!other)
6068     throw INTERP_KERNEL::Exception("DataArrayInt::meldWith : DataArrayInt pointer in input is NULL !");
6069   checkAllocated();
6070   other->checkAllocated();
6071   int nbOfTuples=getNumberOfTuples();
6072   if(nbOfTuples!=other->getNumberOfTuples())
6073     throw INTERP_KERNEL::Exception("DataArrayInt::meldWith : mismatch of number of tuples !");
6074   int nbOfComp1=getNumberOfComponents();
6075   int nbOfComp2=other->getNumberOfComponents();
6076   int *newArr=(int *)malloc(nbOfTuples*(nbOfComp1+nbOfComp2)*sizeof(int));
6077   int *w=newArr;
6078   const int *inp1=getConstPointer();
6079   const int *inp2=other->getConstPointer();
6080   for(int i=0;i<nbOfTuples;i++,inp1+=nbOfComp1,inp2+=nbOfComp2)
6081     {
6082       w=std::copy(inp1,inp1+nbOfComp1,w);
6083       w=std::copy(inp2,inp2+nbOfComp2,w);
6084     }
6085   useArray(newArr,true,C_DEALLOC,nbOfTuples,nbOfComp1+nbOfComp2);
6086   std::vector<int> compIds(nbOfComp2);
6087   for(int i=0;i<nbOfComp2;i++)
6088     compIds[i]=nbOfComp1+i;
6089   copyPartOfStringInfoFrom2(compIds,*other);
6090 }
6091
6092 /*!
6093  * Copy all components in a specified order from another DataArrayInt.
6094  * The specified components become the first ones in \a this array.
6095  * Both numerical and textual data is copied. The number of tuples in \a this and
6096  * the other array can be different.
6097  *  \param [in] a - the array to copy data from.
6098  *  \param [in] compoIds - sequence of zero based indices of components, data of which is
6099  *              to be copied.
6100  *  \throw If \a a is NULL.
6101  *  \throw If \a compoIds.size() != \a a->getNumberOfComponents().
6102  *  \throw If \a compoIds[i] < 0 or \a compoIds[i] > \a this->getNumberOfComponents().
6103  *
6104  *  \if ENABLE_EXAMPLES
6105  *  \ref py_mcdataarrayint_setselectedcomponents "Here is a Python example".
6106  *  \endif
6107  */
6108 void DataArrayInt::setSelectedComponents(const DataArrayInt *a, const std::vector<int>& compoIds)
6109 {
6110   if(!a)
6111     throw INTERP_KERNEL::Exception("DataArrayInt::setSelectedComponents : input DataArrayInt is NULL !");
6112   checkAllocated();
6113   a->checkAllocated();
6114   copyPartOfStringInfoFrom2(compoIds,*a);
6115   std::size_t partOfCompoSz=compoIds.size();
6116   int nbOfCompo=getNumberOfComponents();
6117   int nbOfTuples=std::min(getNumberOfTuples(),a->getNumberOfTuples());
6118   const int *ac=a->getConstPointer();
6119   int *nc=getPointer();
6120   for(int i=0;i<nbOfTuples;i++)
6121     for(std::size_t j=0;j<partOfCompoSz;j++,ac++)
6122       nc[nbOfCompo*i+compoIds[j]]=*ac;
6123 }
6124
6125 /*!
6126  * Assign pointer to one array to a pointer to another appay. Reference counter of
6127  * \a arrayToSet is incremented / decremented.
6128  *  \param [in] newArray - the pointer to array to assign to \a arrayToSet.
6129  *  \param [in,out] arrayToSet - the pointer to array to assign to.
6130  */
6131 void DataArrayInt::SetArrayIn(DataArrayInt *newArray, DataArrayInt* &arrayToSet)
6132 {
6133   if(newArray!=arrayToSet)
6134     {
6135       if(arrayToSet)
6136         arrayToSet->decrRef();
6137       arrayToSet=newArray;
6138       if(arrayToSet)
6139         arrayToSet->incrRef();
6140     }
6141 }
6142
6143 DataArrayIntIterator *DataArrayInt::iterator()
6144 {
6145   return new DataArrayIntIterator(this);
6146 }
6147
6148 /*!
6149  * Creates a new DataArrayInt containing IDs (indices) of tuples holding value equal to a
6150  * given one. The ids are sorted in the ascending order.
6151  *  \param [in] val - the value to find within \a this.
6152  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
6153  *          array using decrRef() as it is no more needed.
6154  *  \throw If \a this is not allocated.
6155  *  \throw If \a this->getNumberOfComponents() != 1.
6156  *  \sa DataArrayInt::findIdsEqualTuple
6157  */
6158 DataArrayInt *DataArrayInt::findIdsEqual(int val) const
6159 {
6160   checkAllocated();
6161   if(getNumberOfComponents()!=1)
6162     throw INTERP_KERNEL::Exception("DataArrayInt::findIdsEqual : the array must have only one component, you can call 'rearrange' method before !");
6163   const int *cptr(getConstPointer());
6164   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
6165   int nbOfTuples=getNumberOfTuples();
6166   for(int i=0;i<nbOfTuples;i++,cptr++)
6167     if(*cptr==val)
6168       ret->pushBackSilent(i);
6169   return ret.retn();
6170 }
6171
6172 /*!
6173  * Creates a new DataArrayInt containing IDs (indices) of tuples holding value \b not
6174  * equal to a given one. 
6175  *  \param [in] val - the value to ignore within \a this.
6176  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
6177  *          array using decrRef() as it is no more needed.
6178  *  \throw If \a this is not allocated.
6179  *  \throw If \a this->getNumberOfComponents() != 1.
6180  */
6181 DataArrayInt *DataArrayInt::findIdsNotEqual(int val) const
6182 {
6183   checkAllocated();
6184   if(getNumberOfComponents()!=1)
6185     throw INTERP_KERNEL::Exception("DataArrayInt::findIdsNotEqual : the array must have only one component, you can call 'rearrange' method before !");
6186   const int *cptr(getConstPointer());
6187   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
6188   int nbOfTuples=getNumberOfTuples();
6189   for(int i=0;i<nbOfTuples;i++,cptr++)
6190     if(*cptr!=val)
6191       ret->pushBackSilent(i);
6192   return ret.retn();
6193 }
6194
6195 /*!
6196  * Creates a new DataArrayInt containing IDs (indices) of tuples holding tuple equal to those defined by [ \a tupleBg , \a tupleEnd )
6197  * This method is an extension of  DataArrayInt::findIdsEqual method.
6198  *
6199  *  \param [in] tupleBg - the begin (included) of the input tuple to find within \a this.
6200  *  \param [in] tupleEnd - the end (excluded) of the input tuple to find within \a this.
6201  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
6202  *          array using decrRef() as it is no more needed.
6203  *  \throw If \a this is not allocated.
6204  *  \throw If \a this->getNumberOfComponents() != std::distance(tupleBg,tupleEnd).
6205  * \throw If \a this->getNumberOfComponents() is equal to 0.
6206  * \sa DataArrayInt::findIdsEqual
6207  */
6208 DataArrayInt *DataArrayInt::findIdsEqualTuple(const int *tupleBg, const int *tupleEnd) const
6209 {
6210   std::size_t nbOfCompoExp(std::distance(tupleBg,tupleEnd));
6211   checkAllocated();
6212   if(getNumberOfComponents()!=(int)nbOfCompoExp)
6213     {
6214       std::ostringstream oss; oss << "DataArrayInt::findIdsEqualTuple : mismatch of number of components. Input tuple has " << nbOfCompoExp << " whereas this array has " << getNumberOfComponents() << " components !";
6215       throw INTERP_KERNEL::Exception(oss.str().c_str());
6216     }
6217   if(nbOfCompoExp==0)
6218     throw INTERP_KERNEL::Exception("DataArrayInt::findIdsEqualTuple : number of components should be > 0 !");
6219   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
6220   const int *bg(begin()),*end2(end()),*work(begin());
6221   while(work!=end2)
6222     {
6223       work=std::search(work,end2,tupleBg,tupleEnd);
6224       if(work!=end2)
6225         {
6226           std::size_t pos(std::distance(bg,work));
6227           if(pos%nbOfCompoExp==0)
6228             ret->pushBackSilent(pos/nbOfCompoExp);
6229           work++;
6230         }
6231     }
6232   return ret.retn();
6233 }
6234
6235 /*!
6236  * Assigns \a newValue to all elements holding \a oldValue within \a this
6237  * one-dimensional array.
6238  *  \param [in] oldValue - the value to replace.
6239  *  \param [in] newValue - the value to assign.
6240  *  \return int - number of replacements performed.
6241  *  \throw If \a this is not allocated.
6242  *  \throw If \a this->getNumberOfComponents() != 1.
6243  */
6244 int DataArrayInt::changeValue(int oldValue, int newValue)
6245 {
6246   checkAllocated();
6247   if(getNumberOfComponents()!=1)
6248     throw INTERP_KERNEL::Exception("DataArrayInt::changeValue : the array must have only one component, you can call 'rearrange' method before !");
6249   if(oldValue==newValue)
6250     return 0;
6251   int *start(getPointer()),*end2(start+getNbOfElems());
6252   int ret(0);
6253   for(int *val=start;val!=end2;val++)
6254     {
6255       if(*val==oldValue)
6256         {
6257           *val=newValue;
6258           ret++;
6259         }
6260     }
6261   if(ret>0)
6262     declareAsNew();
6263   return ret;
6264 }
6265
6266 /*!
6267  * Creates a new DataArrayInt containing IDs (indices) of tuples holding value equal to
6268  * one of given values.
6269  *  \param [in] valsBg - an array of values to find within \a this array.
6270  *  \param [in] valsEnd - specifies the end of the array \a valsBg, so that
6271  *              the last value of \a valsBg is \a valsEnd[ -1 ].
6272  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
6273  *          array using decrRef() as it is no more needed.
6274  *  \throw If \a this->getNumberOfComponents() != 1.
6275  */
6276 DataArrayInt *DataArrayInt::findIdsEqualList(const int *valsBg, const int *valsEnd) const
6277 {
6278   if(getNumberOfComponents()!=1)
6279     throw INTERP_KERNEL::Exception("DataArrayInt::findIdsEqualList : the array must have only one component, you can call 'rearrange' method before !");
6280   std::set<int> vals2(valsBg,valsEnd);
6281   const int *cptr(getConstPointer());
6282   std::vector<int> res;
6283   int nbOfTuples(getNumberOfTuples());
6284   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
6285   for(int i=0;i<nbOfTuples;i++,cptr++)
6286     if(vals2.find(*cptr)!=vals2.end())
6287       ret->pushBackSilent(i);
6288   return ret.retn();
6289 }
6290
6291 /*!
6292  * Creates a new DataArrayInt containing IDs (indices) of tuples holding values \b not
6293  * equal to any of given values.
6294  *  \param [in] valsBg - an array of values to ignore within \a this array.
6295  *  \param [in] valsEnd - specifies the end of the array \a valsBg, so that
6296  *              the last value of \a valsBg is \a valsEnd[ -1 ].
6297  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
6298  *          array using decrRef() as it is no more needed.
6299  *  \throw If \a this->getNumberOfComponents() != 1.
6300  */
6301 DataArrayInt *DataArrayInt::findIdsNotEqualList(const int *valsBg, const int *valsEnd) const
6302 {
6303   if(getNumberOfComponents()!=1)
6304     throw INTERP_KERNEL::Exception("DataArrayInt::findIdsNotEqualList : the array must have only one component, you can call 'rearrange' method before !");
6305   std::set<int> vals2(valsBg,valsEnd);
6306   const int *cptr=getConstPointer();
6307   std::vector<int> res;
6308   int nbOfTuples=getNumberOfTuples();
6309   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
6310   for(int i=0;i<nbOfTuples;i++,cptr++)
6311     if(vals2.find(*cptr)==vals2.end())
6312       ret->pushBackSilent(i);
6313   return ret.retn();
6314 }
6315
6316 /*!
6317  * This method is an extension of DataArrayInt::findIdFirstEqual method because this method works for DataArrayInt with
6318  * any number of components excepted 0 (an INTERP_KERNEL::Exception is thrown in this case).
6319  * This method searches in \b this is there is a tuple that matched the input parameter \b tupl.
6320  * If any the tuple id is returned. If not -1 is returned.
6321  * 
6322  * This method throws an INTERP_KERNEL::Exception if the number of components in \b this mismatches with the size of
6323  * the input vector. An INTERP_KERNEL::Exception is thrown too if \b this is not allocated.
6324  *
6325  * \return tuple id where \b tupl is. -1 if no such tuple exists in \b this.
6326  * \sa DataArrayInt::findIdSequence, DataArrayInt::presenceOfTuple.
6327  */
6328 int DataArrayInt::findIdFirstEqualTuple(const std::vector<int>& tupl) const
6329 {
6330   checkAllocated();
6331   int nbOfCompo=getNumberOfComponents();
6332   if(nbOfCompo==0)
6333     throw INTERP_KERNEL::Exception("DataArrayInt::findIdFirstEqualTuple : 0 components in 'this' !");
6334   if(nbOfCompo!=(int)tupl.size())
6335     {
6336       std::ostringstream oss; oss << "DataArrayInt::findIdFirstEqualTuple : 'this' contains " << nbOfCompo << " components and searching for a tuple of length " << tupl.size() << " !";
6337       throw INTERP_KERNEL::Exception(oss.str().c_str());
6338     }
6339   const int *cptr=getConstPointer();
6340   std::size_t nbOfVals=getNbOfElems();
6341   for(const int *work=cptr;work!=cptr+nbOfVals;)
6342     {
6343       work=std::search(work,cptr+nbOfVals,tupl.begin(),tupl.end());
6344       if(work!=cptr+nbOfVals)
6345         {
6346           if(std::distance(cptr,work)%nbOfCompo!=0)
6347             work++;
6348           else
6349             return std::distance(cptr,work)/nbOfCompo;
6350         }
6351     }
6352   return -1;
6353 }
6354
6355 /*!
6356  * This method searches the sequence specified in input parameter \b vals in \b this.
6357  * This works only for DataArrayInt having number of components equal to one (if not an INTERP_KERNEL::Exception will be thrown).
6358  * This method differs from DataArrayInt::findIdFirstEqualTuple in that the position is internal raw data is not considered here contrary to DataArrayInt::findIdFirstEqualTuple.
6359  * \sa DataArrayInt::findIdFirstEqualTuple
6360  */
6361 int DataArrayInt::findIdSequence(const std::vector<int>& vals) const
6362 {
6363   checkAllocated();
6364   int nbOfCompo=getNumberOfComponents();
6365   if(nbOfCompo!=1)
6366     throw INTERP_KERNEL::Exception("DataArrayInt::findIdSequence : works only for DataArrayInt instance with one component !");
6367   const int *cptr=getConstPointer();
6368   std::size_t nbOfVals=getNbOfElems();
6369   const int *loc=std::search(cptr,cptr+nbOfVals,vals.begin(),vals.end());
6370   if(loc!=cptr+nbOfVals)
6371     return std::distance(cptr,loc);
6372   return -1;
6373 }
6374
6375 /*!
6376  * This method expects to be called when number of components of this is equal to one.
6377  * This method returns the tuple id, if it exists, of the first tuple equal to \b value.
6378  * If not any tuple contains \b value -1 is returned.
6379  * \sa DataArrayInt::presenceOfValue
6380  */
6381 int DataArrayInt::findIdFirstEqual(int value) const
6382 {
6383   checkAllocated();
6384   if(getNumberOfComponents()!=1)
6385     throw INTERP_KERNEL::Exception("DataArrayInt::presenceOfValue : the array must have only one component, you can call 'rearrange' method before !");
6386   const int *cptr=getConstPointer();
6387   int nbOfTuples=getNumberOfTuples();
6388   const int *ret=std::find(cptr,cptr+nbOfTuples,value);
6389   if(ret!=cptr+nbOfTuples)
6390     return std::distance(cptr,ret);
6391   return -1;
6392 }
6393
6394 /*!
6395  * This method expects to be called when number of components of this is equal to one.
6396  * This method returns the tuple id, if it exists, of the first tuple so that the value is contained in \b vals.
6397  * If not any tuple contains one of the values contained in 'vals' -1 is returned.
6398  * \sa DataArrayInt::presenceOfValue
6399  */
6400 int DataArrayInt::findIdFirstEqual(const std::vector<int>& vals) const
6401 {
6402   checkAllocated();
6403   if(getNumberOfComponents()!=1)
6404     throw INTERP_KERNEL::Exception("DataArrayInt::presenceOfValue : the array must have only one component, you can call 'rearrange' method before !");
6405   std::set<int> vals2(vals.begin(),vals.end());
6406   const int *cptr=getConstPointer();
6407   int nbOfTuples=getNumberOfTuples();
6408   for(const int *w=cptr;w!=cptr+nbOfTuples;w++)
6409     if(vals2.find(*w)!=vals2.end())
6410       return std::distance(cptr,w);
6411   return -1;
6412 }
6413
6414 /*!
6415  * This method returns the number of values in \a this that are equals to input parameter \a value.
6416  * This method only works for single component array.
6417  *
6418  * \return a value in [ 0, \c this->getNumberOfTuples() )
6419  *
6420  * \throw If \a this is not allocated
6421  *
6422  */
6423 int DataArrayInt::count(int value) const
6424 {
6425   int ret=0;
6426   checkAllocated();
6427   if(getNumberOfComponents()!=1)
6428     throw INTERP_KERNEL::Exception("DataArrayInt::count : must be applied on DataArrayInt with only one component, you can call 'rearrange' method before !");
6429   const int *vals=begin();
6430   int nbOfTuples=getNumberOfTuples();
6431   for(int i=0;i<nbOfTuples;i++,vals++)
6432     if(*vals==value)
6433       ret++;
6434   return ret;
6435 }
6436
6437 /*!
6438  * This method is an extension of DataArrayInt::presenceOfValue method because this method works for DataArrayInt with
6439  * any number of components excepted 0 (an INTERP_KERNEL::Exception is thrown in this case).
6440  * This method searches in \b this is there is a tuple that matched the input parameter \b tupl.
6441  * This method throws an INTERP_KERNEL::Exception if the number of components in \b this mismatches with the size of
6442  * the input vector. An INTERP_KERNEL::Exception is thrown too if \b this is not allocated.
6443  * \sa DataArrayInt::findIdFirstEqualTuple
6444  */
6445 bool DataArrayInt::presenceOfTuple(const std::vector<int>& tupl) const
6446 {
6447   return findIdFirstEqualTuple(tupl)!=-1;
6448 }
6449
6450
6451 /*!
6452  * Returns \a true if a given value is present within \a this one-dimensional array.
6453  *  \param [in] value - the value to find within \a this array.
6454  *  \return bool - \a true in case if \a value is present within \a this array.
6455  *  \throw If \a this is not allocated.
6456  *  \throw If \a this->getNumberOfComponents() != 1.
6457  *  \sa findIdFirstEqual()
6458  */
6459 bool DataArrayInt::presenceOfValue(int value) const
6460 {
6461   return findIdFirstEqual(value)!=-1;
6462 }
6463
6464 /*!
6465  * This method expects to be called when number of components of this is equal to one.
6466  * This method returns true if it exists a tuple so that the value is contained in \b vals.
6467  * If not any tuple contains one of the values contained in 'vals' false is returned.
6468  * \sa DataArrayInt::findIdFirstEqual
6469  */
6470 bool DataArrayInt::presenceOfValue(const std::vector<int>& vals) const
6471 {
6472   return findIdFirstEqual(vals)!=-1;
6473 }
6474
6475 /*!
6476  * Accumulates values of each component of \a this array.
6477  *  \param [out] res - an array of length \a this->getNumberOfComponents(), allocated 
6478  *         by the caller, that is filled by this method with sum value for each
6479  *         component.
6480  *  \throw If \a this is not allocated.
6481  */
6482 void DataArrayInt::accumulate(int *res) const
6483 {
6484   checkAllocated();
6485   const int *ptr=getConstPointer();
6486   int nbTuple=getNumberOfTuples();
6487   int nbComps=getNumberOfComponents();
6488   std::fill(res,res+nbComps,0);
6489   for(int i=0;i<nbTuple;i++)
6490     std::transform(ptr+i*nbComps,ptr+(i+1)*nbComps,res,res,std::plus<int>());
6491 }
6492
6493 int DataArrayInt::accumulate(int compId) const
6494 {
6495   checkAllocated();
6496   const int *ptr=getConstPointer();
6497   int nbTuple=getNumberOfTuples();
6498   int nbComps=getNumberOfComponents();
6499   if(compId<0 || compId>=nbComps)
6500     throw INTERP_KERNEL::Exception("DataArrayInt::accumulate : Invalid compId specified : No such nb of components !");
6501   int ret=0;
6502   for(int i=0;i<nbTuple;i++)
6503     ret+=ptr[i*nbComps+compId];
6504   return ret;
6505 }
6506
6507 /*!
6508  * This method accumulate using addition tuples in \a this using input index array [ \a bgOfIndex, \a endOfIndex ).
6509  * The returned array will have same number of components than \a this and number of tuples equal to
6510  * \c std::distance(bgOfIndex,endOfIndex) \b minus \b one.
6511  *
6512  * The input index array is expected to be ascendingly sorted in which the all referenced ids should be in [0, \c this->getNumberOfTuples).
6513  *
6514  * \param [in] bgOfIndex - begin (included) of the input index array.
6515  * \param [in] endOfIndex - end (excluded) of the input index array.
6516  * \return DataArrayInt * - the new instance having the same number of components than \a this.
6517  * 
6518  * \throw If bgOfIndex or end is NULL.
6519  * \throw If input index array is not ascendingly sorted.
6520  * \throw If there is an id in [ \a bgOfIndex, \a endOfIndex ) not in [0, \c this->getNumberOfTuples).
6521  * \throw If std::distance(bgOfIndex,endOfIndex)==0.
6522  */
6523 DataArrayInt *DataArrayInt::accumulatePerChunck(const int *bgOfIndex, const int *endOfIndex) const
6524 {
6525   if(!bgOfIndex || !endOfIndex)
6526     throw INTERP_KERNEL::Exception("DataArrayInt::accumulatePerChunck : input pointer NULL !");
6527   checkAllocated();
6528   int nbCompo=getNumberOfComponents();
6529   int nbOfTuples=getNumberOfTuples();
6530   int sz=(int)std::distance(bgOfIndex,endOfIndex);
6531   if(sz<1)
6532     throw INTERP_KERNEL::Exception("DataArrayInt::accumulatePerChunck : invalid size of input index array !");
6533   sz--;
6534   MCAuto<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(sz,nbCompo);
6535   const int *w=bgOfIndex;
6536   if(*w<0 || *w>=nbOfTuples)
6537     throw INTERP_KERNEL::Exception("DataArrayInt::accumulatePerChunck : The first element of the input index not in [0,nbOfTuples) !");
6538   const int *srcPt=begin()+(*w)*nbCompo;
6539   int *tmp=ret->getPointer();
6540   for(int i=0;i<sz;i++,tmp+=nbCompo,w++)
6541     {
6542       std::fill(tmp,tmp+nbCompo,0);
6543       if(w[1]>=w[0])
6544         {
6545           for(int j=w[0];j<w[1];j++,srcPt+=nbCompo)
6546             {
6547               if(j>=0 && j<nbOfTuples)
6548                 std::transform(srcPt,srcPt+nbCompo,tmp,tmp,std::plus<int>());
6549               else
6550                 {
6551                   std::ostringstream oss; oss << "DataArrayInt::accumulatePerChunck : At rank #" << i << " the input index array points to id " << j << " should be in [0," << nbOfTuples << ") !";
6552                   throw INTERP_KERNEL::Exception(oss.str().c_str());
6553                 }
6554             }
6555         }
6556       else
6557         {
6558           std::ostringstream oss; oss << "DataArrayInt::accumulatePerChunck : At rank #" << i << " the input index array is not in ascendingly sorted.";
6559           throw INTERP_KERNEL::Exception(oss.str().c_str());
6560         }
6561     }
6562   ret->copyStringInfoFrom(*this);
6563   return ret.retn();
6564 }
6565
6566 /*!
6567  * Returns a new DataArrayInt by concatenating two given arrays, so that (1) the number
6568  * of tuples in the result array is <em> a1->getNumberOfTuples() + a2->getNumberOfTuples() -
6569  * offsetA2</em> and (2)
6570  * the number of component in the result array is same as that of each of given arrays.
6571  * First \a offsetA2 tuples of \a a2 are skipped and thus are missing from the result array.
6572  * Info on components is copied from the first of the given arrays. Number of components
6573  * in the given arrays must be the same.
6574  *  \param [in] a1 - an array to include in the result array.
6575  *  \param [in] a2 - another array to include in the result array.
6576  *  \param [in] offsetA2 - number of tuples of \a a2 to skip.
6577  *  \return DataArrayInt * - the new instance of DataArrayInt.
6578  *          The caller is to delete this result array using decrRef() as it is no more
6579  *          needed.
6580  *  \throw If either \a a1 or \a a2 is NULL.
6581  *  \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents().
6582  */
6583 DataArrayInt *DataArrayInt::Aggregate(const DataArrayInt *a1, const DataArrayInt *a2, int offsetA2)
6584 {
6585   if(!a1 || !a2)
6586     throw INTERP_KERNEL::Exception("DataArrayInt::Aggregate : input DataArrayInt instance is NULL !");
6587   int nbOfComp=a1->getNumberOfComponents();
6588   if(nbOfComp!=a2->getNumberOfComponents())
6589     throw INTERP_KERNEL::Exception("Nb of components mismatch for array Aggregation !");
6590   int nbOfTuple1=a1->getNumberOfTuples();
6591   int nbOfTuple2=a2->getNumberOfTuples();
6592   DataArrayInt *ret=DataArrayInt::New();
6593   ret->alloc(nbOfTuple1+nbOfTuple2-offsetA2,nbOfComp);
6594   int *pt=std::copy(a1->getConstPointer(),a1->getConstPointer()+nbOfTuple1*nbOfComp,ret->getPointer());
6595   std::copy(a2->getConstPointer()+offsetA2*nbOfComp,a2->getConstPointer()+nbOfTuple2*nbOfComp,pt);
6596   ret->copyStringInfoFrom(*a1);
6597   return ret;
6598 }
6599
6600 /*!
6601  * Returns a new DataArrayInt by concatenating all given arrays, so that (1) the number
6602  * of tuples in the result array is a sum of the number of tuples of given arrays and (2)
6603  * the number of component in the result array is same as that of each of given arrays.
6604  * Info on components is copied from the first of the given arrays. Number of components
6605  * in the given arrays must be  the same.
6606  * If the number of non null of elements in \a arr is equal to one the returned object is a copy of it
6607  * not the object itself.
6608  *  \param [in] arr - a sequence of arrays to include in the result array.
6609  *  \return DataArrayInt * - the new instance of DataArrayInt.
6610  *          The caller is to delete this result array using decrRef() as it is no more
6611  *          needed.
6612  *  \throw If all arrays within \a arr are NULL.
6613  *  \throw If getNumberOfComponents() of arrays within \a arr.
6614  */
6615 DataArrayInt *DataArrayInt::Aggregate(const std::vector<const DataArrayInt *>& arr)
6616 {
6617   std::vector<const DataArrayInt *> a;
6618   for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
6619     if(*it4)
6620       a.push_back(*it4);
6621   if(a.empty())
6622     throw INTERP_KERNEL::Exception("DataArrayInt::Aggregate : input list must be NON EMPTY !");
6623   std::vector<const DataArrayInt *>::const_iterator it=a.begin();
6624   int nbOfComp=(*it)->getNumberOfComponents();
6625   int nbt=(*it++)->getNumberOfTuples();
6626   for(int i=1;it!=a.end();it++,i++)
6627     {
6628       if((*it)->getNumberOfComponents()!=nbOfComp)
6629         throw INTERP_KERNEL::Exception("DataArrayInt::Aggregate : Nb of components mismatch for array aggregation !");
6630       nbt+=(*it)->getNumberOfTuples();
6631     }
6632   MCAuto<DataArrayInt> ret=DataArrayInt::New();
6633   ret->alloc(nbt,nbOfComp);
6634   int *pt=ret->getPointer();
6635   for(it=a.begin();it!=a.end();it++)
6636     pt=std::copy((*it)->getConstPointer(),(*it)->getConstPointer()+(*it)->getNbOfElems(),pt);
6637   ret->copyStringInfoFrom(*(a[0]));
6638   return ret.retn();
6639 }
6640
6641 /*!
6642  * This method takes as input a list of DataArrayInt instances \a arrs that represent each a packed index arrays.
6643  * A packed index array is an allocated array with one component, and at least one tuple. The first element
6644  * of each array in \a arrs must be 0. Each array in \a arrs is expected to be increasingly monotonic.
6645  * 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.
6646  * 
6647  * \return DataArrayInt * - a new object to be managed by the caller.
6648  */
6649 DataArrayInt *DataArrayInt::AggregateIndexes(const std::vector<const DataArrayInt *>& arrs)
6650 {
6651   int retSz=1;
6652   for(std::vector<const DataArrayInt *>::const_iterator it4=arrs.begin();it4!=arrs.end();it4++)
6653     {
6654       if(*it4)
6655         {
6656           (*it4)->checkAllocated();
6657           if((*it4)->getNumberOfComponents()!=1)
6658             {
6659               std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a DataArrayInt instance with nb of compo != 1 at pos " << std::distance(arrs.begin(),it4) << " !";
6660               throw INTERP_KERNEL::Exception(oss.str().c_str());
6661             }
6662           int nbTupl=(*it4)->getNumberOfTuples();
6663           if(nbTupl<1)
6664             {
6665               std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a DataArrayInt instance with nb of tuples < 1 at pos " << std::distance(arrs.begin(),it4) << " !";
6666               throw INTERP_KERNEL::Exception(oss.str().c_str());
6667             }
6668           if((*it4)->front()!=0)
6669             {
6670               std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a DataArrayInt instance with front value != 0 at pos " << std::distance(arrs.begin(),it4) << " !";
6671               throw INTERP_KERNEL::Exception(oss.str().c_str());
6672             }
6673           retSz+=nbTupl-1;
6674         }
6675       else
6676         {
6677           std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a null instance at pos " << std::distance(arrs.begin(),it4) << " !";
6678           throw INTERP_KERNEL::Exception(oss.str().c_str());
6679         }
6680     }
6681   if(arrs.empty())
6682     throw INTERP_KERNEL::Exception("DataArrayInt::AggregateIndexes : input list must be NON EMPTY !");
6683   MCAuto<DataArrayInt> ret=DataArrayInt::New();
6684   ret->alloc(retSz,1);
6685   int *pt=ret->getPointer(); *pt++=0;
6686   for(std::vector<const DataArrayInt *>::const_iterator it=arrs.begin();it!=arrs.end();it++)
6687     pt=std::transform((*it)->begin()+1,(*it)->end(),pt,std::bind2nd(std::plus<int>(),pt[-1]));
6688   ret->copyStringInfoFrom(*(arrs[0]));
6689   return ret.retn();
6690 }
6691
6692 /*!
6693  * Returns in a single walk in \a this the min value and the max value in \a this.
6694  * \a this is expected to be single component array.
6695  *
6696  * \param [out] minValue - the min value in \a this.
6697  * \param [out] maxValue - the max value in \a this.
6698  *
6699  * \sa getMinValueInArray, getMinValue, getMaxValueInArray, getMaxValue
6700  */
6701 void DataArrayInt::getMinMaxValues(int& minValue, int& maxValue) const
6702 {
6703   checkAllocated();
6704   if(getNumberOfComponents()!=1)
6705     throw INTERP_KERNEL::Exception("DataArrayInt::getMinMaxValues : must be applied on DataArrayInt with only one component !");
6706   int nbTuples(getNumberOfTuples());
6707   const int *pt(begin());
6708   minValue=std::numeric_limits<int>::max(); maxValue=-std::numeric_limits<int>::max();
6709   for(int i=0;i<nbTuples;i++,pt++)
6710     {
6711       if(*pt<minValue)
6712         minValue=*pt;
6713       if(*pt>maxValue)
6714         maxValue=*pt;
6715     }
6716 }
6717
6718 /*!
6719  * Converts every value of \a this array to its absolute value.
6720  * \b WARNING this method is non const. If a new DataArrayInt instance should be built containing the result of abs DataArrayInt::computeAbs
6721  * should be called instead.
6722  *
6723  * \throw If \a this is not allocated.
6724  * \sa DataArrayInt::computeAbs
6725  */
6726 void DataArrayInt::abs()
6727 {
6728   checkAllocated();
6729   int *ptr(getPointer());
6730   std::size_t nbOfElems(getNbOfElems());
6731   std::transform(ptr,ptr+nbOfElems,ptr,std::ptr_fun<int,int>(std::abs));
6732   declareAsNew();
6733 }
6734
6735 /*!
6736  * This method builds a new instance of \a this object containing the result of std::abs applied of all elements in \a this.
6737  * This method is a const method (that do not change any values in \a this) contrary to  DataArrayInt::abs method.
6738  *
6739  * \return DataArrayInt * - the new instance of DataArrayInt containing the
6740  *         same number of tuples and component as \a this array.
6741  *         The caller is to delete this result array using decrRef() as it is no more
6742  *         needed.
6743  * \throw If \a this is not allocated.
6744  * \sa DataArrayInt::abs
6745  */
6746 DataArrayInt *DataArrayInt::computeAbs() const
6747 {
6748   checkAllocated();
6749   DataArrayInt *newArr(DataArrayInt::New());
6750   int nbOfTuples(getNumberOfTuples());
6751   int nbOfComp(getNumberOfComponents());
6752   newArr->alloc(nbOfTuples,nbOfComp);
6753   std::transform(begin(),end(),newArr->getPointer(),std::ptr_fun<int,int>(std::abs));
6754   newArr->copyStringInfoFrom(*this);
6755   return newArr;
6756 }
6757
6758 /*!
6759  * Apply a liner function to a given component of \a this array, so that
6760  * an array element <em>(x)</em> becomes \f$ a * x + b \f$.
6761  *  \param [in] a - the first coefficient of the function.
6762  *  \param [in] b - the second coefficient of the function.
6763  *  \param [in] compoId - the index of component to modify.
6764  *  \throw If \a this is not allocated.
6765  */
6766 void DataArrayInt::applyLin(int a, int b, int compoId)
6767 {
6768   checkAllocated();
6769   int *ptr=getPointer()+compoId;
6770   int nbOfComp=getNumberOfComponents();
6771   int nbOfTuple=getNumberOfTuples();
6772   for(int i=0;i<nbOfTuple;i++,ptr+=nbOfComp)
6773     *ptr=a*(*ptr)+b;
6774   declareAsNew();
6775 }
6776
6777 /*!
6778  * Apply a liner function to all elements of \a this array, so that
6779  * an element _x_ becomes \f$ a * x + b \f$.
6780  *  \param [in] a - the first coefficient of the function.
6781  *  \param [in] b - the second coefficient of the function.
6782  *  \throw If \a this is not allocated.
6783  */
6784 void DataArrayInt::applyLin(int a, int b)
6785 {
6786   checkAllocated();
6787   int *ptr=getPointer();
6788   std::size_t nbOfElems=getNbOfElems();
6789   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
6790     *ptr=a*(*ptr)+b;
6791   declareAsNew();
6792 }
6793
6794 /*!
6795  * Returns a full copy of \a this array except that sign of all elements is reversed.
6796  *  \return DataArrayInt * - the new instance of DataArrayInt containing the
6797  *          same number of tuples and component as \a this array.
6798  *          The caller is to delete this result array using decrRef() as it is no more
6799  *          needed.
6800  *  \throw If \a this is not allocated.
6801  */
6802 DataArrayInt *DataArrayInt::negate() const
6803 {
6804   checkAllocated();
6805   DataArrayInt *newArr=DataArrayInt::New();
6806   int nbOfTuples=getNumberOfTuples();
6807   int nbOfComp=getNumberOfComponents();
6808   newArr->alloc(nbOfTuples,nbOfComp);
6809   const int *cptr=getConstPointer();
6810   std::transform(cptr,cptr+nbOfTuples*nbOfComp,newArr->getPointer(),std::negate<int>());
6811   newArr->copyStringInfoFrom(*this);
6812   return newArr;
6813 }
6814
6815 /*!
6816  * Modify all elements of \a this array, so that
6817  * an element _x_ becomes \f$ numerator / x \f$.
6818  *  \warning If an exception is thrown because of presence of 0 element in \a this 
6819  *           array, all elements processed before detection of the zero element remain
6820  *           modified.
6821  *  \param [in] numerator - the numerator used to modify array elements.
6822  *  \throw If \a this is not allocated.
6823  *  \throw If there is an element equal to 0 in \a this array.
6824  */
6825 void DataArrayInt::applyInv(int numerator)
6826 {
6827   checkAllocated();
6828   int *ptr=getPointer();
6829   std::size_t nbOfElems=getNbOfElems();
6830   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
6831     {
6832       if(*ptr!=0)
6833         {
6834           *ptr=numerator/(*ptr);
6835         }
6836       else
6837         {
6838           std::ostringstream oss; oss << "DataArrayInt::applyInv : presence of null value in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
6839           oss << " !";
6840           throw INTERP_KERNEL::Exception(oss.str().c_str());
6841         }
6842     }
6843   declareAsNew();
6844 }
6845
6846 /*!
6847  * Modify all elements of \a this array, so that
6848  * an element _x_ becomes \f$ x / val \f$.
6849  *  \param [in] val - the denominator used to modify array elements.
6850  *  \throw If \a this is not allocated.
6851  *  \throw If \a val == 0.
6852  */
6853 void DataArrayInt::applyDivideBy(int val)
6854 {
6855   if(val==0)
6856     throw INTERP_KERNEL::Exception("DataArrayInt::applyDivideBy : Trying to divide by 0 !");
6857   checkAllocated();
6858   int *ptr=getPointer();
6859   std::size_t nbOfElems=getNbOfElems();
6860   std::transform(ptr,ptr+nbOfElems,ptr,std::bind2nd(std::divides<int>(),val));
6861   declareAsNew();
6862 }
6863
6864 /*!
6865  * Modify all elements of \a this array, so that
6866  * an element _x_ becomes  <em> x % val </em>.
6867  *  \param [in] val - the divisor used to modify array elements.
6868  *  \throw If \a this is not allocated.
6869  *  \throw If \a val <= 0.
6870  */
6871 void DataArrayInt::applyModulus(int val)
6872 {
6873   if(val<=0)
6874     throw INTERP_KERNEL::Exception("DataArrayInt::applyDivideBy : Trying to operate modulus on value <= 0 !");
6875   checkAllocated();
6876   int *ptr=getPointer();
6877   std::size_t nbOfElems=getNbOfElems();
6878   std::transform(ptr,ptr+nbOfElems,ptr,std::bind2nd(std::modulus<int>(),val));
6879   declareAsNew();
6880 }
6881
6882 struct GreatEqual
6883 {
6884   GreatEqual(int v):_v(v) { }
6885   bool operator()(int v) const { return v>=_v; }
6886   int _v;
6887 };
6888
6889 struct GreaterThan
6890 {
6891   GreaterThan(int v):_v(v) { }
6892   bool operator()(int v) const { return v>_v; }
6893   int _v;
6894 };
6895
6896 struct LowerEqual
6897 {
6898   LowerEqual(int v):_v(v) { }
6899   bool operator()(int v) const { return v<=_v; }
6900   int _v;
6901 };
6902
6903 struct LowerThan
6904 {
6905   LowerThan(int v):_v(v) { }
6906   bool operator()(int v) const { return v<_v; }
6907   int _v;
6908 };
6909
6910 struct InRange
6911 {
6912   InRange(int a, int b):_a(a),_b(b) { }
6913   bool operator()(int v) const { return v>=_a && v<_b; }
6914   int _a,_b;
6915 };
6916
6917 /*!
6918  * This method works only on data array with one component.
6919  * This method returns a newly allocated array storing stored ascendantly tuple ids in \b this so that
6920  * this[*id] in [\b vmin,\b vmax)
6921  * 
6922  * \param [in] vmin begin of range. This value is included in range (included).
6923  * \param [in] vmax end of range. This value is \b not included in range (excluded).
6924  * \return a newly allocated data array that the caller should deal with.
6925  *
6926  * \sa DataArrayInt::findIdsNotInRange , DataArrayInt::findIdsStricltyNegative
6927  */
6928 DataArrayInt *DataArrayInt::findIdsInRange(int vmin, int vmax) const
6929 {
6930   InRange ir(vmin,vmax);
6931   MCAuto<DataArrayInt> ret(findIdsAdv(ir));
6932   return ret.retn();
6933 }
6934
6935 struct NotInRange
6936 {
6937   NotInRange(int a, int b):_a(a),_b(b) { }
6938   bool operator()(int v) const { return v<_a || v>=_b; }
6939   int _a,_b;
6940 };
6941
6942 /*!
6943  * This method works only on data array with one component.
6944  * This method returns a newly allocated array storing stored ascendantly tuple ids in \b this so that
6945  * this[*id] \b not in [\b vmin,\b vmax)
6946  * 
6947  * \param [in] vmin begin of range. This value is \b not included in range (excluded).
6948  * \param [in] vmax end of range. This value is included in range (included).
6949  * \return a newly allocated data array that the caller should deal with.
6950  * 
6951  * \sa DataArrayInt::findIdsInRange , DataArrayInt::findIdsStricltyNegative
6952  */
6953 DataArrayInt *DataArrayInt::findIdsNotInRange(int vmin, int vmax) const
6954 {
6955   NotInRange nir(vmin,vmax);
6956   MCAuto<DataArrayInt> ret(findIdsAdv(nir));
6957   return ret.retn();
6958 }
6959
6960 /*!
6961  * 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.
6962  *
6963  * \return a newly allocated data array that the caller should deal with.
6964  * \sa DataArrayInt::findIdsInRange
6965  */
6966 DataArrayInt *DataArrayInt::findIdsStricltyNegative() const
6967 {
6968   LowerThan lt(0);
6969   MCAuto<DataArrayInt> ret(findIdsAdv(lt));
6970   return ret.retn();
6971 }
6972
6973 MCAuto<DataArrayInt> DataArrayInt::findIdsGreaterOrEqualTo(int val) const
6974 {
6975   GreatEqual ge(val);
6976   return findIdsAdv(ge);
6977 }
6978
6979 MCAuto<DataArrayInt> DataArrayInt::findIdsGreaterThan(int val) const
6980 {
6981   GreaterThan gt(val);
6982   return findIdsAdv(gt);
6983 }
6984
6985 MCAuto<DataArrayInt> DataArrayInt::findIdsLowerOrEqualTo(int val) const
6986 {
6987   LowerEqual le(val);
6988   return findIdsAdv(le);
6989 }
6990
6991 MCAuto<DataArrayInt> DataArrayInt::findIdsLowerThan(int val) const
6992 {
6993   LowerThan lt(val);
6994   return findIdsAdv(lt);
6995 }
6996
6997 /*!
6998  * This method works only on data array with one component.
6999  * 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.
7000  * 
7001  * \param [in] vmin begin of range. This value is included in range (included).
7002  * \param [in] vmax end of range. This value is \b not included in range (excluded).
7003  * \return if all ids in \a this are so that (*this)[i]==i for all i in [ 0, \c this->getNumberOfTuples() ). */
7004 bool DataArrayInt::checkAllIdsInRange(int vmin, int vmax) const
7005 {
7006   checkAllocated();
7007   if(getNumberOfComponents()!=1)
7008     throw INTERP_KERNEL::Exception("DataArrayInt::checkAllIdsInRange : this must have exactly one component !");
7009   int nbOfTuples=getNumberOfTuples();
7010   bool ret=true;
7011   const int *cptr=getConstPointer();
7012   for(int i=0;i<nbOfTuples;i++,cptr++)
7013     {
7014       if(*cptr>=vmin && *cptr<vmax)
7015         { ret=ret && *cptr==i; }
7016       else
7017         {
7018           std::ostringstream oss; oss << "DataArrayInt::checkAllIdsInRange : tuple #" << i << " has value " << *cptr << " should be in [" << vmin << "," << vmax << ") !";
7019           throw INTERP_KERNEL::Exception(oss.str().c_str());
7020         }
7021     }
7022   return ret;
7023 }
7024
7025 /*!
7026  * Modify all elements of \a this array, so that
7027  * an element _x_ becomes <em> val % x </em>.
7028  *  \warning If an exception is thrown because of presence of an element <= 0 in \a this 
7029  *           array, all elements processed before detection of the zero element remain
7030  *           modified.
7031  *  \param [in] val - the divident used to modify array elements.
7032  *  \throw If \a this is not allocated.
7033  *  \throw If there is an element equal to or less than 0 in \a this array.
7034  */
7035 void DataArrayInt::applyRModulus(int val)
7036 {
7037   checkAllocated();
7038   int *ptr=getPointer();
7039   std::size_t nbOfElems=getNbOfElems();
7040   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
7041     {
7042       if(*ptr>0)
7043         {
7044           *ptr=val%(*ptr);
7045         }
7046       else
7047         {
7048           std::ostringstream oss; oss << "DataArrayInt::applyRModulus : presence of value <=0 in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
7049           oss << " !";
7050           throw INTERP_KERNEL::Exception(oss.str().c_str());
7051         }
7052     }
7053   declareAsNew();
7054 }
7055
7056 /*!
7057  * Modify all elements of \a this array, so that
7058  * an element _x_ becomes <em> val ^ x </em>.
7059  *  \param [in] val - the value used to apply pow on all array elements.
7060  *  \throw If \a this is not allocated.
7061  *  \throw If \a val < 0.
7062  */
7063 void DataArrayInt::applyPow(int val)
7064 {
7065   checkAllocated();
7066   if(val<0)
7067     throw INTERP_KERNEL::Exception("DataArrayInt::applyPow : input pow in < 0 !");
7068   int *ptr=getPointer();
7069   std::size_t nbOfElems=getNbOfElems();
7070   if(val==0)
7071     {
7072       std::fill(ptr,ptr+nbOfElems,1);
7073       return ;
7074     }
7075   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
7076     {
7077       int tmp=1;
7078       for(int j=0;j<val;j++)
7079         tmp*=*ptr;
7080       *ptr=tmp;
7081     }
7082   declareAsNew();
7083 }
7084
7085 /*!
7086  * Modify all elements of \a this array, so that
7087  * an element _x_ becomes \f$ val ^ x \f$.
7088  *  \param [in] val - the value used to apply pow on all array elements.
7089  *  \throw If \a this is not allocated.
7090  *  \throw If there is an element < 0 in \a this array.
7091  *  \warning If an exception is thrown because of presence of 0 element in \a this 
7092  *           array, all elements processed before detection of the zero element remain
7093  *           modified.
7094  */
7095 void DataArrayInt::applyRPow(int val)
7096 {
7097   checkAllocated();
7098   int *ptr=getPointer();
7099   std::size_t nbOfElems=getNbOfElems();
7100   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
7101     {
7102       if(*ptr>=0)
7103         {
7104           int tmp=1;
7105           for(int j=0;j<*ptr;j++)
7106             tmp*=val;
7107           *ptr=tmp;
7108         }
7109       else
7110         {
7111           std::ostringstream oss; oss << "DataArrayInt::applyRPow : presence of negative value in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
7112           oss << " !";
7113           throw INTERP_KERNEL::Exception(oss.str().c_str());
7114         }
7115     }
7116   declareAsNew();
7117 }
7118
7119 /*!
7120  * Returns a new DataArrayInt by aggregating two given arrays, so that (1) the number
7121  * of components in the result array is a sum of the number of components of given arrays
7122  * and (2) the number of tuples in the result array is same as that of each of given
7123  * arrays. In other words the i-th tuple of result array includes all components of
7124  * i-th tuples of all given arrays.
7125  * Number of tuples in the given arrays must be the same.
7126  *  \param [in] a1 - an array to include in the result array.
7127  *  \param [in] a2 - another array to include in the result array.
7128  *  \return DataArrayInt * - the new instance of DataArrayInt.
7129  *          The caller is to delete this result array using decrRef() as it is no more
7130  *          needed.
7131  *  \throw If both \a a1 and \a a2 are NULL.
7132  *  \throw If any given array is not allocated.
7133  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
7134  */
7135 DataArrayInt *DataArrayInt::Meld(const DataArrayInt *a1, const DataArrayInt *a2)
7136 {
7137   std::vector<const DataArrayInt *> arr(2);
7138   arr[0]=a1; arr[1]=a2;
7139   return Meld(arr);
7140 }
7141
7142 /*!
7143  * Returns a new DataArrayInt by aggregating all given arrays, so that (1) the number
7144  * of components in the result array is a sum of the number of components of given arrays
7145  * and (2) the number of tuples in the result array is same as that of each of given
7146  * arrays. In other words the i-th tuple of result array includes all components of
7147  * i-th tuples of all given arrays.
7148  * Number of tuples in the given arrays must be  the same.
7149  *  \param [in] arr - a sequence of arrays to include in the result array.
7150  *  \return DataArrayInt * - the new instance of DataArrayInt.
7151  *          The caller is to delete this result array using decrRef() as it is no more
7152  *          needed.
7153  *  \throw If all arrays within \a arr are NULL.
7154  *  \throw If any given array is not allocated.
7155  *  \throw If getNumberOfTuples() of arrays within \a arr is different.
7156  */
7157 DataArrayInt *DataArrayInt::Meld(const std::vector<const DataArrayInt *>& arr)
7158 {
7159   std::vector<const DataArrayInt *> a;
7160   for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
7161     if(*it4)
7162       a.push_back(*it4);
7163   if(a.empty())
7164     throw INTERP_KERNEL::Exception("DataArrayInt::Meld : array must be NON empty !");
7165   std::vector<const DataArrayInt *>::const_iterator it;
7166   for(it=a.begin();it!=a.end();it++)
7167     (*it)->checkAllocated();
7168   it=a.begin();
7169   int nbOfTuples=(*it)->getNumberOfTuples();
7170   std::vector<int> nbc(a.size());
7171   std::vector<const int *> pts(a.size());
7172   nbc[0]=(*it)->getNumberOfComponents();
7173   pts[0]=(*it++)->getConstPointer();
7174   for(int i=1;it!=a.end();it++,i++)
7175     {
7176       if(nbOfTuples!=(*it)->getNumberOfTuples())
7177         throw INTERP_KERNEL::Exception("DataArrayInt::meld : mismatch of number of tuples !");
7178       nbc[i]=(*it)->getNumberOfComponents();
7179       pts[i]=(*it)->getConstPointer();
7180     }
7181   int totalNbOfComp=std::accumulate(nbc.begin(),nbc.end(),0);
7182   DataArrayInt *ret=DataArrayInt::New();
7183   ret->alloc(nbOfTuples,totalNbOfComp);
7184   int *retPtr=ret->getPointer();
7185   for(int i=0;i<nbOfTuples;i++)
7186     for(int j=0;j<(int)a.size();j++)
7187       {
7188         retPtr=std::copy(pts[j],pts[j]+nbc[j],retPtr);
7189         pts[j]+=nbc[j];
7190       }
7191   int k=0;
7192   for(int i=0;i<(int)a.size();i++)
7193     for(int j=0;j<nbc[i];j++,k++)
7194       ret->setInfoOnComponent(k,a[i]->getInfoOnComponent(j));
7195   return ret;
7196 }
7197
7198 /*!
7199  * Returns a new DataArrayInt which is a minimal partition of elements of \a groups.
7200  * The i-th item of the result array is an ID of a set of elements belonging to a
7201  * unique set of groups, which the i-th element is a part of. This set of elements
7202  * belonging to a unique set of groups is called \a family, so the result array contains
7203  * IDs of families each element belongs to.
7204  *
7205  * \b Example: if we have two groups of elements: \a group1 [0,4] and \a group2 [ 0,1,2 ],
7206  * then there are 3 families:
7207  * - \a family1 (with ID 1) contains element [0] belonging to ( \a group1 + \a group2 ),
7208  * - \a family2 (with ID 2) contains elements [4] belonging to ( \a group1 ),
7209  * - \a family3 (with ID 3) contains element [1,2] belonging to ( \a group2 ), <br>
7210  * and the result array contains IDs of families [ 1,3,3,0,2 ]. <br> Note a family ID 0 which
7211  * stands for the element #3 which is in none of groups.
7212  *
7213  *  \param [in] groups - sequence of groups of element IDs.
7214  *  \param [in] newNb - total number of elements; it must be more than max ID of element
7215  *         in \a groups.
7216  *  \param [out] fidsOfGroups - IDs of families the elements of each group belong to.
7217  *  \return DataArrayInt * - a new instance of DataArrayInt containing IDs of families
7218  *         each element with ID from range [0, \a newNb ) belongs to. The caller is to
7219  *         delete this array using decrRef() as it is no more needed.
7220  *  \throw If any element ID in \a groups violates condition ( 0 <= ID < \a newNb ).
7221  */
7222 DataArrayInt *DataArrayInt::MakePartition(const std::vector<const DataArrayInt *>& groups, int newNb, std::vector< std::vector<int> >& fidsOfGroups)
7223 {
7224   std::vector<const DataArrayInt *> groups2;
7225   for(std::vector<const DataArrayInt *>::const_iterator it4=groups.begin();it4!=groups.end();it4++)
7226     if(*it4)
7227       groups2.push_back(*it4);
7228   MCAuto<DataArrayInt> ret=DataArrayInt::New();
7229   ret->alloc(newNb,1);
7230   int *retPtr=ret->getPointer();
7231   std::fill(retPtr,retPtr+newNb,0);
7232   int fid=1;
7233   for(std::vector<const DataArrayInt *>::const_iterator iter=groups2.begin();iter!=groups2.end();iter++)
7234     {
7235       const int *ptr=(*iter)->getConstPointer();
7236       std::size_t nbOfElem=(*iter)->getNbOfElems();
7237       int sfid=fid;
7238       for(int j=0;j<sfid;j++)
7239         {
7240           bool found=false;
7241           for(std::size_t i=0;i<nbOfElem;i++)
7242             {
7243               if(ptr[i]>=0 && ptr[i]<newNb)
7244                 {
7245                   if(retPtr[ptr[i]]==j)
7246                     {
7247                       retPtr[ptr[i]]=fid;
7248                       found=true;
7249                     }
7250                 }
7251               else
7252                 {
7253                   std::ostringstream oss; oss << "DataArrayInt::MakePartition : In group \"" << (*iter)->getName() << "\" in tuple #" << i << " value = " << ptr[i] << " ! Should be in [0," << newNb;
7254                   oss << ") !";
7255                   throw INTERP_KERNEL::Exception(oss.str().c_str());
7256                 }
7257             }
7258           if(found)
7259             fid++;
7260         }
7261     }
7262   fidsOfGroups.clear();
7263   fidsOfGroups.resize(groups2.size());
7264   int grId=0;
7265   for(std::vector<const DataArrayInt *>::const_iterator iter=groups2.begin();iter!=groups2.end();iter++,grId++)
7266     {
7267       std::set<int> tmp;
7268       const int *ptr=(*iter)->getConstPointer();
7269       std::size_t nbOfElem=(*iter)->getNbOfElems();
7270       for(const int *p=ptr;p!=ptr+nbOfElem;p++)
7271         tmp.insert(retPtr[*p]);
7272       fidsOfGroups[grId].insert(fidsOfGroups[grId].end(),tmp.begin(),tmp.end());
7273     }
7274   return ret.retn();
7275 }
7276
7277 /*!
7278  * Returns a new DataArrayInt which contains all elements of given one-dimensional
7279  * arrays. The result array does not contain any duplicates and its values
7280  * are sorted in ascending order.
7281  *  \param [in] arr - sequence of DataArrayInt's to unite.
7282  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
7283  *         array using decrRef() as it is no more needed.
7284  *  \throw If any \a arr[i] is not allocated.
7285  *  \throw If \a arr[i]->getNumberOfComponents() != 1.
7286  */
7287 DataArrayInt *DataArrayInt::BuildUnion(const std::vector<const DataArrayInt *>& arr)
7288 {
7289   std::vector<const DataArrayInt *> a;
7290   for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
7291     if(*it4)
7292       a.push_back(*it4);
7293   for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
7294     {
7295       (*it)->checkAllocated();
7296       if((*it)->getNumberOfComponents()!=1)
7297         throw INTERP_KERNEL::Exception("DataArrayInt::BuildUnion : only single component allowed !");
7298     }
7299   //
7300   std::set<int> r;
7301   for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
7302     {
7303       const int *pt=(*it)->getConstPointer();
7304       int nbOfTuples=(*it)->getNumberOfTuples();
7305       r.insert(pt,pt+nbOfTuples);
7306     }
7307   DataArrayInt *ret=DataArrayInt::New();
7308   ret->alloc((int)r.size(),1);
7309   std::copy(r.begin(),r.end(),ret->getPointer());
7310   return ret;
7311 }
7312
7313 /*!
7314  * Returns a new DataArrayInt which contains elements present in each of given one-dimensional
7315  * arrays. The result array does not contain any duplicates and its values
7316  * are sorted in ascending order.
7317  *  \param [in] arr - sequence of DataArrayInt's to intersect.
7318  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
7319  *         array using decrRef() as it is no more needed.
7320  *  \throw If any \a arr[i] is not allocated.
7321  *  \throw If \a arr[i]->getNumberOfComponents() != 1.
7322  */
7323 DataArrayInt *DataArrayInt::BuildIntersection(const std::vector<const DataArrayInt *>& arr)
7324 {
7325   std::vector<const DataArrayInt *> a;
7326   for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
7327     if(*it4)
7328       a.push_back(*it4);
7329   for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
7330     {
7331       (*it)->checkAllocated();
7332       if((*it)->getNumberOfComponents()!=1)
7333         throw INTERP_KERNEL::Exception("DataArrayInt::BuildIntersection : only single component allowed !");
7334     }
7335   //
7336   std::set<int> r;
7337   for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
7338     {
7339       const int *pt=(*it)->getConstPointer();
7340       int nbOfTuples=(*it)->getNumberOfTuples();
7341       std::set<int> s1(pt,pt+nbOfTuples);
7342       if(it!=a.begin())
7343         {
7344           std::set<int> r2;
7345           std::set_intersection(r.begin(),r.end(),s1.begin(),s1.end(),inserter(r2,r2.end()));
7346           r=r2;
7347         }
7348       else
7349         r=s1;
7350     }
7351   DataArrayInt *ret(DataArrayInt::New());
7352   ret->alloc((int)r.size(),1);
7353   std::copy(r.begin(),r.end(),ret->getPointer());
7354   return ret;
7355 }
7356
7357 /// @cond INTERNAL
7358 namespace MEDCouplingImpl
7359 {
7360   class OpSwitchedOn
7361   {
7362   public:
7363     OpSwitchedOn(int *pt):_pt(pt),_cnt(0) { }
7364     void operator()(const bool& b) { if(b) *_pt++=_cnt; _cnt++; }
7365   private:
7366     int *_pt;
7367     int _cnt;
7368   };
7369
7370   class OpSwitchedOff
7371   {
7372   public:
7373     OpSwitchedOff(int *pt):_pt(pt),_cnt(0) { }
7374     void operator()(const bool& b) { if(!b) *_pt++=_cnt; _cnt++; }
7375   private:
7376     int *_pt;
7377     int _cnt;
7378   };
7379 }
7380 /// @endcond
7381
7382 /*!
7383  * This method returns the list of ids in ascending mode so that v[id]==true.
7384  */
7385 DataArrayInt *DataArrayInt::BuildListOfSwitchedOn(const std::vector<bool>& v)
7386 {
7387   int sz((int)std::count(v.begin(),v.end(),true));
7388   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(sz,1);
7389   std::for_each(v.begin(),v.end(),MEDCouplingImpl::OpSwitchedOn(ret->getPointer()));
7390   return ret.retn();
7391 }
7392
7393 /*!
7394  * This method returns the list of ids in ascending mode so that v[id]==false.
7395  */
7396 DataArrayInt *DataArrayInt::BuildListOfSwitchedOff(const std::vector<bool>& v)
7397 {
7398   int sz((int)std::count(v.begin(),v.end(),false));
7399   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(sz,1);
7400   std::for_each(v.begin(),v.end(),MEDCouplingImpl::OpSwitchedOff(ret->getPointer()));
7401   return ret.retn();
7402 }
7403
7404 /*!
7405  * This method allows to put a vector of vector of integer into a more compact data stucture (skyline). 
7406  * This method is not available into python because no available optimized data structure available to map std::vector< std::vector<int> >.
7407  *
7408  * \param [in] v the input data structure to be translate into skyline format.
7409  * \param [out] data the first element of the skyline format. The user is expected to deal with newly allocated array.
7410  * \param [out] dataIndex the second element of the skyline format.
7411  */
7412 void DataArrayInt::PutIntoToSkylineFrmt(const std::vector< std::vector<int> >& v, DataArrayInt *& data, DataArrayInt *& dataIndex)
7413 {
7414   int sz((int)v.size());
7415   MCAuto<DataArrayInt> ret0(DataArrayInt::New()),ret1(DataArrayInt::New());
7416   ret1->alloc(sz+1,1);
7417   int *pt(ret1->getPointer()); *pt=0;
7418   for(int i=0;i<sz;i++,pt++)
7419     pt[1]=pt[0]+(int)v[i].size();
7420   ret0->alloc(ret1->back(),1);
7421   pt=ret0->getPointer();
7422   for(int i=0;i<sz;i++)
7423     pt=std::copy(v[i].begin(),v[i].end(),pt);
7424   data=ret0.retn(); dataIndex=ret1.retn();
7425 }
7426
7427 /*!
7428  * Returns a new DataArrayInt which contains a complement of elements of \a this
7429  * one-dimensional array. I.e. the result array contains all elements from the range [0,
7430  * \a nbOfElement) not present in \a this array.
7431  *  \param [in] nbOfElement - maximal size of the result array.
7432  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
7433  *         array using decrRef() as it is no more needed.
7434  *  \throw If \a this is not allocated.
7435  *  \throw If \a this->getNumberOfComponents() != 1.
7436  *  \throw If any element \a x of \a this array violates condition ( 0 <= \a x < \a
7437  *         nbOfElement ).
7438  */
7439 DataArrayInt *DataArrayInt::buildComplement(int nbOfElement) const
7440 {
7441   checkAllocated();
7442   if(getNumberOfComponents()!=1)
7443     throw INTERP_KERNEL::Exception("DataArrayInt::buildComplement : only single component allowed !");
7444   std::vector<bool> tmp(nbOfElement);
7445   const int *pt=getConstPointer();
7446   int nbOfTuples=getNumberOfTuples();
7447   for(const int *w=pt;w!=pt+nbOfTuples;w++)
7448     if(*w>=0 && *w<nbOfElement)
7449       tmp[*w]=true;
7450     else
7451       throw INTERP_KERNEL::Exception("DataArrayInt::buildComplement : an element is not in valid range : [0,nbOfElement) !");
7452   int nbOfRetVal=(int)std::count(tmp.begin(),tmp.end(),false);
7453   DataArrayInt *ret=DataArrayInt::New();
7454   ret->alloc(nbOfRetVal,1);
7455   int j=0;
7456   int *retPtr=ret->getPointer();
7457   for(int i=0;i<nbOfElement;i++)
7458     if(!tmp[i])
7459       retPtr[j++]=i;
7460   return ret;
7461 }
7462
7463 /*!
7464  * Returns a new DataArrayInt containing elements of \a this one-dimensional missing
7465  * from an \a other one-dimensional array.
7466  *  \param [in] other - a DataArrayInt containing elements not to include in the result array.
7467  *  \return DataArrayInt * - a new instance of DataArrayInt with one component. The
7468  *         caller is to delete this array using decrRef() as it is no more needed.
7469  *  \throw If \a other is NULL.
7470  *  \throw If \a other is not allocated.
7471  *  \throw If \a other->getNumberOfComponents() != 1.
7472  *  \throw If \a this is not allocated.
7473  *  \throw If \a this->getNumberOfComponents() != 1.
7474  *  \sa DataArrayInt::buildSubstractionOptimized()
7475  */
7476 DataArrayInt *DataArrayInt::buildSubstraction(const DataArrayInt *other) const
7477 {
7478   if(!other)
7479     throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstraction : DataArrayInt pointer in input is NULL !");
7480   checkAllocated();
7481   other->checkAllocated();
7482   if(getNumberOfComponents()!=1)
7483     throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstraction : only single component allowed !");
7484   if(other->getNumberOfComponents()!=1)
7485     throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstraction : only single component allowed for other type !");
7486   const int *pt=getConstPointer();
7487   int nbOfTuples=getNumberOfTuples();
7488   std::set<int> s1(pt,pt+nbOfTuples);
7489   pt=other->getConstPointer();
7490   nbOfTuples=other->getNumberOfTuples();
7491   std::set<int> s2(pt,pt+nbOfTuples);
7492   std::vector<int> r;
7493   std::set_difference(s1.begin(),s1.end(),s2.begin(),s2.end(),std::back_insert_iterator< std::vector<int> >(r));
7494   DataArrayInt *ret=DataArrayInt::New();
7495   ret->alloc((int)r.size(),1);
7496   std::copy(r.begin(),r.end(),ret->getPointer());
7497   return ret;
7498 }
7499
7500 /*!
7501  * \a this is expected to have one component and to be sorted ascendingly (as for \a other).
7502  * \a other is expected to be a part of \a this. If not DataArrayInt::buildSubstraction should be called instead.
7503  * 
7504  * \param [in] other an array with one component and expected to be sorted ascendingly.
7505  * \ret list of ids in \a this but not in \a other.
7506  * \sa DataArrayInt::buildSubstraction
7507  */
7508 DataArrayInt *DataArrayInt::buildSubstractionOptimized(const DataArrayInt *other) const
7509 {
7510   static const char *MSG="DataArrayInt::buildSubstractionOptimized : only single component allowed !";
7511   if(!other) throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstractionOptimized : NULL input array !");
7512   checkAllocated(); other->checkAllocated();
7513   if(getNumberOfComponents()!=1) throw INTERP_KERNEL::Exception(MSG);
7514   if(other->getNumberOfComponents()!=1) throw INTERP_KERNEL::Exception(MSG);
7515   const int *pt1Bg(begin()),*pt1End(end()),*pt2Bg(other->begin()),*pt2End(other->end());
7516   const int *work1(pt1Bg),*work2(pt2Bg);
7517   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
7518   for(;work1!=pt1End;work1++)
7519     {
7520       if(work2!=pt2End && *work1==*work2)
7521         work2++;
7522       else
7523         ret->pushBackSilent(*work1);
7524     }
7525   return ret.retn();
7526 }
7527
7528
7529 /*!
7530  * Returns a new DataArrayInt which contains all elements of \a this and a given
7531  * one-dimensional arrays. The result array does not contain any duplicates
7532  * and its values are sorted in ascending order.
7533  *  \param [in] other - an array to unite with \a this one.
7534  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
7535  *         array using decrRef() as it is no more needed.
7536  *  \throw If \a this or \a other is not allocated.
7537  *  \throw If \a this->getNumberOfComponents() != 1.
7538  *  \throw If \a other->getNumberOfComponents() != 1.
7539  */
7540 DataArrayInt *DataArrayInt::buildUnion(const DataArrayInt *other) const
7541 {
7542   std::vector<const DataArrayInt *>arrs(2);
7543   arrs[0]=this; arrs[1]=other;
7544   return BuildUnion(arrs);
7545 }
7546
7547
7548 /*!
7549  * Returns a new DataArrayInt which contains elements present in both \a this and a given
7550  * one-dimensional arrays. The result array does not contain any duplicates
7551  * and its values are sorted in ascending order.
7552  *  \param [in] other - an array to intersect with \a this one.
7553  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
7554  *         array using decrRef() as it is no more needed.
7555  *  \throw If \a this or \a other is not allocated.
7556  *  \throw If \a this->getNumberOfComponents() != 1.
7557  *  \throw If \a other->getNumberOfComponents() != 1.
7558  */
7559 DataArrayInt *DataArrayInt::buildIntersection(const DataArrayInt *other) const
7560 {
7561   std::vector<const DataArrayInt *>arrs(2);
7562   arrs[0]=this; arrs[1]=other;
7563   return BuildIntersection(arrs);
7564 }
7565
7566 /*!
7567  * This method can be applied on allocated with one component DataArrayInt instance.
7568  * This method is typically relevant for sorted arrays. All consecutive duplicated items in \a this will appear only once in returned DataArrayInt instance.
7569  * 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]
7570  * 
7571  * \return a newly allocated array that contain the result of the unique operation applied on \a this.
7572  * \throw if \a this is not allocated or if \a this has not exactly one component.
7573  * \sa DataArrayInt::buildUniqueNotSorted
7574  */
7575 DataArrayInt *DataArrayInt::buildUnique() const
7576 {
7577   checkAllocated();
7578   if(getNumberOfComponents()!=1)
7579     throw INTERP_KERNEL::Exception("DataArrayInt::buildUnique : only single component allowed !");
7580   int nbOfTuples=getNumberOfTuples();
7581   MCAuto<DataArrayInt> tmp=deepCopy();
7582   int *data=tmp->getPointer();
7583   int *last=std::unique(data,data+nbOfTuples);
7584   MCAuto<DataArrayInt> ret=DataArrayInt::New();
7585   ret->alloc(std::distance(data,last),1);
7586   std::copy(data,last,ret->getPointer());
7587   return ret.retn();
7588 }
7589
7590 /*!
7591  * This method can be applied on allocated with one component DataArrayInt instance.
7592  * This method keep elements only once by keeping the same order in \a this that is not expected to be sorted.
7593  *
7594  * \return a newly allocated array that contain the result of the unique operation applied on \a this.
7595  *
7596  * \throw if \a this is not allocated or if \a this has not exactly one component.
7597  *
7598  * \sa DataArrayInt::buildUnique
7599  */
7600 DataArrayInt *DataArrayInt::buildUniqueNotSorted() const
7601 {
7602   checkAllocated();
7603     if(getNumberOfComponents()!=1)
7604       throw INTERP_KERNEL::Exception("DataArrayInt::buildUniqueNotSorted : only single component allowed !");
7605   int minVal,maxVal;
7606   getMinMaxValues(minVal,maxVal);
7607   std::vector<bool> b(maxVal-minVal+1,false);
7608   const int *ptBg(begin()),*endBg(end());
7609   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
7610   for(const int *pt=ptBg;pt!=endBg;pt++)
7611     {
7612       if(!b[*pt-minVal])
7613         {
7614           ret->pushBackSilent(*pt);
7615           b[*pt-minVal]=true;
7616         }
7617     }
7618   ret->copyStringInfoFrom(*this);
7619   return ret.retn();
7620 }
7621
7622 /*!
7623  * Returns a new DataArrayInt which contains size of every of groups described by \a this
7624  * "index" array. Such "index" array is returned for example by 
7625  * \ref MEDCoupling::MEDCouplingUMesh::buildDescendingConnectivity
7626  * "MEDCouplingUMesh::buildDescendingConnectivity" and
7627  * \ref MEDCoupling::MEDCouplingUMesh::getNodalConnectivityIndex
7628  * "MEDCouplingUMesh::getNodalConnectivityIndex" etc.
7629  * This method preforms the reverse operation of DataArrayInt::computeOffsetsFull.
7630  *  \return DataArrayInt * - a new instance of DataArrayInt, whose number of tuples
7631  *          equals to \a this->getNumberOfComponents() - 1, and number of components is 1.
7632  *          The caller is to delete this array using decrRef() as it is no more needed. 
7633  *  \throw If \a this is not allocated.
7634  *  \throw If \a this->getNumberOfComponents() != 1.
7635  *  \throw If \a this->getNumberOfTuples() < 2.
7636  *
7637  *  \b Example: <br> 
7638  *         - this contains [1,3,6,7,7,9,15]
7639  *         - result array contains [2,3,1,0,2,6],
7640  *          where 2 = 3 - 1, 3 = 6 - 3, 1 = 7 - 6 etc.
7641  *
7642  * \sa DataArrayInt::computeOffsetsFull
7643  */
7644 DataArrayInt *DataArrayInt::deltaShiftIndex() const
7645 {
7646   checkAllocated();
7647   if(getNumberOfComponents()!=1)
7648     throw INTERP_KERNEL::Exception("DataArrayInt::deltaShiftIndex : only single component allowed !");
7649   int nbOfTuples=getNumberOfTuples();
7650   if(nbOfTuples<2)
7651     throw INTERP_KERNEL::Exception("DataArrayInt::deltaShiftIndex : 1 tuple at least must be present in 'this' !");
7652   const int *ptr=getConstPointer();
7653   DataArrayInt *ret=DataArrayInt::New();
7654   ret->alloc(nbOfTuples-1,1);
7655   int *out=ret->getPointer();
7656   std::transform(ptr+1,ptr+nbOfTuples,ptr,out,std::minus<int>());
7657   return ret;
7658 }
7659
7660 /*!
7661  * Modifies \a this one-dimensional array so that value of each element \a x
7662  * of \a this array (\a a) is computed as \f$ x_i = \sum_{j=0}^{i-1} a[ j ] \f$.
7663  * Or: for each i>0 new[i]=new[i-1]+old[i-1] for i==0 new[i]=0. Number of tuples
7664  * and components remains the same.<br>
7665  * This method is useful for allToAllV in MPI with contiguous policy. This method
7666  * differs from computeOffsetsFull() in that the number of tuples is \b not changed by
7667  * this one.
7668  *  \throw If \a this is not allocated.
7669  *  \throw If \a this->getNumberOfComponents() != 1.
7670  *
7671  *  \b Example: <br>
7672  *          - Before \a this contains [3,5,1,2,0,8]
7673  *          - After \a this contains  [0,3,8,9,11,11]<br>
7674  *          Note that the last element 19 = 11 + 8 is missing because size of \a this
7675  *          array is retained and thus there is no space to store the last element.
7676  */
7677 void DataArrayInt::computeOffsets()
7678 {
7679   checkAllocated();
7680   if(getNumberOfComponents()!=1)
7681     throw INTERP_KERNEL::Exception("DataArrayInt::computeOffsets : only single component allowed !");
7682   int nbOfTuples=getNumberOfTuples();
7683   if(nbOfTuples==0)
7684     return ;
7685   int *work=getPointer();
7686   int tmp=work[0];
7687   work[0]=0;
7688   for(int i=1;i<nbOfTuples;i++)
7689     {
7690       int tmp2=work[i];
7691       work[i]=work[i-1]+tmp;
7692       tmp=tmp2;
7693     }
7694   declareAsNew();
7695 }
7696
7697
7698 /*!
7699  * Modifies \a this one-dimensional array so that value of each element \a x
7700  * of \a this array (\a a) is computed as \f$ x_i = \sum_{j=0}^{i-1} a[ j ] \f$.
7701  * Or: for each i>0 new[i]=new[i-1]+old[i-1] for i==0 new[i]=0. Number
7702  * components remains the same and number of tuples is inceamented by one.<br>
7703  * This method is useful for allToAllV in MPI with contiguous policy. This method
7704  * differs from computeOffsets() in that the number of tuples is changed by this one.
7705  * This method preforms the reverse operation of DataArrayInt::deltaShiftIndex.
7706  *  \throw If \a this is not allocated.
7707  *  \throw If \a this->getNumberOfComponents() != 1.
7708  *
7709  *  \b Example: <br>
7710  *          - Before \a this contains [3,5,1,2,0,8]
7711  *          - After \a this contains  [0,3,8,9,11,11,19]<br>
7712  * \sa DataArrayInt::deltaShiftIndex
7713  */
7714 void DataArrayInt::computeOffsetsFull()
7715 {
7716   checkAllocated();
7717   if(getNumberOfComponents()!=1)
7718     throw INTERP_KERNEL::Exception("DataArrayInt::computeOffsetsFull : only single component allowed !");
7719   int nbOfTuples=getNumberOfTuples();
7720   int *ret=(int *)malloc((nbOfTuples+1)*sizeof(int));
7721   const int *work=getConstPointer();
7722   ret[0]=0;
7723   for(int i=0;i<nbOfTuples;i++)
7724     ret[i+1]=work[i]+ret[i];
7725   useArray(ret,true,C_DEALLOC,nbOfTuples+1,1);
7726   declareAsNew();
7727 }
7728
7729 /*!
7730  * Returns two new DataArrayInt instances whose contents is computed from that of \a this and \a listOfIds arrays as follows.
7731  * \a this is expected to be an offset format ( as returned by DataArrayInt::computeOffsetsFull ) that is to say with one component
7732  * and ** sorted strictly increasingly **. \a listOfIds is expected to be sorted ascendingly (not strictly needed for \a listOfIds).
7733  * This methods searches in \a this, considered as a set of contiguous \c this->getNumberOfComponents() ranges, all ids in \a listOfIds
7734  * filling completely one of the ranges in \a this.
7735  *
7736  * \param [in] listOfIds a list of ids that has to be sorted ascendingly.
7737  * \param [out] rangeIdsFetched the range ids fetched
7738  * \param [out] idsInInputListThatFetch contains the list of ids in \a listOfIds that are \b fully included in a range in \a this. So
7739  *              \a idsInInputListThatFetch is a part of input \a listOfIds.
7740  *
7741  * \sa DataArrayInt::computeOffsetsFull
7742  *
7743  *  \b Example: <br>
7744  *          - \a this : [0,3,7,9,15,18]
7745  *          - \a listOfIds contains  [0,1,2,3,7,8,15,16,17]
7746  *          - \a rangeIdsFetched result array: [0,2,4]
7747  *          - \a idsInInputListThatFetch result array: [0,1,2,7,8,15,16,17]
7748  * In this example id 3 in input \a listOfIds is alone so it do not appear in output \a idsInInputListThatFetch.
7749  * <br>
7750  */
7751 void DataArrayInt::findIdsRangesInListOfIds(const DataArrayInt *listOfIds, DataArrayInt *& rangeIdsFetched, DataArrayInt *& idsInInputListThatFetch) const
7752 {
7753   if(!listOfIds)
7754     throw INTERP_KERNEL::Exception("DataArrayInt::findIdsRangesInListOfIds : input list of ids is null !");
7755   listOfIds->checkAllocated(); checkAllocated();
7756   if(listOfIds->getNumberOfComponents()!=1)
7757     throw INTERP_KERNEL::Exception("DataArrayInt::findIdsRangesInListOfIds : input list of ids must have exactly one component !");
7758   if(getNumberOfComponents()!=1)
7759     throw INTERP_KERNEL::Exception("DataArrayInt::findIdsRangesInListOfIds : this must have exactly one component !");
7760   MCAuto<DataArrayInt> ret0=DataArrayInt::New(); ret0->alloc(0,1);
7761   MCAuto<DataArrayInt> ret1=DataArrayInt::New(); ret1->alloc(0,1);
7762   const int *tupEnd(listOfIds->end()),*offBg(begin()),*offEnd(end()-1);
7763   const int *tupPtr(listOfIds->begin()),*offPtr(offBg);
7764   while(tupPtr!=tupEnd && offPtr!=offEnd)
7765     {
7766       if(*tupPtr==*offPtr)
7767         {
7768           int i=offPtr[0];
7769           while(i<offPtr[1] && *tupPtr==i && tupPtr!=tupEnd) { i++; tupPtr++; }
7770           if(i==offPtr[1])
7771             {
7772               ret0->pushBackSilent((int)std::distance(offBg,offPtr));
7773               ret1->pushBackValsSilent(tupPtr-(offPtr[1]-offPtr[0]),tupPtr);
7774               offPtr++;
7775             }
7776         }
7777       else
7778         { if(*tupPtr<*offPtr) tupPtr++; else offPtr++; }
7779     }
7780   rangeIdsFetched=ret0.retn();
7781   idsInInputListThatFetch=ret1.retn();
7782 }
7783
7784 /*!
7785  * Returns a new DataArrayInt whose contents is computed from that of \a this and \a
7786  * offsets arrays as follows. \a offsets is a one-dimensional array considered as an
7787  * "index" array of a "iota" array, thus, whose each element gives an index of a group
7788  * beginning within the "iota" array. And \a this is a one-dimensional array
7789  * considered as a selector of groups described by \a offsets to include into the result array.
7790  *  \throw If \a offsets is NULL.
7791  *  \throw If \a offsets is not allocated.
7792  *  \throw If \a offsets->getNumberOfComponents() != 1.
7793  *  \throw If \a offsets is not monotonically increasing.
7794  *  \throw If \a this is not allocated.
7795  *  \throw If \a this->getNumberOfComponents() != 1.
7796  *  \throw If any element of \a this is not a valid index for \a offsets array.
7797  *
7798  *  \b Example: <br>
7799  *          - \a this: [0,2,3]
7800  *          - \a offsets: [0,3,6,10,14,20]
7801  *          - result array: [0,1,2,6,7,8,9,10,11,12,13] == <br>
7802  *            \c range(0,3) + \c range(6,10) + \c range(10,14) ==<br>
7803  *            \c range( \a offsets[ \a this[0] ], offsets[ \a this[0]+1 ]) + 
7804  *            \c range( \a offsets[ \a this[1] ], offsets[ \a this[1]+1 ]) + 
7805  *            \c range( \a offsets[ \a this[2] ], offsets[ \a this[2]+1 ])
7806  */
7807 DataArrayInt *DataArrayInt::buildExplicitArrByRanges(const DataArrayInt *offsets) const
7808 {
7809   if(!offsets)
7810     throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrByRanges : DataArrayInt pointer in input is NULL !");
7811   checkAllocated();
7812   if(getNumberOfComponents()!=1)
7813     throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrByRanges : only single component allowed !");
7814   offsets->checkAllocated();
7815   if(offsets->getNumberOfComponents()!=1)
7816     throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrByRanges : input array should have only single component !");
7817   int othNbTuples=offsets->getNumberOfTuples()-1;
7818   int nbOfTuples=getNumberOfTuples();
7819   int retNbOftuples=0;
7820   const int *work=getConstPointer();
7821   const int *offPtr=offsets->getConstPointer();
7822   for(int i=0;i<nbOfTuples;i++)
7823     {
7824       int val=work[i];
7825       if(val>=0 && val<othNbTuples)
7826         {
7827           int delta=offPtr[val+1]-offPtr[val];
7828           if(delta>=0)
7829             retNbOftuples+=delta;
7830           else
7831             {
7832               std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrByRanges : Tuple #" << val << " of offset array has a delta < 0 !";
7833               throw INTERP_KERNEL::Exception(oss.str().c_str());
7834             }
7835         }
7836       else
7837         {
7838           std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrByRanges : Tuple #" << i << " in this contains " << val;
7839           oss << " whereas offsets array is of size " << othNbTuples+1 << " !";
7840           throw INTERP_KERNEL::Exception(oss.str().c_str());
7841         }
7842     }
7843   MCAuto<DataArrayInt> ret=DataArrayInt::New();
7844   ret->alloc(retNbOftuples,1);
7845   int *retPtr=ret->getPointer();
7846   for(int i=0;i<nbOfTuples;i++)
7847     {
7848       int val=work[i];
7849       int start=offPtr[val];
7850       int off=offPtr[val+1]-start;
7851       for(int j=0;j<off;j++,retPtr++)
7852         *retPtr=start+j;
7853     }
7854   return ret.retn();
7855 }
7856
7857 /*!
7858  * Returns a new DataArrayInt whose contents is computed using \a this that must be a 
7859  * scaled array (monotonically increasing).
7860 from that of \a this and \a
7861  * offsets arrays as follows. \a offsets is a one-dimensional array considered as an
7862  * "index" array of a "iota" array, thus, whose each element gives an index of a group
7863  * beginning within the "iota" array. And \a this is a one-dimensional array
7864  * considered as a selector of groups described by \a offsets to include into the result array.
7865  *  \throw If \a  is NULL.
7866  *  \throw If \a this is not allocated.
7867  *  \throw If \a this->getNumberOfComponents() != 1.
7868  *  \throw If \a this->getNumberOfTuples() == 0.
7869  *  \throw If \a this is not monotonically increasing.
7870  *  \throw If any element of ids in ( \a bg \a stop \a step ) points outside the scale in \a this.
7871  *
7872  *  \b Example: <br>
7873  *          - \a bg , \a stop and \a step : (0,5,2)
7874  *          - \a this: [0,3,6,10,14,20]
7875  *          - result array: [0,0,0, 2,2,2,2, 4,4,4,4,4,4] == <br>
7876  */
7877 DataArrayInt *DataArrayInt::buildExplicitArrOfSliceOnScaledArr(int bg, int stop, int step) const
7878 {
7879   if(!isAllocated())
7880     throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrOfSliceOnScaledArr : not allocated array !");
7881   if(getNumberOfComponents()!=1)
7882     throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrOfSliceOnScaledArr : number of components is expected to be equal to one !");
7883   int nbOfTuples(getNumberOfTuples());
7884   if(nbOfTuples==0)
7885     throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrOfSliceOnScaledArr : number of tuples must be != 0 !");
7886   const int *ids(begin());
7887   int nbOfEltsInSlc(GetNumberOfItemGivenBESRelative(bg,stop,step,"DataArrayInt::buildExplicitArrOfSliceOnScaledArr")),sz(0),pos(bg);
7888   for(int i=0;i<nbOfEltsInSlc;i++,pos+=step)
7889     {
7890       if(pos>=0 && pos<nbOfTuples-1)
7891         {
7892           int delta(ids[pos+1]-ids[pos]);
7893           sz+=delta;
7894           if(delta<0)
7895             {
7896               std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrOfSliceOnScaledArr : At pos #" << i << " of input slice, value is " << pos << " and at this pos this is not monotonically increasing !";
7897               throw INTERP_KERNEL::Exception(oss.str().c_str());
7898             }          
7899         }
7900       else
7901         {
7902           std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrOfSliceOnScaledArr : At pos #" << i << " of input slice, value is " << pos << " should be in [0," << nbOfTuples-1 << ") !";  
7903           throw INTERP_KERNEL::Exception(oss.str().c_str());
7904         }
7905     }
7906   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(sz,1);
7907   int *retPtr(ret->getPointer());
7908   pos=bg;
7909   for(int i=0;i<nbOfEltsInSlc;i++,pos+=step)
7910     {
7911       int delta(ids[pos+1]-ids[pos]);
7912       for(int j=0;j<delta;j++,retPtr++)
7913         *retPtr=pos;
7914     }
7915   return ret.retn();
7916 }
7917
7918 /*!
7919  * 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.
7920  * 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
7921  * in tuple **i** of returned DataArrayInt.
7922  * If ranges overlapped (in theory it should not) this method do not detect it and always returns the first range.
7923  *
7924  * 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)]
7925  * The return DataArrayInt will contain : **[0,4,1,2,2,3]**
7926  * 
7927  * \param [in] ranges typically come from output of MEDCouplingUMesh::ComputeRangesFromTypeDistribution. Each range is specified like this : 1st component is
7928  *             for lower value included and 2nd component is the upper value of corresponding range **excluded**.
7929  * \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
7930  *        is thrown if no ranges in \a ranges contains value in \a this.
7931  * 
7932  * \sa DataArrayInt::findIdInRangeForEachTuple
7933  */
7934 DataArrayInt *DataArrayInt::findRangeIdForEachTuple(const DataArrayInt *ranges) const
7935 {
7936   if(!ranges)
7937     throw INTERP_KERNEL::Exception("DataArrayInt::findRangeIdForEachTuple : null input pointer !");
7938   if(ranges->getNumberOfComponents()!=2)
7939     throw INTERP_KERNEL::Exception("DataArrayInt::findRangeIdForEachTuple : input DataArrayInt instance should have 2 components !");
7940   checkAllocated();
7941   if(getNumberOfComponents()!=1)
7942     throw INTERP_KERNEL::Exception("DataArrayInt::findRangeIdForEachTuple : this should have only one component !");
7943   int nbTuples=getNumberOfTuples();
7944   MCAuto<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbTuples,1);
7945   int nbOfRanges=ranges->getNumberOfTuples();
7946   const int *rangesPtr=ranges->getConstPointer();
7947   int *retPtr=ret->getPointer();
7948   const int *inPtr=getConstPointer();
7949   for(int i=0;i<nbTuples;i++,retPtr++)
7950     {
7951       int val=inPtr[i];
7952       bool found=false;
7953       for(int j=0;j<nbOfRanges && !found;j++)
7954         if(val>=rangesPtr[2*j] && val<rangesPtr[2*j+1])
7955           { *retPtr=j; found=true; }
7956       if(found)
7957         continue;
7958       else
7959         {
7960           std::ostringstream oss; oss << "DataArrayInt::findRangeIdForEachTuple : tuple #" << i << " not found by any ranges !";
7961           throw INTERP_KERNEL::Exception(oss.str().c_str());
7962         }
7963     }
7964   return ret.retn();
7965 }
7966
7967 /*!
7968  * 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.
7969  * 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
7970  * in tuple **i** of returned DataArrayInt.
7971  * If ranges overlapped (in theory it should not) this method do not detect it and always returns the sub position of the first range.
7972  *
7973  * 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)]
7974  * The return DataArrayInt will contain : **[1,2,4,0,2,2]**
7975  * This method is often called in pair with DataArrayInt::findRangeIdForEachTuple method.
7976  * 
7977  * \param [in] ranges typically come from output of MEDCouplingUMesh::ComputeRangesFromTypeDistribution. Each range is specified like this : 1st component is
7978  *             for lower value included and 2nd component is the upper value of corresponding range **excluded**.
7979  * \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
7980  *        is thrown if no ranges in \a ranges contains value in \a this.
7981  * \sa DataArrayInt::findRangeIdForEachTuple
7982  */
7983 DataArrayInt *DataArrayInt::findIdInRangeForEachTuple(const DataArrayInt *ranges) const
7984 {
7985   if(!ranges)
7986     throw INTERP_KERNEL::Exception("DataArrayInt::findIdInRangeForEachTuple : null input pointer !");
7987   if(ranges->getNumberOfComponents()!=2)
7988     throw INTERP_KERNEL::Exception("DataArrayInt::findIdInRangeForEachTuple : input DataArrayInt instance should have 2 components !");
7989   checkAllocated();
7990   if(getNumberOfComponents()!=1)
7991     throw INTERP_KERNEL::Exception("DataArrayInt::findIdInRangeForEachTuple : this should have only one component !");
7992   int nbTuples=getNumberOfTuples();
7993   MCAuto<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbTuples,1);
7994   int nbOfRanges=ranges->getNumberOfTuples();
7995   const int *rangesPtr=ranges->getConstPointer();
7996   int *retPtr=ret->getPointer();
7997   const int *inPtr=getConstPointer();
7998   for(int i=0;i<nbTuples;i++,retPtr++)
7999     {
8000       int val=inPtr[i];
8001       bool found=false;
8002       for(int j=0;j<nbOfRanges && !found;j++)
8003         if(val>=rangesPtr[2*j] && val<rangesPtr[2*j+1])
8004           { *retPtr=val-rangesPtr[2*j]; found=true; }
8005       if(found)
8006         continue;
8007       else
8008         {
8009           std::ostringstream oss; oss << "DataArrayInt::findIdInRangeForEachTuple : tuple #" << i << " not found by any ranges !";
8010           throw INTERP_KERNEL::Exception(oss.str().c_str());
8011         }
8012     }
8013   return ret.retn();
8014 }
8015
8016 /*!
8017  * \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).
8018  * 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).
8019  * 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 !
8020  * If this method has correctly worked, \a this will be able to be considered as a linked list.
8021  * This method does nothing if number of tuples is lower of equal to 1.
8022  *
8023  * This method is useful for users having an unstructured mesh having only SEG2 to rearrange internaly the connectibity without any coordinates consideration.
8024  *
8025  * \sa MEDCouplingUMesh::orderConsecutiveCells1D, DataArrayInt::fromLinkedListOfPairToList
8026  */
8027 void DataArrayInt::sortEachPairToMakeALinkedList()
8028 {
8029   checkAllocated();
8030   if(getNumberOfComponents()!=2)
8031     throw INTERP_KERNEL::Exception("DataArrayInt::sortEachPairToMakeALinkedList : Only works on DataArrayInt instance with nb of components equal to 2 !");
8032   int nbOfTuples(getNumberOfTuples());
8033   if(nbOfTuples<=1)
8034     return ;
8035   int *conn(getPointer());
8036   for(int i=1;i<nbOfTuples;i++,conn+=2)
8037     {
8038       if(i>1)
8039         {
8040           if(conn[2]==conn[3])
8041             {
8042               std::ostringstream oss; oss << "DataArrayInt::sortEachPairToMakeALinkedList : In the tuple #" << i << " presence of a pair filled with same ids !";
8043               throw INTERP_KERNEL::Exception(oss.str().c_str());
8044             }
8045           if(conn[2]!=conn[1] && conn[3]==conn[1] && conn[2]!=conn[0])
8046             std::swap(conn[2],conn[3]);
8047           //not(conn[2]==conn[1] && conn[3]!=conn[1] && conn[3]!=conn[0])
8048           if(conn[2]!=conn[1] || conn[3]==conn[1] || conn[3]==conn[0])
8049             {
8050               std::ostringstream oss; oss << "DataArrayInt::sortEachPairToMakeALinkedList : In the tuple #" << i << " something is invalid !";
8051               throw INTERP_KERNEL::Exception(oss.str().c_str());
8052             }
8053         }
8054       else
8055         {
8056           if(conn[0]==conn[1] || conn[2]==conn[3])
8057             throw INTERP_KERNEL::Exception("DataArrayInt::sortEachPairToMakeALinkedList : In the 2 first tuples presence of a pair filled with same ids !");
8058           int tmp[4];
8059           std::set<int> s;
8060           s.insert(conn,conn+4);
8061           if(s.size()!=3)
8062             throw INTERP_KERNEL::Exception("DataArrayInt::sortEachPairToMakeALinkedList : This can't be considered as a linked list regarding 2 first tuples !");
8063           if(std::count(conn,conn+4,conn[0])==2)
8064             {
8065               tmp[0]=conn[1];
8066               tmp[1]=conn[0];
8067               tmp[2]=conn[0];
8068               if(conn[2]==conn[0])
8069                 { tmp[3]=conn[3]; }
8070               else
8071                 { tmp[3]=conn[2];}
8072               std::copy(tmp,tmp+4,conn);
8073             }
8074           else
8075             {//here we are sure to have (std::count(conn,conn+4,conn[1])==2)
8076               if(conn[1]==conn[3])
8077                 std::swap(conn[2],conn[3]);
8078             }
8079         }
8080     }
8081 }
8082
8083 /*!
8084  * \a this is expected to be a correctly linked list of pairs.
8085  * 
8086  * \sa DataArrayInt::sortEachPairToMakeALinkedList
8087  */
8088 MCAuto<DataArrayInt> DataArrayInt::fromLinkedListOfPairToList() const
8089 {
8090   checkAllocated();
8091   checkNbOfComps(2,"DataArrayInt::fromLinkedListOfPairToList : this is expected to have 2 components");
8092   int nbTuples(getNumberOfTuples());
8093   if(nbTuples<1)
8094     throw INTERP_KERNEL::Exception("DataArrayInt::fromLinkedListOfPairToList : no tuples in this ! Not a linked list !");
8095   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(nbTuples+1,1);
8096   const int *thisPtr(begin());
8097   int *retPtr(ret->getPointer());
8098   retPtr[0]=thisPtr[0];
8099   for(int i=0;i<nbTuples;i++)
8100     {
8101       retPtr[i+1]=thisPtr[2*i+1];
8102       if(i<nbTuples-1)
8103         if(thisPtr[2*i+1]!=thisPtr[2*(i+1)+0])
8104           {
8105             std::ostringstream oss; oss << "DataArrayInt::fromLinkedListOfPairToList : this is not a proper linked list of pair. The link is broken between tuple #" << i << " and tuple #" << i+1 << " ! Call sortEachPairToMakeALinkedList ?";
8106             throw INTERP_KERNEL::Exception(oss.str());
8107           }
8108     }
8109   return ret;
8110 }
8111
8112 /*!
8113  * 
8114  * \param [in] nbTimes specifies the nb of times each tuples in \a this will be duplicated contiguouly in returned DataArrayInt instance.
8115  *             \a nbTimes  should be at least equal to 1.
8116  * \return a newly allocated DataArrayInt having one component and number of tuples equal to \a nbTimes * \c this->getNumberOfTuples.
8117  * \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.
8118  */
8119 DataArrayInt *DataArrayInt::duplicateEachTupleNTimes(int nbTimes) const
8120 {
8121   checkAllocated();
8122   if(getNumberOfComponents()!=1)
8123     throw INTERP_KERNEL::Exception("DataArrayInt::duplicateEachTupleNTimes : this should have only one component !");
8124   if(nbTimes<1)
8125     throw INTERP_KERNEL::Exception("DataArrayInt::duplicateEachTupleNTimes : nb times should be >= 1 !");
8126   int nbTuples=getNumberOfTuples();
8127   const int *inPtr=getConstPointer();
8128   MCAuto<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbTimes*nbTuples,1);
8129   int *retPtr=ret->getPointer();
8130   for(int i=0;i<nbTuples;i++,inPtr++)
8131     {
8132       int val=*inPtr;
8133       for(int j=0;j<nbTimes;j++,retPtr++)
8134         *retPtr=val;
8135     }
8136   ret->copyStringInfoFrom(*this);
8137   return ret.retn();
8138 }
8139
8140 /*!
8141  * This method returns all different values found in \a this. This method throws if \a this has not been allocated.
8142  * But the number of components can be different from one.
8143  * \return a newly allocated array (that should be dealt by the caller) containing different values in \a this.
8144  */
8145 DataArrayInt *DataArrayInt::getDifferentValues() const
8146 {
8147   checkAllocated();
8148   std::set<int> ret;
8149   ret.insert(begin(),end());
8150   MCAuto<DataArrayInt> ret2=DataArrayInt::New(); ret2->alloc((int)ret.size(),1);
8151   std::copy(ret.begin(),ret.end(),ret2->getPointer());
8152   return ret2.retn();
8153 }
8154
8155 /*!
8156  * This method is a refinement of DataArrayInt::getDifferentValues because it returns not only different values in \a this but also, for each of
8157  * them it tells which tuple id have this id.
8158  * This method works only on arrays with one component (if it is not the case call DataArrayInt::rearrange(1) ).
8159  * This method returns two arrays having same size.
8160  * 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.
8161  * 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]]
8162  */
8163 std::vector<DataArrayInt *> DataArrayInt::partitionByDifferentValues(std::vector<int>& differentIds) const
8164 {
8165   checkAllocated();
8166   if(getNumberOfComponents()!=1)
8167     throw INTERP_KERNEL::Exception("DataArrayInt::partitionByDifferentValues : this should have only one component !");
8168   int id=0;
8169   std::map<int,int> m,m2,m3;
8170   for(const int *w=begin();w!=end();w++)
8171     m[*w]++;
8172   differentIds.resize(m.size());
8173   std::vector<DataArrayInt *> ret(m.size());
8174   std::vector<int *> retPtr(m.size());
8175   for(std::map<int,int>::const_iterator it=m.begin();it!=m.end();it++,id++)
8176     {
8177       m2[(*it).first]=id;
8178       ret[id]=DataArrayInt::New();
8179       ret[id]->alloc((*it).second,1);
8180       retPtr[id]=ret[id]->getPointer();
8181       differentIds[id]=(*it).first;
8182     }
8183   id=0;
8184   for(const int *w=begin();w!=end();w++,id++)
8185     {
8186       retPtr[m2[*w]][m3[*w]++]=id;
8187     }
8188   return ret;
8189 }
8190
8191 /*!
8192  * This method split ids in [0, \c this->getNumberOfTuples() ) using \a this array as a field of weight (>=0 each).
8193  * The aim of this method is to return a set of \a nbOfSlices chunk of contiguous ids as balanced as possible.
8194  *
8195  * \param [in] nbOfSlices - number of slices expected.
8196  * \return - a vector having a size equal to \a nbOfSlices giving the start (included) and the stop (excluded) of each chunks.
8197  * 
8198  * \sa DataArray::GetSlice
8199  * \throw If \a this is not allocated or not with exactly one component.
8200  * \throw If an element in \a this if < 0.
8201  */
8202 std::vector< std::pair<int,int> > DataArrayInt::splitInBalancedSlices(int nbOfSlices) const
8203 {
8204   if(!isAllocated() || getNumberOfComponents()!=1)
8205     throw INTERP_KERNEL::Exception("DataArrayInt::splitInBalancedSlices : this array should have number of components equal to one and must be allocated !");
8206   if(nbOfSlices<=0)
8207     throw INTERP_KERNEL::Exception("DataArrayInt::splitInBalancedSlices : number of slices must be >= 1 !");
8208   int sum(accumulate(0)),nbOfTuples(getNumberOfTuples());
8209   int sumPerSlc(sum/nbOfSlices),pos(0);
8210   const int *w(begin());
8211   std::vector< std::pair<int,int> > ret(nbOfSlices);
8212   for(int i=0;i<nbOfSlices;i++)
8213     {
8214       std::pair<int,int> p(pos,-1);
8215       int locSum(0);
8216       while(locSum<sumPerSlc && pos<nbOfTuples) { pos++; locSum+=*w++; }
8217       if(i!=nbOfSlices-1)
8218         p.second=pos;
8219       else
8220         p.second=nbOfTuples;
8221       ret[i]=p;
8222     }
8223   return ret;
8224 }
8225
8226 /*!
8227  * Returns a new DataArrayInt that is a sum of two given arrays. There are 3
8228  * valid cases.
8229  * 1.  The arrays have same number of tuples and components. Then each value of
8230  *   the result array (_a_) is a sum of the corresponding values of \a a1 and \a a2,
8231  *   i.e.: _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ i, j ].
8232  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
8233  *   component. Then
8234  *   _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ i, 0 ].
8235  * 3.  The arrays have same number of components and one array, say _a2_, has one
8236  *   tuple. Then
8237  *   _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ 0, j ].
8238  *
8239  * Info on components is copied either from the first array (in the first case) or from
8240  * the array with maximal number of elements (getNbOfElems()).
8241  *  \param [in] a1 - an array to sum up.
8242  *  \param [in] a2 - another array to sum up.
8243  *  \return DataArrayInt * - the new instance of DataArrayInt.
8244  *          The caller is to delete this result array using decrRef() as it is no more
8245  *          needed.
8246  *  \throw If either \a a1 or \a a2 is NULL.
8247  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
8248  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
8249  *         none of them has number of tuples or components equal to 1.
8250  */
8251 DataArrayInt *DataArrayInt::Add(const DataArrayInt *a1, const DataArrayInt *a2)
8252 {
8253   if(!a1 || !a2)
8254     throw INTERP_KERNEL::Exception("DataArrayInt::Add : input DataArrayInt instance is NULL !");
8255   int nbOfTuple=a1->getNumberOfTuples();
8256   int nbOfTuple2=a2->getNumberOfTuples();
8257   int nbOfComp=a1->getNumberOfComponents();
8258   int nbOfComp2=a2->getNumberOfComponents();
8259   MCAuto<DataArrayInt> ret=0;
8260   if(nbOfTuple==nbOfTuple2)
8261     {
8262       if(nbOfComp==nbOfComp2)
8263         {
8264           ret=DataArrayInt::New();
8265           ret->alloc(nbOfTuple,nbOfComp);
8266           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::plus<int>());
8267           ret->copyStringInfoFrom(*a1);
8268         }
8269       else
8270         {
8271           int nbOfCompMin,nbOfCompMax;
8272           const DataArrayInt *aMin, *aMax;
8273           if(nbOfComp>nbOfComp2)
8274             {
8275               nbOfCompMin=nbOfComp2; nbOfCompMax=nbOfComp;
8276               aMin=a2; aMax=a1;
8277             }
8278           else
8279             {
8280               nbOfCompMin=nbOfComp; nbOfCompMax=nbOfComp2;
8281               aMin=a1; aMax=a2;
8282             }
8283           if(nbOfCompMin==1)
8284             {
8285               ret=DataArrayInt::New();
8286               ret->alloc(nbOfTuple,nbOfCompMax);
8287               const int *aMinPtr=aMin->getConstPointer();
8288               const int *aMaxPtr=aMax->getConstPointer();
8289               int *res=ret->getPointer();
8290               for(int i=0;i<nbOfTuple;i++)
8291                 res=std::transform(aMaxPtr+i*nbOfCompMax,aMaxPtr+(i+1)*nbOfCompMax,res,std::bind2nd(std::plus<int>(),aMinPtr[i]));
8292               ret->copyStringInfoFrom(*aMax);
8293             }
8294           else
8295             throw INTERP_KERNEL::Exception("Nb of components mismatch for array Add !");
8296         }
8297     }
8298   else if((nbOfTuple==1 && nbOfTuple2>1) || (nbOfTuple>1 && nbOfTuple2==1))
8299     {
8300       if(nbOfComp==nbOfComp2)
8301         {
8302           int nbOfTupleMax=std::max(nbOfTuple,nbOfTuple2);
8303           const DataArrayInt *aMin=nbOfTuple>nbOfTuple2?a2:a1;
8304           const DataArrayInt *aMax=nbOfTuple>nbOfTuple2?a1:a2;
8305           const int *aMinPtr=aMin->getConstPointer(),*aMaxPtr=aMax->getConstPointer();
8306           ret=DataArrayInt::New();
8307           ret->alloc(nbOfTupleMax,nbOfComp);
8308           int *res=ret->getPointer();
8309           for(int i=0;i<nbOfTupleMax;i++)
8310             res=std::transform(aMaxPtr+i*nbOfComp,aMaxPtr+(i+1)*nbOfComp,aMinPtr,res,std::plus<int>());
8311           ret->copyStringInfoFrom(*aMax);
8312         }
8313       else
8314         throw INTERP_KERNEL::Exception("Nb of components mismatch for array Add !");
8315     }
8316   else
8317     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Add !");
8318   return ret.retn();
8319 }
8320
8321 /*!
8322  * Adds values of another DataArrayInt to values of \a this one. There are 3
8323  * valid cases.
8324  * 1.  The arrays have same number of tuples and components. Then each value of
8325  *   \a other array is added to the corresponding value of \a this array, i.e.:
8326  *   _a_ [ i, j ] += _other_ [ i, j ].
8327  * 2.  The arrays have same number of tuples and \a other array has one component. Then
8328  *   _a_ [ i, j ] += _other_ [ i, 0 ].
8329  * 3.  The arrays have same number of components and \a other array has one tuple. Then
8330  *   _a_ [ i, j ] += _a2_ [ 0, j ].
8331  *
8332  *  \param [in] other - an array to add to \a this one.
8333  *  \throw If \a other is NULL.
8334  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
8335  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
8336  *         \a other has number of both tuples and components not equal to 1.
8337  */
8338 void DataArrayInt::addEqual(const DataArrayInt *other)
8339 {
8340   if(!other)
8341     throw INTERP_KERNEL::Exception("DataArrayInt::addEqual : input DataArrayInt instance is NULL !");
8342   const char *msg="Nb of tuples mismatch for DataArrayInt::addEqual  !";
8343   checkAllocated(); other->checkAllocated();
8344   int nbOfTuple=getNumberOfTuples();
8345   int nbOfTuple2=other->getNumberOfTuples();
8346   int nbOfComp=getNumberOfComponents();
8347   int nbOfComp2=other->getNumberOfComponents();
8348   if(nbOfTuple==nbOfTuple2)
8349     {
8350       if(nbOfComp==nbOfComp2)
8351         {
8352           std::transform(begin(),end(),other->begin(),getPointer(),std::plus<int>());
8353         }
8354       else if(nbOfComp2==1)
8355         {
8356           int *ptr=getPointer();
8357           const int *ptrc=other->getConstPointer();
8358           for(int i=0;i<nbOfTuple;i++)
8359             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::plus<int>(),*ptrc++));
8360         }
8361       else
8362         throw INTERP_KERNEL::Exception(msg);
8363     }
8364   else if(nbOfTuple2==1)
8365     {
8366       if(nbOfComp2==nbOfComp)
8367         {
8368           int *ptr=getPointer();
8369           const int *ptrc=other->getConstPointer();
8370           for(int i=0;i<nbOfTuple;i++)
8371             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::plus<int>());
8372         }
8373       else
8374         throw INTERP_KERNEL::Exception(msg);
8375     }
8376   else
8377     throw INTERP_KERNEL::Exception(msg);
8378   declareAsNew();
8379 }
8380
8381 /*!
8382  * Returns a new DataArrayInt that is a subtraction of two given arrays. There are 3
8383  * valid cases.
8384  * 1.  The arrays have same number of tuples and components. Then each value of
8385  *   the result array (_a_) is a subtraction of the corresponding values of \a a1 and
8386  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ i, j ].
8387  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
8388  *   component. Then
8389  *   _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ i, 0 ].
8390  * 3.  The arrays have same number of components and one array, say _a2_, has one
8391  *   tuple. Then
8392  *   _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ 0, j ].
8393  *
8394  * Info on components is copied either from the first array (in the first case) or from
8395  * the array with maximal number of elements (getNbOfElems()).
8396  *  \param [in] a1 - an array to subtract from.
8397  *  \param [in] a2 - an array to subtract.
8398  *  \return DataArrayInt * - the new instance of DataArrayInt.
8399  *          The caller is to delete this result array using decrRef() as it is no more
8400  *          needed.
8401  *  \throw If either \a a1 or \a a2 is NULL.
8402  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
8403  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
8404  *         none of them has number of tuples or components equal to 1.
8405  */
8406 DataArrayInt *DataArrayInt::Substract(const DataArrayInt *a1, const DataArrayInt *a2)
8407 {
8408   if(!a1 || !a2)
8409     throw INTERP_KERNEL::Exception("DataArrayInt::Substract : input DataArrayInt instance is NULL !");
8410   int nbOfTuple1=a1->getNumberOfTuples();
8411   int nbOfTuple2=a2->getNumberOfTuples();
8412   int nbOfComp1=a1->getNumberOfComponents();
8413   int nbOfComp2=a2->getNumberOfComponents();
8414   if(nbOfTuple2==nbOfTuple1)
8415     {
8416       if(nbOfComp1==nbOfComp2)
8417         {
8418           MCAuto<DataArrayInt> ret=DataArrayInt::New();
8419           ret->alloc(nbOfTuple2,nbOfComp1);
8420           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::minus<int>());
8421           ret->copyStringInfoFrom(*a1);
8422           return ret.retn();
8423         }
8424       else if(nbOfComp2==1)
8425         {
8426           MCAuto<DataArrayInt> ret=DataArrayInt::New();
8427           ret->alloc(nbOfTuple1,nbOfComp1);
8428           const int *a2Ptr=a2->getConstPointer();
8429           const int *a1Ptr=a1->getConstPointer();
8430           int *res=ret->getPointer();
8431           for(int i=0;i<nbOfTuple1;i++)
8432             res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::minus<int>(),a2Ptr[i]));
8433           ret->copyStringInfoFrom(*a1);
8434           return ret.retn();
8435         }
8436       else
8437         {
8438           a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Substract !");
8439           return 0;
8440         }
8441     }
8442   else if(nbOfTuple2==1)
8443     {
8444       a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Substract !");
8445       MCAuto<DataArrayInt> ret=DataArrayInt::New();
8446       ret->alloc(nbOfTuple1,nbOfComp1);
8447       const int *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
8448       int *pt=ret->getPointer();
8449       for(int i=0;i<nbOfTuple1;i++)
8450         pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::minus<int>());
8451       ret->copyStringInfoFrom(*a1);
8452       return ret.retn();
8453     }
8454   else
8455     {
8456       a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Substract !");//will always throw an exception
8457       return 0;
8458     }
8459 }
8460
8461 /*!
8462  * Subtract values of another DataArrayInt from values of \a this one. There are 3
8463  * valid cases.
8464  * 1.  The arrays have same number of tuples and components. Then each value of
8465  *   \a other array is subtracted from the corresponding value of \a this array, i.e.:
8466  *   _a_ [ i, j ] -= _other_ [ i, j ].
8467  * 2.  The arrays have same number of tuples and \a other array has one component. Then
8468  *   _a_ [ i, j ] -= _other_ [ i, 0 ].
8469  * 3.  The arrays have same number of components and \a other array has one tuple. Then
8470  *   _a_ [ i, j ] -= _a2_ [ 0, j ].
8471  *
8472  *  \param [in] other - an array to subtract from \a this one.
8473  *  \throw If \a other is NULL.
8474  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
8475  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
8476  *         \a other has number of both tuples and components not equal to 1.
8477  */
8478 void DataArrayInt::substractEqual(const DataArrayInt *other)
8479 {
8480   if(!other)
8481     throw INTERP_KERNEL::Exception("DataArrayInt::substractEqual : input DataArrayInt instance is NULL !");
8482   const char *msg="Nb of tuples mismatch for DataArrayInt::substractEqual  !";
8483   checkAllocated(); other->checkAllocated();
8484   int nbOfTuple=getNumberOfTuples();
8485   int nbOfTuple2=other->getNumberOfTuples();
8486   int nbOfComp=getNumberOfComponents();
8487   int nbOfComp2=other->getNumberOfComponents();
8488   if(nbOfTuple==nbOfTuple2)
8489     {
8490       if(nbOfComp==nbOfComp2)
8491         {
8492           std::transform(begin(),end(),other->begin(),getPointer(),std::minus<int>());
8493         }
8494       else if(nbOfComp2==1)
8495         {
8496           int *ptr=getPointer();
8497           const int *ptrc=other->getConstPointer();
8498           for(int i=0;i<nbOfTuple;i++)
8499             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::minus<int>(),*ptrc++));
8500         }
8501       else
8502         throw INTERP_KERNEL::Exception(msg);
8503     }
8504   else if(nbOfTuple2==1)
8505     {
8506       int *ptr=getPointer();
8507       const int *ptrc=other->getConstPointer();
8508       for(int i=0;i<nbOfTuple;i++)
8509         std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::minus<int>());
8510     }
8511   else
8512     throw INTERP_KERNEL::Exception(msg);
8513   declareAsNew();
8514 }
8515
8516 /*!
8517  * Returns a new DataArrayInt that is a product of two given arrays. There are 3
8518  * valid cases.
8519  * 1.  The arrays have same number of tuples and components. Then each value of
8520  *   the result array (_a_) is a product of the corresponding values of \a a1 and
8521  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ i, j ].
8522  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
8523  *   component. Then
8524  *   _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ i, 0 ].
8525  * 3.  The arrays have same number of components and one array, say _a2_, has one
8526  *   tuple. Then
8527  *   _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ 0, j ].
8528  *
8529  * Info on components is copied either from the first array (in the first case) or from
8530  * the array with maximal number of elements (getNbOfElems()).
8531  *  \param [in] a1 - a factor array.
8532  *  \param [in] a2 - another factor array.
8533  *  \return DataArrayInt * - the new instance of DataArrayInt.
8534  *          The caller is to delete this result array using decrRef() as it is no more
8535  *          needed.
8536  *  \throw If either \a a1 or \a a2 is NULL.
8537  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
8538  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
8539  *         none of them has number of tuples or components equal to 1.
8540  */
8541 DataArrayInt *DataArrayInt::Multiply(const DataArrayInt *a1, const DataArrayInt *a2)
8542 {
8543   if(!a1 || !a2)
8544     throw INTERP_KERNEL::Exception("DataArrayInt::Multiply : input DataArrayInt instance is NULL !");
8545   int nbOfTuple=a1->getNumberOfTuples();
8546   int nbOfTuple2=a2->getNumberOfTuples();
8547   int nbOfComp=a1->getNumberOfComponents();
8548   int nbOfComp2=a2->getNumberOfComponents();
8549   MCAuto<DataArrayInt> ret=0;
8550   if(nbOfTuple==nbOfTuple2)
8551     {
8552       if(nbOfComp==nbOfComp2)
8553         {
8554           ret=DataArrayInt::New();
8555           ret->alloc(nbOfTuple,nbOfComp);
8556           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::multiplies<int>());
8557           ret->copyStringInfoFrom(*a1);
8558         }
8559       else
8560         {
8561           int nbOfCompMin,nbOfCompMax;
8562           const DataArrayInt *aMin, *aMax;
8563           if(nbOfComp>nbOfComp2)
8564             {
8565               nbOfCompMin=nbOfComp2; nbOfCompMax=nbOfComp;
8566               aMin=a2; aMax=a1;
8567             }
8568           else
8569             {
8570               nbOfCompMin=nbOfComp; nbOfCompMax=nbOfComp2;
8571               aMin=a1; aMax=a2;
8572             }
8573           if(nbOfCompMin==1)
8574             {
8575               ret=DataArrayInt::New();
8576               ret->alloc(nbOfTuple,nbOfCompMax);
8577               const int *aMinPtr=aMin->getConstPointer();
8578               const int *aMaxPtr=aMax->getConstPointer();
8579               int *res=ret->getPointer();
8580               for(int i=0;i<nbOfTuple;i++)
8581                 res=std::transform(aMaxPtr+i*nbOfCompMax,aMaxPtr+(i+1)*nbOfCompMax,res,std::bind2nd(std::multiplies<int>(),aMinPtr[i]));
8582               ret->copyStringInfoFrom(*aMax);
8583             }
8584           else
8585             throw INTERP_KERNEL::Exception("Nb of components mismatch for array Multiply !");
8586         }
8587     }
8588   else if((nbOfTuple==1 && nbOfTuple2>1) || (nbOfTuple>1 && nbOfTuple2==1))
8589     {
8590       if(nbOfComp==nbOfComp2)
8591         {
8592           int nbOfTupleMax=std::max(nbOfTuple,nbOfTuple2);
8593           const DataArrayInt *aMin=nbOfTuple>nbOfTuple2?a2:a1;
8594           const DataArrayInt *aMax=nbOfTuple>nbOfTuple2?a1:a2;
8595           const int *aMinPtr=aMin->getConstPointer(),*aMaxPtr=aMax->getConstPointer();
8596           ret=DataArrayInt::New();
8597           ret->alloc(nbOfTupleMax,nbOfComp);
8598           int *res=ret->getPointer();
8599           for(int i=0;i<nbOfTupleMax;i++)
8600             res=std::transform(aMaxPtr+i*nbOfComp,aMaxPtr+(i+1)*nbOfComp,aMinPtr,res,std::multiplies<int>());
8601           ret->copyStringInfoFrom(*aMax);
8602         }
8603       else
8604         throw INTERP_KERNEL::Exception("Nb of components mismatch for array Multiply !");
8605     }
8606   else
8607     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Multiply !");
8608   return ret.retn();
8609 }
8610
8611
8612 /*!
8613  * Multiply values of another DataArrayInt to values of \a this one. There are 3
8614  * valid cases.
8615  * 1.  The arrays have same number of tuples and components. Then each value of
8616  *   \a other array is multiplied to the corresponding value of \a this array, i.e.:
8617  *   _a_ [ i, j ] *= _other_ [ i, j ].
8618  * 2.  The arrays have same number of tuples and \a other array has one component. Then
8619  *   _a_ [ i, j ] *= _other_ [ i, 0 ].
8620  * 3.  The arrays have same number of components and \a other array has one tuple. Then
8621  *   _a_ [ i, j ] *= _a2_ [ 0, j ].
8622  *
8623  *  \param [in] other - an array to multiply to \a this one.
8624  *  \throw If \a other is NULL.
8625  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
8626  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
8627  *         \a other has number of both tuples and components not equal to 1.
8628  */
8629 void DataArrayInt::multiplyEqual(const DataArrayInt *other)
8630 {
8631   if(!other)
8632     throw INTERP_KERNEL::Exception("DataArrayInt::multiplyEqual : input DataArrayInt instance is NULL !");
8633   const char *msg="Nb of tuples mismatch for DataArrayInt::multiplyEqual !";
8634   checkAllocated(); other->checkAllocated();
8635   int nbOfTuple=getNumberOfTuples();
8636   int nbOfTuple2=other->getNumberOfTuples();
8637   int nbOfComp=getNumberOfComponents();
8638   int nbOfComp2=other->getNumberOfComponents();
8639   if(nbOfTuple==nbOfTuple2)
8640     {
8641       if(nbOfComp==nbOfComp2)
8642         {
8643           std::transform(begin(),end(),other->begin(),getPointer(),std::multiplies<int>());
8644         }
8645       else if(nbOfComp2==1)
8646         {
8647           int *ptr=getPointer();
8648           const int *ptrc=other->getConstPointer();
8649           for(int i=0;i<nbOfTuple;i++)
8650             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::multiplies<int>(),*ptrc++));    
8651         }
8652       else
8653         throw INTERP_KERNEL::Exception(msg);
8654     }
8655   else if(nbOfTuple2==1)
8656     {
8657       if(nbOfComp2==nbOfComp)
8658         {
8659           int *ptr=getPointer();
8660           const int *ptrc=other->getConstPointer();
8661           for(int i=0;i<nbOfTuple;i++)
8662             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::multiplies<int>());
8663         }
8664       else
8665         throw INTERP_KERNEL::Exception(msg);
8666     }
8667   else
8668     throw INTERP_KERNEL::Exception(msg);
8669   declareAsNew();
8670 }
8671
8672
8673 /*!
8674  * Returns a new DataArrayInt that is a division of two given arrays. There are 3
8675  * valid cases.
8676  * 1.  The arrays have same number of tuples and components. Then each value of
8677  *   the result array (_a_) is a division of the corresponding values of \a a1 and
8678  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ i, j ].
8679  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
8680  *   component. Then
8681  *   _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ i, 0 ].
8682  * 3.  The arrays have same number of components and one array, say _a2_, has one
8683  *   tuple. Then
8684  *   _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ 0, j ].
8685  *
8686  * Info on components is copied either from the first array (in the first case) or from
8687  * the array with maximal number of elements (getNbOfElems()).
8688  *  \warning No check of division by zero is performed!
8689  *  \param [in] a1 - a numerator array.
8690  *  \param [in] a2 - a denominator array.
8691  *  \return DataArrayInt * - the new instance of DataArrayInt.
8692  *          The caller is to delete this result array using decrRef() as it is no more
8693  *          needed.
8694  *  \throw If either \a a1 or \a a2 is NULL.
8695  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
8696  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
8697  *         none of them has number of tuples or components equal to 1.
8698  */
8699 DataArrayInt *DataArrayInt::Divide(const DataArrayInt *a1, const DataArrayInt *a2)
8700 {
8701   if(!a1 || !a2)
8702     throw INTERP_KERNEL::Exception("DataArrayInt::Divide : input DataArrayInt instance is NULL !");
8703   int nbOfTuple1=a1->getNumberOfTuples();
8704   int nbOfTuple2=a2->getNumberOfTuples();
8705   int nbOfComp1=a1->getNumberOfComponents();
8706   int nbOfComp2=a2->getNumberOfComponents();
8707   if(nbOfTuple2==nbOfTuple1)
8708     {
8709       if(nbOfComp1==nbOfComp2)
8710         {
8711           MCAuto<DataArrayInt> ret=DataArrayInt::New();
8712           ret->alloc(nbOfTuple2,nbOfComp1);
8713           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::divides<int>());
8714           ret->copyStringInfoFrom(*a1);
8715           return ret.retn();
8716         }
8717       else if(nbOfComp2==1)
8718         {
8719           MCAuto<DataArrayInt> ret=DataArrayInt::New();
8720           ret->alloc(nbOfTuple1,nbOfComp1);
8721           const int *a2Ptr=a2->getConstPointer();
8722           const int *a1Ptr=a1->getConstPointer();
8723           int *res=ret->getPointer();
8724           for(int i=0;i<nbOfTuple1;i++)
8725             res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::divides<int>(),a2Ptr[i]));
8726           ret->copyStringInfoFrom(*a1);
8727           return ret.retn();
8728         }
8729       else
8730         {
8731           a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Divide !");
8732           return 0;
8733         }
8734     }
8735   else if(nbOfTuple2==1)
8736     {
8737       a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Divide !");
8738       MCAuto<DataArrayInt> ret=DataArrayInt::New();
8739       ret->alloc(nbOfTuple1,nbOfComp1);
8740       const int *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
8741       int *pt=ret->getPointer();
8742       for(int i=0;i<nbOfTuple1;i++)
8743         pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::divides<int>());
8744       ret->copyStringInfoFrom(*a1);
8745       return ret.retn();
8746     }
8747   else
8748     {
8749       a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Divide !");//will always throw an exception
8750       return 0;
8751     }
8752 }
8753
8754 /*!
8755  * Divide values of \a this array by values of another DataArrayInt. There are 3
8756  * valid cases.
8757  * 1.  The arrays have same number of tuples and components. Then each value of
8758  *    \a this array is divided by the corresponding value of \a other one, i.e.:
8759  *   _a_ [ i, j ] /= _other_ [ i, j ].
8760  * 2.  The arrays have same number of tuples and \a other array has one component. Then
8761  *   _a_ [ i, j ] /= _other_ [ i, 0 ].
8762  * 3.  The arrays have same number of components and \a other array has one tuple. Then
8763  *   _a_ [ i, j ] /= _a2_ [ 0, j ].
8764  *
8765  *  \warning No check of division by zero is performed!
8766  *  \param [in] other - an array to divide \a this one by.
8767  *  \throw If \a other is NULL.
8768  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
8769  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
8770  *         \a other has number of both tuples and components not equal to 1.
8771  */
8772 void DataArrayInt::divideEqual(const DataArrayInt *other)
8773 {
8774   if(!other)
8775     throw INTERP_KERNEL::Exception("DataArrayInt::divideEqual : input DataArrayInt instance is NULL !");
8776   const char *msg="Nb of tuples mismatch for DataArrayInt::divideEqual !";
8777   checkAllocated(); other->checkAllocated();
8778   int nbOfTuple=getNumberOfTuples();
8779   int nbOfTuple2=other->getNumberOfTuples();
8780   int nbOfComp=getNumberOfComponents();
8781   int nbOfComp2=other->getNumberOfComponents();
8782   if(nbOfTuple==nbOfTuple2)
8783     {
8784       if(nbOfComp==nbOfComp2)
8785         {
8786           std::transform(begin(),end(),other->begin(),getPointer(),std::divides<int>());
8787         }
8788       else if(nbOfComp2==1)
8789         {
8790           int *ptr=getPointer();
8791           const int *ptrc=other->getConstPointer();
8792           for(int i=0;i<nbOfTuple;i++)
8793             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::divides<int>(),*ptrc++));
8794         }
8795       else
8796         throw INTERP_KERNEL::Exception(msg);
8797     }
8798   else if(nbOfTuple2==1)
8799     {
8800       if(nbOfComp2==nbOfComp)
8801         {
8802           int *ptr=getPointer();
8803           const int *ptrc=other->getConstPointer();
8804           for(int i=0;i<nbOfTuple;i++)
8805             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::divides<int>());
8806         }
8807       else
8808         throw INTERP_KERNEL::Exception(msg);
8809     }
8810   else
8811     throw INTERP_KERNEL::Exception(msg);
8812   declareAsNew();
8813 }
8814
8815
8816 /*!
8817  * Returns a new DataArrayInt that is a modulus of two given arrays. There are 3
8818  * valid cases.
8819  * 1.  The arrays have same number of tuples and components. Then each value of
8820  *   the result array (_a_) is a division of the corresponding values of \a a1 and
8821  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] % _a2_ [ i, j ].
8822  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
8823  *   component. Then
8824  *   _a_ [ i, j ] = _a1_ [ i, j ] % _a2_ [ i, 0 ].
8825  * 3.  The arrays have same number of components and one array, say _a2_, has one
8826  *   tuple. Then
8827  *   _a_ [ i, j ] = _a1_ [ i, j ] % _a2_ [ 0, j ].
8828  *
8829  * Info on components is copied either from the first array (in the first case) or from
8830  * the array with maximal number of elements (getNbOfElems()).
8831  *  \warning No check of division by zero is performed!
8832  *  \param [in] a1 - a dividend array.
8833  *  \param [in] a2 - a divisor array.
8834  *  \return DataArrayInt * - the new instance of DataArrayInt.
8835  *          The caller is to delete this result array using decrRef() as it is no more
8836  *          needed.
8837  *  \throw If either \a a1 or \a a2 is NULL.
8838  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
8839  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
8840  *         none of them has number of tuples or components equal to 1.
8841  */
8842 DataArrayInt *DataArrayInt::Modulus(const DataArrayInt *a1, const DataArrayInt *a2)
8843 {
8844   if(!a1 || !a2)
8845     throw INTERP_KERNEL::Exception("DataArrayInt::Modulus : input DataArrayInt instance is NULL !");
8846   int nbOfTuple1=a1->getNumberOfTuples();
8847   int nbOfTuple2=a2->getNumberOfTuples();
8848   int nbOfComp1=a1->getNumberOfComponents();
8849   int nbOfComp2=a2->getNumberOfComponents();
8850   if(nbOfTuple2==nbOfTuple1)
8851     {
8852       if(nbOfComp1==nbOfComp2)
8853         {
8854           MCAuto<DataArrayInt> ret=DataArrayInt::New();
8855           ret->alloc(nbOfTuple2,nbOfComp1);
8856           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::modulus<int>());
8857           ret->copyStringInfoFrom(*a1);
8858           return ret.retn();
8859         }
8860       else if(nbOfComp2==1)
8861         {
8862           MCAuto<DataArrayInt> ret=DataArrayInt::New();
8863           ret->alloc(nbOfTuple1,nbOfComp1);
8864           const int *a2Ptr=a2->getConstPointer();
8865           const int *a1Ptr=a1->getConstPointer();
8866           int *res=ret->getPointer();
8867           for(int i=0;i<nbOfTuple1;i++)
8868             res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::modulus<int>(),a2Ptr[i]));
8869           ret->copyStringInfoFrom(*a1);
8870           return ret.retn();
8871         }
8872       else
8873         {
8874           a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Modulus !");
8875           return 0;
8876         }
8877     }
8878   else if(nbOfTuple2==1)
8879     {
8880       a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Modulus !");
8881       MCAuto<DataArrayInt> ret=DataArrayInt::New();
8882       ret->alloc(nbOfTuple1,nbOfComp1);
8883       const int *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
8884       int *pt=ret->getPointer();
8885       for(int i=0;i<nbOfTuple1;i++)
8886         pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::modulus<int>());
8887       ret->copyStringInfoFrom(*a1);
8888       return ret.retn();
8889     }
8890   else
8891     {
8892       a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Modulus !");//will always throw an exception
8893       return 0;
8894     }
8895 }
8896
8897 /*!
8898  * Modify \a this array so that each value becomes a modulus of division of this value by
8899  * a value of another DataArrayInt. There are 3 valid cases.
8900  * 1.  The arrays have same number of tuples and components. Then each value of
8901  *    \a this array is divided by the corresponding value of \a other one, i.e.:
8902  *   _a_ [ i, j ] %= _other_ [ i, j ].
8903  * 2.  The arrays have same number of tuples and \a other array has one component. Then
8904  *   _a_ [ i, j ] %= _other_ [ i, 0 ].
8905  * 3.  The arrays have same number of components and \a other array has one tuple. Then
8906  *   _a_ [ i, j ] %= _a2_ [ 0, j ].
8907  *
8908  *  \warning No check of division by zero is performed!
8909  *  \param [in] other - a divisor array.
8910  *  \throw If \a other is NULL.
8911  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
8912  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
8913  *         \a other has number of both tuples and components not equal to 1.
8914  */
8915 void DataArrayInt::modulusEqual(const DataArrayInt *other)
8916 {
8917   if(!other)
8918     throw INTERP_KERNEL::Exception("DataArrayInt::modulusEqual : input DataArrayInt instance is NULL !");
8919   const char *msg="Nb of tuples mismatch for DataArrayInt::modulusEqual !";
8920   checkAllocated(); other->checkAllocated();
8921   int nbOfTuple=getNumberOfTuples();
8922   int nbOfTuple2=other->getNumberOfTuples();
8923   int nbOfComp=getNumberOfComponents();
8924   int nbOfComp2=other->getNumberOfComponents();
8925   if(nbOfTuple==nbOfTuple2)
8926     {
8927       if(nbOfComp==nbOfComp2)
8928         {
8929           std::transform(begin(),end(),other->begin(),getPointer(),std::modulus<int>());
8930         }
8931       else if(nbOfComp2==1)
8932         {
8933           if(nbOfComp2==nbOfComp)
8934             {
8935               int *ptr=getPointer();
8936               const int *ptrc=other->getConstPointer();
8937               for(int i=0;i<nbOfTuple;i++)
8938                 std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::modulus<int>(),*ptrc++));
8939             }
8940           else
8941             throw INTERP_KERNEL::Exception(msg);
8942         }
8943       else
8944         throw INTERP_KERNEL::Exception(msg);
8945     }
8946   else if(nbOfTuple2==1)
8947     {
8948       int *ptr=getPointer();
8949       const int *ptrc=other->getConstPointer();
8950       for(int i=0;i<nbOfTuple;i++)
8951         std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::modulus<int>());
8952     }
8953   else
8954     throw INTERP_KERNEL::Exception(msg);
8955   declareAsNew();
8956 }
8957
8958 /*!
8959  * Returns a new DataArrayInt that is the result of pow of two given arrays. There are 3
8960  * valid cases.
8961  *
8962  *  \param [in] a1 - an array to pow up.
8963  *  \param [in] a2 - another array to sum up.
8964  *  \return DataArrayInt * - the new instance of DataArrayInt.
8965  *          The caller is to delete this result array using decrRef() as it is no more
8966  *          needed.
8967  *  \throw If either \a a1 or \a a2 is NULL.
8968  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
8969  *  \throw If \a a1->getNumberOfComponents() != 1 or \a a2->getNumberOfComponents() != 1.
8970  *  \throw If there is a negative value in \a a2.
8971  */
8972 DataArrayInt *DataArrayInt::Pow(const DataArrayInt *a1, const DataArrayInt *a2)
8973 {
8974   if(!a1 || !a2)
8975     throw INTERP_KERNEL::Exception("DataArrayInt::Pow : at least one of input instances is null !");
8976   int nbOfTuple=a1->getNumberOfTuples();
8977   int nbOfTuple2=a2->getNumberOfTuples();
8978   int nbOfComp=a1->getNumberOfComponents();
8979   int nbOfComp2=a2->getNumberOfComponents();
8980   if(nbOfTuple!=nbOfTuple2)
8981     throw INTERP_KERNEL::Exception("DataArrayInt::Pow : number of tuples mismatches !");
8982   if(nbOfComp!=1 || nbOfComp2!=1)
8983     throw INTERP_KERNEL::Exception("DataArrayInt::Pow : number of components of both arrays must be equal to 1 !");
8984   MCAuto<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbOfTuple,1);
8985   const int *ptr1(a1->begin()),*ptr2(a2->begin());
8986   int *ptr=ret->getPointer();
8987   for(int i=0;i<nbOfTuple;i++,ptr1++,ptr2++,ptr++)
8988     {
8989       if(*ptr2>=0)
8990         {
8991           int tmp=1;
8992           for(int j=0;j<*ptr2;j++)
8993             tmp*=*ptr1;
8994           *ptr=tmp;
8995         }
8996       else
8997         {
8998           std::ostringstream oss; oss << "DataArrayInt::Pow : on tuple #" << i << " of a2 value is < 0 (" << *ptr2 << ") !";
8999           throw INTERP_KERNEL::Exception(oss.str().c_str());
9000         }
9001     }
9002   return ret.retn();
9003 }
9004
9005 /*!
9006  * Apply pow on values of another DataArrayInt to values of \a this one.
9007  *
9008  *  \param [in] other - an array to pow to \a this one.
9009  *  \throw If \a other is NULL.
9010  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples()
9011  *  \throw If \a this->getNumberOfComponents() != 1 or \a other->getNumberOfComponents() != 1
9012  *  \throw If there is a negative value in \a other.
9013  */
9014 void DataArrayInt::powEqual(const DataArrayInt *other)
9015 {
9016   if(!other)
9017     throw INTERP_KERNEL::Exception("DataArrayInt::powEqual : input instance is null !");
9018   int nbOfTuple=getNumberOfTuples();
9019   int nbOfTuple2=other->getNumberOfTuples();
9020   int nbOfComp=getNumberOfComponents();
9021   int nbOfComp2=other->getNumberOfComponents();
9022   if(nbOfTuple!=nbOfTuple2)
9023     throw INTERP_KERNEL::Exception("DataArrayInt::powEqual : number of tuples mismatches !");
9024   if(nbOfComp!=1 || nbOfComp2!=1)
9025     throw INTERP_KERNEL::Exception("DataArrayInt::powEqual : number of components of both arrays must be equal to 1 !");
9026   int *ptr=getPointer();
9027   const int *ptrc=other->begin();
9028   for(int i=0;i<nbOfTuple;i++,ptrc++,ptr++)
9029     {
9030       if(*ptrc>=0)
9031         {
9032           int tmp=1;
9033           for(int j=0;j<*ptrc;j++)
9034             tmp*=*ptr;
9035           *ptr=tmp;
9036         }
9037       else
9038         {
9039           std::ostringstream oss; oss << "DataArrayInt::powEqual : on tuple #" << i << " of other value is < 0 (" << *ptrc << ") !";
9040           throw INTERP_KERNEL::Exception(oss.str().c_str());
9041         }
9042     }
9043   declareAsNew();
9044 }
9045
9046 /*!
9047  * Returns a C array which is a renumbering map in "Old to New" mode for the input array.
9048  * This map, if applied to \a start array, would make it sorted. For example, if
9049  * \a start array contents are [9,10,0,6,4,11,3,7] then the contents of the result array is
9050  * [5,6,0,3,2,7,1,4].
9051  *  \param [in] start - pointer to the first element of the array for which the
9052  *         permutation map is computed.
9053  *  \param [in] end - pointer specifying the end of the array \a start, so that
9054  *         the last value of \a start is \a end[ -1 ].
9055  *  \return int * - the result permutation array that the caller is to delete as it is no
9056  *         more needed.
9057  *  \throw If there are equal values in the input array.
9058  */
9059 int *DataArrayInt::CheckAndPreparePermutation(const int *start, const int *end)
9060 {
9061   std::size_t sz=std::distance(start,end);
9062   int *ret=(int *)malloc(sz*sizeof(int));
9063   int *work=new int[sz];
9064   std::copy(start,end,work);
9065   std::sort(work,work+sz);
9066   if(std::unique(work,work+sz)!=work+sz)
9067     {
9068       delete [] work;
9069       free(ret);
9070       throw INTERP_KERNEL::Exception("Some elements are equals in the specified array !");
9071     }
9072   std::map<int,int> m;
9073   for(int *workPt=work;workPt!=work+sz;workPt++)
9074     m[*workPt]=(int)std::distance(work,workPt);
9075   int *iter2=ret;
9076   for(const int *iter=start;iter!=end;iter++,iter2++)
9077     *iter2=m[*iter];
9078   delete [] work;
9079   return ret;
9080 }
9081
9082 /*!
9083  * Returns a new DataArrayInt containing an arithmetic progression
9084  * that is equal to the sequence returned by Python \c range(\a begin,\a  end,\a  step )
9085  * function.
9086  *  \param [in] begin - the start value of the result sequence.
9087  *  \param [in] end - limiting value, so that every value of the result array is less than
9088  *              \a end.
9089  *  \param [in] step - specifies the increment or decrement.
9090  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
9091  *          array using decrRef() as it is no more needed.
9092  *  \throw If \a step == 0.
9093  *  \throw If \a end < \a begin && \a step > 0.
9094  *  \throw If \a end > \a begin && \a step < 0.
9095  */
9096 DataArrayInt *DataArrayInt::Range(int begin, int end, int step)
9097 {
9098   int nbOfTuples=GetNumberOfItemGivenBESRelative(begin,end,step,"DataArrayInt::Range");
9099   MCAuto<DataArrayInt> ret=DataArrayInt::New();
9100   ret->alloc(nbOfTuples,1);
9101   int *ptr=ret->getPointer();
9102   if(step>0)
9103     {
9104       for(int i=begin;i<end;i+=step,ptr++)
9105         *ptr=i;
9106     }
9107   else
9108     {
9109       for(int i=begin;i>end;i+=step,ptr++)
9110         *ptr=i;
9111     }
9112   return ret.retn();
9113 }
9114
9115 /*!
9116  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
9117  * Server side.
9118  */
9119 void DataArrayInt::getTinySerializationIntInformation(std::vector<int>& tinyInfo) const
9120 {
9121   tinyInfo.resize(2);
9122   if(isAllocated())
9123     {
9124       tinyInfo[0]=getNumberOfTuples();
9125       tinyInfo[1]=getNumberOfComponents();
9126     }
9127   else
9128     {
9129       tinyInfo[0]=-1;
9130       tinyInfo[1]=-1;
9131     }
9132 }
9133
9134 /*!
9135  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
9136  * Server side.
9137  */
9138 void DataArrayInt::getTinySerializationStrInformation(std::vector<std::string>& tinyInfo) const
9139 {
9140   if(isAllocated())
9141     {
9142       int nbOfCompo=getNumberOfComponents();
9143       tinyInfo.resize(nbOfCompo+1);
9144       tinyInfo[0]=getName();
9145       for(int i=0;i<nbOfCompo;i++)
9146         tinyInfo[i+1]=getInfoOnComponent(i);
9147     }
9148   else
9149     {
9150       tinyInfo.resize(1);
9151       tinyInfo[0]=getName();
9152     }
9153 }
9154
9155 /*!
9156  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
9157  * This method returns if a feeding is needed.
9158  */
9159 bool DataArrayInt::resizeForUnserialization(const std::vector<int>& tinyInfoI)
9160 {
9161   int nbOfTuple=tinyInfoI[0];
9162   int nbOfComp=tinyInfoI[1];
9163   if(nbOfTuple!=-1 || nbOfComp!=-1)
9164     {
9165       alloc(nbOfTuple,nbOfComp);
9166       return true;
9167     }
9168   return false;
9169 }
9170
9171 /*!
9172  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
9173  * This method returns if a feeding is needed.
9174  */
9175 void DataArrayInt::finishUnserialization(const std::vector<int>& tinyInfoI, const std::vector<std::string>& tinyInfoS)
9176 {
9177   setName(tinyInfoS[0]);
9178   if(isAllocated())
9179     {
9180       int nbOfCompo=tinyInfoI[1];
9181       for(int i=0;i<nbOfCompo;i++)
9182         setInfoOnComponent(i,tinyInfoS[i+1]);
9183     }
9184 }
9185
9186 DataArrayIntIterator::DataArrayIntIterator(DataArrayInt *da):_da(da),_pt(0),_tuple_id(0),_nb_comp(0),_nb_tuple(0)
9187 {
9188   if(_da)
9189     {
9190       _da->incrRef();
9191       if(_da->isAllocated())
9192         {
9193           _nb_comp=da->getNumberOfComponents();
9194           _nb_tuple=da->getNumberOfTuples();
9195           _pt=da->getPointer();
9196         }
9197     }
9198 }
9199
9200 DataArrayIntIterator::~DataArrayIntIterator()
9201 {
9202   if(_da)
9203     _da->decrRef();
9204 }
9205
9206 DataArrayIntTuple *DataArrayIntIterator::nextt()
9207 {
9208   if(_tuple_id<_nb_tuple)
9209     {
9210       _tuple_id++;
9211       DataArrayIntTuple *ret=new DataArrayIntTuple(_pt,_nb_comp);
9212       _pt+=_nb_comp;
9213       return ret;
9214     }
9215   else
9216     return 0;
9217 }
9218
9219 DataArrayIntTuple::DataArrayIntTuple(int *pt, int nbOfComp):_pt(pt),_nb_of_compo(nbOfComp)
9220 {
9221 }
9222
9223 std::string DataArrayIntTuple::repr() const
9224 {
9225   std::ostringstream oss; oss << "(";
9226   for(int i=0;i<_nb_of_compo-1;i++)
9227     oss << _pt[i] << ", ";
9228   oss << _pt[_nb_of_compo-1] << ")";
9229   return oss.str();
9230 }
9231
9232 int DataArrayIntTuple::intValue() const
9233 {
9234   if(_nb_of_compo==1)
9235     return *_pt;
9236   throw INTERP_KERNEL::Exception("DataArrayIntTuple::intValue : DataArrayIntTuple instance has not exactly 1 component -> Not possible to convert it into an integer !");
9237 }
9238
9239 /*!
9240  * This method returns a newly allocated instance the caller should dealed with by a MEDCoupling::DataArrayInt::decrRef.
9241  * This method performs \b no copy of data. The content is only referenced using MEDCoupling::DataArrayInt::useArray with ownership set to \b false.
9242  * 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
9243  * \b nbOfCompo=1 and \bnbOfTuples==this->_nb_of_elem.
9244  */
9245 DataArrayInt *DataArrayIntTuple::buildDAInt(int nbOfTuples, int nbOfCompo) const
9246 {
9247   if((_nb_of_compo==nbOfCompo && nbOfTuples==1) || (_nb_of_compo==nbOfTuples && nbOfCompo==1))
9248     {
9249       DataArrayInt *ret=DataArrayInt::New();
9250       ret->useExternalArrayWithRWAccess(_pt,nbOfTuples,nbOfCompo);
9251       return ret;
9252     }
9253   else
9254     {
9255       std::ostringstream oss; oss << "DataArrayIntTuple::buildDAInt : unable to build a requested DataArrayInt instance with nbofTuple=" << nbOfTuples << " and nbOfCompo=" << nbOfCompo;
9256       oss << ".\nBecause the number of elements in this is " << _nb_of_compo << " !";
9257       throw INTERP_KERNEL::Exception(oss.str().c_str());
9258     }
9259 }